commit aa4759ecc74e674ed05ae22150cf0e8c5f9fa9fd Author: sunbeam Date: Mon Feb 3 20:43:43 2025 +0800 移植过来 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8110a3f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +Debug +Debug_FLASH diff --git a/CAN_Bootloader/.gitignore b/CAN_Bootloader/.gitignore new file mode 100644 index 0000000..baaf1ed --- /dev/null +++ b/CAN_Bootloader/.gitignore @@ -0,0 +1,2 @@ +/dist +/.build diff --git a/CAN_Bootloader/.idea/CAN_Bootloader.iml b/CAN_Bootloader/.idea/CAN_Bootloader.iml new file mode 100644 index 0000000..bc2cd87 --- /dev/null +++ b/CAN_Bootloader/.idea/CAN_Bootloader.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/CAN_Bootloader/.idea/editor.xml b/CAN_Bootloader/.idea/editor.xml new file mode 100644 index 0000000..5792426 --- /dev/null +++ b/CAN_Bootloader/.idea/editor.xml @@ -0,0 +1,588 @@ + + + + + \ No newline at end of file diff --git a/CAN_Bootloader/.idea/modules.xml b/CAN_Bootloader/.idea/modules.xml new file mode 100644 index 0000000..5b441cf --- /dev/null +++ b/CAN_Bootloader/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/CAN_Bootloader/.idea/workspace.xml b/CAN_Bootloader/.idea/workspace.xml new file mode 100644 index 0000000..e107103 --- /dev/null +++ b/CAN_Bootloader/.idea/workspace.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + 1738399915338 + + + + + + \ No newline at end of file diff --git a/CAN_Bootloader/DM_RP_SA.dll b/CAN_Bootloader/DM_RP_SA.dll new file mode 100644 index 0000000..bfde764 Binary files /dev/null and b/CAN_Bootloader/DM_RP_SA.dll differ diff --git a/CAN_Bootloader/USB2XXX.dll b/CAN_Bootloader/USB2XXX.dll new file mode 100644 index 0000000..7d01443 Binary files /dev/null and b/CAN_Bootloader/USB2XXX.dll differ diff --git a/CAN_Bootloader/default.aproj b/CAN_Bootloader/default.aproj new file mode 100644 index 0000000..98289a9 --- /dev/null +++ b/CAN_Bootloader/default.aproj @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CAN_Bootloader/dlg/诊断子窗口.aardio b/CAN_Bootloader/dlg/诊断子窗口.aardio new file mode 100644 index 0000000..4858b01 --- /dev/null +++ b/CAN_Bootloader/dlg/诊断子窗口.aardio @@ -0,0 +1,87 @@ +import win.ui; +/*DSG{{*/ +var winform = win.form(text="诊断读取";right=679;bottom=499;border="thin";max=false;mode="popup") +winform.add( +btnDID_F010={cls="button";text="F010";left=178;top=162;right=305;bottom=193;z=11}; +btnDID_F010w={cls="button";text="写F010";left=336;top=296;right=463;bottom=327;z=16}; +btnDID_F101={cls="button";text="F101";left=178;top=203;right=305;bottom=234;z=10}; +btnDID_F101w={cls="button";text="写F101";left=338;top=335;right=458;bottom=366;z=15}; +btnDID_F159={cls="button";text="F159";left=36;top=162;right=163;bottom=193;z=5}; +btnDID_F15A={cls="button";text="F15A";left=36;top=203;right=163;bottom=234;z=6}; +btnDID_F180={cls="button";text="F180";left=178;top=40;right=305;bottom=71;z=7}; +btnDID_F187={cls="button";text="零部件编号";left=36;top=40;right=163;bottom=71;z=2}; +btnDID_F18A={cls="button";text="供应商名称";left=36;top=80;right=163;bottom=111;z=3}; +btnDID_F18C={cls="button";text="F18C";left=178;top=80;right=305;bottom=111;z=8}; +btnDID_F190={cls="button";text="F190 VIN";left=178;top=121;right=305;bottom=152;z=9}; +btnDID_F197={cls="button";text="ECU 系统名称";left=36;top=121;right=163;bottom=152;z=4}; +btn_1003={cls="button";text="扩展会话";left=22;top=296;right=126;bottom=323;z=14}; +btn_2701={cls="button";text="解锁";left=158;top=296;right=262;bottom=323;z=13}; +groupbox={cls="groupbox";text="DID";left=16;top=12;right=328;bottom=260;edge=1;z=1}; +groupbox2={cls="groupbox";text="DTC";left=343;top=12;right=655;bottom=260;edge=1;z=12} +) +/*}}*/ + +winform.btnDID_F180.oncommand = function(id,event){ + DiagReadDID(0xF180); +} + +winform.btnDID_F18A.oncommand = function(id,event){ + DiagReadDID(0xF18A); +} + +winform.btnDID_F197.oncommand = function(id,event){ + DiagReadDID(0xF197); +} + +winform.btnDID_F159.oncommand = function(id,event){ + DiagReadDID(0xF159); +} + +winform.btnDID_F15A.oncommand = function(id,event){ + DiagReadDID(0xF15A); +} + +winform.btnDID_F18C.oncommand = function(id,event){ + DiagReadDID(0xF18C); +} + +winform.btnDID_F190.oncommand = function(id,event){ + DiagReadDID(0xF190); +} + +winform.btnDID_F010.oncommand = function(id,event){ + DiagReadDID(0xF010); +} + +winform.btnDID_F101.oncommand = function(id,event){ + DiagReadDID(0xF101); +} + +winform.onClose = function(hwnd,message,wParam,lParam){ + winform.show(false); + return 0; +} + +winform.btn_2701.oncommand = function(id,event){ + ::PostThreadMessage(thrdId,114,0x01,0)//自定义消息 +} + +winform.btn_1003.oncommand = function(id,event){ + ::PostThreadMessage(thrdId,111,0x00,0x03)//自定义消息 +} + +winform.btnDID_F187.oncommand = function(id,event){ + DiagReadDID(0xF187); +} + +winform.btnDID_F010w.oncommand = function(id,event){ + ::PostThreadMessage(thrdId,115,0xF010,0x00)//自定义消息 +} + +winform.btnDID_F101w.oncommand = function(id,event){ + ::PostThreadMessage(thrdId,115,0xF101,0x00)//自定义消息 +} + +winform.show(); +win.loopMessage(); +return winform; \ No newline at end of file diff --git a/CAN_Bootloader/lib/config.aardio b/CAN_Bootloader/lib/config.aardio new file mode 100644 index 0000000..a1cbfc5 --- /dev/null +++ b/CAN_Bootloader/lib/config.aardio @@ -0,0 +1,20 @@ +//config 配置文件 +import fsys.config; +config = fsys.config("/config/"); +//config = fsys.config( io.appData("/软件作者/应用程序名/") ); + +//不需要序列化的配置名字前请添加下划线 +namespace config { + __appName = "应用程序名"; + __appVersion = "1.0.0.01"; + __appDescription = "这是一个测试程序"; + __website = "http://www.aardio.com/"; +} + +/**intellisense(config) +__appName = 应用程序名 +__appVersion = 应用程序内部版本号 +__appDescription = 程序说明 +__website = 官方网站 +? = 配置文件名,\n读写配置并序列化为一个表对象,\n表的成员值可以是支持序列化的普通变量,支持table对象\n配置文件在首次使用时自动加载,退出程序时自动保存\n!fsys_table. +end intellisense**/ \ No newline at end of file diff --git a/CAN_Bootloader/lib/usb2canfd.aardio b/CAN_Bootloader/lib/usb2canfd.aardio new file mode 100644 index 0000000..039f656 --- /dev/null +++ b/CAN_Bootloader/lib/usb2canfd.aardio @@ -0,0 +1,490 @@ +/* +*使用说明: +*1.创建CAN设备对象 CANHw = usb2canfd.USB2CANHW(); +*2.加载DLL CANHw.LoadDll(); +*3.扫描设备 hwnum = CANHw.FlashHw(); +*4.获取可用设备 allhw = CANHw.GetAvailableHW(); +*5.打开设备(初始化) CANHw.OpenDevice(设备序号,通道) +*6.通过SendMsg和GetMsg发送和获取报文 +*/ +namespace usb2canfd{ + //参考 http://www.toomoss.com/help/index.htm + + + //初始化CAN的数据类型定义 + class CANFD_INIT_CONFIG{ + ctor( /*输入构造函数所需要的参数*/ ){ + + }; + type=me; + /*对象的所有成员必须用分号分隔*/ + BYTE Mode; //0-正常模式,1-自发自收模式 + BYTE ISOCRCEnable;//0-禁止ISO CRC,1-使能ISO CRC + BYTE RetrySend;//0-禁止重发,1-无限制重发 + BYTE ResEnable;//0-不接入内部120欧终端电阻,1-接入内部120欧终端电阻 + //波特率参数可以用TCANLINPro软件里面的波特率计算工具计算 + //仲裁段波特率参数,波特率=40M/NBT_BRP*(1+NBT_SEG1+NBT_SEG2) + BYTE NBT_BRP; + BYTE NBT_SEG1; + BYTE NBT_SEG2; + BYTE NBT_SJW; + //数据段波特率参数,波特率=40M/DBT_BRP*(1+DBT_SEG1+DBT_SEG2) + BYTE DBT_BRP; + BYTE DBT_SEG1; + BYTE DBT_SEG2; + BYTE DBT_SJW; + BYTE __Res0[8]; + } + + //初始化CAN的数据类型定义 + class CAN_INIT_CONFIG{ + ctor( /*输入构造函数所需要的参数*/ ){ + + }; + type=me; + /*对象的所有成员必须用分号分隔*/ + //CAN波特率 = 100MHz/(CAN_BRP)/(CAN_SJW+CAN_BS1+CAN_BS2) + INT CAN_BRP; //取值范围1~1024 + BYTE CAN_SJW; //取值范围1~4 + BYTE CAN_BS1; //取值范围1~16 + BYTE CAN_BS2; //取值范围1~8 + BYTE CAN_Mode; //CAN工作模式,0-正常模式,1-环回模式,2-静默模式,3-静默环回模式,bit7为1则接入适配器内部终端电阻,否则不接入 + BYTE CAN_ABOM; //自动离线管理,0-禁止,1-使能 + BYTE CAN_NART; //报文重发管理,0-使能报文重传,1-禁止报文重传 + BYTE CAN_RFLM; //FIFO锁定管理,0-新报文覆盖旧报文,1-丢弃新报文 + BYTE CAN_TXFP; //发送优先级管理,0-标识符决定,1-发送请求顺序决定 + } + + class CAN_FILTER_CONFIG{ + ctor( /*输入构造函数所需要的参数*/ ){ + + }; + type=me; + /*对象的所有成员必须用分号分隔*/ + BYTE Enable; //使能该过滤器,1-使能,0-禁止 + BYTE FilterIndex; //过滤器索引号,取值范围为0到13 + BYTE FilterMode; //过滤器模式,0-屏蔽位模式,1-标识符列表模式 + BYTE ExtFrame; //过滤的帧类型标志,为1 代表要过滤的为扩展帧,为0 代表要过滤的为标准帧。 + INT ID_Std_Ext; //验收码ID + INT ID_IDE; //验收码IDE + INT ID_RTR; //验收码RTR + INT MASK_Std_Ext; //屏蔽码ID,该项只有在过滤器模式为屏蔽位模式时有用 + INT MASK_IDE; //屏蔽码IDE,该项只有在过滤器模式为屏蔽位模式时有用 + INT MASK_RTR; //屏蔽码RTR,该项只有在过滤器模式为屏蔽位模式时有用 + } + + + //CANfd信息帧的数据类型定义 + class CANFD_MSG{ + ctor( /*输入构造函数所需要的参数*/ ){ + + }; + type=me; + /*对象的所有成员必须用分号分隔*/ + INT ID; //报文ID。 //| (1<<31);//扩展帧 + BYTE DLC; //数据字节长度,可设置为-0,1,2,3,4,5,6,7,8,12,16,20,24,32,48,64 + BYTE Flags; //bit[0]-BRS,bit[1]-ESI,bit[2]-FDF,bit[6..5]-Channel,bit[7]-RXD + BYTE __Res0; //保留 + BYTE __Res1; //保留 + INT TimeStamp; //帧接收或者发送时的时间戳,单位为10us + BYTE Data[64]; //报文的数据。 + } + + //CAN信息帧的数据类型定义 + class CAN_MSG{ + ctor( /*输入构造函数所需要的参数*/ ){ + + }; + type=me; + /*对象的所有成员必须用分号分隔*/ + INT ID; //报文ID。 + INT TimeStamp; //接收到信息帧时的时间标识,从CAN 控制器初始化开始计时。 + BYTE RemoteFlag; //是否是远程帧 + BYTE ExternFlag; //是否是扩展帧 + BYTE DataLen; //数据长度(<=8),即Data 的长度。 + BYTE Data[8]; //报文的数据。 + BYTE __Res; + } + + class CAN_UDS_ADDR{ + ctor( /*输入构造函数所需要的参数*/ ){ + + }; + type=me; + /*对象的所有成员必须用分号分隔*/ + INT ReqID; //请求报文ID。 + INT ResID; //应答报文ID。 + BYTE Flag; //bit[0]-帧类型(0-标准帧,1-扩展帧), + //bit[1]-FDF(0-普通CAN帧,1-CANFD帧), + //bit[2]-BRS(0-CANFD帧不加速,1-CANFD帧加速) + BYTE AddrFormats; //0-normal, 1-extended ,2-mixed + BYTE AddrExt; //当AddrFormats不为normal时,该数据放到CAN数据域第1字节 + BYTE MaxDLC; //每帧最大数据字节数,一般设置为8 + + } + + + class DEVICE_INFO{ + ctor( /*输入构造函数所需要的参数*/ ){ + + }; + type=me; + /*对象的所有成员必须用分号分隔*/ + BYTE FirmwareName[32]; //固件名称字符串 + BYTE BuildDate[32]; //固件编译时间字符串 + INT HardwareVersion; //硬件版本号 + INT FirmwareVersion; //固件版本号 + INT SerialNumber[3]; //适配器序列号 + INT Functions; //适配器当前具备的功能 + } + + + + //调用函数 + class USB2CANHW{ + ctor( /*输入构造函数所需要的参数*/ ){ + + }; + type=me; + /*对象的所有成员必须用分号分隔*/ + + //初始化全局变量 + DllHandle = null; + + + + //加载DLL + LoadDll = function(){ + try{ + DllHandle = ..raw.loadDll("\USB2XXX.dll") + } + catch(err) + { + import win; + DllHandle = null; + win.msgboxTimeout("加载USB2LIN的DLL失败,请检查USB2XXX.dll和libusb-1.0.dll文件","错误",3000,); + } + if(DllHandle == null)return 1; + return 0; + } + + //刷新硬件 + FlashHw = function(){ + + if(DllHandle = null){ + //DLL为空,返回 + AvailableHW = {} + return 0; + } + var arr_temp = {int value[] = { length = 10/*可以使用变量*/ } }//类似动态数组 + HwNum = DllHandle.USB_ScanDevice(arr_temp) + AvailableHW = {} + for(i=1;HwNum;1){ + var devtemp = {}; + devtemp.devnum = i; + devtemp.channel = 1; + devtemp.hLINHW = arr_temp.value[i]; + devtemp.name = "dev-" + i + ":" + tostring(arr_temp.value[i],16); + ..table.push(AvailableHW,devtemp); + } + return HwNum; //返回有效硬件数 + } + + //获取设备信息 + GetDevInfo = function(index){ + if(index > HwNum) + { //如果序号大于最大硬件数 + return 0; + } + DllHandle.USB_OpenDevice(AvailableHW[index].hLINHW); + var DeviceInfo = ..usb2canfd.DEVICE_INFO(); + var funcstr = ..raw.buffer(100); + + var ret = DllHandle.DEV_GetDeviceInfo(AvailableHW[index].hLINHW,DeviceInfo,funcstr); + + return ret,DeviceInfo,funcstr; + } + + //获取设备信息 + GetNowInfo = function(){ + if(Hwconnected == null){ + return 0; + } + //DllHandle.USB_OpenDevice(Hwconnected); + var DeviceInfo = ..usb2canfd.DEVICE_INFO(); + var funcstr = ..raw.buffer(100); + + var ret = DllHandle.DEV_GetDeviceInfo(Hwconnected,DeviceInfo,funcstr); + + return ret,DeviceInfo,funcstr; + } + + //获取有效硬件 + GetAvailableHW = function(){ + return AvailableHW; + } + + SetFilter = function(index){ + CANFilter = ..usb2canfd.CAN_FILTER_CONFIG(); + CANFilter.FilterIndex = 0; + CANFilter.Enable = 1; + CANFilter.ExtFrame = 0; //需要过滤接收的帧为标准帧 + CANFilter.FilterMode = 1;//标识符列表模式 + CANFilter.ID_IDE = 0; //接收到的数据帧IDE必须为1,也就是必须为扩展帧数据 + CANFilter.ID_RTR = 0; //接收到的帧类型必须为数据帧 + CANFilter.ID_Std_Ext = 0x620;//接收到的帧ID必须等于CANFilter.ID_Std_Ext设置的值 + var ret = DllHandle.CAN_Filter_Init(AvailableHW[index].hLINHW,0,CANFilter); + + CANFilter.FilterIndex = 1; + CANFilter.ID_Std_Ext = 0x610; + var ret = DllHandle.CAN_Filter_Init(AvailableHW[index].hLINHW,0,CANFilter); + + + for(i=2;13;1){ + CANFilter.FilterIndex = i; + CANFilter.Enable = 0; + DllHandle.CAN_Filter_Init(AvailableHW[index].hLINHW,0,CANFilter); + } + + } + + //打开设备,包括初始化通道 + OpenDevice = function(index,channel,canfd){ + if(index > HwNum) + { //如果序号大于最大硬件数 + return 0; + } + import console; + var ret = DllHandle.USB_OpenDevice(AvailableHW[index].hLINHW) + //canfd = true; + if(canfd == true){ + var canconfig = ..usb2canfd.CANFD_INIT_CONFIG(); + + canconfig.Mode = 0; //0-正常模式,1-自发自收模式 + canconfig.ISOCRCEnable = 0;//0-禁止ISO CRC,1-使能ISO CRC + canconfig.RetrySend = 1;//0-禁止重发,1-无限制重发 + canconfig.ResEnable = 1;//0-不接入内部120欧终端电阻,1-接入内部120欧终端电阻 + //波特率参数可以用TCANLINPro软件里面的波特率计算工具计算 + //仲裁段波特率参数,波特率=40M/NBT_BRP*(1+NBT_SEG1+NBT_SEG2) + canconfig.NBT_BRP = 1; //参数来自官方上位机,默认500K + canconfig.NBT_SEG1 = 59; + canconfig.NBT_SEG2 = 20; + canconfig.NBT_SJW = 2; + //数据段波特率参数,波特率=40M/DBT_BRP*(1+DBT_SEG1+DBT_SEG2) + canconfig.DBT_BRP = 2; //参数来自官方上位机,默认500K + canconfig.DBT_SEG1 = 29; + canconfig.DBT_SEG2 = 10; + canconfig.DBT_SJW = 2; + + ret = DllHandle.CANFD_Init(AvailableHW[index].hLINHW,channel,canconfig); + } + else { + var canconfig = ..usb2canfd.CAN_INIT_CONFIG(); + + canconfig.CAN_Mode = 0x80;//0-正常模式 1-环回模式 0x80终端电阻 + + canconfig.CAN_ABOM = 0;//禁止自动离线 + canconfig.CAN_NART = 0;//禁止报文重传 + canconfig.CAN_RFLM = 0;//FIFO满之后覆盖旧报文 + canconfig.CAN_TXFP = 1;//发送请求决定发送顺序 + //配置波特率,波特率 = 42M/(BRP*(SJW+BS1+BS2)) + canconfig.CAN_BRP = 4; + canconfig.CAN_BS1 = 15; + canconfig.CAN_BS2 = 5; + canconfig.CAN_SJW = 2; + ret = DllHandle.CAN_Init(AvailableHW[index].hLINHW,channel,canconfig); + //console.log("init ret = " + ret); + this.SetFilter(index); + } + + canfd_connected = canfd; + if(ret == 0){//调用成功 + Hwconnected = AvailableHW[index].hLINHW; + Chconntected = channel; + + } + else { + //Hwconnected = null + Chconntected = null; + } + + return ret; + } + + //关闭设备 + CloseDevice = function(){ + if(Hwconnected == null){ + return; + } + try{ + DllHandle.USB_CloseDevice(Hwconnected); + Hwconnected = null; + } + } + + //是否连接 + isConnected = function(){ + if(Hwconnected == null){ + return false; + } + else { + return true; + } + + } + + + //发送报文 + SendMsg = function(id,data){ + if(Hwconnected == null){//未连接 + return 0; + } + if(#data == 0 || #data>8){//长度不对 + return 0; + } + //console.log("发送报文") + var ret = 0; + if(canfd_connected == true){ + var msg = ..usb2canfd.CANFD_MSG(); + msg.Flags = 0; + if(id <= 0x7ff){ + msg.ID = id; //| (1<<31);//扩展帧 + } + else { + msg.ID = id | (1<<31);//扩展帧 + } + + + msg.DLC = #data; + msg.Data = data; + + //console.dumpJson(msg); + //console.log("Hwconnected = " + Hwconnected); + //console.log("Chconntected = " + Chconntected); + ret = DllHandle.CANFD_SendMsg(Hwconnected,Chconntected,msg,1); + } + else { + var msg = ..usb2canfd.CAN_MSG(); + //msg.Flags = 0; + if(id <= 0x7ff){ + msg.ID = id; //| (1<<31);//扩展帧 + } + else { + msg.ID = id | (1<<31);//扩展帧 + } + msg.ExternFlag = 0; + msg.RemoteFlag = 0; + msg.DataLen = #data; + msg.Data = data; + //console.log("发送报文") + ret = DllHandle.CAN_SendMsg(Hwconnected,Chconntected,msg,1); + //console.log("ret = " + ret); + } + + + return ret; + } + + //从设备缓冲区获取报文 + GetMsg = function(){ + var ret = 0; + var retdata = {}; + if(canfd_connected == true){ + //CANFD + do{ + var msgbuf = ..usb2canfd.CANFD_MSG(); + ret = DllHandle.CANFD_GetMsg(Hwconnected,CANIndex,msgbuf,1); + if(ret == 1){ + var data = {}; + for(i=1;msgbuf.DLC;1){ + data[i] = msgbuf.Data[i]; + } + var msg = {"id"=msgbuf.ID;"data"=data;};// + ..table.push(retdata,msg); + } + }while(ret > 0) + } + else { + //CAN + do{ + //raw.convertArray(raw.sizeof(..usb2canfd.CAN_MSG()) + var msgbuf = {}; + for(i=1;10;1){ + //msgbuf.push(new ..usb2canfd.CAN_MS()) + var temp = ..usb2canfd.CAN_MSG() + ..table.push(msgbuf,temp); + } + + //var msgbuf = ..raw.toarray(10,"struct",..usb2canfd.CAN_MS); + ret = DllHandle.CAN_GetMsgWithSize(Hwconnected,CANIndex,msgbuf[1],1); + if(ret == 1){ + var data = {}; + for(i=1;msgbuf[1].DataLen;1){ + data[i] = msgbuf[1].Data[i]; + } + var msg = {"id"=msgbuf[1].ID;"data"=data;};// + ..table.push(retdata,msg); + } + }while(ret > 0) + } + + + return retdata; + } + + GetDiag = function(data){ + if(#data<2){ + return 0,1; + } + var UDSAddr = ..usb2canfd.CAN_UDS_ADDR() + UDSAddr.Flag = 1;//使用扩展帧 + UDSAddr.AddrFormats = 0; + UDSAddr.ReqID = 0x18dadff1; + UDSAddr.ResID = 0x18daf1df; + UDSAddr.MaxDLC = 8; + var req_data = ..raw.buffer(#data); + for(i=1;#data;1){ + req_data[i] = data[i]; + } + ret = DllHandle.CAN_UDS_Request(Hwconnected,CANIndex,UDSAddr,req_data,#data); + var res_data = ..raw.buffer(4096); + //sleep(10); + var ret = DllHandle.CAN_UDS_Response(Hwconnected,CANIndex,UDSAddr,res_data,1000); + + return ret,2,res_data; + } + + SetPower = function(state){ + var ret = DllHandle.LIN_EX_CtrlPowerOut(Hwconnected,state); + return ret; + } + + GetPower = function(){ + var buf = ..raw.buffer(10); + var ret = DllHandle.LIN_EX_GetVbatValue(Hwconnected,buf); + + return ret,buf; + } + + + + + } +} + + +/**intellisense() +usb2canfd = 图莫斯CANFD驱动 +usb2canfd.USB2CANHW = USB2CAN库 +usb2canfd.USB2CANHW() = 创建设备对象\n!usb2canfdUSB2CANHW. +!usb2canfdUSB2CANHW.LoadDll() = 加载DLL +!usb2canfdUSB2CANHW.FlashHw() = 刷新硬件 +!usb2canfdUSB2CANHW.GetDevInfo() = 获取设备信息 +!usb2canfdUSB2CANHW.GetAvailableHW() = 获取有效设备,需要先FlashHw()刷新 +!usb2canfdUSB2CANHW.OpenDevice() = 打开设备 +!usb2canfdUSB2CANHW.CloseDevice() = 关闭设备 +!usb2canfdUSB2CANHW.isConnected() = 是否已连接 +!usb2canfdUSB2CANHW.SendMsg() = 发送报文 +!usb2canfdUSB2CANHW.GetMsg() = 接收报文 +end intellisense**/ + diff --git a/CAN_Bootloader/libusb-1.0.dll b/CAN_Bootloader/libusb-1.0.dll new file mode 100644 index 0000000..5377cb4 Binary files /dev/null and b/CAN_Bootloader/libusb-1.0.dll differ diff --git a/CAN_Bootloader/main.aardio b/CAN_Bootloader/main.aardio new file mode 100644 index 0000000..d908dca --- /dev/null +++ b/CAN_Bootloader/main.aardio @@ -0,0 +1,266 @@ +import win.ui; +/*DSG{{*/ +mainForm = win.form(text="CAN_Bootloader";right=599;bottom=465;border="dialog frame";max=false) +mainForm.add( +btnConnect={cls="button";text="连接";left=204;top=64;right=289;bottom=90;z=4}; +btnFlash={cls="button";text="开始刷写";left=36;top=329;right=135;bottom=357;z=9}; +btnFresh={cls="button";text="刷新";left=204;top=28;right=288;bottom=54;z=2}; +btnOpen={cls="button";text="打开文件";left=36;top=296;right=135;bottom=324;z=8}; +btnOpenFlashdrv={cls="button";text="打开FlashDriver";left=148;top=296;right=247;bottom=324;z=24}; +btnReadF180={cls="button";text="读取boot版本";left=36;top=429;right=135;bottom=457;z=19}; +btnReadF186={cls="button";text="读取当前会话";left=36;top=363;right=135;bottom=391;z=13}; +btnReadF187={cls="button";text="读取型号";left=148;top=429;right=247;bottom=457;z=20}; +btnReadF191={cls="button";text="读取编译日期";left=148;top=362;right=247;bottom=390;z=25}; +btnReadHw={cls="button";text="读取硬件版本号";left=148;top=395;right=247;bottom=423;z=12}; +btnReadSw={cls="button";text="读取软件版本号";left=36;top=396;right=135;bottom=424;z=10}; +btnTest={cls="button";text="停止";left=148;top=330;right=247;bottom=358;z=11}; +cbbChannel={cls="combobox";left=58;top=64;right=191;bottom=90;edge=1;items={};mode="dropdown";z=3}; +cbbDev={cls="combobox";left=58;top=27;right=191;bottom=53;edge=1;items={};mode="dropdown";z=1}; +checkbox={cls="checkbox";text="CANFD设备";left=151;top=101;right=248;bottom=120;checked=1;z=21}; +edFile={cls="richedit";left=8;top=131;right=288;bottom=187;border=1;disabled=1;edge=1;multiline=1;wrap=1;z=14}; +edFile2={cls="richedit";left=8;top=202;right=288;bottom=258;border=1;disabled=1;edge=1;multiline=1;wrap=1;z=22}; +edit={cls="edit";left=294;top=19;right=596;bottom=401;autovscroll=false;edge=1;multiline=1;vscroll=1;z=5}; +progress={cls="progress";left=296;top=436;right=596;bottom=464;edge=1;max=100;min=0;z=15}; +radiobutton={cls="radiobutton";text="左侧";left=45;top=268;right=121;bottom=288;checked=1;group=1;z=26}; +radiobutton2={cls="radiobutton";text="右侧";left=163;top=268;right=242;bottom=287;z=27}; +static={cls="static";text="设备";left=1;top=28;right=61;bottom=52;align="center";center=1;transparent=1;z=6}; +static2={cls="static";text="通道";left=1;top=66;right=61;bottom=90;align="center";center=1;transparent=1;z=7}; +static3={cls="static";text="刷写进度";left=296;top=409;right=349;bottom=429;transparent=1;z=16}; +static4={cls="static";text="烧录APP";left=13;top=108;right=85;bottom=132;center=1;transparent=1;z=17}; +static5={cls="static";text="V0.2_20241219";left=451;top=1;right=595;bottom=17;align="right";center=1;transparent=1;z=18}; +static6={cls="static";text="FlashDriver";left=13;top=184;right=101;bottom=207;transparent=1;z=23} +) +/*}}*/ + +import win; +import usb2canfd; +import win.timer; + +var boot_count = 0;//boot时间计数器 +var bootstate = false;//boot状态标志 +var starttime = time.now(); +timer_bootcount = win.timer(mainForm,100); +timer_bootcount.onTimer = function(){//boot时间定时器,100ms间隔 + boot_count++; +} + +Display = function(str){//显示日志 + var nowtime = time(); + nowtime.format="%H:%M:%S"; + mainForm.edit.print(tostring(nowtime) + " " + str); +} +//遍历目录 +import console; + +/* +import fsys.fileInfo; +info = fsys.fileInfo("C:\Users\fcb19\Desktop\dll\libusb-1.0.dll"); +console.log(info.writeTime); +execute("pause") +raw.loadDll("C:\Users\fcb19\Desktop\dll\libusb-1.0.dll"); +*/ +CANHw = usb2canfd.USB2CANHW();//尝试加载CAN dll +var ret = CANHw.LoadDll(); +if(ret == 0){ + Display("DLL加载成功"); +} +else { + //Display("DLL加载失败"); + return ; +} + + +//初始化界面 +mainForm.cbbChannel.add("通道1"); +mainForm.cbbChannel.add("通道2"); +mainForm.cbbChannel.selIndex = 1 + + +//刷新按键 +mainForm.btnFresh.oncommand = function(id,event){ + mainForm.cbbDev.clear();//清空下拉框,防止反复刷新叠加 + var hwnum = CANHw.FlashHw();//获取硬件数量 + if(hwnum == 0){ + mainForm.cbbDev.text = "未找到硬件" + } + else { + var allhw = CANHw.GetAvailableHW(); + for(i=1;#allhw;1){ + mainForm.cbbDev.add(allhw[i].name); + } + } + mainForm.cbbDev.selIndex = 1 + ::PostThreadMessage(thrdId,100,0,0)//自定义消息 +} + +mainForm.btnConnect.oncommand = function(id,event){ + var canfd_check = mainForm.checkbox.checked?0x80:0x00; + ::PostThreadMessage(thrdId,101,mainForm.cbbDev.selIndex,(mainForm.cbbChannel.selIndex - 1)|canfd_check)//自定义消息 + /* + var ret = CANHw.OpenDevice(mainForm.cbbDev.selIndex,mainForm.cbbChannel.selIndex - 1);//通道为0和1 + if(ret == 0){ + Display("连接成功"); + } + else { + Display("连接失败"); + } + */ +} + +//CAN通讯线程 +import thread.command; +var listener = thread.command(); +var flag_connected=0; +listener.$Display = function(str){ + Display(str); +} +listener.$ShowPath = function(str){ + mainForm.edFile.text = str; +} +listener.$ShowFlashDrvPath = function(str){ + mainForm.edFile2.text = str; +} +listener.$SetProgress = function(pos){ + if(pos >= 0 && pos <= 100){ + mainForm.progress.pos = pos; + } +} + +listener.$Connected = function(){ + mainForm.btnConnect.disabled = true; + mainForm.btnFresh.disabled = true; + mainForm.cbbDev.disabled = true; + mainForm.cbbChannel.disabled = true; + flag_connected = 1; +} +listener.$SendEnd = function(isSuccess){ + //timer_bootcount.disable(); + var usetime = time.now().diffsecond(starttime); + bootstate = false; + if(isSuccess == true){ + Display("刷写成功,用时 " + usetime + " S") + } +} + +//线程函数 +var CanThread = function(){ + + //线程函数内部要添加自已的import语句 + import win; + import console; + //console.log("线程开始运行") + loadcodex("\user\CanThread.aardio");//加载线程程序 + //在子线程启动消息循环 + win.loopMessage(FuncLoopMsg) +} +DiagReadDID = function(did){ + ::PostThreadMessage(thrdId,110,did,0)//自定义消息 +} +var Diag10Req = function(num){ + ::PostThreadMessage(thrdId,111,num,0)//自定义消息 +} +var DiagBootReq = function(){ + ::PostThreadMessage(thrdId,102,0,0)//自定义消息 +} +var DiagStopReq = function(){ + ::PostThreadMessage(thrdId,103,0,0)//自定义消息 +} + +mainForm.btnReadSw.oncommand = function(id,event){ + DiagReadDID(0xF195); +} + + +mainForm.btnReadHw.oncommand = function(id,event){ + DiagReadDID(0xF193); +} + +mainForm.btnReadF186.oncommand = function(id,event){ + DiagReadDID(0xF186); +} + +mainForm.btnTest.oncommand = function(id,event){ + DiagStopReq(); +} + +mainForm.btnFlash.oncommand = function(id,event){ + if(io.exist(mainForm.edFile.text) == null){ + Display("请打开烧写文件"); + return; + } + if(io.exist(mainForm.edFile2.text) == null){ + Display("请打开flashdriver文件"); + return; + } + if(flag_connected == 0){ + Display("请连接设备"); + return; + } + if(bootstate == true){ + return ; + } + bootstate = true; + mainForm.edit.text = ""; + Display("开始刷写流程"); + starttime = time.now(); + //timer_bootcount.enable(); + boot_count = 0; + DiagBootReq(); + + +} + +mainForm.btnOpen.oncommand = function(id,event){ + ::PostThreadMessage(thrdId,104,2,0)//自定义消息-打开文件 +} + +//程序关闭 +mainForm.onClose = function(hwnd,message,wParam,lParam){ + if(thrdId != null){ + ::PostThreadMessage(thrdId,105,0,0)//自定义消息 + thread.waitClose(thrdHandle); + } + + + //PLinHw.isConnected()///待完善 + //console.print("线程已关闭") + //console.pause() +} + +mainForm.btnReadF180.oncommand = function(id,event){ + DiagReadDID(0xF180); +} + +mainForm.btnReadF187.oncommand = function(id,event){ + DiagReadDID(0xF187); +} + +mainForm.btnOpenFlashdrv.oncommand = function(id,event){ + ::PostThreadMessage(thrdId,104,1,0)//自定义消息-打开flashdriver +} + + + +thrdHandle,thrdId = thread.create( CanThread ) + + +mainForm.onClose = function(hwnd,message,wParam,lParam){ + raw.closehandle(thrdHandle); + //frmChild.close(); +} + +mainForm.btnReadF191.oncommand = function(id,event){ + DiagReadDID(0xF191); +} + +mainForm.radiobutton.oncommand = function(id,event){ + ::PostThreadMessage(thrdId,121,0x731,0x7b1)//自定义消息-修改ID +} + +mainForm.radiobutton2.oncommand = function(id,event){ + ::PostThreadMessage(thrdId,121,0x732,0x7b2)//自定义消息-修改ID +} + +mainForm.show(); +::PostThreadMessage(thrdId,121,0x731,0x7b1)//自定义消息-修改ID +return win.loopMessage(); \ No newline at end of file diff --git a/CAN_Bootloader/res/icon.ico b/CAN_Bootloader/res/icon.ico new file mode 100644 index 0000000..dfbb71b Binary files /dev/null and b/CAN_Bootloader/res/icon.ico differ diff --git a/CAN_Bootloader/user/CanThread.aardio b/CAN_Bootloader/user/CanThread.aardio new file mode 100644 index 0000000..205f083 --- /dev/null +++ b/CAN_Bootloader/user/CanThread.aardio @@ -0,0 +1,328 @@ +import usb2canfd; +import thread.command; +import win.timer; +//初始化CAN句柄对象 +CANHw = usb2canfd.USB2CANHW(); +CANHw.LoadDll(); + +DiagReqID = 0x732;//0x18dadff1; +DiagRespID = 0x7B2;//0x18daf1df; +DiagGloableID = 0x7DF;//0x18DB33F1; +stopflag = 0; + +write2Etest = function(did){ + select(did) { + case 0xF010 { + var data = {1,2,3,4, 0,0,0,0, 0,0,0,0, 0,0,0,0,}; + FuncReq2E(did,data); + } + case 0xF101 { + var data = {1,2,3,4, 0,0,0,0, }; + FuncReq2E(did,data); + } + } +} + +//注册一个消息钩子函数 +FuncLoopMsg = function(msg){ + select(msg.message) { + case 100 {//刷新硬件 + FuncFreshHw(); + } + case 101 {//连接硬件 + //console.log("msg.wParam = " + msg.wParam); + //console.log("msg.lParam = " + msg.lParam); + FuncConnect(msg.wParam,msg.lParam); + } + case 102 {//开始boot + FuncStartBoot(); + } + case 103 {//停止boot + FuncStopBoot(); + } + case 104 {//打开s19文件 + if(msg.wParam == 1){ + FuncDisplay("打开FlashDriver"); + var ret = FuncOpenS19File(msg.wParam); + if(ret != null){ + thread.command.$ShowFlashDrvPath(ret); + var crc32 = FuncGetFlashCRC(1); + FuncDisplay("CRC = " ++ string.format("%X",crc32)); + } + } + else { + FuncDisplay("打开烧写文件"); + var ret = FuncOpenS19File(msg.wParam); + if(ret != null){ + thread.command.$ShowPath(ret); + var crc32 = FuncGetFlashCRC(2); + FuncDisplay("CRC = " ++ string.format("%X",crc32)); + } + } + + + } + case 105 {//停止boot + thread.stop(0); + } + case 110 {//readDID + FuncReadDID(msg.wParam); + } + case 111 { + FuncReq10(msg.wParam,msg.lParam); + } + case 112 { + FuncReq28(msg.wParam); + } + case 113 { + FuncReq85(msg.wParam); + } + case 114 { + FuncReq27(msg.wParam); + } + case 115 { + write2Etest(msg.wParam) + } + case 120 { + win.quitMessage() + } + case 121 { + SetDiagID(msg.wParam,msg.lParam); + } + else { + + } + } +} + +SetDiagID = function(reqid,respid){ + DiagReqID = reqid;//0x18dadff1; + DiagRespID = respid;//0x18daf1df; + var idstr = string.format("req=0x%x,resp=0x%x",DiagReqID,DiagRespID); + FuncDisplay(idstr); +} + + + +var delay_const = 100000; +DelayTest = function(){ + import time.performance; + var tk = time.performance.tick(); + for(i=1;1000000;1) + { + } + var tk2 = time.performance.tick(); + tk2 = tk2 - tk; + delay_const = math.ceil(1000000*(1/tk2)); + FuncDisplay(delay_const); + //console.log(delay_const); +} + + + +FuncFreshHw = function(){ + var hwnum = CANHw.FlashHw(); + if(hwnum == 0){ + //mainForm.cbbDev.text = "未找到硬件" + } + else { + FuncDisplay("找到硬件") + } +} + +FuncConnect = function(dev,chn){ + var canfd = (chn&0x80)==0x80?true:false; + var ret = CANHw.OpenDevice(dev,chn&0x7f,canfd); + if(ret == 0){ + FuncDisplay("连接成功"); + thread.command.$Connected(); + } + else { + FuncDisplay("连接失败"); + } +} + +FuncDisplay = function(str){ + thread.command.$Display(str);//"线程" + +} + + +loadcodex("\user\Diag10code.aardio"); +loadcodex("\user\Diag11code.aardio"); +loadcodex("\user\Diag22code.aardio"); +loadcodex("\user\Diag27code.aardio"); +loadcodex("\user\Diag2Ecode.aardio"); +loadcodex("\user\Diag28code.aardio"); +loadcodex("\user\Diag31code.aardio"); +loadcodex("\user\Diag34code.aardio"); +loadcodex("\user\Diag36code.aardio"); +loadcodex("\user\Diag37code.aardio"); +loadcodex("\user\Diag7Fcode.aardio"); +loadcodex("\user\Diag85code.aardio"); + +loadcodex("\user\DiagBootcode.aardio"); +loadcodex("\user\S19Decode.aardio"); + + +RespState = 0; + +FuncDiagPro = function(diagmsg){ + + select(diagmsg.sid) { + case 0x50 { + FuncDiag10Pro(table.slice(diagmsg.data,1,diagmsg.len)) + } + case 0x62 { + FuncDiag22Pro(table.slice(diagmsg.data,1,diagmsg.len)) + } + case 0x67 { + FuncDiag27Pro(table.slice(diagmsg.data,1,diagmsg.len)) + } + case 0x74 { + FuncDiag34Pro(table.slice(diagmsg.data,1,diagmsg.len)) + } + case 0x71 { + FuncDiag31Pro(table.slice(diagmsg.data,1,diagmsg.len)) + } + case 0x76 { + FuncDiag36Pro(table.slice(diagmsg.data,1,diagmsg.len)) + } + case 0x68 { + FuncDiag28Pro(table.slice(diagmsg.data,1,diagmsg.len)) + } + case 0xC5 { + FuncDiag85Pro(table.slice(diagmsg.data,1,diagmsg.len)) + } + case 0x7F { + FuncDiag7FPro(table.slice(diagmsg.data,1,diagmsg.len)) + } + case 0x6E { + FuncDiag2EPro(table.slice(diagmsg.data,1,diagmsg.len)) + } + else { + } + } + RespState = diagmsg.sid; +} + + + + + + + +FuncStartBoot = function(){ + FuncInitBootState(); + boottimer.enable(); + + FuncDisplay("开始刷写"); + stopflag = 0; +} + +var delay = function(w){ + var delay_time = w*delay_const; + for(i=1;delay_time;1) + { + } + +} + +var PackNext = 0x21; +var Packdata = {}; +var PackID = 0; +var FuncSendPackage = function(){ + while(#Packdata > 0) + { + //sleep(1); + delay(1); + var data = {PackNext,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC}; + var max = #Packdata > 7 ? 7 : #Packdata; + for(i=1;max;1){ + data[i+1] = table.remove(Packdata); + } + //sleep(0.3); + CANHw.SendMsg(PackID,data); + + PackNext += 1; + if(PackNext > 0x2f){ + PackNext = 0x20; + } + } + +} +FuncPushPackage = function(ID,data){ + PackNext = 0x21; + Packdata = data; + PackID = ID; +} + + + +boottimer = win.timer(,10); +boottimer.onTimer = function(){ + if(CANHw.isConnected() == false){ + boottimer.disable(); + return; + } + FuncBootSeq(); +} + + +timer1 = win.timer(,1); +diagresp = {} +timer1.onTimer = function(){ + if(CANHw.isConnected() == false){ + return; + } + ret = CANHw.GetMsg(); + + for(i=1;#ret;1){ + //console.log("id = " + tostring(ret[i].id)) + if(ret[i].id & 0x7FFFFFFF == DiagRespID){ + if(ret[i].data[1] == 0x10){//首帧 + var data = {0x30,0x00,0x14,0x00,0,0,0,0}; + CANHw.SendMsg(DiagReqID,data); + diagresp["sid"] = ret[i].data[3]; + diagresp["len"] = ret[i].data[2]-1; + diagresp["data"] = {}; + diagresp["next"] = 0x21; + table.append(diagresp["data"],table.slice(ret[i].data,4)); + } + elseif(ret[i].data[1] <= 0x07){//单帧 + //console.dumpJson() + diagresp["sid"] = ret[i].data[2]; + diagresp["len"] = ret[i].data[1]-1; + diagresp["data"] = table.slice(ret[i].data,3); + FuncDiagPro(diagresp); + } + elseif(ret[i].data[1] >= 0x21 && ret[i].data[1] <= 0x2f){ + if(ret[i].data[1] == diagresp["next"]){//多帧 + diagresp["next"] += 1; + if(diagresp["next"] >= 0x2F){ + diagresp["next"] = 0x20; + } + table.append(diagresp["data"],table.slice(ret[i].data,2)); + if(#diagresp["data"] >= diagresp["len"]){ + FuncDiagPro(diagresp); + } + } + } + elseif(ret[i].data[1] == 0x30){// + FuncSendPackage(); + } + } + else { + //console.varDump(ret[i].id); + //显示报文 + } + + } + +} + +timer1.enable(); +FuncDisplay("正在运行"); + + +DelayTest(); + diff --git a/CAN_Bootloader/user/Diag10code.aardio b/CAN_Bootloader/user/Diag10code.aardio new file mode 100644 index 0000000..a266389 --- /dev/null +++ b/CAN_Bootloader/user/Diag10code.aardio @@ -0,0 +1,33 @@ + +//发送 +FuncReq10 = function(Addr,num){ + if(num >= 1 && num <= 3){ + var data = {0x02,0x10,num,0,0,0,0,0}; + if(Addr == true){ + CANHw.SendMsg(DiagGloableID,data); + } + else { + CANHw.SendMsg(DiagReqID,data); + } + + + } + +} +//接收 +FuncDiag10Pro = function(data){ + //console.dumpJson(data); + select(data[1]) { + case 1 { + FuncDisplay("进入默认会话成功") + } + case 2 { + FuncDisplay("进入编程会话成功") + } + case 3 { + FuncDisplay("进入扩展会话成功") + } + else { + } + } +} diff --git a/CAN_Bootloader/user/Diag11code.aardio b/CAN_Bootloader/user/Diag11code.aardio new file mode 100644 index 0000000..6804389 --- /dev/null +++ b/CAN_Bootloader/user/Diag11code.aardio @@ -0,0 +1,9 @@ +//发送 +FuncReq11 = function(num){ + var txdata = {0x2,0x11,num,0x00,0x00,0x00,0x00,0x00}; + CANHw.SendMsg(DiagReqID,txdata); +} +//接收 +FuncDiag11Pro = function(data){ + FuncDisplay("复位成功") +} \ No newline at end of file diff --git a/CAN_Bootloader/user/Diag22code.aardio b/CAN_Bootloader/user/Diag22code.aardio new file mode 100644 index 0000000..f10eb74 --- /dev/null +++ b/CAN_Bootloader/user/Diag22code.aardio @@ -0,0 +1,75 @@ +var diag22state = 0; +//发送 +FuncReadDID = function(did){ + if(CANHw.isConnected() == false){ + return; + } + var data = {0x03,0x22,did>>8,did&0xff,0,0,0,0}; + var ret = CANHw.SendMsg(DiagReqID,data); + diag22state = 1; + //console.log("did = " + tostring(did,16)); + //console.log("ret = " + ret); + //FuncDisplay("did = " + tostring(did,16)); +} +g22data = {}; +//接收 +FuncDiag22Pro = function(data){ + //console.log("诊断22服务") + if(#data < 3){ + return; + } + var did = (data[1]<<8) + data[2]; + select(did) { + case 0xF180 { + FuncDisplay("BOOT版本号"); + FuncDisplay(string.str(string.pack(table.slice(data,3)))); + + } + case 0xF186 { + FuncDisplay("当前会话: " + data[3]); + } + case 0xF193 { + FuncDisplay("硬件版本号"); + FuncDisplay(string.str(string.pack(table.slice(data,3)))); + g22data["F193"] = string.str(string.pack(table.slice(data,3))); + } + case 0xF195 { + FuncDisplay("软件版本号"); + FuncDisplay(string.str(string.pack(table.slice(data,3)))); + g22data["F195"] = string.str(string.pack(table.slice(data,3))); + } + case 0xF191 { + FuncDisplay("编译时间"); + FuncDisplay(string.str(string.pack(table.slice(data,3)))); + } + case 0xF187 { + FuncDisplay("ECU系统名称"); + FuncDisplay(string.str(string.pack(table.slice(data,3)))); + g22data["F187"] = string.str(string.pack(table.slice(data,3))); + + } + case 0xF198 { + FuncDisplay("repair_shopcode"); + FuncDisplay(string.str(string.pack(table.slice(data,3)))); + } + case 0xF199 { + FuncDisplay("installation_date"); + FuncDisplay(string.format("%x%X%x%x",data[3],data[4],data[5],data[6])); + } + + case 0xF18A { + FuncDisplay("系统供应商公司名称代码"); + FuncDisplay(string.pack(table.slice(data,3))); + + } + case 0xF197 { + FuncDisplay("ECU 系统名称"); + FuncDisplay(string.pack(table.slice(data,3))); + + } + else { + FuncDisplay("未知DID - " + tostring(did,16)); + } + } + +} \ No newline at end of file diff --git a/CAN_Bootloader/user/Diag27code.aardio b/CAN_Bootloader/user/Diag27code.aardio new file mode 100644 index 0000000..66360ea --- /dev/null +++ b/CAN_Bootloader/user/Diag27code.aardio @@ -0,0 +1,78 @@ + +var SecuretySeed = {0,0,0,0,}; +var SecuretyKey = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +var lockstate = 0; +//发送 +FuncReq27 = function(num,key){ + if(num >= 1 && num <= 0x1C){ + if(key == null){ + var data = {0x02,0x27,num,0,0,0,0,0}; + CANHw.SendMsg(DiagReqID,data); + } + else { + if(#key > 4){ + var data = {0x10,0X12,0x27,num,key[1],key[2],key[3],key[4]}; + CANHw.SendMsg(DiagReqID,data); + + FuncPushPackage(DiagReqID,table.slice(key,5)); + } + else { + var data = {0x06,0x27,num,key[1],key[2],key[3],key[4],0x00}; + CANHw.SendMsg(DiagReqID,data); + } + + } + } + else { + FuncDisplay("27长度错误"); + } + +} + +//loadcodex("\user\securety.aardio"); +loadcodex("\user\GeelySecurety.aardio"); +//接收 +FuncDiag27Pro = function(data){ + //console.dumpJson(data); + select(data[1]) { + case 1,3,5,7,9,11,0x11 { + var str = "收到种子"; + for(i=1;4;1){ + SecuretySeed[i] = data[i+1]; + str += " " + tostring(SecuretySeed[i],16); + lockstate = 1; + } + FuncDisplay(str) + SecuretyKey = securetyKeyCalc(SecuretySeed,data[1]); + if(#SecuretyKey >= 4){ + FuncReq27(data[1]+1,SecuretyKey); + var str = "计算密钥-"; + for(i=1;4;1){ + str += " " + tostring(SecuretyKey[i],16); + } + FuncDisplay(str); + } + else { + FuncDisplay("计算失败"); + } + + } + case 2,4,6,8,10,12,0x12 { + FuncDisplay("解锁成功"); + lockstate = 2; + } + else { + FuncDisplay("27服务未知子服务"); + } + } +} + +FuncDiag27GetState = function(){ + if(lockstate == 2){ + return 0; + } + else { + return 1; + } + +} diff --git a/CAN_Bootloader/user/Diag28code.aardio b/CAN_Bootloader/user/Diag28code.aardio new file mode 100644 index 0000000..a5a6d54 --- /dev/null +++ b/CAN_Bootloader/user/Diag28code.aardio @@ -0,0 +1,27 @@ + +//发送 +FuncReq28 = function(num1,num2){ + var txdata = {0x03,0x28,num1,num2,0,0,0,0}; + var ret = CANHw.SendMsg(DiagGloableID,txdata); + +} +//接收 +FuncDiag28Pro = function(data){ + //console.dumpJson(data); + select(data[1]) { + case 0 { + FuncDisplay("使能接收发送") + } + case 1 { + FuncDisplay("使能接收,禁止发送") + } + case 2 { + FuncDisplay("禁止接收,使能发送") + } + case 3 { + FuncDisplay("禁止接收发送") + } + else { + } + } +} \ No newline at end of file diff --git a/CAN_Bootloader/user/Diag2Ecode.aardio b/CAN_Bootloader/user/Diag2Ecode.aardio new file mode 100644 index 0000000..4dab962 --- /dev/null +++ b/CAN_Bootloader/user/Diag2Ecode.aardio @@ -0,0 +1,43 @@ + +var diag22state = 0; +//发送 +FuncDIDWriteStr = function(did,str){ + var data = {} + for(i=1;string.len(str);1){ + data[i] = string.unpack(str,i); + } + FuncReq2E(did,data) + return data; +} + +//FuncDIDWriteStr(0xf198,"0123456789abcdef1234"); + +FuncReq2E = function(did,data){ + if(CANHw.isConnected() == false){ + return; + } + if(#data > 4){ + //多帧 + var txdata = {0x10,3+#data,0x2E,did>>8,did&0xff,data[1],data[2],data[3]}; + CANHw.SendMsg(DiagReqID,txdata); + //等待发送 + FuncPushPackage(DiagReqID,table.slice(data,3)); + } + else { + var txdata = {3+#data,0x2E,did>>8,did&0xff,0,0,0,0}; + for(i=1;#data;1){ + txdata[4+i] = data[i]; + } + CANHw.SendMsg(DiagReqID,txdata); + + } + +} + + +//接收 +FuncDiag2EPro = function(data){ + var did = (data[1]<<8) + data[2]; + FuncDisplay("写入" + tostring(did,16) + "成功"); + +} \ No newline at end of file diff --git a/CAN_Bootloader/user/Diag31code.aardio b/CAN_Bootloader/user/Diag31code.aardio new file mode 100644 index 0000000..268368a --- /dev/null +++ b/CAN_Bootloader/user/Diag31code.aardio @@ -0,0 +1,82 @@ + +FuncReq31EraseFlash = function(addr,len){ + FuncDisplay("开始擦除数据") + var data = {0xfd,0x01,0x44,addr>>24,addr>>16,addr>>8,addr,len>>24,len>>16,len>>8,len}; + FuncReq31(data); +} + +FuncReq31CheckLogicBlock = function(crc){//(addr,len) + //var data = {0x02,0x02,0x44,addr>>24,addr>>16,addr>>8,addr,len>>24,len>>16,len>>8,len}; + var data = {0x02,0x02,crc>>24,crc>>16,crc>>8,crc}; + FuncReq31(data); +} +FuncReq31CheckPD = function(){//Programming Dependencies + var data = {0xFF,0x01}; + FuncReq31(data); +} +FuncReq31CheckFlash = function(){ + var data = {0x02,0x02}; + FuncReq31(data); +} + +FuncReq3103 = function(id){ + //停止例程 + var txdata = {0x04,0x31,0x03,id>>8,id&0xff,0x00,0x00,0x00}; + CANHw.SendMsg(DiagReqID,txdata); +} +FuncReq3101FD02 = function(){ + var txdata = {0x04,0x31,0x01,0xfd,0x02,0x00,0x00,0x00}; + CANHw.SendMsg(DiagReqID,txdata); +} +FuncReq3101FD03 = function(){ + var txdata = {0x04,0x31,0x01,0xfd,0x03,0x00,0x00,0x00}; + CANHw.SendMsg(DiagReqID,txdata); +} + + + +//发送 +FuncReq31 = function(data){ + if(#data > 5){//多帧 + var txdata = {0x10,2+#data,0x31,0x01,data[1],data[2],data[3],data[4]}; + CANHw.SendMsg(DiagReqID,txdata); + FuncPushPackage(DiagReqID,table.slice(data,5)); + } + else { + var txdata = {2+#data,0x31,0x01,0, 0,0,0,0}; + for(i=1;#data;1){ + txdata[3+i] = data[i]; + } + CANHw.SendMsg(DiagReqID,txdata); + } + + +} +//接收 +FuncDiag31Pro = function(data){ + //console.dumpJson(data); + if(#data < 3){ + //FuncDisplay("31长度错误"); + return; + } + var rid = (data[2]<<8) + data[3]; + select(rid) { + case 0xFD01 { + FuncDisplay("擦除成功") + } + case 0xFD02 { + FuncDisplay("flash driver校验成功") + } + case 0x0202 { + FuncDisplay("校验成功") + } + case 0xFF01 { + FuncDisplay("检查标志成功") + } + case 0xF518 { + FuncDisplay("数字签名错误") + } + else { + } + } +} \ No newline at end of file diff --git a/CAN_Bootloader/user/Diag34code.aardio b/CAN_Bootloader/user/Diag34code.aardio new file mode 100644 index 0000000..34e36b3 --- /dev/null +++ b/CAN_Bootloader/user/Diag34code.aardio @@ -0,0 +1,29 @@ + + +//发送 +FuncReq34 = function(addr,len){ + var data = {0x44,addr>>24,addr>>16,addr>>8,addr,len>>24,len>>16,len>>8,len}; + var txdata = {0x10,2+#data,0x34,0x00,data[1],data[2],data[3],data[4]}; + CANHw.SendMsg(DiagReqID,txdata); + FuncPushPackage(DiagReqID,table.slice(data,5)); + +} +var maxlen = 0; +//接收 +FuncDiag34Pro = function(data){ + //console.dumpJson(data); + FuncDisplay("请求下载成功") + maxlen = (data[2]<<8) + data[3]; + FuncDisplay("最大长度:" + maxlen); +} + +FuncGetSengLen = function(){ + if(maxlen>2){ + return maxlen-2; + } + else { + return 0; + } + + +} diff --git a/CAN_Bootloader/user/Diag36code.aardio b/CAN_Bootloader/user/Diag36code.aardio new file mode 100644 index 0000000..76acf43 --- /dev/null +++ b/CAN_Bootloader/user/Diag36code.aardio @@ -0,0 +1,66 @@ + +// +var blocknum=1; +var flag_sendend = false; +var flag_sending = false; +var alldata = {}; +FuncStartSendBlock = function(data){ + blocknum = 0x01; + flag_sendend = false; + flag_sending = true; + alldata = data; +} +FuncStopSendBlock = function(data){ + blocknum = 0x01; + flag_sendend = false; + flag_sending = false; +} +FuncGetSendStatus = function(){ + return flag_sendend; +} +FuncSendNextBlock = function(){ + var len = FuncGetSengLen(); + //sleep(500); + if(#alldata>len){ + FuncReq36(blocknum,table.slice(alldata,1,len)); + alldata = table.slice(alldata,len+1,) + } + else { + FuncReq36(blocknum,alldata); + alldata = {}; + flag_sendend = true; + } + blocknum += 1; +} + + +//发送 +FuncReq36 = function(num,data){ + len = #data+2; + if(len > 7){ + var txdata = {0x10+(len>>8),len&0xff,0x36,num&0xff,data[1],data[2],data[3],data[4]}; + CANHw.SendMsg(DiagReqID,txdata); + FuncPushPackage(DiagReqID,table.slice(data,5)); + } + else { + var txdata = {len,0x36,num&0xff,0, 0,0,0,0}; + for(i=1;#data;1){ + txdata[i+3] = data[i]; + } + + CANHw.SendMsg(DiagReqID,txdata); + } + +} +//接收 +FuncDiag36Pro = function(data){ + //console.dumpJson(data); + /* + if(data[1] == blocknum){ + blocknum += 1; + if(flag_sending == true){ + FuncSendNextBlock(); + } + } + */ +} \ No newline at end of file diff --git a/CAN_Bootloader/user/Diag37code.aardio b/CAN_Bootloader/user/Diag37code.aardio new file mode 100644 index 0000000..debfc9d --- /dev/null +++ b/CAN_Bootloader/user/Diag37code.aardio @@ -0,0 +1,9 @@ +//发送 +FuncReq37 = function(){ + var txdata = {0x1,0x37,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA}; + CANHw.SendMsg(DiagReqID,txdata); +} +//接收 +FuncDiag37Pro = function(data){ + +} \ No newline at end of file diff --git a/CAN_Bootloader/user/Diag7Fcode.aardio b/CAN_Bootloader/user/Diag7Fcode.aardio new file mode 100644 index 0000000..9ea414e --- /dev/null +++ b/CAN_Bootloader/user/Diag7Fcode.aardio @@ -0,0 +1,46 @@ + +var errSID=0,errNRC=0; +FuncGetNrc = function(){ + return errSID,errNRC; +} +FuncClrNrc = function(){ + //return errSID,errNRC; + errSID = 0; + errNRC = 0; +} +var TableToStr = function(data){ + if(data == null){ + return " "; + } + if(#data == 0){ + return " "; + } + var str = "data:" + for(i=1;#data;1){ + str += " " + str += tostring(data[i],16); + } + return str; + +} + +//接收 +FuncDiag7FPro = function(data){ + //console.dumpJson(data); + errSID = data[1]; + errNRC = data[2]; + select(errNRC) { + case 0x78 { + if(errSID != 0x36){ + FuncDisplay("服务正忙") + } + + } + else { + FuncDisplay("SID:" + tostring(errSID,16)) + FuncDisplay("错误 - NRC:" + tostring(errNRC,16)) + FuncDisplay(TableToStr(data)); + } + } + +} \ No newline at end of file diff --git a/CAN_Bootloader/user/Diag85code.aardio b/CAN_Bootloader/user/Diag85code.aardio new file mode 100644 index 0000000..73f156b --- /dev/null +++ b/CAN_Bootloader/user/Diag85code.aardio @@ -0,0 +1,27 @@ + +//发送 +FuncReq85 = function(num){ + if(num >= 1 && num <= 3){ + var data = {0x02,0x85,num,0,0,0,0,0}; + CANHw.SendMsg(DiagGloableID,data); + } + +} +//接收 +FuncDiag85Pro = function(data){ + //console.dumpJson(data); + select(data[1]) { + case 0x01 { + FuncDisplay("DTC开启") + } + case 0x02 { + FuncDisplay("DTC禁能") + } + case 3 { + FuncDisplay("DTC - 01") + } + else { + FuncDisplay("DTC - TDB") + } + } +} \ No newline at end of file diff --git a/CAN_Bootloader/user/DiagBootcode.aardio b/CAN_Bootloader/user/DiagBootcode.aardio new file mode 100644 index 0000000..42a4cdd --- /dev/null +++ b/CAN_Bootloader/user/DiagBootcode.aardio @@ -0,0 +1,521 @@ + + +var bootstate = 0; +var bootcount = 0; +var sendstate = 0; +FuncWait = function(sid){ + if(RespState == (sid + 0x40)){//正响应 + //bootcount = 0; + return 0; + } + errsid,errnrc = FuncGetNrc(); + FuncClrNrc(); + if(errsid == sid){ + if(errnrc == 0x78){//等待 + bootcount = 0; + return 0xff; + } + else { + FuncDisplay("刷写错误 步骤" + bootstate); + boottimer.disable(); + thread.command.$SendEnd(false); + return 1; //负响应 + } + + } + if(stopflag == 1){ + FuncDisplay("停止"); + boottimer.disable(); + thread.command.$SendEnd(false); + return 2;//停止命令 + } + bootcount += 1; + /* + if(bootcount > 20 && sid == 0x36){ + bootcount = 0; + return 0; + } + */ + if(bootcount >= 400){ + FuncDisplay("步骤" + bootstate + "超时 " + tostring(sid,16)); + thread.command.$SendEnd(false); + boottimer.disable(); + return 3;//超时 + } +} + +FuncStopBoot = function(){ + stopflag = 1; +} +FuncClearState = function(){ + RespState = 0; + bootcount = 0; + sendstate = 1; +} +FuncInitBootState = function(){ + bootstate = 0; + RespState = 0; + bootcount = 0; + sendstate = 0; +} + + + + +BCD_Conv = function(num){ + if(num > 99){ + return 0; + } + var ret = 0; + ret += math.floor(num/10) * 16; + ret += num%10; + return ret; +} + +var sendblockstate = 0; +var alldata = {}; +var blocknum = 1; +var alldata_blocknum = 0; +var block_sended = 0; +var sendFlashDriverState = 0; +var FuncSendBlockApp_sendflag = 0; +var nowid=0; +FuncSendBlockInit = function(id){ + var len = 0; + alldata = FuncGetAllData(id); + blocknum = 1; + if(alldata == null){ + FuncDisplay("错误:空数据"); + alldata_blocknum = 0; + sendblockstate = 0xff; + return 1; + } + for(i=1;#alldata;1){ + len += math.ceil(#alldata[i]["data"] / FuncGetSengLen()) + } + alldata_blocknum = len; + block_sended = 0; + sendblockstate = 0; + FuncSendBlockApp_sendflag = 0; + nowid = id; + //console.log("发送数据初始化") + return 0; +} +nextstate = function(val){ + if(val == 0){ + bootstate += 1; + sendstate = 0; + block_sended += 1; + } +} + +FuncSendBlockApp = function(){ + select(sendblockstate) { + case 0{ + if(FuncSendBlockApp_sendflag == 0){ + FuncReq34(alldata[blocknum]["address"],#alldata[blocknum]["data"]); + FuncSendBlockApp_sendflag = 1; + RespState = 0; + bootcount = 0; + } + else { + if(FuncWait(0x34) == 0){ + FuncSendBlockApp_sendflag = 0; + sendblockstate += 1; + } + } + + } + case 1 { + FuncStartSendBlock(alldata[blocknum]["data"]);//初始化 + FuncSendBlockApp_sendflag = 0; + sendblockstate += 1; + } + case 2 { + if(FuncSendBlockApp_sendflag == 0){ + FuncSendNextBlock(); + FuncSendBlockApp_sendflag = 1; + block_sended += 1; + RespState = 0; + bootcount = 0; + } + else { + if(FuncWait(0x36) == 0){ + FuncSendBlockApp_sendflag = 0; + if(FuncGetSendStatus() == true){//所有块发送完成 + sendblockstate += 1; + if(nowid == 1){ + sendblockstate += 1; + } + } + } + } + } + case 3 { + if(FuncSendBlockApp_sendflag == 0){ + FuncReq37(); + FuncSendBlockApp_sendflag = 1; + RespState = 0; + bootcount = 0; + } + else { + if(FuncWait(0x37) == 0){ + FuncSendBlockApp_sendflag = 0; + sendblockstate += 1; + } + } + } + else { + if(blocknum < #alldata){ + blocknum += 1; + sendblockstate = 0; + } + else { + //所有数据发送完成 + return 0; + } + + } + } + return 1; +} +FuncSendBlockFlashDriver = function(){ + select(sendFlashDriverState) { + case 0 { + } + case 1 { + } + case 2 { + } + case 3 { + } + else { + } + } +} + +var delaycount = 0; +//boot总流程 +var boottime = 0; +FuncBootSeq = function(){ + boottime++; + select(bootstate) { + case 0 { + boottime = 1; + if(sendstate == 0){ + //FuncSendBlockInit(0); + g22data = {}; + FuncReadDID(0xF187); + FuncClearState(); + } + else { + var ret = FuncWait(0x22); + if(g22data["F187"]!= null){ + if(g22data["F187"] == "RP-77B"){ + nextstate(0); + } + else { + FuncDisplay("型号错误"); + FuncStopBoot(); + thread.command.$SendEnd(false); + boottimer.disable(); + } + + + } + + } + } + case 1 { + if(sendstate == 0){ + FuncReadDID(0xF195);//读取软件版本 + FuncClearState(); + } + else { + var ret = FuncWait(0x22); + nextstate(ret); + } + } + case 2 { + if(sendstate == 0){ + FuncReadDID(0xF193);//读取硬件版本 + FuncClearState(); + } + else { + var ret = FuncWait(0x22); + if(g22data["F193"]!= null){ + if(g22data["F193"] == "HW01"){ + nextstate(0); + } + else { + FuncDisplay("硬件错误"); + FuncStopBoot(); + thread.command.$SendEnd(false); + boottimer.disable(); + } + + + } + } + } + case 3 { + if(sendstate == 0){ + FuncReq10(true,0x03);//进入扩展会话 + FuncClearState(); + } + else { + var ret = FuncWait(0x10); + nextstate(ret); + } + } + case 4 { + if(sendstate == 0){ + FuncReq85(0x02);//关闭DTC + FuncClearState(); + } + else { + var ret = FuncWait(0x85); + nextstate(ret); + } + } + case 5 { + if(sendstate == 0){ + FuncReq28(0x01,0x01);//禁止发送 + FuncClearState(); + } + else { + var ret = FuncWait(0x28); + nextstate(0); + } + } + case 6 { + if(sendstate == 0){ + FuncReq10(false,0x02);//进入编程会话 + FuncClearState(); + } + else { + var ret = FuncWait(0x10); + nextstate(ret); + } + } + case 7 { + if(sendstate == 0){//等待复位完成 + delaycount = 0; + FuncClearState(); + } + else { + delaycount += 1; + if(delaycount > 20){ + nextstate(0);//延时1S + } + + } + } + case 8 { + if(sendstate == 0){ + FuncReq27(0x09);//解密 + FuncClearState(); + } + else { + var ret = FuncWait(0x27); + nextstate(ret); + } + } + case 9 { + if(sendstate == 0){ + //FuncReq27(02);//发送key + FuncClearState(); + FuncDisplay("等待解锁"); + } + else { + //var ret = FuncWait(0x27); + var ret = FuncDiag27GetState(); + nextstate(ret); + } + } + case 10 { + if(sendstate == 0){ + FuncReq31EraseFlash(0x20005BF0,0x800); + FuncClearState(); + + } + else { + var ret = FuncWait(0x31); + nextstate(ret); + } + } + + case 11 { + if(sendstate == 0){//写入installation_date + FuncReq3103(0xFD01); + FuncClearState(); + } + else { + var ret = FuncWait(0x31); + nextstate(ret); + } + } + case 12 { + if(sendstate == 0){//发送数据 + FuncSendBlockInit(1); + FuncDisplay("开始发送FlashDrv数据"); + FuncClearState(); + } + else { + var ret = FuncSendBlockApp(); + nextstate(ret); + } + } + case 13 { + if(sendstate == 0){//CheckLogicBlock + //var crc = FuncGetFlashCRC(0); + //FuncReq31CheckLogicBlock(crc); + FuncReq3101FD02(); + FuncClearState(); + } + else { + var ret = FuncWait(0x31); + nextstate(ret); + } + } + case 14 { + if(sendstate == 0){// + FuncReq3103(0xFD02); + FuncClearState(); + } + else { + var ret = FuncWait(0x31); + nextstate(ret); + } + } + case 15 { + if(sendstate == 0){//CheckLogicBlock + FuncReq31EraseFlash(0x00010000,0x28000); + FuncClearState(); + } + else { + var ret = FuncWait(0x31); + nextstate(ret); + } + } + + case 16 { + if(sendstate == 0){//发送数据 + FuncSendBlockInit(2); + FuncDisplay("开始发送App数据"); + FuncClearState(); + } + else { + var ret = FuncSendBlockApp(); + nextstate(ret); + } + } + case 17 { + if(sendstate == 0){//CheckLogicBlock + FuncReq3101FD03(); + FuncClearState(); + } + else { + var ret = FuncWait(0x31); + nextstate(ret); + } + } + case 18 { + if(sendstate == 0){////Programming Dependencies + FuncReq3103(0xFD03); + FuncClearState(); + } + else { + var ret = FuncWait(0x31); + nextstate(ret); + } + } + case 19 { + if(sendstate == 0){//等待复位完成 + delaycount = 0; + FuncClearState(); + } + else { + delaycount += 1; + if(delaycount > 10){ + nextstate(0);//延时0.1S + } + + } + } + case 20 { + if(sendstate == 0){//复位 + FuncClearState(); + FuncReq11(0x01); + } + else { + var ret = FuncWait(0x11); + nextstate(ret); + } + } + + case 21 { + if(sendstate == 0){//等待复位完成 + delaycount = 0; + FuncClearState(); + } + else { + delaycount += 1; + if(delaycount > 20){ + nextstate(0);//延时1S + } + + } + } + + case 22 { + if(sendstate == 0){ + FuncReq10(true,0x03);//进入扩展会话 + FuncClearState(); + } + else { + var ret = FuncWait(0x10); + nextstate(ret); + } + } + case 23 { + if(sendstate == 0){ + FuncReq28(0x00,0x01);//开启发送 + FuncClearState(); + } + else { + var ret = FuncWait(0x28); + nextstate(ret); + } + } + case 24 { + if(sendstate == 0){ + FuncReq85(0x01);//开启DTC + FuncClearState(); + } + else { + var ret = FuncWait(0x85); + nextstate(ret); + } + } + case 25 { + if(sendstate == 0){ + FuncReq10(true,0x01);//进入默认会话 + FuncClearState(); + } + else { + var ret = FuncWait(0x10); + nextstate(ret); + } + } + else { + thread.command.$SendEnd(true); + //FuncDisplay("刷写完成,用时 " + boottime/100 + " S") + boottimer.disable(); + } + } + if(alldata_blocknum != 0){ + thread.command.$SetProgress(block_sended/alldata_blocknum * 100); + } + +} \ No newline at end of file diff --git a/CAN_Bootloader/user/GeelySecurety.aardio b/CAN_Bootloader/user/GeelySecurety.aardio new file mode 100644 index 0000000..68bf608 --- /dev/null +++ b/CAN_Bootloader/user/GeelySecurety.aardio @@ -0,0 +1,99 @@ + +xorArray = {0xAA,0x50,0x43,0x52} +securetyKeyCalc = function(pucSeed,ucSecurityLevel){ + //SeedSec_t cal,key,seed; + var seed = {0,0,0,0}; + var key = {0,0,0,0}; + var cal = {0,0,0,0}; + seed[1]=pucSeed[4]; + seed[2]=pucSeed[3]; + seed[3]=pucSeed[2]; + seed[4]=pucSeed[1]; + select(ucSecurityLevel) { + case 0x01 { + var dll = raw.loadDll("/DM_RP_SA.dll",,"cdecl" ); + if(dll != null){ + FuncDisplay("加载密钥dll成功"); + var retlen = raw.buffer(4,0); + var seedraw = raw.buffer(4,0); + var iVariant = raw.buffer(20,0); + var keyraw = raw.buffer(4,0); + seedraw[1] = pucSeed[1]; + seedraw[2] = pucSeed[2]; + seedraw[3] = pucSeed[3]; + seedraw[4] = pucSeed[4]; + var ret = 0; + ret = dll.GenerateKeyEx(seedraw,4,0x01,iVariant,keyraw,4,retlen); + FuncDisplay("ret = " ++ ret ); + + key[1] = keyraw[1]; + key[2] = keyraw[2]; + key[3] = keyraw[3]; + key[4] = keyraw[4]; + return key; + } + else { + FuncDisplay("加载密钥dll失败"); + } + + + } + case 0x09 { + var dll = raw.loadDll("/DM_RP_SA.dll",,"cdecl" ); + if(dll != null){ + FuncDisplay("加载密钥dll成功"); + var retlen = raw.buffer(4,0); + var seedraw = raw.buffer(4,0); + var iVariant = raw.buffer(20,0); + var keyraw = raw.buffer(4,0); + seedraw[1] = pucSeed[1]; + seedraw[2] = pucSeed[2]; + seedraw[3] = pucSeed[3]; + seedraw[4] = pucSeed[4]; + var ret = 0; + ret = dll.GenerateKeyEx(seedraw,4,0x09,iVariant,keyraw,4,retlen); + FuncDisplay("ret = " ++ ret ); + + key[1] = keyraw[1]; + key[2] = keyraw[2]; + key[3] = keyraw[3]; + key[4] = keyraw[4]; + return key; + } + else { + FuncDisplay("加载密钥dll失败"); + } + } + case 0x11 { + /* + cal.byte[0] = seed.byte[0]^xorArray[0]; + cal.byte[1] = seed.byte[1]^xorArray[1]; + cal.byte[2] = seed.byte[2]^xorArray[2]; + cal.byte[3] = seed.byte[3]^xorArray[3]; + + key.byte[3] = ((cal.byte[1]&0x03)<<6)|(( cal.byte[0]&0xFC)>>2); + key.byte[2] = ((cal.byte[0]&0x03)<<6)|(cal.byte[3]&0x3F); + key.byte[1] = (cal.byte[3]&0xFC)|((cal.byte[2]&0xC0)>>6); + key.byte[0] = (cal.byte[2]&0xFC)|(cal.byte[1]&0x03); + */ + cal[1] = seed[1]^xorArray[1]; + cal[2] = seed[2]^xorArray[2]; + cal[3] = seed[3]^xorArray[3]; + cal[4] = seed[4]^xorArray[4]; + + key[4] = ((cal[2]&0x03)<<6)|(( cal[1]&0xFC)>>2); + key[3] = ((cal[1]&0x03)<<6)|(cal[4]&0x3F); + key[2] = (cal[4]&0xFC)|((cal[3]&0xC0)>>6); + key[1] = (cal[3]&0xFC)|(cal[2]&0x03); + } + else { + } + } + var pucKey = {0,0,0,0}; + pucKey[1]=key[4]; + pucKey[2]=key[3]; + pucKey[3]=key[2]; + pucKey[4]=key[1]; + + return pucKey; +} diff --git a/CAN_Bootloader/user/S19Decode.aardio b/CAN_Bootloader/user/S19Decode.aardio new file mode 100644 index 0000000..a7aa661 --- /dev/null +++ b/CAN_Bootloader/user/S19Decode.aardio @@ -0,0 +1,199 @@ +var Crc32Tble = +{ + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +}; +var fileinfo = ""; +var FlashData = {}; +var AllData = {} +FuncGetAllData = function(id){ + if(id > #AllData){ + return null; + } + return AllData[id]; +} +FuncGetFileInfo = function(){ + return fileinfo; +} + +FuncCRC32Calc = function(Data){ + + var usCRC = 0xFFFFFFFF; + + for(i=1;#Data;1){ + var temp = (usCRC ^ Data[i]) & 0xFF; + usCRC = ((usCRC >> 8)&0xffffff) ^ Crc32Tble[temp+1]; + + } + usCRC ^= 0xFFFFFFFF; + return usCRC; +} + +FuncGetFlashCRC = function(id){ + var Data = AllData[id]; + var crc = FuncCRC32Calc(Data[1].data); + return crc; +} + +var s19crc = {}; + + +FuncOpenS19File = function(id,path){ + import fsys.dlg; + if(path == null){ + path = fsys.dlg.open('S19文件|*.sx;*.s19;*.srec|所有文件|*.*||',,,winform); + } + + if(io.exist( path )){ + //winform.editPath.text = path; + var readbuf = string.load(path); + + readbuf = string.split(readbuf,'\r\n'); + //console.dumpJson(readbuf); + var block = null; + FlashData = {}; + for(i=1;#readbuf;1){ + if(#readbuf[i] == 0){ + continue; + } + var str = readbuf[i]; + var data = ""; + var addr = 0; + var len = 0; + select(string.slice(str,1,2)) { + case "S0"{ + //S0为文件信息 + var fileinfobuf = string.slice(str,9,-3);//取出文件信息 + fileinfo = "file info:"+string.unhex(fileinfobuf,"")//解码 + fileinfo = string.replace(fileinfo,"\z"," ");//替换空字符 + FuncDisplay(fileinfo)//显示 + continue; + } + case "S1"{ + len = tonumber(string.slice(str,3,4),16) + addr = tonumber(string.slice(str,5,8),16) + data = string.slice(str,9,-3) + } + case "S2"{ + len = tonumber(string.slice(str,3,4),16) + addr = tonumber(string.slice(str,5,10),16) + data = string.slice(str,11,-3) + + } + case "S3"{ + len = tonumber(string.slice(str,3,4),16) + addr = tonumber(string.slice(str,5,12),16) + data = string.slice(str,13,-3) + } + else { + continue; + } + } + if(block == null){ + //空表,第一次进入 + block = {}; + block["address"] = addr; + block["data"] = {}; + } + else { + //非空表 + if(addr == (block["address"]+#block["data"])){ + //连续,无动作 + } + else { + //不同块,新建块 + FlashData[#FlashData+1]={"address" = block["address"];"data" = block["data"];} + block["address"] = addr; + block["data"] = {}; + + } + + } + + data = string.unhex(data,"") + for(i=1;#data;1){ + var bytedata = string.unpack(data,i) + table.push(block["data"],bytedata) + } + + + } + s19crc = null; + FuncDisplay(string.format("addr=%x ,len = %x",block.address,#block.data))//显示 + if(block.address == 0x10000){ + var last_data_addr = 0; + last_data_addr = #block.data; + var temp = last_data_addr%2048; + if(temp != 0){ + last_data_addr += 2048-temp; + } + for(i=#block.data+1;last_data_addr;1){ + block.data[i] = 0xff; + } + + s19crc = {}; + s19crc["address"] = 0x37800; + s19crc["data"] = {}; + for(i=1;0x800;1){ + s19crc.data[i] = 0xff; + } + last_data_addr+=0x10000; + s19crc.data[0x7FC] = last_data_addr>>24; + s19crc.data[0x7FB] = last_data_addr>>16; + s19crc.data[0x7FA] = last_data_addr>>8; + s19crc.data[0x7F9] = last_data_addr&0XFF; + + var crc32temp = FuncCRC32Calc(block.data); + s19crc.data[0x800] = crc32temp>>24; + s19crc.data[0x7FF] = crc32temp>>16; + s19crc.data[0x7FE] = crc32temp>>8; + s19crc.data[0x7FD] = crc32temp&0XFF; + } + if(block != null){ + table.push(FlashData,block) + } + if(s19crc != null){ + table.push(FlashData,s19crc) + } + + AllData[id] = FlashData; + } + + //blocknum = 1; + + return path; +} + + + + diff --git a/cva_asw_m0118/.vscode/settings.json b/cva_asw_m0118/.vscode/settings.json new file mode 100644 index 0000000..dfbe4f4 --- /dev/null +++ b/cva_asw_m0118/.vscode/settings.json @@ -0,0 +1,25 @@ +{ + "MicroPython.executeButton": [ + { + "text": "▶", + "tooltip": "运行", + "alignment": "left", + "command": "extension.executeFile", + "priority": 3.5 + } + ], + "MicroPython.syncButton": [ + { + "text": "$(sync)", + "tooltip": "同步", + "alignment": "left", + "command": "extension.execute", + "priority": 4 + } + ], + "files.associations": { + "canuser.h": "c", + "apptask.h": "c", + "mcu.h": "c" + } +} \ No newline at end of file diff --git a/cva_asw_m0118/BOOTHEX/RP-77B_BOOT_BL0101.srec b/cva_asw_m0118/BOOTHEX/RP-77B_BOOT_BL0101.srec new file mode 100644 index 0000000..3178425 --- /dev/null +++ b/cva_asw_m0118/BOOTHEX/RP-77B_BOOT_BL0101.srec @@ -0,0 +1,3092 @@ +S01C00006376615F626F6F746C6F616465725F6D303131382E73726563AE +S1130000F05B002085C000009B2D00000B40000029 +S113001000000000000000000000000000000000DC +S11300200000000000000000000000006741000024 +S1130030000000000000000067420000B35C000004 +S113004018C4000018C4000018C4000018C400003C +S113005018C4000018C4000018C4000018C400002C +S113006018C40000D55C000018C4000018C40000C7 +S113007018C4000018C4000018C4000018C400000C +S113008018C4000018C4000018C4000018C40000FC +S113009018C4000018C4000018C4000018C40000EC +S11300A0D163000018C4000018C4000018C4000084 +S11300B018C4000018C4000018C4000018C40000CC +S11300C048573031424C30313031000031353A3408 +S11300D0343A30310000000044656320313220326C +S11300E0303234000000000052502D3737420000F7 +S11300F000000000000000000000000000000000FC +S113040027C08FD2A0D34DDC000000000000FFFF06 +S1130410BFFFFFFFFFFFFFFFFE88E6BE30A25B8E3B +S113042000B5020093680120DB680340DBB2002BB7 +S11304300AD093681B6A9B081840C0B2002803D0F6 +S1130440D0690860012000E0002000BDF2B584B04E +S11304500200002001009468E66801239E43012302 +S11304600D00EDB21D403543E560049E3678002E44 +S113047051D0D169294CA14201D1010012E0D169C6 +S1130480274CA14201D219000CE0D169254CA142AC +S113049001D2022106E0D169234CA14201D20321F9 +S11304A000E004210C00E4B2042C01D1002033E06C +S11304B06C46617094680194019CE4680C25AC431B +S11304C06D466D78AD000C262E4026430396039CA2 +S11304D0019DEC606C4620709068C4681025AC43A4 +S11304E06D462D782D011026354025430295029C3A +S11304F0C4601C009568EE680127BE432700FFB264 +S11305001F403743EF609068006A84081800204059 +S1130510C0B20028F7D0012005B0F0BD00093D00AD +S113052001127A0001366E01015A620200B502001E +S11305309068006A43081800C007C00FC0B20028C2 +S113054003D090690860012000E0002000BDF2B5EE +S113055084B005000026A8680124416920000840F1 +S1130560C0B200286AD0A868016A20000840C0B25E +S1130570002863D0A8688069010920000840C0B23F +S1130580002802D0012806D00BE069462800FFF7B6 +S113059047FF060005E069462800FFF7C7FF06008D +S11305A0FFE73000C0B2002801D1002048E0270056 +S11305B0A8684069000A8007800FC0B2002805D0EF +S11305C0022808D004D3032808D00AE0270008E052 +S11305D00220070005E00420070002E008200700CD +S11305E0FFE7A868406940084006400EC0B20028F2 +S11305F002D18020029000E00290A8684069C00AFD +S11306004007400FC0B2002802D10820019000E04A +S11306100190A8684069810A20000840C0B2401CCB +S113062003900098029948430399484301997943F8 +S1130630490002F05AFB0499086026003000C0B259 +S113064005B0F0BDFCB502000020040095686E6999 +S113065001239E4301232700FFB21F403743019724 +S1130660019E6E611E006F463E704E78002E02D0D1 +S1130670012E0FD01DE004009568AF691026B74322 +S1130680BC462600F6B2360110273E4067463E437C +S1130690AE6111E01C009568AF691026B743BC46F3 +S11306A02600F6B2360110273E4067463E43AE614F +S11306B002E004006D462C706C462478002C01D1B5 +S11306C0002093E0CC68012C01D104000FE0CC6839 +S11306D0022C01D11C000AE0CC68042C01D10224B4 +S11306E005E0CC68082C01D1032400E0FF24250098 +S11306F0EDB2FF2D01D1002078E06D466C70956855 +S11307006E69834F3740BC466E4676783702C02602 +S1130710B6003E4067463E436E614F88002F1CD0B2 +S11307204D88812D19DA4D88802D01D1050000E016 +S11307304D8896680196019E7769FE26B743BC46AC +S11307402E00F6B27700FE263E4067463E43019FE8 +S11307507E610F69002F02D11AE0002046E00D6986 +S1130760092D15D20D69082D00D0086995686E69A8 +S1130770B04F3740BC460600F6B2F702E026B60199 +S11307803E4067463E436E618F68012F02D104E00C +S113079000202BE08868022813D18868401E9568E1 +S11307A06E69A54F3740BC460600F6B2B6028027F4 +S11307B0FF003E4067463E436E610F78002F02D132 +S11307C012E0002012E0180095686E690127BE430C +S11307D00700FFB21F4037436F619068056A180035 +S11307E02840C0B20028F8D068460078F6BDF3B5BA +S11307F081B0070000242600009478690125C069AF +S1130800010928000840C0B2002818D06946380001 +S1130810FFF706FE06003000C0B200280FD078694A +S1130820C069000A4007400F85402900412905D2CC +S1130830009802F05AFA0299086000E0260030009D +S1130840C0B2FEBDFEB5020000206B4618706B46B8 +S113085058705369DE691024E443264010256F461E +S11308607F783F012F403743DF618E88012E01D10D +S113087003001EE08B88022B01D1012319E08B8831 +S1130880042B01D1022314E08B88082B01D103230C +S11308900FE08B88102B01D104230AE08B88202BD6 +S11308A001D1052305E08B88402B01D1062300E00C +S11308B007231E00F6B2072E17D06E4673705669D2 +S11308C00196019EF669A54F3740BC466E46767880 +S11308D03702E026F6003E4067463E430296029EFB +S11308E0019FFE6101266F463E700E78002E01D0F6 +S11308F0012600E006005769F86904403000C0B2E0 +S1130900000105402543FD6168460078FEBD0000F6 +S1130910FFFCFFFFF3B581B007000024260000941C +S1130920786901258069010928000840C0B20028BF +S113093018D069463800FFF773FD06003000C0B2D6 +S113094000280FD078698069000A4007400F85406D +S11309502900412905D2009802F0C7F902990860DC +S113096000E026003000C0B2FEBDFEB5020000204B +S11309706B4618706B46587053699E691024E443A3 +S1130980264010256F467F783F012F4037439F61F3 +S11309908E88012E01D103001EE08B88022B01D129 +S11309A0012319E08B88042B01D1022314E08B88E6 +S11309B0082B01D103230FE08B88102B01D10423D2 +S11309C00AE08B88202B01D1052305E08B88402B7E +S11309D001D1062300E007231E00F6B2072E17D02C +S11309E06E46737056690196019EB6695B4F374037 +S11309F0BC466E4676783702E026F6003E406746EF +S1130A003E430296029E019FBE6101266F463E70E0 +S1130A100E78002E01D0012600E006005769B8695F +S1130A2004403000C0B2000105402543BD61684662 +S1130A300078FEBDFFC7FFFFFFFBFFFFF3B581B0EA +S1130A400700002426000094786901254069010903 +S1130A5028000840C0B2002818D069463800FFF7C3 +S1130A6065FD06003000C0B200280FD078694069E7 +S1130A70000A4007400F85402900412905D200980B +S1130A8002F033F90299086000E026003000C0B299 +S1130A90FEBDFEB5020000206B4618706B46587010 +S1130AA053695E691024E443264010256F467F781D +S1130AB03F012F4037435F618E88012E01D103002F +S1130AC01EE08B88022B01D1012319E08B88042BB3 +S1130AD001D1022314E08B88082B01D103230FE0FA +S1130AE08B88102B01D104230AE08B88202B01D1A1 +S1130AF0052305E08B88402B01D1062300E0072362 +S1130B001E00F6B2072E17D06E4673705669019612 +S1130B10019E7669114F3740BC466E46767837029F +S1130B20E026F6003E4067463E430296029E019F41 +S1130B307E6101266F463E700E78002E01D001269C +S1130B4000E006005769786904403000C0B2000133 +S1130B50054025437D6168460078FEBDFFF8FFFF30 +S1130B60F3B581B0070000242600009478690125BC +S1130B700069010928000840C0B2002818D069465D +S1130B803800FFF7D3FC06003000C0B200280FD0B5 +S1130B9078690069000A4007400F8540290041290F +S1130BA005D2009802F0A1F80299086000E026003E +S1130BB03000C0B2FEBDFEB5020000206B461870C6 +S1130BC06B46587053691E691024E443264010256F +S1130BD06F467F783F012F4037431F618E88012E77 +S1130BE001D103001EE08B88022B01D1012319E0FF +S1130BF08B88042B01D1022314E08B88082B01D1AC +S1130C0003230FE08B88102B01D104230AE08B8887 +S1130C10202B01D1052305E08B88402B01D106232D +S1130C2000E007231E00F6B2072E17D06E4673703D +S1130C3056690196019E3669A14F3740BC466E46FF +S1130C4076783702E026F6003E4067463E43029639 +S1130C50029E019F3E6101266F463E700E78002E73 +S1130C6001D0012600E006005769386904403000CD +S1130C70C0B20001054025433D6168460078FEBDD1 +S1130C80F3B581B00700002426000094786901259B +S1130C90406A010928000840C0B2002818D06946FB +S1130CA03800FFF754FC06003000C0B200280FD013 +S1130CB07869406A000A4007400F854029004129AD +S1130CC005D2009802F011F80299086000E02600AD +S1130CD03000C0B2FEBDFEB5020000206B461870A5 +S1130CE06B46587053695E6A1024E443264010250D +S1130CF06F467F783F012F4037435F628E88012E15 +S1130D0001D103001EE08B88022B01D1012319E0DD +S1130D108B88042B01D1022314E08B88082B01D18A +S1130D2003230FE08B88102B01D104230AE08B8866 +S1130D30202B01D1052305E08B88402B01D106230C +S1130D4000E007231E00F6B2072E17D06E4673701C +S1130D5056690196019E766A594F3740BC466E46E5 +S1130D6076783702E026F6003E4067463E43029618 +S1130D70029E019F7E6201266F463E700E78002E11 +S1130D8001D0012600E006005769786A044030006B +S1130D90C0B20001054025437D6268460078FEBD6F +S1130DA0F3B581B00700002426000094786901257A +S1130DB0006A010928000840C0B2002818D069461A +S1130DC03800FFF7C4FB06003000C0B200280FD083 +S1130DD07869006A000A4007400F854029004129CC +S1130DE005D2009801F081FF0299086000E0260016 +S1130DF03000C0B2FEBDFEB5020000206B46187084 +S1130E006B46587053691E6A1024E443264010252B +S1130E106F467F783F012F4037431F628E88012E33 +S1130E2001D103001EE08B88022B01D1012319E0BC +S1130E308B88042B01D1022314E08B88082B01D169 +S1130E4003230FE08B88102B01D104230AE08B8845 +S1130E50202B01D1052305E08B88402B01D10623EB +S1130E6000E007231E00F6B2072E17D06E467370FB +S1130E7056690196019E366A114F3740BC466E464C +S1130E8076783702E026F6003E4067463E430296F7 +S1130E90029E019F3E6201266F463E700E78002E30 +S1130EA001D0012600E006005769386A044030008A +S1130EB0C0B20001054025433D6268460078FEBD8E +S1130EC0FFF8FFFF70B504000E000025606900689C +S1130ED0000E8007800FC0B2002805D002280FD072 +S1130EE008D3032812D017E031002000FFF71EFBBF +S1130EF0050011E031002000FFF792FA05000BE035 +S1130F0031002000FFF723FB050005E0310020003D +S1130F10FFF70CFB0500FFE72800C0B270BDF0B579 +S1130F2002004878012801D100230AE0487800280B +S1130F3001D1012305E04878022801D1022300E011 +S1130F40FF231800C0B2FF2801D1002017E01C00C5 +S1130F5050690668934D35402600F6B23704C02622 +S1130F60B6023E402E43066050690068000E8007BA +S1130F70800F1C00C0B2E4B2A042F5D10120F0BD44 +S1130F80F8B504000E00002569462000FFF79AFF1B +S1130F9007003800C0B2002801D100200BE0E0684F +S1130FA000680107090F0098C9B2491C01F09DFEB1 +S1130FB030603800C0B2F2BD30B502008888002825 +S1130FC010D0888811280DDA8C88641ED3681868BC +S1130FD00F25A8432500EDB22D072D0F05431D60F5 +S1130FE0012000E0002030BDF8B504000E0000250B +S1130FF069462000FFF7C4FF07003800C0B200288C +S113100001D100200CE060690068000A0107090FA3 +S11310100098C9B2491C01F068FE30603800C0B2C3 +S1131020F2BD70B502008888002812D08888112883 +S11310300FDA8C88641E53691D685B4828402500BC +S1131040EDB22E02F0252D01354005431D6001202F +S113105000E0002070BDF8B504000F0000252E004C +S11310602069C8214058000C8007800FC0B20028B6 +S113107005D002280FD008D3032812D017E0694600 +S11310802000FFF753FA060011E069462000FFF73D +S1131090C7F906000BE069462000FFF758FA06007E +S11310A005E069462000FFF741FA0600FFE730003B +S11310B0C0B2002801D1002019E02069C82140589D +S11310C001090800C007C00FC0B200280CD0206975 +S11310D0C8214058000A0107090F0098C9B2491CE9 +S11310E001F003FE386000E02E003000C0B2F2BD13 +S11310F0FCB502004878012801D100230AE04878B1 +S1131100002801D1012305E04878022801D10223F7 +S113111000E0FF231800C0B2FF2801D100203FE007 +S1131120888800283BD08888112838DA68460370FC +S11311301069C82405591B4C2C406D462D782D048C +S1131140C026B6022E4026430196019CC825445170 +S11311508C88641E1569C826AE59134F3740BC46A7 +S11311602600F6B23702F02636013E4067463E437B +S1131170C827EE510F78002F01D0012400E000248D +S11311801569C82028581026B0432600F6B2360147 +S113119010273E400643C8202E50012000E00020C6 +S11311A0F6BD0000FFFFFCFFFFF0FFFFF8B50400F1 +S11311B00F006069406801090800C007C00FC0B291 +S11311C0002801D100209BE0002005000090606908 +S11311D007264068000C3040C0B2002843D1606943 +S11311E04068C00C3040C0B200280BD0022815D093 +S11311F00ED304281ED017D3062827D020D30728BF +S11312002AD02FE069462000FFF725FF050066E09D +S113121069462000FFF704F9050060E069462000F4 +S1131220FFF784F905005AE069462000FFF78FF9BB +S1131230050054E069462000FFF7A2FE05004EE0D9 +S113124069462000FFF7D0FE050048E0694620000B +S1131250FFF7CDFA050042E069462000FFF7EEFBF8 +S113126005003CE03BE060694068000C3040C0B2DF +S113127001280AD033D3032813D00CD305281CD05B +S113128015D3072825D01ED329E069462000FFF78F +S1131290F7FC050023E06946200000F038FA050059 +S11312A01DE06946200000F00BFA050017E06946CE +S11312B0200000F0DEF9050011E06946200000F08E +S11312C067FD05000BE069462000FFF72FF90500D4 +S11312D005E069462000FFF729F90500FFE728002B +S11312E0C0B201280AD160694068000A0640310092 +S11312F00098C9B2491C01F0F8FC38602800C0B25B +S1131300F2BDF2B582B0010001206A4610700020DF +S113131002004B695C681025AC431500EDB22D0149 +S11313201026354025435D60029C6478002C40D033 +S1131330012C5DD0022C7AD0032C00D1D4E0052CF2 +S113134000D1F0E0072C00D10CE10A2C00D18DE093 +S11313500B2C00D1A9E00C2C0CD00F2C00D12BE1CC +S1131360102C00D11AE1112C00D109E11A2C00D162 +S113137030E13DE102004B695D68B94C2C40150039 +S1131380EDB22D04E026F6022E4026430196019C80 +S11313905C6004004D696E68B24F3740BC4626005D +S11313A0F6B2F704E026B6033E4067463E436E605D +S11313B021E102004B695D68A94C2C401500EDB297 +S11313C02D04E026F6022E4026430196019C5C6023 +S11313D001244D696E68A34F3740BC462600F6B21F +S11313E0F704E026B6033E4067463E436E6002E1E2 +S11313F002004B695D689A4C2C401500EDB22D0437 +S1131400E026F6022E4026430196019C5C600224ED +S11314104D696E68934F3740BC462600F6B2F70418 +S1131420E026B6033E4067463E436E60E3E00200BA +S11314304B695D688A4C2C401500EDB22D04E02602 +S1131440F6022E4026430196019C5C6003244D69FC +S11314506E68844F3740BC462600F6B2F704E02697 +S1131460B6033E4067463E436E60C4E002004B69EB +S11314705D687B4C2C401500EDB22D04E026F6028D +S11314802E4026430196019C5C6004244D696E68DD +S1131490744F3740BC462600F6B2F704E026B60384 +S11314A03E4067463E436E60A5E002004B695D68BE +S11314B06B4C2C401500EDB22D04E026F6022E40B4 +S11314C026430196019C5C6005244D696E68654F56 +S11314D03740BC462600F6B2F704E026B6033E4089 +S11314E067463E436E6086E002004B695D685C4C73 +S11314F02C401500EDB22D04E026F6022E402643C2 +S11315000196019C5C6006244D696E68554F374016 +S1131510BC462600F6B2F704E026B6033E40674612 +S11315203E436E6067E002004B695D684C4C2C40A2 +S11315301500EDB22D04E026F6022E402643019656 +S1131540019C5C6007244D696E68464F3740BC4679 +S11315502600F6B2F704E026B6033E4067463E4353 +S11315606E6048E001224B695D683D4C2C401500DB +S1131570EDB22E04E025ED02354025435D603AE0EE +S113158002224B695D68364C2C401500EDB22E04E6 +S1131590E025ED02354025435D602CE003224B69D4 +S11315A05D682F4C2C401500EDB22E04E025ED02B1 +S11315B0354025435D601EE004224B695D68284C7C +S11315C02C401500EDB22E04E025ED0235402543F4 +S11315D05D6010E005224B695D68214C2C401500CC +S11315E0EDB22E04E025ED02354025435D6002E0B6 +S11315F002006B461A706A461278002A1AD0029AC0 +S11316009288002A13D0029A9288092A0FDA029A41 +S11316109288521E4B695D687F4C2C401500EDB2D8 +S11316202E02E025ED00354025435D6002E0020016 +S11316306B461A70029A1278002A01D0012200E047 +S113164002004B6958681024A0431400E4B224013A +S113165010252C4004435C6068460078FEBD000001 +S1131660FFFFF8FFFFFFC7FF0200106A08600120B8 +S1131670704700B502005068806C03091800C00769 +S1131680C00FC0B2002804D0FA20800008600120F6 +S113169000E0002000BD70B502000878002801D0E9 +S11316A0012400E000245368986C1025A843250009 +S11316B0EDB22D011026354005439D64012070BD17 +S11316C000B502005068406C03091800C007C00F41 +S11316D0C0B2002804D0FA20C0010860012000E054 +S11316E0002000BD70B502000878002801D0012454 +S11316F000E000245368586C1025A8432500EDB27F +S11317002D011026354005435D64012070BD0200A3 +S1131710FA20400208600120704770B504000E00F2 +S1131720002561680120496809090140C9B20029FE +S113173001D100201AE061684968090C0140C9B26E +S1131740002905D131002000FFF71AFC05000BE049 +S113175061684968090C0840C0B2012804D131000D +S1131760200000F02FF905002800C0B270BDF2B5CA +S113177082B0010000206A46107005004C6866685B +S11317801022D243164010232F00FFB23F011F4006 +S113179037436760029E76780A2E11D16C466070DA +S11317A04C6866681D4D35406E4676783604802751 +S11317B07F023E402E43666001256F463D7018E06F +S11317C0029C6478182C14D1012425004E680196DB +S11317D0019E7668114F3740BC462E00F6B236049F +S11317E080277F023E4067463E43019F7E606F46EE +S11317F03C70029C2478002C01D0012400E00400F9 +S11318004D68686802402000C0B2000103401343E1 +S11318106B6068460078FEBDFFF8FFFFFFFFFEFF28 +S113182070B504000E000025606880680109080096 +S1131830C007C00FC0B2002804D031002000FFF759 +S1131840D3FB05002800C0B270BD70B50200087853 +S1131850002801D0012400E0002453689868102572 +S1131860A8432500EDB22D011026354005439D60A7 +S1131870012070BD70B504000E0000256068C068CA +S113188001090800C007C00FC0B2002804D031000D +S11318902000FFF7A9FB05002800C0B270BD70B599 +S11318A002000878002801D0012400E000245368D5 +S11318B0D8681025A8432500EDB22D011026354027 +S11318C00543DD60012070BD70B504000E000025E5 +S11318D06068006901090800C007C00FC0B2002891 +S11318E004D031002000FFF77FFB05002800C0B2C0 +S11318F070BD70B502000878002801D0012400E012 +S11319000024536818691025A8432500EDB22D0161 +S11319101026354005431D61012070BD70B50400DB +S11319200E0000256068406901090800C007C00F67 +S1131930C0B2002804D031002000FFF755FB050099 +S11319402800C0B270BD70B502000878002801D02C +S1131950012400E00024536858691025A843250099 +S1131960EDB22D011026354005435D61012070BDA7 +S113197070B504000E000025606880690109080044 +S1131980C007C00FC0B2002804D031002000FFF708 +S11319902BFB05002800C0B270BD70B502000878AA +S11319A0002801D0012400E0002453689869102520 +S11319B0A8432500EDB22D011026354005439D6155 +S11319C0012070BDF8B505000F0000200400009050 +S11319D06868C06901090800C007C00FC0B20028C8 +S11319E001D1002054E068680726C069000C30402B +S11319F0C0B200280BD0022815D00ED304281ED064 +S1131A0017D3062827D020D307282AD02FE06946E9 +S1131A102800FFF713F8040029E069462800FEF7C0 +S1131A20E6FE040023E069462800FFF729F90400D4 +S1131A301DE069462800FFF76AFE040017E06946C6 +S1131A402800FFF716FE040011E069462800FFF79E +S1131A5037FE04000BE069462800FFF705FE04008A +S1131A6005E069462800FEF7E9FF0400FFE72000CF +S1131A70C0B200280AD06868C069000A0640310074 +S1131A80C9B2491C009801F030F938602000C0B296 +S1131A90F2BDF3B50100012002006B461A7000226A +S1131AA014004D68EE6910239E4310232700FFB2F3 +S1131AB03F011F403743EF61019E7678032E1CD00F +S1131AC0052E0AD0072E28D00E2E66D00F2E44D015 +S1131AD0102E52D0112E30D06FE014004D68EE69F4 +S1131AE0AA4F3740BC462600F6B23704E026F60279 +S1131AF03E4067463E43EE6162E004004D68EE6995 +S1131B00A24F3740BC462600F6B23704E026F60260 +S1131B103E4067463E43EE6152E002244D68EE6962 +S1131B209A4F3740BC462600F6B23704E026F60248 +S1131B303E4067463E43EE6142E003244D68EE6951 +S1131B40924F3740BC462600F6B23704E026F60230 +S1131B503E4067463E43EE6132E004244D68EE6940 +S1131B608A4F3740BC462600F6B23704E026F60218 +S1131B703E4067463E43EE6122E005244D68EE692F +S1131B80824F3740BC462600F6B23704E026F60200 +S1131B903E4067463E43EE6112E006244D68EE691E +S1131BA07A4F3740BC462600F6B23704E026F602E8 +S1131BB03E4067463E43EE6102E014006D462C70E1 +S1131BC0019CA488002C15D0019CA488092C11DA4E +S1131BD0019CA488641E4D68EE69C04F3740BC4622 +S1131BE02600F6B23702E026F6003E4067463E4342 +S1131BF0EE6102E014006D462C70019C2478002CE8 +S1131C0001D00200FFE74C68E0691025A8431500E5 +S1131C10EDB22D012B400343E36168460078F6BD25 +S1131C2070B504000E00002561680120096A0909E5 +S1131C300140C9B2002901D1002026E06168096A87 +S1131C40090C8907890FC9B2002905D002290FD0D0 +S1131C5008D3032912D016E031002000FEF7EEFE6F +S1131C60050010E031002000FFF70AF805000AE043 +S1131C7031002000FEF7BBFD050004E0FA21490213 +S1131C8031600500FFE72800C0B270BDF2B582B034 +S1131C900100012002006B461A7000226B465A7044 +S1131CA04D682E6A1023DB431E4010246F467F7854 +S1131CB03F01274037432F62029E7678032E2AD0B5 +S1131CC0052E04D0072E13D0112E37D049E06D46CF +S1131CD06A704D682E6AC94F3740BC466E467678A6 +S1131CE03704C026B6023E4067463E432E623AE0C1 +S1131CF005004E680196019E366AC04F3740BC46C7 +S1131D002E00F6B23704C026B6023E4067463E4374 +S1131D10019F3E6227E002254E680196019E366AC5 +S1131D20B64F3740BC462E00F6B23704C026B60282 +S1131D303E4067463E43019F3E6214E003254E68E1 +S1131D400196019E366AAD4F3740BC462E00F6B26E +S1131D503704C026B6023E4067463E43019F3E62BA +S1131D6001E06D462A70029D2D78002D01D00200FD +S1131D70FFE74D68286A03401000C0B20001044028 +S1131D801C432C6268460078FEBD0000FFFFF8FF8C +S1131D9070B504000E0000256068806A010908001F +S1131DA0C007C00FC0B2002801D1002027E060683E +S1131DB0806A000C8007800FC0B2002805D002287A +S1131DC00FD008D3032812D017E031002000FFF70A +S1131DD077FC050011E031002000FFF745FC050009 +S1131DE00BE031002000FFF744FC050005E0310062 +S1131DF02000FFF73EFC0500FFE72800C0B270BDDD +S1131E00F2B582B0010000206A46107005004C68EB +S1131E10A66A1022D243164010232F00FFB23F01BE +S1131E201F403743A762029E7678102E11D16C466C +S1131E3060704C68A66A714D35406E4676783704FA +S1131E40C026B6023E402E43A66201256F463D7071 +S1131E5031E0029C64780E2C15D1012425004E68D3 +S1131E600196019EB66A654F3740BC462E00F6B215 +S1131E703704C026B6023E4067463E43019FBE6219 +S1131E806F463C7017E0029C64780F2C13D1022437 +S1131E904D68AE6A594F3740BC462600F6B2370447 +S1131EA0C026B6023E4067463E430196019EAE629E +S1131EB001266F463E70029C2478002C01D0012438 +S1131EC000E004004D68A86A02402000C0B200018E +S1131ED003401343AB6268460078FEBDFFF8FFFF82 +S1131EE070B504000E00002561680120096B090C1F +S1131EF00140C9B2002905D131002000FFF774F870 +S1131F0005000BE06168096B090C0840C0B20128A8 +S1131F1004D131002000FFF7FAFB05002800C0B20D +S1131F2070BDF0B50200002318004C780B2C0CD1C6 +S1131F305468266B9D4D35401E00F6B2370480264A +S1131F40760237402F4327630FE04B78112B0CD1D7 +S1131F5001235468266B954D35401E00F6B23704B4 +S1131F608026760237402F432763C0B2F0BD70B598 +S1131F7004000E00002561680120496B090C014032 +S1131F80C9B2002905D131002000FFF72DF8050062 +S1131F900BE06168496B090C0840C0B2012804D108 +S1131FA031002000FFF7B3FB05002800C0B270BD6C +S1131FB0F0B50200002318004C780B2C0CD15468A7 +S1131FC0666B7A4D35401E00F6B2370480267602E1 +S1131FD037402F4367630FE04B78112B0CD101235B +S1131FE05468666B714D35401E00F6B23704802686 +S1131FF0760237402F436763C0B2F0BDFFFFFCFF9A +S113200070B504000E00002561680120896B090C7D +S11320100140C9B2002905D131002000FEF7E4FFD8 +S113202005000BE06168896B090C0840C0B2012807 +S113203004D131002000FFF76AFB05002800C0B27C +S113204070BDF0B50200002318004C780B2C0CD1A5 +S11320505468A66B554D35401E00F6B237048026F1 +S1132060760237402F43A7630FE04B78112B0CD136 +S113207001235468A66B4D4D35401E00F6B237045B +S11320808026760237402F43A763C0B2F0BD70B5F7 +S113209004000E00002561680120C96B090C014091 +S11320A0C9B2002905D131002000FEF79DFF0500CB +S11320B00BE06168C96B090C0840C0B2012804D167 +S11320C031002000FFF723FB05002800C0B270BDDB +S11320D0F0B50200002318004C780B2C0CD1546886 +S11320E0E66B324D35401E00F6B237048026760288 +S11320F037402F43E7630FE04B78112B0CD10123BA +S11321005468E66B294D35401E00F6B2370480262C +S1132110760237402F43E763C0B2F0BD70B50400C8 +S11321200E00002561680120096C090C0140C9B248 +S1132130002905D131002000FEF756FF05000BE011 +S11321406168096C090C0840C0B2012804D131004F +S11321502000FFF7DCFA05002800C0B270BDF0B51E +S11321600200002318004C780B2C0CD15468266C08 +S11321700E4D35401E00F6B23704802676023740F5 +S11321802F4327640FE04B78112B0CD101235468A3 +S1132190266C064D35401E00F6B2370480267602C2 +S11321A037402F432764C0B2F0BD0000FFFFFEFF9D +S11321B070B504000E00002521680120C9680909D2 +S11321C00140C9B2002905D131002000FEF70CFFFF +S11321D005000AE02168C96809090140C9B201295A +S11321E003D1FA214902316005002800C0B270BD54 +S11321F0F0B50200002318004C780B2C0DD11468A4 +S1132200E5681026B5431E00F6B2360110273E409D +S11322102E43E6600125280012E04B78112B0FD1E4 +S113222001231C001568EF681026B743BC4626003E +S1132230F6B2360110273E4067463E43EE60180072 +S1132240C0B2F0BD38B505000C002869006801096A +S11322500800C007C00FC0B2002801D1002003E06D +S113226021002800FEF78CFE32BD70B5020008780C +S1132270002801D0012400E0002413691868102507 +S1132280A8432500EDB22D011026354005431D60FD +S1132290012070BD38B505000C00286940680109AB +S11322A00800C007C00FC0B2002801D1002003E01D +S11322B021002800FEF798FE32BD70B502000878B0 +S11322C0002801D0012400E0002413695868102577 +S11322D0A8432500EDB22D011026354005435D606D +S11322E0012070BD38B505000C002869006901099A +S11322F00800C007C00FC0B2002801D1002003E0CD +S113230021002800FEF770FE32BD70B50200087887 +S1132310002801D0012400E0002413691869102565 +S1132320A8432500EDB22D011026354005431D615B +S1132330012070BD38B505000C0028694069010909 +S11323400800C007C00FC0B2002801D1002003E07C +S113235021002800FEF748FE32BD70B5020008785F +S1132360002801D0012400E00024136958691025D5 +S1132370A8432500EDB22D011026354005435D61CB +S1132380012070BD38B505000C0028698069010979 +S11323900800C007C00FC0B2002801D1002003E02C +S11323A021002800FEF7ECFD32BD70B5020008786C +S11323B0002801D0012400E0002413699869102545 +S11323C0A8432500EDB22D011026354005439D613B +S11323D0012070BD38B505000C002869C0690109E9 +S11323E00800C007C00FC0B2002801D1002003E0DC +S11323F021002800FEF7F8FD32BD70B50200087810 +S1132400002801D0012400E000241369D8691025B4 +S1132410A8432500EDB22D01102635400543DD61AA +S1132420012070BDF2B582B0060030690124006A53 +S1132430010920000840C0B2002801D1002037E083 +S11324402000694608710027009730690325006A57 +S1132450000C2840C0B2002805D002280FD008D3B1 +S1132460032812D017E069463000FEF75FF8070032 +S113247011E069463000FDF7D3FF07000BE0694621 +S11324803000FEF764F8070005E069463000FEF707 +S11324904DF80700FFE73069006A000A0540AC40C8 +S11324A00098210000F021FC029908603800C0B2B5 +S11324B0FEBDFEB5020000206B4618706B465870D6 +S11324C013691E6A1024E443264010256F467F7862 +S11324D03F012F4037431F624E78012E01D1030084 +S11324E00AE04B78002B01D1012305E04B78022B45 +S11324F001D1022300E0FF231E00F6B2FF2E17D005 +S11325006E46737016690196019E366A844F374091 +S1132510BC466E4676783704C026B6023E4067460F +S11325203E430296029E019F3E6201266F463E7024 +S11325306E463678002E36D08E88012E01D10600E4 +S11325400FE08E88022E01D101260AE08E88042E27 +S113255001D1022605E08E88082E01D1032600E071 +S1132560FF266F467E706E467678FF2E19D06E4633 +S113257076786F46BE7016690296029E376A694E77 +S11325803E400196019FBC466E46B6783702C0268F +S1132590B6003E4067463E430196019E029F3E625E +S11325A001E06E4630700E78002E01D0012600E066 +S11325B006001769386A04403000C0B200010540C3 +S11325C025433D6268460078FEBD38B505000C0021 +S11325D02869806A01090800C007C00FC0B200283A +S11325E001D1002003E021002800FEF7FDFC32BDEC +S11325F070B502000878002801D0012400E000240E +S11326001369986A1025A8432500EDB22D01102600 +S1132610354005439D62012070BD70B505000C0076 +S113262028690126006B00093040C0B2002801D19E +S1132630002023E02869006B000C8007800FC0B2E3 +S1132640002805D002280DD007D303280FD013E0AB +S113265021002800FEF7F2F90FE021002800FEF720 +S1132660C6F80AE021002800FEF70AFB05E0210075 +S11326702800FEF7E3F900E00020C0B270BDFEB50B +S1132680020000206B4618706B46587013691E6B6D +S11326901024E443264010256F467F783F012F40E5 +S11326A037431F634E78052E01D103000AE04B78AF +S11326B0032B01D1012305E04B78072B01D1022321 +S11326C000E0FF231E00F6B2FF2E17D06E46737093 +S11326D016690196019E366B114F3740BC466E4613 +S11326E076783704C026B6023E4067463E430296DB +S11326F0029E019F3E6301266F463E700E78002EB7 +S113270001D0012600E006001769386B0440300050 +S1132710C0B20001054025433D6368460078FEBD14 +S1132720FFFFFCFFFFFCFFFF0200506A086001206E +S113273070470200906A0860012070470200D06A66 +S113274008600120704770B505000C000126286957 +S1132750A0214058000C4007400FC0B200280BD005 +S1132760022813D00DD304281AD014D3062821D05C +S11327701BD307281ED022E021002800FFF7D4FF36 +S11327801EE021002800FFF7D4FF19E021002800F3 +S1132790FFF7D4FF14E021002800FEF7E1F90FE071 +S11327A021002800FEF7B6F80AE021002800FEF711 +S11327B0F7FA05E021002800FEF7D2F900E0002036 +S11327C0C0B270BDF0B50200012318004C78042C8F +S11327D049D0062C37D0082C55D02A2C04D02B2CC9 +S11327E012D02C2C1FD05EE000231469A02566595A +S11327F0AD4D35401E00F6B23704E026F6023E40E9 +S11328002E43A025665150E01469A0256659A64DB3 +S113281035401E00F6B23704E026F6023E402E4351 +S1132820A025665141E002231469A02566599E4DF6 +S113283035401E00F6B23704E026F6023E402E4331 +S1132840A025665131E003231469A0256659964DED +S113285035401E00F6B23704E026F6023E402E4311 +S1132860A025665121E004231469A02566598E4DE4 +S113287035401E00F6B23704E026F6023E402E43F1 +S1132880A025665111E005231469A0256659864DDB +S113289035401E00F6B23704E026F6023E402E43D1 +S11328A0A025665101E000231800C0B2F0BD70B548 +S11328B005000C0001262869A4214058000C40079B +S11328C0400FC0B200280BD0022813D00DD3042827 +S11328D01AD014D3062821D01BD307281ED022E0F7 +S11328E021002800FFF720FF1EE021002800FFF749 +S11328F020FF19E021002800FFF720FF14E0210049 +S11329002800FEF72DF90FE021002800FEF702F859 +S11329100AE021002800FEF743FA05E02100280020 +S1132920FEF71EF900E00020C0B270BDF0B5020051 +S1132930012318004C78042C49D0062C37D0082CDD +S113294055D02A2C04D02B2C12D02C2C1FD05EE076 +S113295000231469A4256659534D35401E00F6B270 +S11329603704E026F6023E402E43A425665150E08B +S11329701469A42566594C4D35401E00F6B237043F +S1132980E026F6023E402E43A425665141E0022390 +S11329901469A4256659444D35401E00F6B2370427 +S11329A0E026F6023E402E43A425665131E003237F +S11329B01469A42566593C4D35401E00F6B237040F +S11329C0E026F6023E402E43A425665121E004236E +S11329D01469A4256659344D35401E00F6B23704F7 +S11329E0E026F6023E402E43A425665111E005235D +S11329F01469A42566592C4D35401E00F6B23704DF +S1132A00E026F6023E402E43A425665101E0002351 +S1132A101800C0B2F0BD70B505000C00012006001E +S1132A202969C0228958090C0840C0B2002802D084 +S1132A30012805D009E021002800FEF741FE05E049 +S1132A4021002800FEF710FE00E00020C0B270BD97 +S1132A50F0B50200012318004C780E2C11D0102C74 +S1132A601ED100231469C02566598E4D35401E00C1 +S1132A70F6B2360480277F023E402E43C0256651BD +S1132A8010E01469C0256659864D35401E00F6B223 +S1132A90360480277F023E402E43C025665101E064 +S1132AA000231800C0B2F0BDFFFFF8FF70B50500A9 +S1132AB00C00012006002969C4228958090C084029 +S1132AC0C0B2002802D0012805D009E02100280066 +S1132AD0FEF7F6FD05E021002800FEF7C5FD00E045 +S1132AE00020C0B270BDF0B50200012318004C787C +S1132AF00E2C11D0102C1ED100231469C425665944 +S1132B00684D35401E00F6B2360480277F023E40F1 +S1132B102E43C425665110E01469C4256659614DDD +S1132B2035401E00F6B2360480277F023E402E4315 +S1132B30C425665101E000231800C0B2F0BD38B5C9 +S1132B4005000C002869CC21405801090800C00781 +S1132B50C00FC0B2002801D1002003E021002800EA +S1132B60FEF70EFA32BD70B502000878002801D0D5 +S1132B70012300E000231469CC2020581025A84329 +S1132B801D00EDB22D01102635400543CC20255003 +S1132B90012070BDFEB50899099A0A9B0B9C009D03 +S1132BA00560019D4560029D8560C16002614361CD +S1132BB0256885616568C561A568056200252E00E4 +S1132BC02E00F6B2032E0BD22E00F6B2B600A619D2 +S1132BD0F6682F00FFB2BF00C7197E626D1CEFE7D5 +S1132BE0F7BDF8B506000C0017002000C0B232286B +S1132BF001DB002011E000252B4A2000C0B2C000F8 +S1132C001058002807D0390030002300DBB2DB0065 +S1132C10D258904705002800C0B2F2BDF4B588B080 +S1132C2004000F003800C0B2322801DB002037E076 +S1132C3000252E001C4A3800C0B2C000101840689D +S1132C4000282BD0194807906068069007980699C9 +S1132C508023C85016480590A068049005980499EC +S1132C600866144803902068029003980299802310 +S1132C70C850089920003B00DBB2DB00D218526830 +S1132C809047060001956068019980228150009563 +S1132C90A168009A0A6622688023D5503000C0B229 +S1132CA009B0F0BDFFFFFEFF50B700005245535579 +S1132CB0202096194B4D4352F446002804D449422F +S1132CC000F013F8404260474042002905D45FD029 +S1132CD000F00BF8404249426047494200F005F8D1 +S1132CE04942604703460B43E6D40022030A8B4261 +S1132CF00BD203098B4219D243088B422ED2411ABC +S1132D0000D20146524110467047FF2209023FD0CB +S1132D1012068B4205D3121209028B4201D31212FE +S1132D20090203098B4219D300E0090AC3098B4243 +S1132D3001D3CB01C01A524183098B4201D38B01C9 +S1132D40C01A524143098B4201D34B01C01A52416C +S1132D5003098B4201D30B01C01A5241C3088B42B1 +S1132D6001D3CB00C01A524183088B4201D38B009C +S1132D70C01A524143088B4201D34B00C01A52413E +S1132D80884200D3401A5241CFD2014610467047C0 +S1132D9008B500F001F808BD7047FEE700B5010072 +S1132DA000200A00D2B2002A05D0022A09D005D395 +S1132DB0032A09D00AE01022100007E018221000AC +S1132DC004E02822100001E048221000C0B200BD37 +S1132DD0F8B505000C002868060080360027684610 +S1132DE007703800C0B2FFF7D9FF0100C9B28908E3 +S1132DF00800C0B2220092B2504380003018F2BDE5 +S1132E0000B5010000200A00D2B2002A082A0ED917 +S1132E10093A0ED0521E0FD0521E10D0521E11D09D +S1132E20521E12D0521E13D0521E14D016E00800A7 +S1132E3014E00C22100011E0102210000EE0142205 +S1132E4010000BE01822100008E02022100005E01A +S1132E503022100002E040221000FFE7C0B200BDA3 +S1132E60F8B505000C0000206946487069460870F2 +S1132E70210089B22800FFF7ABFF06003068000C80 +S1132E8007073F0F3800C0B2FFF7BAFFC0B2F2BD68 +S1132E9070B500231400E4B2002C0CD00468C025E3 +S1132EA0ED03254305604468640F6407CD00ED0815 +S1132EB0254345600BE00468BC4D2540056044682B +S1132EC0BB4E26408C04BB4D25403543456070BD48 +S1132ED010B40268B84B1340036002680B00DBB205 +S1132EE01B04F02424031C401443046010BC7047EA +S1132EF000B502685200520802600268AF4B1340EA +S1132F0003600A00D2B2002A09D0026880231B069B +S1132F101343036002688023DB051343036000BD91 +S1132F2000B50A00D2B2002A06D10268A44B1340AD +S1132F300360026802600CE00A00D2B2012A08D1E0 +S1132F4002689F4B1340036002688023DB04134331 +S1132F50036000BD30B50268803200231D001C00F0 +S1132F60057EED01AC4205D2A500551929000B6080 +S1132F70641CF5E730BDF8B4924982688023D150CF +S1132F8001234468256D2026B5431E00F6B2760160 +S1132F9020273E402E430096009D25650025866827 +S1132FA08027F551F1BC7047F8B4864982688023C4 +S1132FB0D15001234468256D1026B5431E00F6B296 +S1132FC0360110273E402E430096009D25650025BE +S1132FD086688027F551F1BC7047F2B40599069CC8 +S1132FE0079D089E37780776009F076042608360DC +S1132FF0C16004614561F1BC704730B50022110025 +S11330008260026142618261C260C2614262826224 +S1133010C2620262012303701300C37013000371C0 +S11330200023DB4343638363C363036414004425C5 +S113303044551400452544551400C8254455082416 +S11330404625445514002100C9B2202906DA21007E +S1133050C9B2890041188B64641CF4E71100417003 +S11330601100817011003023C1541100C923C154CF +S11330701100CA23C1541100CB23C1541100D5231C +S1133080C1541100D423C1541100D623C1541100DA +S1133090D723C1541100CC23C154D021425030BD98 +S11330A0F0B50024210002681368444D1D400B0054 +S11330B0DBB29B078026F60533402B43136005687B +S11330C02E68414F3740BC462600F6B236078027AB +S11330D07F053E4067463E432E60016809680A0E3C +S11330E01100C907C90FC9B20029F6D1F0BDF8B55E +S11330F00400206801250068000D2840C0B20028A3 +S113310014D0002021680A68520052080300DBB280 +S1133110DB0713430B6020680068000D2840C0B231 +S1133120002803D02000FFF73FFFF4E728002168C0 +S11331300B68264A1A400300DBB25B068026B604FD +S1133140334013430B6020680068400E2840C0B22F +S11331500028F8D16846057020680168174A0A40BB +S11331606946097889078023DB051940114301600A +S11331702A0023681E68144F3740BC461600F6B276 +S1133180360780277F053E4067463E431E60206821 +S11331900068000E2840C0B20028F8D020680068FB +S11331A0C00E2840C0B20028F1D0F1BDFFFF9FFF40 +S11331B0FFFF03E00000FC1FFFFFF0FFFFFFFFBF66 +S11331C0FFFFFFF052455355FFFFFFEFFFFFFFFDE9 +S11331D0F8B594B007000C0016003100C9B289B2EA +S11331E03800FFF7F5FD0500227A61682800FFF733 +S11331F04FFEA17A2800FFF76BFEE17A2800FFF763 +S113320077FE617A2800FFF78BFE207B002805D02B +S11332106846067101A9380000F009FD607A0128AA +S11332200AD1206969460E7039686A46127892009C +S11332308A1888231B01D05015B0F0BDF0B58DB0AD +S113324005000E0000206946487000206946087099 +S11332502800FFF790FE012029680A6852005208EE +S11332600300DBB2DB0713430B6028680068010D21 +S11332700800C007C00FC0B20028F6D030786946F5 +S113328048712868029002984068CE490140684617 +S1133290407940038022920110400843059005982C +S11332A0029948602800FFF722FF0120694608714F +S11332B02F683968C448084069460979C9058022DD +S11332C012041140014304910498386001206946B6 +S11332D0C8702C68616BBD4808406946C978090705 +S11332E08022520511400143039103986063280032 +S11332F0FFF730FE3020305CFFF750FD69468870E0 +S113330068468078002809D0802080006946897842 +S1133310FFF7EBFC297E48436946487068464078CD +S11333206946087128680690069800687F218843DA +S1133330694609794906490E01430C910C9806998E +S1133340086001206946C870286805900598006DDA +S1133350400040086946C978C90701430B910B989E +S113336005990865CE48B16809186A46D18129686B +S1133370049104990A6DCB4911406A46D2895205D9 +S1133380C94B13400B430A930A99049A1165F168D7 +S113339009186A46918129680B6DC44A1A406B4624 +S11333A09B891B04F82464031C4014430994099A60 +S11333B00A65326912186B465A812A68146DBC4B2F +S11333C023406C466489A702FC2424023C401C432D +S11333D00894089B136573691B186C4623812B683A +S11333E01C6DB44F2740BC466C4624896701F82401 +S11333F0A4003C4067463C430794079C1C65B469A1 +S113340020186C46E0802868046D1F27BC436F4673 +S1133410FF88FF06FF0E27430765F478002C6ED063 +S113342001206946887128680268A34911406A46E8 +S11334309279520780239B051A400A430692069903 +S1133440016031796A46517129680B68CB4A1A4088 +S11334506B465B79DB0380242402234013430593EA +S1133460059A0A60326C04922A680392049A039BB8 +S11334709A644422B25C6B461A712A681468C04B81 +S113348023406C4624792702C024A4003C401C43FA +S11334900294029B13604523F35C6C46E3702B6833 +S11334A05C6BB84F2740BC466C46E4782706F02492 +S11334B024053C4067463C435C63C827F75D012F05 +S11334C03BD1002069460870684600784621715C4B +S11334D0884232D26846007880003018806C694691 +S11334E009782A680B00DBB29B00D31888242401D6 +S11334F018516B461B785B1C6C462370E4E7002074 +S113350029680B686C4A1A400300DBB25B0780240D +S1133510A405234013430193019A0A6000222B68F7 +S11335201C68964F2740BC461400E4B2E40380278D +S11335303F023C4067463C431C60706B0390286824 +S113354003990161B16B02912968029A4A61F26B95 +S113355001922A68019B9361C823F35C6C46E37073 +S11335602B681C68BC4F2740BC466C46E478240496 +S113357080277F023C4067463C431C60C927F75DB7 +S1133580002F25D0002029680B68B44A1A40030094 +S1133590DBB25B048024A402234013430193019A09 +S11335A00A6001222B685C68AD4F2740BC461400BA +S11335B0E4B2240380277F013C4067463C435C60BF +S11335C024E000BFFFDFFFFFFFFF7FFFFFFFFFEFF0 +S11335D0012029680B68A14A1A400300DBB25B048E +S11335E08024A402234013430193019A0A60002219 +S11335F02B685C689A4F2740BC461400E4B224034D +S113360080277F013C4067463C435C60D420305CAB +S1133610002853D0012001006A46917129680B6883 +S1133620904A1A406B469B799B058024E40323400F +S113363013430593059A0A6002006B465A712A687F +S11336401468894B23406C466479A4068027FF04E0 +S11336503C401C430494049B136003006C46237198 +S11336602B681C68814F2740BC466C462479A4040F +S11336708027FF023C4067463C430394039C1C6044 +S113368004006F46FC706C690294029CA46C0127D0 +S1133690BC436F46FF7838402043029CA06453E04B +S11336A0FFFF0000FFFF1F800000E07FFFFFE0FF3F +S11336B0FF03FFFF1FFCFFFFFFFFFFDF00200100F0 +S11336C06A46517129680B68664A1A406B465B79F1 +S11336D09B058024E403234013430593059A0A6061 +S11336E002006B461A712A6814685F4B23406C46CB +S11336F02479A4068027FF043C401C430494049BC3 +S1133700136003006C46E3702B681C68574F274016 +S1133710BC466C46E478A4048027FF023C4067461C +S11337203C430394039C1C606C690294029CA76C48 +S11337300124A743BC460700FFB23C00E407E40FA2 +S113374067463C43029FBC64D520305C69460871DF +S113375028680268424911406A461279120380239C +S11337605B011A400A43049204990160D621715CFA +S11337706A46D17029684B68004A05E0FF7FFFFF65 +S1133780FFFCFFFFFFFFFFF01A406B46DB78DB0313 +S113379080242402234013430393039A4A60D722CC +S11337A0B25C2B685C68324F2740BC461400E4B21C +S11337B0A4038027FF013C4067463C430294029CDB +S11337C05C6000273800CC21715CC0B288422DD2E5 +S11337D00020D02171583A00D2B214235A438C5A93 +S11337E0220092B2D02030583900C9B21423594370 +S11337F0435AD020305884463900C9B2142041437A +S1133800604640184088181882420DDA2200D2B26D +S1133810D02030583900C9B2142359434118280024 +S1133820FFF7D6FC641CDBE77F1CCBE7280000F025 +S113383082F92800FFF734FC002029680B680D4A40 +S11338401A400300DBB2DC0580231B041C40144334 +S11338500C600DB0F0BD0000FFFFFEFFFFFFFDFF99 +S1133860FFEFFFFFFFFFBFFFFFFFFFFBFFFFFBFFBC +S1133870FFBFFFFFFFFF7FFF38B504000D0029786D +S113388089B22000FFF7A4FA0168C02212050A4396 +S1133890026031BDF1B50C00217889B20098FFF7C0 +S11338A097FA05000835217889B20098FFF7D8FA0D +S11338B000210B000A001300DBB2834238D2032339 +S11338C01E00324209D129602B681600F6B2A619EF +S11338D0367A36061E432E6028E01600F6B21E40E5 +S11338E0012E08D12B681600F6B2A619367A3604D2 +S11338F01E432E601AE01600F6B21E40022E08D1B6 +S11339002B681600F6B2A619367A36021E432E60CC +S11339100CE01600F6B23340032B07D12B681600D7 +S1133920F6B2A619367A1E432E602D1D521CC2E72C +S1133930F1BDF8B506000C00217889B23000FFF71C +S113394047FA05002868000C0007000FFFF758FA33 +S1133950482160542868400D0100C907C90F684612 +S11339600170281D69460978002904D00168C9003E +S1133970C908616004E00168890C4905490D61606A +S1133980051D217889B23000FFF76AFA00210A0088 +S11339900A000300D2B2DBB29A422AD203221300F5 +S11339A0194206D12A68120E0B00DBB2E3181A7210 +S11339B01DE00B00DBB21340012B06D12A68120C68 +S11339C00B00DBB2E3181A7211E00B00DBB21A40F1 +S11339D0022A06D12A68120A0B00DBB2E3181A7213 +S11339E005E02A680B00DBB2E3181A722D1D491C8E +S11339F0CEE732689268F1BDF0B500252E000A7852 +S1133A00D206D20E0124230093400F78402F12DBFC +S1133A101C0002260568002E0AD0022E04D005D30D +S1133A20032E07D12C6705E06C6703E0EC6201E02C +S1133A302C63FFE725E00E78202E11DB1D000668BD +S1133A40002C0AD0022C04D005D3032C07D13567EF +S1133A5005E0756703E0F56201E03563FFE710E018 +S1133A601C000668002D0AD0022D04D005D3032DB6 +S1133A7007D1346705E0746703E0F46201E034635E +S1133A80FFE7F0BDF0B50300002215000878C40676 +S1133A90E40E01200600A6400F78402F16DB02201A +S1133AA01D6800280DD0022805D007D303280BD1A8 +S1133AB02F6F3A0008E06F6F3A0005E0EF6A3A00B2 +S1133AC002E02F6B3A00FFE732402EE00D78202D04 +S1133AD015DB1D6800280DD0022805D007D3032864 +S1133AE00BD12F6F3A0008E06F6F3A0005E0EF6AE0 +S1133AF03A0002E02F6B3A00FFE7324015E0100075 +S1133B001D6800280DD0022805D007D303280BD147 +S1133B102F6F3A0008E06F6F3A0005E0EF6A3A0051 +S1133B2002E02F6B3A00FFE73240002A01D0012067 +S1133B3000E00020F0BDF0B5017E032937D100215B +S1133B40C9430D0002270668002F0AD0022F04D0B3 +S1133B5005D3032F07D1356705E0756703E0F562E8 +S1133B6001E03563FFE70A0001230468002B0AD053 +S1133B70022B04D005D3032B07D1226705E062672B +S1133B8003E0E26201E02263FFE700260568002EFD +S1133B900AD0022E04D005D3032E07D1296705E0ED +S1133BA0696703E0E96201E02963FFE73EE0017E23 +S1133BB0022925D10021C9430A0001250368002DEB +S1133BC00AD0022D04D005D3032D07D11A6705E0CE +S1133BD05A6703E0DA6201E01A63FFE7002604682B +S1133BE0002E0AD0022E04D005D3032E07D121675C +S1133BF005E0616703E0E16201E02163FFE715E0AE +S1133C00017E012912D10021C94300230268002B3F +S1133C100AD0022B04D005D3032B07D1116705E08A +S1133C20516703E0D16201E01163FFE7F0BDF0B535 +S1133C3000231E000A78D406E40E01221500A540D4 +S1133C400F78402F1ADB2A0002230668002B10D0BD +S1133C50022B06D009D3032B0FD1B76E1743B766D7 +S1133C600BE0F76E1743F76607E0776A174377624E +S1133C7003E0B76A1743B762FFE735E00E78202EFA +S1133C8019DB2B000668002A10D0022A06D009D3BB +S1133C90032A0FD1B76E1F43B7660BE0F76E1F43BD +S1133CA0F76607E0776A1F43776203E0B76A1F434A +S1133CB0B762FFE718E02A000668002B10D0022B39 +S1133CC006D009D3032B0FD1B76E1743B7660BE0A9 +S1133CD0F76E1743F76607E0776A1743776203E0E6 +S1133CE0B76A1743B762FFE7F0BDFFB591B000258F +S1133CF001200990012008900820019003210491DB +S1133D000222059214221092834A0F92FA229205FB +S1133D100E921BAA1278002A0DD1804A0D925E22BF +S1133D2002920C911F2107910299079A8918491C44 +S1133D300B910A900CE0794A0D92262202920C9182 +S1133D40072107910299079A8918491C0B910A9037 +S1133D50139800F0EDF8040001260D98B04259DBE9 +S1133D60129800F0E5F80500300000F0F1F80100C9 +S1133D70280000F0F8F80500139800F0D9F80100C5 +S1133D80280000F0F0F800F041F9009000980028B5 +S1133D9003D000980A99884200DA3BE0009800F0CA +S1133DA0D7F80100280000F0DEF80700139800F0AF +S1133DB0BFF80100380000F07EF98021090400F00A +S1133DC0D3F908D8139800F0B3F80100380000F0D4 +S1133DD072F9020006E0139800F0AAF8390000F026 +S1133DE06AF902000B980099884211DB2000110047 +S1133DF000F0BAF90CD809960098019014001098B4 +S1133E000099884204DB10000F9900F0C1F901D336 +S1133E10761CA2E714A8008800F08AF80E9900F036 +S1133E20CAF9039001980299884201DA0198029034 +S1133E30029C0C98844225DB2000401C38494843EE +S1133E400199FEF74FFF050014A80088281A0128DD +S1133E5003DB14A800882F1A02E014A80088471B6B +S1133E6014A8008885420DDB380000F071F803992E +S1133E7000F08EF904D20494380000F069F803903D +S1133E80641ED6E701980499401A401E05902548FF +S1133E90039001250598A84221DB21486843019934 +S1133EA0FEF720FF07001AA80088381A012804DB4F +S1133EB01AA80088381A069003E01AA80088C01BC4 +S1133EC00690069800F044F8039900F061F904D2D2 +S1133ED00895069800F03CF803906D1CDAE7099801 +S1133EE011990860049800F0CFF90FA20CCA00F0F1 +S1133EF0D5F900F095FA11998860049811998968A8 +S1133F00401A1199C8600598119908610898119987 +S1133F10486015B0F0BD0000CDCCCC3DFF030000DF +S1133F201027000000401C46333333333333E33F60 +S1133F309D2102000AD002D4491E9218FCD5C9055D +S1133F40100A1206524100D3012A4841704700006A +S1133F509D210200EED55242F446FFF7EBFF012209 +S1133F60D2071043604730B405004D400122D20708 +S1133F7015404B180418240E25D01B0E2CD0FF2CF2 +S1133F8031D0FF2B34D0E41A00020902104311434C +S1133F9043084808D10D1B1A02D2641EDB181B18F3 +S1133FA0DB18834200D31B1A4941F9D37F3423DD44 +S1133FB0FF2C05DAE40548086041284330BC70470B +S1133FC0FF20C005F9E728001B0E03D0FF2BF5D115 +S1133FD04902F3D0D043F1E7FF2C01D14002F9D1DB +S1133FE0FF20C005E9E74002F4D1FF2BF8D1F1E747 +S1133FF028004902E2D0EDE70B0200202442DCD184 +S11340005B129B1CD9D9D805D7E7FEE70122D2075A +S11340100118090E7F3910D449421F310FD40018FA +S113402005D2C0011043C84000D5D0437047C00139 +S11340301043C84005D440427047002070470042F6 +S1134040F3D5100070470122D20703004B402ED451 +S1134050431A01D2C01AC91830B44B180418240EDC +S11340601B0E22D0FF2C20D0E31A182B1DDC0902D2 +S11340701143C40D641E0002104394461925ED1A21 +S11340800A00AA40D940451801D36D08A41CE405D0 +S1134090D209280A2D062A436546AA41604103181D +S11340A01B0EFF2B01D3C00DC00530BC704751401F +S11340B006E05140CCE70122D20703004B40F8D47C +S11340C0431A03D2C01AC9185040514030B44B1897 +S11340D0090211430418240E1B0E40D0FF2C3AD0C1 +S11340E025009D410BD31ED8C50D4002401A0BD3A9 +S11340F0ED050100400AC90591416841D5E7C50DA8 +S113410040024918401AD0D001214008491C001827 +S1134110FCD58C4204D36D1A000AED054019C4E79E +S1134120E8051040C1E7182DBFDCAC1C0D00E140D0 +S1134130E5414D40012D4941C40D00021043451A8B +S113414001D46D199543641EE405280A2D06954192 +S1134150604130BC7047FF2BA7D1D843A5E7244268 +S1134160A3D10020A1E7FEE70CB401221206031834 +S1134170DA4207D84B18DA4204D802000A439218EC +S113418002D281420CBC7047FCD088420CBC704700 +S11341900CB4012212060318DA4207D84B18DA428B +S11341A004D802000A43921802D288420CBC704719 +S11341B0FCD08142FAE730B405004D400122D20719 +S11341C015404B180418240E2ED01B0E32D0FF2C91 +S11341D034D0FF2B3AD0E4180002090210431143F3 +S11341E0000A090A9446C2B24A43000AC3B24B43C6 +S11341F0000A4843110A5B181A43D2B2190A091873 +S113420001D44918641E080A7F3C23DBFE2C08DA1B +S1134210E40509061143634699416041284330BCD3 +S11342207047FF20C005F9E728001B0EFF2BF6D1CD +S1134230D043F4E72800FF2CF1D1F9E74002F7D18D +S1134240FF2B01D14902F3D1E005E7E7D805490284 +S1134250E4D0EDE743020020641CDFD15B129B1C19 +S1134260DCD9D805DAE7FEE7010042221201D21EAA +S1134270004207D002D4521E0018FCD5C10A4005E2 +S113428012058918704700000100EED54042F4463B +S1134290FFF7EBFF0122D20711436047F0B50E0090 +S11342A05E400125ED072E40B446AE0ADF184C18D7 +S11342B0F44208D2F7420ED2640D01D07F0D12D120 +S11342C000206146F0BD05D1F74201D87F0D05D12C +S11342D00020C143F0BDFBD1640DF9D00020C143DF +S11342E0490549088FE0E419C902DB0229432B433D +S11342F0DB0A460DC00231438E4630B487B295B214 +S11343007D432E0CADB2140C7C43A419260C24045A +S113431025439CB27C43A419190C7943270CC91971 +S1134320A4B20F043C43090C000C97B247432E0C73 +S1134330BE193543ADB2170C4743360CBF19A6B2AC +S1134340BF193E043543240C3E0C36199FB2474333 +S1134350BF19BCB23E0C89191F0C47437F183E0499 +S11343603443390C704680B297B247432E0CBE19C1 +S11343703543ADB2170C4743360CBF19A6B2BF196B +S11343803E043543240C3E0C36199FB24743BF19F3 +S1134390BCB23E0C89191F0C47437F183E043443BA +S11343A0390C77463F0C90B278432E0C80190604E2 +S11343B0ADB22E43050CA0B22D18120C7A4350193D +S11343C0020C80B2240CA4189AB27A431219140471 +S11343D02043120C89181B0C7B43C91830BCEF0A0C +S11343E0394203D1B61940414941641E6F12BF0DD1 +S11343F0E41B0BDBFF19BC4211DA24050027420839 +S1134400AE417841614166463143F0BD641C05D13B +S1134410401C6141CF0201D34908F4E750E75DE74E +S11344204A1812D2400DC90208430121C9070843A2 +S1134430520D40210901521A521C06D452421F3215 +S113444001D4D0407047C017704700207047000067 +S1134450F8B59CB0050000263700300069460870A6 +S1134460029601963400300069468870402200218B +S11344700CA800F00DFE04A8D349202200F012FE7F +S1134480082069464870FF20801C0390300001001A +S11344906A465278C9B291420FD20021C9430CAA8C +S11344A00300DBB2DB00D15031000CAA0300DBB205 +S11344B0DB00D2189180401CE9E7370038006946D8 +S11344C04978C0B288424BD20220040003982100EC +S11344D089B288423ED3286804A93A00D2B2920035 +S11344E08958FEF702FC210089B2FEF7FEFB019019 +S11344F001986968884213D10CA83900C9B2C9006F +S113450041188C803900C9B2C900401887710CA8C1 +S11345103900C9B2C900465001206946887019E0C3 +S113452001986968884213D20CA83900C9B2C9003D +S113453041188C803900C9B2C90040188771686875 +S11345400199401A0CA93A00D2B2D200885001E075 +S1134550641CBBE768468078002801D17F1CADE766 +S1134560684606700CA869460978C900405802904C +S11345700126300069464978C0B2884211D20CA89D +S11345803100C9B2C90040580299884207D20CA828 +S11345903100C9B2C9004058029068460670761CC2 +S11345A0E7E70CA869460978C900411889880229F7 +S11345B017DA286804A96A46527892008918091FF4 +S11345C00968FEF792FB0399FEF78FFB019068469A +S11345D04078401EA8600398801EE8600198286116 +S11345E014E069460978C90041188979A9606946C7 +S11345F00978C90040188088801EE86068680CA9A2 +S11346006A461278D2008958401A28611DB0F0BD5C +S1134610F8B58AB004000D00002000900700029055 +S11346202000006E00900021684600F0F4FC002198 +S1134630684600F0E1FC697B684600F0A3FC697AF7 +S1134640684600F075FCA97A684600F068FC686862 +S113465006902868059005A8FFF7FAFE07986946B2 +S1134660087108980290029E03940398006CFF213D +S113467088433100C9B20143049104980399086442 +S113468068460179684600F061FCE989491E89B2EF +S1134690684600F0F3FCA87B800604D5E97E6846F2 +S11346A000F07EFC03E00021684600F079FCE97A22 +S11346B0684600F059FC687D002805D0022829D0FE +S11346C010D303283ED04BE00021684600F0B2FC32 +S11346D0E97F684600F090FC2020295C684600F0E1 +S11346E09AFC4AE00121684600F086FC00216846F5 +S11346F000F091FC287C002804D10021684600F0D9 +S113470099FC06E0287C012803D10121684600F0C9 +S113471091FC32E0287C002804D10021684600F096 +S113472089FC06E0287C012803D10121684600F0B9 +S113473081FC0121684600F05FFC0021684600F01E +S11347406AFC1AE00021684600F074FCE97F6846C0 +S113475000F052FC2020295C684600F05CFC0CE070 +S11347600021684600F066FCE97F684600F044FCDE +S11347702020295C684600F04EFC009820660BB0AF +S1134780F0BDF8B50A7A6B461A700200536A6C469B +S11347902478012C03D101241C43546202E05C08F8 +S11347A0640054620C7BCD7AAC4005006E6ACB4F3A +S11347B03740BC462600F6B23702F02636013E40AA +S11347C067463E436E62F1BD1CC30000F6B588B077 +S11347D0099909780200D6690B00DBB2012B03D1D9 +S11347E001233343D36102E073085B00D361099B67 +S11347F05B780400E5691F00FFB2012F03D1022199 +S11348002943E16103E0290002229143E16109990E +S113481089780200566A0F00FFB2012F03D10823E2 +S11348203343536203E033000824A3435362099BD8 +S1134830DB780400256A1F00FFB2012F04D1802118 +S113484049002943216202E0A549294021620090E0 +S113485000210E000122009F7F6A1740002F01D023 +S113486013001E00F6B2002E0FD1099B5B790400E1 +S1134870656A1E00F6B2012E03D104262E43666239 +S113488003E02E000427BE436662099BDB796C4675 +S1134890237005002E696B461B78012B03D104237A +S11348A033432B6103E033000424A3432B61099BAE +S11348B09B796C46237103001C696F463F79012F75 +S11348C003D1082525431D6103E025000826B543CF +S11348D01D61089D6D786E46F5700490049D2E6CE4 +S11348E0804D35406E46F67836022E430796079D76 +S11348F0049E3564089DAD786E46B5700390039DA3 +S11349002E6C794D35406E46B67836042E430696A5 +S1134910069D039E3564089DED786E467570029081 +S1134920029D2D6C2D022D0A6E46767836062E4396 +S11349300596059D029E3564089D2D796E46357059 +S113494005006F6A7026B743BC466E463678370159 +S113495070263E4067463E436E62089F7F79002F73 +S113496005D0022F39D024D3032F4AD06DE0089B01 +S11349709B79002B00D10A0003005C6A1500EDB29C +S1134980002D04D08025ED0425435D6202E0574DDF +S113499025405D6205006E6A554F3740BC460E00E7 +S11349A0F6B23706C026B6043E4067463E436E6202 +S11349B06CE013000400616A4D4D0D401900C9B24A +S11349C00E06C021890431402943616205006E6AE4 +S11349D08027FF0437436F6258E002230400616AB2 +S11349E0434D0D401900C9B20E06C021890431405F +S11349F02943616205006E6A8027FF0437436F62B2 +S1134A0044E0089B9B79002B01D01100FFE70200D2 +S1134A10536A0C00E4B2002C04D08024E4041C4348 +S1134A20546202E0314C1C405462032405006E6A57 +S1134A302F4F3740BC462600F6B23706C026B604D0 +S1134A403E4067463E436E6220E0089B9B79002B04 +S1134A5000D10A0003005C6A1500EDB2002D04D0F9 +S1134A608025ED0425435D6202E0204D25405D6212 +S1134A7005006E6A1E4F3740BC460E00F6B237067C +S1134A80C026B6043E4067463E436E620AB0F0BD9F +S1134A908149016081494160012202720021417211 +S1134AA08172C172017342730822C281C175017699 +S1134AB041768176C17601774177C177202281548E +S1134AC08177022202740A22130043741300837450 +S1134AD0C27401754175817570470000FFF0FFFFD6 +S1134AE0FFFEFFFFFF00FFFFFFFF00FFFFFFFFFBD5 +S1134AF0FFFFFFFCF0B587B004000D0000206946FD +S1134B004870206802900298006906900698012176 +S1134B108843029908612068019001980069059012 +S1134B20059880214900014301980161276838698B +S1134B3004900498802189000143396100BF00BFBB +S1134B4000BF29002068FFF71CFE2A001732290045 +S1134B5010312068FFF73AFE012001006A46117007 +S1134B60266831690391039908433061290020685C +S1134B70FFF74EFD07B0F0BDF2B482B002990160B8 +S1134B8001680A690192019A80235B0013430B6157 +S1134B90026813690093009B8024A4001C431461E1 +S1134BA001230468256902262E43266100BF00BF45 +S1134BB000BF002607683E61F7BC7047F0B50300EC +S1134BC00022100014000D006D1E17D06D1E1DD0A4 +S1134BD0FE3D24D080267600AD1B29D08026B60069 +S1134BE0AD1B2ED08026F600AD1B33D080263601B7 +S1134BF0AD1B38D08B4EAD1B3ED046E01D686F69AF +S1134C003E00F607F60FF6B234003EE01D686E690A +S1134C1077083E00F607F60FF6B2340035E01D685B +S1134C206E69370A3E00F607F60FF6B234002CE040 +S1134C301D686E69770A3E00F607F60FF6B2340077 +S1134C4023E01D686E69B70A3E00F607F60FF6B258 +S1134C5034001AE01D686E69F70A3E00F607F60F85 +S1134C60F6B2340011E01D686E69370B3E00F6079A +S1134C70F60FF6B2340008E01D686E69370E3E0088 +S1134C80F607F60FF6B23400FFE7002C01D001223C +S1134C901000C0B2F0BD000000B4C40440420F00D4 +S1134CA0FFB583B0012069460870002420000399F1 +S1134CB009682200CB6DDB06DB0E1025EB1A6D466E +S1134CC06B706B465B786D46AD8A9BB2AB4200D28B +S1134CD0A2E00194250020006946488003980068FA +S1134CE0006E0190002101A800F078F9012101A8CB +S1134CF000F065F9002101A800F08DF9002101A858 +S1134D0000F07AF96846007CC100491E89B201A806 +S1134D1000F0B4F901980399096808662600300088 +S1134D206946898A80B2884269D203980168220060 +S1134D3001204F6903003B40DBB2002B06D16D1C00 +S1134D4039498D42F1D321006A4611706946097CC4 +S1134D50012907D10699320092B2895C039A12683C +S1134D60516614E06946097C022908D1069932008B +S1134D7092B25200895A039A1268516607E0069962 +S1134D80320092B292008958039A12685166250043 +S1134D900399096822000B6F5B080340002B01D0C4 +S1134DA003001A00D2B2002A06D06D1C1E498D429F +S1134DB0EED32000694608706846007C012807D1BC +S1134DC003980068406F0C99320092B2885414E042 +S1134DD06846007C022808D103980068406F0C994B +S1134DE0320092B25200885207E003980068406F84 +S1134DF00C99320092B292008850761C8FE7002101 +S1134E0001A800F0EBF8002101A800F0D8F80198FF +S1134E1003990968086601E06846047068460078EA +S1134E2007B0F0BD00F0FF00E9030000F0B5030097 +S1134E30002210000C00641E14D0641E1CD0FE3C22 +S1134E4024D080256D00641B2BD08025AD00641B0D +S1134E5032D08025ED00641B39D080252D01641BE0 +S1134E6040D04AE0012425001E68B7692F40AF42B4 +S1134E7000D12200100040E002241D68AE692640E3 +S1134E80A64201D101263200100036E080246400DD +S1134E901D68AE692640A64201D1012632001000E9 +S1134EA02BE08024A4001D68AE692640A64201D1EF +S1134EB001263200100020E08024E4001D68AE6961 +S1134EC02640A64201D101263200100015E08024BC +S1134ED024011D68AE692640A64201D10126320094 +S1134EE010000AE0802464011D68AE692640A642D1 +S1134EF001D1012632001000FFE7C0B2F0BD70B44A +S1134F000A0003689D6D524C2C401500EDB22E042E +S1134F10F8256D03354025439D6570BC70470268D4 +S1134F20520052080B00DBB2DB07134303607047E7 +S1134F3010B40268474B13400A00D2B2920780248F +S1134F40E40522401A43026010BC704710B40268A2 +S1134F50414B13400A00D2B2D406E022920522400B +S1134F601A43026010BC704710B402683B4B1340F4 +S1134F700A00D2B21406C022920422401A430260EC +S1134F8010BC704710B40268354B13400A00D2B20B +S1134F90D2058024240422401A43026010BC7047C6 +S1134FA000B502680B00DBB2012B04D18023DB03C4 +S1134FB01343036002E02B4B1340036000BD00B5B4 +S1134FC002680B00DBB2012B04D180239B03134343 +S1134FD0036002E0244B1340036000BD10B4026878 +S1134FE0224B13400A00D2B21205802464032240EB +S1134FF01A43026010BC704700B502680B00DBB2B4 +S1135000012B04D180231B031343036002E0184BDC +S11350101340036000BD00B502680B00DBB2012B36 +S113502004D18023DB021343036002E0114B1340DD +S1135030036000BD10B402680F4B13400A00D2B2E3 +S11350401404C022920222401A43026010BC70472A +S1135050FFFFE0FFFFFFFFBFFFFFFFC7FFFFFFFCF6 +S1135060FFFF7FFFFFFFBFFFFFFFDFFFFFFFEFFF3C +S1135070FFFFF7FFFFFFFBFFFFFFFCFF0268120BC0 +S113508012030B009BB21B051B0D134303607047F7 +S113509010B50400080011000200200000F02AF8F6 +S11350A0200010BD70B4103A03D378C9103A78C008 +S11350B0FBD2530701D318C918C001D508C908C0C9 +S11350C0D20704D30B880380891C801C002A01D5D5 +S11350D00B78037070BC70478B0701D18307E1D054 +S11350E0124205D00B78491C0370401C521EF9D1A2 +S11350F0704700001206130A1A43130C1A4300BF28 +S1135100094205D0830705D00270401C491EF9D11D +S1135110704700001300103906D330B41400150092 +S113512010393CC0FCD230BC490700D30CC000D5B8 +S113513004C0890002D30280801C002900D50270BB +S11351407047000000B5010008000200D2B2802AB6 +S113515001DB7F221000C0B200BD00B501000800D1 +S1135160C0B2F12805DB0800C0B2FA2801DA012038 +S113517006E00800C0B2802801DA080000E0002040 +S1135180C0B200BDFEB582B0070000252C006E46FB +S11351903F20307030786946097AF0220A43024091 +S11351A032706846007B70706846007CFFF7CAFF67 +S11351B0B0703878002810D0032004002000C0B25A +S11351C0082804DA2000C0B23554641CF6E708222B +S11351D06946F868BB6D984704E003226946F8689D +S11351E0BB6D984740B205B0F0BDFEB50600002087 +S11351F0050001006A460F2313701378F48AF02720 +S113520027431F40177004002100C9B2F38A89B2F2 +S1135210994209D231692300DBB2C95C2300DBB2B5 +S1135220D3185970641CEFE73178002916D00500B3 +S11352302800C0B20721F38AC91A884208DA280074 +S1135240C0B2F18A40181018CC2141706D1CEFE7F0 +S113525008226946F068B36D984706E0F28A521C4A +S1135260D2B26946F068B36D984740B2FEBD3EB510 +S1135270050068461F2101700178EA8A92B2120A79 +S1135280F02313430B400370E98A4170002421008A +S1135290C9B2E4B22100C9B2062909DA2969220097 +S11352A0D2B2895C2200D2B282189170641CF1E7F8 +S11352B008226946E868AB6D9847010049B20029A5 +S11352C004D1298B891D29830121A97640B23EBDD1 +S11352D0FEB5060000273900C9B201A82F220270CA +S11352E00278B37EF0241C4314400470F28A338B9A +S11352F0D21A6B461A806A461288082A02DB0722F1 +S11353006B461A803C00E4B22100C9B26A46128896 +S113531089B291420BD23169328B2300DBB2D218AD +S1135320895C2200D2B282185170641CECE7317897 +S113533000291BD03900C9B23D00EDB22A00D2B217 +S113534007216B461B88C91A8A4209DA2900C9B2A7 +S11353506A46128889184118CC224A706D1CEDE700 +S1135360082201A9F068B36D984707E068460288EF +S1135370521CD2B201A9F068B36D9847010049B23A +S113538000290BD1318B6A46128889183183B17E8A +S1135390491CB176B17E102900DBB77640B2FEBD60 +S11353A0F8B504000D00160000210F000F202B7823 +S11353B00200134206D03200D2B2521E2B780340B0 +S11353C09A4208DA606D002802D0A248616D8847CD +S11353D00620C04315E02A7810404222A05208005B +S11353E0C0B24222A25A80B2904209D20800C0B28E +S11353F028184078E26B0B00DBB2D054491CEEE76E +S11354000020F2BDF8B504000D00170000210800CB +S11354106A4610703800C0B2082808D0606D0028B1 +S113542002D08D48616D88470620C04339E0287852 +S11354300002F0221201024068781618300080B28F +S1135440082808DA606D002802D08448616D884716 +S11354500620C04325E04020205A320092B29042F8 +S113546008D2606D002802D07D48616D8847022013 +S1135470C04316E0422026520800C0B2062809DACA +S11354800800C0B228188078E26B0B00DBB2D0545D +S1135490491CF1E706204422A05201204622A054D0 +S11354A00020F2BDF4B505000C00002217004620D0 +S11354B0285C21780907090F884202D00320C043E1 +S11354C040E04220285A4421695A461A300080B2EA +S11354D0082801DB0720060068460078401E3100DA +S11354E089B2884208DA686D002802D05D48696D87 +S11354F088470620C04325E011000800C0B23300ED +S113550080B29BB298420CD2E86B0B00DBB244270A +S1135510EF5BDB190F00FFB2E7197F78C754491C12 +S1135520EBE74420285A80194423E8524620285C9B +S1135530401C4623E8544620285C102801DB462002 +S11355402A540020F2BD70B504000D00160030008E +S1135550C0B2032808DA606D002802D04248616DA9 +S113556088470620C04300E0002070BD70B50400E9 +S11355700E0015002B009BB23200E168200000F001 +S113558001F870BDFEB5040000263700002C02D1DE +S11355900020C0435CE0A08A69460989884208D299 +S11355A0606D002802D03148616D88470220C043F5 +S11355B04EE03420205C012808D1606D002802D020 +S11355C0CA48616D88470120C04341E068460089AC +S11355D0E0823000208335002800C0B26946098982 +S11355E080B2884209D201982900C9B2405C21697D +S11355F02A00D2B288546D1CEEE7E08A082804DA47 +S11356002000FFF7F2FD070020E02000FFF72FFE47 +S11356100700380040B2002818D13000A0833000C1 +S1135620A0773000E077E06D80472200203203C28B +S1135630083AE06D8047002264305141220028324C +S113564003C2083A2663012034216054380040B272 +S1135650FEBD000084C20000B0C200007CC1000096 +S1135660B4C10000DCC20000FCC20000ECC10000B8 +S1135670FFB583B004006846007E022803DB684659 +S1135680007E092800DB2FE100252900C9B228008B +S1135690C0B201006A46127EC9B2914209D205998C +S11356A00200D2B2895C01AA0300DBB2D154401CCF +S11356B0EFE72F00FFB23800C0B208216A46127E1D +S11356C0891A884208DA01A83900C9B26A46127EEA +S11356D0891845547F1CEEE701AE3078C0B200094A +S11356E0002806D0022865D021D3032800D1B3E0D6 +S11356F0FAE05120205C012804D10520C043502148 +S1135700605401E0502025546846027E01A920001F +S1135710FFF746FE694608706946002008560028CF +S113572004D10498A063022051216054DCE051208C +S1135730205C012804D10520C0435021605401E0BD +S1135740502025546846027E01A92000FFF75AFE26 +S1135750694608706946002008560221C9438842F8 +S11357600CD10720C04350216054512025540023FC +S1135770002202212000FFF705FDB5E06946002064 +S11357800856002815D10498A063012051216054C3 +S113579060784721605401234720225C00212000C7 +S11357A0FFF7F0FCE06D8047002264305141A064B3 +S11357B0E16499E05120205C012804D00520C04315 +S11357C05021605490E00498A16B884200D08BE093 +S11357D06846027E01A92000FFF764FE694608704E +S11357E00326F643694600200856B04207D101A8B3 +S11357F000F0B6FB502026545120255474E069462D +S113580000200856002826D1E06D8047002264302D +S11358105141A064E1644420205A4221615A8842E3 +S113582003D302205121605415E06078002812D07F +S11358304720205C401E472160544720205C0028FC +S113584009D160784721605401234720225C00215C +S11358502000FFF797FC47E03420205C012843D167 +S11358606846027E01A92000FFF76DFE69460870B4 +S1135870694600200856002835D1E06D8047002293 +S1135880643051412200283203C2083A0F20317893 +S11358900140022906D10720C0432063022034219D +S11358A0605420E03178014001290CD1E07F401C94 +S11358B0E077E07F022816DB0620C0432063022045 +S11358C0342160540FE0317801420CD17078002803 +S11358D002D18448A08301E07078A083B078FFF7F8 +S11358E03CFCA077E577FFE707B0F0BD20C20000DD +S11358F0FEB50100089A0020030051240C5D022C1F +S113590002D00420C04328E08C6B8D68AC4201D1E6 +S1135910012400E00400009D2C7042240C5B6D46C1 +S11359202D892600B6B2B54202D26D462D892C00CF +S113593005002B0026009BB2B6B2B34209D2CB6B52 +S11359402E00B6B29B5D019E2F00BFB2F3556D1CB5 +S1135950EFE714805123C8540020FEBD70B4020048 +S11359600B00187810705878507058685060986818 +S11359709060D868D06018691061988A9082002479 +S11359802000D08220001083200090762000908395 +S1135990200090772000D0770020002115002035CA +S11359A003C5083D1500283503C5083D14632500CB +S11359B0342695559D69D5639D8B402695532500C6 +S11359C04226955325004426955325004626955591 +S11359D02500472695559064D164200050215054E9 +S11359E051201454186A5065586A9065986AD065B5 +S11359F070BC704770B504003420205C01285AD173 +S1135A00384DA08BA84202D0A08B002841D0A07FA3 +S1135A10002810D0A07F00283BD0E06D8047020012 +S1135A200B002000203003C8801A9941002930DC83 +S1135A3001DB00282DD22000FFF74AFC06003000CD +S1135A4040B2002822D1A08BA84202D0A08B4019DA +S1135A50A083E06D80470022643051412200283247 +S1135A6003C2083AE06D804702000B00A07F0021CA +S1135A70801859412200203203C2083A208BE18A5F +S1135A80884206D300203421605402E002203421ED +S1135A906054E06D8047220028320CCA121A8B41F0 +S1135AA0002B08DC01DB002A05D20120C04320635F +S1135AB00220342160545120205C012811D1E06D72 +S1135AC08047A26CE36C121A8B41002B09DC01DBCA +S1135AD0002A06D20220C0435021605400205121E4 +S1135AE0605470BDFFFF000008B4024B9C4608BC24 +S1135AF06047C04639020020F0B5020052B2002AC5 +S1135B0017D41822B74B040064B2A408A4001C598B +S1135B10FF25C6001640B540AC438D01EDB2C6006A +S1135B20324095402543020052B2920892009D50A3 +S1135B301BE00F22AC4B182405006DB21540083D44 +S1135B40AD08AE0005006DB22A40083A92089200F2 +S1135B509A58FF25C7002740BD40AA438D01EDB2E6 +S1135B60C7003C40A54015439D51F0BD10B504004D +S1135B70601E80214904884201D301200EE0601E8A +S1135B809A49086003210020C043FFF7B5FF0020B5 +S1135B90974908600720BD490860002010BD002215 +S1135BA002604160012303724272704700B5017ABA +S1135BB000290FD0417A00290CD101684268914232 +S1135BC008D20168491C016001684268914201D110 +S1135BD00121417200BD70B504000E001500AC48EF +S1135BE0215AAC482018FFF7DAFF7820205C0128FE +S1135BF006D02A0092B2310020001830FFF7B6FC1C +S1135C0070BDFEB505000E001400082100226F4689 +S1135C103800FFF76FFA2000C0B2782805D09C48FE +S1135C20295A9C482818FFF7BAFF7920285C0028D5 +S1135C3014D02000C0B211280FD02000C0B2122806 +S1135C400BD02000C0B2312807D02000C0B27E287B +S1135C5003D02000C0B27F2800D10AE068467F212B +S1135C600170467084700322694628001830FFF7DB +S1135C707DFCF7BD10B5040088200001201803C87E +S1135C800022401C514188221201A21803C2083A82 +S1135C90892000012018FFF789FFBD482018FFF76D +S1135CA085FF7C482018FFF781FF10BDB94803C861 +S1135CB0704780B5B8480168491C0160B54A03CAF9 +S1135CC0083A0023401C594103C2083ACD48FFF763 +S1135CD0D1FF01BDF8B596B0002000216A461170CD +S1135CE0AE4C68460078CC21615C884251D268464B +S1135CF0007869460873C44D03A92868FDF7C2FEFD +S1135D00002840D0D02020586946097814225143F5 +S1135D104018407A012832D103A92868FDF76CFEA7 +S1135D2003A92868FDF705FE03AC4820205C029017 +S1135D3003A808300190B54D982040012E18307802 +S1135D404C2148432818071D029A01993800FFF78F +S1135D50C3F9049831784C225143685030784C216F +S1135D604843281844214822A25C42543078401CFD +S1135D7030703078202806D30020307003E003A967 +S1135D802868FDF739FE68460078401C69460870AB +S1135D90A6E717B0F0BDF1B582B0002468460470E0 +S1135DA09A489B49451898214901415C2A789142B7 +S1135DB015D04C2629784C22514340180190029F5B +S1135DC0320001993800FFF787F92878401C2870C1 +S1135DD02878202800D32C70012069460870684672 +S1135DE00078FEBD00E400E01CED00E014E000E0FB +S1135DF018E000E0F3B595B0170000242600F6B2D1 +S1135E002000C0B2E4B265482100CC22825CC9B251 +S1135E1091420ED21599D02282582300DBB2142568 +S1135E206B43D2185268914201D1260001E0641CF0 +S1135E30E9E7D03002A902683300DBB214256B43D2 +S1135E40D25A0A7048228F5400683100C9B2142211 +S1135E5051434018406803903800C0B2019016982E +S1135E60009002A805000835019A00992800FFF760 +S1135E7033F9654D02A92868FDF70CFD02A92868CD +S1135E80FDF7FAFC002017B0F0BD000010E000E0C0 +S1135E908C080000A8080000FEB5002402945A4FA4 +S1135EA05C4E3000803038603500D8350122052141 +S1135EB0280000F0B0F901220521280000F006FABC +S1135EC001220521280000F010FA3500D035052202 +S1135ED00021280000F09FF905220121280000F08C +S1135EE09AF92E4D2800FDF788F80420CC21685437 +S1135EF04948D021685001200100297021006970AF +S1135F002100A9702100E97030216C54C821685423 +S1135F1002AA0B2130000830FCF763FE68780128E0 +S1135F200BD101200190FA20C00000909E4B9F4AA3 +S1135F30029928001C30FDF7D8FE002001909C48EF +S1135F400090994B9B4A029928000830FDF7CDFE3A +S1135F5029003868FDF772F9092000F0F9F9F7BD56 +S1135F6010B5040000200100C9B2082908DA0100B4 +S1135F70C9B2615C904A0300DBB2D154401CF2E721 +S1135F8008228D498D208000FFF734FF10BD0000EA +S1135F909C08000000200020A0320020D04F0020E8 +S1135FA0F8B586B0012501AC280020700226300027 +S1135FB060702800A080814F01AA07213800FCF7F7 +S1135FC02DFE2800207030006070A68001AA0721F1 +S1135FD03800FCF723FE25700720607001AA2921F0 +S1135FE03800FCF71BFE7648006E009002216846DC +S1135FF0FEF7ACFF00F0B4F900F031FB07B0F0BDE0 +S11360000000000008200020A8500020CC3C002004 +S1136010011300001C310020DCC00000F8B59CB066 +S113602000F0DEFC6749002000F036FF00F086F93E +S1136030654C200000F040FFC0204000201800F014 +S1136040D9FF6248039000270297614D029A039991 +S11360502800FFF74FF8D820019000975D4D009A73 +S113606001992800FFF746F804A8012101700121D5 +S1136070818004AA132120000830FCF7CFFD04AA74 +S1136080142120000830FCF7C9FD04AA15212000C2 +S11360900830FCF7C3FD04AA162120000830FCF7E1 +S11360A0BDFD04AA172120000830FCF7B7FDFFF757 +S11360B0F3FE494E4949300000F0C6FF484B494AB7 +S11360C031002000603001F046FA474D2A000921D2 +S11360D020000830FCF785FD2868FA218900FCF7C8 +S11360E004FEFFF743FD414800F032F92000603020 +S11360F0FFF7FAFC00F014F93D48016800293CD090 +S113610007603C4C2068401C206020680A21FCF792 +S1136110ECFD002905D138480078012801D100F0B0 +S113612037FA2068FA21890088420FD327600120BA +S113613000F03CFA0400314802681100491C016077 +S11361402300DBB22E49002000F0A6FE2A48017885 +S113615000290AD12B490A78521C0A7009780B29A4 +S113616003DB01210170FFF71BFF012001F0F6FAA8 +S1136170300001F0CDFB01F0DBFA09A8FFF70BFEBC +S11361800128B9D109982049884203D009981F49A8 +S11361908842B1D109A84421435C021D0999300009 +S11361A01830FFF765FAA7E74C1D000080841E0035 +S11361B0C409000020A10700EC06002024310020BF +S11361C080320020BCC300001C31002004130000F6 +S11361D0CC3C0020D04F002008200020B80600202E +S11361E0035C0000D75B0000A8320020FFFF000022 +S11361F0A0320020A4320020D3550020AC5000204F +S1136200D4C30000D255002032070000DF0700008D +S1136210016042607047F5B582B06846007B002893 +S113622028D16846007B6A4610700800029A1268FA +S11362308300D458244B23406C4624782402E02560 +S1136240ED0025401D430195019B8400135101235A +S11362500C00029D2D68A600AF590426B743BC4626 +S11362601E00F6B2B60004273E4067463E43A70030 +S1136270EE5127E000200A00029B1B6894001C5981 +S11362800425AC430500EDB2AD000426354025439A +S11362900195019C95005C516C46247B6D462C70E5 +S11362A00C00029D2D68A600AE59074F3740BC462E +S11362B06E4636783702E026F6003E4067463E4397 +S11362C0A700EE51FFBD0000FFF8FFFF30B44368A4 +S11362D05B6901248C40A3431400E4B28C401C434A +S11362E0230045686B6130BC704730B443681B6859 +S11362F001248C40A3431400E4B28C401C432300CB +S113630045682B6030BC704700B5010049B20029D4 +S113631005D40121C206D20E91400B4A116000BD82 +S113632000B50A480168012906DB0168491E0160BD +S11363300068012800DA62B600BD000072B60348A6 +S11363400168491C0160704700E100E01831002039 +S113635010B50400200040B2FFF7D6FF10BD0000C6 +S113636018B589B000F041F86846FEF791FB0120AA +S113637069460872804A0192C87248727F4C6A4624 +S1136380292120000830FCF72CFC0028F6D0B2208C +S11363904000241869462000FEF7ACFB00212000D1 +S11363A0FEF7ADFD00200AB010BD7CB506000D005F +S11363B0734B1E705D70734C00940222012172486D +S11363C0FEF76EFC207800026178084380B276BD47 +S11363D010B56D4C02212000FEF7F0FB012803D11B +S11363E002212000FEF722FD10BDF0B595B0674CE8 +S11363F0032205212000FFF70EFF01256846C57121 +S113640005200E9021680D910D990E9A92008958DD +S1136410402291436A46D279920140231A400A43AA +S1136420149214990D9A0E9B9B00D15069468D715C +S11364300C9020680B900B980C99890040582027E9 +S1136440FF43384020266946897949013140014398 +S1136450139113980B990C9A9200885003220221ED +S11364602000FFF7D8FE6846457102200A90216893 +S1136470099109990A9A92008958402291436A46DF +S11364805279920140231A400A431292129B0999AD +S11364900A9A92008B5069460D7108902068079003 +S11364A00798089989004058384069460979490194 +S11364B031400143119111980799089A920088502C +S11364C0032204212000FFF7A6FE6846C5700420BD +S11364D00690216805910599069A920089584022F0 +S11364E091436A46D278920140231A400A4310929B +S11364F0109B0599069A92008B5069468D70049002 +S113650020680390039804998900405838406946EC +S113651089784901314001430F910F980399049AF6 +S113652092008850032203212000FFF774FE68467E +S11365304570032002902168029A92008B584022F1 +S113654093439C466A465278920140231A4063461C +S11365501A43029B9B00CA506B461D70236884003B +S11365601C5927406C462478640126403E4384002D +S11365701E5115B0F0BD000040420F001C31002038 +S1136580685500207455002080320020EC31002032 +S11365901CB5032000F00AF8040000222100C9B24F +S11365A0032000F00BF80090009816BD10B504000D +S11365B000216006400EFFF7F8FE10BDF8B5050097 +S11365C00C0017002100C9B280202843C0B2FFF795 +S11365D0ECFE0600002F00D03E80684605702800BF +S11365E0C0B2FFF7E3FF60406946487068468470B4 +S11365F00098F2BDFEB582B004000F000A9E200090 +S1136600C0B2FFF7D3FF0500002E00D0358028006C +S1136610B8436946097C6A46127B91400143684647 +S113662001706846017880202043C0B2FFF7BDFEA8 +S1136630684604716846007C6946097B884001A964 +S113664088702000C0B2FFF7B1FF0100394001A8F3 +S11366508078484001AA5070019805B0F0BDF0B5AB +S113666099B015273800002529006A4651710100A8 +S1136670C9B2090941400800C0B28008484001007D +S1136680C9B2490841406846017168460079010071 +S1136690C907C90F012901DB952007002C000495C7 +S11366A0200080B2C0086946487320004001694652 +S11366B0087328006946C8722800694688720498DD +S11366C0C008694648720498400169460872280067 +S11366D06946C87128006946887105A83249502264 +S11366E0FEF7E0FC05AE77706846407B29217054C4 +S11366F06846007B2B2170546846C07A2D21705463 +S11367006846807A2F2170546846407A312170544B +S11367106846007A332170546846C0793521705434 +S11367206846807937217054684640794B2170540B +S1136730FFF716FE002809D0280069460870FF20DC +S1136740694648706846857000982BE02C0020004C +S1136750C0B24000305C002806D12000C0B2400026 +S113676030184078002814D000222000C0B2400025 +S1136770301841782000C0B24000305CFFF71EFFA3 +S1136780009068464078002801D000980AE0641C14 +S1136790DDE72800694608702800694648706846A5 +S11367A08570009819B0F0BD2CC1000010B55B4C89 +S11367B00320206160615A48A0615A49E161802147 +S11367C0C90021620021A1626162E162206656482B +S11367D060661020A0662167E166616753A1E01D31 +S11367E001F010F95249200001F00CF92020A071A9 +S11367F010BDF1B586B00C0015000020019006987C +S1136800C7680698006900900098874203D20098F0 +S1136810C01B401E05E006988068C01B0099401804 +S1136820401E06998968C91B884202D3069880686D +S1136830C01BA84201D2060000E02E000698406862 +S1136840C01903900596049403980290059A04993C +S11368500298FEF741FC0298019880190190A4194E +S1136860AD1BBF1906988068874201D1002007003C +S11368700698C760002DC4D1019807B0F0BDF8B5E3 +S113688088B004000D001600E0680390A068039926 +S1136890401A0290029886420FD260680399401809 +S11368A0009005960495009F059A04993800FEF718 +S11368B013FC03988019E06020E00298019060685E +S11368C0039940180090019807900695009F079A35 +S11368D006993800FEF700FC0298301A01906068AF +S11368E0009001980590029828180490009F059A3A +S11368F004993800FEF7F0FB0198E06009B0F0BDA0 +S113690000B501000A69CB68934204D38868401E2D +S1136910C01A801801E0D01A401E00BDB0500020FB +S1136920FCC3000058510020585500205254540014 +S113693008C40000F1B582B00F0015000197274884 +S1136940029918225143401806001836706900282D +S113695003D0022821D010D326E03000FFF7D0FF67 +S113696000900098A84201D2002405E02C002A00DF +S113697001993000FFF783FF17E03000FFF7C0FFF5 +S113698000900098A84201D2009C00E02C00220054 +S113699001993000FFF773FF07E02A0001993000E6 +S11369A0FFF727FF040000E000242000FEBDF1B53E +S11369B00F001600094D2878002801D1FFF7F6FED4 +S11369C0EFF31084012080F310883200390000981E +S11369D0FFF7B0FF84F31088F2BD0000B050002030 +S11369E080B5FFF7E3FE01BD70B504000E00A56895 +S11369F061682800401C814207D32068465528005E +S1136A00401CA060E068401CE060A06861688842A7 +S1136A100DD1A26821682069FFF7C9FFA1688842E7 +S1136A2003D00020C043E06001E00020A06070BDFE +S1136A30F7B584B01F000C9D05980290012401262F +S1136A4002980699884206D302980699FCF74DF9F4 +S1136A500290761CF4E7BE4200D23E000D98C007B7 +S1136A601BD4002D19D00D98800705D5002F03D114 +S1136A7030206946087002E0202069460870002D25 +S1136A800BD0AE4209D26D1E684601780498FFF718 +S1136A90ABFF0498C0680028F1D50498C0680028AA +S1136AA03CD4022F01D37F1E08E005982100FCF797 +S1136AB01CF9019001980699884202D30698444330 +S1136AC0EFE705982100FCF710F90190059801996A +S1136AD06143401A059012480199415C0498FFF7FC +S1136AE083FF0498C068002806D420000699FCF7A8 +S1136AF0FCF80400002CE4D10D98C0070ED5002D3D +S1136B000CD0002D0AD0AE4208D26D1E202104986C +S1136B10FFF76AFF0498C0680028F2D507B0F0BDFB +S1136B20ECC30000FEB582B007000A9C029800285E +S1136B3002D50298454200E0029D01260398854251 +S1136B4006DB28000399FCF7CDF80500761CF5E771 +S1136B500498864201D204980600002C06D00298BC +S1136B60002802D40B98400700D5641E0B988007B8 +S1136B7002D50498002810D00B98C0070DD4002C1F +S1136B800BD0002C09D0A64207D2641E2021380065 +S1136B90FFF72AFFF8680028F3D5F868002836D4F0 +S1136BA00298002807D50298414202912D2138000D +S1136BB0FFF71AFF06E00B98400703D52B21380096 +S1136BC0FFF712FFF868002821D40B988007800F84 +S1136BD0022810D1049800280DD1002C0BD0002CD1 +S1136BE009D0A64207D2641E30213800FFF7FCFE0C +S1136BF0F8680028F3D5F868002808D40B980190A9 +S1136C000094049B039A02993800FFF711FF05B022 +S1136C10F0BDF5B59BB00C000AA805904020069085 +S1136C20002007901B980990002008902078070006 +S1136C30641C3800C0B2002800D11BE13800C0B287 +S1136C40252800D00DE100200500012102912278C1 +S1136C5017003A00D2B2232A13D02B2A0CD02D2AA3 +S1136C6002D0302A03D011E00D43641C0FE02A0047 +S1136C7002251543641C0AE02A0004251543641CFC +S1136C8005E02A0008251543641C00E00290029ADE +S1136C90002ADCD1039021780F003900C9B23029D1 +S1136CA003DB3900C9B23A2906DB049020780100DD +S1136CB0C9B22E2920D109E0641C03990A22514348 +S1136CC03A00D2B2891830390391E4E7641C217880 +S1136CD008000100C9B2302903DB0100C9B23A2916 +S1136CE000DB09E0641C04990A2251430200D2B279 +S1136CF0891830390491EAE727783800C0B26C2843 +S1136D0003D03800C0B2682803D1641C207807007F +S1136D10F3E73800C0B2252800D19BE058284ED0B4 +S1136D2063280AD064281CD070287BD073285DD0D7 +S1136D3075282DD0782842D091E01C9800681C99C1 +S1136D4008601C98006800681C990968091D1C9A51 +S1136D5011600290029E3100C9B205A8FFF744FEFB +S1136D607DE01C9800681C9908601C980068006805 +S1136D701C990968091D1C9A1160029001950398D9 +S1136D800090049B0A22029905A8FFF7CBFE66E057 +S1136D901C9800681C9908601C98006800681C997D +S1136DA00968091D1C9A11600290019503980090CE +S1136DB0049B0A22029905A8FFF73AFE4FE01C98AB +S1136DC000681C9908601C98006800681C99096890 +S1136DD0091D1C9A11600290019503980090049B70 +S1136DE01022029905A8FFF723FE38E01C980068DA +S1136DF01C9908601C98006806681C980068001DAF +S1136E001C99086030780700761C3800C0B200284E +S1136E1007D03900C9B205A8FFF7E6FD0898002895 +S1136E20F0D51CE01C9800681C9908601C98006848 +S1136E3000681C990968091D1C9A116002900020C1 +S1136E4001900820009008231022029905A8FFF75A +S1136E50EFFD04E0252105A8FFF7C6FDFFE7641C4C +S1136E6004E03900C9B205A8FFF7BEFD0898002860 +S1136E7000D4DBE6089801280BDB0798002804D02F +S1136E80079A0AA91B98FFF792FD089807994018DA +S1136E90089008981DB0F0BD0CB438B505000C007E +S1136EA004A800906A4621002800FFF7B2FE01B052 +S1136EB0029930BC03B00847F0B58BB004003548E4 +S1136EC00590069000200790089009900A90324D92 +S1136ED0324F334E05A80390029601973148009033 +S1136EE02B00314A314920000830FBF753FE2A00B9 +S1136EF02F492000603000F0BFFD0220694608746D +S1136F0004A803902B48029001960095264B3A0062 +S1136F10294920008030FCF760F8284A28492000DD +S1136F20C830FFF775F9274A27492000D030FFF70A +S1136F306FF9264A26492000D830FFF769F9254A17 +S1136F4025492000E030FFF763F9244A2449200052 +S1136F50E830FFF75DF90095124B3200214920001B +S1136F60F03000F0BFFE104B3A001049882040007A +S1136F70201800F0C9FE1C49B22040002018FDF77B +S1136F80FBFD1A49C0204000201800F031F80BB076 +S1136F90F0BD00BF00127A0000E0064000F8064091 +S1136FA000E8064000E4064000F0064000F0074018 +S1136FB00000024000F00540008003400050034000 +S1136FC0000006404050034000100640805003403B +S1136FD000200640C05003400030064000510340EA +S1136FE00040064000D0074000C0024000A0074017 +S1136FF00160704710B502680121126852090A4005 +S11370001300DBB2012B19D10D4B046863600368D4 +S11370101B688024A343046823600A4B0468A360AC +S113702003681B68DB0A0B40DBB2002BF8D1036852 +S11370301B685B0A0B40DBB2002BF8D010BD0000CC +S113704020C528D9FFFF000038B505000C00210039 +S1137050280000F024FC0548A8600548E8600F20DB +S11370606860044828610620A88231BD0CC0000075 +S113707054C200005C080020F3B581B01400C025A0 +S11370802600F6B2281D0090029F320000993800B5 +S1137090FEF722F8F7BD43780B707047F3B581B063 +S11370A01400C0252600F6B2280028300090029F64 +S11370B0320000993800FEF70FF8F7BDF5B583B03C +S11370C00C00C0250C2002902800183001902600E6 +S11370D0029A01993000FDF7FFFF082628000C30C2 +S11370E0009027000C37320000993800FDF7F4FFB8 +S11370F02020E07205B0F0BDF3B581B01400C025C6 +S11371002600F6B20095029F320000993800FDF780 +S1137110E3FFF7BD30B500231C001500E4B2EDB267 +S1137120AC4205D220241D00EDB24C555B1CF3E7A4 +S113713030BD000008B4024B9C4608BC6047C04602 +S11371404D02002008B4024B9C4608BC6047C04670 +S11371504D04002038B50124724D0C21280000F0A4 +S1137160DBFD002813D10121280000F0D5FD012802 +S11371700AD1A3480168A34A914202D00020040026 +S113718007E00021016004E00020040001E0002089 +S113719004002000C0B232BD802000017047F0B569 +S11371A00400200000252E00954209D2964E4F5D22 +S11371B04740FFB2BF00F659000A70406D1CF3E768 +S11371C01E00F6B2012E02D10026F643301AF0BD9D +S11371D0FEB5002701970097FFF7B0F88B48FBF73F +S11371E086FF852424018A4D3A0021002800FDF7FA +S11371F081FF80204002056886480668864806604C +S113720086490D600A6882F30988096881F3088851 +S113721080214902BE4A116000688047F7BD70B5FD +S113722085252D0100247A4E220029003000FDF727 +S113723061FFFFF783F823213A4800F02DFE70BD6B +S113724080B50020009003230622C0210120FFF70F +S1137250D1F901BDE0B56846762101706C4B34214B +S1137260595C41700222694658689B68984707BD7B +S113727080B56748417C002916D184210901415C0D +S1137280012903D0B249415C01290AD10021A14A54 +S113729081500121AE4A81540221417440684170F9 +S11372A002E0042000F082F901BDF8B5584C607C7E +S11372B0002802D0607C012832D1E06900282FD058 +S11372C0206AE16988422BD200252E006769C048F4 +S11372D0205C032814D0FFF731F801216069FFF71F +S11372E029FF06003000C0B2002807D1E169491E19 +S11372F08020C0003818FFF71DFF0600FFF710F8C4 +S11373003000C0B2002805D102206074E561A56197 +S1137310256205E0E561A5612562032000F046F9D8 +S1137320F1BD00002C320020F8B59F4800780128F8 +S113733064D1374C607C002802D0607C01285DD188 +S1137340B048205C012859D1E06AA16A884255D22C +S1137350002637009E48205C03282BD03000694665 +S11373600870300069464870022069460870FEF7CC +S1137370E5FF3500280069460978C0B2884217D273 +S11373808022D2002800C0B28002201801003531CA +S1137390606AE36AC0182B00DBB29B02C018FFF7D7 +S11373A0D1FE07003800C0B2002801D16D1CE1E70E +S11373B0FEF7B6FF3800C0B2002813D1E06A80217E +S11373C009014018E062E06AA16A884205D33000EE +S11373D08D4960540220607401E001206074FFF75D +S11373E039FF07E0300088496054A662E662032052 +S11373F000F0DCF83000834960542663F1BD0000DE +S1137400F063002055AAAA55189900009C31002069 +S1137410C028002004000100143100201031002095 +S1137420F8B5A34C607C002802D0607C01286DD1A3 +S11374302600113601253570654820180178012988 +S113744002D00178002957D18D4801F009F90028AC +S11374504AD18C4801F004F9002845D188480068D5 +S11374608949884207D03A482554022030700020C8 +S1137470B74960544AE08F480768824800688E49DB +S1137480401800900098A021890288420ED20098EA +S11374908A4988420AD30123009A802149020020A4 +S11374A0C043FFF77CFE8649605002E00020844917 +S11374B0605083482058874207D02548255402202D +S11374C030700020A249605420E0A148255420488F +S11374D020180178002903D1052000F067F815E091 +S11374E005700220307011E01948255402203070D4 +S11374F000209749605409E00178022906D00078F9 +S1137500032803D19248255402203070F1BD0000B5 +S113751008ED00E04808000080B56548417C00297A +S113752002D0417C012912D18A4941580A290CD33D +S11375300749415C002908D19A490020FFF7ACFCB7 +S1137540FEF7FCFEFFF744FE01E00121417401BD9A +S1137550430800007047FEB582B006008520000194 +S1137560019000250095524C2700009A019938009B +S1137570FDF7C0FD2660029860600398A06004983F +S1137580E0604F4825503000FEF7AEFAFFF7E2FD09 +S1137590012807D16F48255001204A496054022030 +S11375A06168487005B0F0BDFD3000200021404AFC +S11375B00B00537410747C4BD15070477B48007C93 +S11375C070477A48407C70477948007870470000DB +S11375D04408000010B560493A4A8A181378002B11 +S11375E007D184231B01C85400236F4C0B51012382 +S11375F0137002224A7410BD574A6E4BD0546E4B1E +S1137600D15470473E0800003D08000038B505001D +S11376100C0051488461456100210A00674BC25443 +S1137620674A8154802149028D420CD1A0218902EC +S11376308C4208D10121634A81548169624A8918C4 +S1137640890AC16117E0002D0AD1082C08D1022152 +S11376505C4A815481695C4A8918890AC1610AE0DB +S11376605A498D4207D15A498C4204D20321554AC2 +S113767081540221C1610120FFF798FF31BD000050 +S1137680C0000100F87F0300DDCCBBAA38B50500BB +S11376900C00314801214A4A815400210A00474B19 +S11376A0C25445628462C1620220FFF77FFF31BD8C +S11376B0C0280020FC7F03000000FFFF0140000001 +S11376C03808000043080000F4B503000022140049 +S11376D010000C00A4B2A24208D21F4C256BAD18B6 +S11376E0641935259E5C6655521CF2E71A4C256BCD +S11376F00E00B6B2AD1925636D462D783426A55516 +S1137700256B80263601B54204D301252E002B4F6C +S1137710E6552800C0B2F2BD00200F4902004A74A9 +S113772004220A7402000A4BCA542A4A8850704739 +S113773080B50948017C062909DA2749027C9200B0 +S11377408A58002A03D0007C80000858804701BD75 +S11377503C08000048080000C028002010B50400C0 +S11377601248017C002902D0017C052906D10E496A +S113777041180A682300DBB2D2180A600D49411887 +S11377800A78012A0CD100220A700B49405C0128B6 +S113779004D1FFF755FDFFF742FD01E0FFF73FFD80 +S11377A010BD0000A4C3000048080000C028002049 +S11377B0FC30002041080000420800003E080000A0 +S11377C03D08000044080000FF030000F05B0020B7 +S11377D00108000038080000A00600200021016014 +S11377E041600A00027241727047002202604160E7 +S11377F00123037242727047407A7047FEB5050058 +S11378000E001400082100226F463800FDF772FCB8 +S11378102000C0B2782805D07448295A7448281822 +S1137820FFF7E3FF7920285C002814D02000C0B2C1 +S113783011280FD02000C0B212280BD02000C0B2F3 +S1137840312807D02000C0B27E2803D02000C0B267 +S11378507F2800D10AE068467F2101704670847059 +S11378600322694628001830FDF780FEF7BD10B5E5 +S1137870020000231800180080B25468A0420CD201 +S113788090681C00A4B2E400005D0C00E4B2A042C5 +S113789001D1012002E05B1CEDE7002010BD70B5B2 +S11378A005000C00210028001830FEF757F80120CD +S11378B0687000263000A8703000782168540020D9 +S11378C0002188221201AA1803C2083AA08D49494E +S11378D06852E08D48496852208E44496852892094 +S11378E000012818FFF77AFF44482818FFF776FFAD +S11378F03F482818FFF772FF3100300040498842A2 +S113790005D231002A187B23D154401CF6E770BD00 +S1137910FEB50400002630006946C8803000694680 +S113792008713700350020001830FEF763F801A80D +S1137930801C0090324B22007B32210079312000E0 +S11379401830FDF7D5FF69460871694604200856CA +S113795000283CD17B20205C07003900C9B22000FC +S1137960FFF785FF00282CD03500606885422ED2B1 +S1137970A068E900405C3900C9B288421FD1A06800 +S1137980E90040188078002806D07C20205CC0B232 +S1137990C0097821605402E0300078216054280046 +S11379A07A2160546846C28821007B31200004009B +S11379B0A368E800181843682000984707E06D1C86 +S11379C0D3E711223900C9B22000FFF717FF084896 +S11379D02018FFF711FF012806D101206070A6705E +S11379E003482018FFF7FAFEF7BD00008C080000DA +S11379F0A8080000880800008A0800009C0800000D +S1137A000208000031B48B0707D00B780370002BF9 +S1137A1020D0401C491C8B07F7D1164CE501830785 +S1137A2022D104C9131B93432B4205D104C004C9BA +S1137A30131B93432B42F9D0FF231A42027009D03F +S1137A40120A1A42427005D0120A1A42827001D0F8 +S1137A50120AC27031BC70470270120A4270120AD4 +S1137A608270120AC270001D04C9131B93432B4277 +S1137A70F2D0E1E701010101F8B504000F0015009F +S1137A80276065600026A660E0208002E060802018 +S1137A9040052061802000026061200000F002F9AE +S1137AA02076E661207E002800D06661200000F088 +S1137AB001F8F1BDF1B489B0012069460871099952 +S1137AC009680791002106916A461279520002233F +S1137AD01A400692069A079B1A606A46D070099A61 +S1137AE0126805916B46DB781B0110242340059333 +S1137AF0059B13606B469870099B1B6804916C4648 +S1137B00A478640120252C400494049C1C606C46D9 +S1137B106070099C246803916D466D78AD01402620 +S1137B2035400395039D25606D462870099D2D6899 +S1137B3002916E463678F60008273E400296029E71 +S1137B402E60099E366808910100C9B28900042795 +S1137B50394031600AB0F0BC7047F0B5010000252F +S1137B602800012213000C681E00F6B2F6018027DB +S1137B703E4026600B681B68DB091340DBB2002B18 +S1137B80F8D00B681B685B091340DBB2002B0CD1E7 +S1137B900B681B681B091340DBB2002B05D10B6873 +S1137BA01B681340DBB2002B00D01000C0B2F0BD44 +S1137BB0FFB587B000242700250009A800784028D5 +S1137BC001DB012007000A98002801D101200700E9 +S1137BD03800C0B200284DD107980068012600681B +S1137BE0C10930000840C0B2002802D102200700B9 +S1137BF040E00798FFF75EFF08206946C870200040 +S1137C00694648700798006805900294FF20049024 +S1137C1005996A4652788918097F049A91436A46FD +S1137C20D378049A1A400A430292029A05996B4641 +S1137C305B78C9180A7709A909786A469170694678 +S1137C400E7007990E680194039068460078301806 +S1137C50007F0399884369468978039A0A4002435E +S1137C600192019869460978711808770798FFF717 +S1137C7074FF07003800C0B200280FD12500082D7A +S1137C800CD22800C01D0799096822000300DBB24A +S1137C90CB181B7F0A9E73556D1CF0E73800C0B2E9 +S1137CA00BB0F0BD7CB50500082200216846FDF745 +S1137CB0EFF900263400FF20694608706B46002265 +S1137CC000212800FFF774FF01000800C0B200285B +S1137CD005D168460078800701D401200400200003 +S1137CE0C0B276BD10B4019C016042608360C46080 +S1137CF010BC704700B5BFF34F8F054805490860B5 +S1137D00BFF34F8F00BFFDE701604260836070479F +S1137D100400FA050CED00E030B502000023180061 +S1137D200C00E4B20D2C01DBC0B2B4E00C00E4B2F0 +S1137D30002C14D0022C29D01CD3042C3ED031D3D7 +S1137D40062C53D046D3082C68D05BD30A2C7DD0A4 +S1137D5070D30C2C00D191E000D283E09AE0156836 +S1137D6001242D682540EDB2012D01D1200000E051 +S1137D7018008FE0156801242D686D082540EDB2C8 +S1137D80012D01D1200000E0180083E015680124D2 +S1137D902D68AD082540EDB2012D01D1200000E091 +S1137DA0180077E0156801242D68ED082540EDB230 +S1137DB0012D01D1200000E018006BE015680124BA +S1137DC02D682D092540EDB2012D01D1200000E0E0 +S1137DD018005FE0156801242D686D092540EDB297 +S1137DE0012D01D1200000E0180053E015680124A2 +S1137DF02D68ED092540EDB2012D01D1200000E0F0 +S1137E00180047E0156801242D682D0A2540EDB2BD +S1137E10012D01D1200000E018003BE01568012489 +S1137E202D686D0A2540EDB2012D01D1200000E03E +S1137E3018002FE0156801242D68AD0A2540EDB225 +S1137E40012D01D1200000E0180023E01568012471 +S1137E502D68ED0A2540EDB2012D01D1200000E08E +S1137E60180017E0156801242D682D0B2540EDB28C +S1137E70012D01D1200000E018000BE01568012459 +S1137E802D686D0B2540EDB2012D01D1200000E0DD +S1137E901800FFE7C0B230BDF3B581B03048019996 +S1137EA08968802288506A46127A002A5AD0022AA7 +S1137EB000D187E06ED3042A00D1B3E000D299E068 +S1137EC0062A00D1DEE000D2C4E0082A00D109E18C +S1137ED000D2EFE00A2A00D134E100D21AE10C2AE0 +S1137EE000D15FE100D245E10E2A00D18AE100D23F +S1137EF070E1102A00D1B5E100D29BE1122A00D131 +S1137F00E0E100D2C6E1142A00D10BE200D2F1E193 +S1137F10162A00D136E200D21CE2182A00D161E20E +S1137F2000D247E21A2A00D18CE200D272E21C2A63 +S1137F3000D1B7E200D29DE21E2A00D1EAE200D2CB +S1137F40CCE2202A00D11DE300D2FFE2222A00D194 +S1137F5050E300D232E3232A00D167E369E300BF90 +S1137F605245535501200100019A92685468012337 +S1137F709C430B00DBB20340234353600024019D68 +S1137F80AD686E680127BE432700FFB23840304316 +S1137F9068604EE301200100019A9268946801230D +S1137FA09C430B00DBB20340234393600024019DF8 +S1137FB0AD68AE680127BE432700FFB238403043A6 +S1137FC0A86036E301200100019A9268D468012375 +S1137FD09C430B00DBB203402343D3600024019D88 +S1137FE0AD68EE680127BE432700FFB23840304336 +S1137FF0E8601EE301200100019A926814690123DC +S11380009C430B00DBB20340234313610024019D16 +S1138010AD682E690127BE432700FFB238403043C4 +S1138020286106E301200100019A92685469012342 +S11380309C430B00DBB20340234353610024019DA6 +S1138040AD686E690127BE432700FFB23840304354 +S11380506861EEE201200100019A926894690123AB +S11380609C430B00DBB20340234393610024019D36 +S1138070AD68AE690127BE432700FFB238403043E4 +S1138080A861D6E201200100019A9268D469012313 +S11380909C430B00DBB203402343D3610024019DC6 +S11380A0AD68EE690127BE432700FFB23840304374 +S11380B0E861BEE201200100019A9268146A01237A +S11380C09C430B00DBB20340234313620024019D55 +S11380D0AD682E6A0127BE432700FFB23840304303 +S11380E02862A6E201200100019A9268D46A012361 +S11380F09C430B00DBB203402343D3620024019D65 +S1138100AD68EE6A0127BE432700FFB23840304312 +S1138110E8628EE201200100019A5268146801238A +S11381209C430B00DBB20340234313600024019DF6 +S11381306D682E680127BE432700FFB238403043E4 +S1138140286076E201200100019A526854680123F4 +S11381509C430B00DBB20340234353600024019D86 +S11381606D686E680127BE432700FFB23840304374 +S113817068605EE201200100019A526814690123DB +S11381809C430B00DBB20340234313610024019D95 +S11381906D682E690127BE432700FFB23840304383 +S11381A0286146E201200100019A526854690123C2 +S11381B09C430B00DBB20340234353610024019D25 +S11381C06D686E690127BE432700FFB23840304313 +S11381D068612EE201200100019A5268946901232A +S11381E09C430B00DBB20340234393610024019DB5 +S11381F06D68AE690127BE432700FFB238403043A3 +S1138200A86116E201200100019A5268D469012391 +S11382109C430B00DBB203402343D3610024019D44 +S11382206D68EE690127BE432700FFB23840304332 +S1138230E861FEE101200100019A5268146A0123F9 +S11382409C430B00DBB20340234313620024019DD3 +S11382506D682E6A0127BE432700FFB238403043C1 +S11382602862E6E101200100019A5268946A012320 +S11382709C430B00DBB20340234393620024019D23 +S11382806D68AE6A0127BE432700FFB23840304311 +S1138290A862CEE101200100019A5268146B012307 +S11382A09C430B00DBB20340234313630024019D72 +S11382B06D682E6B0127BE432700FFB23840304360 +S11382C02863B6E101200100019A5268546B01232E +S11382D09C430B00DBB20340234353630024019D02 +S11382E06D686E6B0127BE432700FFB238403043F0 +S11382F068639EE101200100019A5268146C012315 +S11383009C430B00DBB20340234313640024019D10 +S11383106D682E6C0127BE432700FFB238403043FE +S1138320286486E101200100019A5268546C0123FB +S11383309C430B00DBB20340234353640024019DA0 +S11383406D686E6C0127BE432700FFB2384030438E +S113835068646EE101200100019A5268946C012363 +S11383609C430B00DBB20340234393640024019D30 +S11383706D68AE6C0127BE432700FFB2384030431E +S1138380A86456E101200100019A5268146D01238A +S11383909C430B00DBB20340234313650024019D7F +S11383A06D682E6D0127BE432700FFB2384030436D +S11383B028653EE101200100019A5268146E0123F0 +S11383C09C430B00DBB20340234313660024019D4E +S11383D06D682E6E0127BE432700FFB2384030433C +S11383E0286626E101200100019A5268546E012397 +S11383F09C430B00DBB20340234353660024019DDE +S11384006D686E6E0127BE432700FFB238403043CB +S113841068660EE101200100019A5268946E0123FE +S11384209C430B00DBB20340234393660024019D6D +S11384306D68AE6E0127BE432700FFB2384030435B +S1138440A866F6E001200100019A5268D46E012367 +S11384509C430B00DBB203402343D3660024019DFD +S11384606D68EE6E0127BE432700FFB238403043EB +S1138470E866DEE001200100019A5268146F0123CE +S11384809C430B00DBB20340234313670024019D8C +S11384906D682E6F0127BE432700FFB2384030437A +S11384A02867C6E001200100019A52688023D4584D +S11384B001239C430B00DBB203402343802413516C +S11384C00024019D6D688026AE590127BE43270014 +S11384D0FFB2384030438026A851AAE001200100B1 +S11384E0019A52688423D45801239C430B00DBB2C5 +S11384F003402343842413510024019D6D68842682 +S1138500AE590127BE432700FFB2384030438426CA +S1138510A8518EE001200100019A52689023D4589A +S113852001239C430B00DBB20340234390241351EB +S11385300024019D6D689026AE590127BE43270093 +S1138540FFB2384030439026A85172E00120010068 +S1138550019A52689C23D45801239C430B00DBB23C +S1138560034023439C2413510024019D6D689C26E1 +S1138570AE590127BE432700FFB2384030439C2642 +S1138580A85156E001200100019A52689423D4585E +S113859001239C430B00DBB2034023439424135177 +S11385A00024019D6D689426AE590127BE4327001F +S11385B0FFB2384030439426A8513AE0012001002C +S11385C0019A5268C823D45801239C430B00DBB2A0 +S11385D003402343C82413510024019D6D68C82619 +S11385E0AE590127BE432700FFB238403043C826A6 +S11385F0A8511EE001200100019A5268CC23D458EE +S113860001239C430B00DBB203402343CC241351CE +S11386100024019D6D68CC26AE590127BE43270076 +S1138620FFB238403043CC26A85102E0FFF762FB8A +S1138630FFE700200199896880228850F7BD000077 +S113864008B4024B9C4608BC6047C04601000020A9 +S113865008B4024B9C4608BC6047C046A7000020F3 +S1138660F0B595B00400002528006946C87360077A +S1138670400F002801D00120CAE06748006802903A +S11386800298006801260068C0093040C0B2002882 +S113869001D10920BCE00298FFF7D2FF6846867337 +S11386A02800694608710298006814900995FF2013 +S11386B0139014996A4612798918097F139A914381 +S11386C06A46927B139B13400B4309930999149AAE +S11386D06B461B79D218117721006A46517369469B +S11386E0CE700299096812910895119012996A4600 +S11386F0D2788918097F119A91436A46527B119B5B +S113870013400B4308930899129A6B46DB78D218EE +S11387101177210A6A46117302216A4691700299FF +S11387200968109107950F9010996A4692788918F4 +S1138730097F0F9A91436A46127B0F9B13400B43A8 +S113874007930799109A6B469B78D21811772100EA +S1138750090C6A46D17103216A465170029909686D +S11387600E9106950D900E996A4652788918097FE4 +S11387700D9A91436A46D2790D9B13400B4306939D +S113878006990E9A6B465B78D2181177210E6A46C9 +S1138790917104216A461170029909680C9105953A +S11387A00B900C996A4612788918097F0B9A9143A9 +S11387B06A4692790B9B13400B43059305990C9AD7 +S11387C06B461B78D218117729006A465171052728 +S11387D002990E6804950A903800C0B23018007FE0 +S11387E00A998843694649790A9A0A4002430492DD +S11387F004983900C9B2711808770298FFF728FF66 +S113880001000800C0B2002801D10B2000E02800BC +S1138810C0B215B0F0BD0000F05B0020F1B489B027 +S11388200120694608710999096807910021069198 +S11388306A461279520002231A400692069A079B4E +S11388401A606A46D070099A126805916B46DB7803 +S11388501B01102423400593059B13606B469870FD +S1138860099B1B6804916C46A478640120252C4064 +S11388700494049C1C606C466070099C24680391F9 +S11388806D466D78AD01402635400395039D256006 +S11388906D462870099D2D6802916E463678F60063 +S11388A008273E400296029E2E60099E3668089173 +S11388B00100C9B289000427394031600AB0F0BC14 +S11388C07047F0B5010000252800012213000C6850 +S11388D01E00F6B2F60180273E4026600B681B6836 +S11388E0DB091340DBB2002BF8D00B681B685B0973 +S11388F01340DBB2002B0CD10B681B681B0913401F +S1138900DBB2002B05D10B681B681A40D2B2002AD7 +S113891001D007221000C0B2F0BDF2B584B004004B +S11389200025280069468870280069464870206838 +S113893001260068C10A30000840C0B200280ED1E8 +S11389406846007C01280AD160680068010D300087 +S11389500840C0B2012802D130006946487020683E +S11389600068C10930000840C0B2002801D10920C4 +S11389706DE02000FFF752FF0D20694608702900C2 +S113898022680195FF2002900B00DBB2D3181F7FF1 +S1138990029B9F43BC466B461F78029B3B40674645 +S11389A03B430193019B0F00FFB2D7193B776B4602 +S11389B01B7C002B01D0370000E02F0031006A46F9 +S11389C01170216803910195029003986946097812 +S11389D04018007F029988433900C9B2029A0A40BC +S11389E002430192019803996A461278891808771C +S11389F02000FFF766FF6946097C002909D0216839 +S1138A000968CA0A31001140C9B2002901D10521FF +S1138A1008006946097C002909D1216809680A0B04 +S1138A2031001140C9B2002901D10521080001001B +S1138A30C9B200290BD169464978002907D02168B9 +S1138A403200D2B2520380239B011A400A60C0B2A2 +S1138A5005B0F0BD10B50400824804602000FFF7A3 +S1138A60DDFE0020E06110BDF3B595B000273800AD +S1138A70694608707B48046815988005800D0028B5 +S1138A8003D0012069460870E7E038003D001698DD +S1138A90854200D3E1E0206801260068C109300066 +S1138AA00840C0B2002803D1092069460870D4E008 +S1138AB02000FFF7B3FE05216846017338006A46BB +S1138AC09071206814900997FF201390149A6B46B4 +S1138AD09B79D218137F139A93439C466A46137B5F +S1138AE0139A1A4063461A430992099B9C46149BA5 +S1138AF06A4692799A1863461377159A6B46DA7226 +S1138B0032006B465A712268129208971190129A99 +S1138B106B465B79D218137F119A93439C466A463D +S1138B20D37A119A1A4063461A430892089B9C46CA +S1138B30129B6A4652799A1863461377159AAB02C8 +S1138B40D218120A6B469A7202226B461A71226874 +S1138B50109207970F90109A6B461B79D218137FC7 +S1138B600F9A93439C466A46937A0F9A1A40634637 +S1138B701A430792079B9C46109B6A4612799A18DF +S1138B8063461377159AAB02D218120C6B465A72CD +S1138B9003226B46DA7022680E9206970D900E9AA5 +S1138BA06B46DB78D218137F0D9A93439C466A4632 +S1138BB0537A0D9A1A4063461A430692069B9C46C2 +S1138BC00E9B6A46D2789A1863461377159AAB02BD +S1138BD0D218120E6B461A7204226B469A702268DF +S1138BE00C9205970B900C9A6B469B78D218137FC6 +S1138BF00B9A93439C466A46137A0B9A1A4063462F +S1138C001A430592059B9C460C9B6A4692789A18D7 +S1138C10634613776A46D6716A465170266804978C +S1138C200A90684640783018007F0A99884369465C +S1138C30C9790A9A0A400243049204986946497819 +S1138C40711808772000FFF73CFE694608706846F3 +S1138C500078002801D16D1C19E76846007817B028 +S1138C60F0BD0000F05B0020F7B598B000252800A7 +S1138C7069464874874800680190072018990140A4 +S1138C80002901D0012501E11A990840002801D0EA +S1138C900325FBE028006946087002950B950198AE +S1138CA0006801270068C10A38000840C0B20128E2 +S1138CB002D138006946087068460078002803D05D +S1138CC000210198FFF729FE18988005800D0B906C +S1138CD00B98A021490544182E001A98864205D203 +S1138CE01998805D2070641C761CF6E70198006872 +S1138CF00068C10938000840C0B2002801D1092524 +S1138D00BCE00198FFF78AFD062069460874280034 +S1138D10694688720198006816900A95FF2015909C +S1138D2016996A46927A8918097F159A91436A4678 +S1138D30137C159A1A400A430A920A9A16996B46AA +S1138D409B7AC9180A7718996A46D17369464F7293 +S1138D500199096814910995139014996A46527AF5 +S1138D608918097F139A91436A46D27B139B134057 +S1138D700B4309930999149A6B465B7AD2181177BD +S1138D801899090A6A46917302216A461172019977 +S1138D90096812910895119012996A46127A8918F5 +S1138DA0097F119A91436A46927B119B13400B43AE +S1138DB008930899129A6B461B7AD218117718995E +S1138DC0090C6A46517303216A46D17001990968F6 +S1138DD0109107950F9010996A46D2788918097FE7 +S1138DE00F9A91436A46527B0F9B13400B430793A0 +S1138DF00799109A6B46DB78D21811771899090EE7 +S1138E006A46117304216A469170019909680E91AA +S1138E1006950D900E996A4692788918097F0D9AE5 +S1138E2091436A46127B0D9B13400B4306930699AC +S1138E300E9A6B469B78D21811771A99C908491E65 +S1138E406A46D17205216A46517001990F680595E9 +S1138E500C90684640783818007F0C99884369461E +S1138E60C97A0C9A0A4002430592059869464978E2 +S1138E70791808770198FFF724FD05006846007803 +S1138E80002803D001210198FFF747FD2800C0B254 +S1138E901BB0F0BDF05B00200022026041600123A2 +S1138EA003724272704770B504000E0015009E48AC +S1138EB0215A9E482018FFF7EFFF7820205C0128F4 +S1138EC006D02A0092B2310020001830FCF74EFB85 +S1138ED070BDFEB505000E001400082100226F4687 +S1138EE03800FCF707F92000C0B2782805D08E4876 +S1138EF0295A8E482818FFF7CFFF7920285C0028CC +S1138F0014D02000C0B211280FD02000C0B2122803 +S1138F100BD02000C0B2312807D02000C0B27E2878 +S1138F2003D02000C0B27F2800D10AE068467F2128 +S1138F300170467084700322694628001830FCF7DB +S1138F4015FBF7BD30B50020030004210200130017 +S1138F500C00DBB2E4B2A34208D2754B1400E4B2B5 +S1138F6014256C431B191871521CF0E730BDFFB572 +S1138F7081B0070000252E002C00280069460870E7 +S1138F8029002A00002F02D10A98058032E038789F +S1138F90C0B200096B46187038780007000F6B46A2 +S1138FA05870280001006A461278C9B291420BD267 +S1138FB00100C9B2791849780322121AD2009140EB +S1138FC031430E00401CEDE7280069464978C0B2E1 +S1138FD088420BD22800C0B2381840790321491BBB +S1138FE0C9008840204304006D1CEDE721003000D7 +S1138FF0FEF70CFB05B0F0BD7047FBB5040017008D +S1139000089D2E88FEF7DAFA012814D1FEF7D9FA62 +S11390100100C9B2022908D10121320092B2B95427 +S1139020761C0021424A11710DE00221320092B2F5 +S1139030B954761C07E00320310089B27854761CB9 +S113904000203B4908712E80F7BDF8B504000F00DD +S113905015001E00FEF760FBF1BD7047FBB5040070 +S11390601700089D2E88FEF7A9FA042822D1FEF7DE +S1139070A8FA012805D10220310089B27854761C5F +S113908018E0FEF79EFA022814D1FEF79DFA012893 +S113909008D10120310089B27854761C002025497A +S11390A0087007E00320310089B27854761C002050 +S11390B0204908702E80F7BDF8B504000F00150094 +S11390C01E00FEF729FBF1BD7047FBB50400170035 +S11390D0089D2E88FEF772FA042822D1FEF771FA51 +S11390E0012805D10220310089B27854761C18E099 +S11390F0FEF767FA022814D1FEF766FA012808D1B0 +S11391000120310089B27854761C00200849087681 +S113911007E00320310089B27854761C002004490A +S113912008762E80F7BD00008C080000A808000017 +S11391300C08002038080020704770477047F7B5C6 +S1139140FFB087B0002604963000694608733000EB +S11391506946488134003000694608700420694635 +S11391604873802080000190320005AD01992800E9 +S1139170FBF7C0FF30006946088188A800888699FB +S11391808968869A7A23D25CD2008918497889B290 +S1139190884205D2132231218698FFF79AFE2BE1EB +S11391A07F27879840783840694608738798807885 +S11391B000028799C97840186946C88188A8008840 +S11391C0001F6946488168464089002802D0879874 +S11391D0001D0490350028006946497BC0B28842CE +S11391E034D287482900C9B214225143415A6A46ED +S11391F0D289914228D1869949782A00D2B214237F +S11392005A4382189278914218D12900C9B2142283 +S113921051434118C97800290FD02900C9B214223A +S113922051434018C07886998978884205D0332202 +S113923031218698FFF74DFEDEE007E0222231213E +S11392408698FFF746FED7E06D1CC4E72800694600 +S1139250497BC0B2884205D3312231218698FFF779 +S113926038FEC9E0802080000190009605AC009A89 +S113927001992000FBF73EFF05AC71202070879810 +S11392804078607087988078A0708798C078E07084 +S11392900420694608816846007B012805D000D275 +S11392A081E003285BD02CD37DE055482900C9B266 +S11392B01422514340180079012808D12770312025 +S11392C060702420A07003206946088118E04C4E89 +S11392D002A8009080239B0005AA6846418904984F +S11392E084462F00FFB214204743F0198768604674 +S11392F0B84701202900C9B21422514371180871DA +S11393005AE03F482900C9B2142251434018007959 +S113931000281BD002A8009080239B0005AA684661 +S1139320418904980190364884462F00FFB21420E6 +S113933047436046C019C7680198B84730482900B8 +S1139340C9B2142251434018067107E02770312036 +S113935060702420A0700320694608812CE0284E08 +S11393602800C0B21421484330180079002811D0D5 +S113937002A8009080239B0005AA684641890498AE +S1139380B4462F00FFB2142677436646F6193669B1 +S1139390B04707E02770312060702420A0700320BC +S11393A06946088108E02770312060701220A0709F +S11393B00320694608811FE068460089042809DB08 +S11393C02078712806D16846028905A98698FFF796 +S11393D06AFD11E068460089032808D120787F28B7 +S11393E005D1A27831218698FFF773FD04E0242289 +S11393F031218698FFF76DFD7FB00AB0F0BD000003 +S11394000C080020002202604160012303724272B2 +S1139410704770B504000E0015009648215A96480E +S11394202018FFF7EFFF7820205C012806D02A00DF +S113943092B2310020001830FCF798F870BDFEB5E8 +S113944005000E001400082100226F463800FBF7C7 +S113945051FE2000C0B2782805D08648295A864893 +S11394602818FFF7CFFF7920285C002814D02000AB +S1139470C0B211280FD02000C0B212280BD0200097 +S1139480C0B2312807D02000C0B27E2803D020000B +S1139490C0B27F2800D10AE068467F21017046707F +S11394A084700322694628001830FCF75FF8F7BD82 +S11394B0FAB583B00400150001A870490A68026077 +S11394C088200001201803C8009001A800990170A9 +S11394D00099090A41700099090CC9B2427807231E +S11394E05A43891881700099090EC9B2027803237E +S11394F05A438918C1706846007C042819D3042093 +S113950001000A9A11806946097BA278914208D128 +S1139510029000262F00320002993800FBF7EAFD82 +S113952007E0029001AE2F00029A31003800FBF7E9 +S1139530D3FD05B0F0BDFEB504002000C0B2012883 +S113954002D0092846D093E04D4D68460E782F7816 +S1139550774007704E786F78774047708E78AF7891 +S113956077408770CE78ED787540C57001ADC678C8 +S1139570F02737402F70C678B700BC263E404778A6 +S1139580BF07BF0F37436F7046783700FFB2BF087D +S1139590BC460778C0263E4067463E43AE70067818 +S11395A0360180780007000F3043E87028781E7871 +S11395B0B0420BD168785E78B04207D1A8789E7823 +S11395C0B04203D1E878DD78A84201D0002050E011 +S11395D001204EE02A4D68460E782F7877400770B8 +S11395E04E786F78774047708E78AF787740877081 +S11395F0CE78ED787540C57001AD4678B700BC46AD +S11396008778F0263E4067463E432E700678F6B2D1 +S1139610B6083B273740BC4647787E263E4067461F +S11396203E436E70C6783700FFB23F09BC460778E8 +S11396302C263E4067463E43AE7086783601C0789D +S11396407D2707403743EF7028781E78B0420BD14E +S113965068785E78B04207D1A8789E78B04203D18A +S1139660E878DD78A84201D0002002E0012000E083 +S11396700020FEBD8C080000A808000010C40000F3 +S113968014C40000F7B586B000206946887208212A +S11396900020009003AC009A2000FBF72BFD002073 +S11396A06946C880002069460881002069464871DF +S11396B06846008C06998968069A7A23D25CD2009F +S11396C08918497889B2884205D21322272106983D +S11396D0FFF7B5FE14E106984078012805D122224F +S11396E027210698FFF7ABFE0AE107984078400669 +S11396F0400E6946087103AF6720387068460079E8 +S1139700787068460079C00700D47FE000263000F6 +S11397107C49087034002000C0B2022837DA7A4D40 +S1139720684600792100C9B20901695C88422CD1DC +S11397302000C0B20001281880782100C9B20901B4 +S11397406918497888421FD206988821090140186F +S11397500CC808382000C0B200012818083003C81B +S1139760121A8B41694800218B4208DC01DB8242DA +S113977005D2362227210698FFF761FEC0E02000BB +S1139780C0B200012818467001E0641CC3E7200041 +S1139790C0B2022805DB312227210698FFF74FFECD +S11397A0AEE006206946088101A8801C0090684646 +S11397B00389DBB2BA1C684601790698FFF778FE84 +S11397C06846C08800281BD06846C288921C92B2A2 +S11397D003A90698FFF71DFE6846007949490870F9 +S11397E06846C0884A4908806846C088009003A833 +S11397F0851C484E009A29003000FBF76DFC7FE081 +S1139800312227210698FFF71AFE79E03D4D68467C +S113981000792978491C884205D0242227210698FA +S1139820FFF70DFE6CE06846008C801E80B200904D +S11398300798831C3648028836492878FFF77BFE50 +S11398406946487168464079012822D1022203A959 +S11398500698FFF7DEFD00200100297069460979AA +S1139860491E069A917004002100C9B2022947DA00 +S113987025496A4612792300DBB21B01CB5C9A426C +S113988005D102002300DBB21B01C9184A70641C15 +S1139890EAE7352227210698FFF7D1FD00242000AE +S11398A0C0B202282CDA184A28782100C9B209016A +S11398B0515C884222D12000C0B2000110184078C7 +S11398C0401C2100C9B20901511848702000C0B2DF +S11398D00001101880782100C9B209015118497893 +S11398E088420BD2069888210901401803C8230036 +S11398F0DBB21B01D218083203C2083A641CCEE75B +S113990009B0F0BDD55500208006002010270000C6 +S1139910D0550020805500200000000096300777C5 +S11399202C610EEEBA51099919C46D078FF46A704F +S113993035A563E9A395649E3288DB0EA4B8DC796F +S11399401EE9D5E088D9D2972B4CB609BD7CB17EEF +S1139950072DB8E7911DBF906410B71DF220B06ABF +S11399604871B9F3DE41BE847DD4DA1AEBE4DD6DCF +S113997051B5D4F4C785D38356986C13C0A86B64CF +S11399807AF962FDECC9658A4F5C0114D96C0663EF +S1139990633D0FFAF50D088DC8206E3B5E10694CCF +S11399A0E44160D5727167A2D1E4033C47D4044B0F +S11399B0FD850DD26BB50AA5FAA8B5356C98B242EF +S11399C0D6C9BBDB40F9BCACE36CD832755CDF456F +S11399D0CF0DD6DC593DD1ABAC30D9263A00DE519F +S11399E08051D7C81661D0BFB5F4B42123C4B3568F +S11399F09995BACF0FA5BDB89EB802280888055F0F +S1139A00B2D90CC624E90BB1877C6F2F114C68586E +S1139A10AB1D61C13D2D66B69041DC760671DB015C +S1139A20BC20D2982A10D5EF8985B1711FB5B6062E +S1139A30A5E4BF9F33D4B8E8A2C9077834F9000F6E +S1139A408EA8099618980EE1BB0D6A7F2D3D6D080E +S1139A50976C6491015C63E6F4516B6B62616C1CFE +S1139A60D83065854E0062F2ED95066C7BA5011B2E +S1139A70C1F4088257C40FF5C6D9B06550E9B712CE +S1139A80EAB8BE8B7C88B9FCDF1DDD62492DDA158E +S1139A90F37CD38C654CD4FB5861B24DCE51B53AAE +S1139AA07400BCA3E230BBD441A5DF4AD795D83DAE +S1139AB06DC4D1A4FBF4D6D36AE96943FCD96E34EE +S1139AC0468867ADD0B860DA732D0444E51D0333CE +S1139AD05F4C0AAAC97C0DDD3C710550AA410227DE +S1139AE010100BBE86200CC925B56857B3856F20AE +S1139AF009D466B99FE461CE0EF9DE5E98C9D9290E +S1139B002298D0B0B4A8D7C7173DB359810DB42E4D +S1139B103B5CBDB7AD6CBAC02083B8EDB6B3BF9A99 +S1139B200CE2B6039AD2B1743947D5EAAF77D29D25 +S1139B301526DB048316DC73120B63E3843B649405 +S1139B403E6A6D0DA85A6A7A0BCF0EE49DFF099305 +S1139B5027AE000AB19E077D44930FF0D2A3088775 +S1139B6068F2011EFEC206695D5762F7CB67658025 +S1139B7071366C19E7066B6E761BD4FEE02BD38925 +S1139B805A7ADA10CC4ADD676FDFB9F9F9EFBE8E85 +S1139B9043BEB717D58EB060E8A3D6D67E93D1A1C5 +S1139BA0C4C2D83852F2DF4FF167BBD16757BCA6A5 +S1139BB0DD06B53F4B36B248DA2B0DD84C1B0AAF45 +S1139BC0F64A0336607A0441C3EF60DF55DF67A8C5 +S1139BD0EF8E6E3179BE69468CB361CB1A8366BC55 +S1139BE0A0D26F2536E2685295770CCC03470BBBA5 +S1139BF0B91602222F260555BE3BBAC5280BBDB2A5 +S1139C00925AB42B046AB35CA7FFD7C231CFD0B544 +S1139C108B9ED92C1DAEDE5BB0C2649B26F263EC36 +S1139C209CA36A750A936D02A906099C3F360EEB44 +S1139C308567077213570005824ABF95147AB8E204 +S1139C40AE2BB17B381BB60C9B8ED2920DBED5E5E4 +S1139C50B7EFDC7C21DFDB0BD4D2D38642E2D4F134 +S1139C60F8B3DD686E83DA1FCD16BE815B26B9F6C4 +S1139C70E177B06F7747B718E65A0888706A0FFF24 +S1139C80CA3B06665C0B0111FF9E658F69AE62F8E4 +S1139C90D3FF6B6145CF6C1678E20AA0EED20DD7E4 +S1139CA05483044EC2B30339612667A7F71660D004 +S1139CB04D476949DB776E3E4A6AD1AEDC5AD6D944 +S1139CC0660BDF40F03BD83753AEBCA9C59EBBDE64 +S1139CD07FCFB247E9FFB5301CF2BDBD8AC2BACA14 +S1139CE03093B353A6A3B4240536D0BA9306D7CD84 +S1139CF02957DE54BF67D9232E7A66B3B84A61C4A4 +S1139D00021B685D942B6F2A37BE0BB4A18E0CC363 +S1139D101BDF055A8DEF022DF0B590B00120010034 +S1139D206A469170DA4A04920499C96A0423DB43AF +S1139D3019406C46A478A40004252C400C430B94D1 +S1139D400B99049CE16201006C46617003920399D3 +S1139D50C96A0124A1436C46647804400C430A9404 +S1139D600A99039CE16200210C006D462C7002925A +S1139D70029AD26A13406A4612789200042422405E +S1139D801A430992099A029BDA62CB4A0892CB4A97 +S1139D900792089B079C23660300C94C0194019C0D +S1139DA024680F25AC431D00EDB22D072D0F25436C +S1139DB00695069C019D2C60C24CC34D0595059DDE +S1139DC08026AC51C14D2D682D0EAD07AD0FEDB2FF +S1139DD0022D2AD10B006C462370BD4B5D68BD4C2F +S1139DE02C406D462D782D02F02636012E40264358 +S1139DF00296029C5C600C00B44D0195019E36688D +S1139E00B54F3740BC462600F6B23704C026B6022A +S1139E103E4067463E43019F3E602B001B681B0E7D +S1139E209B079B0FDBB2002BF7D103000092009C31 +S1139E30E4680C25AC431D00EDB2AD000C262E40A9 +S1139E4026430196019C009DEC6004001500EE6819 +S1139E500127BE432700FFB207403743EF601300DA +S1139E601B6A9C0803002340DBB2002BF7D00B00D5 +S1139E706C4663710892089B5B690124A3436C469A +S1139E80647904401C430F940F9B089C63610B008E +S1139E906C4623710792079B9B691024A3436C466D +S1139EA02479240110252C401C430E940E9B079CFE +S1139EB0A3610B006C46E3700692069B5C69874BBA +S1139EC023406C46E4782402C025AD0025401D43A0 +S1139ED00D950D9B069C636150236C46A3700592FF +S1139EE0059B5B69FE24A3436C46A4786400FE25AD +S1139EF025401D430C950C9B059C63610B006C462F +S1139F0063700492049B5C69754B23406C466478CF +S1139F10A4028025ED002C401C430B940B9B049C55 +S1139F20636104231C006D462C700392039C6569D5 +S1139F306C4C2C406D462D78ED02E026B6012E4087 +S1139F4026430A960A9C039D6C6104000292029DBA +S1139F506D690126B5432600F6B206402E430996E4 +S1139F60099D029E7561FA256D015F4E35605F4D56 +S1139F7029605F4E05273760346880277F02BC4222 +S1139F80FAD33360584B1960296013001C6A03002C +S1139F902340DBB2002BF8D002246B461C71554BD6 +S1139FA00693069DC826AE594B4D35406E4636790C +S1139FB03704C026B6023E402E430896089D069EEE +S1139FC0C827F55109256E46F5700593059DC826E9 +S1139FD0AD59404E2E400296029D6E46F6783702E9 +S1139FE0F02636013E402E430296029D059EC82768 +S1139FF0F55105006E46B5700493049BC8255B5962 +S113A0001025AB436D46AD782D01102635401D4318 +S113A0100795079B049DC826AB516B4658702C4D81 +S113A0206B682C4818406B465B781E02F0231B01BA +S113A030334003436B606846047024480390039CD8 +S113A0402668254C34406E4636783704C026B6025E +S113A0503E402643039C266003001B681B0E9B079F +S113A0609B0FDBB2022BF7D10B00154C0094009C24 +S113A07024680F25AC431D00EDB22D072D0F254399 +S113A0800295029C009D2C600C000568114E01E0B5 +S113A09000F005402E402500EDB22F02F0252D01E1 +S113A0A03D40354305600191019E1666064E8027AA +S113A0B0F15110B0F0BD00BF2020961900E0064019 +S113A0C000E406405245535500F0064000E80640BF +S113A0D000000240FFF0FFFFFFFFFCFFFFFCFFFF5B +S113A0E0FFFBFFFFFFC7FFFF14E000E018E000E004 +S113A0F010E000E000F80640002202604160012305 +S113A10003724272704770B504000E001500B8481F +S113A110215AB8482018FFF7EFFF7820205C012867 +S113A12006D02A0092B2310020001830FBF71EFA44 +S113A13070BDFEB505000E001400082100226F4614 +S113A1403800FAF7D7FF2000C0B2782805D0A84815 +S113A150295AA8482818FFF7CFFF7920285C00283F +S113A16014D02000C0B211280FD02000C0B2122891 +S113A1700BD02000C0B2312807D02000C0B27E2806 +S113A18003D02000C0B27F2800D10AE068467F21B6 +S113A1900170467084700322694628001830FBF76A +S113A1A0E5F9F7BDF7B5FFB085B0050000206946B5 +S113A1B0488000206946C8800026002069468880BF +S113A1C00024002069460870802189000020029044 +S113A1D004AF029A3800FAF78DFF86A80088A968B0 +S113A1E07A22AA5CD2008918497889B2884205D2B9 +S113A1F0132222212800FFF79CFFF6E086A800889E +S113A200401EC00705D5132222212800FFF791FF25 +S113A210EBE086A800884008694648806846408884 +S113A220002805D1132222212800FFF782FFDCE059 +S113A230622004A9320092B28854761C01273800A7 +S113A24086A9098880B2884200D3BEE08598390087 +S113A25089B2405C000285993A0092B28918497823 +S113A26008436946C880002001006A461170040052 +S113A2702000A98A80B2884200D3A0E02869210086 +S113A28089B214224A43805A6946C988884200D058 +S113A29093E0A8782969220092B214235343C91881 +S113A2A00979884205D0332222212800FFF741FF93 +S113A2B09BE0300080B22969220092B214235343F8 +S113A2C0C91889894018801C4B49884205DB14222F +S113A2D022212800FFF72DFF87E02869210089B299 +S113A2E014224A4380188078052809D0687829699F +S113A2F0220092B214235343C918C978884205D264 +S113A300222222212800FFF714FF6EE02869210091 +S113A31089B214224A4380188289D2B22869210062 +S113A32089B214234B43C0188168280005002B69A7 +S113A3309C4623009BB214205843634618180369B3 +S113A3402800984701206946087004A885993A00B6 +S113A35092B2895C320092B28154761C85993A009B +S113A36092B289184978320092B28154761C6846B8 +S113A37086802869210089B214224A438018808982 +S113A38003902869210089B214224A438018806806 +S113A390029004A8694689884618039A02993000F5 +S113A3A0FAF79AFE684680882969220092B214233B +S113A3B05343C9188989461801E0641C58E7684664 +S113A3C00078002801D0BF1C39E7684600780028CF +S113A3D006D0320092B204A92800FFF794FE04E0EC +S113A3E0312222212800FFF7A4FE7FB008B0F0BD7F +S113A3F08C080000A808000001020000002202608E +S113A4004160012303724272704770B504000E006C +S113A41015009D48215A9D482018FFF7EFFF78202A +S113A420205C012806D02A0092B2310020001830A6 +S113A430FBF79CF870BDFEB505000E001400082162 +S113A44000226F463800FAF755FE2000C0B2782883 +S113A45005D08D48295A8D482818FFF7CFFF792059 +S113A460285C002814D02000C0B211280FD020008E +S113A470C0B212280BD02000C0B2312807D020006F +S113A480C0B27E2803D02000C0B27F2800D10AE0E9 +S113A49068467F2101704670847003226946280053 +S113A4A01830FBF763F8F7BD704770477047704783 +S113A4B0F4B5FFB085B005000E00002738006946EA +S113A4C048803800694608703800694608710220DF +S113A4D069464870802189003A0004AC2000FAF7EC +S113A4E009FE84A80088A9687A22AA5CD200891887 +S113A4F0497889B2884205D213222F212800FFF718 +S113A5009AFFBDE06878012805D122222F21280076 +S113A510FFF791FFB4E070780002B1784018694603 +S113A5204880F078694608703C0020006946497804 +S113A530C0B2884223D256482100C9B214225143E2 +S113A540415A6A465288914217D12100C9B2142255 +S113A55051434118897800290ED02100C9B2142230 +S113A560514340188078A978884205D033222F219E +S113A5702800FFF760FF83E001E0641CD5E72000BA +S113A58069464978C0B2884205D331222F21280078 +S113A590FFF751FF74E004A86F21017071784170D6 +S113A5A0B1788170F178C17068460078002802D0D3 +S113A5B003281CD05FE036482100C9B2142251435D +S113A5C04118CF722100C9B21422514341180969BC +S113A5D000290BD02100C9B214225143401800694C +S113A5E08047042204A92800FFF70FFF48E0284F02 +S113A5F084A800882100C9B2142251437918097A29 +S113A600091D884205DA22222F212800FFF713FFB3 +S113A61036E001202100C9B2142251437918C872CE +S113A6202000C0B2142148433818007A0390301D2A +S113A63002902000C0B214214843381840680190A9 +S113A640039A02990198FAF747FD01982000C0B2D5 +S113A650142148433818C06800280BD02000C0B229 +S113A660142148433818C0688047042204A92800EC +S113A670FFF7CBFE04E031222F212800FFF7DBFE99 +S113A6807FB006B0F0BD00008C080000A8080000F0 +S113A690E407002000220260416001230372427239 +S113A6A0704770B504000E0015002548215A25484E +S113A6B02018FFF7EFFF7820205C012806D02A003D +S113A6C092B2310020001830FAF750FF70BDFEB589 +S113A6D005000E001400082100226F463800FAF726 +S113A6E009FD2000C0B2782805D01548295A15481C +S113A6F02818FFF7CFFF7920285C002814D0200009 +S113A700C0B211280FD02000C0B212280BD02000F4 +S113A710C0B2312807D02000C0B27E2803D0200068 +S113A720C0B27F2800D10AE068467F2101704670DC +S113A73084700322694628001830FAF717FFF7BD22 +S113A7408C080000A808000010B50024FCF724FDC4 +S113A750801C10BD10B5010000200300012213006D +S113A760DBB2052B0CDA04239B1ADB000C00DC4063 +S113A770002C03D005239B1A180001E0521CEEE7BD +S113A780C0B210BDF7B586B00020050001006A46CE +S113A79011700400070001006A4651700290010024 +S113A7A06A46D170060006994978012905D122220A +S113A7B034210698FFF78BFFA4E069460B8C0699B9 +S113A7C08A689446069A7A21515CC90062465118F7 +S113A7D0497889B28B4205D2132234210698FFF7B7 +S113A7E076FF8FE0079989780907090F6A46117087 +S113A7F007998978C9B209096A4691706946097846 +S113A80000290BD069460978052907D26946897859 +S113A810002903D069468978052905D331223421DA +S113A8200698FFF754FF6DE001000A006B461B78A1 +S113A830D2B29A4208D22A02079B0D00EDB25B19EC +S113A840DB78D518491CF0E7070038006946897899 +S113A850C0B288420BD2210207986A4612783B00A4 +S113A860DBB2D2188018C0780C187F1CEDE7002CDE +S113A87005D1222234210698FFF729FF42E000F097 +S113A88083F8280000F08EF8200000F08EF80120F4 +S113A89000F091F8FFF758FF02900298FFF75AFF73 +S113A8A06946487003A87421320092B28154761C20 +S113A8B0694649780901320092B28154761C69468E +S113A8C08E800126694649783200D2B291420FD374 +S113A8D002996A465278921BD200D1406A46928805 +S113A8E0815469468988491C6A469180761CE9E747 +S113A8F021002800FCF7CAFE6846828803A906984E +S113A900FFF7CFFE09B0F0BD0022026041600123D1 +S113A910037242727047FEB505000E001400082150 +S113A92000226F463800FAF7E5FB2000C0B2782811 +S113A93005D06348295A63482818FFF7E5FF7920B2 +S113A940285C002814D02000C0B211280FD02000A9 +S113A950C0B212280BD02000C0B2312807D020008A +S113A960C0B27E2803D02000C0B27F2800D10AE004 +S113A97068467F210170467084700322694628006E +S113A9801830FAF7F3FDF7BD002001004E4A1170AC +S113A99001004E4A11704E4908604E4908604E4904 +S113A9A0086070474B49086070474B49086070471E +S113A9B0494800687047494908707047474800781B +S113A9C07047434800687047F6B583B005000A2114 +S113A9D000226C462000FAF78DFB6878012805D127 +S113A9E0222236212800FFF796FF66E06846008A97 +S113A9F0A9687A22AA5CD2008918497889B2884267 +S113AA0005D2132236212800FFF785FF55E033488D +S113AA100078012802D0022844D049E02A4C039847 +S113AA2040782070294E2078317888420BD02078E5 +S113AA303178491CC9B2884205D0732236212800D6 +S113AA40FFF769FF39E0224F2348006839686A46F6 +S113AA50128A8918891E884205D27122362128005B +S113AA60FFF759FF29E020783178491CC9B28842A0 +S113AA7017D122786846018A891E89B20398801CFE +S113AA80FCF722FE012805D138686946098A401876 +S113AA90801E3860207830706846762101702178F5 +S113AAA041700AE0312236212800FFF734FF04E028 +S113AAB0242236212800FFF72EFF05B0F0BD000048 +S113AAC08C080000A8080000D8550020D9550020A3 +S113AAD0945500208C55002090550020D755002017 +S113AAE091490870704730B5010089B2142928DAF9 +S113AAF000218E4A0B000400A4B20C2565435419AE +S113AB00237103009BB20C245C4313191B1D1C7896 +S113AB10102525431D7003009BB20C245C431319BC +S113AB201B1D1C78402525431D7003009BB20C247B +S113AB305C431319D98003009BB20C245C431219A3 +S113AB40117230BD70B5010000231C001A001800FA +S113AB501C00A4B2142C10DA744C1D00ADB20C26E7 +S113AB606E43A41924796406640E22001400E4B22E +S113AB700C4200D0401C5B1CEAE780B270BDF2B509 +S113AB80010000242500230020002500ADB2142D6F +S113AB9039DA664D2600B6B20C277743EE193679BA +S113ABA033001E00F6B216422BD06E4636880700DC +S113ABB0BFB23F1DBE4223DB2600B6B20C2777434B +S113ABC0EE59360C0700BFB2CE55401C2600B6B273 +S113ABD00C277743EE59360A0700BFB2CE55401C06 +S113ABE02600B6B20C277743ED590600B6B28D5550 +S113ABF0401C5D066D0E0600B6B28D55401C00E08B +S113AC0001E0641CC1E780B2F2BDF0B5020000248B +S113AC102500230020002500ADB2142D33DA434D66 +S113AC202600B6B20C277743EE19367933000E00AE +S113AC30B6B20700BFB23F1DBE4224DB2600B6B247 +S113AC400C277743EE59360C0700BFB2D655401C8B +S113AC502600B6B20C277743EE59360A0700BFB276 +S113AC60D655401C2600B6B20C277743ED59060092 +S113AC70B6B29555401C5D066D0E0600B6B29555EC +S113AC80401C641CC7E780B2F0BD38B50400002046 +S113AC9005002100264A891A04D09D3918D02F397D +S113ACA035D03FE00500280080B214280FDA1F4891 +S113ACB0290089B20C224A438058802149038842E2 +S113ACC003D2280080B2FFF70EFF6D1CEBE729E0EA +S113ACD00500280080B2142818DA1448290089B223 +S113ACE00C224A4381588022D20391420CD329007A +S113ACF089B20C224A43805880210904884203D235 +S113AD00280080B2FFF7EFFE6D1CE2E70AE00500C1 +S113AD10280080B2142805DA280080B2FFF7E3FE89 +S113AD206D1CF5E731BD0000D4550020F406002069 +S113AD3033FFFF00010005000000000000000000D8 +S113AD4000000000090005000000000000000000F1 +S113AD500000000071720000AB7200002973000053 +S113AD6055750000217400001975000001000000F1 +S113AD7032070000DF070000B2070000AC320020F9 +S113AD8000020000AC340020200800000000000095 +S113AD90F55D0000AD5C00003200F4018813000092 +S113ADA001020304050607081A62040050000000AB +S113ADB0000000001B6304005000000000000000BD +S113ADC01603F00050000000000000001703F0001C +S113ADD050000000000000008873C0005000000014 +S113ADE0000000000100C10050000000000000004D +S113ADF00101C10050000000000000000121C10059 +S113AE0050000000000000000127C10050000000B5 +S113AE10000000000128C1005000000000000000F4 +S113AE200129C10050000000000000000131C100F0 +S113AE3050000000000000000041C100500000006C +S113AE40000000000151C10050000000000000009B +S113AE500063C10050000000000000000069C10050 +S113AE6050000000000000000181C10050000000FB +S113AE70000000000136C200500000000000000085 +S113AE800064C10050000000000000000067C10021 +S113AE90500000000000000092F0000088550020DF +S113AEA002000000A9A40000ABA4000020F00000F0 +S113AEB08A55002002000000ADA40000AFA40000E9 +S113AEC001FD0209000000006F8F0000F98F0000EF +S113AED0FB8F000002FD020900000000B990000091 +S113AEE0C9900000CB90000003FD0209000000009F +S113AEF04B9000005B9000005D90000004FD02098F +S113AF0000000000399100003B9100003D910000D9 +S113AF1086F10601000000009855002001000000A1 +S113AF209770000087F10601000000009955002089 +S113AF30080000009D70000080F106010000000080 +S113AF40A1550020080000007970000091F106016D +S113AF5000000000A955002018000000BD7000008A +S113AF6093F1060100000000C15500200400000018 +S113AF70F970000095F1060100000000C55500209D +S113AF8008000000157100000022026041600123E6 +S113AF9003724272704770B504000E0015007E48BB +S113AFA0215A7E482018FFF7EFFF7820205C012803 +S113AFB006D02A0092B2310020001830FAF7D6FAEF +S113AFC070BDFEB505000E001400082100226F4676 +S113AFD03800FAF78FF82000C0B2782805D06E4800 +S113AFE0295A6E482818FFF7CFFF7920285C0028DB +S113AFF014D02000C0B211280FD02000C0B21228F3 +S113B0000BD02000C0B2312807D02000C0B27E2867 +S113B01003D02000C0B27F2800D10AE068467F2117 +S113B0200170467084700322694628001830FAF7CC +S113B0309DFAF7BDF6B583B004000E000821002781 +S113B0403A0001AD2800FAF755F83800694648700F +S113B0506846008AA1687A22A25CD20089184978DD +S113B06089B2884205D2132228212000FFF7A9FFC4 +S113B0708EE06078012805D1222228212000FFF7E4 +S113B080A0FF85E070784006400E69460870B578E8 +S113B09001A8682101706946097841706846007802 +S113B0A0002805D0022838D01CD3032850D06AE0E9 +S113B0B02800C0B2012807D02800C0B2022803D05B +S113B0C02800C0B2032807D135480770022201A91D +S113B0D02000FFF760FF04E0312228212000FFF761 +S113B0E070FF55E02800C0B2012807D02800C0B284 +S113B0F0022803D02800C0B2032808D1012028491F +S113B1000870022201A92000FFF745FF04E0312264 +S113B11028212000FFF755FF3AE02800C0B201289B +S113B12007D02800C0B2022803D02800C0B20328E8 +S113B13008D102201A490870022201A92000FFF751 +S113B1402AFF04E0312228212000FFF73AFF1FE004 +S113B1502800C0B2012807D02800C0B2022803D0BA +S113B1602800C0B2032808D103200D490870022228 +S113B17001A92000FFF70FFF04E03122282120005D +S113B180FFF71FFF04E0122228212000FFF719FF18 +S113B19005B0F0BD000000008C080000A808000005 +S113B1A0D6550020002202604160012303724272DE +S113B1B0704770B504000E0015002548215A254833 +S113B1C02018FFF7EFFF7820205C012806D02A0022 +S113B1D092B2310020001830FAF7C8F970BDFEB5FC +S113B1E005000E001400082100226F463800F9F70C +S113B1F081FF2000C0B2782805D01548295A154887 +S113B2002818FFF7CFFF7920285C002814D02000ED +S113B210C0B211280FD02000C0B212280BD02000D9 +S113B220C0B2312807D02000C0B27E2803D020004D +S113B230C0B27F2800D10AE068467F2101704670C1 +S113B24084700322694628001830FAF78FF9F7BD95 +S113B2508C080000A8080000F6B585B005000E00B3 +S113B260002420006946088020006946488008219F +S113B270220003AF3800F9F73DFF6846008BA96848 +S113B2807A22AA5CD2008918497889B2884205D208 +S113B29013222E212800FFF7A2FF82E0707800021B +S113B2A0B17808436946088003A86E21017071785B +S113B2B04170B17881702000A98A80B288426BD233 +S113B2C02869210089B214224A43805A69460988B0 +S113B2D088425FD12869210089B214224A43801828 +S113B2E0007900280FD0A8782969220092B214238B +S113B2F05343C9180979884205D0332222212800F2 +S113B300FFF76DFF4DE06846008BC01E29692200DF +S113B31092B214235343C9188989884205D0132251 +S113B3202E212800FFF75BFF3BE02869210089B24A +S113B33014224A4380188078032809D06878296940 +S113B340220092B214235343C918C978884205D203 +S113B35022222E212800FFF742FF22E02869210043 +S113B36089B214224A43801880890290F01C01900B +S113B3702869210089B214224A4380188768029AF6 +S113B38001993800F9F7A8FE032203A92800FFF762 +S113B39010FF06E0641C8EE731222E212800FFF7FF +S113B3A01EFF07B0F0BD00000022026041600123CF +S113B3B003724272704770B504000E0015002548F0 +S113B3C0215A25482018FFF7EFFF7820205C012838 +S113B3D006D02A0092B2310020001830FAF7C6F8DD +S113B3E070BDFEB505000E001400082100226F4652 +S113B3F03800F9F77FFE2000C0B2782805D0154840 +S113B400295A15482818FFF7CFFF7920285C00280F +S113B41014D02000C0B211280FD02000C0B21228CE +S113B4200BD02000C0B2312807D02000C0B27E2843 +S113B43003D02000C0B27F2800D10AE068467F21F3 +S113B4400170467084700322694628001830FAF7A8 +S113B4508DF8F7BD8C080000A8080000F6B5FFB011 +S113B46082B0070000221000694648701000694647 +S113B470087010006946488015008021890001ACDD +S113B4802000F9F737FE82A80088B9687A22BA5CEE +S113B490D2008918497889B2884205D21322192129 +S113B4A03800FFF79EFF75E07F2681984078304092 +S113B4B06946487001AC5920207068464078607035 +S113B4C068464078012804D0022827D00A2844D0AE +S113B4D05BE082A80088032805D0132219213800D4 +S113B4E0FFF77FFF56E081988078694608706846C8 +S113B4F00078FFF727FB69464880A6700120E070BA +S113B5006846408880B2000A2071684640886071AD +S113B510062201A93800FFF74EFF3BE082A800880D +S113B520032805D0132219213800FFF75AFF31E010 +S113B5308198807869460870A67068460278FF2171 +S113B540FE31E01CFFF71BFB05002A00D21C92B25F +S113B55001A93800FFF72FFF1CE082A80088022809 +S113B56005D0132219213800FFF73BFF12E0FF2119 +S113B570FE31E01CFFF749FB05002A00D21C92B201 +S113B58001A93800FFF717FF04E01222192138003F +S113B590FFF727FF7FB004B0F0BD00000022026077 +S113B5A04160012303724272704770B504000E00BB +S113B5B015006348215A63482018FFF7EFFF7820ED +S113B5C0205C012806D02A0092B2310020001830F5 +S113B5D0F9F7CCFF70BDFEB505000E00140008217C +S113B5E000226F463800F9F785FD2000C0B27828A4 +S113B5F005D05348295A53482818FFF7CFFF79201C +S113B600285C002814D02000C0B211280FD02000DC +S113B610C0B212280BD02000C0B2312807D02000BD +S113B620C0B27E2803D02000C0B27F2800D10AE037 +S113B63068467F21017046708470032269462800A1 +S113B6401830F9F793FFF7BDF2B582B00500170083 +S113B6500821002422006E463000F9F74BFD380023 +S113B660A9687A22AA5CD2008918497880B289B282 +S113B670884205D0132210212800FFF7ACFF5EE0BA +S113B680029840784606760E68465021017046704E +S113B6902D49695A89B2090A81702B49695AC170C6 +S113B6A02A49695A89B2090A01712849695A4171BA +S113B6B0FDF748FC3000C0B2012806D03AD3032875 +S113B6C00BD018D3042827D034E0AC706E70062257 +S113B6D069462800FFF769FF31E0AC706E700622FE +S113B6E069462800FFF761FF1548295A15482818AC +S113B6F0FFF754FF23E0AC706E7006226946280001 +S113B700FFF753FF0E48295A0E482818FFF746FF43 +S113B7100120FBF75FFF12E0AC706E7006226946F1 +S113B7202800FFF742FF0648295A06482818FFF761 +S113B73035FF04E0122210212800FFF74CFFF7BD6B +S113B7408C080000A8080000880800008A0800008F +S113B750210400004D0400002D050000000000003D +S113B7604F05000045060000EF07000045080000F3 +S113B770150900006B0900003D0A0000930A00004F +S113B780610B0000B70B0000810C0000D70C000017 +S113B790A10D0000F70D0000C50E00001F0F0000F2 +S113B7A0810F0000B90F0000E90F00002310000012 +S113B7B057100000F1100000AD1100000313000049 +S113B7C069160000000000007316000097160000C0 +S113B7D0C1160000E51600000F170000000000006D +S113B7E01B1700006F170000211800004B18000001 +S113B7F0751800009F180000C9180000F318000015 +S113B8001D19000047190000711900009B19000060 +S113B810C5190000931A0000211C00008D1C0000B3 +S113B820911D0000011E0000E11E0000231F000006 +S113B8306F1F0000B11F0000012000004320000022 +S113B8408F200000D12000001D2100005F21000096 +S113B850B1210000F1210000452200006B2200000C +S113B86095220000BB220000E52200000B2300000B +S113B870352300005B23000085230000AB23000078 +S113B880D5230000FB23000025240000B32400007E +S113B890CB250000F12500001B2600007F260000B8 +S113B8A029270000000000003327000000000000EA +S113B8B03D2700000000000047270000C5270000C6 +S113B8C0AF2800002D290000172A0000512A00008B +S113B8D0AD2A0000E72A00003F2B0000672B000080 +S113B8E0002202604160012303724272704770B506 +S113B8F004000E0015002548215A25482018FFF79A +S113B900EFFF7820205C012806D02A0092B2310093 +S113B91020001830F9F72AFE70BDFEB505000E00B0 +S113B9201400082100226F463800F9F7E3FB2000D9 +S113B930C0B2782805D01548295A15482818FFF7A9 +S113B940CFFF7920285C002814D02000C0B2112831 +S113B9500FD02000C0B212280BD02000C0B2312872 +S113B96007D02000C0B27E2803D02000C0B27F28B8 +S113B97000D10AE068467F2101704670847003227A +S113B980694628001830F9F7F1FDF7BD8C0800006E +S113B990A8080000F2B582B00400160000221500C9 +S113B9A008216F463800F9F7A5FB6078012805D116 +S113B9B0222237212000FFF7B0FF40E03000A168C9 +S113B9C07A22A25CD2008918497880B289B288426E +S113B9D005D2132237212000FFF79FFF2FE07720A5 +S113B9E069462A0092B288546D1C2F00FEF7E6FFC8 +S113B9F0012802D0022814D019E0FEF7E2FF050066 +S113BA00FEF7D6FF854205D0132237212000FFF729 +S113BA1084FF11E03A0092B269462000FFF767FF05 +S113BA200AE0312237212000FFF777FF04E02422C7 +S113BA3037212000FFF771FF0020FEF7BCFFF7BDA0 +S113BA40002202604160012303724272704770B5A4 +S113BA5004000E0015002548215A25482018FFF738 +S113BA60EFFF7820205C012806D02A0092B2310032 +S113BA7020001830F9F77AFD70BDFEB505000E0000 +S113BA801400082100226F463800F9F733FB200028 +S113BA90C0B2782805D01548295A15482818FFF748 +S113BAA0CFFF7920285C002814D02000C0B21128D0 +S113BAB00FD02000C0B212280BD02000C0B2312811 +S113BAC007D02000C0B27E2803D02000C0B27F2857 +S113BAD000D10AE068467F21017046708470032219 +S113BAE0694628001830F9F741FDF7BD8C080000BD +S113BAF0A8080000FEB504000F001600082100226B +S113BB0001AD2800F9F7F6FAFF253100A0687A2282 +S113BB10A25CD2008018407889B280B2814205D0FC +S113BB20132211212000FFF7A8FF37E078784006A0 +S113BB30400E6946087001A85121017069460978D0 +S113BB404170857068460078012804D021D3032809 +S113BB5015D00AD31DE0032201A92000FFF777FFC7 +S113BB6001210120FBF748FD18E0032201A9200070 +S113BB70FFF76DFF02210120FBF73EFD0EE00322DB +S113BB8001A92000FFF763FF03210120FBF734FD27 +S113BB9004E0122211212000FFF76FFFF7BD00001F +S113BBA0002202604160012303724272704770B543 +S113BBB004000E0015002548215A25482018FFF7D7 +S113BBC0EFFF7820205C012806D02A0092B23100D1 +S113BBD020001830F9F7CAFC70BDFEB505000E0050 +S113BBE01400082100226F463800F9F783FA200078 +S113BBF0C0B2782805D01548295A15482818FFF7E7 +S113BC00CFFF7920285C002814D02000C0B211286E +S113BC100FD02000C0B212280BD02000C0B23128AF +S113BC2007D02000C0B27E2803D02000C0B27F28F5 +S113BC3000D10AE068467F210170467084700322B7 +S113BC40694628001830F9F791FCF7BD8C0800000C +S113BC50A8080000FEB504000E001500082100220B +S113BC606F463800F9F746FA2800A1687A22A25CE8 +S113BC70D2008918497880B289B2884205D2132249 +S113BC8085212000FFF7A9FF2DE06078012805D168 +S113BC90222285212000FFF7A0FF24E070784706C8 +S113BCA07F0E6846C521017047703800C0B2012874 +S113BCB002D0022809D011E00120FEF711FF022270 +S113BCC069462000FFF773FF0DE00020FEF708FF30 +S113BCD0022269462000FFF76AFF04E01222852150 +S113BCE02000FFF77AFFF7BD0022026041600123C4 +S113BCF003724272704770B504000E001500444888 +S113BD00215A44482018FFF7EFFF7820205C0128CF +S113BD1006D02A0092B2310020001830F9F726FC30 +S113BD2070BDFEB505000E001400082100226F4608 +S113BD303800F9F7DFF92000C0B2782805D034487C +S113BD40295A34482818FFF7CFFF7920285C0028A7 +S113BD5014D02000C0B211280FD02000C0B2122885 +S113BD600BD02000C0B2312807D02000C0B27E28FA +S113BD7003D02000C0B27F2800D10AE068467F21AA +S113BD800170467084700322694628001830F9F760 +S113BD90EDFBF7BDF7B504000D00002216000821E5 +S113BDA06F463800F9F7A6F968460089A1687A2237 +S113BDB0A25CD2008918497889B2884205D013223E +S113BDC014212000FFF7ADFF20E068780004304321 +S113BDD0A97809020143EE780E435420694608709D +S113BDE030000D49401A03D09D3801D02F3808D1B6 +S113BDF03000FEF74AFF012269462000FFF77BFF6F +S113BE0004E0312214212000FFF78BFFF7BD00006E +S113BE108C080000A808000033FFFF000022026025 +S113BE204160012303724272704770B504000E0032 +S113BE3015002548215A25482018FFF7EFFF7820E0 +S113BE40205C012806D02A0092B23100200018306C +S113BE50F9F78CFB70BDFEB505000E001400082137 +S113BE6000226F463800F9F745F92000C0B278285F +S113BE7005D01548295A15482818FFF7CFFF79200F +S113BE80285C002814D02000C0B211280FD0200054 +S113BE90C0B212280BD02000C0B2312807D0200035 +S113BEA0C0B27E2803D02000C0B27F2800D10AE0AF +S113BEB068467F2101704670847003226946280019 +S113BEC01830F9F753FBF7BD8C080000A8080000F0 +S113BED0FEB504000E001500082100226F4638004C +S113BEE0F9F708F92800A1687A22A25CD20089181F +S113BEF0497880B289B2884205D013223E212000BD +S113BF00FFF7A9FF15E0707847067F0E3800C0B22E +S113BF10002809D168467E210170477002226946D3 +S113BF202000FFF782FF04E012223E212000FFF7E9 +S113BF3092FFF7BDF0B587B0254802902548264901 +S113BF400691264901912649264A0592264A274BFD +S113BF500493274B0093274B274C0394069C84425D +S113BF6007D00478029D2C70029C641C0294401C2F +S113BF70F4E7059C8C4207D00C78019D2C70019C41 +S113BF80641C0194491CF4E7049C944203D00024EB +S113BF901470521CF8E7039C9C4207D01C78009D47 +S113BFA02C705B1C009C641C0094F4E70024134D6B +S113BFB0AD08AC4207D2124DA600AD59114EA700F0 +S113BFC0F551641CF3E70F4D0F4E356007B0F0BD1B +S113BFD08006002034AD000088AF0000000000207F +S113BFE01C880000988E000000200020DA550020F4 +S113BFF0000000000000000000000000000000003D +S113C000000000000000000008ED00E01002010044 +S113C01049B6000011020100F5BA00002702010030 +S113C020859600002803010035B000003E0201009F +S113C030D1BE00008502010055BC000022030000AF +S113C040A5A100002E04000059B200001404000051 +S113C05095BD0000190301005DB400002F0300002A +S113C060B1A40000310401003F9100003405000038 +S113C07085A7000036020000C9A9000037010000AE +S113C08095B9000072B60021002200230024002587 +S113C09000260027B846B946BA46BB46BC460A49FC +S113C0A00A4A521A013A05DD0020042308601944A3 +S113C0B0043AFBDA06488546064880470648804726 +S113C0C062B6F9F7ABFFFEE700000020EF5B00204B +S113C0D0F05B0020199D000035BF00000000010046 +S113C0E0320700000001080001000000FFFFFFFF0D +S113C0F001000100DF07000000010800010000004A +S113C100FFFFFFFF02000100B2070000000008006B +S113C11000000000FFFFFFFF0300010034020000E5 +S113C1200000080000000000FFFFFFFF03000113F0 +S113C13002401D010B000600070008000C001C0053 +S113C140180017040E000F4004033D0121503E5413 +S113C1503F4C3C052300240025002600270028002E +S113C16029002A002C002D002E002F003000310061 +S113C170320033002B003400000000004669727363 +S113C18074206672616D652073686F756C64206ECF +S113C1906F7420757365206D756C7469706C65209F +S113C1A06672616D65207472616E736D6973736913 +S113C1B06F6E2E004D756C74692D6672616D65200D +S113C1C0726573706F6E736520746F6F206C61722B +S113C1D0676520666F7220726563656976696E674C +S113C1E0206275666665722E000000004D657373EB +S113C1F06167652073697A6520746F6F206C617262 +S113C20067652E205365742061206C6172676572C6 +S113C2102073656E64206275666665720A000000AC +S113C22041626F72742070726576696F7573206DE8 +S113C2306573736167652C207472616E736D6973C5 +S113C24073696F6E20696E2070726F6772657373A5 +S113C2502E0A0000000000000000000000000000A2 +S113C26000000000000000000000000000000000CA +S113C27000000000000000000000000000000000BA +S113C2800000000053696E676C652D6672616D6510 +S113C290206C656E67746820746F6F20736D616CB9 +S113C2A06C206F7220746F6F206C617267652E0052 +S113C2B04669727374206672616D652073686F7568 +S113C2C06C64206265203820627974657320696E1D +S113C2D0206C656E6774682E00000000436F6E73F7 +S113C2E065637574697665206672616D6520746F27 +S113C2F06F2073686F72742E00000000466C6F77B5 +S113C30020636F6E74726F6C206672616D65207449 +S113C3106F6F2073686F72742E00000001000000BC +S113C32002000000040000000800000010000000EB +S113C33020000000400000008000000000F00DF824 +S113C340002801D000BF00BF00BF00BF002000BF15 +S113C35000BFF9F763FE00F002F80120704780B5D2 +S113C36000F002F801BD00000746384600F002F86C +S113C370FBE7000080B500BF00BF024A110018208F +S113C380ABBEFBE7260002000548014603B468463D +S113C39080F3098800BF00BF00BF00BFFFF7CEFFD6 +S113C3A0A5EDF5FE2D2D2D2D2D4A756D70546F4183 +S113C3B070702D2D2D2D2D0A000000002D2D2D2DFA +S113C3C02D494E544F20424F4F542D2D2D2D2D0AC3 +S113C3D00000000025303464203A204D5F535F4351 +S113C3E054524C203D20307825780A0030313233C5 +S113C3F03435363738394142434445465465726DC5 +S113C400696E616C000000005345474745520000C7 +S10BC410010203044D535751CE +S903C389B0 diff --git a/cva_asw_m0118/BOOTHEX/cva_m0118_FlashDrv_iar.srec b/cva_asw_m0118/BOOTHEX/cva_m0118_FlashDrv_iar.srec new file mode 100644 index 0000000..10249a3 --- /dev/null +++ b/cva_asw_m0118/BOOTHEX/cva_m0118_FlashDrv_iar.srec @@ -0,0 +1,65 @@ +S32520005BF000000000395E00204D5E00204D600020F1B489B00120694608710999096807914E +S32520005C10002106916A461279520002231A400692069A079B1A606A46D070099A1268059193 +S32520005C306B46DB781B01102423400593059B13606B469870099B1B6804916C46A478640124 +S32520005C5020252C400494049C1C606C466070099C246803916D466D78AD01402635400395A9 +S32520005C70039D25606D462870099D2D6802916E463678F60008273E400296029E2E60099E3E +S32520005C90366808910100C9B289000427394031600AB0F0BC7047F0B501000025280001222A +S32520005CB013000C681E00F6B2F60180273E4026600B681B68DB091340DBB2002BF8D00B689F +S32520005CD01B685B091340DBB2002B0CD10B681B681B091340DBB2002B05D10B681B681A4074 +S32520005CF0D2B2002A01D007221000C0B2F0BDF2B584B00400002528006946887028006946ED +S32520005D104870206801260068C10A30000840C0B200280ED16846007C01280AD16068006864 +S32520005D30010D30000840C0B2012802D130006946487020680068C10930000840C0B20028D6 +S32520005D5001D109206DE02000FFF752FF0D2069460870290022680195FF2002900B00DBB278 +S32520005D70D3181F7F029B9F43BC466B461F78029B3B4067463B430193019B0F00FFB2D71978 +S32520005D903B776B461B7C002B01D0370000E02F0031006A461170216803910195029003984F +S32520005DB0694609784018007F029988433900C9B2029A0A4002430192019803996A4612785F +S32520005DD0891808772000FFF766FF6946097C002909D021680968CA0A31001140C9B20029C8 +S32520005DF001D1052108006946097C002909D1216809680A0B31001140C9B2002901D1052109 +S32520005E1008000100C9B200290BD169464978002907D021683200D2B2520380239B011A4026 +S32520005E300A60C0B205B0F0BD10B50400824804602000FFF7DDFE0020E06110BDF3B595B0EB +S32520005E5000273800694608707B48046815988005800D002803D0012069460870E7E0380056 +S32520005E703D001698854200D3E1E0206801260068C10930000840C0B2002803D10920694607 +S32520005E900870D4E02000FFF7B3FE05216846017338006A469071206814900997FF2013901A +S32520005EB0149A6B469B79D218137F139A93439C466A46137B139A1A4063461A430992099BCE +S32520005ED09C46149B6A4692799A1863461377159A6B46DA7232006B465A7122681292089734 +S32520005EF01190129A6B465B79D218137F119A93439C466A46D37A119A1A4063461A43089219 +S32520005F10089B9C46129B6A4652799A1863461377159AAB02D218120A6B469A7202226B46C5 +S32520005F301A712268109207970F90109A6B461B79D218137F0F9A93439C466A46937A0F9A05 +S32520005F501A4063461A430792079B9C46109B6A4612799A1863461377159AAB02D218120C5F +S32520005F706B465A7203226B46DA7022680E9206970D900E9A6B46DB78D218137F0D9A934345 +S32520005F909C466A46537A0D9A1A4063461A430692069B9C460E9B6A46D2789A1863461377C2 +S32520005FB0159AAB02D218120E6B461A7204226B469A7022680C9205970B900C9A6B469B785E +S32520005FD0D218137F0B9A93439C466A46137A0B9A1A4063461A430592059B9C460C9B6A4600 +S32520005FF092789A18634613776A46D6716A465170266804970A90684640783018007F0A9981 +S3252000601088436946C9790A9A0A4002430492049869464978711808772000FFF73CFE6946B2 +S32520006030087068460078002801D16D1C19E76846007817B0F0BD0000F05B0020F7B598B010 +S325200060500025280069464874874800680190072018990140002901D0012501E11A99084074 +S32520006070002801D00325FBE028006946087002950B950198006801270068C10A380008408C +S32520006090C0B2012802D138006946087068460078002803D000210198FFF729FE18988005D0 +S325200060B0800D0B900B98A021490544182E001A98864205D21998805D2070641C761CF6E7E8 +S325200060D0019800680068C10938000840C0B2002801D10925BCE00198FFF78AFD06206946B6 +S325200060F008742800694688720198006816900A95FF20159016996A46927A8918097F159AD0 +S3252000611091436A46137C159A1A400A430A920A9A16996B469B7AC9180A7718996A46D17324 +S3252000613069464F720199096814910995139014996A46527A8918097F139A91436A46D27BF8 +S32520006150139B13400B4309930999149A6B465B7AD21811771899090A6A46917302216A468B +S3252000617011720199096812910895119012996A46127A8918097F119A91436A46927B119B82 +S3252000619013400B4308930899129A6B461B7AD21811771899090C6A46517303216A46D17039 +S325200061B001990968109107950F9010996A46D2788918097F0F9A91436A46527B0F9B1340FF +S325200061D00B4307930799109A6B46DB78D21811771899090E6A46117304216A469170019975 +S325200061F009680E9106950D900E996A4692788918097F0D9A91436A46127B0D9B13400B4396 +S32520006210069306990E9A6B469B78D21811771A99C908491E6A46D17205216A465170019923 +S325200062300F6805950C90684640783818007F0C9988436946C97A0C9A0A400243059205987B +S3252000625069464978791808770198FFF724FD050068460078002803D001210198FFF747FDBD +S325200062702800C0B21BB0F0BDF05B0020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S32520006290FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S325200062B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S325200062D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S325200062F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S32520006310FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S32520006330FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S32520006350FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S32520006370FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S32520006390FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S325200063B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S325200063D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10CACC19E4 +S70500000001F9 diff --git a/cva_asw_m0118/SDK/lib/shared/common/check/crc.h b/cva_asw_m0118/SDK/lib/shared/common/check/crc.h new file mode 100644 index 0000000..e9c3c55 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/check/crc.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CRC_H_ +#define _CRC_H_ + +/*! \brief Contains public interface to various functions related + * to the CRC algorithms + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/*! \brief The CRC table + */ +static const uint16_t c_crcTable[] = +{ + 0X0000, 0XC0C1, 0XC181, 0X0140, 0XC301, 0X03C0, 0X0280, 0XC241, + 0XC601, 0X06C0, 0X0780, 0XC741, 0X0500, 0XC5C1, 0XC481, 0X0440, + 0XCC01, 0X0CC0, 0X0D80, 0XCD41, 0X0F00, 0XCFC1, 0XCE81, 0X0E40, + 0X0A00, 0XCAC1, 0XCB81, 0X0B40, 0XC901, 0X09C0, 0X0880, 0XC841, + 0XD801, 0X18C0, 0X1980, 0XD941, 0X1B00, 0XDBC1, 0XDA81, 0X1A40, + 0X1E00, 0XDEC1, 0XDF81, 0X1F40, 0XDD01, 0X1DC0, 0X1C80, 0XDC41, + 0X1400, 0XD4C1, 0XD581, 0X1540, 0XD701, 0X17C0, 0X1680, 0XD641, + 0XD201, 0X12C0, 0X1380, 0XD341, 0X1100, 0XD1C1, 0XD081, 0X1040, + 0XF001, 0X30C0, 0X3180, 0XF141, 0X3300, 0XF3C1, 0XF281, 0X3240, + 0X3600, 0XF6C1, 0XF781, 0X3740, 0XF501, 0X35C0, 0X3480, 0XF441, + 0X3C00, 0XFCC1, 0XFD81, 0X3D40, 0XFF01, 0X3FC0, 0X3E80, 0XFE41, + 0XFA01, 0X3AC0, 0X3B80, 0XFB41, 0X3900, 0XF9C1, 0XF881, 0X3840, + 0X2800, 0XE8C1, 0XE981, 0X2940, 0XEB01, 0X2BC0, 0X2A80, 0XEA41, + 0XEE01, 0X2EC0, 0X2F80, 0XEF41, 0X2D00, 0XEDC1, 0XEC81, 0X2C40, + 0XE401, 0X24C0, 0X2580, 0XE541, 0X2700, 0XE7C1, 0XE681, 0X2640, + 0X2200, 0XE2C1, 0XE381, 0X2340, 0XE101, 0X21C0, 0X2080, 0XE041, + 0XA001, 0X60C0, 0X6180, 0XA141, 0X6300, 0XA3C1, 0XA281, 0X6240, + 0X6600, 0XA6C1, 0XA781, 0X6740, 0XA501, 0X65C0, 0X6480, 0XA441, + 0X6C00, 0XACC1, 0XAD81, 0X6D40, 0XAF01, 0X6FC0, 0X6E80, 0XAE41, + 0XAA01, 0X6AC0, 0X6B80, 0XAB41, 0X6900, 0XA9C1, 0XA881, 0X6840, + 0X7800, 0XB8C1, 0XB981, 0X7940, 0XBB01, 0X7BC0, 0X7A80, 0XBA41, + 0XBE01, 0X7EC0, 0X7F80, 0XBF41, 0X7D00, 0XBDC1, 0XBC81, 0X7C40, + 0XB401, 0X74C0, 0X7580, 0XB541, 0X7700, 0XB7C1, 0XB681, 0X7640, + 0X7200, 0XB2C1, 0XB381, 0X7340, 0XB101, 0X71C0, 0X7080, 0XB041, + 0X5000, 0X90C1, 0X9181, 0X5140, 0X9301, 0X53C0, 0X5280, 0X9241, + 0X9601, 0X56C0, 0X5780, 0X9741, 0X5500, 0X95C1, 0X9481, 0X5440, + 0X9C01, 0X5CC0, 0X5D80, 0X9D41, 0X5F00, 0X9FC1, 0X9E81, 0X5E40, + 0X5A00, 0X9AC1, 0X9B81, 0X5B40, 0X9901, 0X59C0, 0X5880, 0X9841, + 0X8801, 0X48C0, 0X4980, 0X8941, 0X4B00, 0X8BC1, 0X8A81, 0X4A40, + 0X4E00, 0X8EC1, 0X8F81, 0X4F40, 0X8D01, 0X4DC0, 0X4C80, 0X8C41, + 0X4400, 0X84C1, 0X8581, 0X4540, 0X8701, 0X47C0, 0X4680, 0X8641, + 0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040 +}; + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Calculates the CRC16 result + * + * This function implements the CRC16 calculation + * + * \param[in] pData : the input byte array + * \param[in] length : the length of input array + * \return the CRC16 result + */ +static inline uint16_t Crc_CalcCrc16(const uint8_t *pData, uint32_t length) +{ + uint8_t tmp; + uint16_t crcWord = 0xFFFF; + + while(length--) + { + tmp = *pData++ ^ crcWord; + crcWord >>= 8; + crcWord ^= c_crcTable[tmp]; + } + return crcWord; +} + +/*! \brief Calculates the CRC8 result + * + * This function implements the CRC8 calculation + * + * \param[in] pData : the input byte array + * \param[in] length : the length of input array + * \param[in] polynomial : the polynomial used for the calculation + * \return the CRC8 result + */ +static inline uint8_t Crc_CalcCrc8(const uint8_t *pData, uint32_t length, uint8_t polynomial) +{ + uint8_t bitIndex = 0; + uint8_t byteIndex = 0; + uint8_t crc = 0xFF; + for(byteIndex = 0; byteIndex < length; ++byteIndex) + { + crc ^= pData[byteIndex]; + for(bitIndex = 0; bitIndex < 8; ++bitIndex) + { + if((crc & 0x80) != 0) + { + crc = (crc << 1) ^ polynomial; + } + else + { + crc = (crc << 1); + } + } + } + return ~crc; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _CRC_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/container/list.h b/cva_asw_m0118/SDK/lib/shared/common/container/list.h new file mode 100644 index 0000000..d240b07 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/container/list.h @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _LIST_H_ +#define _LIST_H_ + +/*! \brief Contains public interface to various functions related + * to a wrapped linked-list + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Declaration of LIST object + */ +typedef struct _ListNode_ +{ + int32_t nextIndex; /*!< next index value */ + void *pElement; /*!< the pointer to the element */ +} ListNode; + +/*! \brief Declaration of LIST object + */ +typedef struct _ListType_ +{ + ListNode *nodeArray; /*!< the pointer to the nodes, which must be an 1-D array */ + uint32_t containerSize; /*!< the size of the container */ + uint32_t length; /*!< the length of list */ + ListNode head; /*!< the head node */ +} ListType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the LIST object. + * + * This function initialize the LIST instance + * + * \param[in] obj : pointer to List instance + * \param[in] pNodes : pointer to node + * \param[in] pContainer : pointer to container + * \param[in] elemSize : element size in byte + * \param[in] containerSize : the size of the container + */ +static inline void List_Init(ListType *obj, ListNode *pNodes, void *pContainer, uint32_t elemSize, uint32_t containerSize) +{ + obj->nodeArray = pNodes; + obj->containerSize = containerSize; + uint32_t i = 0; + for(i = 0; i < obj->containerSize; ++i) + { + obj->nodeArray[i].pElement = (void *)((unsigned char *)pContainer + i * elemSize); + obj->nodeArray[i].nextIndex = -1; /* Next index is -1 representing not occupied */ + } + obj->head.nextIndex = obj->containerSize; /* next index = containerSize Mark the list */ + obj->head.pElement = NULL; + obj->length = 0; +} + +/*! \brief Get the length of the list + * + * This function get the length of the list + * + * \param[in] obj : pointer to List instance + * \return The length + */ +static inline uint32_t List_Length(const ListType *obj) +{ + return obj->length; +} + +/*! \brief Insert the element at the given index + * + * This function insert the element at the given index. + * + * \note If the given index is larger than the last element index+1, + * or the vector is full, the function will do nothing + * + * \param[in] obj : pointer to List instance + * \param[in] pElem : the pointer to the element + * \param[in] elemSize : the element size + * \param[in] index : the index to insert + * \return the result of the operation + * - true : success + * - false : fail + */ +static inline bool List_Insert(ListType *obj, const void *pElem, uint32_t elemSize, uint32_t index) +{ + /* If full, we cannot insert more elements */ + if(obj->length == obj->containerSize) + { + return false; + } + + /* If no enough elements*/ + if(index > obj->length) + { + return false; + } + + /* Find first node not occupied*/ + uint32_t actualIndex = 0; + bool actualIndexFound = false; + uint32_t i = 0; + for(i = 0; i < obj->containerSize; ++i) + { + if(obj->nodeArray[i].nextIndex == -1) + { + actualIndexFound = true; + actualIndex = i; + break; + } + } + if(actualIndexFound == false) + { + return false; /* Must found */ + } + + /* Assign the value */ + unsigned char *src = (unsigned char *)pElem; + unsigned char *dest = (unsigned char *)(obj->nodeArray[actualIndex].pElement); + uint32_t byte; + for(byte = 0; byte < elemSize; byte++) + { + *dest++ = *src++; + } + + /* Find the previous node */ + if(index == 0) + { + /* Insert at the first node */ + obj->nodeArray[actualIndex].nextIndex = obj->head.nextIndex; /* Replace the first valid data node */ + obj->head.nextIndex = actualIndex; /* Mark the new first node */ + } + else + { + uint32_t prevIndex = obj->head.nextIndex; + for(i = 0; i < index - 1; ++i) + { + prevIndex = obj->nodeArray[prevIndex].nextIndex; + } + obj->nodeArray[actualIndex].nextIndex = obj->nodeArray[prevIndex].nextIndex; + obj->nodeArray[prevIndex].nextIndex = actualIndex; + } + + /* Increase the length */ + obj->length++; + + return true; +} + +/*! \brief Get the element at the given index + * + * This function gets the element at the given index + * + * \note index must be in the range of 0-size + * + * \param[in] obj : pointer to List instance + * \param[out] pElem : pointer to the element to get + * \param[in] elemSize : size of element + * \param[in] index : index of the element to get + * \return result of the operation + * - true : success + * - false : failed + */ +static inline bool List_GetElement(const ListType *obj, void *pElem, uint32_t elemSize, uint32_t index) +{ + if(index >= obj->length) + { + return false; + } + + uint32_t i = 0; + uint32_t actualIndex = obj->head.nextIndex; + for(i = 0; i < index; ++i) + { + actualIndex = obj->nodeArray[actualIndex].nextIndex; + } + + unsigned char *dest = (unsigned char *)pElem; + unsigned char *src = (unsigned char *)(obj->nodeArray[actualIndex].pElement); + + for(i = 0; i < elemSize; i++) + { + *dest++ = *src++; + } + + return true; +} + +/*! \brief Get the element at the given index + * + * This function gets the element at the given index + * + * \note index must be in the range of 0-size-1 + * + * \param[in] obj : pointer to List instance + * \param[in] elemSize : the element size + * \param[in] index : the index to get + * \return the pointer to the element + */ +static inline const void *List_At(const ListType *obj, uint32_t elemSize, uint32_t index) +{ + if(index >= obj->length) + { + return ((void *)0); + } + + uint32_t i = 0; + uint32_t actualIndex = obj->head.nextIndex; + for(i = 0; i < index; ++i) + { + actualIndex = obj->nodeArray[actualIndex].nextIndex; + } + + return obj->nodeArray[actualIndex].pElement; +} + +/*! \brief Clear the whole vector + * + * This function clears the whole vector + * + * \param[in] obj : pointer to List instance + */ +static inline void List_Clear(ListType *obj) +{ + uint32_t i = 0; + for(i = 0; i < obj->containerSize; ++i) + { + obj->nodeArray[i].nextIndex = -1; /* Next index is -1 representing not occupied */ + } + obj->head.nextIndex = obj->containerSize; + obj->head.pElement = NULL; + obj->length = 0; +} + +/*! \brief Remove the element at the given index + * + * This function removes the element at the given index + * + * \param[in] obj : pointer to List instance + */ +static inline bool List_Remove(ListType *obj, uint32_t elemSize, uint32_t index) +{ + /* If empty, we cannot remove any elements */ + if(obj->length == 0) + { + return false; + } + + /* If no enough elements */ + if(index >= obj->length) + { + return false; + } + + /* Find the previous node */ + if(index == 0) + { + /* Remove the first node */ + uint32_t currentIndex = obj->head.nextIndex; + obj->head.nextIndex = obj->nodeArray[obj->head.nextIndex].nextIndex; + obj->nodeArray[currentIndex].nextIndex = -1; /* Mark unoccupied */ + } + else + { + uint32_t prevIndex = obj->head.nextIndex; + uint32_t i = 0; + for(i = 0; i < index - 1; ++i) + { + prevIndex = obj->nodeArray[prevIndex].nextIndex; + } + uint32_t currentIndex = obj->nodeArray[prevIndex].nextIndex; + obj->nodeArray[prevIndex].nextIndex = obj->nodeArray[currentIndex].nextIndex; + obj->nodeArray[currentIndex].nextIndex = -1; /* Mark unoccupied */ + } + + /* Decrease the length */ + obj->length--; + + return true; +} + +/*! \brief Whether the list is full + * + * This function returns whether the list is full. + * + * \param[in] obj : pointer to List instance + */ +static inline bool List_IsFull(const ListType *obj) +{ + return obj->length == obj->containerSize; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _LIST_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/container/ringbuffer.h b/cva_asw_m0118/SDK/lib/shared/common/container/ringbuffer.h new file mode 100644 index 0000000..0f6221a --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/container/ringbuffer.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _RINGBUFFER_H_ +#define _RINGBUFFER_H_ + +/*! \brief Contains public interface to various functions related + * to the ring buffer template + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief RingBuffer prototype definition + */ +typedef struct _RingBufferType_ +{ + void *pBuffer; /*!< The actual buffer holder */ + int32_t readIndex; /*!< The current index for the read */ + int32_t writeIndex; /*!< The current index for the write */ + int32_t usedNum; /*!< The number of used elements */ + int32_t totalNum; /*!< The number of total elements */ +} RingBufferType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the ringbuffer instance + * + * This function initializes a ringbuffer instance + * + * \param[in] obj : pointer to RingBuffer instance + * \param[in] pBuffer : the actual buffer holder + * \param[in] size : the size of actual buffer holder + */ +static inline void RingBuffer_Init(RingBufferType *obj, void *pBuffer, uint32_t size) +{ + obj->pBuffer = pBuffer; + obj->readIndex = 0; + obj->writeIndex = 0; + obj->usedNum = 0; + obj->totalNum = size; +} + +/*! \brief Puts an element to the ringbuffer. + * + * This function puts an element to the ringbuffer. + * + * \param[in] obj : pointer to RingBuffer instance + * \param[in] pElem : pointer to the element to push into the buffer + * \param[in] size : the size of the element in bytes + * \return the result of the put operation + * true : success + * false : failed because the buffer is full + */ +static inline bool RingBuffer_Put(RingBufferType *obj, const void *pElem, uint32_t size) +{ + uint32_t i = 0; + unsigned char *src; + unsigned char *dest; + + /* Check if the buffer is full */ + if(obj->usedNum >= obj->totalNum) + { + return false; + } + + /* Copy the element */ + src = (unsigned char *)pElem; + dest = (unsigned char *)obj->pBuffer + (obj->writeIndex * size); + for(i = 0; i < size; i++) + { + *dest++ = *src++; + } + + /* Move the index */ + obj->writeIndex++; + if(obj->writeIndex >= obj->totalNum) + { + obj->writeIndex = 0; + } + obj->usedNum++; + + return true; +} + +/*! \brief Gets an element from the ringbuffer. + * + * This function gets an element from the ringbuffer. + * + * \param[in] obj : pointer to RingBuffer instance + * \param[in] pElem : pointer to the element to get from the buffer + * \param[in] size : the size of the element in bytes + * \return the result of the put operation + * true : success + * false : failed because the buffer is empty + */ +static inline bool RingBuffer_Get(RingBufferType *obj, void *pElem, uint32_t size) +{ + uint32_t i = 0; + unsigned char *src; + unsigned char *dest; + + /* Check if the buffer is empty */ + if(obj->usedNum <= 0) + { + return false; + } + + /* Copy the element */ + dest = (unsigned char *)pElem; + src = (unsigned char *)obj->pBuffer + (obj->readIndex * size); + for(i = 0; i < size; i++) + { + *dest++ = *src++; + } + + /* Move the index */ + obj->readIndex++; + if(obj->readIndex >= obj->totalNum) + { + obj->readIndex = 0; + } + obj->usedNum--; + + return true; +} + +/*! \brief See if the ringbuffer is full. + * + * This function gets if the ringbuffer is full + * + * \param[in] obj : pointer to RingBuffer instance + * \return whether the buffer is full + * true : the buffer is full + * false : the buffer is not full + */ +static inline bool RingBuffer_IsFull(const RingBufferType *obj) +{ + return (obj->usedNum >= obj->totalNum); +} + +/*! \brief See if the ringbuffer is empty. + * + * This function gets if the ringbuffer is empty + * + * \param[in] obj : pointer to RingBuffer instance + * \return whether the buffer is empty + * true : the buffer is empty + * false : the buffer is not empty + */ +static inline bool RingBuffer_IsEmpty(const RingBufferType *obj) +{ + return (obj->usedNum <= 0); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _RINGBUFFER_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/container/table.h b/cva_asw_m0118/SDK/lib/shared/common/container/table.h new file mode 100644 index 0000000..80d3eb5 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/container/table.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _TABLE_H_ +#define _TABLE_H_ + +/*! \brief Contains public interface to various functions related + * to the table template + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Declaration of table prototype + * The container should be an array in the form of buffer[rowNum][columnNum] + */ +typedef struct _TableType_ +{ + void *pContainer; /*!< The pointer to the container, which must be a 2-D array */ + uint16_t rowNum; /*!< Total row number of the container */ + uint16_t columnNum; /*!< Total column number of the container */ +} TableType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the TABLE object. + * + * This function initializes a 2-D table instance + * + * \note The container should be the 2-D array + * + * \param[in] obj : pointer to Table instance + * \param[in] pContainer : the container (2-D array) for this table + * \param[in] rowNum : the total row count of the table + * \param[in] columnNum : the total column count of the table + */ +static inline void Table_Init(TableType *obj, void *pContainer, uint16_t rowNum, uint16_t columnNum) +{ + obj->pContainer = pContainer; + obj->rowNum = rowNum; + obj->columnNum = columnNum; +} + +/*! \brief Get a certain element determined by row and column from the table + * + * This function gets a certain element determined by row and column from the table + * + * \param[in] obj : pointer to Table instance + * \param[out] pElem : pointer to the element + * \param[in] elemSize : the size of element in byte + * \param[in] row : the row of the output element + * \param[in] column : the column of the output element + * \return the result of the get operation + * - true : succees + * - false : fail to get the element + */ +static inline bool Table_GetElement(const TableType *obj, void *pElem, uint16_t elemSize, uint16_t row, uint16_t column) +{ + if(row > obj->rowNum - 1 || column > obj->columnNum - 1) + { + return false; + } + + int i = 0; + unsigned char *src; + unsigned char *dest; + + dest = (unsigned char *)pElem; + src = (unsigned char *)(obj->pContainer) + elemSize * (row * obj->columnNum + column); + + for(i = 0; i < elemSize; i++) + { + *dest++ = *src++; + } + + return true; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _TABLE_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/container/table3d.h b/cva_asw_m0118/SDK/lib/shared/common/container/table3d.h new file mode 100644 index 0000000..94c7607 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/container/table3d.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _TABLE3D_H_ +#define _TABLE3D_H_ + +/*! \brief Contains public interface to various functions related + * to the 3-D table template + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Declaration of 3-D table prototype + * \note The container should be an array in the form of buffer[depthNum][rowNum][columnNum] + */ +typedef struct _Table3DType_ +{ + void *pContainer; /*!< The pointer to the container, which must be a 3-D array */ + uint16_t rowNum; /*!< Total row number of the container */ + uint16_t columnNum; /*!< Total column number of the container */ + uint16_t depthNum; /*!< Total depth number of the container */ +} Table3DType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the TABLE 3D object. + * + * This function initializes a 3-D table instance + * + * \note The container should be the 3-D array + * + * \param[in] obj : pointer to 3-D Table instance + * \param[in] pContainer : the container (3-D array) for this table + * \param[in] rowNum : the total row count of the table + * \param[in] columnNum : the total column count of the table + * \param[in] depthNum : the total depth count of the table + */ +static inline void Table3D_Init(Table3DType *obj, void *pContainer, uint16_t rowNum, uint16_t columnNum, uint16_t depthNum) +{ + obj->pContainer = pContainer; + obj->rowNum = rowNum; + obj->columnNum = columnNum; + obj->depthNum = depthNum; +} + +/*! \brief Get a certain element determined by row, column, depth from the table + * + * This function gets a certain element determined by row, column, depth from the table + * + * \param[in] obj : pointer to 3-D Table instance + * \param[out] pElem : pointer to the element + * \param[in] elemSize : the size of element in byte + * \param[in] row : the row of the output element + * \param[in] column : the column of the output element + * \param[in] depth : the depth of the output element + * \return the result of the get operation + * - true : succees + * - false : fail to get the element + */ +static inline bool Table3D_GetElement(const Table3DType *obj, void *pElem, uint16_t elemSize, uint16_t row, uint16_t column, uint16_t depth) +{ + if(row > obj->rowNum - 1 || column > obj->columnNum - 1 || depth > obj->depthNum - 1) + { + return false; + } + + int i = 0; + unsigned char *src; + unsigned char *dest; + + dest = (unsigned char *)pElem; + src = (unsigned char *)(obj->pContainer) + elemSize * (depth * obj->rowNum * obj->columnNum + row * obj->columnNum + column); + + for(i = 0; i < elemSize; i++) + { + *dest++ = *src++; + } + + return true; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _TABLE3D_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/container/vector.h b/cva_asw_m0118/SDK/lib/shared/common/container/vector.h new file mode 100644 index 0000000..62c04d3 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/container/vector.h @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _VECTOR_H_ +#define _VECTOR_H_ + +/*! \brief Contains public interface to various functions related + * to a wrapped fix-size array + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Declaration of Vector prototype + */ +typedef struct _VectorType_ +{ + void *pContainer; /*!< The pointer to the container, which must be an 1-D array */ + uint32_t containerSize; /*!< The size of the container */ + uint32_t length; /*!< The current occupied length */ + +} VectorType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the Vector instance. + * + * This function initializes the Vector instance + * + * \param[in] obj : pointer to Vector instance + * \param[in] pContainer : the container (1-D array) for this table + * \param[in] size : the size of the container array + */ +static inline void Vector_Init(VectorType *obj, void *pContainer, uint32_t size) +{ + obj->pContainer = pContainer; + obj->containerSize = size; + obj->length = 0; +} + +/*! \brief Gets the current length of the vector + * + * This function gets the current length of the vector + * + * \param[in] obj : pointer to Vector instance + * \return the current length of the vector + */ +static inline uint32_t Vector_Length(const VectorType *obj) +{ + return obj->length; +} + +/*! \brief Inserts an element at the given index + * + * This function inserts an element at the given index + * + * \note If the given index is larger than the last element index+1, + * or the vector is full, the function will do nothing + * + * \param[in] obj : pointer to Vector instance + * \param[in] pElem : pointer to the element + * \param[in] elemSize : the size of element in byte + * \param[in] index : index where the element is inserted + * \return the result of the insert operation + * - true : success + * - false : failed + */ +static inline bool Vector_Insert(VectorType *obj, const void *pElem, uint32_t elemSize, uint32_t index) +{ + /* If full, we cannot insert more elements */ + if(obj->length == obj->containerSize) + { + return false; + } + + /* If no enough elements */ + if(index > obj->length) + { + return false; + } + + unsigned char *src; + unsigned char *dest; + + /* Move items by one position in memory */ + if(obj->length > 0) + { + uint32_t i = 0; + for(i = obj->length; i > index; --i) + { + src = (unsigned char *)(obj->pContainer) + elemSize * (i - 1); + dest = (unsigned char *)(obj->pContainer) + elemSize * i; + uint32_t byte; + for(byte = 0; byte < elemSize; byte++) + { + *dest++ = *src++; + } + } + } + + /* Assign the value */ + src = (unsigned char *)pElem; + dest = (unsigned char *)(obj->pContainer) + elemSize * index; + uint32_t byte; + for(byte = 0; byte < elemSize; byte++) + { + *dest++ = *src++; + } + + /* Increase the length */ + obj->length++; + + return true; +} + +/*! \brief Gets the element at the given index + * + * This function gets the element at the given index + * + * \note index must be in the range of 0-size + * + * \param[in] obj : pointer to Vector instance + * \param[in] pElem : pointer to the element + * \param[in] elemSize : the size of element in byte + * \param[in] index : index of the element to get + * \return the result of the get operation + * - true : success + * - false : failed + */ +static inline bool Vector_GetElement(const VectorType *obj, void *pElem, uint32_t elemSize, uint32_t index) +{ + if(index >= obj->length) + { + return false; + } + + int i = 0; + unsigned char *src; + unsigned char *dest; + + dest = (unsigned char *)pElem; + src = (unsigned char *)(obj->pContainer) + elemSize * index; + + for(i = 0; i < elemSize; i++) + { + *dest++ = *src++; + } + + return true; +} + +/*! \brief Get the pointer to the element at the given index + * + * This function gets the pointer to the element at the given index + * + * \note index must be in the range of 0-size + * + * \param[in] obj : pointer to Vector instance + * \param[in] elemSize : the size of element in byte + * \param[in] index : index of the element to get + * \return pointer to the element + */ +static inline const void *Vector_At(const VectorType *obj, uint32_t elemSize, uint32_t index) +{ + if(index >= obj->length) + { + return ((void *)0); + } + + return (void *)((unsigned char *)(obj->pContainer) + elemSize * index); +} + +/*! \brief Clears the whole vector + * + * This function clears the whole vector + * + * \param[in] obj : pointer to Vector instance + */ +static inline void Vector_Clear(VectorType *obj) +{ + obj->length = 0; +} + +/*! \brief Remove the element at the given index + * + * This function removes the element at the at the given index + * + * \param[in] obj : pointer to Vector instance + * \param[in] elemSize : the size of element in byte + * \param[in] index : index of the element to remove + * \return the result of the remove operation + * - true : success + * - false : failed + */ +static inline bool Vector_Remove(VectorType *obj, uint32_t elemSize, uint32_t index) +{ + /* If empty, we cannot remove any elements */ + if(obj->length == 0) + { + return false; + } + + /* If no enough elements */ + if(index >= obj->length) + { + return false; + } + + unsigned char *src; + unsigned char *dest; + + /* Move items by one position in memory */ + if(obj->length - 1 > index) + { + uint32_t i = 0; + for(i = index; i < obj->length; ++i) + { + src = (unsigned char *)(obj->pContainer) + elemSize * (i + 1); + dest = (unsigned char *)(obj->pContainer) + elemSize * i; + uint32_t byte; + for(byte = 0; byte < elemSize; byte++) + { + *dest++ = *src++; + } + } + } + + /* Decrease the length */ + obj->length--; + + return true; +} + +/*! \brief Whether the vector is full + * + * This function gets whether the vector is full + * + * \param[in] obj : pointer to Vector instance + * \return whether the vector is full + * - true : full + * - false : not full + */ +static inline bool Vector_IsFull(const VectorType *obj) +{ + return obj->length == obj->containerSize; +} + +/*! \brief Whether the vector is empty + * + * This function gets whether the vector is empty + * + * \param[in] obj : pointer to Vector instance + * \return whether the vector is empty + * - true : empty + * - false : not empty + */ +static inline bool Vector_IsEmpty(const VectorType *obj) +{ + return obj->length == 0; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _VECTOR_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/curve/gradient.h b/cva_asw_m0118/SDK/lib/shared/common/curve/gradient.h new file mode 100644 index 0000000..f34ed05 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/curve/gradient.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _GRADIENT_H_ +#define _GRADIENT_H_ + +/*! \brief Contains public interface to various functions related + * to the 1st order linear curve with GRADIENT + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Declaration of Gradient Class + * + */ +typedef struct _GradientType_ +{ + _iq target; /*!< Input: target input */ + _iq upStep; /*!< Parameter: up step of ramp */ + _iq downStep; /*!< Parameter: down step of ramp */ + _iq output; /*!< Output: output value */ + +} GradientType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the Gradient instance + * + * This function initializes the Gradient instance + * + * \param[in] obj : pointer to Gradient instance + * \param[in] upStep : step when going up + * \param[in] downStep : step when going down + */ +static inline void Gradient_Init(GradientType *obj, _iq upStep, _iq downStep) +{ + obj->target = 0; + obj->output = 0; + obj->upStep = upStep; + obj->downStep = downStep; +} + +/*! \brief Calculates the output + * + * This function calculates the output + * + * \param[in] obj : pointer to Gradient instance + */ +static inline void Gradient_Calc(GradientType *obj) +{ + _iq upStep = _IQabs(obj->upStep); /* step must be a positive value */ + _iq downStep = _IQabs(obj->downStep); /* step must be a positive value */ + + if(obj->target > obj->output) + { + if((obj->target - obj->output) > upStep) + { + obj->output += upStep; + } + else + { + obj->output = obj->target; /* less than one step needed, just jump to the target */ + } + } + else if(obj->target < obj->output) + { + if((obj->output - obj->target) > downStep) + { + obj->output -= downStep; + } + else + { + obj->output = obj->target; /* less than one step needed, just jump to the target */ + } + } +} + +/*! \brief Calculate the output using the external reference + * + * This function calculates the output using the external reference, + * instead of the internal output + * + * \param[in] obj : pointer to Gradient instance + * \param[in] pOutput : pointer to external output + */ +static inline void Gradient_CalcExternal(GradientType *obj, _iq *pOutput) +{ + _iq upStep = _IQabs(obj->upStep); /* step must be a positive value */ + _iq downStep = _IQabs(obj->downStep); /* step must be a positive value */ + + if(obj->target > (*pOutput)) + { + if((obj->target - (*pOutput)) > upStep) + { + (*pOutput) += upStep; + } + else + { + (*pOutput) = obj->target; /* less than one step needed, just jump to the target */ + } + } + else if(obj->target < (*pOutput)) + { + if(((*pOutput) - obj->target) > downStep) + { + (*pOutput) -= downStep; + } + else + { + (*pOutput) = obj->target; /* less than one step needed, just jump to the target */ + } + } + + obj->output = *pOutput; /* We don't use the obj->output normally in this function, just be safe */ +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _GRADIENT_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/curve/ramp.h b/cva_asw_m0118/SDK/lib/shared/common/curve/ramp.h new file mode 100644 index 0000000..8e72933 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/curve/ramp.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _RAMP_H_ +#define _RAMP_H_ + +/*! \brief Contains public interface to various functions related + * to the ramp object + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Declaration of Ramp Class + */ +typedef struct _RampType_ +{ + _iq target; /*!< Input: target input */ + _iq step; /*!< Parameter: step of ramp */ + _iq output; /*!< Output: output value */ + +} RampType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the Ramp instance + * + * This function initializes the Ramp instance + * + * \param[in] obj : pointer to Ramp instance + * \param[in] Step : step of going up and down + */ +static inline void Ramp_Init(RampType *obj, _iq step) +{ + obj->target = 0; + obj->output = 0; + obj->step = step; +} + +/*! \brief Calculates the output + * + * This function calculates the output + * + * \param[in] obj : pointer to Ramp instance + */ +static inline void Ramp_Calc(RampType *obj) +{ + _iq step = _IQabs(obj->step); /* step must be a positive value */ + + if(_IQabs(obj->target - obj->output) > step) + { + if(obj->target > obj->output) + { + obj->output += step; + } + else + { + obj->output -= step; + } + } + else + { + /* less than one step needed, just jump to the target */ + obj->output = obj->target; + } +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _RAMP_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/filter/average.h b/cva_asw_m0118/SDK/lib/shared/common/filter/average.h new file mode 100644 index 0000000..13c7903 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/filter/average.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _AVERAGE_H_ +#define _AVERAGE_H_ + +/*! \brief Contains public interface to various functions related + * to the Averaging with sliding window (AVERAGE) filter object + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +typedef struct _AverageType_ +{ + bool isInitial; /*!< Internal variable: Flag to indicate initial state */ + _iq *pBuffer; /*!< Internal variable: The pointer to the buffer */ + uint16_t winSize; /*!< Internal variable: window length */ + uint16_t index; /*!< Internal variable: index of the value ready to pop */ + _iq sum; /*!< Internal variable: the sum of all the values in buffer */ + + _iq output; /*!< Output: The output value */ +} AverageType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the AVERAGE object + * + * This function initializes the average instance. + * + * \param[in] obj : pointer to Average instance + * \param[in] buffer : filter buffer + * \param[in] bufferSize : size of buffer + */ +static inline void Average_Init(AverageType *obj, _iq buffer[], uint16_t bufferSize) +{ + obj->pBuffer = &buffer[0]; + obj->winSize = bufferSize; + + for(obj->index = 0; obj->index < obj->winSize; obj->index++) + { + obj->pBuffer[obj->index] = 0; + } + + obj->index = 0; + obj->isInitial = true; + obj->sum = 0; + obj->output = 0; +} + +/*! \brief Push input to the filter + * + * This function pushes input to the filter. + * + * \param[in] obj : pointer to Average instance + * \param[in] input : input value to be filter + */ +static inline void Average_PushInput(AverageType *obj, _iq input) +{ + if(obj->isInitial) + { + obj->output = input; + obj->isInitial = false; + } + else + { + obj->sum = obj->sum - obj->pBuffer[obj->index] + input; + obj->pBuffer[obj->index] = input; + obj->index++; + if(obj->index > obj->winSize - 1) + { + obj->index = 0; + } + obj->output = obj->sum / obj->winSize; + } +} + +/*! \brief Get the output value + * + * This function gets the filter result. + * + * \param[in] obj : pointer to Average instance + * \return the filter result in IQ format + */ +static inline _iq Average_GetOutput(const AverageType *obj) +{ + return obj->output; +} + +/*! \brief Reset the filter + * + * This function resets the filter to the initial state. + * + * \param[in] obj : pointer to Average instance + */ +static inline void Average_Reset(AverageType *obj) +{ + for(obj->index = 0; obj->index < obj->winSize; obj->index++) + { + obj->pBuffer[obj->index] = 0; + } + + obj->index = 0; + obj->isInitial = true; + obj->output = 0; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _AVERAGE_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/filter/bp_so.h b/cva_asw_m0118/SDK/lib/shared/common/filter/bp_so.h new file mode 100644 index 0000000..1fdd670 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/filter/bp_so.h @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _BP_SO_H_ +#define _BP_SO_H_ + +/*! \brief Contains public interface to various functions related + * to the 2nd-Order band-pass (BpSo) filter object + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines the BpSo object + * + * The transfer function is as follows: + * + * 1 - Z^-2 + * H(z) = (1-b)------------------------------------- + * 1 - 2*b*cosWn*z^-1 + (2*b - 1)*z^-2 + * + * 1 + * b = --------------- + * 1+tan(deltaW/2) + * + * + * a1= -2*b*cosWn + * + * a2= 2*b - 1 + * + * a3= 1 - b + */ +typedef struct _BpSoType_ +{ + _iq coeff1; /*!< Parameter: The coefficient of Y(k-1) */ + _iq coeff2; /*!< Parameter: The coefficient of Y(k-2) */ + _iq coeff3; /*!< Parameter: The coefficient of X(k)-X(k-2) */ + bool isInitial; /*!< Internal variable: Has the filter got the first input */ + _iq prevOutput; /*!< Internal variable: The previous output cached */ + _iq prevPrevOutput; /*!< Internal variable: The previous previous output cached */ + _iq prevInput; /*!< Internal variable: The previous input cached */ + _iq prevPrevInput; /*!< Internal variable: The previous previous input cached */ + _iq output; /*!< Output: The output value */ +} BpSoType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the BpSo instance + * + * This function initializes the BpSo instance using the unit of rad/s + * + * \param[in] obj : pointer to BpSo instance + * \param[in] Wc_rps : the center frequency in rad/s + * \param[in] runFreq_kHz : the frequency pushing the data in + * \param[in] deltaW : 3-dB bandwidth in rad/s + */ +static inline void BpSo_Init(BpSoType *obj, float Wc_rps, float runFreq_kHz, float deltaW) +{ + float b = 1 / (tan((deltaW / runFreq_kHz * 0.001) * 0.5) + 1); + float a1 = -2 * b * cos(Wc_rps / runFreq_kHz * 0.001); + float a2 = 2 * b - 1; + float a3 = 1 - b; + + obj->coeff1 = _IQ(a1); + obj->coeff2 = _IQ(a2); + obj->coeff3 = _IQ(a3); + + obj->isInitial = true; + obj->output = 0; + obj->prevOutput = 0; + obj->prevPrevOutput = 0; + obj->prevInput = 0; + obj->prevPrevInput = 0; +} + +/*! \brief Initializes the BpSo instance, 2nd interface + * + * This function is an overload initialization that + * initialize the BpSo instance using the unit of Hz + * + * \param[in] obj : pointer to BpSo instance + * \param[in] fc_Hz : the center frequency in Hz + * \param[in] runFreq_kHz : the frequency pushing the data in + * \param[in] deltaF : 3 dB bandwidth in Hz + */ +static inline void BpSo_Init2(BpSoType *obj, float fc_Hz, float runFreq_kHz, float deltaF) +{ + float b = 1 / (tan((MATH_2PI * deltaF / runFreq_kHz * 0.001) * 0.5) + 1); + float a1 = -2 * b * cos(MATH_2PI * fc_Hz / runFreq_kHz * 0.001); + float a2 = 2 * b - 1; + float a3 = 1 - b; + + obj->coeff1 = _IQ(a1); + obj->coeff2 = _IQ(a2); + obj->coeff3 = _IQ(a3); + + obj->isInitial = true; + obj->output = 0; + obj->prevOutput = 0; + obj->prevPrevOutput = 0; + obj->prevInput = 0; + obj->prevPrevInput = 0; +} + +/*! \brief Push input to the filter + * + * This function is used to push data into the filter + * + * \param[in] obj : pointer to BpSo instance + * \param[in] input : the input data in IQ format + */ +static inline void BpSo_PushInput(BpSoType *obj, _iq input) +{ + if(obj->isInitial) + { + obj->output = input; + obj->prevOutput = input; + obj->prevPrevOutput = input; + obj->prevInput = input; + obj->prevPrevInput = input; + obj->isInitial = false; + } + else + { + obj->output = -_IQmpy(obj->prevOutput, obj->coeff1) - _IQmpy(obj->prevPrevOutput, obj->coeff2) + + _IQmpy(input - obj->prevPrevInput, obj->coeff3); + + obj->prevPrevInput = obj->prevInput; + obj->prevInput = input; + obj->prevPrevOutput = obj->prevOutput; + obj->prevOutput = obj->output; + } +} + +/*! \brief Gets the output value + * + * This function gets the output of the filter + * + * \param[in] obj : pointer to BpSo instance + * \return the result of the filter in IQ format + */ +static inline _iq BpSo_GetOutput(const BpSoType *obj) +{ + return obj->output; +} + +/*! \brief Resets the filter + * + * This function resets the filter to initial state + * + * \param[in] obj : pointer to BpSo instance + */ +static inline void BpSo_Reset(BpSoType *obj) +{ + obj->isInitial = true; + obj->output = 0; + obj->prevOutput = 0; + obj->prevPrevOutput = 0; + obj->prevInput = 0; + obj->prevPrevInput = 0; +} + +/*! \brief Update the parameters of the filter + * + * This function updates the parameters of the filter using the unit of rad/s + * + * \param[in] obj : pointer to BpSo instance + * \param[in] Wc_rps : the center frequency in rad/s + * \param[in] runFreq_kHz : the frequency pushing the data in + * \param[in] deltaW : 3-dB bandwidth in rad/s + */ +static inline void BpSo_UpdateParams(BpSoType *obj, float Wc_rps, float runFreq_kHz, float deltaW) +{ + float b = 1 / (tan((deltaW / runFreq_kHz * 0.001) * 0.5) + 1); + float a1 = -2 * b * cos(Wc_rps / runFreq_kHz * 0.001); + float a2 = 2 * b - 1; + float a3 = 1 - b; + + obj->coeff1 = _IQ(a1); + obj->coeff2 = _IQ(a2); + obj->coeff3 = _IQ(a3); +} + +/*! \brief Update the parameters of the filter + * + * This function updates the parameters of the filter using the unit of Hz + * + * \param[in] obj : pointer to BpSo instance + * \param[in] fc_Hz : the center frequency in Hz + * \param[in] runFreq_kHz : the frequency pushing the data in + * \param[in] deltaF : 3 dB bandwidth in Hz + */ +static inline void BpSo_UpdateParams2(BpSoType *obj, float fc_Hz, float runFreq_kHz, float deltaF) +{ + float b = 1 / (tan((MATH_2PI * deltaF / runFreq_kHz * 0.001) * 0.5) + 1); + float a1 = -2 * b * cos(MATH_2PI * fc_Hz / runFreq_kHz * 0.001); + float a2 = 2 * b - 1; + float a3 = 1 - b; + + obj->coeff1 = _IQ(a1); + obj->coeff2 = _IQ(a2); + obj->coeff3 = _IQ(a3); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _BP_SO_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/filter/bs_so.h b/cva_asw_m0118/SDK/lib/shared/common/filter/bs_so.h new file mode 100644 index 0000000..f915d73 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/filter/bs_so.h @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _BS_SO_H_ +#define _BS_SO_H_ + +/*! \brief Contains public interface to various functions related + * to the Band-stop (NOTCH) filter object + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines the BS_SO object + * \note The transfer function is as follows: + * + * 1-2*cosWn*z^-1 + z^-2 + * H(z) = b----------------------------------- + * 1 - 2*b*cosWn*z^-1 + (2*b -1)*z^-2 + * + * 1 + * b = --------------- + * 1+tan(deltaW/2) + * + * a1= -2*b*cosWn + * + * a2= 2*b - 1 + * + */ +typedef struct _BsSoType_ +{ + _iq coeff1; /*!< Parameter: The coefficient of Y(k-1) */ + _iq coeff2; /*!< Parameter: The coefficient of Y(k-2) */ + _iq coeff3; /*!< Parameter: The coefficient of X(k) */ + _iq coeff4; /*!< Parameter: The coefficient of X(k-1) */ + _iq coeff5; /*!< Parameter: The coefficient of X(k-2) */ + bool isInitial; /*!< Internal variable: Has the filter got the first input */ + _iq prevOutput; /*!< Internal variable: The previous output cached */ + _iq prevPrevOutput; /*!< Internal variable: The previous previous output cached */ + _iq prevInput; /*!< Internal variable: The previous input cached */ + _iq prevPrevInput; /*!< Internal variable: The previous previous input cached */ + _iq output; /*!< Output: The output value */ +} BsSoType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Theoretically initialize the BS_SO object with detailed parameters + * + * This function initializes the BsSo instance using the unit of rad/s + * + * \param[in] obj : pointer to BsSo instance + * \param[in] Wc_rps : the center frequency in rad/s + * \param[in] runFreq_kHz : the frequency pushing the data in + * \param[in] deltaW : 3-dB bandwidth in rad/s + */ +static inline void BsSo_Init(BsSoType *obj, float Wc_rps, float runFreq_kHz, float deltaW) +{ + float b = 1 / (tan((deltaW / runFreq_kHz * 0.001) / 2) + 1); + float a2 = 2 * b - 1; + float a1 = -2 * b * cos(Wc_rps / runFreq_kHz * 0.001); + obj->coeff1 = _IQ(a1); + obj->coeff2 = _IQ(a2); + obj->coeff3 = _IQ(b); + obj->coeff4 = obj->coeff1; + obj->coeff5 = obj->coeff3; + + obj->isInitial = true; + obj->output = 0; + obj->prevOutput = 0; + obj->prevPrevOutput = 0; + obj->prevInput = 0; + obj->prevPrevInput = 0; +} + +/*! \brief Theoretically initialize the BS_SO object with detailed parameters, 2nd interface + * + * This function is an overload initialization that + * initialize the BsSo instance using the unit of Hz + * + * \param[in] obj : pointer to BsSo instance + * \param[in] fc_Hz : the center frequency in Hz + * \param[in] runFreq_kHz : the frequency pushing the data in + * \param[in] deltaF : 3 dB bandwidth in Hz + */ +static inline void BsSo_Init2(BsSoType *obj, float fc_Hz, float runFreq_kHz, float deltaF) +{ + float b = 1 / (tan((MATH_2PI * deltaF / runFreq_kHz * 0.001) / 2) + 1); + float a2 = 2 * b - 1; + float a1 = -2 * b * cos(MATH_2PI * fc_Hz / runFreq_kHz * 0.001); + obj->coeff1 = _IQ(a1); + obj->coeff2 = _IQ(a2); + obj->coeff3 = _IQ(b); + obj->coeff4 = obj->coeff1; + obj->coeff5 = obj->coeff3; + + obj->isInitial = true; + obj->output = 0; + obj->prevOutput = 0; + obj->prevPrevOutput = 0; + obj->prevInput = 0; + obj->prevPrevInput = 0; +} + +/*! \brief Push input to the filter + * + * This function is used to push data into the filter + * + * \param[in] obj : pointer to BsSo instance + * \param[in] input : the input data in IQ format + */ +static inline void BsSo_PushInput(BsSoType *obj, _iq input) +{ + if(obj->isInitial) + { + obj->output = input; + obj->prevOutput = input; + obj->prevPrevOutput = input; + obj->prevInput = input; + obj->prevPrevInput = input; + obj->isInitial = false; + } + else + { + obj->output = -_IQmpy(obj->prevOutput, obj->coeff1) - _IQmpy(obj->prevPrevOutput, obj->coeff2) + + _IQmpy(input, obj->coeff3) + _IQmpy(obj->prevInput, obj->coeff4) + + _IQmpy(obj->prevPrevInput, obj->coeff5); + + obj->prevPrevInput = obj->prevInput; + obj->prevInput = input; + obj->prevPrevOutput = obj->prevOutput; + obj->prevOutput = obj->output; + } +} + +/*! \brief Gets the output value + * + * This function gets the output of the filter + * + * \param[in] obj : pointer to BsSo instance + * \return the result of the filter in IQ format + */ +static inline _iq BsSo_GetOutput(const BsSoType *obj) +{ + return obj->output; +} + +/*! \brief Resets the filter + * + * This function resets the filter to initial state + * + * \param[in] obj : pointer to BsSo instance + */ +static inline void BsSo_Reset(BsSoType *obj) +{ + obj->isInitial = true; + obj->output = 0; + obj->prevOutput = 0; + obj->prevPrevOutput = 0; + obj->prevInput = 0; + obj->prevPrevInput = 0; +} + +/*! \brief Update the parameters of the filter + * + * This function updates the parameters of the filter with unit rad/s + * + * \param[in] obj : pointer to BsSo instance + * \param[in] Wc_rps : the center frequency in rad/s + * \param[in] runFreq_kHz : the frequency pushing the data in + * \param[in] deltaW : 3-dB bandwidth in rad/s + */ +static inline void BsSo_UpdateParams(BsSoType *obj, float Wc_rps, float runFreq_kHz, float deltaW) +{ + float b = 1 / (tan((deltaW / runFreq_kHz * 0.001) / 2) + 1); + float a2 = 2 * b - 1; + float a1 = -2 * b * cos(Wc_rps / runFreq_kHz * 0.001); + obj->coeff1 = _IQ(a1); + obj->coeff2 = _IQ(a2); + obj->coeff3 = _IQ(b); + obj->coeff4 = obj->coeff1; + obj->coeff5 = obj->coeff3; +} + +/*! \brief Update the parameters of the filter + * + * This function update the parameters of the filter with unit Hz + * + * \param[in] obj : pointer to BsSo instance + * \param[in] fc_Hz : the center frequency in Hz + * \param[in] runFreq_kHz : the frequency pushing the data in + * \param[in] deltaF : 3 dB bandwidth in Hz + */ +static inline void BsSo_UpdateParams2(BsSoType *obj, float fc_Hz, float runFreq_kHz, float deltaF) +{ + float b = 1 / (tan((MATH_2PI * deltaF / runFreq_kHz * 0.001) / 2) + 1); + float a2 = 2 * b - 1; + float a1 = -2 * b * cos(MATH_2PI * fc_Hz / runFreq_kHz * 0.001); + obj->coeff1 = _IQ(a1); + obj->coeff2 = _IQ(a2); + obj->coeff3 = _IQ(b); + obj->coeff4 = obj->coeff1; + obj->coeff5 = obj->coeff3; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _BS_SO_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/filter/debounce.h b/cva_asw_m0118/SDK/lib/shared/common/filter/debounce.h new file mode 100644 index 0000000..dde5537 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/filter/debounce.h @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _DEBOUNCE_H_ +#define _DEBOUNCE_H_ + +/*! \brief Contains public interface to various functions related + * to the debounce (DEBOUNCE) object + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "common/iqmath/iqmath.h" +#include "common/sort/compare.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +typedef enum +{ + DEBOUNCE_TYPE_OVER, /*!< Over the threshold is active */ + DEBOUNCE_TYPE_UNDER, /*!< Under the threshold is active */ +} Debounce_ModeType; + +/*! \brief Defines all the parameters used to initialize DEBOUNCE object + */ +typedef struct _Debounce_ParamsType_ +{ + uint32_t debounceConfirmCntMax; /*!< The max value of the debounce count */ + uint32_t debounceRehabCntMax; /*!< The max value of the debounce count */ + _iq threshold; /*!< The threshold of the input compare */ + Debounce_ModeType compType; /*!< The compare type */ +} Debounce_ParamsType; + +/*! \brief Defines the DEBOUNCE object + */ +typedef struct _DebounceType_ +{ + _iq input; /*!< Input: The input value of the debounce */ + + uint32_t countConfirmMax; /*!< Parameters: The max value of the debounce count */ + uint32_t countRehabMax; /*!< Parameters: The max value of the debounce count */ + _iq threshold; /*!< Parameters: The threshold of the input compare */ + + uint32_t count; /*!< Internal variable: The count of the debouncing process */ + bool (*comp)(_iq, _iq); /*!< Internal Variable: The compare function pointer */ + + bool isActive; /*!< Output: Is active after debounce */ +} DebounceType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the DEBOUNCE object + * + * This function initialize the debounce instance. + * + * \param[in] obj : pointer to Debounce instance + * \param[in] pParams : The pointer to initial parameters + */ +static inline void Debounce_Init(DebounceType *obj, const Debounce_ParamsType *pParams) +{ + obj->countConfirmMax = pParams->debounceConfirmCntMax; + obj->countRehabMax = pParams->debounceRehabCntMax; + obj->threshold = pParams->threshold; + if(pParams->compType == DEBOUNCE_TYPE_UNDER) + { + obj->comp = Compare_SmallerThan; + } + else if(pParams->compType == DEBOUNCE_TYPE_OVER) + { + obj->comp = Compare_GreaterThan; + } + obj->count = 0; + obj->isActive = false; +} + +/*! \brief Run the DEBOUNCE process + * + * This function is the calculation of debounce process. + * + * \param[in] obj :pointer to Debounce instance + */ +static inline void Debounce_Run(DebounceType *obj) +{ + if(obj->comp(obj->input, obj->threshold)) + { + if(obj->isActive) + { + obj->count = 0; + } + else if(++obj->count >= obj->countConfirmMax) + { + obj->isActive = true; + obj->count = 0; + } + } + else + { + if(!obj->isActive) + { + obj->count = 0; + } + else if(++obj->count >= obj->countRehabMax) + { + obj->isActive = false; + obj->count = 0; + } + } +} + +/*! \brief Reset the DEBOUNCE object + * + * This function resets the debounce instance to intial state. + * + * \param[in] obj : pointer to Debounce instance + */ +static inline void Debounce_Reset(DebounceType *obj) +{ + obj->count = 0; + obj->isActive = false; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _DEBOUNCE_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/filter/iir_fo.h b/cva_asw_m0118/SDK/lib/shared/common/filter/iir_fo.h new file mode 100644 index 0000000..b1fc4c9 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/filter/iir_fo.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _IIR_FO_H_ +#define _IIR_FO_H_ + +/*! \brief Contains public interface to various functions related + * to the 1st-Order IIR (IirFo) low-pass filter object + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +typedef struct _IirFoType_ +{ + _iq output; /*!< the output value */ + bool isInitial; /*!< the flag to indicate whether the instance is initialized */ + _iq filterCoeff; /*!< 1st order IIR, y[n] = y[n-1] + coeff*(x[n]-y[n-1]) */ + +} IirFoType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the IirFo object + * + * This function initializes the 1st-order IIR filter instance + * + * \param[in] obj : pointer to IirFo instance + * \param[in] filterCoeff : the coefficient of the filter + */ +static inline void IirFo_Init(IirFoType *obj, _iq filterCoeff) +{ + obj->isInitial = true; + obj->output = 0; + if(filterCoeff > 0 && filterCoeff < _IQ(1.0)) + { + obj->filterCoeff = filterCoeff; + } + else + { + obj->filterCoeff = _IQ(1.0); /* Just for protection, normally we don't want this */ + } +} + +/*! \brief Theoretically initialize the IirFo object with detailed parameters + * + * This function initialize the IirFo object in the theoretical way using the unit rad/s + * + * \note The Wc_rps is the cutoff frequency in the unit of rad/s + * + * \param[in] obj : pointer to IirFo instance + * \param[in] Wc_rps : the cut-off frequency in rad/s + * \param[in] runFreq_kHz : the calculation frequency of the filter + */ +static inline void IirFo_InitTheo(IirFoType *obj, float Wc_rps, float runFreq_kHz) +{ + obj->isInitial = true; + obj->output = 0; + _iq filterCoeff = _IQ(Wc_rps / runFreq_kHz * 0.001); + if(filterCoeff > 0 && filterCoeff < _IQ(1.0)) + { + obj->filterCoeff = filterCoeff; + } + else + { + obj->filterCoeff = _IQ(1.0); /* Just for protection, normally we don't want this */ + } +} + +/*! \brief Theoretically initialize the IirFo object with detailed parameters, 2nd interface + * + * This function initialize the IirFo object in the theoretical way using the unit Hz + * + * \note The fc_Hz is the cutoff frequency in the unit of Hz + * + * \param[in] obj : pointer to IirFo instance + * \param[in] fc_Hz : the cut-off frequency in Hz + * \param[in] runFreq_kHz : the calculation frequency of the filter + */ +static inline void IirFo_InitTheo2(IirFoType *obj, float fc_Hz, float runFreq_kHz) +{ + obj->isInitial = true; + obj->output = 0; + _iq filterCoeff = _IQ(MATH_2PI * fc_Hz / runFreq_kHz * 0.001); + if(filterCoeff > 0 && filterCoeff < _IQ(1.0)) + { + obj->filterCoeff = filterCoeff; + } + else + { + obj->filterCoeff = _IQ(1.0); /* Just for protection, normally we don't want this */ + } +} + +/*! \brief Push input to the filter + * + * This function push data into the filter + * + * \param[in] obj : pointer to IirFo instance + * \param[in] input : the input data + */ +static inline void IirFo_PushInput(IirFoType *obj, _iq input) +{ + if(obj->isInitial) + { + obj->output = input; + obj->isInitial = false; + } + else + { + obj->output = obj->output + _IQmpy(input - obj->output, obj->filterCoeff); + } +} + +/*! \brief Get the output value + * + * This function gets the output value. + * + * \param[in] obj : pointer to IirFo instance + * \return the filter result of the filter in IQ format. + */ +static inline _iq IirFo_GetOutput(const IirFoType *obj) +{ + return obj->output; +} + +/*! \brief Reset the filter + * + * This function reset the filter to the initial state. + * + * \param[in] obj : pointer to IirFo instance + */ +static inline void IirFo_Reset(IirFoType *obj) +{ + obj->isInitial = true; + obj->output = 0; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _IIR_FO_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/filter/iir_so.h b/cva_asw_m0118/SDK/lib/shared/common/filter/iir_so.h new file mode 100644 index 0000000..4b06a4b --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/filter/iir_so.h @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _IIR_SO_H_ +#define _IIR_SO_H_ + +/*! \brief Contains public interface to various functions related + * to the 1st-Order IIR (IirSo) low-pass filter object + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines the IirSo object + * \note The transfer function is as follows: + * + * Wc^2 + * H(s) = ------------------------- + * s^2 + 2*Zeta*Wc*s + Wc^2 + * + * The discrete equation uses Tustin method, in which + * + * 2 z - 1 + * s = --- * ------- + * T z + 1 + * + * We add pre-warping to compensate the frequency, in which + * + * 2 T + * W' = --- * tan(W*---) + * T 2 + */ +typedef struct _IirSoType_ +{ + _iq coeff1; /*!< Parameter: The coefficient of Y(k-1) */ + _iq coeff2; /*!< Parameter: The coefficient of Y(k-2) */ + _iq coeff3; /*!< Parameter: The coefficient of X(k)+2*X(k-1)+X(k-2) */ + + bool isInitial; /*!< Internal variable: Has the filter got the first input */ + _iq prevOutput; /*!< Internal variable: The previous output cached */ + _iq prevPrevOutput; /*!< Internal variable: The previous previous output cached */ + _iq prevInput; /*!< Internal variable: The previous input cached */ + _iq prevPrevInput; /*!< Internal variable: The previous previous input cached */ + _iq output; +} IirSoType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the IirSo object + * + * This function initialize the IirSo instance with parameters + * + * \note The Wc_rps is the cutoff frequency in the unit of rad/s + * + * \param[in] obj : pointer to IirSo instance + * \param[in] Wc_rps : the cut-off frequency in rad/s + * \param[in] runFreq_kHz : the frequency pushing the data in + * \param[in] zeta : the zeta coefficient + */ +static inline void IirSo_Init(IirSoType *obj, float Wc_rps, float runFreq_kHz, float zeta) +{ + /* Prewarping */ + float twoph = 2000 * runFreq_kHz; + float hptwo = 0.0005 / runFreq_kHz; + Wc_rps = twoph * tan(Wc_rps * hptwo); + + _iq tmp = _IQ(Wc_rps / runFreq_kHz * 0.001); + _iq c1 = _IQmpy(tmp, tmp); + _iq c2 = _IQ(zeta * Wc_rps / runFreq_kHz * 0.001); + _iq k = _IQ(1) + c2 + _IQdiv4(c1); + + obj->coeff1 = _IQdiv(_IQ(2) - _IQdiv2(c1), k); + obj->coeff2 = _IQdiv(-_IQdiv4(c1) - _IQ(1) + c2, k); + obj->coeff3 = _IQdiv(_IQdiv4(c1), k); + + obj->isInitial = true; + obj->output = 0; + obj->prevOutput = 0; + obj->prevPrevOutput = 0; + obj->prevInput = 0; + obj->prevPrevInput = 0; +} + +/*! \brief Theoretically initialize the IirSo object with detailed parameters, 2nd interface + * + * This function theoretically initialize the IirSo object with detailed parameters + * This is an overload function. + * + * \note The fc_Hz is the cutoff frequency in the unit of Hz + * + * \param[in] obj : pointer to IirSo instance + * \param[in] fc_Hz : the cut-off frequency in Hz + * \param[in] runFreq_kHz : the frequency pushing the data in + * \param[in] zeta : the zeta coefficient + */ +static inline void IirSo_Init2(IirSoType *obj, float fc_Hz, float runFreq_kHz, float zeta) +{ + /* Prewarping */ + float twoph = 2000 * runFreq_kHz; + float hptwo = 0.0005 / runFreq_kHz; + float Wc_rps = twoph * tan(MATH_2PI * fc_Hz * hptwo); + + _iq tmp = _IQ(Wc_rps / runFreq_kHz * 0.001); + _iq c1 = _IQmpy(tmp, tmp); + _iq c2 = _IQ(zeta * Wc_rps / runFreq_kHz * 0.001); + _iq k = _IQ(1) + c2 + _IQdiv4(c1); + + obj->coeff1 = _IQdiv(_IQ(2) - _IQdiv2(c1), k); + obj->coeff2 = _IQdiv(-_IQdiv4(c1) - _IQ(1) + c2, k); + obj->coeff3 = _IQdiv(_IQdiv4(c1), k); + + obj->isInitial = true; + obj->output = 0; + obj->prevOutput = 0; + obj->prevPrevOutput = 0; + obj->prevInput = 0; + obj->prevPrevInput = 0; +} + +/*! \brief Push input to the filter + * + * This function push data into the filter + * + * \param[in] obj : pointer to IirSo instance + * \param[in] input : input data in IQ format + */ +static inline void IirSo_PushInput(IirSoType *obj, _iq input) +{ + if(obj->isInitial) + { + obj->output = input; + obj->prevOutput = input; + obj->prevPrevOutput = input; + obj->prevInput = input; + obj->prevPrevInput = input; + obj->isInitial = false; + } + else + { + obj->output = _IQmpy(obj->prevOutput, obj->coeff1) + _IQmpy(obj->prevPrevOutput, obj->coeff2) + + _IQmpy(input + _IQmpy2(obj->prevInput) + obj->prevPrevInput, obj->coeff3); + + obj->prevPrevInput = obj->prevInput; + obj->prevInput = input; + obj->prevPrevOutput = obj->prevOutput; + obj->prevOutput = obj->output; + } +} + +/*! \brief Get the output value + * + * This function gets the filter result + * + * \param[in] obj : pointer to IirSo instance + * \return the filter result + */ +static inline _iq IirSo_GetOutput(const IirSoType *obj) +{ + return obj->output; +} + +/*! \brief Reset the filter + * + * This function resets the filter to the initial state + * + * \param[in] obj : pointer to IirSo instance + */ +static inline void IirSo_Reset(IirSoType *obj) +{ + obj->isInitial = true; + obj->output = 0; + obj->prevOutput = 0; + obj->prevPrevOutput = 0; + obj->prevInput = 0; + obj->prevPrevInput = 0; +} + +/*! \brief Update the parameters of the filter + * + * This function updates the parameter of the filter in the runtime. + * + * \param[in] obj : pointer to IirSo instance + * \param[in] Wc_rps : the cut-off frequency in rad/s + * \param[in] runFreq_kHz : the frequency pushing the data in + * \param[in] zeta : the zeta coefficient + */ +static inline void IirSo_UpdateParams(IirSoType *obj, float Wc_rps, float runFreq_kHz, float zeta) +{ + /* Prewarping */ + float twoph = 2000 * runFreq_kHz; + float hptwo = 0.0005 / runFreq_kHz; + Wc_rps = twoph * tan(Wc_rps * hptwo); + + _iq tmp = _IQ(Wc_rps / runFreq_kHz * 0.001); + _iq c1 = _IQmpy(tmp, tmp); + _iq c2 = _IQ(zeta * Wc_rps / runFreq_kHz * 0.001); + _iq k = _IQ(1) + c2 + _IQdiv4(c1); + + obj->coeff1 = _IQdiv(_IQ(2) - _IQdiv2(c1), k); + obj->coeff2 = _IQdiv(-_IQdiv4(c1) - _IQ(1) + c2, k); + obj->coeff3 = _IQdiv(_IQdiv4(c1), k); +} + +/*! \brief Update the parameters of the filter + * + * This function updates the parameter of the filter in the runtime. + * This is an overload function. + * + * \param[in] obj : pointer to IirSo instance + * \param[in] fc_Hz : the cut-off frequency in Hz + * \param[in] runFreq_kHz : the frequency pushing the data in + * \param[in] zeta : the zeta coefficient + */ +static inline void IirSo_UpdateParams2(IirSoType *obj, float fc_Hz, float runFreq_kHz, float zeta) +{ + /* Prewarping */ + float twoph = 2000 * runFreq_kHz; + float hptwo = 0.0005 / runFreq_kHz; + float Wc_rps = twoph * tan(MATH_2PI * fc_Hz * hptwo); + + _iq tmp = _IQ(Wc_rps / runFreq_kHz * 0.001); + _iq c1 = _IQmpy(tmp, tmp); + _iq c2 = _IQ(zeta * Wc_rps / runFreq_kHz * 0.001); + _iq k = _IQ(1) + c2 + _IQdiv4(c1); + + obj->coeff1 = _IQdiv(_IQ(2) - _IQdiv2(c1), k); + obj->coeff2 = _IQdiv(-_IQdiv4(c1) - _IQ(1) + c2, k); + obj->coeff3 = _IQdiv(_IQdiv4(c1), k); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _IIR_SO_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/interp/interp1d.h b/cva_asw_m0118/SDK/lib/shared/common/interp/interp1d.h new file mode 100644 index 0000000..c244380 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/interp/interp1d.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _INTERP1D_H_ +#define _INTERP1D_H_ + +/*! \brief Contains public interface to various functions related + * to the 1-D Linear Interpolation + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +typedef struct _Interp1d_PointType_ +{ + _iq x; /*!< x. */ + _iq y; /*!< y. */ +} Interp1d_PointType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief This is an linear interpolate calculation function using 2 x and the scale as input + * The result x should satisfy: scale = (x-x1) / (x2-x1) + * + * \param[in] x1 : x value of point 1 + * \param[in] x2 : x value of point 2 + * \param[in] scale : the scale = (x-x1) / (x2-x1) + * \return the value x in the scale equation + */ +static inline _iq Interp1d(_iq x1, _iq x2, _iq scale) +{ + return (_IQmpy(scale, x2 - x1) + x1); +} + +/*! \brief This is an linear interpolate calculation function using 2 points as input + * Calculate y for the given x, based on two points - (x1, y1) and (x2, y2) + * + * \note If x1 is equal to x2, which is not actually allowed, it will return + * (y1+y2)/2 instead. User should prevent this situation. + * + * \param[in] x1 : x value of point 1 + * \param[in] y1 : y value of point 1 + * \param[in] x2 : x value of point 2 + * \param[in] y2 : y value of point 2 + * \param[in] x : x value of the target point + * \return the y value of the target point + */ +static inline _iq Interp1dPoints(_iq x1, _iq y1, _iq x2, _iq y2, _iq x) +{ + return (x2 != x1) ? (_IQmpy(_IQdiv(y2 - y1, x2 - x1), x - x1) + y1) : _IQdiv2(y2 + y1); +} + +/*! \brief This is an linear interpolate calculation function using the whole table as input + * + * \note The values in x[] must be from smallest to biggest + * + * \param[in] u0 : x value of the target point + * \param[in] x[] : the x value array + * \param[in] y[] : the y value array + * \param[in] maxIndex : max index of the array + * \return the y value of the target point + */ +static inline _iq Interp1dTable(_iq u0, const _iq x[], const _iq y[], uint32_t maxIndex) +{ + _iq frac; + uint32_t right; + uint32_t left; + uint32_t bpIdx; + + if(u0 <= x[0U]) + { + left = 0U; + frac = (x[1U] == x[0U]) ? _IQ(0.5) : _IQdiv(u0 - x[0U], x[1U] - x[0U]); + } + else if(u0 < x[maxIndex]) + { + /* Binary Search */ + bpIdx = maxIndex >> 1U; + left = 0U; + right = maxIndex; + while(right - left > 1U) + { + if(u0 < x[bpIdx]) + { + right = bpIdx; + } + else + { + left = bpIdx; + } + + bpIdx = (right + left) >> 1U; + } + + frac = (x[left + 1U] != x[left]) ? _IQdiv(u0 - x[left], x[left + 1U] - x[left]) : _IQ(0.5); + } + else + { + left = maxIndex - 1U; + frac = (x[maxIndex] != x[maxIndex - 1U]) ? _IQdiv(u0 - x[maxIndex - 1U], x[maxIndex] - x[maxIndex - 1U]) : _IQ(0.5); + } + + return (_IQmpy(_IQ(1.0) - frac, y[left]) + _IQmpy(y[left + 1U], frac)); +} + +/*! \brief This is an linear interpolate calculation function using the whole table as input + * + * \note The values in pPt[].x must be from smallest to biggest + * + * \param[in] u0 : x value of the target point + * \param[in] pPt : the pointer to the points array + * \param[in] maxIndex : max index of the array + * \return the y value of the target point + */ +static inline _iq Interp1dPtArray(_iq u0, const Interp1d_PointType *pPt, uint32_t maxIndex) +{ + _iq frac; + uint32_t right; + uint32_t left; + uint32_t bpIdx; + + if(u0 <= pPt[0U].x) + { + left = 0U; + frac = (pPt[1U].x == pPt[0U].x) ? _IQ(0.5) : _IQdiv(u0 - pPt[0U].x, pPt[1U].x - pPt[0U].x); + } + else if(u0 < pPt[maxIndex].x) + { + /* Binary Search */ + bpIdx = maxIndex >> 1U; + left = 0U; + right = maxIndex; + while(right - left > 1U) + { + if(u0 < pPt[bpIdx].x) + { + right = bpIdx; + } + else + { + left = bpIdx; + } + + bpIdx = (right + left) >> 1U; + } + + frac = (pPt[left + 1U].x != pPt[left].x) ? _IQdiv(u0 - pPt[left].x, pPt[left + 1U].x - pPt[left].x) : _IQ(0.5); + } + else + { + left = maxIndex - 1U; + frac = (pPt[maxIndex].x != pPt[maxIndex - 1U].x) ? _IQdiv(u0 - pPt[maxIndex - 1U].x, pPt[maxIndex].x - pPt[maxIndex - 1U].x) : _IQ(0.5); + } + + return (_IQmpy(_IQ(1.0) - frac, pPt[left].y) + _IQmpy(pPt[left + 1U].y, frac)); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _INTERP1D_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/interp/interp2d.h b/cva_asw_m0118/SDK/lib/shared/common/interp/interp2d.h new file mode 100644 index 0000000..99050c6 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/interp/interp2d.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _INTERP2D_H_ +#define _INTERP2D_H_ + +/*! \brief Contains public interface to various functions related + * to the 2-D linear interpolation + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "common/iqmath/iqmath.h" +#include "interp1d.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief This is an 2-D linear interpolate calculation function using the row and column scale as input + * + * \param[in] x00 : the x value of (0, 0) point + * \param[in] x01 : the x value of (0, 1) point + * \param[in] x10 : the x value of (1, 0) point + * \param[in] x11 : the x value of (1, 1) point + * \param[in] rowScale : the scale of row + * \param[in] columnScale : the scale of column + * \return the x value of the target point + */ +static inline _iq Interp2d(_iq x00, _iq x01, _iq x10, _iq x11, _iq rowScale, _iq columnScale) +{ + return Interp1d(Interp1d(x00, x10, rowScale), + Interp1d(x01, x11, rowScale), + columnScale); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _INTERP2D_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/iqmath/iqmath.h b/cva_asw_m0118/SDK/lib/shared/common/iqmath/iqmath.h new file mode 100644 index 0000000..d1c0f99 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/iqmath/iqmath.h @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _IQMATH_H_ +#define _IQMATH_H_ + +//! \brief This is the default floating point implementation of IQ math library. +//! Almost all the platforms can use it, but some may come across +//! the performance issue. So use it carefully unless you know what +//! you are doing. +//! + +//########################################################################### +#ifndef _USING_CUSTOM_IQMATH_ +//########################################################################### +// The default floating point IQ math +//=========================================================================== + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define MATH_PI (3.1415926535897932384626433832795f) +#define MATH_2PI (6.283185307179586476925286766559f) +#define MATH_ONE_OVER_THREE (0.3333333333f) +#define MATH_ONE_OVER_SQRT_THREE (0.5773502692f) +#define MATH_SQRT_THREE_OVER_TWO (0.8660254038f) +#define IQMATH_ONE_OVER_THREE (0.3333333333f) +#define IQMATH_ONE_OVER_SQRT_THREE (0.5773502692f) +#define IQMATH_SQRT_THREE_OVER_TWO (0.8660254038f) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +typedef float _iq; + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +#define _IQmpy2(A) ((A)*2.0f) +#define _IQmpy4(A) ((A)*4.0f) +#define _IQmpy8(A) ((A)*8.0f) +#define _IQmpy16(A) ((A)*16.0f) +#define _IQmpy32(A) ((A)*32.0f) +#define _IQmpy64(A) ((A)*64.0f) + +#define _IQdiv2(A) ((A)*0.5f) +#define _IQdiv4(A) ((A)*0.25f) +#define _IQdiv8(A) ((A)*0.125f) +#define _IQdiv16(A) ((A)*0.0625f) +#define _IQdiv32(A) ((A)*0.03125f) +#define _IQdiv64(A) ((A)*0.015625f) + +#define _IQ(A) (A) + +#define _IQtoF(A) (A) + +//! \note In case for some compiler version, __fmax and __fmin are not defined +//! Add a simple implementation here +#ifndef __fmax +#define __fmax(A, B) (A>B ? A : B) +#endif +#ifndef __fmin +#define __fmin(A, B) (A= 0.0f ? (atan2f(A,B)*(1.0f/6.283185307f)) : (1.0f + (atan2f(A,B)*(1.0f/6.283185307f)))) + +#define _IQsqrt(A) sqrtf(A) + +#define _IQisqrt(A) (1.0f/sqrtf(A)) + +#define _IQexp(A) expf(A) + +#define _IQint(A) ((long) (A)) + +#define _IQfrac(A) ((A) - (float)((long) (A))) + +#define _IQmag(A,B) sqrtf((A)*(A) + (B)*(B)) + +#define _IQabs(A) fabsf(A) + +#define _IQlog(A) logf(A) + + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +//########################################################################### +#else +//########################################################################### +// The custom IQ math +//=========================================================================== + +//! \note It's the user's duty to undefine the macros that are different with ones +//! defined above in the "iqmathcustom.h", which must be put in this folder. +//! \note When building some kind of library and we cannot access the BSW, just create +//! and fake the MCU folder. +//! +#include "iqmathcustom.h" +#endif + +#endif /* _IQMATH_H_ */ \ No newline at end of file diff --git a/cva_asw_m0118/SDK/lib/shared/common/matrix/matrix.h b/cva_asw_m0118/SDK/lib/shared/common/matrix/matrix.h new file mode 100644 index 0000000..f2b96b9 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/matrix/matrix.h @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MATRIX_H_ +#define _MATRIX_H_ + +/*! \brief Contains public interface to various functions related + * to the matrix object. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines the initial parameters for matrix object + */ +typedef struct _MatrixType_ +{ + _iq *pContainer; /*!< Pointer to the matrix table container */ + uint16_t rowNum; /*!< Total row number of the container */ + uint16_t columnNum; /*!< Total column number of the container */ +} MatrixType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the MATRIX object. + * + * This function initialize the MATRIX object. + * + * \note The container should be the 2-D array + * + * \param[in] obj : pointer to MATRIX instance + * \param[in] pContainer : pointer to the container + * \param[in] rowNum : the row number of the 2-D array + * \param[in] columnNum : the column number of the 2-D array + */ +static inline void Matrix_Init(MatrixType *obj, _iq *pContainer, uint16_t rowNum, uint16_t columnNum) +{ + obj->pContainer = pContainer; + obj->rowNum = rowNum; + obj->columnNum = columnNum; +} + +/*! \brief Set the value to the MATRIX element. + * + * This function sets the value to the specific position. + * + * \note The row and column start with 0 + * The first element is row 0 and column 0 + * + * \param[in] obj : pointer to MATRIX instance + * \param[in] value : the value to be set + * \param[in] row : the row index to set value + * \param[in] column : the column index to set value + * \return the result of the operation + * - true : success + * - false : failed + */ +static inline bool Matrix_SetValue(MatrixType *obj, _iq value, uint16_t row, uint16_t column) +{ + if(row >= obj->rowNum || column >= obj->columnNum) + { + return false; + } + + (*(obj->pContainer + column + row * obj->columnNum)) = value; + + return true; +} + +/*! \brief Set the "other" matrix to this MATRIX. + * + * This function set the whole matrix values with another matrix + * + * \param[in] obj : pointer to MATRIX instance + * \param[in] other : the pointer to the other matrix + * \return the result of the operation + * - true : success + * - false : failed + */ +static inline bool Matrix_SetMatrix(MatrixType *obj, const MatrixType *other) +{ + if(obj->rowNum != other->rowNum || obj->columnNum != other->columnNum) + { + return false; + } + + uint16_t i; + uint16_t j; + for(i = 0; i < obj->rowNum; i++) + { + for(j = 0; j < obj->columnNum; j++) + { + (*(obj->pContainer + j + i * obj->columnNum)) = (*(other->pContainer + j + i * obj->columnNum)); + } + } + + return true; +} + +/*! \brief Get the value of the MATRIX element. + * + * This function gets the value of the specific position + * + * \note The row and column start with 0 + * The first element is row 0 and column 0 + * + * \param[in] obj : pointer to MATRIX instance + * \param[out] pValue : pointer to the output value + * \param[in] row : the row index + * \param[in] column : the column index + * \return the result of the operation + * - true : success + * - false : failed + */ +static inline bool Matrix_GetValue(MatrixType *obj, _iq *pValue, uint16_t row, uint16_t column) +{ + if(row >= obj->rowNum || column >= obj->columnNum) + { + return false; + } + + *pValue = (*(obj->pContainer + column + row * obj->columnNum)); + + return true; +} + +/*! \brief multiply 2 matrix + * + * This function multiply 2 matrix + * + * \note The formula is S = LR, return false if mismatch, else return true. + * + * \param[in] pL : pointer to the left matrix + * \param[in] pR : pointer to the right matrix + * \param[out] pS : pointer to the product matrix + * \return the result of the operation + * - true : success + * - false : failed + */ +static inline bool Matrix_Multiply(const MatrixType *pL, const MatrixType *pR, MatrixType *pS) +{ + uint16_t i; + uint16_t j; + + if((pL->columnNum != pR->rowNum) || (pR->columnNum > 1)) + { + return false; + } + + for(i = 0; i < pL->rowNum; i++) + { + *(pS->pContainer + i) = 0; + for(j = 0; j < pR->rowNum; j++) + { + (*(pS->pContainer + i)) += _IQmpy((*(pL->pContainer + j + i * pR->rowNum)), (*(pR->pContainer + j))); + } + } + + return true; +} + +/*! \brief Add 2 matrix + * + * This function add 2 matrix. + * + * \note The formula is S = L+R, return false if mismatch, else return true. + * + * \param[in] pL : pointer to the left matrix + * \param[in] pR : pointer to the right matrix + * \param[out] pS : pointer to the sum matrix + * \return the result of the operation + * - true : success + * - false : failed + */ +static inline bool Matrix_Add(MatrixType *pL, MatrixType *pR, MatrixType *pS) +{ + uint16_t i; + uint16_t j; + + if((pL->columnNum != pR->columnNum) && (pL->rowNum != pR->rowNum)) + { + return false; + } + + for(i = 0; i < pL->rowNum; i++) + { + for(j = 0; j < pL->columnNum; j++) + { + (*(pS->pContainer + j + i * pL->columnNum)) + = (*(pL->pContainer + j + i * pL->columnNum)) + (*(pR->pContainer + j + i * pL->columnNum)); + } + } + + return true; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _MATRIX_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/matrix/matrix_f32.h b/cva_asw_m0118/SDK/lib/shared/common/matrix/matrix_f32.h new file mode 100644 index 0000000..f0cfcc5 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/matrix/matrix_f32.h @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MATRIX_F32_H_ +#define _MATRIX_F32_H_ + +/*! \brief Contains public interface to various functions related + * to the matrix object using float32_t. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines the initial parameters for matrix object + */ +typedef struct _MatrixF32Type_ +{ + float *pContainer; /*!< Pointer to the matrix table container */ + uint16_t rowNum; /*!< Total row number of the container */ + uint16_t columnNum; /*!< Total column number of the container */ +} MatrixF32Type; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the MATRIX_F32 object. + * + * This function initialize the MATRIX_F32 object. + * + * \note The container should be the 2-D array + * + * \param[in] obj : pointer to Matrix_f32 instance + * \param[in] pContainer : pointer to the container + * \param[in] rowNum : the row number of the 2-D array + * \param[in] columnNum : the column number of the 2-D array + */ +static inline void MatrixF32_Init(MatrixF32Type *obj, float *pContainer, uint16_t rowNum, uint16_t columnNum) +{ + obj->pContainer = pContainer; + obj->rowNum = rowNum; + obj->columnNum = columnNum; +} + +/*! \brief Set the value to the MATRIX_F32 element. + * + * This function sets the value to the specific position. + * + * \note The row and column start with 0 + * The first element is row 0 and column 0 + * + * \param[in] obj : pointer to Matrix_f32 instance + * \param[in] value : the value to be set + * \param[in] row : the row index to set value + * \param[in] column : the column index to set value + * \return the result of the operation + * - true : success + * - false : failed + */ +static inline bool MatrixF32_SetValue(MatrixF32Type *obj, float value, uint16_t row, uint16_t column) +{ + if(row >= obj->rowNum || column >= obj->columnNum) + { + return false; + } + + (*(obj->pContainer + column + row * obj->columnNum)) = value; + + return true; +} + +/*! \brief Set the "other" matrix to this MATRIX. + * + * This function set the whole matrix values with another matrix + * + * \param[in] obj : pointer to Matrix_f32 instance + * \param[in] other : the pointer to the other matrix + * \return the result of the operation + * - true : success + * - false : failed + */ +static inline bool MatrixF32_SetMatrix(MatrixF32Type *obj, const MatrixF32Type *other) +{ + if(obj->rowNum != other->rowNum || obj->columnNum != other->columnNum) + { + return false; + } + + uint16_t i; + uint16_t j; + for(i = 0; i < obj->rowNum; i++) + { + for(j = 0; j < obj->columnNum; j++) + { + (*(obj->pContainer + j + i * obj->columnNum)) = (*(other->pContainer + j + i * obj->columnNum)); + } + } + + return true; +} + +/*! \brief Get the value of the MATRIX_F32 element. + * + * This function gets the value of the specific position + * + * \note The row and column start with 0 + * The first element is row 0 and column 0 + * + * \param[in] obj : pointer to Matrix_f32 instance + * \param[out] pValue : pointer to the output value + * \param[in] row : the row index + * \param[in] column : the column index + * \return the result of the operation + * - true : success + * - false : failed + */ +static inline bool MatrixF32_GetValue(const MatrixF32Type *obj, float *pValue, uint16_t row, uint16_t column) +{ + if(row >= obj->rowNum || column >= obj->columnNum) + { + return false; + } + + *pValue = (*(obj->pContainer + column + row * obj->columnNum)); + + return true; +} + +/*! \brief multiply 2 matrix + * + * This function multiply 2 matrix + * + * \note The formula is S = LR, return false if mismatch, else return true. + * + * \param[in] pL : pointer to the left matrix + * \param[in] pR : pointer to the right matrix + * \param[out] pS : pointer to the product matrix + * \return the result of the operation + * - true : success + * - false : failed + */ +static inline bool MatrixF32_Multiply(const MatrixF32Type *pL, const MatrixF32Type *pR, MatrixF32Type *pS) +{ + uint16_t i; + uint16_t j; + + if((pL->columnNum != pR->rowNum) || (pR->columnNum > 1)) + { + return false; + } + + for(i = 0; i < pL->rowNum; i++) + { + *(pS->pContainer + i) = 0; + for(j = 0; j < pR->rowNum; j++) + { + (*(pS->pContainer + i)) += ((*(pL->pContainer + j + i * pR->rowNum)) * (*(pR->pContainer + j))); + } + } + + return true; +} + +/*! \brief Add 2 matrix + * + * This function add 2 matrix. + * + * \note The formula is S = L+R, return false if mismatch, else return true. + * + * \param[in] pL : pointer to the left matrix + * \param[in] pR : pointer to the right matrix + * \param[out] pS : pointer to the sum matrix + * \return the result of the operation + * - true : success + * - false : failed + */ +static inline bool MatrixF32_Add(const MatrixF32Type *pL, const MatrixF32Type *pR, MatrixF32Type *pS) +{ + uint16_t i; + uint16_t j; + + if((pL->columnNum != pR->columnNum) && (pL->rowNum != pR->rowNum)) + { + return false; + } + + for(i = 0; i < pL->rowNum; i++) + { + for(j = 0; j < pL->columnNum; j++) + { + (*(pS->pContainer + j + i * pL->columnNum)) + = (*(pL->pContainer + j + i * pL->columnNum)) + (*(pR->pContainer + j + i * pL->columnNum)); + } + } + + return true; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _MATRIX_F32_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/pid/ipi.h b/cva_asw_m0118/SDK/lib/shared/common/pid/ipi.h new file mode 100644 index 0000000..3a547dc --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/pid/ipi.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _IPI_H_ +#define _IPI_H_ + +/*! \brief Contains public interface to various functions related + * to the Incremental PI (IPI) object. + * \note The form of this PID is parallel. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +typedef struct _IpiType_ +{ + _iq ref; /*!< Input: Reference input */ + _iq fdb; /*!< Input: Feedback input */ + + _iq Kp; /*!< Parameter: Proportional gain */ + _iq Ki; /*!< Parameter: Integral gain */ + + _iq lastError; /*!< Internal Variable: last error */ + + _iq delta; /*!< Output: The output of increment value */ +} IpiType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the IPI object + * + * This function intialize the IPI object + * + * \param[in] obj : pointer to IPI instance + * \param[in] Kp : Kp value in IQ format + * \param[in] Ki : Ki value in IQ format + */ +static inline void Ipi_Init(IpiType *obj, _iq Kp, _iq Ki) +{ + obj->ref = 0; + obj->fdb = 0; + obj->delta = 0; + obj->Kp = Kp; + obj->Ki = Ki; + obj->lastError = 0; +} + +/*! \brief Run the IPI control + * + * This function run the IPI calculation + * + * \param[in] obj : pointer to IPI instance + */ +static inline void Ipi_Run(IpiType *obj) +{ + /* Compute the error */ + _iq error = obj->ref - obj->fdb; + /* Compute the proportional output */ + _iq Up = _IQmpy(obj->Kp, error - obj->lastError); + /* Compute the integral output */ + _iq Ui = _IQmpy(obj->Ki, error); + /* Remember error for next time */ + obj->lastError = error; + /* Assign the output */ + obj->delta = Up + Ui; +} + +/*! \brief Reset the IPI variables + * + * This function reset the IPI instance to the initial state + * + * \param[in] obj : pointer to IPI instance + */ +static inline void Ipi_Reset(IpiType *obj) +{ + obj->lastError = 0; + obj->delta = 0; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _IPI_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/pid/pid.h b/cva_asw_m0118/SDK/lib/shared/common/pid/pid.h new file mode 100644 index 0000000..a7434ef --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/pid/pid.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PID_H_ +#define _PID_H_ + +/*! \brief Contains public interface to various functions related + * to the PID object. + * \note The form of this PID is parallel. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Declaration of PID object + */ +typedef struct _PidType_ +{ + _iq ref; /*!< Input: Reference input */ + _iq fdb; /*!< Input: Feedback input */ + + _iq Kp; /*!< Parameter: Proportional gain */ + _iq Ki; /*!< Parameter: Integral gain */ + _iq Kd; /*!< Parameter: Derivative gain */ + _iq outMax; /*!< Parameter: Maximum output */ + _iq outMin; /*!< Parameter: Minimum output */ + + _iq Ui; /*!< Internal Variable: Integral output */ + _iq lastError; /*!< Internal Variable: last error */ + + _iq output; /*!< Output: PID output */ +} PidType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the PID object + * + * This function initializes the PID instance + * + * \param[in] obj : pointer to Pid instance + * \param[in] Kp : the Kp value in IQ format + * \param[in] Ki : the Ki value in IQ format + * \param[in] Kd : the Kd value in IQ format + * \param[in] min : the min value allowed in output + * \param[in] max : the max value allowed in output + */ +static inline void Pid_Init(PidType *obj, _iq Kp, _iq Ki, _iq Kd, _iq min, _iq max) +{ + obj->Kp = Kp; + obj->Ki = Ki; + obj->Kd = Kd; + obj->outMin = min; + obj->outMax = max; + + obj->ref = 0; + obj->fdb = 0; + obj->Ui = 0; + obj->lastError = 0; + obj->output = 0; +} + +/*! \brief Run the PID control + * + * This fucntion runs the PID control + * + * \note The form of this PID is parallel + * + * \param[in] obj : pointer to Pid instance + */ +static inline void Pid_Run(PidType *obj) +{ + /* Compute the error */ + _iq error = obj->ref - obj->fdb; + + /* Compute the proportional output */ + _iq Up = _IQmpy(obj->Kp, error); + + /* Compute the integral output */ + obj->Ui = obj->Ui + _IQmpy(obj->Ki, error); + /* Saturate Ui */ + if(obj->Ui > obj->outMax) + { + obj->Ui = obj->outMax; + } + if(obj->Ui < obj->outMin) + { + obj->Ui = obj->outMin; + } + + /* Compute the derivative output */ + _iq Ud = _IQmpy(obj->Kd, (error - obj->lastError)); + obj->lastError = error; + + /* Compute the pre-saturated output */ + _iq tmpOutput = Up + obj->Ui + Ud; + + /* Saturate the output */ + if(tmpOutput > obj->outMax) + { + obj->output = obj->outMax; + } + else if(tmpOutput < obj->outMin) + { + obj->output = obj->outMin; + } + else + { + obj->output = tmpOutput; + } +} + +/*! \brief Reset the PID variables + * + * This function reset the PID to initial state + * + * \note The form of this PID is parallel + * + * \param[in] obj : pointer to Pid instance + */ +static inline void Pid_Reset(PidType *obj) +{ + obj->lastError = 0; + obj->output = 0; + obj->Ui = 0; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _PID_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/smc/smc.h b/cva_asw_m0118/SDK/lib/shared/common/smc/smc.h new file mode 100644 index 0000000..8ef3a4a --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/smc/smc.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _SMC_H_ +#define _SMC_H_ + +/*! \brief Contains public interface to various functions related + * to the Sliding Mode Control (SMC) object. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines all the parameters used to initialize SMC object + * \note We use 2 coefficients to determine the current output: + * + * accumulator(k) = coeff1 * accumulator(k-1) + coeff2 * Z(k) + * + * If coeff1 + coeff2 = 1, this will act like a normal LPF + * whose gain will be 1. But sometimes we need this algorithm's + * gain NOT equal to 1. So 2 coefficients are put here for the + * user to set freely. + */ +typedef struct _Smc_ParamsType_ +{ + float Kslide; /*!< The gain of the sliding mode */ + float maxError; /*!< The max error of input */ + float coeff1; /*!< The coefficient of last output */ + float coeff2; /*!< The coefficient of bang-bang control value */ +} Smc_ParamsType; + +/*! \brief Declaration of SMC object + */ +typedef struct _SmcType_ +{ + _iq error; /*!< Input: Reference input */ + + _iq Kslide; /*!< Parameter: The gain of the sliding mode */ + _iq maxError; /*!< Parameter: The max error of input */ + _iq gain; /*!< Parameter: The max error of input */ + _iq coeff1; /*!< Parameter: The coefficient of last output */ + _iq coeff2; /*!< Parameter: The coefficient of bang-bang control value */ + + _iq accum; /*!< Internal variable: The accumulator of bang-bang control value */ + + _iq output; /*!< Output: The output of the sliding-mode control */ +} SmcType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the SMC object + * + * This function initialize the SMC instance + * + * \param[in] obj : pointer to Smc instance + * \param[in] pParams : + */ +static inline void Smc_Init(SmcType *obj, const Smc_ParamsType *pParams) +{ + /* Initialize all parameters */ + obj->Kslide = _IQ(pParams->Kslide); + obj->maxError = _IQ(pParams->maxError); + obj->gain = _IQdiv(obj->Kslide, obj->maxError); + obj->coeff1 = _IQ(pParams->coeff1); + obj->coeff2 = _IQ(pParams->coeff2); + + /* Initialize all internal variables */ + obj->accum = 0; + + /* Reset the outputs */ + obj->output = 0; +} + +/*! \brief Run the SMC control + * + * This function run the SMC algorithm. + * + * \param[in] obj : pointer to Smc instance + */ +static inline void Smc_Run(SmcType *obj) +{ + /* Bang-bang control with linear treatment around zero */ + _iq Z; + if(_IQabs(obj->error) < obj->maxError) + { + Z = _IQmpy(obj->gain, obj->error); + } + else if(obj->error > 0) + { + Z = obj->Kslide; + } + else + { + Z = -obj->Kslide; + } + + /* Filter the bang-bang control value */ + obj->accum = _IQmpy(obj->accum, obj->coeff1) + _IQmpy(Z, obj->coeff2); + + /* Put together the final output */ + obj->output = obj->accum + Z; +} + +/*! \brief Reset the SMC variables + * + * This function reset the SMC instance to the initial state. + * + * \param[in] obj : pointer to Smc instance + */ +static inline void Smc_Reset(SmcType *obj) +{ + obj->accum = 0; + obj->output = 0; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _SMC_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/sort/compare.h b/cva_asw_m0118/SDK/lib/shared/common/sort/compare.h new file mode 100644 index 0000000..f624dc5 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/sort/compare.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _COMPARE_H_ +#define _COMPARE_H_ + +/*! \brief Contains public interface to various functions related + * to the compare object + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define FLOAT_EQUAL_DEADBAND (0.0001) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief The greater than (>) comparison + * + * This function do the greater comparison between 2 IQ value + * + * \param[in] A : value A in IQ format + * \param[in] B : value B in IQ format + */ +static inline bool Compare_GreaterThan(_iq A, _iq B) +{ + return A > B; +} + +/*! \brief The smaller than (<) comparison + * + * This function do the smaller comparison between 2 IQ value + * + * \param[in] A : value A in IQ format + * \param[in] B : value B in IQ format + */ +static inline bool Compare_SmallerThan(_iq A, _iq B) +{ + return A < B; +} + +/*! \brief The greater than or equal (>=) comparison + * + * This function do the greater than or equal (>=) comparison between 2 IQ value + * + * \param[in] A : value A in IQ format + * \param[in] B : value B in IQ format + */ +static inline bool Compare_GreaterOrEqual(_iq A, _iq B) +{ + return A >= B; +} + +/*! \brief The smaller than or equal (<=) comparison + * + * This function do the smaller than or equal (<=) comparison between 2 IQ value + * + * \param[in] A : value A in IQ format + * \param[in] B : value B in IQ format + */ +static inline bool Compare_SmallerOrEqual(_iq A, _iq B) +{ + return A <= B; +} + +/*! \brief The equal (==) comparison + * + * This function do the equal (==) comparison between 2 IQ value + * + * \note If the IQ is floating value, it's not the exact equal because of the precision + * of floating value. + * + * \param[in] A : value A in IQ format + * \param[in] B : value B in IQ format + */ +static inline bool Compare_Equal(_iq A, _iq B) +{ + if((long)_IQ(0.1)) + { /* Fix-point IQ math */ + return (A == B); + } + else + { + return (_IQabs(A - B) < _IQ(FLOAT_EQUAL_DEADBAND)); + } +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _COMPARE_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/sort/sort.h b/cva_asw_m0118/SDK/lib/shared/common/sort/sort.h new file mode 100644 index 0000000..ffa8de2 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/sort/sort.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _SORT_H_ +#define _SORT_H_ + +/*! \brief Contains public interface to various functions related + * to the sort algorithms + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Return the max value in an array + * + * This function returns the max value in an array + * + * \param[in] array[] : the array to search + * \param[in] len : the length of the array + */ +static inline _iq MaxInArray(const _iq array[], uint16_t len) +{ + _iq retval = array[0]; + uint16_t i = 0; + for(i = 0; i < len; i++) + { + if(array[i] > retval) + { + retval = array[i]; + } + } + return retval; +} + +/*! \brief Return the minimum value in an array + * + * This function returns the minimun value in an array + * + * \param[in] array[] : the array to search + * \param[in] len : the length of the array + */ +static inline _iq MinInArray(const _iq array[], uint16_t len) +{ + _iq retval = array[0]; + uint16_t i = 0; + for(i = 0; i < len; i++) + { + if(array[i] < retval) + { + retval = array[i]; + } + } + return retval; +} + +/*! \brief Return the max absolute value in an array + * + * This function returns the max absolute value in an array + * + * \param[in] array[] : the array to search + * \param[in] len : the length of the array + */ +static inline _iq MaxAbsInArray(const _iq array[], uint16_t len) +{ + _iq retval = _IQabs(array[0]); + uint16_t i = 0; + for(i = 0; i < len; i++) + { + if(_IQabs(array[i]) > retval) + { + retval = _IQabs(array[i]); + } + } + return retval; +} + +/*! \brief Return the minimum absolute value in an array + * + * This function returns the minimum absolute value in an array + * + * \param[in] array[] : the array to search + * \param[in] len : the length of the array + */ +static inline _iq MinAbsInArray(const _iq array[], uint16_t len) +{ + _iq retval = _IQabs(array[0]); + uint16_t i = 0; + for(i = 0; i < len; i++) + { + if(_IQabs(array[i]) < retval) + { + retval = _IQabs(array[i]); + } + } + return retval; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _SORT_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/stimer/stimer.h b/cva_asw_m0118/SDK/lib/shared/common/stimer/stimer.h new file mode 100644 index 0000000..7542cea --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/stimer/stimer.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _STIMER_H_ +#define _STIMER_H_ + +/*! \brief Contains public interface to various functions related + * to the Software Timer (STIMER) object. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Declaration of STIMER object + */ +typedef struct _StimerType_ +{ + uint32_t counter; /*!< The counter register */ + uint32_t period; /*!< The period, time out will occur when count reach period */ + bool enable; /*!< Whether the timer is started */ + bool overflow; /*!< Whether the timer is overflow */ + +} StimerType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief The constructor of the timer object + * + * This function initialize the Stimer object + * + * \param[in] obj : pointer to Stimer instance + */ +static inline void Stimer_Init(StimerType *obj) +{ + obj->counter = 0; + obj->period = 0; + obj->enable = false; + obj->overflow = false; +} + +/*! \brief Start the timer for the period, this is one shot + * + * This function start the timer. This is one-shot. + * + * \note The real time is based on the time base running Ticker() + * \note Call this function if already started will restart the timer + * + * \param[in] obj : pointer to Stimer instance + * \param[in] period : the period value + */ +static inline void Stimer_Start(StimerType *obj, uint32_t period) +{ + obj->counter = 0; + obj->period = period; + obj->enable = true; + obj->overflow = false; +} + +/*! \brief The time base of the timer object + * + * This function provide the real time base of the stimer instance. + * + * \param[in] obj : pointer to Stimer instance + */ +static inline void Stimer_Tick(StimerType *obj) +{ + if(obj->enable && obj->overflow == false) + { + if(obj->counter < obj->period) + { + obj->counter++; + if(obj->counter == obj->period) + { + obj->overflow = true; + } + } + } +} + +/*! \brief Whether timeout + * + * This function returns whether it's timeout + * + * \param[in] obj : pointer to Stimer instance + * \return Whether it's timeout + * - true : the timer is time-out + * - false : the timer is not time-out + */ +static inline bool Stimer_Timeout(const StimerType *obj) +{ + return obj->overflow; +} + +/*! \brief Whether it's started + * + * This function returns whether the Timer instance is started + * + * \param[in] obj : pointer to Stimer instance + * \return Whether it's started + * - true : the timer is started + * - false : the timer is not started + */ +static inline bool Stimer_IsActive(StimerType *obj) +{ + return obj->enable; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _STIMER_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/common/trigger/trigger.h b/cva_asw_m0118/SDK/lib/shared/common/trigger/trigger.h new file mode 100644 index 0000000..52ddcbe --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/common/trigger/trigger.h @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _TRIGGER_H_ +#define _TRIGGER_H_ + +/*! \brief Contains public interface to various functions related + * to the Trigger object + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "common/iqmath/iqmath.h" +#include "common/sort/compare.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of Compare mode + */ +typedef enum +{ + TRIGGER_COMPTYPE_OVER, + TRIGGER_COMPTYPE_UNDER, +} Trigger_CompModeType; + +/*! \brief The definition of parameters of Trigger class + */ +typedef struct _Trigger_ParamsType_ +{ + Trigger_CompModeType compType; + _iq threshold; + _iq recoverValue; + uint16_t trigCntMax; + uint16_t recoverCntMax; + bool isRecoverable; +} Trigger_ParamsType; + +/*! \brief The definition of Trigger prototype + */ +typedef struct _TriggerType_ +{ + _iq input; /*!< Input: The input for scan */ + + _iq threshold; /*!< Parameter: The threshold for compare */ + _iq recoverValue; /*!< Parameter: The recover value that will reverse trigger */ + uint16_t trigCntMax; /*!< Parameter: The max counts for the compare */ + uint16_t recoverCntMax; /*!< Parameter: The max counts for the recover */ + bool isRecoverable; /*!< Parameter: Whether the trigger can be recovered */ + + uint16_t trigCnt; /*!< Internal Variable: The count for the compare */ + uint16_t recoverCnt; /*!< Internal Variable: The count for the recover */ + bool (*comp)(_iq, _iq); /*!< Internal Variable: The compare function pointer */ + bool (*recover)(_iq, _iq); /*!< Internal Variable: The recover function pointer */ + + bool compSatisfied; /*!< Output: Whether compare satisfied without debounce */ + bool isTriggered; /*!< Output: Whether it's triggered based on compare and debounce */ +} TriggerType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief The initialization of Trigger + * + * This function initializes the trigger instance + * + * \param[in] obj : pointer to Trigger instance + * \param[in] pParams : pointer to the parameters + */ +static inline void Trigger_Init(TriggerType *obj, const Trigger_ParamsType *pParams) +{ + obj->trigCntMax = pParams->trigCntMax; + obj->recoverCntMax = pParams->recoverCntMax; + obj->threshold = pParams->threshold; + obj->recoverValue = pParams->recoverValue; + obj->isRecoverable = pParams->isRecoverable; + if(pParams->compType == TRIGGER_COMPTYPE_OVER) + { + obj->comp = Compare_GreaterThan; + obj->recover = Compare_SmallerThan; + } + else if(pParams->compType == TRIGGER_COMPTYPE_UNDER) + { + obj->comp = Compare_SmallerThan; + obj->recover = Compare_GreaterThan; + } + + obj->trigCnt = 0; + obj->recoverCnt = 0; + obj->compSatisfied = false; + obj->isTriggered = false; +} + +/*! \brief Run the trigger algorithm + * + * This function runs the trigger algorithm + * + * \param[in] obj : pointer to Trigger instance + */ +static inline void Trigger_Run(TriggerType *obj) +{ + if(obj->comp(obj->input, obj->threshold)) + { + obj->compSatisfied = true; + obj->recoverCnt = 0; + if(obj->trigCnt < obj->trigCntMax) + { + obj->trigCnt++; + } + if(obj->trigCnt >= obj->trigCntMax) + { + obj->isTriggered = true; + } + } + else + { + obj->compSatisfied = false; + obj->trigCnt = 0; + if(obj->isRecoverable) + { + if(obj->recover(obj->input, obj->recoverValue)) + { + if(obj->recoverCnt < obj->recoverCntMax) + { + obj->recoverCnt++; + } + if(obj->recoverCnt >= obj->recoverCntMax) + { + obj->isTriggered = false; + } + } + else + { + obj->recoverCnt = 0; + } + } + } +} + +/*! \brief Reset the trigger instance + * + * This function reset the trigger to the initial state + * + * \param[in] obj : pointer to Trigger instance + */ +static inline void Trigger_Reset(TriggerType *obj) +{ + obj->trigCnt = 0; + obj->recoverCnt = 0; + obj->compSatisfied = false; + obj->isTriggered = false; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _TRIGGER_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/acim/imefe.h b/cva_asw_m0118/SDK/lib/shared/md_lib/acim/imefe.h new file mode 100644 index 0000000..fa34def --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/acim/imefe.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _IMEFE_H_ +#define _IMEFE_H_ + +/*! \brief Contains public interface to various functions related + * to the Induction Motor Enhance Flux Estimator (IMEFE) object. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "common/iqmath/iqmath.h" +#include "common/filter/iir_fo.h" +#include "common/pid/pid.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines all the parameters used to initialize IMEFE object + */ +typedef struct _Imefe_ParamsType_ +{ + float Rs_ohm; /*!< Stator resistance (ohm) */ + float Rr_ohm; /*!< Rotor resistance (ohm) */ + float Ls_H; /*!< Stator inductance (H) */ + float Lr_H; /*!< Rotor inductance (H) */ + float Lm_H; /*!< Magnetizing inductance (H) */ + float IBase_A; /*!< Base phase current (amp) */ + float VBase_V; /*!< Base phase voltage (volt) */ + float fBase_Hz; /*!< Base value of frequency used for P.U. */ + float phaseCalcFreq_kHz; /*!< Frequency to run phase calculation */ + float responseSpeed_rps; /*!< The response speed in rad/s */ + float spdCalcFreq_kHz; /*!< Frequency to run phase calculation */ + float spdFilterPole_rps; /*!< Pole value of speed filter calculation */ + float gain; /*!< Controller Gain (0.0 to 0.9999) */ + float linearError; /*!< Controller Max allowed linear error (0.0 to 0.9999) */ + +} Imefe_ParamsType; + +/*! \brief Defines the IMEFE object + */ +typedef struct _ImefeType_ +{ + _iq Ialpha; /*!< Input: The stationary d-axis stator current */ + _iq Ibeta; /*!< Input: The stationary q-axis stator current */ + _iq Valpha; /*!< Input: The stationary d-axis stator voltage */ + _iq Vbeta; /*!< Input: The stationary q-axis stator voltage */ + _iq emfAs; /*!< Internal Variable: The stationary d-axis emf */ + _iq emfBs; /*!< Internal Variable: The stationary q-axis emf */ + _iq psiAs; /*!< Internal Variable: The stationary d-axis psi */ + _iq psiBs; /*!< Internal Variable: The stationary q-axis psi */ + _iq psiAr; /*!< Internal Variable: The stationary d-axis psi */ + _iq psiBr; /*!< Internal Variable: The stationary q-axis psi */ + _iq gain1; /*!< Parameter: Motor dependent control gain */ + _iq sigma1; /*!< Parameter: Motor dependent control gain */ + _iq gain2; /*!< Parameter: Motor dependent control gain */ + _iq sigma2; /*!< Parameter: Motor dependent control gain */ + _iq Rs; /*!< Parameter: Motor dependent control gain */ + _iq model; /*!< Parameter: Motor dependent control gain */ + _iq gain3; /*!< Parameter: Motor dependent control gain */ + _iq gain4; /*!< Parameter: Motor dependent control gain */ + _iq gain5; /*!< Parameter: Motor dependent control gain */ + _iq factor; /*!< Parameter: Motor dependent control gain */ + _iq maxErr; /*!< Parameter: Motor dependent control max Error */ + IirFoType lpfFlx; /*!< Internal Variable: The filter for electric flux calculation */ + IirFoType lpfSpd; /*!< Internal Variable: The filter for electric speed calculation */ + PidType pidVAs; /*!< Internal Variable: The Stationary d-axis stator voltage PID */ + PidType pidVBs; /*!< Internal Variable: The Stationary q-axis stator voltage PID */ + PidType pidPLL; /*!< Internal Variable: The PLL PID */ + _iq rawSpeed_pu; /*!< Internal variable: The raw speed before filter in P.U. */ + _iq rawWslip_pu; /*!< Internal variable: The raw slip speed before filter in P.U. */ + _iq angle_pu; /*!< Output: The electric angle */ + _iq speed_pu; /*!< Output: The filtered electric speed updated every electric period */ + +} ImefeType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the IMEFE object + * + * This function initalizes IMEFE by setting configuration parameters + * + * \param[in] obj : pointer to IMEFE instance + * \param[in] pParams : pointer to IMEFE configuration parameters + */ +extern int32_t Imefe_Init(ImefeType *obj, const Imefe_ParamsType *pParams); + +/*! \brief Run the Angle Compensation + * + * This function runs IMEFE function, calculates Angle compensation value + * + * \param[in] obj : pointer to IMEFE instance + */ +extern int32_t Imefe_Run(ImefeType *obj); + +/*! \brief Calculate the speed + * \note Might run slower than current control frequency + * + * + * \param[in] obj : pointer to IMEFE instance + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Imefe_CalcSpeed(ImefeType *obj); + +/*! \brief Reset the IMEFE object + * + * This function resets the IMEFE relevant calculation parameters + * + * \param[in] obj : pointer to IMEFE instance + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Imefe_Reset(ImefeType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _IMEFE_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/angle_comp/angle_comp.c b/cva_asw_m0118/SDK/lib/shared/md_lib/angle_comp/angle_comp.c new file mode 100644 index 0000000..2a65c6e --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/angle_comp/angle_comp.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "angle_comp.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void AngleComp_Init(AngleCompType *obj, const AngleComp_ParamsType *pParams) +{ + obj->runFreq_kHz = pParams->runFreq_kHz; + obj->compFactor = _IQ(pParams->fBase_Hz * 0.001 / pParams->runFreq_kHz * pParams->delayCompFactor); +} diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/angle_comp/angle_comp.h b/cva_asw_m0118/SDK/lib/shared/md_lib/angle_comp/angle_comp.h new file mode 100644 index 0000000..f58f92c --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/angle_comp/angle_comp.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _ANGLE_COMP_H_ +#define _ANGLE_COMP_H_ + +/*! \brief Contains public interface to various functions related + * to the Angle Compensation (ANGLE_COMP) object. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines all the parameters used to initialize ANGLE_COMP object + */ +typedef struct _AngleComp_ParamsType_ +{ + float runFreq_kHz; /*!< the frequency of running current loop in kHz */ + float fBase_Hz; /*!< Base value of frequency used for P.U. */ + float delayCompFactor; /*!< The factor used to compensate the delay caused by PWM generation. */ +} AngleComp_ParamsType; + +/*! \brief Defines the ANGLE_COMP object + */ +typedef struct _AngleCompType_ +{ + _iq speed_pu; /*!< Input: the electrical speed in P.U. */ + _iq angleUncomp_pu; /*!< Input: the angle before compensation in P.U. */ + + _iq compFactor; /*!< Internal variable: The factor used to calculate delta angle */ + float runFreq_kHz; /*!< Internal variable: The frequency of running current loop in kHz */ + + _iq angleComp_pu; /*!< Output: the angle after compensation in P.U. */ +} AngleCompType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the ANGLE_COMP object + * + * This function initalizes ANGLE_COMP by setting configuration parameters + * + * \param[in] obj : pointer to Angle_Comp instance + * \param[in] pParams : pointer to Angle_Comp configuration parameters + */ +extern void AngleComp_Init(AngleCompType *obj, const AngleComp_ParamsType *pParams); + +/*! \brief Run the Angle Compensation + * + * This function runs Angle_Comp function, calculates Angle compensation value + * + * \param[in] obj : pointer to Angle_Comp instance + */ +static inline void AngleComp_Run(AngleCompType *obj) +{ + _iq angleTmp_pu = obj->angleUncomp_pu + _IQmpy(obj->compFactor, obj->speed_pu); + + angleTmp_pu = _IQfrac(angleTmp_pu); /* get the fraction part */ + if(angleTmp_pu < 0) + { + angleTmp_pu += _IQ(1.0); + } + + obj->angleComp_pu = angleTmp_pu; +} + +/*! \brief Update the Angle Compensation configuration parameters + * + * This function updates the Angle_Comp function configuration parameters + * + * \param[in] obj : pointer to Angle_Comp instance + * \param[in] runFreq_kHz : the frequency of running current loop + */ +static inline void AngleComp_UpdateParams(AngleCompType *obj, float runFreq_kHz) +{ + obj->compFactor = _IQmpy(obj->compFactor, _IQ(obj->runFreq_kHz / runFreq_kHz)); + obj->runFreq_kHz = runFreq_kHz; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _ANGLE_COMP_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/angle_comp/zero_offset.c b/cva_asw_m0118/SDK/lib/shared/md_lib/angle_comp/zero_offset.c new file mode 100644 index 0000000..8f03106 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/angle_comp/zero_offset.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "zero_offset.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void ZeroOffset_Init(ZeroOffsetType *obj, const ZeroOffset_ParamsType *pParams) +{ + obj->scale = _IQ(pParams->delay_us * pParams->fBase_Hz / 1000000); + obj->offset = -_IQmpy(obj->scale, _IQ(pParams->calibBaseOnSpd_Hz / pParams->fBase_Hz)); +} diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/angle_comp/zero_offset.h b/cva_asw_m0118/SDK/lib/shared/md_lib/angle_comp/zero_offset.h new file mode 100644 index 0000000..dcec645 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/angle_comp/zero_offset.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _ZERO_OFFSET_H_ +#define _ZERO_OFFSET_H_ + +/*! \brief Contains public interface to various functions related + * to the Zero angle Offset (ZERO_OFFSET) object. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines all the parameters used to initialize ZERO_OFFSET object + */ +typedef struct _ZeroOffset_ParamsType_ +{ + float calibBaseOnSpd_Hz; /*!< calibrate zero position base on speed in Hz */ + float fBase_Hz; /*!< Base value of frequency used for P.U. */ + float delay_us; /*!< The delay time for the current in */ +} ZeroOffset_ParamsType; + +/*! \brief Defines the ANGLE_COMP object + */ +typedef struct _ZeroOffsetType_ +{ + _iq speed_pu; /*!< Input: the electrical speed in P.U. */ + _iq angleUncomp_pu; /*!< Input: the angle before compensation in P.U. */ + + _iq scale; /*!< Parameter: The scale for scale*speed+offset */ + _iq offset; /*!< Parameter: The offset for scale*speed+offset */ + + _iq angleComp_pu; /*!< Output: the angle after compensation in P.U. */ +} ZeroOffsetType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the ZERO_OFFSET object + * + * This function initalizes Zero_Offset by setting configuration parameters + * + * \param[in] obj : pointer to Zero_Offset instance + * \param[in] pParams : pointer to Zero_Offset configuration parameters + */ +extern void ZeroOffset_Init(ZeroOffsetType *obj, const ZeroOffset_ParamsType *pParams); + +/*! \brief Run the ZERO_OFFSET Compensation + * + * This function runs Zero_Offset function, calculates zero offset value + * + * \param[in] obj : pointer to Zero_Offset instance + */ +static inline void ZeroOffset_Run(ZeroOffsetType *obj) +{ + _iq angleTmp_pu = obj->angleUncomp_pu + _IQmpy(obj->scale, obj->speed_pu) + obj->offset; + + angleTmp_pu = _IQfrac(angleTmp_pu); /* get the fraction part */ + if(angleTmp_pu < 0) + { + angleTmp_pu += _IQ(1.0); + } + + obj->angleComp_pu = angleTmp_pu; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _ZERO_OFFSET_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/clarke/clarke.h b/cva_asw_m0118/SDK/lib/shared/md_lib/clarke/clarke.h new file mode 100644 index 0000000..7603570 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/clarke/clarke.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CLARKE_H_ +#define _CLARKE_H_ + +/*! \brief Contains public interface to various functions related + * to the clarke modules + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Clarke prototype definition + */ +typedef struct _ClarkeType_ +{ + _iq As; /*!< phase A component */ + _iq Bs; /*!< phase B component */ + _iq Cs; /*!< phase C component */ + _iq alpha; /*!< the alpha component */ + _iq beta; /*!< the beta component */ +} ClarkeType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Runs the clarke function + * + * This function runs clarke function, calculates clarke transforms value + * + * \param[in] obj : pointer to Clarke instance + */ +static inline void Clarke_Run(ClarkeType *obj) +{ + obj->alpha = _IQmpy(_IQmpy2(obj->As) - (obj->Bs + obj->Cs), IQMATH_ONE_OVER_THREE); + obj->beta = _IQmpy((obj->Bs - obj->Cs), IQMATH_ONE_OVER_SQRT_THREE); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _CLARKE_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/clff/clff.c b/cva_asw_m0118/SDK/lib/shared/md_lib/clff/clff.c new file mode 100644 index 0000000..740d8ae --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/clff/clff.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "clff.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void Clff_Init(ClffType *obj, const Clff_ParamsType *pParams) +{ + /* Based value */ + obj->RsBase_ohm = pParams->VBase_V / pParams->IBase_A; + obj->LBase_mH = pParams->VBase_V / pParams->IBase_A / (2 * MATH_PI * pParams->fBase_Hz) * 1000.0; + obj->PsiBase_Wb = pParams->VBase_V / (2 * MATH_PI * pParams->fBase_Hz); + + /*init value */ + _iq Vdc_pu = _IQ(pParams->ratedVdc_V / pParams->VBase_V); + obj->Kd = _IQdiv(_IQ(pParams->Ld_mH / obj->LBase_mH), Vdc_pu); + obj->Kq = _IQdiv(_IQ(pParams->Lq_mH / obj->LBase_mH), Vdc_pu); + obj->Kf = _IQdiv(_IQ(pParams->flux_Wb / obj->PsiBase_Wb), Vdc_pu); + obj->Kr = _IQdiv(_IQ(pParams->Rs_Ohm / obj->RsBase_ohm), Vdc_pu); + + obj->minVdc_pu = _IQ(pParams->minVdc_V / pParams->VBase_V); + obj->maxVdc_pu = _IQ(pParams->maxVdc_V / pParams->VBase_V); + + obj->Vd = 0; + obj->Vq = 0; +} diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/clff/clff.h b/cva_asw_m0118/SDK/lib/shared/md_lib/clff/clff.h new file mode 100644 index 0000000..81dff22 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/clff/clff.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CLFF_H_ +#define _CLFF_H_ + +/*! \brief Contains public interface to various functions related + * to the Current Loop Feed-Forward (CLFF) object + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines the initial parameters for CLFF object + */ +typedef struct _Clff_ParamsType_ +{ + float Rs_Ohm; /*!< Stationary resistance in Ohm */ + float Ld_mH; /*!< Normal D-axis inductance in mH */ + float Lq_mH; /*!< Normal Q-axis inductance in mH */ + float flux_Wb; /*!< The flux of rotor */ + float ratedVdc_V; /*!< Rated dc bus voltage */ + float IBase_A; /*!< Base value of current used for P.U. */ + float VBase_V; /*!< Base value of voltage used for P.U. */ + float fBase_Hz; /*!< Base value of frequency used for P.U. */ + float minVdc_V; /*!< Minimum DC voltage allowed */ + float maxVdc_V; /*!< Maximum DC voltage allowed */ +} Clff_ParamsType; + +/*! \brief Defines the dynamic parameters used to update CLFF object + */ +typedef struct _Clff_DynamicParamsType_ +{ + float Rs_Ohm; /*!< Stationary resistance in Ohm */ + float Ld_mH; /*!< Normal D-axis inductance in mH */ + float Lq_mH; /*!< Normal Q-axis inductance in mH */ + float flux_Wb; /*!< The flux of rotor */ + _iq Vdc_pu; /*!< bus voltage in P.U. */ +} Clff_DynamicParamsType; + +/*! \brief Defines the CLFF object + */ +typedef struct _ClffType_ +{ + _iq Id_pu; /*!< Input: Id current in P.U. */ + _iq Iq_pu; /*!< Input: Iq current in P.U. */ + _iq eleFreq_pu; /*!< Input: electrical frequency in P.U. */ + + _iq Kf; /*!< Parameter: coefficient determined by Back EMF */ + _iq Kd; /*!< Parameter: coefficient determined by Ld */ + _iq Kq; /*!< Parameter: coefficient determined by Lq */ + _iq Kr; /*!< Parameter: coefficient determined by Rs */ + float RsBase_ohm; /*!< Parameter: Base value of resistance used for P.U. */ + float LBase_mH; /*!< Parameter: Base value of Ls used for P.U. */ + float PsiBase_Wb; /*!< Parameter: Base value of flux used for P.U. */ + _iq minVdc_pu; /*!< Parameter: Minimum DC voltage allowed in P.U. */ + _iq maxVdc_pu; /*!< Parameter: Maximum DC voltage allowed in P.U. */ + + _iq Vd; /*!< Output: theoretical Vd */ + _iq Vq; /*!< Output: theoretical Vq */ +} ClffType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the CLFF object + * + * This function initalizes CLFF by setting configuration parameters + * + * \param[in] obj : pointer to Clff instance + * \param[in] pParams : pointer to CLFF configuration parameters + */ +extern void Clff_Init(ClffType *obj, const Clff_ParamsType *pParams); + +/*! \brief Calculate the theoretical Vd, Vq + * + * This function runs Clff function, calculates the theoretical Vd, Vq value + * + * \param[in] obj : pointer to Clff instance + */ +static inline void Clff_Calc(ClffType *obj) +{ + obj->Vd = _IQmpy(obj->Kr, obj->Id_pu) + - _IQmpy(_IQmpy(obj->Kq, obj->Iq_pu), obj->eleFreq_pu); + + obj->Vq = _IQmpy(obj->Kr, obj->Iq_pu) + + _IQmpy(_IQmpy(obj->Kd, obj->Id_pu) + obj->Kf, obj->eleFreq_pu); +} + +/*! \brief Update the parameters + * + * This function updates the Clff function configuration parameters dynamically + * + * \param[in] obj : pointer to Clff instance + * \param[in] pParams : pointer to Clff dynamic configuration parameters instance + */ +static inline void Clff_UpdateParams(ClffType *obj, const Clff_DynamicParamsType *pParams) +{ + if(pParams->Vdc_pu >= obj->minVdc_pu && pParams->Vdc_pu <= obj->maxVdc_pu) + { + obj->Kd = _IQdiv(_IQ(pParams->Ld_mH / obj->LBase_mH), pParams->Vdc_pu); + obj->Kq = _IQdiv(_IQ(pParams->Lq_mH / obj->LBase_mH), pParams->Vdc_pu); + obj->Kf = _IQdiv(_IQ(pParams->flux_Wb / obj->PsiBase_Wb), pParams->Vdc_pu); + obj->Kr = _IQdiv(_IQ(pParams->Rs_Ohm / obj->RsBase_ohm), pParams->Vdc_pu); + } + else + { + obj->Kd = 0; + obj->Kq = 0; + obj->Kf = 0; + obj->Kr = 0; + } +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _CLFF_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/estidc/estidc.h b/cva_asw_m0118/SDK/lib/shared/md_lib/estidc/estidc.h new file mode 100644 index 0000000..788d113 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/estidc/estidc.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _ESTIDC_H_ +#define _ESTIDC_H_ + +/*! \brief Contains public interface to various functions related + * to the DC current Estimation (ESTIDC) object. + * + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines the phase enumeration + */ +typedef enum +{ + ESTIDC_PHASE_A = 0, + ESTIDC_PHASE_B, + ESTIDC_PHASE_C, + ESTIDC_PHASE_U, + ESTIDC_PHASE_V, + ESTIDC_PHASE_W, + + ESTIDC_PHASE_Num +} Estidc_PhaseType; + +/*! \brief Defines all the parameters used to initialize ESTIDC object + */ +typedef struct _Estidc_ParamsType_ +{ + _iq Tdb; /*!< Percentage of dead-band */ + uint8_t phaseNumber; /*!< Number of phase */ +} Estidc_ParamsType; + +/*! \brief data of each phase + */ +typedef struct _Estidc_PhaseDataType +{ + _iq I; /*!< Current of ever phase */ + _iq T; /*!< 100%-(duty of ever phase ) */ + _iq prevI; /*!< The last Current of ever phase */ + _iq prevT; /*!< The last 100%-(duty of ever phase) */ + _iq prevPrevT; /*!< The previous last 100%-(duty of ever phase) */ +} Estidc_PhaseDataType; + +/*! \brief Defines the ESTIDC object + */ +typedef struct _EstidcType_ +{ + _iq Ia; /*!< Input: current of phase A */ + _iq Ib; /*!< Input: current of phase B */ + _iq Ic; /*!< Input: current of phase C */ + _iq Iu; /*!< Input: current of phase U */ + _iq Iv; /*!< Input: current of phase V */ + _iq Iw; /*!< Input: current of phase W */ + _iq Ta; /*!< Input: 100%-(duty) of phase A */ + _iq Tb; /*!< Input: 100%-(duty) of phase B */ + _iq Tc; /*!< Input: 100%-(duty) of phase C */ + _iq Tu; /*!< Input: 100%-(duty) of phase U */ + _iq Tv; /*!< Input: 100%-(duty) of phase V */ + _iq Tw; /*!< Input: 100%-(duty) of phase W */ + + _iq Tdb; /*!< Parameter: Percentage of dead-band */ + uint16_t phaseNumber; /*!< Parameter: Number of phase */ + + Estidc_PhaseDataType data[ESTIDC_PHASE_Num]; /*!< Internal Variable: data of each phase */ + + _iq estIdc; /*!< Output: The estimated DC current */ +} EstidcType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the ESTIDC object + * + * This function initalizes Estidc by setting configuration parameters + * + * \param[in] obj : pointer to Estidc instance + * \param[in] pParams : pointer to Estidc configuration parameters + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Estidc_Init(EstidcType *obj, const Estidc_ParamsType *pParams); + +/*! \brief Run the estimation + * + * This function runs Estidc function, calculates idc estimation value + * + * \param[in] obj : pointer to Estidc instance + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Estidc_Run(EstidcType *obj); + +/*! \brief Update the parameters of ESTIDC object + * + * This function updates the Estidc function configuration parameters + * + * \param[in] obj : pointer to Estidc instance + * \param[in] Tdb : the percentage of dead-band + */ +extern void Estidc_UpdateParams(EstidcType *obj, _iq Tdb); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _ESTIDC_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/esttrq/esttrq_tf.c b/cva_asw_m0118/SDK/lib/shared/md_lib/esttrq/esttrq_tf.c new file mode 100644 index 0000000..b71bef4 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/esttrq/esttrq_tf.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "esttrq_tf.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void EstTrqTf_Init(EstTrqTfType *obj, const EstTrqTf_ParamsType *pParams) +{ + obj->torqueFactor_I = _IQ(1.5 * pParams->polePairs * pParams->IBase_A / pParams->torqueBase_Nm); + obj->torqueFactor_F = _IQ((pParams->Ld_mH - pParams->Lq_mH) * 0.001 * pParams->IBase_A); + obj->flux_Wb = pParams->flux_Wb; + obj->IBaseFactor = 0.001 * pParams->IBase_A; +} + +void EstTrqTf_Calc(EstTrqTfType *obj) +{ + obj->torque_pu = _IQmpy(_IQmpy(obj->filteredIqFdb_pu, + _IQmpy(obj->filteredIdFdb_pu, obj->torqueFactor_F) + obj->flux_Wb), + obj->torqueFactor_I); +} + +void EstTrqTf_UpdateParams(EstTrqTfType *obj, float Ld_mH, float Lq_mH, float flux_Wb) +{ + obj->torqueFactor_F = _IQ((Ld_mH - Lq_mH) * obj->IBaseFactor); + obj->flux_Wb = flux_Wb; +} diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/esttrq/esttrq_tf.h b/cva_asw_m0118/SDK/lib/shared/md_lib/esttrq/esttrq_tf.h new file mode 100644 index 0000000..c662110 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/esttrq/esttrq_tf.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _ESTTRQ_TF_H_ +#define _ESTTRQ_TF_H_ + +/*! \brief Contains public interface to various functions related + * to the Torque Estimation using Torque Formula method. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines all the parameters used to initialize ESTTRQ_TF object + */ +typedef struct _EstTrqTf_ParamsType_ +{ + float IBase_A; /*!< Base value of current used for P.U. */ + float fBase_Hz; /*!< Base value of frequency used for P.U. */ + float torqueBase_Nm; /*!< Base value of torque used for P.U. */ + uint32_t polePairs; /*!< Pole pairs of the motor */ + float Ld_mH; /*!< d-axis inductance in mH */ + float Lq_mH; /*!< q-axis inductance in mH */ + float flux_Wb; /*!< The flux of PM in Webers */ +} EstTrqTf_ParamsType; + +/*! \brief Defines the ESTTRQ_TF object + */ +typedef struct _EstTrqTfType_ +{ + _iq filteredIdFdb_pu; /*!< Input: The Id feedback in P.U. */ + _iq filteredIqFdb_pu; /*!< Input: The Iq feedback in P.U. */ + + _iq flux_Wb; /*!< Parameter: The flux of PM in Webers */ + _iq torqueFactor_I; /*!< Parameter: Current factor to calculate torque */ + _iq torqueFactor_F; /*!< Parameter: Flux factor to calculate torque */ + float IBaseFactor; /*!< Parameter: Base current factor to calculate torque */ + + _iq torque_pu; /*!< Output: The estimated torque */ +} EstTrqTfType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the ESTTRQ_TF object + * + * This function initalizes Esttrq_Tf by setting configuration parameters + * + * \param[in] obj : pointer to Esttrq_Tf instance + * \param[in] pParams : pointer to parameters + */ +extern void EstTrqTf_Init(EstTrqTfType *obj, const EstTrqTf_ParamsType *pParams); + +/*! \brief Run the Torque estimation + * + * This function runs Esttrq_Tf function, calculates torque estimation value + * + * \param[in] obj : pointer to Esttrq_Tf instance + */ +extern void EstTrqTf_Calc(EstTrqTfType *obj); + +/*! \brief Update the parameters of ESTTRQ_TF object + * + * This function updates the Esttrq_Tf function configuration parameters + * + * \param[in] obj : pointer to Esttrq_Tf instance + * \param[in] Ld_mH : d-axis inductance in mH + * \param[in] Lq_mH : q-axis inductance in mH + * \param[in] flux_Wb : the flux of PM in Webers + */ +extern void EstTrqTf_UpdateParams(EstTrqTfType *obj, float Ld_mH, float Lq_mH, float flux_Wb); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _ESTTRQ_TF_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/fag/fag.c b/cva_asw_m0118/SDK/lib/shared/md_lib/fag/fag.c new file mode 100644 index 0000000..d43ad00 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/fag/fag.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "fag.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void Fag_Init(FagType *obj, float fBase_Hz, float runFreq_kHz) +{ + obj->factor = _IQ(fBase_Hz / (runFreq_kHz * 1000.0)); + obj->angle_pu = 0; + obj->frequency_pu = 0; +} diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/fag/fag.h b/cva_asw_m0118/SDK/lib/shared/md_lib/fag/fag.h new file mode 100644 index 0000000..c6ed019 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/fag/fag.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FAG_H_ +#define _FAG_H_ + +/*! \brief Contains public interface to various functions related + * to the fag modules + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Fag prototype definition + */ +typedef struct _FagType_ +{ + _iq frequency_pu; /*!< Input: The electric frequency */ + + _iq factor; /*!< Internal Variable: The factor used to calculate the angle */ + + _iq angle_pu; /*!< Output: The angle generated */ +} FagType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the FAG object + * + * This function initalizes Fag by setting configuration parameters + * + * \param[in] obj : pointer to Fag instance + * \param[in] fBase_Hz : the default maximum current base frequency + * \param[in] runFreq_kHz : the frequency of running current loop + */ +extern void Fag_Init(FagType *obj, float fBase_Hz, float runFreq_kHz); + +/*! \brief Gets FAG calculation value + * + * This function gets Fag function calculation value + * + * \param[in] obj : pointer to Fag instance + */ +static inline _iq Fag_GetAngle(FagType *obj) +{ + return (obj->angle_pu); +} + +/*! \brief Sets the frequency of false angle + * + * This function Sets the frequency of false angle + * + * \param[in] obj : pointer to Fag instance + * \param[in] frequency : the desired frequency of false angle + */ +static inline void Fag_SetFrequency(FagType *obj, _iq frequency) +{ + obj->frequency_pu = frequency; +} + +/*! \brief Runs the FAG + * + * This function runs Fag function, calculates dynamic changing false angle value + * + * \param[in] obj : pointer to Fag instance + */ +static inline void Fag_Run(FagType *obj) +{ + obj->angle_pu += _IQmpy(obj->frequency_pu, obj->factor); + + obj->angle_pu = _IQfrac(obj->angle_pu); /* Get the fraction part */ + if(obj->angle_pu < 0) + { + obj->angle_pu += _IQ(1.0); + } +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _FAG_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/fast/fast.h b/cva_asw_m0118/SDK/lib/shared/md_lib/fast/fast.h new file mode 100644 index 0000000..dde87db --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/fast/fast.h @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FAST_H_ +#define _FAST_H_ + +/*! \brief Contains public interface to various functions related + * to the Flux, Angle, Speed, Torque estimation (FAST) modules + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "common/iqmath/iqmath.h" +#include "common/pid/pid.h" +#include "common/filter/iir_fo.h" +#include "md_lib/clarke/clarke.h" +#include "md_lib/park/park.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Fast prototype definition + */ +typedef struct _Fast_ParamsType_ +{ + uint32_t polePairs; /*!< Pole pairs of the motor */ + float runFreq_kHz; /*!< Frequency to run the process */ + float Rs_Ohm; /*!< Stationary resistance in Ohm */ + float Ld_mH; /*!< d-axis inductance in mH */ + float Lq_mH; /*!< q-axis inductance in mH */ + float fBase_Hz; /*!< Base value of frequency used for P.U. */ + float VBase_V; /*!< Base value of voltage used for P.U. */ + float IBase_A; /*!< Base value of current used for P.U. */ + float torqueBase_Nm; /*!< Base value of torque used for P.U. */ + float spdFilterPole_rps; /*!< Pole value of speed filter calculation */ + float dirFilterPole_rps; /*!< Pole value of speed direction filter calculation */ + float fluxFilterPole_rps; /*!< Pole value of flux filter calculation */ + float ratedVdc_V; /*!< The rated phase-to-ground voltage */ + float fstCalcFreq_kHz; /*!< The calculation frequency of flux, speed and torque */ + float minElecFreq_Hz; /*!< The min speed supported in Hz */ + float fluxBase_Wb; /*!< Base value of current used for P.U. */ + float defaultFlux_Wb; /*!< The default value of flux in Wb */ + float gain; /*!< Controller Gain (0.0 to 0.9999) */ + float linearError; /*!< Controller Max allowed linear error (0.0 to 0.9999) */ + float dampingFactor; /*!< Damping factor of controller */ +} Fast_ParamsType; + +/*! \brief Defines the dynamic parameters used to update Fast object + */ +typedef struct _Fast_DynamicParamsType_ +{ + float runFreq_kHz; /*!< Frequency to run the process */ + float Rs_Ohm; /*!< Stationary resistance in Ohm */ + float Ld_mH; /*!< d-axis inductance in mH */ + float Lq_mH; /*!< q-axis inductance in mH */ + float fBase_Hz; /*!< Base value of frequency used for P.U. */ + float VBase_V; /*!< Base value of voltage used for P.U. */ + float IBase_A; /*!< Base value of current used for P.U. */ +} Fast_DynamicParamsType; + +/*! \brief Defines the Fast type + */ +typedef struct _FastType_ +{ + _iq Ia_pu; /*!< Input: The Stationary current of phase A */ + _iq Ib_pu; /*!< Input: The Stationary current of phase B */ + _iq Ic_pu; /*!< Input: The Stationary current of phase C */ + _iq Va_pu; /*!< Input: The Stationary voltage of phase A */ + _iq Vb_pu; /*!< Input: The Stationary voltage of phase B */ + _iq Vc_pu; /*!< Input: The Stationary voltage of phase C */ + + _iq Fdsmo; /*!< Parameter: Motor dependent control gain */ + _iq Fqsmo; /*!< Parameter: Motor dependent control gain */ + _iq Gdsmo; /*!< Parameter: Motor dependent control gain */ + _iq Gqsmo; /*!< Parameter: Motor dependent control gain */ + _iq Kdsmo; /*!< Parameter: Motor dependent control gain */ + _iq Kqsmo; /*!< Parameter: Motor dependent control gain */ + _iq Kslide; /*!< Parameter: Sliding control gain */ + _iq maxError; /*!< Parameter: Maximum current error for linear SMC */ + _iq angleFactor; /*!< Parameter: Factor to calculate angle from speed */ + _iq fluxFactor; /*!< Parameter: Factor to calculate flux */ + _iq torqueFactor_I; /*!< Parameter: Current factor to calculate torque */ + _iq torqueFactor_F; /*!< Parameter: Flux factor to calculate torque */ + _iq minSpd_pu; /*!< Parameter: Min electric speed in P.U. */ + _iq defaultFlux_pu; /*!< Parameter: The default value of flux in P.U. */ + + _iq Vd; /*!< Internal Variable: The d-axis voltage */ + _iq Vq; /*!< Internal Variable: The q-axis voltage */ + _iq Zd; /*!< Internal Variable: Stationary d-axis sliding control */ + _iq Zq; /*!< Internal Variable: Stationary q-axis sliding control */ + _iq Eq; /*!< Internal Variable: Stationary q-axis back EMF */ + ClarkeType clarkeI; /*!< Internal Variable: The clarke transform for current */ + ClarkeType clarkeV; /*!< Internal Variable: The clarke transform for current */ + ParkType parkI; /*!< Internal Variable: The park transform for current */ + ParkType parkV; /*!< Internal Variable: The park transform for current */ + PidType pidPLL; /*!< Internal Variable: The PLL PID */ + _iq Id; /*!< Internal Variable: The d-axis current */ + _iq Iq; /*!< Internal Variable: The q-axis current */ + _iq IdEst; /*!< Internal Variable: Estimated d-axis current */ + _iq IqEst; /*!< Internal Variable: Estimated q-axis current */ + _iq IdError; /*!< Internal Variable: The d-axis current error */ + _iq IqError; /*!< Internal Variable: The q-axis current error */ + IirFoType filterSpd; /*!< Internal Variable: The filter for electric speed calculation */ + IirFoType filterDir; /*!< Internal Variable: The filter for speed direction detection */ + IirFoType filterFlux; /*!< Internal Variable: The filter for flux calculation */ + int16_t spdDir; /*!< Internal Variable: The actual speed direction; 1:forward, -1:backward */ + _iq rawSpeed_pu; /*!< Internal variable: The raw speed before filter in P.U. */ + _iq currentAngle_pu; /*!< Internal variable: The angle for this control loop */ + _iq nextAngle_pu; /*!< Internal variable: The angle for next control loop */ + + _iq angle_pu; /*!< Output: The electric angle */ + _iq speed_pu; /*!< Output: The filtered electric speed updated every electric period */ + _iq flux_pu; /*!< Output: The flux of PM in P.U. */ + _iq torque_pu; /*!< Output: The electrical torque in P.U. */ +} FastType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the FAST object + * + * This function initalizes Fast by setting configuration parameters + * + * \param[in] obj : pointer to Fast instance + * \param[in] pParams : pointer to Fast configuration parameters + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Fast_Init(FastType *obj, const Fast_ParamsType *pParams); + +/*! \brief Run the FAST + * + * This function runs Fast function, calculates Fast relevant value + * + * \param[in] obj : pointer to Fast instance + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Fast_Run(FastType *obj); + +/*! \brief Calculates current motor speed + * + * This function calculates current motor speed based on Fast estimation parameters + * + * \param[in] obj : pointer to Fast instance + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Fast_CalcSpeed(FastType *obj); + +/*! \brief Calculates current motor parameters + * + * This function calculates current motor flux and torque + * based on Fast estimation parameters + * + * \param[in] obj : pointer to Fast instance + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Fast_CalcFluxAndTorque(FastType *obj); + +/*! \brief Updates configuration parameters + * + * This function updates configuration parameters dynamically + * + * \param[in] obj : pointer to Fast instance + * \param[in] pParams : pointer to Fast configuration parameters + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Fast_UpdateParams(FastType *obj, const Fast_DynamicParamsType *pParams); + +/*! \brief Reset the Fast object + * + * This function resets the Fast relevant calculation parameters + * + * \param[in] obj : pointer to Fast instance + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Fast_Reset(FastType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _FAST_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/foc/efoc.h b/cva_asw_m0118/SDK/lib/shared/md_lib/foc/efoc.h new file mode 100644 index 0000000..6a92f98 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/foc/efoc.h @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _EFOC_H_ +#define _EFOC_H_ + +/*! \brief Contains public interface to various functions related + * to the Enhanced Field-Oriented Control (EFOC) object + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "common/iqmath/iqmath.h" +#include "md_lib/clarke/clarke.h" +#include "md_lib/park/park.h" +#include "md_lib/ipark/ipark.h" +#include "md_lib/svgen/svgen.h" +#include "md_lib/fullwave/fullwave.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines the control type of the EFOC + */ +typedef enum +{ + EFOC_CTRLTYPE_VVVF = 0, + EFOC_CTRLTYPE_CURRENTLOOP, + EFOC_CTRLTYPE_FULLWAVE, + EFOC_CTRLTYPE_OFFLINE, +} EFoc_CtrlModeType; + +/*! \brief Defines all the parameters used to initialize EFOC object + */ +typedef struct _EFoc_ParamsType_ +{ + float VsMax_pu; /*!< Max allowed Vs */ + float VdMaxScale; /*!< Max allowed Vd scale factor based on Vs. */ + float minVdc_V; /*!< Minimum DC voltage allowed */ + float maxVdc_V; /*!< Maximum DC voltage allowed */ + float Rs_Ohm; /*!< Stationary resistance in Ohm */ + float Ld_mH; /*!< Normal D-axis inductance in mH */ + float Lq_mH; /*!< Normal Q-axis inductance in mH */ + float flux_Wb; /*!< The flux of rotor */ + float runFreq_kHz; /*!< Frequency to run FOC */ + float fBase_Hz; /*!< Base value of frequency used for P.U. */ + float VBase_V; /*!< Base value of voltage used for P.U. */ + float ratedVdc_V; /*!< Rated dc bus voltage */ + float IBase_A; /*!< Base value of current used for P.U. */ + EFoc_CtrlModeType ctrlType; /*!< Control type of FOC */ + float switchTime_ms; /*!< The switch time between FOC and full wave */ + float fullwaveBWScale; /*!< Current control run frequency / Bandwidth in full wave mode */ + float lambda; /*!< Control parameter for the decouple network */ + float alpha; /*!< Control parameter for the Ls */ + float beta; /*!< Control parameter for the Rs */ +} EFoc_ParamsType; + +/*! \brief Defines the dynamic parameters used to update EFOC object + */ +typedef struct _EFoc_DynamicParamsType_ +{ + float Rs_Ohm; /*!< Stationary resistance in Ohm */ + float Ld_mH; /*!< Normal D-axis inductance in mH */ + float Lq_mH; /*!< Normal Q-axis inductance in mH */ + float flux_Wb; /*!< The flux of rotor */ + float runFreq_kHz; /*!< Frequency to run FOC */ + _iq Vdc_pu; /*!< DC bus voltage */ + float lambda; /*!< Control parameter for the decouple network */ + float alpha; /*!< Control parameter for the Ls */ + float beta; /*!< Control parameter for the Rs */ +} EFoc_DynamicParamsType; + +/*! \brief Defines the EFOC object + */ +typedef struct _EFocType_ +{ + _iq Ia_pu; /*!< Input: The phase-A current */ + _iq Ib_pu; /*!< Input: The phase-B current */ + _iq Ic_pu; /*!< Input: The phase-C current */ + _iq parkSinTh; /*!< Input: The sin value for PARK transform */ + _iq parkCosTh; /*!< Input: The cos value for PARK transform */ + _iq iparkSinTh; /*!< Input: The sin value for IPARK transform */ + _iq iparkCosTh; /*!< Input: The cos value for IPARK transform */ + _iq Vref; /*!< Input: Only used in VVVF mode */ + _iq IdRef; /*!< Input: The Id reference */ + _iq IqRef; /*!< Input: The Iq reference */ + _iq speed_pu; /*!< Input: Feedback speed in P.U. */ + _iq compVd; /*!< Input: The compensation value of Vd, normally is 0 */ + _iq compVq; /*!< Input: The compensation value of Vq, normally is 0 */ + + _iq VsMax; /*!< Parameters: Max value of Vs */ + _iq VdMax; /*!< Parameters: Max value of Vd */ + EFoc_CtrlModeType ctrlType; /*!< Parameters: Control type of FOC */ + _iq minVdc_pu; /*!< Parameter: Minimum DC voltage allowed in P.U. */ + _iq maxVdc_pu; /*!< Parameter: Maximum DC voltage allowed in P.U.*/ + + _iq Kr; /*!< Internal variable: coefficient determined by Rs */ + _iq Kd_Vd; /*!< Internal variable: coefficient determined by Ld in Vd equation */ + _iq Kq_Vd; /*!< Internal variable: coefficient determined by Lq in Vd equation */ + _iq Kq_Vq; /*!< Internal variable: coefficient determined by Lq in Vq equation */ + _iq Kd_Vq; /*!< Internal variable: coefficient determined by Ld in Vq equation */ + _iq Kf; /*!< Internal variable: coefficient determined by flux in Vq equation */ + float factorR; /*!< Internal variable: factor of IBase/VBase */ + float factorL; /*!< Internal variable: factor of fBase*IBase/VBase */ + float factorBemf; /*!< Internal variable: factor of fBase/VBase */ + ClarkeType clarkeI; /*!< Internal variable: Clarke transform of current */ + ParkType park; /*!< Internal variable: Part transform */ + IparkType ipark; /*!< Internal variable: iPark transform */ + SvgenType svgen; /*!< Internal variable: SVPWM generator */ + FullWaveType fullwave; /*!< Internal variable: Full wave control */ + _iq Vd; /*!< Internal variable: Vd */ + _iq Vq; /*!< Internal variable: Vq */ + _iq lastErrorId; /*!< Internal variable: Last error of Id */ + _iq lastErrorIq; /*!< Internal variable: Last error of Iq */ + _iq VdAccum; /*!< Internal variable: The accumulator of Vd */ + _iq VqAccum; /*!< Internal variable: The accumulator of Vq */ + + _iq Vs; /*!< Output: Clarke transform of current */ +} EFocType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the EFOC object + * + * This function initalizes EFoc by setting configuration parameters + * + * \param[in] obj : pointer to EFoc instance + * \param[in] pParams : pointer to EFoc configuration parameters + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t EFoc_Init(EFocType *obj, const EFoc_ParamsType *pParams); + +/*! \brief Set the current feedback value + * + * This function sets current feedback value + * + * \param[in] obj : pointer to EFoc instance + * \param[in] Ia_pu : The phase-A current in P.U. + * \param[in] Ib_pu : The phase-B current in P.U. + * \param[in] Ic_pu : The phase-C current in P.U. + */ +static inline void EFoc_SetCurrentFdb(EFocType *obj, _iq Ia_pu, _iq Ib_pu, _iq Ic_pu) +{ + obj->Ia_pu = Ia_pu; + obj->Ib_pu = Ib_pu; + obj->Ic_pu = Ic_pu; +} + +/*! \brief The main process function of EFoc + * + * This function runs EFoc function, perform motor control functions + * + * \param[in] obj : pointer to EFoc instance + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t EFoc_Run(EFocType *obj); + +/*! \brief Get the PWM compare value of EFoc + * + * This function gets three phase duty + * + * \param[in] obj : pointer to EFoc instance + * \param[out] Ta : the phase-A duty + * \param[out] Tb : the phase-B duty + * \param[out] Tc : the phase-C duty + */ +extern void EFoc_GetPwmCompareValue(EFocType *obj, _iq *Ta, _iq *Tb, _iq *Tc); + +/*! \brief Reset the EFoc object + * + * This function resets the EFoc relevant calculation parameters + * + * \param[in] obj : pointer to EFoc instance + */ +extern void EFoc_Reset(EFocType *obj); + +/*! \brief Update the parameters of EFoc + * + * This function updates the EFoc function configuration parameters + * + * \param[in] obj : pointer to EFoc instance + * \param[in] pParams : pointer to control configuration paramter + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t EFoc_UpdateParams(EFocType *obj, const EFoc_DynamicParamsType *pParams); + +/*! \brief Change the control type of EFoc + * + * This function updates the EFoc function configuration parameters + * + * \param[in] obj : pointer to EFoc instance + * \param[in] ctrlType : the control type of the EFOC + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t EFoc_ChangeCtrlType(EFocType *obj, EFoc_CtrlModeType ctrlType); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _EFOC_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/foc/foc.c b/cva_asw_m0118/SDK/lib/shared/md_lib/foc/foc.c new file mode 100644 index 0000000..0a7e162 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/foc/foc.c @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "foc.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define FULL_WAVE_VS (_IQ(0.66666)) /* The Vs used in full wave mode */ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void Foc_Init(FocType *obj, const Foc_ParamsType *pParams) +{ + obj->ctrlType = pParams->ctrlType; + + obj->minVdc_pu = _IQ(pParams->minVdc_V / pParams->VBase_V); + obj->maxVdc_pu = _IQ(pParams->maxVdc_V / pParams->VBase_V); + obj->factorKpKi = 2 * MATH_PI * pParams->IBase_A / pParams->VBase_V / pParams->bandWidthScale; + + /* Calculate PID parameters */ + _iq Ki_parallel = _IQ(2 * MATH_PI * pParams->Rs_Ohm / pParams->bandWidthScale + * pParams->IBase_A / pParams->ratedVdc_V); + _iq Kp_parallel = _IQ(2 * MATH_PI * pParams->Ld_mH * pParams->runFreq_kHz / pParams->bandWidthScale + * pParams->IBase_A / pParams->ratedVdc_V); + + obj->VsMax = _IQ(pParams->VsMax_pu); + obj->VdMax = _IQ(pParams->VsMax_pu * pParams->VdMaxScale); + + /* Apply to current PID, note that the pidIq limits will be set dynamically, so just set 0 when init */ + Pid_Init(&obj->pidId, Kp_parallel, Ki_parallel, 0, -obj->VdMax, obj->VdMax); + + Ki_parallel = _IQ(2 * MATH_PI * pParams->Rs_Ohm / pParams->bandWidthScale + * pParams->IBase_A / pParams->ratedVdc_V); + Kp_parallel = _IQ(2 * MATH_PI * pParams->Lq_mH * pParams->runFreq_kHz / pParams->bandWidthScale + * pParams->IBase_A / pParams->ratedVdc_V); + Pid_Init(&obj->pidIq, Kp_parallel, Ki_parallel, 0, 0, 0); + + /* Full wave control */ + FullWave_ParamsType fullwaveParams; + fullwaveParams.Rs_Ohm = pParams->Rs_Ohm; + fullwaveParams.Ld_mH = pParams->Ld_mH; + fullwaveParams.runFreq_kHz = pParams->runFreq_kHz; + fullwaveParams.ratedVdc_V = pParams->ratedVdc_V; + fullwaveParams.IBase_A = pParams->IBase_A; + fullwaveParams.VsMax = pParams->VsMax_pu; + fullwaveParams.VdMaxScale = pParams->VdMaxScale; + fullwaveParams.VsRampStep = FULL_WAVE_VS / (pParams->switchTime_ms * pParams->runFreq_kHz); + fullwaveParams.bandWidthScale = pParams->fullwaveBWScale; + FullWave_Init(&obj->fullwave, &fullwaveParams); + + obj->svgen.mode = SVGEN_MODE_NORMAL; + + obj->IdRef = 0; + obj->IqRef = 0; + obj->Vref = 0; + obj->Vdff = 0; + obj->Vqff = 0; +} + +void Foc_Run(FocType *obj) +{ + if(obj->ctrlType == FOC_CTRLTYPE_VVVF) + { + /* No current control */ + obj->ipark.Ds = obj->Vref; + obj->ipark.Qs = 0; + } + else + { + /* Clarke transform */ + obj->clarkeI.As = obj->Ia_pu; + obj->clarkeI.Bs = obj->Ib_pu; + obj->clarkeI.Cs = obj->Ic_pu; + Clarke_Run(&obj->clarkeI); + + /* Park transform */ + obj->park.alpha = obj->clarkeI.alpha; + obj->park.beta = obj->clarkeI.beta; + obj->park.sinTh = obj->parkSinTh; + obj->park.cosTh = obj->parkCosTh; + Park_Run(&obj->park); + + if(obj->ctrlType == FOC_CTRLTYPE_CURRENTLOOP) + { + /* Id PID */ + obj->pidId.ref = obj->IdRef; + obj->pidId.fdb = obj->park.Ds; + Pid_Run(&obj->pidId); + obj->Vd = _IQsat(obj->pidId.output + obj->Vdff, obj->VdMax, -obj->VdMax); + + /* Vq limit calculation */ + _iq VsMaxSqr = _IQmpy(obj->VsMax, obj->VsMax); + _iq VdSqr = _IQmpy(obj->Vd, obj->Vd); + _iq VqMaxSqr = VdSqr < VsMaxSqr ? VsMaxSqr - VdSqr : 0; + _iq VqMax = _IQsqrt(VqMaxSqr); + + /* Iq PID */ + obj->pidIq.outMax = VqMax; + obj->pidIq.outMin = -VqMax; + obj->pidIq.ref = obj->IqRef; + obj->pidIq.fdb = obj->park.Qs; + Pid_Run(&obj->pidIq); + obj->Vq = _IQsat(obj->pidIq.output + obj->Vqff, VqMax, -VqMax); + + /* IPARK */ + obj->ipark.Ds = obj->Vd; + obj->ipark.Qs = obj->Vq; + } + else if(obj->ctrlType == FOC_CTRLTYPE_FULLWAVE) + { + /* Full-wave control */ + obj->fullwave.IqRef_pu = obj->IqRef; + obj->fullwave.Iq_pu = obj->park.Qs; + obj->fullwave.speed_pu = obj->speed_pu; + obj->fullwave.Vdff = obj->Vdff; + FullWave_Run(&obj->fullwave); + + /* IPARK */ + obj->ipark.Ds = obj->fullwave.Vd; + obj->ipark.Qs = obj->fullwave.Vq; + } + } + + obj->ipark.sinTh = obj->iparkSinTh; + obj->ipark.cosTh = obj->iparkCosTh; + IPark_Run(&obj->ipark); + + /* Calculate Vs */ + obj->Vs = _IQmag(obj->ipark.Ds, obj->ipark.Qs); + + /* SVGEN */ + obj->svgen.Ualpha = obj->ipark.alpha; + obj->svgen.Ubeta = obj->ipark.beta; + Svgen_Run(&obj->svgen); +} + +void Foc_GetPwmCompareValue(FocType *obj, _iq *Ta, _iq *Tb, _iq *Tc) +{ + *Ta = obj->svgen.Ta; + *Tb = obj->svgen.Tb; + *Tc = obj->svgen.Tc; +} + +void Foc_Reset(FocType *obj) +{ + obj->IqRef = 0; /* Clear IqRef first just to be safe */ + obj->IdRef = 0; + obj->pidId.Ui = 0; + obj->pidId.output = 0; + obj->pidIq.Ui = 0; + obj->pidIq.output = 0; + obj->Vd = 0; + obj->Vq = 0; + obj->ipark.Ds = 0; + obj->ipark.Qs = 0; + obj->Vdff = 0; + obj->Vqff = 0; +} + +void Foc_UpdateParams(FocType *obj, const Foc_DynamicParamsType *pParams) +{ + if(pParams->Vdc_pu >= obj->minVdc_pu && pParams->Vdc_pu <= obj->maxVdc_pu) + { + if(obj->ctrlType != FOC_CTRLTYPE_FULLWAVE) + { + obj->pidId.Kp = _IQdiv(_IQ(obj->factorKpKi * pParams->Ld_mH * pParams->runFreq_kHz), pParams->Vdc_pu); + obj->pidId.Ki = _IQdiv(_IQ(obj->factorKpKi * pParams->Rs_Ohm), pParams->Vdc_pu); + + obj->pidIq.Kp = _IQdiv(_IQ(obj->factorKpKi * pParams->Lq_mH * pParams->runFreq_kHz), pParams->Vdc_pu); + obj->pidIq.Ki = obj->pidId.Ki; + } + else + { + FullWave_DynamicParamsType fullwaveDynamicParams; + fullwaveDynamicParams.Rs_Ohm = pParams->Rs_Ohm; + fullwaveDynamicParams.Ld_mH = pParams->Ld_mH; + fullwaveDynamicParams.runFreq_kHz = pParams->runFreq_kHz; + fullwaveDynamicParams.Vdc_pu = pParams->Vdc_pu; + FullWave_UpdateParams(&obj->fullwave, &fullwaveDynamicParams); + } + } +} + +void Foc_ChangeCtrlType(FocType *obj, Foc_CtrlModeType ctrlType) +{ + if(obj->ctrlType != FOC_CTRLTYPE_FULLWAVE + && ctrlType == FOC_CTRLTYPE_FULLWAVE) + { /* Switch to full wave control */ + /* Remember the current Vd, Vq */ + obj->fullwave.Vd = obj->ipark.Ds; + obj->fullwave.Vq = obj->ipark.Qs; + obj->fullwave.pidIq.output = -obj->fullwave.Vd; + obj->fullwave.pidIq.Ui = obj->fullwave.pidIq.output; + /* Change the target Vs */ + FullWave_SetVsMax(&obj->fullwave, FULL_WAVE_VS); + obj->svgen.mode = SVGEN_MODE_SQUAREWAVE; + } + else if(obj->ctrlType == FOC_CTRLTYPE_FULLWAVE + && ctrlType == FOC_CTRLTYPE_CURRENTLOOP) + { /* Switch back to current loop */ + /* Remember the current Vd, Vq */ + obj->pidId.output = obj->ipark.Ds; + obj->pidId.Ui = obj->pidId.output; + obj->pidIq.output = obj->ipark.Qs; + obj->pidIq.Ui = obj->pidIq.output; + /* Change the target Vs */ + FullWave_SetVsMax(&obj->fullwave, obj->VsMax); + obj->svgen.mode = SVGEN_MODE_NORMAL; + } + + obj->ctrlType = ctrlType; +} diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/foc/foc.h b/cva_asw_m0118/SDK/lib/shared/md_lib/foc/foc.h new file mode 100644 index 0000000..1de372a --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/foc/foc.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FOC_H_ +#define _FOC_H_ + +/*! \brief Contains public interface to various functions related + * to the Field-Oriented Control (FOC) object + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "common/iqmath/iqmath.h" +#include "common/pid/pid.h" +#include "md_lib/clarke/clarke.h" +#include "md_lib/park/park.h" +#include "md_lib/ipark/ipark.h" +#include "md_lib/svgen/svgen.h" +#include "md_lib/fullwave/fullwave.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines the control type of the FOC + */ +typedef enum +{ + FOC_CTRLTYPE_VVVF = 0, + FOC_CTRLTYPE_CURRENTLOOP, + FOC_CTRLTYPE_FULLWAVE, + FOC_CTRLTYPE_OFFLINE, +} Foc_CtrlModeType; + +/*! \brief Defines all the parameters used to initialize FOC object + */ +typedef struct _Foc_ParamsType_ +{ + float VsMax_pu; /*!< Max allowed Vs */ + float VdMaxScale; /*!< Max allowed Vd scale factor based on Vs. */ + float minVdc_V; /*!< Minimum DC voltage allowed */ + float maxVdc_V; /*!< Maximum DC voltage allowed */ + float Rs_Ohm; /*!< Stationary resistance in Ohm */ + float Ld_mH; /*!< Normal D-axis inductance in mH */ + float Lq_mH; /*!< Normal Q-axis inductance in mH */ + float runFreq_kHz; /*!< Frequency to run FOC */ + float fBase_Hz; /*!< Base value of frequency used for P.U. */ + float ratedVdc_V; /*!< Rated dc bus voltage */ + float VBase_V; /*!< Base value of voltage used for P.U. */ + float IBase_A; /*!< Base value of current used for P.U. */ + Foc_CtrlModeType ctrlType; /*!< Control type of FOC */ + float switchTime_ms; /*!< The switch time between FOC and full wave */ + float bandWidthScale; /*!< Current control run frequency / Bandwidth */ + float fullwaveBWScale; /*!< Current control run frequency / Bandwidth in full wave mode */ +} Foc_ParamsType; + +/*! \brief Defines the dynamic parameters used to update FOC object + */ +typedef struct _Foc_DynamicParamsType_ +{ + float Rs_Ohm; /*!< Stationary resistance in Ohm */ + float Ld_mH; /*!< Normal D-axis inductance in mH */ + float Lq_mH; /*!< Normal Q-axis inductance in mH */ + float runFreq_kHz; /*!< Frequency to run FOC */ + _iq Vdc_pu; /*!< DC bus voltage */ +} Foc_DynamicParamsType; + +/*! \brief Defines the FOC object + */ +typedef struct _FocType_ +{ + _iq Ia_pu; /*!< Input: The phase-A current */ + _iq Ib_pu; /*!< Input: The phase-B current */ + _iq Ic_pu; /*!< Input: The phase-C current */ + _iq parkSinTh; /*!< Input: The sin value for PARK transform */ + _iq parkCosTh; /*!< Input: The cos value for PARK transform */ + _iq iparkSinTh; /*!< Input: The sin value for IPARK transform */ + _iq iparkCosTh; /*!< Input: The cos value for IPARK transform */ + _iq Vref; /*!< Input: Only used in VVVF mode */ + _iq IdRef; /*!< Input: The Id reference */ + _iq IqRef; /*!< Input: The Iq reference */ + _iq speed_pu; /*!< Input: Feedback speed in P.U. */ + _iq Vdff; /*!< Input: Feed-forward Vd */ + _iq Vqff; /*!< Input: Feed-forward Vq */ + + _iq VsMax; /*!< Parameter: Max value of Vs */ + _iq VdMax; /*!< Parameter: Max value of Vd */ + Foc_CtrlModeType ctrlType; /*!< Parameter: Control type of FOC */ + float factorKpKi; /*!< Parameter: The factor to calculate Kp Ki in runtime */ + _iq minVdc_pu; /*!< Parameter: Minimum DC voltage allowed in P.U. */ + _iq maxVdc_pu; /*!< Parameter: Maximum DC voltage allowed in P.U. */ + + PidType pidId; /*!< Internal variable: The PID control of Id current */ + PidType pidIq; /*!< Internal variable: The PID control of Iq current */ + ClarkeType clarkeI; /*!< Internal variable: Clarke transform of current */ + ParkType park; /*!< Internal variable: Part transform */ + IparkType ipark; /*!< Internal variable: iPark transform */ + SvgenType svgen; /*!< Internal variable: SVPWM generator */ + FullWaveType fullwave; /*!< Internal variable: Full wave control */ + _iq Vd; /*!< Internal variable: Vd */ + _iq Vq; /*!< Internal variable: Vq */ + + _iq Vs; /*!< Output: Clarke transform of current */ +} FocType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the FOC object + * + * This function initalizes Foc by setting configuration parameters + * + * \param[in] obj : pointer to Foc instance + * \param[in] pParams : pointer to Foc configuration parameters + */ +extern void Foc_Init(FocType *obj, const Foc_ParamsType *pParams); + +/*! \brief Set the current feedback value + * + * This function runs Foc function, perform motor control functions + * + * \param[in] obj : pointer to Foc instance + * \param[in] Ia_pu : The phase-A current in P.U. + * \param[in] Ib_pu : The phase-B current in P.U. + * \param[in] Ic_pu : The phase-C current in P.U. + */ +static inline void Foc_SetCurrentFdb(FocType *obj, _iq Ia_pu, _iq Ib_pu, _iq Ic_pu) +{ + obj->Ia_pu = Ia_pu; + obj->Ib_pu = Ib_pu; + obj->Ic_pu = Ic_pu; +} + +/*! \brief The main process function of Foc + * + * This function runs Foc function, perform motor control functions + * + * \param[in] obj : pointer to Foc instance + */ +extern void Foc_Run(FocType *obj); + +/*! \brief Get the PWM compare value of Foc + * + * This function gets three phase duty + * + * \param[in] obj : pointer to Foc instance + * \param[out] Ta : the phase-A duty + * \param[out] Tb : the phase-B duty + * \param[out] Tc : the phase-C duty + */ +extern void Foc_GetPwmCompareValue(FocType *obj, _iq *Ta, _iq *Tb, _iq *Tc); + +/*! \brief Reset the Foc object + * + * This function resets the Foc relevant calculation parameters + * + * \param[in] obj : pointer to Foc instance + */ +extern void Foc_Reset(FocType *obj); + +/*! \brief Update the parameters of Foc + * + * This function updates the Foc function configuration parameters + * + * \param[in] obj : pointer to Foc instance + * \param[in] pParams : pointer to control configuration paramter + */ +extern void Foc_UpdateParams(FocType *obj, const Foc_DynamicParamsType *pParams); + +/*! \brief Change the control type of Foc + * + * This function updates the Foc function configuration parameters + * + * \param[in] obj : pointer to Foc instance + * \param[in] ctrlType : the control type of the FOC + */ +extern void Foc_ChangeCtrlType(FocType *obj, Foc_CtrlModeType ctrlType); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _FOC_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/fullwave/fullwave.h b/cva_asw_m0118/SDK/lib/shared/md_lib/fullwave/fullwave.h new file mode 100644 index 0000000..e8648e7 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/fullwave/fullwave.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FULLWAVE_H_ +#define _FULLWAVE_H_ + +/*! \brief Contains public interface to various functions related + * to the full-wave control (FULLWAVE) object. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "common/iqmath/iqmath.h" +#include "common/pid/pid.h" +#include "common/curve/ramp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines all the parameters used to initialize FULLWAVE object + */ +typedef struct _FullWave_ParamsType_ +{ + float Rs_Ohm; /*!< Stationary resistance in Ohm */ + float Ld_mH; /*!< Normal D-axis inductance in mH */ + float runFreq_kHz; /*!< Frequency to run FOC */ + float ratedVdc_V; /*!< Rated dc bus voltage */ + float IBase_A; /*!< Base value of current used for P.U. */ + float VBase_V; /*!< Base value of voltage used for P.U. */ + float VsMax; /*!< Max allowed Vs */ + float VdMaxScale; /*!< Max allowed Vd scale factor based on Vs. */ + float VsRampStep; /*!< The step of changing the Vs */ + float bandWidthScale; /*!< Current control run frequency / Bandwidth */ + float minVdc_V; /*!< Minimum DC voltage allowed */ + float maxVdc_V; /*!< Minimum DC voltage allowed */ +} FullWave_ParamsType; + +/*! \brief Defines the dynamic parameters used to update FULLWAVE object + */ +typedef struct _FullWave_DynamicParamsType_ +{ + float Rs_Ohm; /*!< Stationary resistance in Ohm */ + float Ld_mH; /*!< Normal D-axis inductance in mH */ + float runFreq_kHz; /*!< Frequency to run FOC */ + _iq Vdc_pu; /*!< DC bus voltage */ +} FullWave_DynamicParamsType; + +/*! \brief Defines the FULLWAVE object + */ +typedef struct _FullWaveType_ +{ + _iq IqRef_pu; /*!< Input: Command Iq current in P.U. */ + _iq Iq_pu; /*!< Input: Feedback Iq current in P.U. */ + _iq speed_pu; /*!< Input: Feedback speed in P.U. */ + _iq Vdff; /*!< Input: Feed-forward Vd */ + + float factorKpKi; /*!< Parameter: The factor to calculate Kp and Ki */ + _iq minVdc_pu; /*!< Parameter: Minimum DC voltage allowed in P.U. */ + _iq maxVdc_pu; /*!< Parameter: Maximum DC voltage allowed in P.U. */ + + PidType pidIq; /*!< Internal variable: The PID to tune Iq */ + RampType rampVs; /*!< Internal variable: The ramp of changing the Vs */ + _iq VdMaxScale; /*!< Internal variable: Max allowed Vd scale factor based on Vs. */ + _iq VsMax; /*!< Internal variable: The Max ABS value of Vs */ + + _iq Vd; /*!< Output: Vd */ + _iq Vq; /*!< Output: Vq */ +} FullWaveType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the FullWave object + * + * This function initalizes FullWave by setting configuration parameters + * + * \param[in] obj : pointer to FullWave instance + * \param[in] pParams : pointer to FullWave configuration parameters + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t FullWave_Init(FullWaveType *obj, const FullWave_ParamsType *pParams); + +/*! \brief Run the full wave control + * + * This function runs full wave control function, perform motor control functions + * + * \param[in] obj : pointer to FullWave instance + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t FullWave_Run(FullWaveType *obj); + +/*! \brief Set the Vs max + * + * This function sets Vs max value + * + * \param[in] obj : pointer to FullWave instance + * \param[in] VsMax : Vs max value + */ +extern void FullWave_SetVsMax(FullWaveType *obj, _iq VsMax); + +/*! \brief Update the parameters + * + * This function updates the FullWave function configuration parameters + * + * \param[in] obj : pointer to FullWave instance + * \param[in] pParams : pointer to control configuration paramter + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t FullWave_UpdateParams(FullWaveType *obj, const FullWave_DynamicParamsType *pParams); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _FULLWAVE_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/fw/fw.c b/cva_asw_m0118/SDK/lib/shared/md_lib/fw/fw.c new file mode 100644 index 0000000..362649f --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/fw/fw.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "fw.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/*! \brief Defines the Field Weakening (FW) increment delta correction + */ +#define FW_INC_DELTA (0.00002) + +/*! \brief Defines the Field Weakening (FW) decrement delta correction + */ +#define FW_DEC_DELTA (0.00002) + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void Fw_Init(FwType *obj, _iq maxNegIdRef) +{ + obj->outMax = 0; + obj->outMin = maxNegIdRef; + obj->deltaInc = _IQ(FW_INC_DELTA); + obj->deltaDec = _IQ(FW_DEC_DELTA); + + obj->output = 0; +} + +void Fw_Run(FwType *obj) +{ + if(obj->refValue > obj->fbackValue) + { + obj->output += obj->deltaInc; + } + else if(obj->refValue < obj->fbackValue) + { + obj->output -= obj->deltaDec; + } + + obj->output = _IQsat(obj->output, obj->outMax, obj->outMin); /* Saturate the output */ +} diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/fw/fw.h b/cva_asw_m0118/SDK/lib/shared/md_lib/fw/fw.h new file mode 100644 index 0000000..4ad5265 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/fw/fw.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FW_H_ +#define _FW_H_ + +/*! \brief Contains public interface to various functions related + * to the Field Weakening (FW) object + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +typedef struct _FwType_ +{ + _iq refValue; /*!< Input: The reference value */ + _iq fbackValue; /*!< Input: The feedback value */ + + _iq outMax; /*!< Parameter: Maximum output */ + _iq outMin; /*!< Parameter: Minimum output */ + _iq deltaInc; /*!< Parameter: The field weakening delta increment of Id reference */ + _iq deltaDec; /*!< Parameter: The field weakening delta decrement of Id reference */ + + _iq output; /*!< Output: The output of field weakening */ +} FwType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the Fw object + * + * This function initalizes Fw by setting configuration parameters + * + * \param[in] obj : pointer to Fw instance + * \param[in] maxNegIdRef : max -id reference value + */ +extern void Fw_Init(FwType *obj, _iq maxNegIdRef); + +/*! \brief Run the field weakening control + * + * This function runs Fw function, perform motor control functions + * + * \param[in] obj : pointer to Fw instance + */ +extern void Fw_Run(FwType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _FW_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/ipark/ipark.h b/cva_asw_m0118/SDK/lib/shared/md_lib/ipark/ipark.h new file mode 100644 index 0000000..f09f204 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/ipark/ipark.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _IPARK_H_ +#define _IPARK_H_ + +/*! \brief Contains the public interface to the + * Park transform module routines + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines the IPARK object + * + */ +typedef struct _IparkType_ +{ + _iq sinTh; /*!< Input: sin value of rotating angle (pu) */ + _iq cosTh; /*!< Input: cos value of rotating angle (pu) */ + _iq Ds; /*!< Input: rotating d-axis stator variable */ + _iq Qs; /*!< Input: rotating q-axis stator variable */ + + _iq alpha; /*!< Output: stationary alpha-axis stator variable */ + _iq beta; /*!< Output: stationary beta-axis stator variable */ +} IparkType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Process the IPARK algorithm + * + * This function runs IPARK function to calculate stationary axis variable + * + * \param[in] obj : pointer to Ipark instance + */ +static inline void IPark_Run(IparkType *obj) +{ + obj->alpha = _IQmpy(obj->Ds, obj->cosTh) - _IQmpy(obj->Qs, obj->sinTh); + obj->beta = _IQmpy(obj->Qs, obj->cosTh) + _IQmpy(obj->Ds, obj->sinTh); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _IPARK_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/ipd/hfi.h b/cva_asw_m0118/SDK/lib/shared/md_lib/ipd/hfi.h new file mode 100644 index 0000000..8f980e2 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/ipd/hfi.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _HFI_H_ +#define _HFI_H_ + +/*! \brief Contains public interface to various functions related + * to the Initial Position Detection (IPD) using + * High Frequency Injection method (HFI) object. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "common/iqmath/iqmath.h" +#include "common/filter/bp_so.h" +#include "common/filter/iir_fo.h" +#include "common/pid/pid.h" +#include "md_lib/fag/fag.h" +#include "md_lib/park/park.h" +#include "md_lib/clarke/clarke.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines all the parameters used to initialize HFI object + */ +typedef struct _Hfi_ParamsType_ +{ + float runFreq_kHz; /*!< Frequency to run the process */ + float injectFreq_kHz; /*!< The injected frequency in kHz */ + float injectVd_pVdc; /*!< The injected frequency per Vdc */ + float lpfPole_rps; /*!< Pole value of low pass filter in rad/s */ + float pllPole_rps; /*!< Pole value of PLL in rad/s */ + float Ld_mH; /*!< d-axis inductance in mH */ + float Lq_mH; /*!< q-axis inductance in mH */ + float ratedVdc_V; /*!< Rated DC bus voltage in Volts */ + float fBase_Hz; /*!< Base value of frequency used for P.U. */ + float compFactor; /*!< The factor to compensate the high-frequency voltage and current */ +} Hfi_ParamsType; + +/*! \brief Defines the HFI object + */ +typedef struct _HfiType_ +{ + _iq Ia_pu; /*!< Input: The phase-A current */ + _iq Ib_pu; /*!< Input: The phase-B current */ + _iq Ic_pu; /*!< Input: The phase-C current */ + + _iq VdAmplitude; /*!< Internal Variable: The amplitude of high-frequency Vd */ + _iq compAngle_pu; /*!< Internal Variable: The compensation angle */ + _iq angleFactor; /*!< Internal Variable: Factor to calculate angle from speed */ + _iq nextAngle_pu; /*!< Internal variable: The angle for next control loop */ + ClarkeType clarkeI; /*!< Internal Variable: The Clarke transform for current */ + IirFoType lpf; /*!< Internal Variable: The low pass filter for the Iq */ + BpSoType IalphaBpf; /*!< Internal Variable: The band-pass filter for the alpha-axis current */ + BpSoType IbetaBpf; /*!< Internal Variable: The band-pass filter for the beta-axis current */ + FagType fag; /*!< Internal Variable: The high-frequency angle generator */ + ParkType park; /*!< Internal Variable: The PARK transform of the injected high-frequency current */ + PidType pidPLL; /*!< Internal Variable: The PLL PID */ + + _iq Vd_hf; /*!< Output: The high-frequency Vd */ + _iq estAngle; /*!< Output: The delta angle between the true angle and the one passed in from inputs */ +} HfiType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the HFI object + * + * This function initalizes Hfi by setting configuration parameters + * + * \param[in] obj : pointer to Hfi instance + * \param[in] pParams : pointer to Hfi configuration parameters + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Hfi_Init(HfiType *obj, const Hfi_ParamsType *pParams); + +/*! \brief Run the HFI process + * + * This function runs Hfi function to control motor + * + * \param[in] obj : pointer to Hfi instance + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Hfi_Run(HfiType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _HFI_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/motor/im.c b/cva_asw_m0118/SDK/lib/shared/md_lib/motor/im.c new file mode 100644 index 0000000..e69de29 diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/motor/im.h b/cva_asw_m0118/SDK/lib/shared/md_lib/motor/im.h new file mode 100644 index 0000000..e69de29 diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/motor/im_pte.h b/cva_asw_m0118/SDK/lib/shared/md_lib/motor/im_pte.h new file mode 100644 index 0000000..e69de29 diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/motor/ipm.c b/cva_asw_m0118/SDK/lib/shared/md_lib/motor/ipm.c new file mode 100644 index 0000000..7064d99 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/motor/ipm.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "common/interp/interp2d.h" +#include "ipm_pte.h" +#include "ipm.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void Ipm_Init(IpmType *obj, const Ipm_ParamsType *pParams) +{ + obj->type = pParams->type; + obj->maxRows = pParams->maxRows; + obj->maxColumns = pParams->maxColumns; + obj->defaultRs_Ohm = pParams->defaultRs_Ohm; + obj->defaultLd_mH = pParams->defaultLd_mH; + obj->defaultLq_mH = pParams->defaultLq_mH; + obj->defaultPsi_Wb = pParams->defaultPsi_Wb; + + obj->Rs_Ohm = obj->defaultRs_Ohm; + if(obj->type == IPM_OUTPUTTYPE_FIXED) + { + obj->Ld_mH = obj->defaultLd_mH; + obj->Lq_mH = obj->defaultLq_mH; + obj->Psi_Wb = obj->defaultPsi_Wb; + } + else if(obj->type == IPM_OUTPUTTYPE_DYNAMIC) + { + Table_Init(&obj->paramTable, pParams->pContainer, obj->maxRows, obj->maxColumns); + /* Calculate row and column interval, the table must have at least 4 elements */ + IpmPteType elem00; + IpmPteType elem01; + IpmPteType elem10; + Table_GetElement(&obj->paramTable, (void *)&elem00, sizeof(IpmPteType), 0, 0); + Table_GetElement(&obj->paramTable, (void *)&elem01, sizeof(IpmPteType), 0, 1); + Table_GetElement(&obj->paramTable, (void *)&elem10, sizeof(IpmPteType), 1, 0); + /*! \note The interval between rows and columns must the same for the whole table */ + obj->rowInterval = _IQabs(elem10.absId_pu - elem00.absId_pu); + obj->columnInterval = _IQabs(elem01.absIq_pu - elem00.absIq_pu); + obj->oneOverRowIntvl = _IQdiv(_IQ(1.0), obj->rowInterval); + obj->oneOverColumnIntvl = _IQdiv(_IQ(1.0), obj->columnInterval); + } +} + +void Ipm_Calc(IpmType *obj) +{ + if(obj->type == IPM_OUTPUTTYPE_DYNAMIC) + { + /* The row and column index value should all be ABS */ + obj->absId_pu = _IQabs(obj->Id_pu); + obj->absIq_pu = _IQabs(obj->Iq_pu); + /* Find row */ + /*! \note The interval between rows must the same for the whole table */ + uint16_t row = (uint16_t)(obj->absId_pu / obj->rowInterval); + row = (row > obj->maxRows - 2 ? obj->maxRows - 2 : row); + /* Find column */ + /*! \note The interval between columns must the same for the whole table */ + uint16_t column = (uint16_t)(obj->absIq_pu / obj->columnInterval); + column = (column > obj->maxColumns - 2 ? obj->maxColumns - 2 : column); + /* Find 4 elements */ + IpmPteType topLeft; + IpmPteType topRight; + IpmPteType bottomLeft; + IpmPteType bottomRight; + Table_GetElement(&obj->paramTable, (void *)&topLeft, sizeof(IpmPteType), row, column); + Table_GetElement(&obj->paramTable, (void *)&topRight, sizeof(IpmPteType), row, column + 1); + Table_GetElement(&obj->paramTable, (void *)&bottomLeft, sizeof(IpmPteType), row + 1, column); + Table_GetElement(&obj->paramTable, (void *)&bottomRight, sizeof(IpmPteType), row + 1, column + 1); + _iq rowScale = _IQmpy(obj->absId_pu - topLeft.absId_pu, obj->oneOverRowIntvl); + rowScale = (rowScale > _IQ(1.0) ? _IQ(1.0) : (rowScale < 0 ? 0 : rowScale)); + _iq columnScale = _IQmpy(obj->absIq_pu - topLeft.absIq_pu, obj->oneOverColumnIntvl); + columnScale = (columnScale > _IQ(1.0) ? _IQ(1.0) : (columnScale < 0 ? 0 : columnScale)); + /* Calculate Ld */ + obj->Ld_mH = Interp2d(topLeft.Ld_mH, topRight.Ld_mH, bottomLeft.Ld_mH, bottomRight.Ld_mH, rowScale, columnScale); + /* Calculate Lq */ + obj->Lq_mH = Interp2d(topLeft.Lq_mH, topRight.Lq_mH, bottomLeft.Lq_mH, bottomRight.Lq_mH, rowScale, columnScale); + + /* Calculate Psi */ + obj->Psi_Wb = Interp2d(topLeft.Psi_wb, topRight.Psi_wb, bottomLeft.Psi_wb, bottomRight.Psi_wb, rowScale, columnScale); + } +} diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/motor/ipm.h b/cva_asw_m0118/SDK/lib/shared/md_lib/motor/ipm.h new file mode 100644 index 0000000..b107706 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/motor/ipm.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _IPM_H_ +#define _IPM_H_ + +/*! \brief Contains public interface to various functions related + * to the Interior Permanent Magnet Motor (IPM) + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "common/iqmath/iqmath.h" +#include "common/container/table.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines the motor object + */ +typedef enum +{ + IPM_OUTPUTTYPE_FIXED, + IPM_OUTPUTTYPE_DYNAMIC, +} Ipm_ParamsModeType; + +/*! \brief Defines the initial parameters for IPM object + */ +typedef struct _Ipm_ParamsType_ +{ + Ipm_ParamsModeType type; /*!< How the use motor parameters */ + void *pContainer; /*!< Pointer to the table container */ + uint16_t maxRows; /*!< Max row number of motor parameter 2-D table */ + uint16_t maxColumns; /*!< Max column number of motor parameter 2-D table */ + _iq defaultRs_Ohm; /*!< The default value of Rs */ + _iq defaultLd_mH; /*!< The default value of Ld */ + _iq defaultLq_mH; /*!< The default value of Lq */ + _iq defaultPsi_Wb; /*!< The default value of Psi */ +} Ipm_ParamsType; + +/*! \brief Defines the motor object + */ +typedef struct _IpmType_ +{ + _iq temp_pu; /*!< Input: Motor temperature */ + _iq Id_pu; /*!< Input: D-axis current */ + _iq Iq_pu; /*!< Input: Q-axis current */ + + Ipm_ParamsModeType type; /*!< Parameter: How to use motor parameters */ + uint16_t maxRows; /*!< Parameter: Max row number of motor parameter matrix */ + uint16_t maxColumns; /*!< Parameter: Max column number of motor parameter matrix */ + _iq defaultRs_Ohm; /*!< Parameter: The default value of Rs */ + _iq defaultLd_mH; /*!< Parameter: The default value of Ld */ + _iq defaultLq_mH; /*!< Parameter: The default value of Lq */ + _iq defaultPsi_Wb; /*!< Parameter: The default value of Psi */ + + TableType paramTable; /*!< Internal variable: The motor parameter table */ + _iq rowInterval; /*!< Internal variable: The interval between rows of motor parameter matrix */ + _iq columnInterval; /*!< Internal variable: The interval between columns of motor parameter matrix */ + _iq oneOverRowIntvl; /*!< Internal variable: Reciprocal of interval between rows of motor parameter matrix */ + _iq oneOverColumnIntvl; /*!< Internal variable: Reciprocal of interval between columns of motor parameter matrix */ + _iq absId_pu; /*!< Internal variable: ABS value of D-axis current */ + _iq absIq_pu; /*!< Internal variable: ABS value of Q-axis current */ + + _iq Rs_Ohm; /*!< Output: The stator resistance in P.U. */ + _iq Ld_mH; /*!< Output: The direct stator inductance in P.U. */ + _iq Lq_mH; /*!< Output: The quadrature stator inductance in P.U. */ + _iq Psi_Wb; /*!< Output: The permanent magnet flux in P.U. */ +} IpmType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the IPM object + * + * This function initalizes Ipm by setting configuration parameters + * + * \param[in] obj : pointer to Ipm instance + * \param[in] pParams : pointer to Ipm configuration parameters + */ +extern void Ipm_Init(IpmType *obj, const Ipm_ParamsType *pParams); + +/*! \brief Calculates and Gets the Ipm parameters + * + * This function calculates and gets the Ipm parameters from table data + * + * \param[in] obj : pointer to Ipm instance + */ +extern void Ipm_Calc(IpmType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _IPM_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/motor/ipm_pte.h b/cva_asw_m0118/SDK/lib/shared/md_lib/motor/ipm_pte.h new file mode 100644 index 0000000..cfa6100 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/motor/ipm_pte.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _IPM_PTE_H_ +#define _IPM_PTE_H_ + +/*! \brief Contains public interface to various functions related + * to the Interior Permanent Magnet Motor (IPM) + * Parameters Table Element (PTE) + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines the IPM parameters table element + * \note To make it simple we use the ABS value for the row and column, + * but actually the Id normally is negative, and Iq is irrelevant of + * the sign. + * \note The size must align to 4 bytes + */ +typedef struct _IpmPteType_ +{ + _iq absId_pu; /*!< Donate the row variable - ABS Id value in P.U. */ + _iq absIq_pu; /*!< Donate the column variable - ABS Iq value in P.U. */ + + _iq Ld_mH; /*!< Donate the D-axis inductance in mH */ + _iq Lq_mH; /*!< Donate the D-axis inductance in mH */ + _iq Psi_wb; /*!< Donate the permanent magnet flux in Wb */ +} IpmPteType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _IPM_PTE_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/park/park.h b/cva_asw_m0118/SDK/lib/shared/md_lib/park/park.h new file mode 100644 index 0000000..7dc95fc --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/park/park.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PARK_H_ +#define _PARK_H_ + +/*! \brief Contains the public interface to the + * Park transform module routines + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines the PARK object + */ +typedef struct _ParkType_ +{ + _iq alpha; /*!< Input: stationary d-axis stator variable */ + _iq beta; /*!< Input: stationary q-axis stator variable */ + _iq sinTh; /*!< Input: sin value of rotating angle (pu) */ + _iq cosTh; /*!< Input: cos value of rotating angle (pu) */ + + _iq Ds; /*!< Output: rotating d-axis stator variable */ + _iq Qs; /*!< Output: rotating q-axis stator variable */ +} ParkType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief The main process function of Park + * + * This function runs Park function to calculate rotating axis variable + * + * \param[in] obj : pointer to Park instance + */ +static inline void Park_Run(ParkType *obj) +{ + obj->Ds = _IQmpy(obj->alpha, obj->cosTh) + _IQmpy(obj->beta, obj->sinTh); + obj->Qs = _IQmpy(obj->beta, obj->cosTh) - _IQmpy(obj->alpha, obj->sinTh); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _PARK_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/pcud/pcud.h b/cva_asw_m0118/SDK/lib/shared/md_lib/pcud/pcud.h new file mode 100644 index 0000000..b870bdd --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/pcud/pcud.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PCUD_H_ +#define _PCUD_H_ + +/*! \brief Contains public interface to various functions related + * to the phase current unbalance detection (PCUD) object. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines all the parameters used to initialize PCUD object + */ +typedef struct _Pcud_ParamsType_ +{ + float unbalanceTh; /*!< the threshold of unbalance, normally will be 1.2 (120%) */ + float minDetectI_A; /*!< the minimum detect current in A */ + float minDetectFreq_Hz; /*!< the minimum detect frequency in Hz */ + float IBase_A; /*!< the current base value in A */ + float fBase_Hz; /*!< the base value of frequency used for P.U. */ +} Pcud_ParamsType; + +/*! \brief Defines the PCUD object + */ +typedef struct _PcudType_ +{ + _iq Ia_rms; /*!< Input: phase A current */ + _iq Ib_rms; /*!< Input: phase B current */ + _iq Ic_rms; /*!< Input: phase C current */ + _iq speed_pu; /*!< Input: speed feedback in P.U. */ + + _iq unbalanceTh; /*!< Parameter: The threshold of unbalance */ + _iq minDetectI_pu; /*!< Parameter: The minimum detect current in P.U. */ + _iq minDetectFreq_pu; /*!< Parameter: The minimum detect frequency in P.U. */ + + bool isUnbalance; /*!< Output: Whether is unbalanced */ +} PcudType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the PCUD object + * + * This function initalizes Pcud by setting configuration parameters + * + * \param[in] obj : pointer to Pcud instance + * \param[in] pParams : pointer to Pcud configuration parameters + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Pcud_Init(PcudType *obj, const Pcud_ParamsType *pParams); + +/*! \brief Run the PCUD process + * + * This function runs the phase current unbalance detection + * + * \param[in] obj : pointer to Pcud instance + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Pcud_Run(PcudType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _PCUD_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/phlack/phlack.h b/cva_asw_m0118/SDK/lib/shared/md_lib/phlack/phlack.h new file mode 100644 index 0000000..5e9fb7f --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/phlack/phlack.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PHLACK_H_ +#define _PHLACK_H_ + +/*! \brief Contains public interface to various functions related + * to the Phase-lacking (PHLACK) object. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines all the parameters used to initialize PHLACK object + */ +typedef struct _Phlack_ParamsType_ +{ + float runFreq_kHz; /*!< the frequency of running current loop in kHz */ + float Vref; /*!< the reference voltage used to detect the current */ + float detectFreq_Hz; /*!< the reference frequency used to detect the current */ + float detectTime_ms; /*!< the time used to detect the phase lacking */ + float currentTh_A; /*!< the current threshold used to determine the phase lacking */ + float IBase_A; /*!< the base value of phase current in A */ + float fBase_Hz; /*!< the frequency base value in Hz */ + float VBase_V; /*!< the base value of voltage in V */ +} Phlack_ParamsType; + +typedef enum +{ + PHLACK_STATUS_FINISH = 0, + PHLACK_STATUS_RUNNING, +} Phlack_StatusType; + +/*! \brief Defines the PHLACK object + */ +typedef struct _PhlackType_ +{ + bool startCmd; /*!< Input: True to command to start, will set false when finished */ + _iq Ia_pu; /*!< Input: The current of phase A */ + _iq Ib_pu; /*!< Input: the current of phase B */ + _iq Ic_pu; /*!< Input: the current of phase C */ + + _iq detectFreq_pu; /*!< Parameter: The reference frequency used to detect the current */ + _iq detectVolt_pu; /*!< Parameter: The reference voltage used to detect the current */ + _iq currentTh_pu; /*!< Parameter: The current threshold used to determine the phase lacking */ + uint32_t scanCountMax; /*!< Parameter: The max value of count used for timing */ + + uint32_t scanCount; /*!< Internal variable: The count value used for scan timing */ + Phlack_StatusType status; /*!< Internal variable: The status of the current process */ + bool flagA; /*!< Internal variable: The phase lacking flag of phase A */ + bool flagB; /*!< Internal variable: The phase lacking flag of phase B */ + bool flagC; /*!< Internal variable: The phase lacking flag of phase C */ + + _iq Vref_pu; /*!< Output: The reference voltage in P.U. */ + _iq freqRef_pu; /*!< Output: The reference frequency in P.U. */ + bool lackingPhaseA; /*!< Output: The final flag output of lacking phase A */ + bool lackingPhaseB; /*!< Output: The final flag output of lacking phase B */ + bool lackingPhaseC; /*!< Output: The final flag output of lacking phase C */ +} PhlackType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the PHLACK object + * + * This function initalizes Phlack by setting configuration parameters + * + * \param[in] obj : pointer to Phlack instance + * \param[in] pParams : pointer to Phlack configuration parameters + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Phlack_Init(PhlackType *obj, const Phlack_ParamsType *pParams); + +/*! \brief Run the PHLACK process + * + * This function runs the phase-lacking detection + * + * \param[in] obj : pointer to Phlack instance + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Phlack_Run(PhlackType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _PHLACK_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/pvcr/pvcr.h b/cva_asw_m0118/SDK/lib/shared/md_lib/pvcr/pvcr.h new file mode 100644 index 0000000..15c47bd --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/pvcr/pvcr.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PVCR_H_ +#define _PVCR_H_ + +/*! \brief Contains public interface to various functions related + * Phase Voltage and Current Reconstruction (PVCR) object. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines all the parameters used to initialize PVCR object + */ +typedef struct _Pvcr_ParamsType_ +{ + float Tdb; /*!< The percent taking account of dead-band time and rise/fall time */ +} Pvcr_ParamsType; + +/*! \brief Defines the PVCR object + */ +typedef struct _PvcrType_ +{ + _iq sensedIa; /*!< Input: The sampled current of phase A */ + _iq sensedIb; /*!< Input: The sampled current of phase B */ + _iq sensedIc; /*!< Input: The sampled current of phase C */ + _iq Ta; /*!< Input: 100%-(duty of phase A) */ + _iq Tb; /*!< Input: 100%-(duty of phase B) */ + _iq Tc; /*!< Input: 100%-(duty of phase C) */ + _iq Vdc; /*!< Input: Voltage of DC */ + + _iq Tdb; /*!< Parameter: The percent taking account of dead-band time and rise/fall time */ + + _iq offsetV; /*!< Internal variable: The offset voltage of 3 phases, note that all 3 phases's offset are the same */ + _iq prevTa; /*!< Internal variable: The previous Ta */ + _iq prevTb; /*!< Internal variable: The previous Tb */ + _iq prevTc; /*!< Internal variable: The previous Tc */ + _iq prevPrevTa; /*!< Internal variable: The previous of previous Ta */ + _iq prevPrevTb; /*!< Internal variable: The previous of previous Tb */ + _iq prevPrevTc; /*!< Internal variable: The previous of previous Tc; */ + _iq prevIa; /*!< Internal variable: The previous Ia */ + _iq prevIb; /*!< Internal variable: The previous Ib */ + _iq prevIc; /*!< Internal variable: The previous Ic */ + + _iq Va; /*!< Output: The estimated phase A voltage at the middle of last PWM period */ + _iq Vb; /*!< Output: The estimated phase B voltage at the middle of last PWM period */ + _iq Vc; /*!< Output: The estimated phase C voltage at the middle of last PWM period */ + _iq Ia; /*!< Output: The estimated phase A current at the middle of last PWM period */ + _iq Ib; /*!< Output: The estimated phase A current at the middle of last PWM period */ + _iq Ic; /*!< Output: The estimated phase A current at the middle of last PWM period */ +} PvcrType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the PVCR object + * + * This function initalizes Pvcr by setting configuration parameters + * + * \param[in] obj : pointer to Pvcr instance + * \param[in] pParams : pointer to Pvcr configuration parameters + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Pvcr_Init(PvcrType *obj, const Pvcr_ParamsType *pParams); + +/*! \brief Run the PVCR process + * \note The input must use the FOC control result from this loop + * + * This function runs the phase Voltage and current reconstruction function + * + * \param[in] obj : pointer to Pvcr instance + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Pvcr_Run(PvcrType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _PVCR_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/pwmdbc/pwmdbc.h b/cva_asw_m0118/SDK/lib/shared/md_lib/pwmdbc/pwmdbc.h new file mode 100644 index 0000000..76d6099 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/pwmdbc/pwmdbc.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PWMDBC_H_ +#define _PWMDBC_H_ + +/*! \brief Contains public interface to various functions related + * to the PWM Dead-band Compensation (PWMDBC) object. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines all the parameters used to initialize PWMDBC object + */ +typedef struct _Pwmdbc_ParamsType_ +{ + float Tdb; /*!< The percent taking account of dead-band time and rise/fall time */ + float zeroCurrentTh_A; /*!< The threshold for zero current, in A */ + float IBase_A; /*!< Base value of current used for P.U. */ + float gain; /*!< Gain value for the compensation */ +} Pwmdbc_ParamsType; + +/*! \brief Defines the dynamic parameters used to update PWMDBC object + */ +typedef struct _Pwmdbc_DynamicParamsType_ +{ + float Tdb; /*!< The percent taking account of dead-band time and rise/fall time */ + float zeroCurrentTh_A; /*!< The threshold for zero current, in A */ + float gain; /*!< Gain value for the compensation */ +} Pwmdbc_DynamicParamsType; + +/*! \brief Defines the PWMDBC object + */ +typedef struct _PwmdbcType_ +{ + _iq TaUncomp; /*!< Input: (duty of phase A) - 50% before compensation */ + _iq TbUncomp; /*!< Input: (duty of phase B) - 50% before compensation */ + _iq TcUncomp; /*!< Input: (duty of phase C) - 50% before compensation */ + _iq Ia_pu; /*!< Input: The sampled current of phase A */ + _iq Ib_pu; /*!< Input: The sampled current of phase B */ + _iq Ic_pu; /*!< Input: The sampled current of phase C */ + + _iq Tdb; /*!< Parameter: The percent taking account of dead-band time and rise/fall time */ + _iq scale; /*!< Parameter: The scale of dead-band percent */ + _iq zeroCurrentTh_pu; /*!< Parameter: The threshold for zero current, in P.U. */ + float IBase_A; /*!< Parameter: Base value of current used for P.U. */ + + _iq TaComp; /*!< Input: (duty of phase A) - 50% after compensation */ + _iq TbComp; /*!< Input: (duty of phase B) - 50% after compensation */ + _iq TcComp; /*!< Input: (duty of phase C) - 50% after compensation */ +} PwmdbcType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the PWMDBC object + * + * This function initalizes Pwmdbc by setting configuration parameters + * + * \param[in] obj : pointer to Pwmdbc instance + * \param[in] pParams : pointer to Pwmdbc configuration parameters + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Pwmdbc_Init(PwmdbcType *obj, const Pwmdbc_ParamsType *pParams); + +/*! \brief Run the PWMDBC process + * + * This function runs the pwm dead-band compensation function + * + * \param[in] obj : pointer to Pwmdbc instance + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Pwmdbc_Run(PwmdbcType *obj); + +/*! \brief Update the parameters of PWMDBC + * + * This function updates the Pwmdbc function configuration parameters + * + * \param[in] obj : pointer to Pwmdbc instance + * \param[in] pParams : pointer to control configuration paramter + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Pwmdbc_UpdateParams(PwmdbcType *obj, const Pwmdbc_DynamicParamsType *pParams); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _PWMDBC_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/sensor/hall.h b/cva_asw_m0118/SDK/lib/shared/md_lib/sensor/hall.h new file mode 100644 index 0000000..7a2ccd6 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/sensor/hall.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _HALL_H_ +#define _HALL_H_ + +/*! \brief Contains the public interface to the hall abstract class. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "common/iqmath/iqmath.h" +#include "common/filter/iir_fo.h" +#include "../fag/fag.h" +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines the hall parameters + */ +typedef struct _Hall_ParamsType_ +{ + float phaseCalcFreq_kHz; /*!< Frequency to run phase calculation */ + float spdCalcFreq_kHz; /*!< Frequency to run speed calculation */ + float fBase_Hz; /*!< Base value of frequency used for P.U. */ + float spdFilterPole_rps; /*!< Pole value of speed filter calculation */ + float stamptimerFreq_Hz; /*!< Base clock source frequency */ + uint8_t* pForwardHalSqe; /*!< Hall value order */ + float timeOutFreq_Hz; /*!< Timeout detection frequency */ +} Hall_ParamsType; + +/*! \brief Defines the hall object + */ +typedef struct _HallType_ +{ + uint8_t halValue; /*!< Input: Current hall value */ + uint32_t timerCntDiff; /*!< Input: Time of change hall value */ + uint32_t dirRef; /*!< Input: Desired direction at startup */ + + _iq hallAngleBuf_pu[7]; /*!< Parameter: Hall Angle value used for P.U */ + uint16_t cntInCycle; /*!< Parameter: Mechanical commutation threshold value */ + uint32_t timerOutCnt; /*!< Parameter: Time out count threshold value */ + float spdCalCoef; /*!< Parameter: Coefficient of speed calculation*/ + float spdCalFastCoef; /*!< Parameter: Coefficient of fast speed calculation*/ + + _iq halCalibAngle_pu; /*!< Internal variable: Current hall value angle used for P.U */ + uint32_t timerCntDiffCycle; /*!< Internal variable: The time count after one turn of the electric angle */ + uint8_t halValuePre; /*!< Internal variable: previous hall value */ + bool reStartFlag; /*!< Internal variable: Start flag */ + int16_t reStartCnt; /*!< Internal variable: Start flag */ + uint16_t commutationCnt; /*!< Internal variable: Commutation count */ + FagType hallEstObj; /*!< Internal variable: Angle estimation object */ + FagType startAngleObj; /*!< Internal variable: Start Angle calculate object */ + uint32_t timerCnt; /*!< Internal variable: Running time counter */ + uint32_t reStartTimerCnt; /*!< Internal variable: Running time counter */ + _iq rawSpeed_pu; /*!< Internal variable: The raw speed before filter in P.U. */ + _iq rawSpeedFast_pu; /*!< Internal variable: The raw fast speed in P.U. */ + IirFoType filterSpd; /*!< Internal Variable: The filter for electric speed calculation */ + + _iq angle_pu; /*!< Output: The electrical angle in P.U. */ + uint8_t speedDir; /*!< Output: The electrical angle in P.U. */ + _iq speed_pu; /*!< Output: The speed in P.U. */ +} HallType; + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize hall + * + * This function Initialize hall object by setting configuration parameters + * + * \param[in] obj : pointer to hall instance + * \param[in] pParams : pointer to hall configuration parameters + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Hall_Init(HallType *obj, const Hall_ParamsType *pParams); + +/*! \brief Calculate the angle for PARK and IPARK module + * + * \note Must run in the same frequency with current control loop + * + * \param[in] obj : pointer to hall instance + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Hall_EstAngle(HallType *obj); + +/*! \brief Calculate the speed + * + * \note Might run slower than current control frequency + * + * \param[in] obj : pointer to Hall instance + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Hall_CalcSpeed(HallType *obj); + + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _HALL_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/sensor/resolver.h b/cva_asw_m0118/SDK/lib/shared/md_lib/sensor/resolver.h new file mode 100644 index 0000000..1db1716 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/sensor/resolver.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _RESOLVER_H_ +#define _RESOLVER_H_ + +/*! \brief Contains the public interface to the resolver + * abstract class. This would also cover the usage of + * MagnetoResistance position sensor + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "common/iqmath/iqmath.h" +#include "common/pid/pid.h" +#include "common/filter/iir_fo.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines the Resolver parameters + * \note The pole pair scale should not > 128 + */ +typedef struct _Resolver_ParamsType_ +{ + float polePairScale; /*!< Pole pair of the motor / Pole pair of the resolver */ + uint16_t reverseDir; /*!< Set this value other than 0 will reverse the positive direction, default to use 0 */ + float phaseCalcFreq_kHz; /*!< Frequency to run phase calculation */ + float spdCalcFreq_kHz; /*!< Frequency to run phase calculation */ + float fBase_Hz; /*!< Base value of frequency used for P.U. */ + float responseSpeed_rps; /*!< The response speed in rad/s */ + float spdFilterPole_rps; /*!< Pole value of speed filter calculation */ +} Resolver_ParamsType; + +/*! \brief Defines the dynamic parameters used to update RESOLVER object + */ +typedef struct _Resolver_DynamicParamsType_ +{ + float phaseCalcFreq_kHz; /*!< Frequency to run phase calculation */ + float spdCalcFreq_kHz; /*!< Frequency to run phase calculation */ +} Resolver_DynamicParamsType; + +/*! \brief Defines the Resolver object + */ +typedef struct _ResolverType_ +{ + _iq sin_pu; /*!< Input: The sin value in P.U. */ + _iq cos_pu; /*!< Input: The cos value in P.U. */ + + _iq error; /*!< Parameter: error to calculate angle from speed */ + _iq angleFactor; /*!< Parameter: Factor to calculate angle from speed */ + _iq polePairScale; /*!< Parameter: Pole pair of the motor / Pole pair of the resolver */ + uint16_t reverseDir; /*!< Parameter: Set this value other than 0 will reverse the positive direction, default to use 0 */ + float phaseCalcFreq_kHz; /*!< Parameter: Frequency to run phase calculation */ + float spdCalcFreq_kHz; /*!< Parameter: Frequency to run phase calculation */ + + uint16_t polePairScaleFactor; /*!< Internal variable: The factor for pole pair scale */ + bool firstCalcStatus; /*!< Internal variable: The PLL PID first calculate status */ + PidType pidPLL; /*!< Internal variable: The PLL PID */ + IirFoType filterSpd; /*!< Internal Variable: The filter for electric speed calculation */ + _iq rawSpeed_pu; /*!< Internal variable: The raw speed before filter in P.U. */ + _iq currentAngle_pu; /*!< Internal variable: The angle represented by input */ + _iq nextAngle_pu; /*!< Internal variable: The angle represented by input */ + + _iq angle_pu; /*!< Output: The electrical angle in P.U. */ + _iq speed_pu; /*!< Output: The speed in P.U. */ +} ResolverType; + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize resolver + * + * This function initalizes resolver by setting configuration parameters + * + * \param[in] obj : pointer to Resolver instance + * \param[in] pParams : pointer to Resolver configuration parameters + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Resolver_Init(ResolverType *obj, const Resolver_ParamsType *pParams); + +/*! \brief Run the resolver the calculate the phase + * for PARK and IPARK module + * \note Must run in the same frequency with current control loop + * + * \param[in] obj : pointer to Resolver instance + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Resolver_CalcPhase(ResolverType *obj); + +/*! \brief Calculate the speed + * \note Might run slower than current control frequency + * + * + * \param[in] obj : pointer to Resolver instance + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Resolver_CalcSpeed(ResolverType *obj); + +/*! \brief Update the parameters of Resolver + * + * This function updates the Resolver function configuration parameters + * + * \param[in] obj : pointer to Resolver instance + * \param[in] pParams : pointer to control configuration paramter + * \return the MCUs authorized evaluation + * - -1 : Functions not available + * - 0 : Functions available + */ +extern int32_t Resolver_UpdateParams(ResolverType *obj, const Resolver_DynamicParamsType *pParams); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _RESOLVER_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/spdctrl/afwsc.c b/cva_asw_m0118/SDK/lib/shared/md_lib/spdctrl/afwsc.c new file mode 100644 index 0000000..9a199bc --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/spdctrl/afwsc.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "afwsc.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define DAMPING_FACTOR (4) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void Afwsc_Init(AfwscType *obj, Afwsc_ParamsType *pParams) +{ + obj->speedRef = 0; + + /* Calculate PID parameters */ + _iq Ki_series = _IQ(pParams->spdFilterPole_rps / (DAMPING_FACTOR * DAMPING_FACTOR) * pParams->runFreq_kHz / 1000); + float K = 1.5 * pParams->polePairs * pParams->rotorFlux_Wb / pParams->inertia_kgm2; + _iq Kp_series = _IQ(pParams->spdFilterPole_rps / (K * DAMPING_FACTOR) + * 2 * MATH_PI * pParams->fBase_Hz / pParams->polePairs / pParams->IBase_A); + _iq Kp_parallel = Kp_series; + _iq Ki_parallel = _IQmpy(Ki_series, Kp_series); + + Pid_Init(&obj->pidSpd, Kp_parallel, Ki_parallel, 0, _IQ(0), _IQ(pParams->maxCurrent_A / pParams->IBase_A)); + + Ramp_Init(&obj->spdRamp, _IQ(0.000005)); + + Fw_Init(&obj->fwObj, _IQ(pParams->minId_A / pParams->IBase_A)); +} + +void Afwsc_Run(AfwscType *obj) +{ + /* Field weakening */ + obj->fwObj.refValue = obj->VsRef; + obj->fwObj.fbackValue = obj->Vs; + Fw_Run(&obj->fwObj); + obj->IdRef = obj->fwObj.output; + + /* Ramp for the reference */ + obj->spdRamp.target = obj->speedRef; + Ramp_Calc(&obj->spdRamp); + /* PID for speed */ + obj->pidSpd.ref = obj->spdRamp.output; + obj->pidSpd.fdb = obj->speed; + Pid_Run(&obj->pidSpd); + /* PID output is iq */ + obj->IqRef = obj->pidSpd.output; +} + +void Afwsc_Reset(AfwscType *obj) +{ + obj->fwObj.output = 0; + obj->pidSpd.Ui = 0; + ; + obj->IdRef = 0; + obj->IqRef = 0; +} diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/spdctrl/afwsc.h b/cva_asw_m0118/SDK/lib/shared/md_lib/spdctrl/afwsc.h new file mode 100644 index 0000000..f5b3222 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/spdctrl/afwsc.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _AFWSC_H_ +#define _AFWSC_H_ + +/*! \brief Contains public interface to various functions related + * to the Auto Field-Weakening Speed Control of (AFWSC) object + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "common/iqmath/iqmath.h" +#include "common/pid/pid.h" +#include "common/curve/ramp.h" +#include "md_lib/fw/fw.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines the initial parameters for AFWSC_IPM object + */ +typedef struct _Afwsc_ParamsType_ +{ + uint16_t polePairs; /*!< Pole pairs of the motor */ + float runFreq_kHz; /*!< Frequency to run */ + float fBase_Hz; /*!< Base value of frequency used for P.U. */ + float IBase_A; /*!< Base value of current used for P.U. */ + float inertia_kgm2; /*!< The inertia of the rotoring system */ + float rotorFlux_Wb; /*!< The rotor flux, equal to BEMF in v*s/rad */ + float spdFilterPole_rps; /*!< Pole value of speed filter calculation */ + float minId_A; /*!< Max value of Id to prevent demagnetization for PM motors */ + float maxCurrent_A; /*!< Max value of speed PID output */ +} Afwsc_ParamsType; + +/*! \brief Defines the AFWSC_IPM object + */ +typedef struct _AfwscType_ +{ + _iq speedRef; /*!< Input: The speed reference value of speed loop control */ + _iq speed; /*!< Input: The speed feedback */ + _iq VsRef; /*!< Input: The reference value of Vs */ + _iq Vs; /*!< Input: The feedback value of Vs */ + + PidType pidSpd; /*!< Internal Variable: The PID for speed loop */ + RampType spdRamp; /*!< Internal Variable: The ramp for speed reference value */ + FwType fwObj; /*!< Internal Variable: The field-weakening object */ + + _iq IdRef; /*!< Output: The Id reference value */ + _iq IqRef; /*!< Output: The Iq reference value */ +} AfwscType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the Afwsc object + * + * This function initalizes Afwsc by setting configuration parameters + * + * \param[in] obj : pointer to Afwsc instance + * \param[in] pParams : pointer to Afwsc configuration parameters + */ +extern void Afwsc_Init(AfwscType *obj, Afwsc_ParamsType *pParams); + +/*! \brief The main process function of Afwsc + * + * This function runs Afwsc function, perform motor control functions + * + * \param[in] obj : pointer to Svgen instance + */ +extern void Afwsc_Run(AfwscType *obj); + +/*! \brief Reset the Afwsc object + * + * This function resets the Afwsc relevant calculation parameters + * + * \param[in] obj : pointer to Afwsc instance + */ +extern void Afwsc_Reset(AfwscType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _AFWSC_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/svgen/gdgen.h b/cva_asw_m0118/SDK/lib/shared/md_lib/svgen/gdgen.h new file mode 100644 index 0000000..65c7590 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/svgen/gdgen.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _GDGEN_H_ +#define _GDGEN_H_ + +/*! \brief Contains the public interface to the + * GDPWM generator routines + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines the control mode of the GDGEN + */ +typedef enum +{ + GDGEN_MODE_NORMAL = 0, /*!< Normal mode of sine and trapezoid */ + GDGEN_MODE_SQUAREWAVE, /*!< Square wave mode */ +} Gdgen_ModeType; + +/*! \brief Defines the Space Vector Generator object + */ +typedef struct _GdgenType_ +{ + _iq Ualpha; /*!< Input: reference alpha-axis phase voltage */ + _iq Ubeta; /*!< Input: reference beta-axis phase voltage */ + + Gdgen_ModeType mode; /*!< Parameter: the working mode */ + + _iq Ta; /*!< Output: reference phase-a switching function */ + _iq Tb; /*!< Output: reference phase-b switching function */ + _iq Tc; /*!< Output: reference phase-c switching function */ +} GdgenType; + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief The main process function of Gdgen + * + * This function runs Gdgen function, perform motor control functions + * + * \param[in] obj : pointer to Gdgen instance + */ +static inline void Gdgen_Run(GdgenType *obj) +{ + _iq Vmax, Vcom; + _iq Vref1, Vref2, Vref3; + _iq Va_tmp = -_IQdiv2(obj->Ualpha); + _iq Vb_tmp = _IQmpy(IQMATH_SQRT_THREE_OVER_TWO, obj->Ubeta); + + Vref1 = obj->Ualpha; /*alpha */ + Vref2 = Va_tmp + Vb_tmp; /*-0.5*alpha + sqrt(3)/2 * beta; */ + Vref3 = Va_tmp - Vb_tmp; /*-0.5*alpha - sqrt(3)/2 * beta; */ + + Vmax = 0; + + /* find Vmax, Vcom */ + Vmax = (_IQabs(Vref1) > _IQabs(Vref2)) ? Vref1 : Vref2; + if(_IQabs(Vref3) > _IQabs(Vmax)) + { + Vmax = Vref3; + } + Vcom = (Vmax > 0) ? (Vmax - _IQ(0.5)) : (Vmax + _IQ(0.5)); + + /* Subtract common-mode term to achieve GD modulation */ + obj->Ta = (Vref1 - Vcom); + obj->Tb = (Vref2 - Vcom); + obj->Tc = (Vref3 - Vcom); + + /* If in SquareWave mode, the outputs is not continuous */ + if(obj->mode == GDGEN_MODE_SQUAREWAVE) + { + if(obj->Ta > 0) + { + obj->Ta = _IQ(0.5); + } + if(obj->Ta < 0) + { + obj->Ta = -_IQ(0.5); + } + if(obj->Tb > 0) + { + obj->Tb = _IQ(0.5); + } + if(obj->Tb < 0) + { + obj->Tb = -_IQ(0.5); + } + if(obj->Tc > 0) + { + obj->Tc = _IQ(0.5); + } + if(obj->Tc < 0) + { + obj->Tc = -_IQ(0.5); + } + } +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _GDGEN_H_ */ diff --git a/cva_asw_m0118/SDK/lib/shared/md_lib/svgen/svgen.h b/cva_asw_m0118/SDK/lib/shared/md_lib/svgen/svgen.h new file mode 100644 index 0000000..dbd0454 --- /dev/null +++ b/cva_asw_m0118/SDK/lib/shared/md_lib/svgen/svgen.h @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _SVGEN_H_ +#define _SVGEN_H_ + +/*! \brief Contains the public interface to the + * SVPWM generator routines + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "common/iqmath/iqmath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Defines the control mode of the SVGEN + */ +typedef enum +{ + SVGEN_MODE_NORMAL = 0, /*!< Normal mode of sine and trapezoid */ + SVGEN_MODE_SQUAREWAVE, /*!< Square wave mode */ +} Svgen_ModeType; + +/*! \brief Defines the Space Vector Generator object + */ +typedef struct _SvgenType_ +{ + _iq Ualpha; /*!< Input: reference alpha-axis phase voltage */ + _iq Ubeta; /*!< Input: reference beta-axis phase voltage */ + + Svgen_ModeType mode; /*!< Parameter: the working mode */ + + _iq Ta; /*!< Output: reference phase-a switching function */ + _iq Tb; /*!< Output: reference phase-b switching function */ + _iq Tc; /*!< Output: reference phase-c switching function */ + +} SvgenType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief The main process function of Svgen + * + * This function runs Svgen function, perform motor control functions + * + * \param[in] obj : pointer to Svgen instance + */ +static inline void Svgen_Run(SvgenType *obj) +{ + _iq Vmax, Vmin, Vcom; + _iq Vref1, Vref2, Vref3; + _iq Va_tmp = -_IQdiv2(obj->Ualpha); + _iq Vb_tmp = _IQmpy(IQMATH_SQRT_THREE_OVER_TWO, obj->Ubeta); + + Vref1 = obj->Ualpha; /* alpha */ + Vref2 = Va_tmp + Vb_tmp; /* -0.5*alpha + sqrt(3)/2 * beta; */ + Vref3 = Va_tmp - Vb_tmp; /* -0.5*alpha - sqrt(3)/2 * beta; */ + + Vmax = 0; + Vmin = 0; + + /* find order Vmin,Vmid,Vmax */ + if(Vref1 > Vref2) + { + Vmax = Vref1; + Vmin = Vref2; + } + else + { + Vmax = Vref2; + Vmin = Vref1; + } + + if(Vref3 > Vmax) + { + Vmax = Vref3; + } + else if(Vref3 < Vmin) + { + Vmin = Vref3; + } + + Vcom = _IQmpy(Vmax + Vmin, _IQ(0.5)); + + /* Subtract common-mode term to achieve SV modulation */ + obj->Ta = (Vref1 - Vcom); + obj->Tb = (Vref2 - Vcom); + obj->Tc = (Vref3 - Vcom); + + /* If in SquareWave mode, the outputs is not continuous */ + if(obj->mode == SVGEN_MODE_SQUAREWAVE) + { + if(obj->Ta > 0) + { + obj->Ta = _IQ(0.5); + } + if(obj->Ta < 0) + { + obj->Ta = -_IQ(0.5); + } + if(obj->Tb > 0) + { + obj->Tb = _IQ(0.5); + } + if(obj->Tb < 0) + { + obj->Tb = -_IQ(0.5); + } + if(obj->Tc > 0) + { + obj->Tc = _IQ(0.5); + } + if(obj->Tc < 0) + { + obj->Tc = -_IQ(0.5); + } + } +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _SVGEN_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/dbc/dbc_comm.c b/cva_asw_m0118/SDK/middleware/dbc/dbc_comm.c new file mode 100644 index 0000000..fc419e0 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/dbc/dbc_comm.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "dbc_comm.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void DbcComm_Init(DbcCommType *obj, const DbcComm_ParamsType *pParams) +{ + uint8_t node = 0; + for(node = 0; node < DBCCOMM_NODE_NUM; ++node) + { + obj->enableNodeTx[node] = false; + obj->enableNodeRx[node] = false; + } + + obj->sendCanMsg = pParams->sendCanMsg; + + uint16_t i = 0; + /* Process send message */ + for(i = 0; i < obj->txMsgNum; ++i) + { + obj->txMsgArray[i].periodCntMax = (uint32_t)(pParams->runFreq_kHz * obj->txMsgArray[i].pInfo->period_ms); + obj->txMsgArray[i].periodCnt = i; /* Stagger the start timing */ + } + + /* Process received message */ + for(i = 0; i < obj->rxMsgNum; ++i) + { + obj->rxMsgArray[i].timeoutCntMax = (uint32_t)(pParams->runFreq_kHz * obj->rxMsgArray[i].pInfo->timeout_ms); + obj->rxMsgArray[i].timeoutCnt = 0; + obj->rxMsgArray[i].isTimeout = false; + } +} + +void DbcComm_Run(DbcCommType *obj) +{ + uint16_t i = 0; + /* Process send message */ + for(i = 0; i < obj->txMsgNum; ++i) + { + DbcComm_CanNodeType node = obj->txMsgArray[i].pInfo->node; + if(obj->enableNodeTx[node]) + { + if(obj->txMsgArray[i].periodCntMax > 0) + { + obj->txMsgArray[i].periodCnt++; + if(obj->txMsgArray[i].periodCnt >= obj->txMsgArray[i].periodCntMax) + { + obj->txMsgArray[i].periodCnt = 0; + /* Pack message and send it */ + DbcComm_CanMsgType msg = CAN_MSG_DEFAULT; + obj->txMsgArray[i].pInfo->packMsg(obj, &msg); + obj->sendCanMsg(node, &msg); + } + } + } + } + + /* Process received message */ + for(i = 0; i < obj->rxMsgNum; ++i) + { + DbcComm_CanNodeType node = obj->rxMsgArray[i].pInfo->node; + if(obj->enableNodeRx[node]) + { + if(obj->rxMsgArray[i].timeoutCntMax > 0 && false == obj->rxMsgArray[i].isTimeout) + { + obj->rxMsgArray[i].timeoutCnt++; + if(obj->rxMsgArray[i].timeoutCnt >= obj->rxMsgArray[i].timeoutCntMax) + { + obj->rxMsgArray[i].timeoutCnt = 0; + obj->rxMsgArray[i].isTimeout = true; + } + } + } + } +} + +void DbcComm_ReceiveCanMsg(DbcCommType *obj, DbcComm_CanNodeType node, const DbcComm_CanMsgType *pMsg) +{ + uint16_t i = 0; + for(i = 0; i < obj->rxMsgNum; ++i) + { + if(pMsg->id == obj->rxMsgArray[i].pInfo->id && node == obj->rxMsgArray[i].pInfo->node) + { + obj->rxMsgArray[i].timeoutCnt = 0; + obj->rxMsgArray[i].isTimeout = false; + obj->rxMsgArray[i].pInfo->unpackMsg(obj, pMsg); + break; + } + } +} + +void DbcComm_EnableRx(DbcCommType *obj, DbcComm_CanNodeType node, bool enable) +{ + if(obj->enableNodeRx[node] != enable) + { + /* Change the enable status */ + uint16_t i = 0; + for(i = 0; i < obj->rxMsgNum; ++i) + { + if(obj->rxMsgArray[i].pInfo->node == node) + { + if(obj->rxMsgArray[i].timeoutCntMax > 0) + { + obj->rxMsgArray[i].timeoutCnt = 0; + obj->rxMsgArray[i].isTimeout = false; + } + } + } + obj->enableNodeRx[node] = enable; + } +} + +void DbcComm_EnableTx(DbcCommType *obj, DbcComm_CanNodeType node, bool enable) +{ + if(obj->enableNodeTx[node] != enable) + { + /* Change the enable status */ + uint16_t i = 0; + for(i = 0; i < obj->txMsgNum; ++i) + { + if(obj->txMsgArray[i].pInfo->node == node) + { + if(obj->txMsgArray[i].periodCntMax > 0) + { + obj->txMsgArray[i].periodCnt = obj->txMsgArray[i].periodCntMax; + } + } + } + obj->enableNodeTx[node] = enable; + } +} diff --git a/cva_asw_m0118/SDK/middleware/dbc/dbc_comm.h b/cva_asw_m0118/SDK/middleware/dbc/dbc_comm.h new file mode 100644 index 0000000..1b2b9d0 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/dbc/dbc_comm.h @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _DBC_COMM_H_ +#define _DBC_COMM_H_ + +/*! \brief Contains public interface to various functions related + * to the CAN communication using the CAN dbc file + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/*! \brief The default value used for initialization + */ +#define CAN_MSG_DEFAULT { \ + 404, \ + {0, 0, 0, 0, 0, 0, 0, 0}, \ + 8, \ + 0, \ + 0 \ +} + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief CAN message type definition + * + * The identifier field may have 11 bits for standard frames + * (CAN specification 2.0A) or 29 bits for extended frames + * (CAN specification 2.0B). + */ +typedef struct _DbcComm_CanMsgType_ +{ + uint32_t id; /*!< the CAN ID, 11 bits for standard frames (CAN SPEC 2.0A) or 29 bits for extended frames (CAN SPEC 2.0B) */ + uint8_t data[8]; /*!< The data field has up to 8 bytes (64 bit) of message data */ + uint8_t length; /*!< The data length code denotes the number of data bytes, 0 to 8 (bytes) */ + uint8_t extended; /*!< Extended Frame if set to 1, else Standard Frame. */ + uint8_t remote; /*!< Remote Frame if set to 1, else Data Frame. */ +} DbcComm_CanMsgType; + +/*! \brief Defines all the CAN node + */ +typedef enum +{ + DBCCOMM_NODE_0 = 0, + DBCCOMM_NODE_1, + DBCCOMM_NODE_2, + DBCCOMM_NODE_3, + DBCCOMM_NODE_4, + DBCCOMM_NODE_5, + DBCCOMM_NODE_6, + DBCCOMM_NODE_7, + DBCCOMM_NODE_8, + + DBCCOMM_NODE_NUM +} DbcComm_CanNodeType; + +/*! \brief Forward declaration of DBCCOMM class + */ +struct _DbcCommType_; + +/*! \brief Tx message information + */ +typedef struct _DbcComm_TxMsgInfoType_ +{ + DbcComm_CanNodeType node; /*!< the node for this message */ + uint32_t id; /*!< the CAN id of this message */ + float period_ms; /*!< Period for transmit messages, 0 for single-shot */ + void (*packMsg)(struct _DbcCommType_ *obj, DbcComm_CanMsgType *pMsg); /*!< pointer to the function to pack this message */ +} DbcComm_TxMsgInfoType; + +/*! \brief Rx message information + */ +typedef struct _DbcComm_RxMsgInfoType_ +{ + DbcComm_CanNodeType node; /*!< the node for this message */ + uint32_t id; /*!< the CAN id of this message */ + float timeout_ms; /*!< Time out threshold for receive messages, 0 for single-shot */ + void (*unpackMsg)(struct _DbcCommType_ *obj, const DbcComm_CanMsgType *pMsg); /*!< pointer to the function to unpack this message */ +} DbcComm_RxMsgInfoType; + +/*! \brief Tx message definition + */ +typedef struct _DbcComm_TxMsgType_ +{ + uint32_t periodCntMax; /*!< the period count max value, determined by period*/ + uint32_t periodCnt; /*!< the period counter */ + const DbcComm_TxMsgInfoType *pInfo; /*!< the informatin of TX message */ +} DbcComm_TxMsgType; + +/*! \brief Rx message definition + */ +typedef struct _DbcComm_RxMsgType_ +{ + uint16_t timeoutCntMax; /*!< the counter max value, determined by timeout period */ + uint16_t timeoutCnt; /*!< the timeout counter */ + bool isTimeout; /*!< whether is timeout */ + const DbcComm_RxMsgInfoType *pInfo; /*!< the informatin of RX message */ +} DbcComm_RxMsgType; + +/*! \brief The adapter of CAN send implementation + */ +typedef void (*DbcComm_SendCanMsgShimType)(DbcComm_CanNodeType node, const DbcComm_CanMsgType *pMsg); + +/*! \brief Type definition of TX message array + */ +typedef DbcComm_TxMsgType *DbcComm_TxMsgArray; + +/*! \brief Type definition of RX message array + */ +typedef DbcComm_RxMsgType *DbcComm_RxMsgArray; + +/*! \brief Defines all the parameters used to initialize power CAN communication object + */ +typedef struct _DbcComm_ParamsType_ +{ + float runFreq_kHz; /*!< Frequency to run this module */ + DbcComm_SendCanMsgShimType sendCanMsg; /*!< function to implement CAN send */ +} DbcComm_ParamsType; + +/*! \brief Defines all the inputs for DBCCOMM object + */ +struct _DbcComm_InputsType_; +typedef struct _DbcComm_InputsType_ DbcComm_InputsType; + +/*! \brief Defines all the outputs for DBCCOMM object + */ +struct _DbcComm_OutputsType_; +typedef struct _DbcComm_OutputsType_ DbcComm_OutputsType; + +/*! \brief Defines the DBCCOMM object + */ +typedef struct _DbcCommType_ +{ + bool enableNodeTx[DBCCOMM_NODE_NUM]; /*!< TX enable flag for all nodes */ + bool enableNodeRx[DBCCOMM_NODE_NUM]; /*!< RX enalbe flag for all nodes */ + DbcComm_TxMsgArray txMsgArray; /*!< TX message array */ + DbcComm_RxMsgArray rxMsgArray; /*!< RX message array */ + uint16_t txMsgNum; /*!< Total TX message number */ + uint16_t rxMsgNum; /*!< Total RX message number */ + DbcComm_InputsType *pInputs; /*!< pointer to the inputs */ + DbcComm_OutputsType *pOutputs; /*!< pointer to the outputs */ + DbcComm_SendCanMsgShimType sendCanMsg; /*!< function to implement CAN send */ + +} DbcCommType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the DBCCOMM object + * + * This function initialize the DbcComm object using the given parameters + * + * \param[in] obj : pointer to DbcComm instance + * \param[in] pParams : + */ +extern void DbcComm_Init(DbcCommType *obj, const DbcComm_ParamsType *pParams); + +/*! \brief Run the DBCCOMM + * + * This function process the DbcComm main logic + * + * \param[in] obj : pointer to DbcComm instance + */ +extern void DbcComm_Run(DbcCommType *obj); + +/*! \brief Receive the can message + * + * This function receive the can message for dbc logic to analyze. + * + * \note IMPORTANT!!! This interface should be called in the same thread as DbcComm_Run + * + * \param[in] obj : pointer to DbcComm instance + * \param[in] node : the CAN node to receive the message + * \param[in] pMsg : the pointer to the message to receive + */ +extern void DbcComm_ReceiveCanMsg(DbcCommType *obj, DbcComm_CanNodeType node, const DbcComm_CanMsgType *pMsg); + +/*! \brief Enable/Disable RX of the node + * + * This function enables or disables the RX of the given node + * + * \param[in] obj : pointer to DbcComm instance + * \param[in] node : the node to operate + * \param[in] enable : whether to enable or disable the RX function + * - true : enable the RX + * - false : disable the RX + */ +extern void DbcComm_EnableRx(DbcCommType *obj, DbcComm_CanNodeType node, bool enable); + +/*! \brief Enable/Disable TX of the node + * + * This function enables or disables the TX of the given node + * + * \param[in] obj : pointer to DbcComm instance + * \param[in] node : the node to operate + * \param[in] enable : whether to enable or disable the TX function + * - true : enable the TX + * - false : disable the TX + */ +extern void DbcComm_EnableTx(DbcCommType *obj, DbcComm_CanNodeType node, bool enable); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _DBC_COMM_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/isotp/isotp.c b/cva_asw_m0118/SDK/middleware/isotp/isotp.c new file mode 100644 index 0000000..11b9443 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/isotp/isotp.c @@ -0,0 +1,845 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "isotp.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/*! \brief Protocol Control Information (PCI) types, for identifying each frame of an ISO-TP message. + */ +#define ISOTP_PCI_TYPE_SINGLE_FRAME (0x0) +#define ISOTP_PCI_TYPE_FIRST_FRAME (0x1) +#define ISOTP_PCI_TYPE_CONSECUTIVE_FRAME (0x2) +#define ISOTP_PCI_TYPE_FLOW_CONTROL_FRAME (0x3) + +/*! \brief Protocol Control Information (PCI) flow control identifiers. + */ +#define ISOTP_PCI_FLOW_STATUS_CONTINUE (0x0) +#define ISOTP_PCI_FLOW_STATUS_WAIT (0x1) +#define ISOTP_PCI_FLOW_STATUS_OVERFLOW (0x2) + +/* invalid bs */ +#define ISOTP_INVALID_BS 0xFFFF + +/*! \brief Network layer result code + */ +#define ISOTP_PROTOCOL_RESULT_OK (0) +#define ISOTP_PROTOCOL_RESULT_TIMEOUT_A (-1) +#define ISOTP_PROTOCOL_RESULT_TIMEOUT_BS (-2) +#define ISOTP_PROTOCOL_RESULT_TIMEOUT_CR (-3) +#define ISOTP_PROTOCOL_RESULT_WRONG_SN (-4) +#define ISOTP_PROTOCOL_RESULT_INVALID_FS (-5) +#define ISOTP_PROTOCOL_RESULT_UNEXP_PDU (-6) +#define ISOTP_PROTOCOL_RESULT_WFT_OVRN (-7) +#define ISOTP_PROTOCOL_RESULT_BUFFER_OVFLW (-8) +#define ISOTP_PROTOCOL_RESULT_ERROR (-9) + +/*! \brief Return logic true if 'a' is after 'b' + */ +#define IsoTp_TimeAfter(a, b) ((int64_t)((int64_t)(b) - (int64_t)(a)) < 0) + +#define IsoTp_SetPciType(byte, type) (byte[0] = (0xFF & ((((uint8_t)type) << 4) | 0x0f))) +#define IsoTp_GetPciType(byte) ((uint8_t)(byte[0] >> 4)) + +/*! \brief single frame + * +-------------------------+-----+ + * | byte #0 | ... | + * +-------------------------+-----+ + * | nibble #0 | nibble #1 | ... | + * +-------------+-----------+ ... + + * | PCIType = 0 | SF_DL | ... | + * +-------------+-----------+-----+ + */ +#define IsoTp_SetSFDataLen(byte, len) (byte[0] &= (((uint8_t)len) | 0xf0)) +#define IsoTp_GetSFDataLen(byte) (byte[0] & 0x0f) + +/*! \brief first frame + * +-------------------------+-----------------------+-----+ + * | byte #0 | byte #1 | ... | + * +-------------------------+-----------+-----------+-----+ + * | nibble #0 | nibble #1 | nibble #2 | nibble #3 | ... | + * +-------------+-----------+-----------+-----------+-----+ + * | PCIType = 1 | FF_DL | ... | + * +-------------+-----------+-----------------------+-----+ + */ +#define IsoTp_SetFFDataLen(byte, len) \ + do \ + { \ + byte[0] &= ((len >> 8) | 0xf0); \ + byte[1] = (len & 0xff); \ + } while(0) +#define IsoTp_GetFFDataLen(byte) (((((uint16_t)byte[0]) & 0x0f) << 8) + byte[1]) + +/*! \brief consecutive frame + * +-------------------------+-----+ + * | byte #0 | ... | + * +-------------------------+-----+ + * | nibble #0 | nibble #1 | ... | + * +-------------+-----------+ ... + + * | PCIType = 2 | SN | ... | + * +-------------+-----------+-----+ + */ +#define IsoTp_SetCFSn(byte, sn) (byte[0] &= (((uint8_t)sn) | 0xf0)) +#define IsoTp_GetCFSn(byte) (byte[0] & 0x0f) + +/*! \brief flow control frame + * +-------------------------+-----------------------+-----------------------+-----+ + * | byte #0 | byte #1 | byte #2 | ... | + * +-------------------------+-----------+-----------+-----------+-----------+-----+ + * | nibble #0 | nibble #1 | nibble #2 | nibble #3 | nibble #4 | nibble #5 | ... | + * +-------------+-----------+-----------+-----------+-----------+-----------+-----+ + * | PCIType = 1 | FS | BS | STmin | ... | + * +-------------+-----------+-----------------------+-----------------------+-----+ + */ +#define IsoTp_SetFCFlowState(byte, fs) (byte[0] &= (((uint8_t)fs) | 0xf0)) +#define IsoTp_GetFCFlowState(byte) (byte[0] & 0x0f) +#define IsoTp_SetFCBlockSize(byte, bs) (byte[1] = bs) +#define IsoTp_GetFCBlockSize(byte) (byte[1]) +#define IsoTp_SetFCStmin(byte, STmin) (byte[2] = STmin) +#define IsoTp_GetFCStmin(byte) (byte[2]) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief ISOTP sender status + */ +typedef enum +{ + ISOTP_SEND_STATUS_IDLE, + ISOTP_SEND_STATUS_INPROGRESS, + ISOTP_SEND_STATUS_ERROR, +} IsoTp_SendStatusType; + +/*! \brief ISOTP receiver status + */ +typedef enum +{ + ISOTP_RECEIVE_STATUS_IDLE, + ISOTP_RECEIVE_STATUS_INPROGRESS, + ISOTP_RECEIVE_STATUS_FULL, +} IsoTp_ReceiveStatusType; + +/*! \brief ISOTP message + */ +typedef struct _IsoTp_MsgType_ +{ + uint8_t byte[8]; +} IsoTp_MsgType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +/* st_min to microsecond */ +static uint8_t IsoTp_MsToStMin(uint8_t ms) +{ + uint8_t stMin; + + stMin = ms; + if(stMin > 0x7F) + { + stMin = 0x7F; + } + + return stMin; +} + +/* st_min to msec */ +static uint8_t IsoTp_StMinToMs(uint8_t stMin) +{ + uint8_t ms; + + if(stMin >= 0xF1 && stMin <= 0xF9) + { + ms = 1; /* Actually it should be 0.1 - 0.9 ms */ + } + else if(stMin <= 0x7F) + { + ms = stMin; + } + else + { + ms = 0; + } + + return ms; +} + +static int8_t IsoTp_SendFlowControl(IsoTpType *obj, uint8_t flow_status, uint8_t block_size, uint8_t st_min_ms) +{ + int8_t ret; + uint8_t index = 0; + IsoTp_MsgType msg; + + /* Setup message */ + IsoTp_SetPciType(msg.byte, ISOTP_PCI_TYPE_FLOW_CONTROL_FRAME); + IsoTp_SetFCFlowState(msg.byte, flow_status); + IsoTp_SetFCBlockSize(msg.byte, block_size); + IsoTp_SetFCStmin(msg.byte, IsoTp_MsToStMin(st_min_ms)); + + /* Send message */ + if(obj->framePadding) + { + /* All pad with 0 */ + for(index = 3; index < 8; ++index) + { + msg.byte[index] = 0; + } + ret = obj->sendCanMsg(obj->sendArbitrationId, msg.byte, 8); + } + else + { + ret = obj->sendCanMsg(obj->sendArbitrationId, msg.byte, 3); + } + + return ret; +} + +static int8_t IsoTp_SendSingleFrame(IsoTpType *obj) +{ + int8_t ret; + uint8_t i = 0; + uint8_t index = 0; + IsoTp_MsgType msg; + + /* Setup message */ + IsoTp_SetPciType(msg.byte, ISOTP_PCI_TYPE_SINGLE_FRAME); + IsoTp_SetSFDataLen(msg.byte, (uint8_t)obj->sendSize); + for(index = 0; index < obj->sendSize; ++index) + { + msg.byte[index + 1] = obj->sendBuffer[index]; + } + + /* Send message */ + if(obj->framePadding) + { + /* All pad with 0 */ + for(i = 0; i < 7 - obj->sendSize; ++i) + { + msg.byte[i + obj->sendSize + 1] = 0; + } + ret = obj->sendCanMsg(obj->sendArbitrationId, msg.byte, 8); + } + else + { + ret = obj->sendCanMsg(obj->sendArbitrationId, msg.byte, obj->sendSize + 1); + } + + return ret; +} + +static int8_t IsoTp_SendFirstFrame(IsoTpType *obj) +{ + int8_t ret; + IsoTp_MsgType msg; + + /* Setup message */ + IsoTp_SetPciType(msg.byte, ISOTP_PCI_TYPE_FIRST_FRAME); + IsoTp_SetFFDataLen(msg.byte, obj->sendSize); + uint8_t index = 0; + for(index = 0; index < 6; ++index) /* 6 data bytes for the first frame */ + { + msg.byte[index + 2] = obj->sendBuffer[index]; + } + + /* Send message */ + ret = obj->sendCanMsg(obj->sendArbitrationId, msg.byte, 8); + if(ISOTP_RET_OK == ret) + { + obj->sendOffset += 6; /* 6 data bytes for the first frame */ + obj->sendSN = 1; + } + + return ret; +} + +static int8_t IsoTp_SendConsecutiveFrame(IsoTpType *obj) +{ + int8_t ret; + IsoTp_MsgType msg; + uint16_t dataLength; + uint8_t index = 0; + + /* setup message */ + IsoTp_SetPciType(msg.byte, ISOTP_PCI_TYPE_CONSECUTIVE_FRAME); + IsoTp_SetCFSn(msg.byte, obj->sendSN); + dataLength = obj->sendSize - obj->sendOffset; + if(dataLength > 7) /* Max 7 data bytes for the consecutive frame */ + { + dataLength = 7; + } + for(index = 0; index < dataLength; ++index) + { + msg.byte[index + 1] = obj->sendBuffer[obj->sendOffset + index]; + } + + /* Send message */ + if(obj->framePadding) + { + /* All pad with 0 */ + uint8_t i = 0; + for(i = 0; i < 7 - dataLength; ++i) + { + msg.byte[i + 1 + dataLength] = 0; + } + ret = obj->sendCanMsg(obj->sendArbitrationId, msg.byte, 8); + } + else + { + ret = obj->sendCanMsg(obj->sendArbitrationId, msg.byte, dataLength + 1); + } + + if(ISOTP_RET_OK == ret) + { + obj->sendOffset += dataLength; + if(++(obj->sendSN) > 0x0F) + { + obj->sendSN = 0; + } + } + + return ret; +} + +static int8_t IsoTp_ReceiveSingleFrame(IsoTpType *obj, const IsoTp_MsgType *pMsg, uint8_t len) +{ + uint8_t index = 0; + + /* Check data length */ + if((0 == IsoTp_GetSFDataLen(pMsg->byte)) + || (IsoTp_GetSFDataLen(pMsg->byte) > (len - 1))) + { + if(obj->debug != NULL) + { + obj->debug("Single-frame length too small or too large."); + } + return ISOTP_RET_LENGTH; + } + + /* Copying data */ + /* polyspace-begin DEFECT:OUT_BOUND_ARRAY [No action planned:High] "Still keep default because one frame max length is 8" */ + obj->receiveSize = IsoTp_GetSFDataLen(pMsg->byte); + for(index = 0; index < obj->receiveSize; ++index) + { + obj->receiveBuffer[index] = pMsg->byte[index + 1]; + } + /* polyspace-end DEFECT:OUT_BOUND_ARRAY [No action planned:High] "Still keep default because one frame max length is 8" */ + + return ISOTP_RET_OK; +} + +static int8_t IsoTp_ReceiveFirstFrame(IsoTpType *obj, const IsoTp_MsgType *pMsg, uint8_t len) +{ + uint16_t payloadLength; + uint8_t index = 0; + + if(8 != len) + { + if(obj->debug != NULL) + { + obj->debug("First frame should be 8 bytes in length."); + } + return ISOTP_RET_LENGTH; + } + + /* Check data length */ + payloadLength = IsoTp_GetFFDataLen(pMsg->byte); + + /* Should not use multiple frame transmission */ + if(payloadLength <= 7) + { + if(obj->debug != NULL) + { + obj->debug("First frame should not use multiple frame transmission."); + } + return ISOTP_RET_LENGTH; + } + + if(payloadLength > obj->receiveBufferSize) + { + if(obj->debug != NULL) + { + obj->debug("Multi-frame response too large for receiving buffer."); + } + return ISOTP_RET_OVERFLOW; + } + + /* Copying data */ + obj->receiveSize = payloadLength; + for(index = 0; index < 6; ++index) /* 6 data bytes for the first frame */ + { + obj->receiveBuffer[index] = pMsg->byte[index + 2]; + } + obj->receiveOffset = 6; /* 6 data bytes for the first frame */ + obj->receiveSN = 1; + + return ISOTP_RET_OK; +} + +static int8_t IsoTp_ReceiveConsecutiveFrame(IsoTpType *obj, const IsoTp_MsgType *pMsg, uint8_t len) +{ + uint16_t remaining_bytes; + uint8_t index = 0; + + /* Check SN */ + if(obj->receiveSN != IsoTp_GetCFSn(pMsg->byte)) + { + return ISOTP_RET_WRONG_SN; + } + + /* Check data length */ + remaining_bytes = obj->receiveSize - obj->receiveOffset; + if(remaining_bytes > 7) /* Max 7 data bytes for the consecutive frame */ + { + remaining_bytes = 7; + } + if(remaining_bytes > len - 1) + { + if(obj->debug != NULL) + { + obj->debug("Consecutive frame too short."); + } + return ISOTP_RET_LENGTH; + } + + /* Copying data */ + for(index = 0; index < remaining_bytes; ++index) + { + obj->receiveBuffer[index + obj->receiveOffset] = pMsg->byte[index + 1]; + } + + obj->receiveOffset += remaining_bytes; + if(++(obj->receiveSN) > 0x0F) + { + obj->receiveSN = 0; + } + + return ISOTP_RET_OK; +} + +static int8_t IsoTp_ReceiveFlowControlFrame(IsoTpType *obj, const IsoTp_MsgType *pMsg, uint8_t len) +{ + /* Check message length */ + if(len < 3) + { + if(obj->debug != NULL) + { + obj->debug("Flow control frame too short."); + } + return ISOTP_RET_LENGTH; + } + + return ISOTP_RET_OK; +} + +int8_t IsoTp_Send(IsoTpType *obj, const uint8_t payload[], uint16_t size) +{ + return IsoTp_SendWithId(obj, obj->sendArbitrationId, payload, size); +} + +int8_t IsoTp_SendWithId(IsoTpType *obj, uint32_t id, const uint8_t payload[], uint16_t size) +{ + int8_t ret; + uint8_t i = 0; + + if(obj == NULL) + { + return ISOTP_RET_ERROR; + } + + if(size > obj->sendBufferSize) + { + if(obj->debug != NULL) + { + obj->debug("Message size too large. Set a larger send buffer\n"); + } + return ISOTP_RET_OVERFLOW; + } + + if(ISOTP_SEND_STATUS_INPROGRESS == obj->sendStatus) + { + if(obj->debug != NULL) + { + obj->debug("Abort previous message, transmission in progress.\n"); + } + return ISOTP_RET_INPROGRESS; + } + + /* Copy into local buffer */ + obj->sendSize = size; + obj->sendOffset = 0; + for(i = 0; i < size; ++i) + { + obj->sendBuffer[i] = payload[i]; + } + + if(obj->sendSize < 8) + { + /* Send single frame */ + ret = IsoTp_SendSingleFrame(obj); + } + else + { + /* Send multiple frames */ + ret = IsoTp_SendFirstFrame(obj); + + /* Initialize multi-frame control flags */ + if(ISOTP_RET_OK == ret) + { + obj->sendBsRemain = 0; + obj->sendSTMin = 0; + obj->sendWaitFrameCount = 0; + obj->sendTimerSeptime = obj->getTimeMs(); + /* Refresh BS timer */ + obj->sendTimerBlockSize = obj->getTimeMs() + ISOTP_DEFAULT_RESPONSE_TIMEOUT; + obj->sendProtocolResult = ISOTP_PROTOCOL_RESULT_OK; + obj->sendStatus = ISOTP_SEND_STATUS_INPROGRESS; + } + } + /* polyspace-end DEFECT:NULL_PTR [No action planned:High] "Still keep default because the null pointer is handled" */ + + return ret; +} + +void IsoTp_HandleIncomingCanMsg(IsoTpType *obj, uint32_t id, const uint8_t *data, uint8_t len) +{ + int8_t ret; + IsoTp_MsgType msg; + + if(len < 2 || len > 8) + { + return; + } + + uint8_t i = 0; + for(i = 0; i < len; ++i) + { + msg.byte[i] = data[i]; + } + for(i = 0; i < 8 - len; ++i) /* len will NOT > 8 */ + { + msg.byte[i + len] = 0; /* Padding */ + } + + switch(IsoTp_GetPciType(msg.byte)) + { + case ISOTP_PCI_TYPE_SINGLE_FRAME: + { + /* Update protocol result */ + if(ISOTP_RECEIVE_STATUS_INPROGRESS == obj->receiveStatus) + { + obj->receiveProtocolResult = ISOTP_PROTOCOL_RESULT_UNEXP_PDU; + } + else + { + obj->receiveProtocolResult = ISOTP_PROTOCOL_RESULT_OK; + } + + /* Handle message */ + ret = IsoTp_ReceiveSingleFrame(obj, &msg, len); + + if(ISOTP_RET_OK == ret) + { + obj->receiveArbitrationId = id; + /* Change status */ + obj->receiveStatus = ISOTP_RECEIVE_STATUS_FULL; + } + break; + } + case ISOTP_PCI_TYPE_FIRST_FRAME: + { + /* Update protocol result */ + if(ISOTP_RECEIVE_STATUS_INPROGRESS == obj->receiveStatus) + { + obj->receiveProtocolResult = ISOTP_PROTOCOL_RESULT_UNEXP_PDU; + } + else + { + obj->receiveProtocolResult = ISOTP_PROTOCOL_RESULT_OK; + } + + /* Handle message */ + ret = IsoTp_ReceiveFirstFrame(obj, &msg, len); + + /* If overflow happened */ + if(ISOTP_RET_OVERFLOW == ret) + { + /* Update protocol result */ + obj->receiveProtocolResult = ISOTP_PROTOCOL_RESULT_BUFFER_OVFLW; + /* Change status */ + obj->receiveStatus = ISOTP_RECEIVE_STATUS_IDLE; + /* Send error message */ + IsoTp_SendFlowControl(obj, ISOTP_PCI_FLOW_STATUS_OVERFLOW, 0, 0); + break; + } + + /* If receive successful */ + if(ISOTP_RET_OK == ret) + { + obj->receiveArbitrationId = id; + /* Change status */ + obj->receiveStatus = ISOTP_RECEIVE_STATUS_INPROGRESS; + /* Send FC frame */ + obj->receiveBlockSizeCount = obj->blockSize; + IsoTp_SendFlowControl(obj, ISOTP_PCI_FLOW_STATUS_CONTINUE, obj->receiveBlockSizeCount, ISOTP_DEFAULT_ST_MIN); + /* Refresh timer CR */ + obj->receiveTimerCr = obj->getTimeMs() + ISOTP_DEFAULT_RESPONSE_TIMEOUT; + } + + break; + } + case ISOTP_PCI_TYPE_CONSECUTIVE_FRAME: + { + /* Check if in receiving status */ + if(ISOTP_RECEIVE_STATUS_INPROGRESS != obj->receiveStatus) + { + obj->receiveProtocolResult = ISOTP_PROTOCOL_RESULT_UNEXP_PDU; + break; + } + + if(id != obj->receiveArbitrationId) + { + break; + } + + /* Handle message */ + ret = IsoTp_ReceiveConsecutiveFrame(obj, &msg, len); + + /* If wrong SN */ + if(ISOTP_RET_WRONG_SN == ret) + { + obj->receiveProtocolResult = ISOTP_PROTOCOL_RESULT_WRONG_SN; + obj->receiveStatus = ISOTP_RECEIVE_STATUS_IDLE; + break; + } + + /* If success */ + if(ISOTP_RET_OK == ret) + { + /* Refresh timer CR */ + obj->receiveTimerCr = obj->getTimeMs() + ISOTP_DEFAULT_RESPONSE_TIMEOUT; + + /* Receive finished */ + if(obj->receiveOffset >= obj->receiveSize) + { + obj->receiveStatus = ISOTP_RECEIVE_STATUS_FULL; + } + else + { + /* Send FC when BS reaches limit */ + if(obj->blockSize > 0) + { + if(0 == --obj->receiveBlockSizeCount) + { + obj->receiveBlockSizeCount = obj->blockSize; + IsoTp_SendFlowControl(obj, ISOTP_PCI_FLOW_STATUS_CONTINUE, obj->receiveBlockSizeCount, ISOTP_DEFAULT_ST_MIN); + } + } + } + } + + break; + } + case ISOTP_PCI_TYPE_FLOW_CONTROL_FRAME: + { + /* Handle fc frame only when sending in progress */ + if(ISOTP_SEND_STATUS_INPROGRESS != obj->sendStatus) + { + break; + } + + /* Handle message */ + ret = IsoTp_ReceiveFlowControlFrame(obj, &msg, len); + + if(ISOTP_RET_OK == ret) + { + /* Refresh BS timer */ + obj->sendTimerBlockSize = obj->getTimeMs() + ISOTP_DEFAULT_RESPONSE_TIMEOUT; + + /* Overflow */ + if(ISOTP_PCI_FLOW_STATUS_OVERFLOW == IsoTp_GetFCFlowState(msg.byte)) + { + obj->sendProtocolResult = ISOTP_PROTOCOL_RESULT_BUFFER_OVFLW; + obj->sendStatus = ISOTP_SEND_STATUS_ERROR; + } + + /* Wait */ + else if(ISOTP_PCI_FLOW_STATUS_WAIT == IsoTp_GetFCFlowState(msg.byte)) + { + obj->sendWaitFrameCount += 1; + /* Wait exceed allowed count */ + if(obj->sendWaitFrameCount > ISOTP_MAX_WFT_NUMBER) + { + obj->sendProtocolResult = ISOTP_PROTOCOL_RESULT_WFT_OVRN; + obj->sendStatus = ISOTP_SEND_STATUS_ERROR; + } + } + + /* Permit send */ + else if(ISOTP_PCI_FLOW_STATUS_CONTINUE == IsoTp_GetFCFlowState(msg.byte)) + { + if(0 == IsoTp_GetFCBlockSize(msg.byte)) + { + obj->sendBsRemain = ISOTP_INVALID_BS; + } + else + { + obj->sendBsRemain = IsoTp_GetFCBlockSize(msg.byte); + } + obj->sendSTMin = IsoTp_StMinToMs(IsoTp_GetFCStmin(msg.byte)); + obj->sendWaitFrameCount = 0; + } + } + break; + } + default: + break; + }; + + return; +} + +int8_t IsoTp_Receive(IsoTpType *link, bool *IsFuncAddr, uint8_t *payload, uint16_t payload_size, uint16_t *out_size) +{ + uint16_t copylen; + uint16_t i = 0; + + if(ISOTP_RECEIVE_STATUS_FULL != link->receiveStatus) + { + return ISOTP_RET_NO_DATA; + } + + *IsFuncAddr = (link->receiveArbitrationId == link->funcId) ? true : false; + + copylen = link->receiveSize; + if(copylen > payload_size) + { + copylen = payload_size; + } + + for(i = 0; i < copylen; ++i) + { + payload[i] = link->receiveBuffer[i]; + } + *out_size = copylen; + + link->receiveStatus = ISOTP_RECEIVE_STATUS_IDLE; + + return ISOTP_RET_OK; +} + +void IsoTp_Init(IsoTpType *obj, const IsoTp_Params *pParams) +{ + obj->framePadding = pParams->framePadding; + obj->blockSize = pParams->blockSize; + obj->physId = pParams->recvPhysId; + obj->funcId = pParams->recvFuncId; + obj->sendArbitrationId = pParams->sendid; + obj->sendBuffer = pParams->sendBuf; + obj->sendBufferSize = pParams->sendBufSize; + obj->sendSize = 0; + obj->sendOffset = 0; + obj->sendSN = 0; + obj->sendBsRemain = 0; + obj->sendSTMin = 0; + obj->sendWaitFrameCount = 0; + obj->sendTimerSeptime = 0; + obj->sendTimerBlockSize = 0; + obj->sendProtocolResult = 0; + obj->sendStatus = ISOTP_SEND_STATUS_IDLE; + obj->receiveBuffer = pParams->recvBuf; + obj->receiveBufferSize = pParams->recvBufSize; + obj->receiveSize = 0; + obj->receiveOffset = 0; + obj->receiveSN = 0; + obj->receiveBlockSizeCount = 0; + obj->receiveTimerCr = 0; + obj->receiveProtocolResult = ISOTP_PROTOCOL_RESULT_OK; + obj->receiveStatus = ISOTP_RECEIVE_STATUS_IDLE; + + obj->debug = pParams->debug; + obj->sendCanMsg = pParams->sendCanMsg; + obj->getTimeMs = pParams->getTimeMs; +} + +void IsoTp_Poll(IsoTpType *obj) +{ + int8_t ret; + + /* Only polling when operation in progress */ + if(ISOTP_SEND_STATUS_INPROGRESS == obj->sendStatus) + { + /* Continue send data */ + if((ISOTP_INVALID_BS == obj->sendBsRemain || obj->sendBsRemain > 0) /* send data if bs_remain is invalid or bs_remain large than zero */ + && (0 == obj->sendSTMin || (0 != obj->sendSTMin && IsoTp_TimeAfter(obj->getTimeMs(), obj->sendTimerSeptime)))) + { /* st_min is zero or go beyond interval time */ + ret = IsoTp_SendConsecutiveFrame(obj); + if(ISOTP_RET_OK == ret) + { + if(ISOTP_INVALID_BS != obj->sendBsRemain) + { + obj->sendBsRemain -= 1; + } + /* Refresh BS timer */ + obj->sendTimerBlockSize = obj->getTimeMs() + ISOTP_DEFAULT_RESPONSE_TIMEOUT; + obj->sendTimerSeptime = obj->getTimeMs() + obj->sendSTMin; + + /* Check if send finish */ + if(obj->sendOffset >= obj->sendSize) + { + obj->sendStatus = ISOTP_SEND_STATUS_IDLE; + } + } + else + { + obj->sendStatus = ISOTP_SEND_STATUS_ERROR; + } + } + + /* Check timeout */ + if(IsoTp_TimeAfter(obj->getTimeMs(), obj->sendTimerBlockSize)) + { + obj->sendProtocolResult = ISOTP_PROTOCOL_RESULT_TIMEOUT_BS; + obj->sendStatus = ISOTP_SEND_STATUS_ERROR; + } + } + + /* Only polling when operation in progress */ + if(ISOTP_RECEIVE_STATUS_INPROGRESS == obj->receiveStatus) + { + /* check timeout */ + if(IsoTp_TimeAfter(obj->getTimeMs(), obj->receiveTimerCr)) + { + obj->receiveProtocolResult = ISOTP_PROTOCOL_RESULT_TIMEOUT_CR; + obj->receiveStatus = ISOTP_RECEIVE_STATUS_IDLE; + } + } + + return; +} diff --git a/cva_asw_m0118/SDK/middleware/isotp/isotp.h b/cva_asw_m0118/SDK/middleware/isotp/isotp.h new file mode 100644 index 0000000..c485b89 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/isotp/isotp.h @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _ISOTP_H_ +#define _ISOTP_H_ + +/*! \brief Contains public interface to various functions related + * to the ISO TP (ISO 15765-2) + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/*! \brief Defines all the return values + */ +#define ISOTP_RET_OK (0) +#define ISOTP_RET_ERROR (-1) +#define ISOTP_RET_INPROGRESS (-2) +#define ISOTP_RET_OVERFLOW (-3) +#define ISOTP_RET_WRONG_SN (-4) +#define ISOTP_RET_NO_DATA (-5) +#define ISOTP_RET_TIMEOUT (-6) +#define ISOTP_RET_LENGTH (-7) + +/*! \brief The default timeout to use when waiting for a response during a multi-frame send or receive. + */ +#define ISOTP_DEFAULT_RESPONSE_TIMEOUT (100) + +/*! \brief The STmin parameter value specifies the minimum time gap allowed between + * the transmission of consecutive frame network protocol data units + */ +#define ISOTP_DEFAULT_ST_MIN (1) + +/*! \brief This parameter indicate how many FC N_PDU WTs can be transmitted by the + * receiver in a row. + */ +#define ISOTP_MAX_WFT_NUMBER (1) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The declaration of the buffer used for both send and receive + */ +typedef uint8_t *IsoTp_Buffer; + +/*! \brief User implemented, print debug message + */ +typedef void (*IsoTp_DebugShim)(const char *message, ...); + +/*! \brief User implemented, send can message + */ +typedef int8_t (*IsoTp_SendCanMsgShim)(const uint32_t arbitrationId, const uint8_t *pData, const uint8_t size); + +/*! \brief User implemented, get millisecond + */ +typedef int64_t (*IsoTp_GetTimeShimMs)(void); + +/*! \brief Defines all the parameters used to initialize ISOTP object + */ +typedef struct _IsoTp_Params_ +{ + bool framePadding; + uint8_t blockSize; + uint32_t recvPhysId; + uint32_t recvFuncId; + uint32_t sendid; + uint8_t *sendBuf; + uint16_t sendBufSize; + uint8_t *recvBuf; + uint16_t recvBufSize; + IsoTp_DebugShim debug; + IsoTp_SendCanMsgShim sendCanMsg; + IsoTp_GetTimeShimMs getTimeMs; +} IsoTp_Params; + +/*! \brief Structure containing the data for linking an application to a CAN instance. + * The data stored in this structure is used internally and may be used by software programs + * using this library. + */ +typedef struct _IsoTpType_ +{ + bool framePadding; /*!< whether need frame padding */ + uint8_t blockSize; /*!< Max number of messages the receiver can receive at one time, this value is affected by CAN driver queue length */ + + uint32_t physId; /*!< physical addressing id */ + uint32_t funcId; /*!< functional addressing id */ + + uint32_t sendArbitrationId; /*! used to reply consecutive frame */ + IsoTp_Buffer sendBuffer; /*!< send buffer */ + uint16_t sendBufferSize; /*!< the size of send buffer */ + uint16_t sendSize; /*!< the size of data to send */ + uint16_t sendOffset; /*!< the offset of current send process */ + + uint8_t sendSN; /*!< serial number of send message */ + uint16_t sendBsRemain; /*!< Remaining block size */ + uint8_t sendSTMin; /*!< Separation Time between consecutive frames, unit millisecond */ + uint8_t sendWaitFrameCount; /*!< Maximum number of FC.Wait frame transmissions */ + int64_t sendTimerSeptime; /*!< Last time send consecutive frame */ + int64_t sendTimerBlockSize; /*!< Time until transmission of the next FlowControl N_PDU start at sending FF, CF, receive FC end at receive FC */ + int sendProtocolResult; /*!< the result of send protocol */ + uint8_t sendStatus; /*!< the send status */ + + uint32_t receiveArbitrationId; /*! used to determine whether physical or functional addressing */ + IsoTp_Buffer receiveBuffer; /*!< message receive buffer */ + uint16_t receiveBufferSize; /*!< the size of RX buffer */ + uint16_t receiveSize; /*!< the size to receive */ + uint16_t receiveOffset; /*!< the offset of receive process */ + + uint8_t receiveSN; /*!< serial number of receive message */ + uint8_t receiveBlockSizeCount; /*!< Maximum number of FC.Wait frame transmissions */ + int64_t receiveTimerCr; /*!< Time until reception of the next ConsecutiveFrame N_PDU start at sending FC, receive CF end at receive FC */ + int8_t receiveProtocolResult; /*!< the result of receive protocol */ + uint8_t receiveStatus; /*!< the receive status */ + + IsoTp_DebugShim debug; /*!< the adapter of debug function */ + IsoTp_SendCanMsgShim sendCanMsg; /*!< the adapter of can-send-message function */ + IsoTp_GetTimeShimMs getTimeMs; /*!< the adapter of get-time-stamp function */ + +} IsoTpType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the ISO-TP library. + * + * This function intiliaze the ISO-TP instance + * + * \param[in] obj : pointer to ISOTP instance + * \param[in] pParams : pointer to the initialization parameters + */ +extern void IsoTp_Init(IsoTpType *obj, const IsoTp_Params *pParams); + +/*! \brief Polling function + * + * Call this function periodically to handle timeouts, send consecutive frames, etc. + * + * \param[in] obj : pointer to ISOTP instance + */ +extern void IsoTp_Poll(IsoTpType *obj); + +/*! \brief Handles incoming CAN messages. + * + * Determines whether an incoming message is a valid ISO-TP frame or not and handles it accordingly. + * + * \param[in] obj : pointer to ISOTP instance + * \param[in] id : the incoming CAN frame ID + * \param[in] pData : pointer to data of incoming CAN frame + * \param[in] len : the length of data of incoming CAN frame + */ +extern void IsoTp_HandleIncomingCanMsg(IsoTpType *obj, uint32_t id, const uint8_t *pData, uint8_t len); + +/*! \brief Sends ISO-TP frames via CAN, using the ID set in the initializing function. + * + * Single-frame messages will be sent immediately when calling this function. + * Multi-frame messages will be sent consecutively when calling isotp_poll. + * + * \param[in] obj : pointer to ISOTP instance + * \param[in] pPayload : the incoming CAN frame ID + * \param[in] size : pointer to data of incoming CAN frame + */ +extern int8_t IsoTp_Send(IsoTpType *obj, const uint8_t pPayload[], uint16_t size); + +/*! \brief Send with message ID + * + * With the exception that this function is used only for functional addressing. + * + * \param[in] obj : pointer to ISOTP instance + * \param[in] id : the message ID to send + * \param[in] pPayload : pointer to data to send + * \param[in] size : the size of data to send + */ +extern int8_t IsoTp_SendWithId(IsoTpType *obj, uint32_t id, const uint8_t pPayload[], uint16_t size); + +/*! \brief Receives and parses the received data and copies the parsed data in to the internal buffer. + * + * This function receives and parses the received data and copies the parsed data in to the internal buffer. + * + * \param[in] obj : pointer to ISOTP instance + * \param[out] IsFuncAddr : pointer the result of whether is functional addressing + * \param[out] pPayload : pointer to the payload + * \param[in] payloadSize : the payload size + * \param[out] pOutSize : the size of actual output payload + */ +extern int8_t IsoTp_Receive(IsoTpType *obj, bool *IsFuncAddr, uint8_t *pPayload, uint16_t payloadSize, uint16_t *pOutSize); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _ISOTP_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/nvm/fee/fee.c b/cva_asw_m0118/SDK/middleware/nvm/fee/fee.c new file mode 100644 index 0000000..1443226 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/fee/fee.c @@ -0,0 +1,893 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "fee.h" +#include "fee_initialization.h" +#include "fee_trace.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/*! \brief Macro for the start address of the block data + */ +#define FEE_BLOCK_DATA_START_ADDR (((Fee_AddressType)obj->runtime->activeSector->startAddr) + FEE_SECTOR_HEAD_SIZE) + +/*! \brief Macro for the end address of the block data + */ +#define FEE_BLOCK_DATA_ADDR (obj->runtime->activeSector->endAddr) + +/*! \brief Macro for the start address of the block info + */ +#define FEE_BLOCK_INFO_START_ADDR (((Fee_AddressType)obj->runtime->activeSector->endAddr) - FEE_SECTOR_HEAD_SIZE - FEE_BLOCK_HEAD_INFO_SIZE) + +/*! \brief Macro for the end address of the block info + */ +#define FEE_BLOCK_INFO_END_ADDR (obj->runtime->activeSector->startAddr + FEE_SECTOR_HEAD_SIZE) + +/*! \brief Get a macro for a block object + */ +#define Fee_GetBlock(obj, idx) (&obj->blocks[idx]) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the static + ******************************************************************************/ +static bool Fee_OnEntryRetrievalJob(const FeeType *obj); +static void Fee_ExitRetrievalJob(const FeeType *obj); +static bool Fee_RetrievalActiveSector(const FeeType *obj); +static bool Fee_ReadJob(const FeeType *obj); +static bool Fee_WriteJob(const FeeType *obj); +static void FEE_OnEntryGcJob(const FeeType *obj); +static bool Fee_GcJob(const FeeType *obj); +static void Fee_OnEntryGcCopyJob(const FeeType *obj); +static bool Fee_GcCopyJob(const FeeType *obj); +static bool Fee_GcInitBlockInfo(const FeeType *obj, const Fee_BlockType *block); +static bool Fee_GcWriteBlockToNewSector(const FeeType *obj); +static const Fee_SectorConfigType *Fee_FoundBackupSector(const FeeType *obj); +static uint16_t Fee_SearchBlock(const Fee_SectorType *obj, uint16_t blockNumber); + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void Fee_Configure(const FeeType *obj) +{ + /* Initialize system job request. */ + Fee_InitJob(obj->runtime->jobs->sysJob); + + /* Initialize user job request. */ + Fee_InitJob(obj->runtime->jobs->userJob); + + /* Initialize to reject request status. */ + obj->runtime->jobs->accept = false; + + /* Initialize the status of the main function. */ + obj->runtime->mainFunFsm = FEE_MAIN_FUN_FSM_INITIALIZATION; + + Fee_EntryInitialization(obj); +} + +void Fee_MainFunction(const FeeType *obj) +{ + switch(obj->runtime->mainFunFsm) + { + case FEE_MAIN_FUN_FSM_INITIALIZATION: + { + if(Fee_InitializationJob(obj)) + { + if(Fee_OnEntryRetrievalJob(obj)) + { + obj->runtime->mainFunFsm = FEE_MAIN_FUN_FSM_RETRIEVAL; + } + else + { + obj->runtime->mainFunFsm = FEE_MAIN_FUN_FSM_ERROR; + } + } + break; + } + case FEE_MAIN_FUN_FSM_RETRIEVAL: + { + if(Fee_RetrievalActiveSector(obj)) + { + Fee_ExitRetrievalJob(obj); + Fee_EnableJobs(obj->runtime->jobs); + obj->runtime->mainFunFsm = FEE_MAIN_FUN_FSM_IDLE; + } + break; + } + case FEE_MAIN_FUN_FSM_IDLE: + { + if(Fee_GetSysJob(obj->runtime->jobs, obj->runtime->job)) + { + if(obj->runtime->job->op == FEE_JOB_OP_GC) + { + FEE_OnEntryGcJob(obj); + } + } + else if(Fee_GetUserJob(obj->runtime->jobs, obj->runtime->job)) + { + if(obj->runtime->job->op == FEE_JOB_OP_READ) + { + obj->runtime->mainFunFsm = FEE_MAIN_FUN_FSM_READ; + } + else if(obj->runtime->job->op == FEE_JOB_OP_WRITE) + { + obj->runtime->mainFunFsm = FEE_MAIN_FUN_FSM_WRITE; + } + else + { + /* Do nothing. */ + } + } + break; + } + case FEE_MAIN_FUN_FSM_READ: + { + /* polyspace-begin DEFECT:USELESS_IF [ Not a defect: Medium ] "Ensure consistent code style between top and bottom." */ + if(Fee_ReadJob(obj)) + { + /* Clear current request job. */ + Fee_InitJob(obj->runtime->jobs->userJob); + obj->runtime->mainFunFsm = FEE_MAIN_FUN_FSM_IDLE; + } + /* polyspace-end DEFECT:USELESS_IF [ Not a defect: Medium ] "Ensure consistent code style between top and bottom." */ + break; + } + case FEE_MAIN_FUN_FSM_WRITE: + { + /* polyspace-begin DEFECT:USELESS_IF [ Not a defect: Medium ] "Ensure consistent code style between top and bottom." */ + if(Fee_WriteJob(obj)) + { + /* Clear current request job. */ + Fee_InitJob(obj->runtime->jobs->userJob); + obj->runtime->mainFunFsm = FEE_MAIN_FUN_FSM_IDLE; + } + /* polyspace-end DEFECT:USELESS_IF [ Not a defect: Medium ] "Ensure consistent code style between top and bottom." */ + break; + } + case FEE_MAIN_FUN_FSM_GC: + { + if(Fee_GcJob(obj)) + { + /* Clear current request job. */ + Fee_InitJob(obj->runtime->jobs->sysJob); + + if(FEE_GC_ERROR == obj->runtime->gcRuntime->gcFsm) + { + Fee_EntryInitialization(obj); + obj->runtime->mainFunFsm = FEE_MAIN_FUN_FSM_INITIALIZATION; + } + else if(FEE_GC_FINISH == obj->runtime->gcRuntime->gcFsm) + { + obj->runtime->mainFunFsm = FEE_MAIN_FUN_FSM_IDLE; + } + } + break; + } + default: + { + FEE_DBG_MAIN_FSM_ERROR_ENTRY(); + break; + } + } +} + +Fee_ReturnType Fee_Read(const FeeType *obj, uint16_t blockNumber, uint16_t blockOffset, uint8_t *dataBuffer, NotificationPtrType notificationPtr) +{ + Fee_ReturnType ret = FEE_RETURN_NOT_OK; + Fee_JobControlBlockType config; + uint16_t blockIdx; + + /* Find the index of the block. */ + blockIdx = Fee_SearchBlock(obj->sector, blockNumber); + + /* Check whether the index is invalid. */ + if(FEE_INVALID_BLOCK_INDEX != blockIdx) + { + /* Initialize read request configuration. */ + config.blockIdx = blockIdx; + config.blockOffset = blockOffset; + config.dataBuffPtr = dataBuffer; + config.notificationPtr = notificationPtr; + config.op = FEE_JOB_OP_READ; + config.lock = FEE_JOB_LOCK; + + /* Check if there is already a request. */ + if(false == Fee_QueryUserJobIsLock(obj->runtime->jobs)) + { + /* Configuration Request. */ + if(Fee_SetUserJob(obj->runtime->jobs, &config)) + { + /* Configure job Status. */ + obj->runtime->jobResult = FEE_JOB_RESULT_PENDING; + ret = FEE_RETURN_OK; + } + } + } + else + { + /* Configure job Status. */ + obj->runtime->jobResult = FEE_JOB_RESULT_BL_INVALID; + } + return ret; +} + +Fee_ReturnType Fee_Write(const FeeType *obj, uint16_t blockNumber, uint8_t *dataBuffer, NotificationPtrType notificationPtr) +{ + Fee_ReturnType ret = FEE_RETURN_NOT_OK; + Fee_JobControlBlockType config; + uint16_t blockIdx; + + /* Find the index of the block. */ + blockIdx = Fee_SearchBlock(obj->sector, blockNumber); + + /* Check whether the index is invalid. */ + if(0xFFFF != blockIdx) + { + /* Check whether the remaining space is sufficient for storage. */ + if(Fee_CheckRemSpace(obj->runtime->activeSector, Fee_GetBlock(obj->sector, blockIdx))) + { + /* Initialize write request configuration. */ + config.blockIdx = blockIdx; + config.dataBuffPtr = dataBuffer; + config.notificationPtr = notificationPtr; + config.op = FEE_JOB_OP_WRITE; + config.lock = FEE_JOB_LOCK; + + /* Check if there is already a request. */ + if(false == Fee_QueryUserJobIsLock(obj->runtime->jobs)) + { + /* Configuration User Request. */ + if(Fee_SetUserJob(obj->runtime->jobs, &config)) + { + /* Configure job Status. */ + obj->runtime->jobResult = FEE_JOB_RESULT_PENDING; + ret = FEE_RETURN_OK; + } + } + } + else + { + /* Configure Request Recycling. */ + config.op = FEE_JOB_OP_GC; + + /* Check if there are already system requests. */ + if(false == Fee_QuerySysJobIsLock(obj->runtime->jobs)) + { + /* Configuration System Request. */ + Fee_SetSysJob(obj->runtime->jobs, &config); + } + } + } + else + { + obj->runtime->jobResult = FEE_JOB_RESULT_BL_INVALID; + } + + return ret; +} + +Fee_JobResultType Fee_GetJobResult(const FeeType *obj) +{ + return obj->runtime->jobResult; +} + +Fee_StatusType Fee_GetStatus(const FeeType *obj) +{ + Fee_StatusType ret = FEE_STATUS_UNKNOW; + + if(FEE_MAIN_FUN_FSM_GC == obj->runtime->mainFunFsm) + { + ret = FEE_STATUS_GC; + } + else if(FEE_MAIN_FUN_FSM_READ == obj->runtime->mainFunFsm) + { + ret = FEE_STATUS_READ; + } + else if(FEE_MAIN_FUN_FSM_WRITE == obj->runtime->mainFunFsm) + { + ret = FEE_STATUS_WRITE; + } + else if(FEE_MAIN_FUN_FSM_IDLE == obj->runtime->mainFunFsm) + { + ret = FEE_STATUS_IDLE; + } + else if(FEE_MAIN_FUN_FSM_ERROR == obj->runtime->mainFunFsm) + { + ret = FEE_STATUS_ERROR; + } + else if(FEE_MAIN_FUN_FSM_INITIALIZATION == obj->runtime->mainFunFsm) + { + ret = FEE_STATUS_UNINIT; + } + else if(FEE_MAIN_FUN_FSM_RETRIEVAL == obj->runtime->mainFunFsm) + { + ret = FEE_STATUS_UNINIT; + } + else + { + ret = FEE_STATUS_UNKNOW; + } + + return ret; +} + +void Fee_GetVersionInfo(Fee_VersionInfoType *versionInfoPtr) +{ + if(NULL != versionInfoPtr) + { + versionInfoPtr->sw_major_version = FEE_SW_MAJOR_VERSION; + versionInfoPtr->sw_minor_version = FEE_SW_MINOR_VERSION; + versionInfoPtr->sw_patch_version = FEE_SW_PATCH_VERSION; + } +} + +static bool Fee_OnEntryRetrievalJob(const FeeType *obj) +{ + bool ret = false; + int blockIdx; + + if(NULL != obj) + { + if(NULL != obj->runtime->activeSector) + { + /* Initialize the block index table. */ + for(blockIdx = 0; blockIdx < obj->sector->blockSize; blockIdx++) + { + Fee_BlockSetPhyAddr(obj->sector->blocks[blockIdx].info, NULL); + } + + /* The variable search points to the bottom of the sector. */ + obj->runtime->activeSector->info->searchAddr = FEE_BLOCK_INFO_START_ADDR; + /* Prepare to find the starting address of the remaining space. */ + obj->runtime->activeSector->info->remAddr = FEE_BLOCK_DATA_START_ADDR; + /* Return true. */ + ret = true; + } + } + return ret; +} + +static void Fee_ExitRetrievalJob(const FeeType *obj) +{ + /* Find the starting address of the remaining space. */ + for(; FLS_STATE_NOT_WRITABLE == obj->flsMethod->isWriteable(obj->runtime->activeSector->info->remAddr, Fee_BLOCK_WRITE_ALIGNED_SIZE); obj->runtime->activeSector->info->remAddr += Fee_BLOCK_WRITE_ALIGNED_SIZE) + { + } +} + +static bool Fee_RetrievalActiveSector(const FeeType *obj) +{ + bool ret = false; + const Fee_BlockType *block = NULL; + + /* Check the range of index addresses. */ + if(obj->runtime->activeSector->info->searchAddr > FEE_BLOCK_INFO_END_ADDR) + { + /* Check whether the flash space is not writable. */ + if(FLS_STATE_NOT_WRITABLE == obj->flsMethod->isWriteable(obj->runtime->activeSector->info->searchAddr, FEE_BLOCK_HEAD_INFO_SIZE)) + { + /* Read flash data. */ + if(FLS_STATE_OK == obj->flsMethod->read(obj->runtime->activeSector->info->searchAddr, (uint8_t *)obj->buff, FEE_BLOCK_HEAD_INFO_SIZE)) + { + /* Analyze the data and find the described block configuration. */ + block = Fee_MatchBlock(obj->sector, obj->flsMethod, (uint8_t *)obj->buff); + + /* If the block points to a null pointer, no matching block was found. */ + if(NULL != block) + { + /* Create a block index table. */ + Fee_BlockSetPhyAddr(block->info, Fee_GetBlockHeadPhyAddr((uint8_t *)obj->buff)); + obj->runtime->activeSector->info->remAddr = block->info->phyAddr + FEE_BLOCKSIZE(block->cfg); + } + } + + /* Point to the next block info. */ + obj->runtime->activeSector->info->searchAddr -= FEE_BLOCK_HEAD_INFO_SIZE; + } + else + { + /* If a writable flash address is found, the traversal is considered complete. */ + obj->runtime->activeSector->info->headInfoAddr = obj->runtime->activeSector->info->searchAddr; + ret = true; + } + } + else + { + FEE_DBG_STORAGE_ERROR_ENTRY(); + } + + return ret; +} + +static bool Fee_ReadJob(const FeeType *obj) +{ + bool ret = true; + Fee_NotificationType notificationRet = FEE_JOBERRORNOTIFICATION; + const Fee_BlockType *block; + + /* Reset job processing status. */ + obj->runtime->jobResult = FEE_JOB_RESULT_NOT_OK; + + /* Get block configuration. */ + block = Fee_GetBlock(obj->sector, obj->runtime->job->blockIdx); + + /* Check whether the block configuration is valid. */ + if(block != NULL) + { + /* Check whether the block has been assigned a flash address. */ + if(NULL != block->info->phyAddr) + { + /* Check the validity of the data stored on the flash by the block. */ + if(FLS_STATE_OK == obj->flsMethod->read(block->info->phyAddr, obj->runtime->job->dataBuffPtr, FEE_BLOCKSIZE(block->cfg))) + { + obj->runtime->jobResult = FEE_JOB_RESULT_OK; + notificationRet = FEE_JOBENDNOTIFICATION; + } + else + { + obj->runtime->jobResult = FEE_JOB_RESULT_BL_INCONSISTENT; + } + } + else + { + obj->runtime->jobResult = FEE_JOB_RESULT_BL_INVALID; + } + } + + /* Callback notification function. */ + if(obj->runtime->job->notificationPtr != NULL) + { + obj->runtime->job->notificationPtr(notificationRet); + } + + return ret; +} + +static bool Fee_WriteJob(const FeeType *obj) +{ + bool ret = true; + Fee_NotificationType notificationRet = FEE_JOBERRORNOTIFICATION; + const Fee_BlockType *block; + uint16_t blocksize; + Fee_AddressType tempPhyAddr; + + /* Reset job processing status. */ + obj->runtime->jobResult = FEE_JOB_RESULT_NOT_OK; + + block = Fee_GetBlock(obj->sector, obj->runtime->job->blockIdx); + + if(NULL != block) + { + blocksize = FEE_BLOCKSIZE(block->cfg); + + /* First write the block data to the flash, ensure safe writing, and then write the block header information. */ + if(FLS_STATE_OK == obj->flsMethod->write(obj->runtime->activeSector->info->remAddr, obj->runtime->job->dataBuffPtr, blocksize)) + { + tempPhyAddr = block->info->phyAddr; + Fee_BlockSetPhyAddr(block->info, obj->runtime->activeSector->info->remAddr); + Fee_WriteBlockHeadInfo(block, obj->flsMethod->crc8, (uint8_t *)obj->buff); + if(FLS_STATE_OK == obj->flsMethod->write(obj->runtime->activeSector->info->headInfoAddr, obj->buff, FEE_BLOCK_HEAD_INFO_SIZE)) + { + obj->runtime->jobResult = FEE_JOB_RESULT_OK; + notificationRet = FEE_JOBENDNOTIFICATION; + } + else + { + block->info->phyAddr = tempPhyAddr; + } + obj->runtime->activeSector->info->headInfoAddr -= FEE_BLOCK_HEAD_INFO_SIZE; + } + else + { + (void)obj->runtime->activeSector->info->remAddr; + } + obj->runtime->activeSector->info->remAddr += blocksize; + } + else + { + obj->runtime->jobResult = FEE_JOB_RESULT_BL_INVALID; + notificationRet = FEE_JOBENDNOTIFICATION; + } + + /* Callback notification function. */ + if(obj->runtime->job->notificationPtr != NULL) + { + obj->runtime->job->notificationPtr(notificationRet); + } + return ret; +} + +static void FEE_OnEntryGcJob(const FeeType *obj) +{ + obj->runtime->gcRuntime->state = FEE_GC_STATE_NO_ERROR; + obj->runtime->gcRuntime->gcFsm = FEE_GC_INIT; + obj->runtime->mainFunFsm = FEE_MAIN_FUN_FSM_GC; +} + +static bool Fee_GcJob(const FeeType *obj) +{ + bool ret = false; + + switch(obj->runtime->gcRuntime->gcFsm) + { + case FEE_GC_INIT: + { + /* Find backup sector. */ + obj->runtime->gcRuntime->backupSector = Fee_FoundBackupSector(obj); + + if(obj->runtime->gcRuntime->backupSector != NULL) + { + /* Information about initializing the backup sector. */ + Fee_SectorInitInfo(obj->runtime->gcRuntime->backupSector); + + /* Check whether all sectors have been erased. */ + if(false == Fee_SectorIsErase(obj->runtime->gcRuntime->backupSector, obj->flsMethod)) + { + /* Execute the sector erase action. */ + obj->runtime->gcRuntime->gcFsm = FEE_GC_ERASE_BACKUPSECTOR; + Fee_InitEraseSector(obj->runtime->gcRuntime->backupSector); + } + else + { + obj->runtime->gcRuntime->backupSector->info->status = FEE_SECTOR_UNUSED; + obj->runtime->gcRuntime->gcFsm = FEE_GC_START; + } + } + else + { + /* If the backup sector is not found, it is considered a major configuration defect. */ + obj->runtime->gcRuntime->state = FEE_GC_STATE_NOT_FOUND_BACKUPSECTOR; + obj->runtime->gcRuntime->gcFsm = FEE_GC_ERROR; + } + break; + } + case FEE_GC_ERASE_BACKUPSECTOR: + { + /* Erase the backed up sector. */ + Fee_EraseSector(obj->runtime->gcRuntime->backupSector, obj->flsMethod); + if((FEE_SECTOR_NOT_ERROR == obj->runtime->gcRuntime->backupSector->info->errors) && (FEE_SECTOR_ERASE == obj->runtime->gcRuntime->backupSector->info->status)) + { + obj->runtime->gcRuntime->gcFsm = FEE_GC_START; + } + else if(FEE_SECTOR_NOT_ERROR != obj->runtime->gcRuntime->backupSector->info->errors) + { + obj->runtime->gcRuntime->state = FEE_GC_STATE_ERASE_BACKUP_SECTOR_ERROR; + obj->runtime->gcRuntime->gcFsm = FEE_GC_ERROR; + } + break; + } + case FEE_GC_START: + { + /* Write initialization completion flag bit. */ + Fee_SectorWriteInitMark(obj->runtime->gcRuntime->backupSector, obj->flsMethod, obj->buff); + + if(FEE_SECTOR_NOT_ERROR != obj->runtime->gcRuntime->backupSector->info->errors) + { + obj->runtime->gcRuntime->state = FEE_GC_STATE_WRITE_INIT_MARK_ERROR; + obj->runtime->gcRuntime->gcFsm = FEE_GC_ERROR; + FEE_DBG_GC_WRITE_INIT_MARK_ERROR_ENTRY(); + } + else + { + Fee_OnEntryGcCopyJob(obj); + obj->runtime->gcRuntime->gcFsm = FEE_GC_COPY; + } + break; + } + case FEE_GC_COPY: + { + /* Handling data job. */ + if(Fee_GcCopyJob(obj)) + { + /* Erase the active sector after data GC is completed. */ + Fee_InitEraseSector(obj->runtime->activeSector); + obj->runtime->activeSector->info->status = FEE_SECTOR_UNUSED; + obj->runtime->gcRuntime->gcFsm = FEE_GC_ERASE_ACTIVESECTOR; + } + if(FEE_GC_COPY_ERROR == obj->runtime->gcRuntime->copyFsm) + { + obj->runtime->gcRuntime->state = FEE_GC_STATE_COPY_ERROR; + obj->runtime->gcRuntime->gcFsm = FEE_GC_ERROR; + } + else if(FEE_SECTOR_NOT_ERROR != obj->runtime->gcRuntime->backupSector->info->errors) + { + obj->runtime->gcRuntime->state = FEE_GC_STATE_COPY_ERROR; + obj->runtime->gcRuntime->gcFsm = FEE_GC_ERROR; + } + else if(FEE_GC_STATE_NO_ERROR != obj->runtime->gcRuntime->state) + { + obj->runtime->gcRuntime->gcFsm = FEE_GC_ERROR; + } + break; + } + case FEE_GC_ERASE_ACTIVESECTOR: + { + /* Erase the active sector after data transfer is completed. */ + Fee_EraseSector(obj->runtime->activeSector, obj->flsMethod); + + if((FEE_SECTOR_NOT_ERROR == obj->runtime->activeSector->info->errors) && (FEE_SECTOR_ERASE == obj->runtime->activeSector->info->status)) + { + obj->runtime->gcRuntime->gcFsm = FEE_GC_FINISH; + } + else if(FEE_SECTOR_NOT_ERROR != obj->runtime->activeSector->info->errors) + { + obj->runtime->gcRuntime->state = FEE_GC_STATE_ERASE_ACTIVE_SECTOR_ERROR; + obj->runtime->gcRuntime->gcFsm = FEE_GC_ERROR; + FEE_DBG_GC_ERASE_ACTIVE_SECTOR_ERROR_ENTRY(); + } + break; + } + case FEE_GC_FINISH: + { + /* Write the flag bit of the active sector to the sector info. */ + Fee_SectorWriteEnableSectorMark(obj->runtime->gcRuntime->backupSector, obj->flsMethod, obj->buff); + Fee_SectorFillHeadInfo(obj->runtime->gcRuntime->backupSector, obj->flsMethod, obj->buff); + + if(FEE_SECTOR_NOT_ERROR != obj->runtime->gcRuntime->backupSector->info->errors) + { + obj->runtime->gcRuntime->state = FEE_GC_STATE_WRITE_ENA_MARK_ERROR; + obj->runtime->gcRuntime->gcFsm = FEE_GC_ERROR; + FEE_DBG_GC_WRITE_ENABLE_MARK_ERROR_ENTRY(); + } + else + { + obj->runtime->activeSector = obj->runtime->gcRuntime->backupSector; + obj->runtime->gcRuntime->backupSector = NULL; + obj->runtime->activeSector->info->status = FEE_SECTOR_ACTIVE; + ret = true; + } + break; + } + default: + { + ret = true; + FEE_DBG_GC_FSM_ERROR_ENTRY(); + break; + } + } + + return ret; +} + +static void Fee_OnEntryGcCopyJob(const FeeType *obj) +{ + obj->runtime->gcRuntime->copyFsm = FEE_GC_COPY_WRITE_MARK; + obj->runtime->gcRuntime->blockCnt = 0; +} + +static bool Fee_GcCopyJob(const FeeType *obj) +{ + bool ret = false; + switch(obj->runtime->gcRuntime->copyFsm) + { + case FEE_GC_COPY_WRITE_MARK: + { + /* Write the start transport flag bit to the backup sector. */ + Fee_SectorWriteStartHandMark(obj->runtime->gcRuntime->backupSector, obj->flsMethod, obj->buff); + + if(FEE_SECTOR_NOT_ERROR != obj->runtime->gcRuntime->backupSector->info->errors) + { + obj->runtime->gcRuntime->copyFsm = FEE_GC_COPY_ERROR; + FEE_DBG_GC_WRITE_START_MARK_ERROR_ENTRY(); + } + else + { + obj->runtime->gcRuntime->copyFsm = FEE_GC_COPY_INIT; + } + break; + } + case FEE_GC_COPY_INIT: + { + /* Latest data of index block. */ + if(obj->runtime->gcRuntime->blockCnt < obj->sector->blockSize) + { + if(Fee_GcInitBlockInfo(obj, &(obj->sector->blocks[obj->runtime->gcRuntime->blockCnt]))) + { + obj->runtime->gcRuntime->copyFsm = FEE_GC_COPY_WRITEBLOCK; + } + else if(FEE_GC_STATE_READ_ERROR == obj->runtime->gcRuntime->state) + { + obj->runtime->gcRuntime->copyFsm = FEE_GC_COPY_ERROR; + } + obj->runtime->gcRuntime->blockCnt++; + } + else + { + obj->runtime->gcRuntime->copyFsm = FEE_GC_COPY_FINISH; + } + break; + } + case FEE_GC_COPY_WRITEBLOCK: + { + /* Write to backup sector. */ + if(Fee_GcWriteBlockToNewSector(obj)) + { + obj->runtime->gcRuntime->copyFsm = FEE_GC_COPY_INIT; + } + break; + } + case FEE_GC_COPY_FINISH: + { + /* Write the completion handling flag bit to backup sector info. */ + Fee_SectorWriteEndHandMark(obj->runtime->gcRuntime->backupSector, obj->flsMethod, obj->buff); + + if(FEE_SECTOR_NOT_ERROR != obj->runtime->gcRuntime->backupSector->info->errors) + { + obj->runtime->gcRuntime->copyFsm = FEE_GC_COPY_ERROR; + FEE_DBG_GC_WRITE_END_MARK_ERROR_ENTRY(); + } + else + { + ret = true; + } + break; + } + default: + { + FEE_DBG_GC_COPY_FSM_ERROR_ENTRY(); + break; + } + } + + return ret; +} + +static bool Fee_GcInitBlockInfo(const FeeType *obj, const Fee_BlockType *block) +{ + bool ret = false; + uint16_t blocksize; + + /* Calculate the location and data size of the valid data stored in the block. */ + if(NULL != block) + { + obj->runtime->gcRuntime->currentBlock = block; + blocksize = FEE_BLOCKSIZE(obj->runtime->gcRuntime->currentBlock->cfg); + + if(NULL != Fee_BlockGetPhyAddr(obj->runtime->gcRuntime->currentBlock->info)) + { + if(FLS_STATE_OK != obj->flsMethod->read(obj->runtime->gcRuntime->currentBlock->info->phyAddr, (uint8_t *)obj->buff, blocksize)) + { + obj->runtime->gcRuntime->state = FEE_GC_STATE_READ_ERROR; + } + else + { + ret = true; + } + } + } + return ret; +} + +static bool Fee_GcWriteBlockToNewSector(const FeeType *obj) +{ + bool ret = false; + uint16_t blocksize; + Fee_AddressType tempPhyaddr; + + /* Obtain the assigned address of the block in the backup sector. */ + blocksize = FEE_BLOCKSIZE(obj->runtime->gcRuntime->currentBlock->cfg); + + /* First write the block data to the flash, ensure safe writing, and then write the block header information. */ + if(FLS_STATE_OK == obj->flsMethod->write(obj->runtime->gcRuntime->backupSector->info->remAddr, (uint8_t *)obj->buff, blocksize)) + { + tempPhyaddr = Fee_BlockGetPhyAddr(obj->runtime->gcRuntime->currentBlock->info); + Fee_BlockSetPhyAddr(obj->runtime->gcRuntime->currentBlock->info, obj->runtime->gcRuntime->backupSector->info->remAddr); + Fee_WriteBlockHeadInfo(obj->runtime->gcRuntime->currentBlock, obj->flsMethod->crc8, obj->buff); + + if(FLS_STATE_OK == obj->flsMethod->write(obj->runtime->gcRuntime->backupSector->info->headInfoAddr, (uint8_t *)obj->buff, FEE_BLOCK_HEAD_INFO_SIZE)) + { + obj->runtime->gcRuntime->backupSector->info->headInfoAddr -= FEE_BLOCK_HEAD_INFO_SIZE; + ret = true; + } + else + { + Fee_BlockSetPhyAddr(obj->runtime->gcRuntime->currentBlock->info, tempPhyaddr); + obj->runtime->gcRuntime->state = FEE_GC_STATE_WRITE_ERROR; + FEE_DBG_GC_WRITE_BLOCK_HEAD_INFO_ERROR_ENTRY(); + } + + obj->runtime->gcRuntime->backupSector->info->remAddr += blocksize; + } + else + { + obj->runtime->gcRuntime->state = FEE_GC_STATE_WRITE_ERROR; + FEE_DBG_GC_WRITE_BLOCK_DATA_ERROR_ENTRY(); + } + return ret; +} + +static const Fee_SectorConfigType *Fee_FoundBackupSector(const FeeType *obj) +{ + const Fee_SectorConfigType *backupSector = NULL; + int sectorIdx; + + /* Find the backup sector by checking the status of the sector. */ + for(sectorIdx = 0; sectorIdx < obj->sector->sectorSize; sectorIdx++) + { + if(FEE_SECTOR_ACTIVE != obj->sector->sectors[sectorIdx].info->status) + { + backupSector = &obj->sector->sectors[sectorIdx]; + break; + } + } + + return backupSector; +} + +static uint16_t Fee_SearchBlock(const Fee_SectorType *obj, uint16_t blockNumber) +{ + uint16_t retBlock = FEE_INVALID_BLOCK_INDEX; + uint16_t blockStartIdx = 0; + uint16_t blockMiddleIdx = (obj->blockSize - 1) / 2; + uint16_t blockEndIdx = obj->blockSize - 1; + bool finishFlag = false; + + while(false == finishFlag) + { + /* If the current block and the input block are the same. */ + if(Fee_BlockCheckBlockNumber(obj->blocks[blockMiddleIdx].cfg, blockNumber)) + { + /* Returns the index of the block. */ + retBlock = blockMiddleIdx; + finishFlag = true; + } + else + { + /* Currently, there are only two or fewer blocks left that are not found, then check the other block. */ + if((blockEndIdx - blockStartIdx) <= 1) + { + finishFlag = true; + if(Fee_BlockCheckBlockNumber(obj->blocks[blockEndIdx].cfg, blockNumber)) + { + retBlock = blockEndIdx; + } + } + else + { + /* In descending order, first determine whether it is in the right range, */ + /* and then check whether it is in the left range. */ + if(obj->blocks[blockMiddleIdx].cfg->number < blockNumber) + { + blockStartIdx = blockMiddleIdx + 1; + } + else + { + blockEndIdx = blockMiddleIdx - 1; + } + + /* Calculate Median. */ + blockMiddleIdx = blockEndIdx + blockStartIdx; + blockMiddleIdx /= 2; + } + } + } + return retBlock; +} diff --git a/cva_asw_m0118/SDK/middleware/nvm/fee/fee.h b/cva_asw_m0118/SDK/middleware/nvm/fee/fee.h new file mode 100644 index 0000000..03c40d4 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/fee/fee.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FEE_H_ +#define _FEE_H_ + +/*! \brief Contains public interface to various functions related + * to the FEE (Flash EEPROM Emulation) module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include +#include "fee_types.h" +#include "fee_extra.h" +#include "fee_version.h" + +/*! \addtogroup Flash EEPROM Emulation + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Configures the FEE driver + * + * This function configures the FEE driver + * + * \param[in] obj : pointer to FEE driver instance + */ +extern void Fee_Configure(const FeeType *obj); + +/*! \brief Main function of FEE driver + * + * This function is the main process of running the FEE driver + * + * \param[in] obj : pointer to FEE driver instance + */ +extern void Fee_MainFunction(const FeeType *obj); + +/*! \brief Read the data from FEE + * + * This function reads the data from FEE with given parameters + * + * \param[in] obj : pointer to FEE driver instance + * \param[in] blockNumber : block number to read + * \param[in] blockOffset : offset of dataset defined by user in block + * \param[out] dataBuffer : pointer to the result data buffer + * \param[in] notificationPtr : pointer to the notification callback function + */ +extern Fee_ReturnType Fee_Read(const FeeType *obj, uint16_t blockNumber, uint16_t blockOffset, uint8_t *dataBuffer, NotificationPtrType notificationPtr); + +/*! \brief Write the data to FEE + * + * This function writed the data to FEE with given parameters + * + * \param[in] obj : pointer to FEE driver instance + * \param[in] blockNumber : block number to write + * \param[in] dataBuffer : pointer to the data buffer to write + * \param[in] notificationPtr : pointer to the notification callback function + */ +extern Fee_ReturnType Fee_Write(const FeeType *obj, uint16_t blockNumber, uint8_t *dataBuffer, NotificationPtrType notificationPtr); + +/*! \brief Cancel the newest request + * + * This function cancels the newest request in the request buffer + * + * \param[in] obj : pointer to FEE driver instance + */ +extern Fee_ReturnType Fee_Cancel(const FeeType *obj); + +/*! \brief Get the prev job result + * + * This function gets the prev job result of block + * + * \param[in] obj : pointer to FEE driver instance + */ +extern Fee_JobResultType Fee_GetJobResult(const FeeType *obj); + +/*! \brief Get the current running status + * + * This function gets the current running status of FEE + * + * \param[in] obj : pointer to FEE driver instance + */ +extern Fee_StatusType Fee_GetStatus(const FeeType *obj); + +/*! \brief Get the version information of this driver + * + * This function gets the version information of this driver. + * + * \param[out] versionInfoPtr : pointer to the version object + */ +extern void Fee_GetVersionInfo(Fee_VersionInfoType *versionInfoPtr); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _FEE_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/nvm/fee/fee_block.h b/cva_asw_m0118/SDK/middleware/nvm/fee/fee_block.h new file mode 100644 index 0000000..abfdf67 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/fee/fee_block.h @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FEE_BLOCK_H_ +#define _FEE_BLOCK_H_ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "fee_extra.h" +#include "fee_types.h" + +/*! \addtogroup Flash EEPROM Emulation + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Macro that defines the size of block info. + */ +#if(defined FEE_BLOCK_HEAD_INFO_SIZE) +#error FEE_BLOCK_HEAD_INFO_SIZE already defined +#endif +#define FEE_BLOCK_HEAD_INFO_SIZE (16) + +/*! \brief Macro defining the calculated length of crc8 in block info. + */ +#if(defined FEE_BLOCK_CALC_HEAD_INFO_CRC8_LEN) +#error FEE_BLOCK_CALC_HEAD_INFO_CRC8_LEN already defined +#endif +#define FEE_BLOCK_CALC_HEAD_INFO_CRC8_LEN (12) + +/*! \brief Macro that defines the start flag bit index in block info. + */ +#if(defined FEE_BLOCK_HEAD_INFO_START_INFO_IDX) +#error FEE_BLOCK_HEAD_INFO_START_INFO_IDX already defined +#endif +#define FEE_BLOCK_HEAD_INFO_START_INFO_IDX (0) + +/*! \brief Macro that defines the index of number in block info. + */ +#if(defined FEE_BLOCK_HEAD_INFO_BLOCK_NUMBER_IDX) +#error FEE_BLOCK_HEAD_INFO_BLOCK_NUMBER_IDX already defined +#endif +#define FEE_BLOCK_HEAD_INFO_BLOCK_NUMBER_IDX (4) + +/*! \brief Define the index representing the data address in block info. + */ +#if(defined FEE_BLOCK_HEAD_INFO_PHY_ADDR_IDX) +#error FEE_BLOCK_HEAD_INFO_PHY_ADDR_IDX already defined +#endif +#define FEE_BLOCK_HEAD_INFO_PHY_ADDR_IDX (8) + +/*! \brief Define a macro in block info that represents the index of the crc8 result. + */ +#if(defined FEE_BLOCK_HEAD_INFO_CRC8_IDX) +#error FEE_BLOCK_HEAD_INFO_CRC8_IDX already defined +#endif +#define FEE_BLOCK_HEAD_INFO_CRC8_IDX (12) + +/*! \brief Macro that defines the start flag bit in block info. + */ +#if(defined FEE_BLOCK_HEAD_INFO_START_INFO) +#error FEE_BLOCK_HEAD_INFO_START_INFO already defined +#endif +#define FEE_BLOCK_HEAD_INFO_START_INFO (0XAAAAAAAA) + +/*! \brief Define flash write aligned macros. + */ +#if(defined Fee_BLOCK_WRITE_ALIGNED_SIZE) +#error Fee_BLOCK_WRITE_ALIGNED_SIZE already defined +#endif +#define Fee_BLOCK_WRITE_ALIGNED_SIZE (8) + +/*! \brief Macro that defines the valid flag bits of a block. + */ +#if(defined FEE_BLOCK_VALID_WORD) +#error FEE_BLOCK_VALID_WORD already defined +#endif +#define FEE_BLOCK_VALID_WORD (0xAA) + +/*! \brief Macro defining block invalid byte padding. + */ +#if(defined FEE_BLOCK_FILL_WORD) +#error FEE_BLOCK_FILL_WORD already defined +#endif +#define FEE_BLOCK_FILL_WORD (0xDD) + +/*! \brief Macro that defines an invalid index for a block definition block. + */ +#if(defined FEE_INVALID_BLOCK_INDEX) +#error FEE_INVALID_BLOCK_INDEX already defined +#endif +#define FEE_INVALID_BLOCK_INDEX (0xFFFF) + +/*! \brief Define macros for calculating block sizes. + */ +#define FEE_BLOCKSIZE(obj) (ALIGN8BYTE(obj->dataSize)) + +/*! \brief Used to define whether crc is required in a block. + */ +typedef enum +{ + FEE_CRC_NONE = 0x00, + FEE_CRC8 = 0x01, +} Fee_BlockCrcType; + +/*! \brief Define the type of block configuration. + */ +typedef struct _Fee_BlockConfigType_ +{ + uint16_t number; + uint16_t dataSize; +} Fee_BlockConfigType; + +/*! \brief Define the type of block runtime information. + */ +typedef struct _Fee_BlockInfoType_ +{ + Fee_AddressType phyAddr; +} Fee_BlockInfoType; + +/*! \brief Define a block type. + */ +typedef struct _Fee_BlockType_ +{ + const struct _Fee_BlockConfigType_ * cfg; + struct _Fee_BlockInfoType_ * info; +} Fee_BlockType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +__attribute__((always_inline)) static inline void Fee_BlockSetPhyAddr(Fee_BlockInfoType *obj, Fee_AddressType phyAddr) +{ + obj->phyAddr = phyAddr; +} + +__attribute__((always_inline)) static inline Fee_AddressType Fee_BlockGetPhyAddr(Fee_BlockInfoType *obj) +{ + return obj->phyAddr; +} + +__attribute__((always_inline)) static inline bool Fee_BlockCheckBlockNumber(const Fee_BlockConfigType *obj, uint16_t blockNumber) +{ + bool ret = false; + + /* Determine whether the numbers of the incoming blocks are the same. */ + if(obj->number == blockNumber) + { + ret = true; + } + return ret; +} + +__attribute__((always_inline)) static inline Fee_AddressType Fee_GetBlockHeadPhyAddr(uint8_t *data) +{ + uint32_t *phyAddr; + + phyAddr = (uint32_t *)&data[FEE_BLOCK_HEAD_INFO_PHY_ADDR_IDX]; + + return (Fee_AddressType)*phyAddr; +} + +__attribute__((always_inline)) static inline void Fee_WriteBlockHeadInfo(const Fee_BlockType *obj, Fee_calcCrc8Type crc8Method, uint8_t *cache) +{ + uint32_t *startInfo; + uint16_t *blockNumber; + Fee_AddressType *phyAddr; + uint8_t *crc8; + + /* Initialize cache. */ + memset((void *)cache, 0x00, FEE_BLOCK_HEAD_INFO_SIZE); + + startInfo = (uint32_t *)&cache[FEE_BLOCK_HEAD_INFO_START_INFO_IDX]; + blockNumber = (uint16_t *)&cache[FEE_BLOCK_HEAD_INFO_BLOCK_NUMBER_IDX]; + phyAddr = (Fee_AddressType *)&cache[FEE_BLOCK_HEAD_INFO_PHY_ADDR_IDX]; + crc8 = (uint8_t *)&cache[FEE_BLOCK_HEAD_INFO_CRC8_IDX]; + + *startInfo = FEE_BLOCK_HEAD_INFO_START_INFO; + *blockNumber = obj->cfg->number; + *phyAddr = obj->info->phyAddr; + *crc8 = crc8Method((void *)cache, FEE_BLOCK_CALC_HEAD_INFO_CRC8_LEN); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _FEE_BLOCK_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/nvm/fee/fee_extra.h b/cva_asw_m0118/SDK/middleware/nvm/fee/fee_extra.h new file mode 100644 index 0000000..0a5a40c --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/fee/fee_extra.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FEE_EXTRA_H_ +#define _FEE_EXTRA_H_ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup Flash EEPROM Emulation + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/*! \brief Define macros that express the address of a feed. + */ +#define Fee_AddressType uint8_t * + +/*! \brief Define N-byte aligned macros. + */ +#ifndef ALIGNBYTE +#define ALIGNBYTE(size, n) ((size + n - 1) & ~(n - 1)) +#endif + +/*! \brief Define 4-byte aligned macros. + */ +#ifndef ALIGN4BYTE +#define ALIGN4BYTE(size) (ALIGNBYTE(size, 4)) +#endif + +/*! \brief Define 8-byte aligned macros. + */ +#ifndef ALIGN8BYTE +#define ALIGN8BYTE(size) (ALIGNBYTE(size, 8)) +#endif + +/*! \brief Define 64-byte aligned macros. + */ +#ifndef ALIGN64BYTE +#define ALIGN64BYTE(size) (ALIGNBYTE(size, 64)) +#endif + +/*! \brief Define address aligned macros. + */ +#ifndef ALIGNED +#define ALIGNED(val, alncnt) (((uint32_t)val) & ~(alncnt - 1)) +#endif + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +/*! \brief Define the type of the Notification return value. + */ +typedef enum +{ + FEE_JOBENDNOTIFICATION = 0x00, + FEE_JOBERRORNOTIFICATION = 0x01, +} Fee_NotificationType; + +/*! \brief Define the type of return value for flash operations. + */ +typedef enum +{ + FLS_STATE_OK = 0x00, + FLS_STATE_NOT_WRITABLE = 0x01, + FLS_STATE_ECC_ERROR = 0x02, + FLS_STATE_READ_BACK_FAIL = 0x04, + FLS_STATE_PROGRAM_FAIL = 0x05, + FLS_STATE_ERASE_FAIL = 0x05, + FLS_STATE_NOT_WRITTEN = 0x07, + FLS_STATE_UNKNOW = 0x08, +}Fls_StateType; + +/*! \brief Define the type of virtual function for Notification. + */ +typedef void (*NotificationPtrType)(Fee_NotificationType notificationNumber); + +/*! \brief Define the type of virtual function for writing flash operations. + */ +typedef Fls_StateType (*Fee_writeMethodType)(Fee_AddressType sAddr, uint8_t *buff, uint32_t size); + +/*! \brief Define virtual function types for read flash operations. + */ +typedef Fls_StateType (*Fee_readMethodType)(Fee_AddressType sAddr, uint8_t *buff, uint32_t size); + +/*! \brief Define virtual function types for erasing flash operations. + */ +typedef Fls_StateType (*Fee_eraseMethodType)(Fee_AddressType eraseAddr); + +/*! \brief Define virtual function types to check whether flash is writable. + */ +typedef Fls_StateType (*Fee_isWriteableType)(Fee_AddressType sAddr, uint32_t size); + +/*! \brief Define virtual function types for calculating crc8. + */ +typedef uint8_t (*Fee_calcCrc8Type)(void *sAddr, uint32_t size); + +/*! \brief Define the type of the feed operation flash method. + */ +typedef struct _Fee_MethodType_ +{ + Fee_writeMethodType write; + Fee_readMethodType read; + Fee_eraseMethodType erase; + Fee_isWriteableType isWriteable; + Fee_calcCrc8Type crc8; +} Fee_MethodType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _FEE_EXTRA_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/nvm/fee/fee_initialization.c b/cva_asw_m0118/SDK/middleware/nvm/fee/fee_initialization.c new file mode 100644 index 0000000..302ee52 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/fee/fee_initialization.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "fee_initialization.h" +#include "fee_extra.h" +#include "fee_types.h" +#include "fee_trace.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the static + ******************************************************************************/ +static void Fee_InitializationCheckSector(const FeeType *obj); +static void Fee_InitializationSector(const FeeType *obj); +static void Fee_InitializationFindActiveSector(const FeeType *obj); +static void Fee_InitializationGcRepairSector(const FeeType *obj); +static void Fee_InitializationFirstSector(const FeeType *obj); +static void Fee_InitializationUnEraseSector(const FeeType *obj); +static void Fee_InitializationEraseSector(const FeeType *obj); +static void Fee_InitializationFinish(const FeeType *obj); + +/******************************************************************************* + * the functions + ******************************************************************************/ +void Fee_EntryInitialization(const FeeType *obj) +{ + obj->runtime->initializationFsm = FEE_INITIALIZATION_SECTOR; +} + +bool Fee_InitializationJob(const FeeType *obj) +{ + bool ret = false; + switch(obj->runtime->initializationFsm) + { + case FEE_INITIALIZATION_SECTOR: + { + Fee_InitializationSector(obj); + break; + } + case FEE_INITIALIZATION_CHECK_SECTOR: + { + Fee_InitializationCheckSector(obj); + break; + } + case FEE_INITIALIZATION_FIND_ACTIVE_SECTOR: + { + Fee_InitializationFindActiveSector(obj); + break; + } + case FEE_INITIALIZATION_ERASE_SECTOR: + { + Fee_InitializationEraseSector(obj); + break; + } + case FEE_INITIALIZATION_UNINITIALIZATION_ERASE_SECTOR: + { + Fee_InitializationUnEraseSector(obj); + break; + } + case FEE_INITIALIZATION_UNINITIALIZATION: + { + Fee_InitializationFirstSector(obj); + break; + } + case FEE_INITIALIZATION_GC_REPAIR_SECTOR: + { + Fee_InitializationGcRepairSector(obj); + break; + } + case FEE_INITIALIZATION_FINISH: + { + Fee_InitializationFinish(obj); + ret = true; + break; + } + default: + { + FEE_DBG_INITIALIZATION_FSM_ERROR_ENTRY(); + break; + } + } + return ret; +} + +static void Fee_InitializationCheckSector(const FeeType *obj) +{ + int sectorIdx; + + for(sectorIdx = 0; sectorIdx < obj->sector->sectorSize; sectorIdx++) + { + Fee_SectorCheckErase(&obj->sector->sectors[sectorIdx], obj->flsMethod); + if (FEE_SECTOR_ERASE != Fee_SectorGetStatus(&obj->sector->sectors[sectorIdx])) + { + Fee_CheckSectorIsValid(&obj->sector->sectors[sectorIdx], obj->flsMethod, (uint8_t *)obj->buff); + } + } + + /* Initialize the state machine to the next state */ + obj->runtime->initializationFsm = FEE_INITIALIZATION_FIND_ACTIVE_SECTOR; +} + +static void Fee_InitializationSector(const FeeType *obj) +{ + /* Initialize sector runtime data. */ + Fee_SectorsInit(obj->sector, obj->flsMethod, obj->buff); + + /* Initialize the state machine to the default state. */ + obj->runtime->initializationFsm = FEE_INITIALIZATION_CHECK_SECTOR; +} + +static void Fee_InitializationFindActiveSector(const FeeType *obj) +{ + const Fee_SectorConfigType *activeSector; + const Fee_SectorConfigType *gcSector; + + /* Initialize the state machine. */ + obj->runtime->initializationFsm = FEE_INITIALIZATION_UNINITIALIZATION; + + /* The activity sector value is NULL. */ + obj->runtime->activeSector = NULL; + + /* Find the active sector. */ + activeSector = Fee_SearchValidSector(obj->sector); + + /* Check if the active sector is found. */ + if(activeSector != NULL) + { + obj->runtime->activeSector = activeSector; + obj->runtime->initializationFsm = FEE_INITIALIZATION_FINISH; + } + + /* The backup sector value is NULL. */ + obj->runtime->gcRuntime->backupSector = NULL; + + /* Find the backup sector. */ + gcSector = Fee_SearchGcSector(obj->sector); + + /* Check if the backup sector is found. */ + if(gcSector != NULL) + { + /* Check whether the backup section is in the transportation completion state. */ + /* If not, check whether it is in the state before the transportation is completed. */ + if(FEE_SECTOR_END_HAND_FINISH == gcSector->info->status) + { + /* Execute the sector repair program. */ + obj->runtime->gcRuntime->backupSector = gcSector; + obj->runtime->initializationFsm = FEE_INITIALIZATION_GC_REPAIR_SECTOR; + } + else if(FEE_SECTOR_END_HAND_FINISH > gcSector->info->status) + { + /* Check whether there is an active sector. */ + if(NULL == obj->runtime->activeSector) + { + /* Execute the reinitialization of the sector program. */ + obj->runtime->initializationFsm = FEE_INITIALIZATION_UNINITIALIZATION; + } + } + } +} + +static void Fee_InitializationGcRepairSector(const FeeType *obj) +{ + /* If there is no active sector, flip the backup sector to the active state. */ + if(NULL == obj->runtime->activeSector) + { + obj->runtime->activeSector = obj->runtime->gcRuntime->backupSector; + } + obj->runtime->initializationFsm = FEE_INITIALIZATION_FINISH; +} + +static void Fee_InitializationFirstSector(const FeeType *obj) +{ + const Fee_SectorConfigType *activeSector; + + /* Get the first sector. */ + activeSector = Fee_GetFirstSector(obj->sector); + + /* Check whether the active sector is found. */ + if(activeSector != NULL) + { + /* Initialize the active sector. */ + obj->runtime->activeSector = activeSector; + Fee_InitEraseSector(obj->runtime->activeSector); + obj->runtime->initializationFsm = FEE_INITIALIZATION_UNINITIALIZATION_ERASE_SECTOR; + } + else + { + obj->runtime->initializationFsm = FEE_INITIALIZATION_ERROR; + } +} + +static void Fee_InitializationUnEraseSector(const FeeType *obj) +{ + /* Erase active sector. */ + Fee_EraseSector(obj->runtime->activeSector, obj->flsMethod); + + /* Check whether the active sector is in the error state. */ + /* If not, check whether it is in the erase state. */ + if(FEE_SECTOR_NOT_ERROR != obj->runtime->activeSector->info->errors) + { + obj->runtime->initializationFsm = FEE_INITIALIZATION_ERROR; + } + else if(FEE_SECTOR_ERASE == obj->runtime->activeSector->info->status) + { + /* Initialize the active sector. */ + obj->runtime->activeSector->info->status = FEE_SECTOR_UNUSED; + Fee_SectorWriteHeadInfo(obj->runtime->activeSector, obj->flsMethod, obj->buff); + obj->runtime->initializationFsm = FEE_INITIALIZATION_FINISH; + } +} + +static void Fee_InitializationEraseSector(const FeeType *obj) +{ + /* Erase active sector. */ + Fee_EraseSector(obj->runtime->activeSector, obj->flsMethod); + + /* Check whether the active sector is in the error state. */ + /* If not, check whether it is in the erase state. */ + if(FEE_SECTOR_NOT_ERROR != obj->runtime->activeSector->info->errors) + { + obj->runtime->initializationFsm = FEE_INITIALIZATION_ERROR; + } + else if(FEE_SECTOR_ERASE == obj->runtime->activeSector->info->status) + { + obj->runtime->initializationFsm = FEE_INITIALIZATION_FINISH; + } +} + +static void Fee_InitializationFinish(const FeeType *obj) +{ + /* Check whether the active sector is NULL. */ + if(obj->runtime->activeSector != NULL) + { + /* Set the state of the active sector to the actvie state. */ + obj->runtime->activeSector->info->status = FEE_SECTOR_ACTIVE; + } + else + { + /* An irretrievable mistake. */ + FEE_DBG_STORAGE_ERROR_ENTRY(); + } +} diff --git a/cva_asw_m0118/SDK/middleware/nvm/fee/fee_initialization.h b/cva_asw_m0118/SDK/middleware/nvm/fee/fee_initialization.h new file mode 100644 index 0000000..48d6b37 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/fee/fee_initialization.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FEE_INITIALIZATION_H_ +#define _FEE_INITIALIZATION_H_ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "fee_types.h" + +/*! \addtogroup Flash EEPROM Emulation + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Internal initializtion + * + * This function is the internal initializtion FEE driver + * + * \param[in] obj : pointer to FEE driver instance + */ +extern void Fee_EntryInitialization(const FeeType *obj); + +/*! \brief Initialize job of FEE + * + * This function implemente the initialiazation job of FEE + * + * \param[in] obj : pointer to FEE driver instance + */ +extern bool Fee_InitializationJob(const FeeType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _FEE_INITIALIZATION_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/nvm/fee/fee_jobs.h b/cva_asw_m0118/SDK/middleware/nvm/fee/fee_jobs.h new file mode 100644 index 0000000..5982fb1 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/fee/fee_jobs.h @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FEE_JOBS_H_ +#define _FEE_JOBS_H_ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "fee_extra.h" + +/*! \addtogroup Flash EEPROM Emulation + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Job's request type definition. + */ +typedef enum +{ + FEE_JOB_OP_UNDEFINE = 0x00, + FEE_JOB_OP_READ = 0x01, + FEE_JOB_OP_WRITE = 0x02, + FEE_JOB_OP_GC = 0x03, +} Fee_JobOpType; + +/*! \brief Definition of mutex type for job. + */ +typedef enum +{ + FEE_JOB_LOCK = 0x01, + FEE_JOB_UNLOCK = 0x02, +} Fee_JobLockType; + +/*! \brief Control block type definition for job. + */ +typedef struct _Fee_JobControlBlockType_ +{ + Fee_JobLockType lock; + uint16_t blockIdx; + uint16_t blockOffset; + Fee_JobOpType op; + uint8_t *dataBuffPtr; + NotificationPtrType notificationPtr; +} Fee_JobControlBlockType; + +/*! \brief Job object type definition. + */ +typedef struct _Fee_JobsType_ +{ + bool accept; + struct _Fee_JobControlBlockType_ *userJob; + struct _Fee_JobControlBlockType_ *sysJob; +} Fee_JobsType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +__attribute__((always_inline)) static inline void Fee_InitJob(Fee_JobControlBlockType *obj) +{ + obj->lock = FEE_JOB_UNLOCK; + obj->blockIdx = 0x0000; + obj->blockOffset = 0x0000; + obj->op = FEE_JOB_OP_UNDEFINE; + obj->dataBuffPtr = NULL; + obj->notificationPtr = NULL; +} + +__attribute__((always_inline)) static inline void Fee_DisableJobs(Fee_JobsType *obj) +{ + obj->accept = false; +} + +__attribute__((always_inline)) static inline void Fee_EnableJobs(Fee_JobsType *obj) +{ + obj->accept = true; +} + +__attribute__((always_inline)) static inline bool Fee_QueryUserJobIsLock(Fee_JobsType *obj) +{ + bool result = false; + + /* Check whether the mutex of the user job is locked. */ + /* If it is locked, return true. */ + if(FEE_JOB_LOCK == obj->userJob->lock) + { + result = true; + } + + return result; +} + +__attribute__((always_inline)) static inline bool Fee_QuerySysJobIsLock(Fee_JobsType *obj) +{ + bool result = false; + + /* Check whether the mutex of the system job is locked. */ + /* If it is locked, return true. */ + if(FEE_JOB_LOCK == obj->sysJob->lock) + { + result = true; + } + + return result; +} + +__attribute__((always_inline)) static inline bool Fee_GetUserJob(Fee_JobsType *obj, Fee_JobControlBlockType *config) +{ + bool result = false; + + if(Fee_QueryUserJobIsLock(obj)) + { + (*config) = *obj->userJob; + result = true; + } + + return result; +} + +__attribute__((always_inline)) static inline bool Fee_GetSysJob(Fee_JobsType *obj, Fee_JobControlBlockType *config) +{ + bool result = false; + + if(Fee_QuerySysJobIsLock(obj)) + { + (*config) = *obj->sysJob; + result = true; + } + + return result; +} + +__attribute__((always_inline)) static inline bool Fee_SetUserJob(Fee_JobsType *obj, Fee_JobControlBlockType *config) +{ + bool result = false; + + /* To check whether the user job can accept requests, */ + /* it is necessary to check whether the user job is allowed to accept requests by the feed. */ + /* In addition, it is also necessary to check whether the user job mutex is unlocked. */ + if((obj->accept) && (false == Fee_QueryUserJobIsLock(obj))) + { + *obj->userJob = *config; + obj->userJob->lock = FEE_JOB_LOCK; + result = true; + } + + return result; +} + +__attribute__((always_inline)) static inline bool Fee_SetSysJob(Fee_JobsType *obj, Fee_JobControlBlockType *config) +{ + bool result = false; + + /* To check whether the system job can accept requests, */ + /* it is necessary to check whether the user job is allowed to accept requests by the feed. */ + /* In addition, it is also necessary to check whether the system job mutex is unlocked. */ + if((obj->accept) && (false == Fee_QuerySysJobIsLock(obj))) + { + *obj->sysJob = *config; + obj->sysJob->lock = FEE_JOB_LOCK; + result = true; + } + + return result; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _FEE_JOBS_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/nvm/fee/fee_sector.h b/cva_asw_m0118/SDK/middleware/nvm/fee/fee_sector.h new file mode 100644 index 0000000..16420fd --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/fee/fee_sector.h @@ -0,0 +1,884 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FEE_SECTOR_H_ +#define _FEE_SECTOR_H_ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include +#include "fee_block.h" +#include "fee_extra.h" +#include "fee_trace.h" +#include "fee_types.h" + +/*! \addtogroup Flash EEPROM Emulation + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/*! \brief Macro that defines the number of flags contained in the section header. + */ +#if(defined FEE_SECTOR_HEAD_MARK_NUM) +#error FEE_SECTOR_HEAD_MARK_NUM already defined +#endif +#define FEE_SECTOR_HEAD_MARK_NUM (4) + +/*! \brief Macro for the size of the sector header information flag header. + */ +#if(defined FEE_SECTOR_HEAD_SIZE) +#error FEE_SECTOR_HEAD_SIZE already defined +#endif +#define FEE_SECTOR_HEAD_SIZE (64) + +/*! \brief Defines the minimum unit of sector size, + * which depends on the hardware of the flash and needs to be aligned with the flash section. + */ +#if(defined FEE_SECTION_LENGTH) +#error FEE_SECTION_LENGTH already defined +#endif +#define FEE_SECTION_LENGTH (1024) + +/*! \brief Define the size of each flag bit in the sector header. + */ +#if(defined FEE_SECTOR_HEAD_INFO_LEN) +#error FEE_SECTOR_HEAD_INFO_LEN already defined +#endif +#define FEE_SECTOR_HEAD_INFO_LEN (8) + +/*! \brief Define the size of the backup redundancy area for each flag bit in the sector header. + */ +#if(defined FEE_SECTOR_HEAD_INFO_BACKUP_AREA_LEN) +#error FEE_SECTOR_HEAD_INFO_BACKUP_AREA_LEN already defined +#endif +#define FEE_SECTOR_HEAD_INFO_BACKUP_AREA_LEN (4) + +/*! \brief Defines the index of the header of the flag bit in the sector information header. + */ +#if(defined FEE_SECTOR_HEAD_MARK_IDX) +#error FEE_SECTOR_HEAD_MARK_IDX already defined +#endif +#define FEE_SECTOR_HEAD_MARK_IDX (0) + +/*! \brief The index of the FLAG that defines the flag bits in the sector header. + */ +#if(defined FEE_SECTOR_HEAD_FLAG_IDX) +#error FEE_SECTOR_HEAD_FLAG_IDX already defined +#endif +#define FEE_SECTOR_HEAD_FLAG_IDX (1) + +/*! \brief The index that defines the fill of the flag bit in the sector header. + */ +#if(defined FEE_SECTOR_HEAD_FILL_IDX) +#error FEE_SECTOR_HEAD_FILL_IDX already defined +#endif +#define FEE_SECTOR_HEAD_FILL_IDX (2) + +/*! \brief Defines the index of the crc8 flag bit in the sector header. + */ +#if(defined FEE_SECTOR_HEAD_CRC_IDX) +#error FEE_SECTOR_HEAD_CRC_IDX already defined +#endif +#define FEE_SECTOR_HEAD_CRC_IDX (3) + +/*! \brief Macro that defines the calculated length of the crc8 flag bit in the sector header. + */ +#if(defined FEE_SECTOR_HEAD_CRC_LEN) +#error FEE_SECTOR_HEAD_CRC_LEN already defined +#endif +#define FEE_SECTOR_HEAD_CRC_LEN (3) + +/*! \brief Macro that defines the header of the flag bit in the sector information header. + */ +#if(defined FEE_SECTOR_VALID_WORD) +#error FEE_SECTOR_VALID_WORD already defined +#endif +#define FEE_SECTOR_VALID_WORD (0X5A) + +/*! \brief Macro that defines the header of the flag bit in the sector information header. + */ +#if(defined FEE_SECTOR_INIT_FLAG_WORD) +#error FEE_SECTOR_INIT_FLAG_WORD already defined +#endif +#define FEE_SECTOR_INIT_FLAG_WORD (0X01) + +/*! \brief Macro that defines the initialization status flag bits in the sector header. + */ +#if(defined FEE_SECTOR_INIT_START_FLAG_WORD) +#error FEE_SECTOR_INIT_START_FLAG_WORD already defined +#endif +#define FEE_SECTOR_INIT_START_FLAG_WORD (0X02) + +/*! \brief Macro that defines the transport completion status flag bit in the sector header. + */ +#if(defined FEE_SECTOR_INIT_WRITE_END_FLAG_WORD) +#error FEE_SECTOR_INIT_WRITE_END_FLAG_WORD already defined +#endif +#define FEE_SECTOR_INIT_WRITE_END_FLAG_WORD (0X03) + +/*! \brief Macro that defines the enable sector status flag bits in the sector header. + */ +#if(defined FEE_SECTOR_INIT_ENABLE_FLAG_WORD) +#error FEE_SECTOR_INIT_ENABLE_FLAG_WORD already defined +#endif +#define FEE_SECTOR_INIT_ENABLE_FLAG_WORD (0X04) + +/*! \brief Define macros that need to be filled in the sector. + */ +#if(defined FEE_SECTOR_FILL_WORD) +#error FEE_SECTOR_FILL_WORD already defined +#endif +#define FEE_SECTOR_FILL_WORD (0x00) + +/*! \brief Macro that defines the position of the sector initialization flag bit in the sector header information. + */ +#define FEE_SECTOR_INIT_IDX (0) + +/*! \brief Macro that defines the position of the start moving flag bit in the sector header information. + */ +#define FEE_SECTOR_START_HAND_IDX (8) + +/*! \brief A macro that defines the position of the transport end flag bit in the sector header information. + */ +#define FEE_SECTOR_END_HAND_IDX (16) + +/*! \brief Macro that defines the position of the enable flag bit in the sector header information. + */ +#define FEE_SECTOR_EN_SECTOR_IDX (24) + +/*! \brief Define macros for marking data addresses in the backup sector header. + */ +#define FEE_SECTOR_BACKUP_HEAD_ADDR(obj) (obj->endAddr - FEE_SECTOR_HEAD_SIZE) +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Define the type of sector state. + */ +typedef enum +{ + + FEE_SECTOR_INIT = 0x00, + FEE_SECTOR_INIT_FINISH = 0x01, + FEE_SECTOR_START_HAND = 0x02, + FEE_SECTOR_START_HAND_FINISH = 0x03, + FEE_SECTOR_END_HAND = 0x04, + FEE_SECTOR_END_HAND_FINISH = 0x05, + FEE_SECTOR_EN = 0x06, + FEE_SECTOR_EN_FINISH = 0x07, + FEE_SECTOR_UNUSED = 0x08, + FEE_SECTOR_ACTIVE = 0x09, + FEE_SECTOR_ERASE = 0x0A, + FEE_SECTOR_UNDEFINE = 0xFF, +} Fee_SectorStatusType; + +/*! \brief Define sector error types. + */ +typedef enum +{ + FEE_SECTOR_NOT_ERROR = 0x00000000, + FEE_SECTOR_READ_ERROR = 0x00000001, + FEE_SECTOR_WRITE_ERROR = 0x00000002, + FEE_SECTOR_ERASE_ERROR = 0x00000004, + FEE_SECTOR_ADDR_NOALIGNED = 0x00000008, + FEE_SECTOR_WRITE_EN_MARK_ERROR = 0x00000010, + FEE_SECTOR_WRITE_INIT_MARK_ERROR = 0x00000020, + FEE_SECTOR_WRITE_START_MARK_ERROR = 0x00000040, + FEE_SECTOR_WRITE_END_MARK_ERROR = 0x00000080, + FEE_SECTOR_WRITE_FINISH_MARK_ERROR = 0x00000100, + FEE_SECTOR_WRITE_HEAD_FILL_ERROR = 0x00000200, + FEE_SECTOR_UNDEFINE_ERROR = 0x00000400, +} Fee_SectorErrorType; + +/*! \brief Define the type of external state feedback from the sector. + */ +typedef enum +{ + FEE_SECTOR_RETURN_SECTOR1_ACTIVE = 0x01, + FEE_SECTOR_RETURN_SECTOR2_ACTIVE = 0x02, + FEE_SECTOR_RETURN_SECTOR1_ACTIVE_SECTOR2_UNERASE = 0x03, + FEE_SECTOR_RETURN_SECTOR2_ACTIVE_SECTOR1_UNERASE = 0x04, + FEE_SECTOR_RETURN_UNINITIALIZATION = 0x05, + FEE_SECTOR_RETURN_SECTOR1_UNERASE = 0x06, + FEE_SECTOR_RETURN_SECTOR2_UNERASE = 0x07, + FEE_SECTOR_RETURN_UNDEFINE = 0x08, +} Fee_SectorReturnType; + +/*! \brief Define the type of sector runtime information. + */ +typedef struct _Fee_SectorInfoType_ +{ + Fee_AddressType searchAddr; + Fee_AddressType remAddr; + Fee_AddressType headInfoAddr; + uint32_t eraseSectionIdx; + Fee_SectorStatusType status; + Fee_SectorErrorType errors; +} Fee_SectorInfoType; + +/*! \brief Define the type of sector configuration information. + */ +typedef struct _Fee_SectorConfigType_ +{ + Fee_AddressType startAddr; + Fee_AddressType endAddr; + uint32_t const eraseSectionNum; + struct _Fee_SectorInfoType_ *const info; +} Fee_SectorConfigType; + +/*! \brief Define the type of the sector object. + */ +typedef struct _Fee_SectorType_ +{ + uint16_t sectorSize; + const struct _Fee_SectorConfigType_ *sectors; + uint16_t blockSize; + const struct _Fee_BlockType_ *blocks; +} Fee_SectorType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +__attribute__((always_inline)) static inline bool Fee_SectorIsErase(const Fee_SectorConfigType *obj, const Fee_MethodType *method) +{ + bool ret = true; + uint32_t sectionIdx; + + /* Check whether all the flash space of the sector is writable. */ + + for(sectionIdx = 0; sectionIdx < obj->eraseSectionNum; sectionIdx++) + { + if(FLS_STATE_NOT_WRITABLE == method->isWriteable((Fee_AddressType)(obj->startAddr + sectionIdx * FEE_SECTION_LENGTH), FEE_SECTION_LENGTH)) + { + ret = false; + break; + } + } + + return ret; +} + +__attribute__((always_inline)) static inline void Fee_SectorCheckErase(const Fee_SectorConfigType *obj, const Fee_MethodType *method) +{ + if (Fee_SectorIsErase(obj, method)) + { + obj->info->status = FEE_SECTOR_ERASE; + } +} + +__attribute__((always_inline)) static inline bool Fee_CheckSectorIsInitFinished(const Fee_calcCrc8Type method, uint8_t *cache) +{ + bool ret = false; + uint8_t crc; + + /* The flag bits of the sector header information are composed of a start flag, */ + /* a status flag, an idle bit fill, and a crc8 check code to check the integrity of the flag bit data. */ + + crc = method(cache, FEE_SECTOR_HEAD_CRC_LEN); + + if(cache[FEE_SECTOR_HEAD_CRC_IDX] == crc) + { + if(FEE_SECTOR_VALID_WORD == cache[FEE_SECTOR_HEAD_MARK_IDX]) + { + if(FEE_SECTOR_INIT_FLAG_WORD == cache[FEE_SECTOR_HEAD_FLAG_IDX]) + { + if(FEE_SECTOR_FILL_WORD == cache[FEE_SECTOR_HEAD_FILL_IDX]) + { + ret = true; + } + } + } + } + + return ret; +} + +__attribute__((always_inline)) static inline bool Fee_CheckSectorIsStartHand(const Fee_calcCrc8Type method, uint8_t *cache) +{ + bool ret = false; + uint8_t crc; + + /* The flag bits of the sector header information are composed of a start flag, */ + /* a status flag, an idle bit fill, and a crc8 check code to check the integrity of the flag bit data. */ + + crc = method(cache, FEE_SECTOR_HEAD_CRC_LEN); + + if(cache[FEE_SECTOR_HEAD_CRC_IDX] == crc) + { + if(FEE_SECTOR_VALID_WORD == cache[FEE_SECTOR_HEAD_MARK_IDX]) + { + if(FEE_SECTOR_INIT_START_FLAG_WORD == cache[FEE_SECTOR_HEAD_FLAG_IDX]) + { + if(FEE_SECTOR_FILL_WORD == cache[FEE_SECTOR_HEAD_FILL_IDX]) + { + ret = true; + } + } + } + } + + return ret; +} + +__attribute__((always_inline)) static inline bool Fee_CheckSectorIsEndHand(const Fee_calcCrc8Type method, uint8_t *cache) +{ + bool ret = false; + uint8_t crc; + + /* The flag bits of the sector header information are composed of a start flag, */ + /* a status flag, an idle bit fill, and a crc8 check code to check the integrity of the flag bit data. */ + + crc = method(cache, FEE_SECTOR_HEAD_CRC_LEN); + + if(cache[FEE_SECTOR_HEAD_CRC_IDX] == crc) + { + if(FEE_SECTOR_VALID_WORD == cache[FEE_SECTOR_HEAD_MARK_IDX]) + { + if(FEE_SECTOR_INIT_WRITE_END_FLAG_WORD == cache[FEE_SECTOR_HEAD_FLAG_IDX]) + { + if(FEE_SECTOR_FILL_WORD == cache[FEE_SECTOR_HEAD_FILL_IDX]) + { + ret = true; + } + } + } + } + + return ret; +} + +__attribute__((always_inline)) static inline bool Fee_CheckSectorIsEnSector(const Fee_calcCrc8Type method, uint8_t *cache) +{ + bool ret = false; + uint8_t crc; + + /* The flag bits of the sector header information are composed of a start flag, */ + /* a status flag, an idle bit fill, and a crc8 check code to check the integrity of the flag bit data. */ + + crc = method(cache, FEE_SECTOR_HEAD_CRC_LEN); + + if(cache[FEE_SECTOR_HEAD_CRC_IDX] == crc) + { + if(FEE_SECTOR_VALID_WORD == cache[FEE_SECTOR_HEAD_MARK_IDX]) + { + if(FEE_SECTOR_INIT_ENABLE_FLAG_WORD == cache[FEE_SECTOR_HEAD_FLAG_IDX]) + { + if(FEE_SECTOR_FILL_WORD == cache[FEE_SECTOR_HEAD_FILL_IDX]) + { + ret = true; + } + } + } + } + + return ret; +} + +__attribute__((always_inline)) static inline void Fee_UpdateSectorStatus(const Fee_SectorConfigType *obj, const Fee_calcCrc8Type method, uint8_t *data) +{ + if(Fee_CheckSectorIsInitFinished(method, &data[FEE_SECTOR_INIT_IDX]) || Fee_CheckSectorIsInitFinished(method, &data[FEE_SECTOR_INIT_IDX + FEE_SECTOR_HEAD_INFO_BACKUP_AREA_LEN])) + { + obj->info->status = FEE_SECTOR_INIT_FINISH; + } + else + { + return; + } + if(Fee_CheckSectorIsStartHand(method, &data[FEE_SECTOR_START_HAND_IDX]) || Fee_CheckSectorIsStartHand(method, &data[FEE_SECTOR_START_HAND_IDX + FEE_SECTOR_HEAD_INFO_BACKUP_AREA_LEN])) + { + obj->info->status = FEE_SECTOR_START_HAND_FINISH; + } + else + { + return; + } + if(Fee_CheckSectorIsEndHand(method, &data[FEE_SECTOR_END_HAND_IDX]) || Fee_CheckSectorIsEndHand(method, &data[FEE_SECTOR_END_HAND_IDX + FEE_SECTOR_HEAD_INFO_BACKUP_AREA_LEN])) + { + obj->info->status = FEE_SECTOR_END_HAND_FINISH; + } + else + { + return; + } + if(Fee_CheckSectorIsEnSector(method, &data[FEE_SECTOR_EN_SECTOR_IDX]) || Fee_CheckSectorIsEnSector(method, &data[FEE_SECTOR_EN_SECTOR_IDX + FEE_SECTOR_HEAD_INFO_BACKUP_AREA_LEN])) + { + obj->info->status = FEE_SECTOR_EN_FINISH; + } + else + { + return; + } +} + +__attribute__((always_inline)) static inline void Fee_CheckSectorIsValid(const Fee_SectorConfigType *obj, const Fee_MethodType *method, uint8_t *cache) +{ + /* When it is detected that the header information of a sector is not writable, */ + /* it will be checked to see if the sector is in an active state. */ + /* The sector initialization flag, the start of transport flag, the transport completion flag, */ + /* and the enable sector flag should be checked respectively. */ + /* Only when all flag bits are checked to be valid can they be considered active sectors.*/ + Fls_StateType flsState; + + flsState = method->read(obj->startAddr, cache, FEE_SECTOR_HEAD_SIZE); + + if(FLS_STATE_OK == flsState) + { + Fee_UpdateSectorStatus(obj, method->crc8, cache); + } + else if ((FLS_STATE_ECC_ERROR == flsState) || (FLS_STATE_READ_BACK_FAIL == flsState)) + { + flsState = method->read(FEE_SECTOR_BACKUP_HEAD_ADDR(obj), cache, FEE_SECTOR_HEAD_SIZE); + + if(FLS_STATE_OK == flsState) + { + Fee_UpdateSectorStatus(obj, method->crc8, cache); + } + else + { + obj->info->errors = FEE_SECTOR_READ_ERROR; + } + } + else if (FLS_STATE_NOT_WRITTEN == flsState) + { + obj->info->status = FEE_SECTOR_UNDEFINE; + } + else + { + obj->info->errors = FEE_SECTOR_READ_ERROR; + } + +} + +__attribute__((always_inline)) static inline void Fee_SectorInitInfo(const Fee_SectorConfigType *obj) +{ + obj->info->remAddr = obj->startAddr + FEE_SECTOR_HEAD_SIZE; + obj->info->headInfoAddr = obj->endAddr - FEE_SECTOR_HEAD_SIZE - FEE_BLOCK_HEAD_INFO_SIZE; + obj->info->searchAddr = obj->endAddr - FEE_SECTOR_HEAD_SIZE - FEE_BLOCK_HEAD_INFO_SIZE; + obj->info->errors = FEE_SECTOR_NOT_ERROR; + obj->info->status = FEE_SECTOR_UNDEFINE; +} + +__attribute__((always_inline)) static inline void Fee_SectorsInit(const Fee_SectorType *obj, const Fee_MethodType *method, void *cache) +{ + int sectorIdx; + + /* Reset the information of the sector runtime and check the status of the sector based on its header information. */ + + for(sectorIdx = 0; sectorIdx < obj->sectorSize; sectorIdx++) + { + Fee_SectorInitInfo(&obj->sectors[sectorIdx]); + } +} + +__attribute__((always_inline)) static inline bool Fee_CheckRemSpace(const Fee_SectorConfigType *obj, const Fee_BlockType *block) +{ + bool ret = false; + uint16_t freeSize; + int preFreeSize; + + /* Calculation of sector free space size: */ + /* Total space - Space occupied by block info - Space occupied by block data - 64Byte sector header information - 8-byte placeholder. */ + /* In order to prevent the area of block info and block data from crossing each other's boundaries, */ + /* at least one flash phrase size placeholder should be reserved. */ + + freeSize = obj->info->headInfoAddr - obj->info->remAddr; + preFreeSize = freeSize - FEE_BLOCKSIZE(block->cfg) - FEE_BLOCK_HEAD_INFO_SIZE - Fee_BLOCK_WRITE_ALIGNED_SIZE; + + if(preFreeSize > 0) + { + ret = true; + } + + return ret; +} + +__attribute__((always_inline)) static inline const Fee_SectorConfigType *Fee_GetFirstSector(const Fee_SectorType *obj) +{ + const Fee_SectorConfigType *ret = NULL; + + if(obj->sectors != NULL) + { + ret = &obj->sectors[0]; + } + + return ret; +} + +__attribute__((always_inline)) static inline const Fee_SectorConfigType *Fee_SearchValidSector(const Fee_SectorType *obj) +{ + const Fee_SectorConfigType *ret = NULL; + int sectorEnFinshCnt = 0; + int sectorIdx; + + for(sectorIdx = 0; sectorIdx < obj->sectorSize; sectorIdx++) + { + if((FEE_SECTOR_EN_FINISH == obj->sectors[sectorIdx].info->status) && (FEE_SECTOR_NOT_ERROR == obj->sectors[sectorIdx].info->errors)) + { + sectorEnFinshCnt++; + ret = &obj->sectors[sectorIdx]; + } + } + if(sectorEnFinshCnt != 1) + { + FEE_DBG_SEARCH_MULTIPLE_VALID_SECTOR_ERROR_ENTRY(); + ret = NULL; + } + return ret; +} + +__attribute__((always_inline)) static inline const Fee_SectorConfigType *Fee_SearchGcSector(const Fee_SectorType *obj) +{ + const Fee_SectorConfigType *ret = NULL; + bool gcSectorCnt = 0; + int sectorIdx; + + /* When switching from one sector to another, */ + /* first look for sectors with a status of either unint or not active. */ + + for(sectorIdx = 0; sectorIdx < obj->sectorSize; sectorIdx++) + { + if((obj->sectors[sectorIdx].info->status < FEE_SECTOR_EN_FINISH) && (FEE_SECTOR_NOT_ERROR == obj->sectors[sectorIdx].info->errors)) + { + gcSectorCnt++; + ret = &obj->sectors[sectorIdx]; + } + } + + if(gcSectorCnt != 1) + { + FEE_DBG_SEARCH_MULTIPLE_GC_SECTOR_ERROR_ENTRY(); + ret = NULL; + } + return ret; +} + +__attribute__((always_inline)) static inline void Fee_InitEraseSector(const Fee_SectorConfigType *obj) +{ + obj->info->eraseSectionIdx = 0; +} + +__attribute__((always_inline)) static inline void Fee_EraseSector(const Fee_SectorConfigType *obj, const Fee_MethodType *method) +{ + Fee_AddressType eraseAddr; + + /* When erasing a sector, */ + /* erase the sections of the N flash files that make up the sector in a time-sharing manner. */ + + if((obj->info->status != FEE_SECTOR_ACTIVE) && (obj->info->status != FEE_SECTOR_ERASE)) + { + if(obj->info->eraseSectionIdx < obj->eraseSectionNum) + { + eraseAddr = obj->startAddr + (obj->info->eraseSectionIdx * FEE_SECTION_LENGTH); + + if(ALIGNED((eraseAddr) + FEE_SECTION_LENGTH - 1, FEE_SECTION_LENGTH) > ALIGNED(eraseAddr, FEE_SECTION_LENGTH)) + { + obj->info->errors = FEE_SECTOR_ADDR_NOALIGNED; + } + else if(FLS_STATE_OK != method->erase(eraseAddr)) + { + obj->info->errors = FEE_SECTOR_ERASE_ERROR; + } + else + { + obj->info->eraseSectionIdx++; + } + } + else + { + obj->info->status = FEE_SECTOR_ERASE; + } + } +} + +__attribute__((always_inline)) static inline bool Fee_SectorWriteHeadMark(const Fee_MethodType *method, Fee_AddressType writeAddr, uint8_t *cache) +{ + bool ret = false; + + if(FLS_STATE_OK == method->write(writeAddr, cache, FEE_SECTOR_HEAD_INFO_LEN)) + { + ret = true; + } + + return ret; +} + +__attribute__((always_inline)) static inline void Fee_SectorWriteInitMark(const Fee_SectorConfigType *obj, const Fee_MethodType *method, uint8_t *cache) +{ + int idx; + + /* The data format of the flag bit of the sector header information consists of a start flag bit, */ + /* a status flag bit, a fill bit, and a crc check bit. */ + /* When assembling a flag bit, the check value of crc8 is written last. */ + if(((FEE_SECTOR_UNUSED == obj->info->status) || (FEE_SECTOR_ERASE == obj->info->status)) && (FEE_SECTOR_NOT_ERROR == obj->info->errors)) + { + obj->info->status = FEE_SECTOR_INIT; + + cache[FEE_SECTOR_HEAD_MARK_IDX] = FEE_SECTOR_VALID_WORD; + cache[FEE_SECTOR_HEAD_FLAG_IDX] = FEE_SECTOR_INIT_FLAG_WORD; + cache[FEE_SECTOR_HEAD_FILL_IDX] = FEE_SECTOR_FILL_WORD; + cache[FEE_SECTOR_HEAD_CRC_IDX] = method->crc8(cache, FEE_SECTOR_HEAD_CRC_LEN); + + for(idx = 0; idx < FEE_SECTOR_HEAD_INFO_BACKUP_AREA_LEN; idx++) + { + cache[FEE_SECTOR_HEAD_INFO_BACKUP_AREA_LEN + idx] = cache[idx]; + } + + if(Fee_SectorWriteHeadMark(method, obj->startAddr + FEE_SECTOR_INIT_IDX, cache)) + { + Fee_SectorWriteHeadMark(method, FEE_SECTOR_BACKUP_HEAD_ADDR(obj) + FEE_SECTOR_INIT_IDX, cache); + obj->info->status = FEE_SECTOR_INIT_FINISH; + } + else + { + obj->info->errors = FEE_SECTOR_WRITE_INIT_MARK_ERROR; + } + } + else + { + obj->info->errors = FEE_SECTOR_WRITE_INIT_MARK_ERROR; + } +} + +__attribute__((always_inline)) static inline void Fee_SectorWriteStartHandMark(const Fee_SectorConfigType *obj, const Fee_MethodType *method, uint8_t *cache) +{ + int idx; + + /* The data format of the flag bit of the sector header information consists of a start flag bit, */ + /* a status flag bit, a fill bit, and a crc check bit. */ + /* When assembling a flag bit, the check value of crc8 is written last. */ + + if((FEE_SECTOR_INIT_FINISH == obj->info->status) && (FEE_SECTOR_NOT_ERROR == obj->info->errors)) + { + obj->info->status = FEE_SECTOR_START_HAND; + + cache[FEE_SECTOR_HEAD_MARK_IDX] = FEE_SECTOR_VALID_WORD; + cache[FEE_SECTOR_HEAD_FLAG_IDX] = FEE_SECTOR_INIT_START_FLAG_WORD; + cache[FEE_SECTOR_HEAD_FILL_IDX] = FEE_SECTOR_FILL_WORD; + cache[FEE_SECTOR_HEAD_CRC_IDX] = method->crc8(cache, FEE_SECTOR_HEAD_CRC_LEN); + + for(idx = 0; idx < FEE_SECTOR_HEAD_INFO_BACKUP_AREA_LEN; idx++) + { + cache[FEE_SECTOR_HEAD_INFO_BACKUP_AREA_LEN + idx] = cache[idx]; + } + + if(Fee_SectorWriteHeadMark(method, obj->startAddr + FEE_SECTOR_START_HAND_IDX, cache)) + { + Fee_SectorWriteHeadMark(method, FEE_SECTOR_BACKUP_HEAD_ADDR(obj) + FEE_SECTOR_START_HAND_IDX, cache); + obj->info->status = FEE_SECTOR_START_HAND_FINISH; + } + else + { + obj->info->errors = FEE_SECTOR_WRITE_START_MARK_ERROR; + } + } + else + { + obj->info->errors = FEE_SECTOR_WRITE_START_MARK_ERROR; + } +} + +__attribute__((always_inline)) static inline void Fee_SectorWriteEndHandMark(const Fee_SectorConfigType *obj, const Fee_MethodType *method, uint8_t *cache) +{ + int idx; + + /* The data format of the flag bit of the sector header information consists of a start flag bit, */ + /* a status flag bit, a fill bit, and a crc check bit. */ + /* When assembling a flag bit, the check value of crc8 is written last. */ + + if(FEE_SECTOR_START_HAND_FINISH == obj->info->status) + { + obj->info->status = FEE_SECTOR_END_HAND; + + cache[FEE_SECTOR_HEAD_MARK_IDX] = FEE_SECTOR_VALID_WORD; + cache[FEE_SECTOR_HEAD_FLAG_IDX] = FEE_SECTOR_INIT_WRITE_END_FLAG_WORD; + cache[FEE_SECTOR_HEAD_FILL_IDX] = FEE_SECTOR_FILL_WORD; + cache[FEE_SECTOR_HEAD_CRC_IDX] = method->crc8(cache, FEE_SECTOR_HEAD_CRC_LEN); + + for(idx = 0; idx < FEE_SECTOR_HEAD_INFO_BACKUP_AREA_LEN; idx++) + { + cache[FEE_SECTOR_HEAD_INFO_BACKUP_AREA_LEN + idx] = cache[idx]; + } + + if(Fee_SectorWriteHeadMark(method, obj->startAddr + FEE_SECTOR_END_HAND_IDX, cache)) + { + Fee_SectorWriteHeadMark(method, FEE_SECTOR_BACKUP_HEAD_ADDR(obj) + FEE_SECTOR_END_HAND_IDX, cache); + obj->info->status = FEE_SECTOR_END_HAND_FINISH; + } + else + { + obj->info->errors = FEE_SECTOR_WRITE_END_MARK_ERROR; + } + } + else + { + obj->info->errors = FEE_SECTOR_WRITE_END_MARK_ERROR; + } +} + +__attribute__((always_inline)) static inline void Fee_SectorWriteEnableSectorMark(const Fee_SectorConfigType *obj, const Fee_MethodType *method, uint8_t *cache) +{ + int idx; + + /* The data format of the flag bit of the sector header information consists of a start flag bit, */ + /* a status flag bit, a fill bit, and a crc check bit. */ + /* When assembling a flag bit, the check value of crc8 is written last. */ + + if(FEE_SECTOR_END_HAND_FINISH == obj->info->status) + { + obj->info->status = FEE_SECTOR_EN; + + cache[FEE_SECTOR_HEAD_MARK_IDX] = FEE_SECTOR_VALID_WORD; + cache[FEE_SECTOR_HEAD_FLAG_IDX] = FEE_SECTOR_INIT_ENABLE_FLAG_WORD; + cache[FEE_SECTOR_HEAD_FILL_IDX] = FEE_SECTOR_FILL_WORD; + cache[FEE_SECTOR_HEAD_CRC_IDX] = method->crc8(cache, FEE_SECTOR_HEAD_CRC_LEN); + + for(idx = 0; idx < FEE_SECTOR_HEAD_INFO_BACKUP_AREA_LEN; idx++) + { + cache[FEE_SECTOR_HEAD_INFO_BACKUP_AREA_LEN + idx] = cache[idx]; + } + + if(Fee_SectorWriteHeadMark(method, obj->startAddr + FEE_SECTOR_EN_SECTOR_IDX, cache)) + { + Fee_SectorWriteHeadMark(method, FEE_SECTOR_BACKUP_HEAD_ADDR(obj) + FEE_SECTOR_EN_SECTOR_IDX, cache); + obj->info->status = FEE_SECTOR_EN_FINISH; + } + else + { + obj->info->errors = FEE_SECTOR_WRITE_EN_MARK_ERROR; + } + } + else + { + obj->info->errors = FEE_SECTOR_WRITE_EN_MARK_ERROR; + } +} + +__attribute__((always_inline)) static inline void Fee_SectorFillHeadInfo(const Fee_SectorConfigType *obj, const Fee_MethodType *method, uint8_t *cache) +{ + Fee_AddressType writeAddr; + Fee_AddressType startWriteAddr = obj->startAddr + (FEE_SECTOR_HEAD_MARK_NUM * FEE_SECTOR_HEAD_INFO_LEN); + Fee_AddressType endWriteAddr = obj->startAddr + FEE_SECTOR_HEAD_SIZE; + + /* After initializing the header information of the sector, */ + /* in order to ensure the security of the sector's flash operation, */ + /* the remaining unused header information should be filled in to initialize to ensure the certainty of the sector.*/ + + if(FEE_SECTOR_EN_FINISH == obj->info->status) + { + memset((void *)cache, FEE_SECTOR_FILL_WORD, ALIGN8BYTE(FEE_SECTOR_HEAD_INFO_LEN)); + + for(writeAddr = startWriteAddr; writeAddr < endWriteAddr; writeAddr = writeAddr + Fee_BLOCK_WRITE_ALIGNED_SIZE) + { + if(FLS_STATE_OK != method->write(writeAddr, cache, ALIGN8BYTE(FEE_SECTOR_HEAD_INFO_LEN))) + { + obj->info->errors |= FEE_SECTOR_WRITE_HEAD_FILL_ERROR; + break; + } + } + + startWriteAddr = FEE_SECTOR_BACKUP_HEAD_ADDR(obj) + (FEE_SECTOR_HEAD_MARK_NUM * FEE_SECTOR_HEAD_INFO_LEN); + endWriteAddr = FEE_SECTOR_BACKUP_HEAD_ADDR(obj) + FEE_SECTOR_HEAD_SIZE; + + for(writeAddr = startWriteAddr; writeAddr < endWriteAddr; writeAddr = writeAddr + Fee_BLOCK_WRITE_ALIGNED_SIZE) + { + if(FLS_STATE_OK != method->write(writeAddr, cache, ALIGN8BYTE(FEE_SECTOR_HEAD_INFO_LEN))) + { + obj->info->errors |= FEE_SECTOR_WRITE_HEAD_FILL_ERROR; + break; + } + } + } + else + { + obj->info->errors |= FEE_SECTOR_WRITE_HEAD_FILL_ERROR; + } +} + +__attribute__((always_inline)) static inline Fee_SectorStatusType Fee_SectorGetStatus(const Fee_SectorConfigType *obj) +{ + return obj->info->status; +} + +__attribute__((always_inline)) static inline void Fee_SectorWriteHeadInfo(const Fee_SectorConfigType *obj, const Fee_MethodType *method, uint8_t *cache) +{ + if(FEE_SECTOR_UNUSED == obj->info->status) + { + Fee_SectorWriteInitMark(obj, method, cache); + Fee_SectorWriteStartHandMark(obj, method, cache); + Fee_SectorWriteEndHandMark(obj, method, cache); + Fee_SectorWriteEnableSectorMark(obj, method, cache); + Fee_SectorFillHeadInfo(obj, method, cache); + } +} + +__attribute__((always_inline)) static inline const Fee_BlockType *Fee_MatchBlock(const Fee_SectorType *obj, const Fee_MethodType *method, uint8_t *data) +{ + const Fee_BlockType *ret = NULL; + uint8_t calcCrc; + uint8_t *blockCrc; + uint32_t *blockEnMark; + uint16_t *blockNumber; + int blockIdx; + + /* Block info parses the format according to the protocol, */ + /* and after performing integrity checks, the description information of the block will be paired to ensure that the description of the block info can access the corresponding block data. */ + + blockCrc = (uint8_t *)&(data[FEE_BLOCK_HEAD_INFO_CRC8_IDX]); + calcCrc = method->crc8((void *)data, FEE_BLOCK_CALC_HEAD_INFO_CRC8_LEN); + + if((*blockCrc) == calcCrc) + { + blockEnMark = (uint32_t *)&(data[FEE_BLOCK_HEAD_INFO_START_INFO_IDX]); + blockNumber = (uint16_t *)&(data[FEE_BLOCK_HEAD_INFO_BLOCK_NUMBER_IDX]); + + if(FEE_BLOCK_HEAD_INFO_START_INFO == (*blockEnMark)) + { + for(blockIdx = 0; blockIdx < obj->blockSize; blockIdx++) + { + if(Fee_BlockCheckBlockNumber(obj->blocks[blockIdx].cfg, *blockNumber)) + { + ret = &obj->blocks[blockIdx]; + break; + } + } + } + } + return ret; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _FEE_SECTOR_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/nvm/fee/fee_trace.h b/cva_asw_m0118/SDK/middleware/nvm/fee/fee_trace.h new file mode 100644 index 0000000..8cf7e03 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/fee/fee_trace.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FEE_TRACE_H_ +#define _FEE_TRACE_H_ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +/*! \addtogroup Flash EEPROM Emulation + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +#ifndef FEE_DBG_MAIN_FSM_ERROR_ENTRY +#define FEE_DBG_MAIN_FSM_ERROR_ENTRY() +#endif + +#ifndef FEE_DBG_GC_FSM_ERROR_ENTRY +#define FEE_DBG_GC_FSM_ERROR_ENTRY() +#endif + +#ifndef FEE_DBG_GC_COPY_FSM_ERROR_ENTRY +#define FEE_DBG_GC_COPY_FSM_ERROR_ENTRY() +#endif + +#ifndef FEE_DBG_INITIALIZATION_FSM_ERROR_ENTRY +#define FEE_DBG_INITIALIZATION_FSM_ERROR_ENTRY() +#endif + +#ifndef FEE_DBG_SEARCH_MULTIPLE_VALID_SECTOR_ERROR_ENTRY +#define FEE_DBG_SEARCH_MULTIPLE_VALID_SECTOR_ERROR_ENTRY() +#endif + +#ifndef FEE_DBG_SEARCH_MULTIPLE_GC_SECTOR_ERROR_ENTRY +#define FEE_DBG_SEARCH_MULTIPLE_GC_SECTOR_ERROR_ENTRY() +#endif + +#ifndef FEE_DBG_STORAGE_ERROR_ENTRY +#define FEE_DBG_STORAGE_ERROR_ENTRY() +#endif + +#ifndef FEE_DBG_GC_WRITE_BLOCK_DATA_ERROR_ENTRY +#define FEE_DBG_GC_WRITE_BLOCK_DATA_ERROR_ENTRY() +#endif + +#ifndef FEE_DBG_GC_WRITE_BLOCK_HEAD_INFO_ERROR_ENTRY +#define FEE_DBG_GC_WRITE_BLOCK_HEAD_INFO_ERROR_ENTRY() +#endif + +#ifndef FEE_DBG_GC_READ_BLOCK_DATA_ERROR_ENTRY +#define FEE_DBG_GC_READ_BLOCK_DATA_ERROR_ENTRY() +#endif + +#ifndef FEE_DBG_GC_ERASE_ACTIVE_SECTOR_ERROR_ENTRY +#define FEE_DBG_GC_ERASE_ACTIVE_SECTOR_ERROR_ENTRY() +#endif + +#ifndef FEE_DBG_GC_WRITE_INIT_MARK_ERROR_ENTRY +#define FEE_DBG_GC_WRITE_INIT_MARK_ERROR_ENTRY() +#endif + +#ifndef FEE_DBG_GC_WRITE_START_MARK_ERROR_ENTRY +#define FEE_DBG_GC_WRITE_START_MARK_ERROR_ENTRY() +#endif + +#ifndef FEE_DBG_GC_WRITE_END_MARK_ERROR_ENTRY +#define FEE_DBG_GC_WRITE_END_MARK_ERROR_ENTRY() +#endif + +#ifndef FEE_DBG_GC_WRITE_ENABLE_MARK_ERROR_ENTRY +#define FEE_DBG_GC_WRITE_ENABLE_MARK_ERROR_ENTRY() +#endif + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _FEE_TRACE_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/nvm/fee/fee_types.h b/cva_asw_m0118/SDK/middleware/nvm/fee/fee_types.h new file mode 100644 index 0000000..f94daed --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/fee/fee_types.h @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FEE_TYPES_H_ +#define _FEE_TYPES_H_ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "fee_sector.h" +#include "fee_jobs.h" +#include "fee_extra.h" + +/*! \addtogroup Flash EEPROM Emulation + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The return value type of the public method of the fee module. + */ +typedef enum +{ + FEE_RETURN_OK = 0X00, + FEE_RETURN_NOT_OK = 0X01, +} Fee_ReturnType; + +/*! \brief fee module global state type. + */ +typedef enum +{ + FEE_STATUS_UNINIT = 0x00, + FEE_STATUS_IDLE = 0x01, + FEE_STATUS_READ = 0x02, + FEE_STATUS_WRITE = 0x03, + FEE_STATUS_GC = 0x04, + FEE_STATUS_UNKNOW = 0x05, + FEE_STATUS_ERROR = 0x06, +} Fee_StatusType; + +/*! \brief Returns the type of result that the module has processed this request. + */ +typedef enum +{ + FEE_JOB_RESULT_OK = 0x00, + FEE_JOB_RESULT_NOT_OK = 0x01, + FEE_JOB_RESULT_PENDING = 0x02, + FEE_JOB_RESULT_BL_INCONSISTENT = 0x03, + FEE_JOB_RESULT_BL_INVALID = 0x04, +} Fee_JobResultType; + +/*! \brief Internal main state type of the fee module. + */ +typedef enum +{ + FEE_MAIN_FUN_FSM_INITIALIZATION = 0x00, + FEE_MAIN_FUN_FSM_RETRIEVAL = 0x01, + FEE_MAIN_FUN_FSM_IDLE = 0X02, + FEE_MAIN_FUN_FSM_READ = 0x03, + FEE_MAIN_FUN_FSM_WRITE = 0x04, + FEE_MAIN_FUN_FSM_GC = 0x05, + FEE_MAIN_FUN_FSM_ERROR = 0x06, +} Fee_MainFunFsmType; + +/*! \brief The configuration type of the fee. + */ +typedef struct _Fee_ConfigType_ +{ + uint32_t blockSize; +} Fee_ConfigType; + +/*! \brief The sub state type of the initialization main state of the fee module. + */ +typedef enum +{ + FEE_INITIALIZATION_SECTOR = 0x00, + FEE_INITIALIZATION_CHECK_SECTOR = 0x01, + FEE_INITIALIZATION_FIND_ACTIVE_SECTOR = 0x02, + FEE_INITIALIZATION_GC_REPAIR_SECTOR = 0x03, + FEE_INITIALIZATION_ERASE_SECTOR = 0x04, + FEE_INITIALIZATION_UNINITIALIZATION_ERASE_SECTOR = 0x05, + FEE_INITIALIZATION_UNINITIALIZATION = 0X06, + FEE_INITIALIZATION_FINISH = 0x07, + FEE_INITIALIZATION_ERROR = 0x08, +} Fee_InitializationFsmType; + +/*! \brief The sub state type of the feed's main page fee module state. + */ +typedef enum +{ + FEE_GC_INIT = 0x00, + FEE_GC_ERASE_BACKUPSECTOR = 0x01, + FEE_GC_START = 0x02, + FEE_GC_FOUND_BLOCK = 0x03, + FEE_GC_COPY = 0x04, + FEE_GC_ERASE_ACTIVESECTOR = 0x05, + FEE_GC_FINISH = 0x06, + FEE_GC_ERROR = 0x07, +} Fee_GcFsmType; + +/*! \brief The sub state type of the copy sub state of the feed's main page fee module state. + */ +typedef enum +{ + FEE_GC_COPY_WRITE_MARK = 0x01, + FEE_GC_COPY_INIT = 0x02, + FEE_GC_COPY_WRITEBLOCK = 0x04, + FEE_GC_COPY_FINISH = 0x05, + FEE_GC_COPY_ERROR = 0x06, +} Fee_GcCopyFsmType; + +/*! \brief Define the type of copy sub state execution results for the feed's main page fee module state. + */ +typedef enum +{ + FEE_GC_STATE_NO_ERROR = 0x00, + FEE_GC_STATE_UNKNOW_ERROR = 0x01, + FEE_GC_STATE_WRITE_ERROR = 0x02, + FEE_GC_STATE_READ_ERROR = 0x03, + FEE_GC_STATE_NOT_FOUND_BACKUPSECTOR = 0x04, + FEE_GC_STATE_ERASE_BACKUP_SECTOR_ERROR = 0x05, + FEE_GC_STATE_WRITE_INIT_MARK_ERROR = 0x06, + FEE_GC_STATE_COPY_ERROR = 0x07, + FEE_GC_STATE_ERASE_ACTIVE_SECTOR_ERROR = 0x08, + FEE_GC_STATE_WRITE_ENA_MARK_ERROR = 0x09, +} Fee_GcCopyStateType; + +/*! \brief Defines the type of runtime for page fee module. + */ +typedef struct _Fee_GcRuntimeType_ +{ + Fee_GcFsmType gcFsm; + Fee_GcCopyFsmType copyFsm; + const struct _Fee_SectorConfigType_* backupSector; + uint32_t blockCnt; + const struct _Fee_BlockType_* currentBlock; + Fee_AddressType searchAddr; + Fee_AddressType copySrcDataAddr; + Fee_GcCopyStateType state; +} Fee_GcRuntimeType; + +/*! \brief Define the type of feed module runtime. + */ +typedef struct _Fee_RunTimeType_ +{ + Fee_MainFunFsmType mainFunFsm; + Fee_InitializationFsmType initializationFsm; + struct _Fee_JobsType_* const jobs; + const struct _Fee_SectorConfigType_* activeSector; + struct _Fee_JobControlBlockType_* const job; + struct _Fee_GcRuntimeType_* const gcRuntime; + Fee_JobResultType jobResult; +} Fee_RunTimeType; + +/*! \brief Define the type of the fee object. + */ +typedef struct _FeeType_ +{ + const struct _Fee_SectorType_* sector; + const struct _Fee_MethodType_* flsMethod; + struct _Fee_RunTimeType_* runtime; + void* const buff; +} FeeType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _FEE_TYPES_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/nvm/fee/fee_version.h b/cva_asw_m0118/SDK/middleware/nvm/fee/fee_version.h new file mode 100644 index 0000000..c0f062f --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/fee/fee_version.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FEE_VERSION_H_ +#define _FEE_VERSION_H_ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +/*! \addtogroup Flash EEPROM Emulation + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/*! \brief Macro for the major version number of the software of the fee module. + */ +#if(defined FEE_SW_MAJOR_VERSION) +#error FEE_SW_MAJOR_VERSION already defined +#endif +#define FEE_SW_MAJOR_VERSION (1U) + +/*! \brief Macro for the software version number of the fee module. + */ +#if(defined FEE_SW_MINOR_VERSION) +#error FEE_SW_MINOR_VERSION already defined +#endif +#define FEE_SW_MINOR_VERSION (0U) + +/*! \brief Macro for the software patch version number of the fee module. + */ +#if(defined FEE_SW_PATCH_VERSION) +#error FEE_SW_PATCH_VERSION already defined +#endif +#define FEE_SW_PATCH_VERSION (0U) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Type of software version number of the fee module. + */ +typedef struct _Fee_VersionInfoType_ +{ + uint8_t sw_major_version; + uint8_t sw_minor_version; + uint8_t sw_patch_version; +} Fee_VersionInfoType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _FEE_VERSION_H_ */ \ No newline at end of file diff --git a/cva_asw_m0118/SDK/middleware/nvm/nvm.c b/cva_asw_m0118/SDK/middleware/nvm/nvm.c new file mode 100644 index 0000000..a52fc82 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/nvm.c @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include +#include "nvm_extra.h" +#include "nvm_block.h" +#include "nvm_queue.h" +#include "nvm.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ +void Nvm_Configure(const NvmType *obj) +{ + /* Initialize job queue. */ + Nvm_Queue_Init(obj->runtime->queue); + + /* Initialize mainfunction state machine. */ + obj->runtime->state = NVM_STATE_IDLE; + obj->runtime->nextState = FEE_STATE_INVALID; +} + +void Nvm_MainFunction(const NvmType *obj) +{ + /* Check if the state is illegal and if the state function is a null pointer. */ + if((FEE_STATE_INVALID > obj->runtime->state) && (NULL != obj->stateMachine[obj->runtime->state].fn)) + { + obj->stateMachine[obj->runtime->state].fn(obj); + } + + /* Check if the jump state is illegal and determine if there is a state that needs to be jumped. */ + if((FEE_STATE_INVALID > obj->runtime->nextState)) + { + /* Jump Status Management. */ + obj->runtime->state = obj->runtime->nextState; + obj->runtime->nextState = FEE_STATE_INVALID; + /* Check if there are entry functions for executing jump states. */ + if(NULL != obj->stateMachine[obj->runtime->state].onEntry) + { + /* Entry function for executing jump state. */ + obj->stateMachine[obj->runtime->state].onEntry(obj); + } + } +} + +Nvm_ReturnType Nvm_Read(const NvmType *obj, uint16_t blockNumber, uint8_t *dataBuffer) +{ + Nvm_ReturnType ret = NVM_RETURN_NOT_OK; + uint16_t blockIdx; + Nvm_QueueMemberType member; + uint8_t priority; + uint16_t blockBaseNumber; + uint16_t blockEcuNumber; + + /* Check if mainfunction can respond to read job. */ + if(NVM_STATE_UNINIT != obj->runtime->state) + { + /* Data required to initialize read job. */ + blockBaseNumber = NVM_GET_BLOCKNUMBER(blockNumber); + blockEcuNumber = NVM_GET_BLOCKDATASETNUMBER(blockNumber); + blockIdx = Nvm_Block_Search(obj->blockTable, blockBaseNumber); + priority = NVM_BLOCK_GET_PRIORITY(obj->blockTable, blockIdx); + + /* Check if the block is an undefined block. */ + if(NVM_BLOCK_INVALID_IDX != blockIdx) + { + /* Initialize read job as a member of the user job queue. */ + Nvm_Queue_InitMember(&member, blockIdx, blockEcuNumber, NVM_STATE_READ, priority, dataBuffer); + + /* Check if the user job queue is full. */ + if(NVM_RETURN_NOT_OK == Nvm_Queue_CheckFull(obj->runtime->queue)) + { + /* Insert read job members into the user job queue based on priority. */ + Nvm_Queue_Insert(obj->runtime->queue, &member); + ret = NVM_RETURN_OK; + } + } + } + + return ret; +} + +Nvm_ReturnType Nvm_ReadAll(const NvmType *obj) +{ + Nvm_ReturnType ret = NVM_RETURN_NOT_OK; + Nvm_QueueMemberType member; + + /* Check if mainfunction can respond to readAll job. */ + if(NVM_STATE_UNINIT != obj->runtime->state) + { + /* Initialize readAll job as a member of the system job queue. */ + NVM_QUEUE_SYSMEMBER(&member, NVM_STATE_READALL); + + /* Check if the system job queue is full */ + if(NVM_RETURN_NOT_OK == Nvm_Queue_CheckFull(obj->runtime->queue)) + { + /* Insert readAll job members into the system job queue based on priority. */ + Nvm_Queue_Insert(obj->runtime->queue, &member); + ret = NVM_RETURN_OK; + } + } + + return ret; +} + +Nvm_ReturnType Nvm_Write(const NvmType *obj, uint16_t blockNumber, uint8_t *dataBuffer) +{ + Nvm_ReturnType ret = NVM_RETURN_NOT_OK; + Nvm_QueueMemberType member; + uint8_t priority; + uint16_t blockIdx; + uint16_t blockBaseNumber; + uint16_t blockEcuNumber; + + /* Check if mainfunction can respond to write job. */ + if(NVM_STATE_UNINIT != obj->runtime->state) + { + /* Data required to initialize write job. */ + blockBaseNumber = NVM_GET_BLOCKNUMBER(blockNumber); + blockEcuNumber = NVM_GET_BLOCKDATASETNUMBER(blockNumber); + blockIdx = Nvm_Block_Search(obj->blockTable, blockBaseNumber); + priority = NVM_BLOCK_GET_PRIORITY(obj->blockTable, blockIdx); + + /* Check if the block is an undefined block. */ + if(NVM_BLOCK_INVALID_IDX != blockIdx) + { + /* Initialize write job as a member of the user job queue. */ + Nvm_Queue_InitMember(&member, blockIdx, blockEcuNumber, NVM_STATE_WRITE, priority, dataBuffer); + + /* Check if the user job queue is full. */ + if(NVM_RETURN_NOT_OK == Nvm_Queue_CheckFull(obj->runtime->queue)) + { + /* Insert write job members into the user job queue based on priority. */ + Nvm_Queue_Insert(obj->runtime->queue, &member); + ret = NVM_RETURN_OK; + } + } + } + + return ret; +} + +Nvm_ReturnType Nvm_WriteAll(const NvmType *obj) +{ + Nvm_ReturnType ret = NVM_RETURN_NOT_OK; + Nvm_QueueMemberType member; + + /* Check if mainfunction can respond to writeAll job. */ + if(NVM_STATE_UNINIT != obj->runtime->state) + { + /* Initialize writeAll job as a member of the system job queue. */ + NVM_QUEUE_SYSMEMBER(&member, NVM_STATE_WRITEALL); + + /* Check if the system job queue is full. */ + if(NVM_RETURN_NOT_OK == Nvm_Queue_CheckFull(obj->runtime->queue)) + { + /* Insert writeAll job members into the system job queue based on priority. */ + Nvm_Queue_Insert(obj->runtime->queue, &member); + ret = NVM_RETURN_OK; + } + } + + return ret; +} + +Nvm_ReturnType Nvm_Erase(const NvmType *obj, uint16_t blockNumber) +{ + Nvm_ReturnType ret = NVM_RETURN_NOT_OK; + Nvm_QueueMemberType member; + uint8_t priority; + uint16_t blockIdx; + uint16_t blockBaseNumber; + uint16_t blockEcuNumber; + uint8_t *dataBuffer; + + /* Check if mainfunction can respond to erase job. */ + if(NVM_STATE_UNINIT != obj->runtime->state) + { + /* Initialize the data required for erase job. */ + blockBaseNumber = NVM_GET_BLOCKNUMBER(blockNumber); + blockEcuNumber = NVM_GET_BLOCKDATASETNUMBER(blockNumber); + blockIdx = Nvm_Block_Search(obj->blockTable, blockBaseNumber); + priority = NVM_BLOCK_GET_PRIORITY(obj->blockTable, blockIdx); + dataBuffer = NVM_BLOCK_GET_ROM_BUFF_PTR(obj->blockTable, blockIdx, blockEcuNumber); + + /* Check if the block is an undefined block. */ + if(NVM_BLOCK_INVALID_IDX != blockIdx) + { + /* Initialize write job as a member of the user job queue. */ + Nvm_Queue_InitMember(&member, blockIdx, blockEcuNumber, NVM_STATE_ERASE, priority, dataBuffer); + + /* Check if the user job queue is full. */ + if(NVM_RETURN_NOT_OK == Nvm_Queue_CheckFull(obj->runtime->queue)) + { + /* Insert write job members into the user job queue based on priority. */ + Nvm_Queue_Insert(obj->runtime->queue, &member); + ret = NVM_RETURN_OK; + } + } + } + + return ret; +} + +Nvm_ReturnType Nvm_EraseAll(const NvmType *obj) +{ + Nvm_ReturnType ret = NVM_RETURN_NOT_OK; + Nvm_QueueMemberType member; + + /* Check if mainfunction can respond to writeAll job. */ + if(NVM_STATE_UNINIT != obj->runtime->state) + { + /* Initialize writeAll job as a member of the system job queue. */ + NVM_QUEUE_SYSMEMBER(&member, NVM_STATE_ERASEALL); + + /* Check if the system job queue is full. */ + if(NVM_RETURN_NOT_OK == Nvm_Queue_CheckFull(obj->runtime->queue)) + { + /* Insert writeAll job members into the system job queue based on priority. */ + Nvm_Queue_Insert(obj->runtime->queue, &member); + ret = NVM_RETURN_OK; + } + } + + return ret; +} + +void Nvm_CancelJob(const NvmType *obj) +{ + /* Remove unresponsive jobs from the user queue. */ + Nvm_Queue_RemoveLastItem(obj->runtime->queue); +} + +Nvm_stateType Nvm_GetStatus(const NvmType *obj) +{ + /* Obtain the internal state of NVM. */ + return obj->runtime->state; +} + +Nvm_BlockState Nvm_GetBlockStatus(const NvmType *obj, uint16_t blockNumber) +{ + Nvm_BlockState ret = NVM_REQ_ERROR; + uint16_t blockBaseNumber; + uint16_t blockDatasetNumber; + uint16_t blockIdx; + + blockBaseNumber = NVM_GET_BLOCKNUMBER(blockNumber); + blockDatasetNumber = NVM_GET_BLOCKDATASETNUMBER(blockNumber); + + /* Find the index of the block. */ + blockIdx = Nvm_Block_Search(obj->blockTable, blockBaseNumber); + + /* Check if the block is an undefined block. */ + if(NVM_BLOCK_INVALID_IDX != blockIdx) + { + /* Obtain the status of the block. */ + ret = NVM_BLOCK_GET_STATE(obj->blockTable, blockIdx, blockDatasetNumber); + } + + return ret; +} + +void Nvm_GetVersionInfo(Nvm_VersionInfoType *versionInfoPtr) +{ + /* Check if it is a null pointer. */ + if(NULL != versionInfoPtr) + { + versionInfoPtr->sw_major_version = NVM_SW_MAJOR_VERSION; + versionInfoPtr->sw_minor_version = NVM_SW_MINOR_VERSION; + versionInfoPtr->sw_patch_version = NVM_SW_PATCH_VERSION; + } +} diff --git a/cva_asw_m0118/SDK/middleware/nvm/nvm.h b/cva_asw_m0118/SDK/middleware/nvm/nvm.h new file mode 100644 index 0000000..7fba1cd --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/nvm.h @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _NVM_H_ +#define _NVM_H_ + +/*! \brief Contains public interface to various functions related + * to the NVM (NVRAM Manager) module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include +#include "nvm_types.h" +#include "nvm_version.h" + +/*! \addtogroup NVRAM Manager + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +/*! \brief Macro for the value range of the nvm module dataset section. + */ +#ifndef NVM_DATASET_SELECTION_BITS +#define NVM_DATASET_SELECTION_BITS (4) +#endif + +/*! \brief Macro for masking the value range of the nvm module dataset section. + */ +#define NVM_DATASET_SELECTION_MASK ((1 << NVM_DATASET_SELECTION_BITS) - 1) + +/*! \brief Macro for masking the value range of the nvm module dataset section. + */ +#define NVM_NUMBER_SELECTION_MASK (~NVM_DATASET_SELECTION_MASK) + +/*! \brief Macro for NVM module to obtain block id field in blocknumber. + */ +#define NVM_GET_BLOCKNUMBER(blockNumber) (blockNumber & NVM_NUMBER_SELECTION_MASK) + +/*! \brief NVM module obtains macro for dataset field in blocknumber. + */ +#define NVM_GET_BLOCKDATASETNUMBER(blockNumber) (blockNumber & NVM_DATASET_SELECTION_MASK) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Configures the NVM driver + * + * This function configures the NVM driver + * + * \param[in] obj : pointer to NVM driver instance + */ +extern void Nvm_Configure(const NvmType *obj); + +/*! \brief Main function of NVM driver + * + * This function is the main process of running the NVM driver + * + * \param[in] obj : pointer to NVM driver instance + */ +extern void Nvm_MainFunction(const NvmType *obj); + +/*! \brief Read the data from NVM + * + * This function reads the data from NVM with given parameters + * + * \param[in] obj : pointer to NVM driver instance + * \param[in] block : block to read + * \param[out] dataBuffer : pointer to the result data buffer + * \param[in] notificationPtr : pointer to the notification callback function + */ +extern Nvm_ReturnType Nvm_Read(const NvmType *obj, uint16_t blockNumber, uint8_t *dataBuffer); + +/*! \brief Read the all block data to NVM + * + * This function reads the data from NVM with given parameters + * + * \param[in] obj : pointer to NVM driver instance + */ +extern Nvm_ReturnType Nvm_ReadAll(const NvmType *obj); + +/*! \brief Write the data to NVM + * + * This function writed the data to NVM with given parameters + * + * \param[in] obj : pointer to FEE driver instance + * \param[in] block : block number to write + * \param[in] dataBuffer : pointer to the data buffer to write + * \param[in] notificationPtr : pointer to the notification callback function + */ +extern Nvm_ReturnType Nvm_Write(const NvmType *obj, uint16_t blockNumber, uint8_t *dataBuffer); + +/*! \brief Write the all block data + * + * This function writed the data to NVM with given parameters + * + * \param[in] obj : pointer to FEE driver instance + */ +extern Nvm_ReturnType Nvm_WriteAll(const NvmType *obj); + +/*! \brief Erase NVM Block + * + * This function Erase NVM Block with given parameters + * + * \param[in] obj : pointer to FEE driver instance + * \param[in] blockNumber : block to write + */ +extern Nvm_ReturnType Nvm_Erase(const NvmType *obj, uint16_t blockNumber); + +/*! \brief Erase NVM All Block + * + * This function Erase NVM All Block with given parameters + * + * \param[in] obj : pointer to FEE driver instance + */ +extern Nvm_ReturnType Nvm_EraseAll(const NvmType *obj); + +/*! \brief Get Nvm Status + * + * This function Get NVM module status with given parameters + * + * \param[in] obj : pointer to FEE driver instance + */ +extern Nvm_stateType Nvm_GetStatus(const NvmType *obj); + +/*! \brief Cancel Nvm Job + * + * This function Cancel NVM Queue Last Job + * + * \param[in] obj : pointer to FEE driver instance + */ +extern void Nvm_CancelJob(const NvmType *obj); + +/*! \brief Get Block Status + * + * This function Get NVM Block status with given parameters + * + * \param[in] obj : pointer to FEE driver instance + * \param[in] blockNumber : block + */ +extern Nvm_BlockState Nvm_GetBlockStatus(const NvmType *obj, uint16_t blockNumber); + +/*! \brief Get the version information of this driver + * + * This function gets the version information of this driver. + * + * \param[out] versionInfoPtr : pointer to the version object + */ +extern void Nvm_GetVersionInfo(Nvm_VersionInfoType *versionInfoPtr); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _NVM_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/nvm/nvm_block.c b/cva_asw_m0118/SDK/middleware/nvm/nvm_block.c new file mode 100644 index 0000000..b633e4f --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/nvm_block.c @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ +#include +#include "nvm_block.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the static + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ +void Nvm_Block_DataRepair(const Nvm_BlockType *obj, const Nvm_MethodType *method, uint16_t blockIdx, uint16_t datasetIdx) +{ + bool writeFlag = false; + uint8_t *mainBuff; + uint8_t *backupBuff; + uint8_t *tempBuff; + uint8_t *romBuff; + uint32_t copySize; + uint32_t dataSize; + + /* Obtain necessary data for performing block data validity checks. */ + mainBuff = NVM_BLOCK_GET_RAM_BUFF_PTR(obj, blockIdx, datasetIdx); + tempBuff = NVM_BLOCK_GET_TEMP_RAM_BUFF_PTR(obj, blockIdx); + romBuff = NVM_BLOCK_GET_ROM_BUFF_PTR(obj, blockIdx, datasetIdx); + copySize = Nvm_Block_CalcUseSize(obj, blockIdx); + dataSize = NVM_BLOCK_GET_DATASIZE(obj, blockIdx); + + /* Check if the block is configured with verification function. */ + if(NVM_BLOCK_IS_CRC(obj, blockIdx)) + { + /* Check if the block type is redundant. */ + if(NVM_BLOCK_IS_REDUNDANT(obj, blockIdx)) + { + /* Perform data checks on the main area. */ + Nvm_Block_IntegrityCheck(obj, blockIdx, NVM_BLOCK_MAIN_IDX, method); + /* Check whether the data validation result of the main area is invalid. */ + if(NVM_BLOCK_CRC_FAIL_MASK == NVM_BLOCK_GET_INTEGRITY(obj, blockIdx, NVM_BLOCK_MAIN_IDX)) + { + /* Obtain the backup data address of the redundant type block. */ + backupBuff = NVM_BLOCK_GET_RAM_BUFF_PTR(obj, blockIdx, NVM_BLOCK_BACKUP_IDX); + /* Perform data checks on the backup area */ + Nvm_Block_IntegrityCheck(obj, blockIdx, NVM_BLOCK_BACKUP_IDX, method); + /* Check whether the data validation result of the backup area is valid. */ + if(NVM_BLOCK_CRC_OK_MASK == NVM_BLOCK_GET_INTEGRITY(obj, blockIdx, NVM_BLOCK_BACKUP_IDX)) + { + /* Restore the data in the backup area to the main area. */ + memcpy(tempBuff, backupBuff, copySize); + writeFlag = true; + } + else + { + /* Restore data from the ROM region to the main region. */ + memcpy(tempBuff, romBuff, dataSize); + writeFlag = true; + } + } + } + else + { + /* Perform data checks on the main area. */ + Nvm_Block_IntegrityCheck(obj, blockIdx, datasetIdx, method); + /* Check whether the data validation result of the main area is invalid. */ + if(NVM_BLOCK_CRC_OK_MASK != NVM_BLOCK_GET_INTEGRITY(obj, blockIdx, datasetIdx)) + { + /* Restore data from the ROM region to the main region. */ + memcpy((void *)tempBuff, (void *)romBuff, dataSize); + writeFlag = true; + } + } + } + else + { + /* Initialize tempbuff. */ + memset((void *)tempBuff, NVM_BLOCK_RAMBUFF_DEFAULT_VALUE, ALIGN8BYTE(copySize)); + /* Check if the data in the main area is uninitialized. */ + if (0 == memcmp((void *)mainBuff, (void *)tempBuff, ALIGN8BYTE(copySize))) + { + /* Check if the block type is redundant. */ + if(NVM_BLOCK_IS_REDUNDANT(obj, blockIdx)) + { + /* Obtain the backup data address of the redundant type block. */ + backupBuff = NVM_BLOCK_GET_RAM_BUFF_PTR(obj, blockIdx, NVM_BLOCK_BACKUP_IDX); + + /* Check if the data in the backup area is uninitialized. */ + if (0 == memcmp((void *)backupBuff, tempBuff, ALIGN8BYTE(copySize))) + { + /* Restore data from ROM area to main and backup areas. */ + memcpy(tempBuff, romBuff, dataSize); + writeFlag = true; + } + else + { + /* Restore the data in the backup area to the main area. */ + memcpy(tempBuff, backupBuff, copySize); + writeFlag = true; + } + } + else + { + /* Restore data from ROM area to main and backup areas. */ + memcpy(tempBuff, romBuff, dataSize); + writeFlag = true; + } + } + else + { + /* Restore data from main area to block all area data. */ + memcpy(tempBuff, mainBuff, dataSize); + writeFlag = true; + } + } + + if(writeFlag) + { + /* Perform data recovery. */ + Nvm_Block_WriteDataToRamBlock(obj, method, blockIdx, datasetIdx, tempBuff); + } +} + +void Nvm_Block_SetDefaultVal(const Nvm_BlockType *obj, const Nvm_MethodType *method, uint16_t blockIdx, uint16_t datasetIdx) +{ + uint8_t *buff; + /* Initialize all data regions of the block with data from non rom regions. */ + buff = NVM_BLOCK_GET_TEMP_RAM_BUFF_PTR(obj, blockIdx); + Nvm_Block_GetRomData(obj, blockIdx, datasetIdx, buff); + Nvm_Block_WriteDataToRamBlock(obj, method, blockIdx, datasetIdx, buff); +} + +void Nvm_Block_ClrRamBuff(const Nvm_BlockType *obj, uint16_t blockIdx, uint16_t datasetIdx) +{ + uint8_t *mainRamBuff; + uint32_t dataSize; + + /* Initialize all initializable data regions of the dataset in the block. */ + dataSize = ALIGN8BYTE(Nvm_Block_CalcUseSize(obj, blockIdx)); + mainRamBuff = NVM_BLOCK_GET_RAM_BUFF_PTR(obj, blockIdx, datasetIdx); + + memset((void *)mainRamBuff, NVM_BLOCK_RAMBUFF_DEFAULT_VALUE, dataSize); +} + +void Nvm_Block_ClrBlockRamBuff(const Nvm_BlockType *obj, uint16_t blockIdx, uint16_t datasetIdx) +{ + /* Initialize all initializable data regions of the block. */ + if(NVM_BLOCK_IS_REDUNDANT(obj, blockIdx)) + { + Nvm_Block_ClrRamBuff(obj, blockIdx, NVM_BLOCK_MAIN_IDX); + Nvm_Block_ClrRamBuff(obj, blockIdx, NVM_BLOCK_BACKUP_IDX); + } + else + { + Nvm_Block_ClrRamBuff(obj, blockIdx, datasetIdx); + } +} + +void Nvm_Block_SetState(const Nvm_BlockType *obj, uint16_t blockIdx, uint16_t datasetIdx, Nvm_BlockState state) +{ + /* Set the status of the dataset in the block. */ + obj->items[blockIdx].info[datasetIdx].state = state; +} + +void Nvm_Block_SetInternalState(const Nvm_BlockType *obj, uint16_t blockIdx, uint16_t datasetIdx, Nvm_BlockState state) +{ + /* Set the internal processing status of the NVM for the dataset in the block. */ + obj->items[blockIdx].info[datasetIdx].internalState = state; +} + +void Nvm_Block_SetTempRamBuffDefaultVal(const Nvm_BlockType *obj, uint16_t blockIdx, uint16_t datasetIdx) +{ + /* Initialize the tempbuff of the block. */ + memset((void *)obj->items[blockIdx].tempRamBuffPtr, NVM_BLOCK_RAMBUFF_DEFAULT_VALUE, ALIGN8BYTE(Nvm_Block_CalcUseSize(obj, blockIdx))); +} + +uint32_t Nvm_Block_CalcUseSize(const Nvm_BlockType *obj, uint16_t blockIdx) +{ + uint32_t ret; + + /* Check if the block is configured with crc verification. */ + if(NVM_CRC8 == obj->items[blockIdx].crc) + { + /* Calculate the size used to store valid data in BLCOK. */ + ret = obj->items[blockIdx].dataSize + NVM_BLOCK_PLACEHOLDER_BYTES + NVM_BLOCK_CRC_BYTES; + } + else + { + /* Calculate the size used to store valid data in BLCOK. */ + ret = obj->items[blockIdx].dataSize + NVM_BLOCK_PLACEHOLDER_BYTES; + } + + return ret; +} + +void Nvm_Block_GetRomData(const Nvm_BlockType *obj, uint16_t blockIdx, uint8_t datasetIdx, uint8_t *data) +{ + uint8_t *romBuff; + + /* Obtain data from the rom area of the dataset in the block. */ + romBuff = NVM_BLOCK_GET_ROM_BUFF_PTR(obj, blockIdx, datasetIdx); + memcpy((void *)data, (void *)romBuff, NVM_BLOCK_GET_DATASIZE(obj, blockIdx)); +} + +bool Nvm_Block_GetWriteData(const Nvm_BlockType *obj, uint16_t blockIdx, uint8_t datasetIdx, const Nvm_MethodType *method, uint8_t *data) +{ + bool ret = true; + uint8_t integrity; + + + /* Check if the block type is redundant. */ + if(NVM_BLOCK_IS_REDUNDANT(obj, blockIdx)) + { + /* Perform data checks on the main area. */ + Nvm_Block_IntegrityCheck(obj, blockIdx, NVM_BLOCK_MAIN_IDX, method); + /* Perform data checks on the main area. */ + integrity = NVM_BLOCK_GET_INTEGRITY(obj, blockIdx, NVM_BLOCK_MAIN_IDX); + /* Check whether the data validation result of the main area is invalid. */ + if(NVM_BLOCK_CRC_OK_MASK == integrity) + { + /* Copy valid data */ + memcpy((void *)data, (void *)NVM_BLOCK_GET_RAM_BUFF_PTR(obj, blockIdx, NVM_BLOCK_MAIN_IDX), NVM_BLOCK_GET_DATASIZE(obj, blockIdx)); + } + else + { + /* Perform data checks on the backup area. */ + Nvm_Block_IntegrityCheck(obj, blockIdx, datasetIdx, method); + /* Perform data checks on the backup area. */ + integrity = NVM_BLOCK_GET_INTEGRITY(obj, blockIdx, NVM_BLOCK_BACKUP_IDX); + /* Check whether the data validation result of the backup area is invalid. */ + if(NVM_BLOCK_CRC_OK_MASK == integrity) + { + /* Copy valid data. */ + memcpy((void *)data, (void *)NVM_BLOCK_GET_RAM_BUFF_PTR(obj, blockIdx, NVM_BLOCK_BACKUP_IDX), NVM_BLOCK_GET_DATASIZE(obj, blockIdx)); + } + else + { + ret = false; + } + } + } + else + { + /* Perform data checks on the dataset area. */ + Nvm_Block_IntegrityCheck(obj, blockIdx, datasetIdx, method); + /* Perform data checks on the dataset area. */ + integrity = NVM_BLOCK_GET_INTEGRITY(obj, blockIdx, datasetIdx); + /* Check whether the data validation result of the dataset area is invalid. */ + if(NVM_BLOCK_CRC_OK_MASK == integrity) + { + /* Copy valid data. */ + memcpy((void *)data, (void *)NVM_BLOCK_GET_RAM_BUFF_PTR(obj, blockIdx, datasetIdx), NVM_BLOCK_GET_DATASIZE(obj, blockIdx)); + } + else + { + ret = false; + } + } + + return ret; +} + +void Nvm_Block_IntegrityCheck(const Nvm_BlockType *obj, uint16_t blockIdx, uint8_t datasetIdx, const Nvm_MethodType *method) +{ + uint8_t crc; + uint32_t crcLen; + uint8_t *mainRamBuff; + + /* Set the data validity flag bit of the dataset in the block to error */ + obj->items[blockIdx].info[datasetIdx].integrity = NVM_BLOCK_CRC_FAIL_MASK; + + /* Check if the block is configured with crc verification */ + if(NVM_BLOCK_IS_CRC(obj, blockIdx)) + { + /* The required data length, starting address, and parity bits for obtaining verification data */ + crcLen = NVM_BLOCK_GET_CRC_LEN(obj, blockIdx); + mainRamBuff = obj->items[blockIdx].buff[datasetIdx].ramBuffPtr; + crc = method->crc8(mainRamBuff, crcLen); + /* Compare check bits */ + if(crc == mainRamBuff[crcLen]) + { + /* Verification passed, configure the data validity flag as successful */ + obj->items[blockIdx].info[datasetIdx].integrity = NVM_BLOCK_CRC_OK_MASK; + } + } + else + { + /* Verification passed, configure the data validity flag as successful */ + obj->items[blockIdx].info[datasetIdx].integrity = NVM_BLOCK_CRC_OK_MASK; + } +} + +void Nvm_Block_WriteDataToBuff(const Nvm_BlockType *obj, const Nvm_MethodType *method, uint16_t blockIdx, uint16_t datasetIdx, uint8_t *data) +{ + uint8_t * buff; + uint32_t dataSize; + uint32_t crcLen; + + /* Write data to the corresponding RAM area based on blockid and dataset */ + buff = NVM_BLOCK_GET_RAM_BUFF_PTR(obj, blockIdx, datasetIdx); + dataSize = ALIGN8BYTE(Nvm_Block_CalcUseSize(obj, blockIdx)); + + memset((void *)buff, NVM_BLOCK_RAMBUFF_DEFAULT_VALUE, ALIGN8BYTE(Nvm_Block_CalcUseSize(obj, blockIdx))); + memcpy((void *)buff, (void *)data, dataSize); + + if(NVM_BLOCK_IS_CRC(obj, blockIdx)) + { + crcLen = NVM_BLOCK_GET_CRC_LEN(obj, blockIdx); + buff[crcLen] = method->crc8(buff, crcLen); + } +} + +void Nvm_Block_WriteDataToRamBlock(const Nvm_BlockType *obj, const Nvm_MethodType *method, uint16_t blockIdx, uint16_t datasetIdx, uint8_t *data) +{ + /* If the type of the block is redundant, the data will be written to the main and backup areas. */ + /* Otherwise, the data will be written to the dataset area. */ + if(NVM_BLOCK_IS_REDUNDANT(obj, blockIdx)) + { + Nvm_Block_WriteDataToBuff(obj, method, blockIdx, NVM_BLOCK_MAIN_IDX, data); + Nvm_Block_WriteDataToBuff(obj, method, blockIdx, NVM_BLOCK_BACKUP_IDX, data); + } + else + { + Nvm_Block_WriteDataToBuff(obj, method, blockIdx, datasetIdx, data); + } +} + +uint16_t Nvm_Block_Search(const Nvm_BlockType *obj, uint16_t blockNumber) +{ + uint16_t retBlock = NVM_BLOCK_INVALID_IDX; + uint16_t blockStartIdx = 0; + uint16_t blockMiddleIdx = (obj->itemsNum - 1) / 2; + uint16_t blockEndIdx = obj->itemsNum - 1; + bool retFlag = false; + + while(false == retFlag) + { + /* If the current block and the input block are the same */ + if(blockNumber == obj->items[blockMiddleIdx].number) + { + /* Returns the index of the block */ + retBlock = blockMiddleIdx; + retFlag = true; + } + else + { + /* Currently, there are only two or fewer blocks left that are not found, then check the other block */ + if((blockEndIdx - blockStartIdx) <= 1) + { + retFlag = true; + if(blockNumber == obj->items[blockEndIdx].number) + { + retBlock = blockEndIdx; + } + } + else + { + /* In descending order, first determine whether it is in the right range, */ + /* and then check whether it is in the left range */ + if(obj->items[blockMiddleIdx].number < blockNumber) + { + blockStartIdx = blockMiddleIdx + 1; + } + else + { + blockEndIdx = blockMiddleIdx - 1; + } + + /* Calculate Median */ + blockMiddleIdx = blockEndIdx + blockStartIdx; + blockMiddleIdx /= 2; + } + } + } + + return retBlock; +} diff --git a/cva_asw_m0118/SDK/middleware/nvm/nvm_block.h b/cva_asw_m0118/SDK/middleware/nvm/nvm_block.h new file mode 100644 index 0000000..8c09da4 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/nvm_block.h @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _NVM_BLOCK_H_ +#define _NVM_BLOCK_H_ + +/*! \brief Contains public interface to various functions related + * to the NVM (NVRAM Manager) module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include +#include "nvm_types.h" + +/*! \addtogroup NVRAM Manager + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +/*! \brief Define a macro for rampoff initialization data. + */ +#define NVM_BLOCK_RAMBUFF_DEFAULT_VALUE (0x00) + +/*! \brief Macro defining invalid block index. + */ +#define NVM_BLOCK_INVALID_IDX (0xFFFF) + +/*! \brief Define macros with invalid datasets. + */ +#define NVM_DATASET_INVALID_IDX (0xFFFF) + +/*! \brief The highest priority macro for the job. + */ +#define NVM_BLOCK_HIGHT_PRIORITY (0) + +/*! \brief Define the placeholder length for the effective storage of data in a block. + */ +#define NVM_BLOCK_PLACEHOLDER_BYTES (0) + +/*! \brief Define the CRC length for effective storage of data in a block. + */ +#define NVM_BLOCK_CRC_BYTES (1) + +/*! \brief Define macros that failed data validation. + */ +#define NVM_BLOCK_CRC_FAIL_MASK (0x00) + +/*! \brief Define macros for successful data validation. + */ +#define NVM_BLOCK_CRC_OK_MASK (0x01) + +/*! \brief Macro that defines the dataset value of the main region. + */ +#define NVM_BLOCK_MAIN_IDX (0) + +/*! \brief Macro that defines the dataset value of the backup region. + */ +#define NVM_BLOCK_BACKUP_IDX (1) + +/*! \brief Macro defining the number of failed retry attempts for request feed operations. + */ +#define NVM_BLOCK_RETRY_NUM (3) + +/*! \brief Define a macro to determine whether the block type is immediate. + */ +#define NVM_BLOCK_IS_IMMEDIATE(obj, blockIdx) (obj->items[blockIdx].immediate) + +/*! \brief Define a macro to determine whether the block is configured with CRC. + */ +#define NVM_BLOCK_IS_CRC(obj, blockIdx) (NVM_CRC8 == obj->items[blockIdx].crc) + +/*! \brief Define a macro to determine whether a block is of normal type. + */ +#define NVM_BLOCK_IS_NORMAL(obj, blockIdx) (NVM_BLOCK_NORMAL == obj->items[blockIdx].type) + +/*! \brief Define a macro to determine whether a block is a redundant type. + */ +#define NVM_BLOCK_IS_REDUNDANT(obj, blockIdx) (NVM_BLOCK_REDUNDANT == obj->items[blockIdx].type) + +/*! \brief Define a macro to determine whether a block is a dataset type. + */ +#define NVM_BLOCK_IS_DATASET(obj, blockIdx) (NVM_BLOCK_DATASET == obj->items[blockIdx].type) + +/*! \brief Define a macro to obtain the datasetN checksum bit in a block. + */ +#define NVM_BLOCK_GET_INTEGRITY(obj, blockIdx, datasetIdx) (obj->items[blockIdx].info[datasetIdx].integrity) + +/*! \brief Define a macro to obtain the status of datasetN in a block. + */ +#define NVM_BLOCK_GET_STATE(obj, blockIdx, datasetIdx) (obj->items[blockIdx].info[datasetIdx].state) + +/*! \brief Define a macro to obtain the internal management status of datasetN in a block. + */ +#define NVM_BLOCK_GET_INT_STATE(obj, blockIdx, datasetIdx) (obj->items[blockIdx].info[datasetIdx].internalState) + +/*! \brief Define a macro to obtain the number of datasets in a block. + */ +#define NVM_BLOCK_GET_DATASETNUM(obj, blockIdx) (obj->items[blockIdx].datasetNum) + +/*! \brief Define macros for obtaining priority in blocks. + */ +#define NVM_BLOCK_GET_PRIORITY(obj, blockIdx) (obj->items[blockIdx].priority) + +/*! \brief Define macros for obtaining blockrambuff addresses. + */ +#define NVM_BLOCK_GET_RAM_BUFF_PTR(obj, blockIdx, datasetIdx) ((uint8_t *)obj->items[blockIdx].buff[datasetIdx].ramBuffPtr) + +/*! \brief Define macros for obtaining block tempbuff addresses. + */ +#define NVM_BLOCK_GET_TEMP_RAM_BUFF_PTR(obj, blockIdx) ((uint8_t *)obj->items[blockIdx].tempRamBuffPtr) + +/*! \brief Define macros for obtaining block rombuff addresses. + */ +#define NVM_BLOCK_GET_ROM_BUFF_PTR(obj, blockIdx, datasetIdx) ((uint8_t *)obj->items[blockIdx].buff[datasetIdx].romBuffPtr) + +/*! \brief Define macros for obtaining block data length. + */ +#define NVM_BLOCK_GET_DATASIZE(obj, blockIdx) (obj->items[blockIdx].dataSize) + +/*! \brief Define macros for obtaining block crc length. + */ +#define NVM_BLOCK_GET_CRC_LEN(obj, blockIdx) (obj->items[blockIdx].dataSize + NVM_BLOCK_PLACEHOLDER_BYTES) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ +void Nvm_Block_Init(const Nvm_BlockType *obj); +void Nvm_Block_DataRepair(const Nvm_BlockType *obj, const Nvm_MethodType *method, uint16_t blockIdx, uint16_t datasetIdx); +void Nvm_Block_SetDefaultVal(const Nvm_BlockType *obj, const Nvm_MethodType *method, uint16_t blockIdx, uint16_t datasetIdx); +void Nvm_Block_ClrRamBuff(const Nvm_BlockType *obj, uint16_t blockIdx, uint16_t datasetIdx); +void Nvm_Block_ClrBlockRamBuff(const Nvm_BlockType *obj, uint16_t blockIdx, uint16_t datasetIdx); +void Nvm_Block_SetState(const Nvm_BlockType *obj, uint16_t blockIdx, uint16_t datasetIdx, Nvm_BlockState state); +void Nvm_Block_SetInternalState(const Nvm_BlockType *obj, uint16_t blockIdx, uint16_t datasetIdx, Nvm_BlockState state); +void Nvm_Block_SetTempRamBuffDefaultVal(const Nvm_BlockType *obj, uint16_t blockIdx, uint16_t datasetIdx); +uint32_t Nvm_Block_CalcUseSize(const Nvm_BlockType *obj, uint16_t blockIdx); +void Nvm_Block_GetRomData(const Nvm_BlockType *obj, uint16_t blockIdx, uint8_t datasetIdx, uint8_t *data); +bool Nvm_Block_GetWriteData(const Nvm_BlockType *obj, uint16_t blockIdx, uint8_t datasetIdx, const Nvm_MethodType *method, uint8_t *data); +void Nvm_Block_WriteDataToBuff(const Nvm_BlockType *obj, const Nvm_MethodType *method, uint16_t blockIdx, uint16_t datasetIdx, uint8_t *data); +void Nvm_Block_IntegrityCheck(const Nvm_BlockType *obj, uint16_t blockIdx, uint8_t ecu, const Nvm_MethodType *method); +void Nvm_Block_WriteDataToRamBlock(const Nvm_BlockType *obj, const Nvm_MethodType *method, uint16_t blockIdx, uint16_t datasetIdx, uint8_t *data); +uint16_t Nvm_Block_Search(const Nvm_BlockType *obj, uint16_t blockNumber); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _NVM_BLOCK_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/nvm/nvm_extra.h b/cva_asw_m0118/SDK/middleware/nvm/nvm_extra.h new file mode 100644 index 0000000..c28e76b --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/nvm_extra.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _NVM_EXTRA_H_ +#define _NVM_EXTRA_H_ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +/*! \addtogroup NVRAM Manager + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +/*! \brief Define N-byte aligned macros. + */ +#ifndef ALIGNBYTE +#define ALIGNBYTE(size, n) ((size + n - 1) & ~(n - 1)) +#endif + +/*! \brief Define 4-byte aligned macros. + */ +#ifndef ALIGN4BYTE +#define ALIGN4BYTE(size) (ALIGNBYTE(size, 4)) +#endif + +/*! \brief Define 8-byte aligned macros. + */ +#ifndef ALIGN8BYTE +#define ALIGN8BYTE(size) (ALIGNBYTE(size, 8)) +#endif + +/*! \brief Define 64-byte aligned macros. + */ +#ifndef ALIGN64BYTE +#define ALIGN64BYTE(size) (ALIGNBYTE(size, 64)) +#endif + +/*! \brief Define address aligned macros. + */ +#ifndef ALIGNED +#define ALIGNED(val, alncnt) (((uint32_t)val) & ~(alncnt - 1)) +#endif +/******************************************************************************* + * the typedefs + ******************************************************************************/ +/*! \brief Define the type of the Notification return value. + */ +typedef enum +{ + NVM_JOBFINISHNOTIFICATION = 0x00, + NVM_JOBERRORNOTIFICATION = 0x01, +} NVM_NotificationType; + +/*! \brief Define the type of return value for lower level module operations. + */ +typedef enum +{ + NVM_JOB_RESULT_OK = 0x00, + NVM_JOB_RESULT_NOT_OK = 0x01, + NVM_JOB_RESULT_PENDING = 0x02, + NVM_JOB_RESULT_BL_INCONSISTENT = 0x03, + NVM_JOB_RESULT_BL_INVALID = 0x04, +} NVM_JobResultType; + +/*! \brief Define the type of return value for lower level module status. + */ +typedef enum +{ + NVM_STATUS_IDLE = 0x01, + NVM_STATUS_READ = 0x02, + NVM_STATUS_WRITE = 0x03, + NVM_STATUS_GC = 0x04, + NVM_STATUS_UNKNOW = 0x05, + NVM_STATUS_ERROR = 0x06, +} Nvm_StatusType; + +/*! \brief Define the type of virtual function for Notification. + */ +typedef void (*NvmNotificationPtrType)(NVM_NotificationType notificationNumber); + +/*! \brief Define the type of virtual function for writing lower level module operations. + */ +typedef bool (*Nvm_writeMethodType)(uint16_t blockNumber, uint8_t *dataBuffer, NvmNotificationPtrType notificationPtr); + +/*! \brief Define virtual function types for read lower level module operations. + */ +typedef bool (*Nvm_readMethodType)(uint16_t blockNumber, uint16_t blockOffset, uint8_t *dataBuffer, NvmNotificationPtrType notificationPtr); + +/*! \brief Define virtual function types for calculating crc8. + */ +typedef uint8_t (*Nvm_calcCrc8Type)(void *sAddr, uint32_t size); + +/*! \brief Define virtual function types for lower level module job handle result. + */ +typedef NVM_JobResultType (*Nvm_getJobResultType)(void); + +/*! \brief Define virtual function types for lower level module module status. + */ +typedef Nvm_StatusType (*Nvm_GetStatusType)(void); + +/*! \brief Define the type of the nvm operation lower level module method. + */ +typedef struct _Nvm_MethodType_ +{ + Nvm_writeMethodType write; + Nvm_readMethodType read; + Nvm_calcCrc8Type crc8; + Nvm_getJobResultType getJobResult; + Nvm_GetStatusType getStatus; +} Nvm_MethodType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _NVM_EXTRA_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/nvm/nvm_queue.c b/cva_asw_m0118/SDK/middleware/nvm/nvm_queue.c new file mode 100644 index 0000000..10ee900 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/nvm_queue.c @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "nvm_queue.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define NVM_QUEUE_FULL(OBJ) (OBJ->index >= OBJ->memberNum) +#define NVM_QUEUE_EMPTY(OBJ) (OBJ->index == 0) + +#define NVM_QUEUE_BLOCK_UNVALID (0xFFFF) +#define NVM_QUEUE_DATASET_UNVALID (0xFFFF) +#define NVM_QUEUE_PRIORITY_UNVALID (0xFF) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the static + ******************************************************************************/ +static void Nvm_Queue_Append(Nvm_QueueType *obj, Nvm_QueueMemberType *member); + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void Nvm_Queue_Init(Nvm_QueueType *obj) +{ + uint8_t idx; + /* Initialize all members of the queue. */ + for(idx = 0; idx < obj->memberNum; idx++) + { + obj->members[idx].blockIdx = NVM_QUEUE_BLOCK_UNVALID; + obj->members[idx].datasetIdx = NVM_QUEUE_DATASET_UNVALID; + obj->members[idx].op = FEE_STATE_INVALID; + obj->members[idx].priority = NVM_QUEUE_PRIORITY_UNVALID; + obj->members[idx].state = NVM_QUEUEMEMBERSTATE_UNUSED; + } + + /* The index value of the queue points to the header of the queue. */ + obj->index = 0; +} + +void Nvm_Queue_InitMember(Nvm_QueueMemberType *member, uint16_t blockIdx, uint16_t datasetIdx, Nvm_stateType op, uint8_t priority, uint8_t *databuff) +{ + /* Initialize members of the queue. */ + member->blockIdx = blockIdx; + member->datasetIdx = datasetIdx; + member->op = op; + member->databuff = databuff; + member->priority = priority; + member->state = NVM_QUEUEMEMBERSTATE_USED; +} + +void Nvm_Queue_Insert(Nvm_QueueType *obj, Nvm_QueueMemberType *member) +{ + uint8_t localIdx; + + /* Check if the queue is empty. */ + if(NVM_RETURN_NOT_OK == Nvm_Queue_CheckEmpty(obj)) + { + /* Insert members into the queue according to priority. */ + for(localIdx = obj->index; localIdx > 0; localIdx--) + { + if(obj->members[localIdx - 1].priority > member->priority) + { + if(NVM_QUEUEMEMBERSTATE_LOCK != obj->members[localIdx - 1].state) + { + obj->members[localIdx] = obj->members[localIdx - 1]; + } + else + { + break; + } + } + else + { + break; + } + } + + obj->members[localIdx] = *member; + obj->members[localIdx].state = NVM_QUEUEMEMBERSTATE_USED; + obj->index++; + } + else + { + /* Append member to queue. */ + Nvm_Queue_Append(obj, member); + } +} + +void Nvm_Queue_RemoveLastItem(Nvm_QueueType *obj) +{ + Nvm_QueueMemberType member; + + /* Set the member of the queue to the default value. */ + member.blockIdx = NVM_QUEUE_BLOCK_UNVALID; + member.datasetIdx = NVM_QUEUE_DATASET_UNVALID; + member.op = FEE_STATE_INVALID; + member.priority = NVM_QUEUE_PRIORITY_UNVALID; + member.state = NVM_QUEUEMEMBERSTATE_UNUSED; + member.databuff = NULL; + + /* Remove member from queue. */ + if(NVM_QUEUEMEMBERSTATE_LOCK != obj->members[obj->index - 1].state) + { + obj->members[obj->index - 1] = member; + obj->index--; + } +} + +void Nvm_Queue_RemoveFirstItem(Nvm_QueueType *obj) +{ + uint8_t localIdx; + + /* Check if the queue is not empty. */ + if(NVM_RETURN_NOT_OK == Nvm_Queue_CheckEmpty(obj)) + { + /* Remove member from queue. */ + for(localIdx = 0; localIdx < obj->index; localIdx++) + { + if((localIdx + 1) >= obj->index) + { + /* Set the member of the queue to the default value. */ + obj->members[localIdx].blockIdx = NVM_QUEUE_BLOCK_UNVALID; + obj->members[localIdx].datasetIdx = NVM_QUEUE_DATASET_UNVALID; + obj->members[localIdx].op = FEE_STATE_INVALID; + obj->members[localIdx].priority = NVM_QUEUE_PRIORITY_UNVALID; + obj->members[localIdx].state = NVM_QUEUEMEMBERSTATE_UNUSED; + } + else + { + obj->members[localIdx] = obj->members[localIdx + 1]; + } + } + obj->index--; + } +} + +Nvm_ReturnType Nvm_Queue_CheckFull(Nvm_QueueType *obj) +{ + Nvm_ReturnType ret = NVM_RETURN_NOT_OK; + + /* When the index value points to the end of the queue, it indicates that the queue is full. */ + if(obj->index >= obj->memberNum) + { + ret = NVM_RETURN_OK; + } + return ret; +} + +Nvm_ReturnType Nvm_Queue_CheckEmpty(Nvm_QueueType *obj) +{ + Nvm_ReturnType ret = NVM_RETURN_NOT_OK; + + /* When the index value points to the queue header, it indicates that the queue is empty. */ + if(obj->index == 0) + { + ret = NVM_RETURN_OK; + } + + return ret; +} + +static void Nvm_Queue_Append(Nvm_QueueType *obj, Nvm_QueueMemberType *member) +{ + /* Append member to the end of the queue. */ + obj->members[obj->index] = (*member); + obj->members[obj->index].state = NVM_QUEUEMEMBERSTATE_USED; + obj->index++; +} diff --git a/cva_asw_m0118/SDK/middleware/nvm/nvm_queue.h b/cva_asw_m0118/SDK/middleware/nvm/nvm_queue.h new file mode 100644 index 0000000..8fd183b --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/nvm_queue.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _NVM_QUEUE_H_ +#define _NVM_QUEUE_H_ + +/*! \brief Contains public interface to various functions related + * to the NVM (NVRAM Manager) module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include +#include "nvm_types.h" + +/*! \addtogroup NVRAM Manager + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +/*! \brief Define macro to obtain whether queue header members already exist. + */ +#define NVM_QUEUE_FISTMEMBER_VALID(OBJ) (NVM_QUEUEMEMBERSTATE_UNUSED != OBJ->members[0].state) + +/*! \brief Define a macro to obtain the operation attribute of queue header members. + */ +#define NVM_QUEUE_FISTMEMBER_OP(OBJ) (OBJ->members[0].op) + +/*! \brief Define macros for adding system queue members. + */ +#define NVM_QUEUE_SYSMEMBER(member, op) Nvm_Queue_InitMember(member, NVM_BLOCK_INVALID_IDX, NVM_DATASET_INVALID_IDX, op, NVM_BLOCK_HIGHT_PRIORITY, NULL) + +/*! \brief Define macros for locking queue header members. + */ +#define NVM_QUEUE_LOCK_FIRST_JOB(obj) obj->members[0].state = NVM_QUEUEMEMBERSTATE_LOCK + +/*! \brief Define macros for obtaining queue header members. + */ +#define NVM_QUEUE_FIRST_JOB(obj) obj->members[0] + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ +void Nvm_Queue_Init(Nvm_QueueType *obj); +void Nvm_Queue_InitMember(Nvm_QueueMemberType *member, uint16_t blockIdx, uint16_t datasetIdx, Nvm_stateType op, uint8_t priority, uint8_t *databuff); +void Nvm_Queue_Insert(Nvm_QueueType *obj, Nvm_QueueMemberType *member); +void Nvm_Queue_RemoveLastItem(Nvm_QueueType *obj); +void Nvm_Queue_RemoveFirstItem(Nvm_QueueType *obj); +Nvm_ReturnType Nvm_Queue_CheckFull(Nvm_QueueType *obj); +Nvm_ReturnType Nvm_Queue_CheckEmpty(Nvm_QueueType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _NVM_QUEUE_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/nvm/nvm_statemachine.c b/cva_asw_m0118/SDK/middleware/nvm/nvm_statemachine.c new file mode 100644 index 0000000..85e782f --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/nvm_statemachine.c @@ -0,0 +1,908 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "nvm_statemachine.h" +#include "nvm_queue.h" +#include "nvm_block.h" +#include "nvm_extra.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ +/*! \brief Macro that defines whether to complete immediate writing. + */ +#define NVM_IMMEDIATE_WRITE_FINISH(obj) (NVM_IMMEDIATEWRITEFSM_FINISH == obj->runtime->immediateWriteJob->job) + +/*! \brief Define macros that immediately fail to write. + */ +#define NVM_IMMEDIATE_WRITE_FAIL(obj) (NVM_IMMEDIATEWRITEFSM_WRITEERROR == obj->runtime->immediateWriteJob->job) + +/*! \brief Define macros that immediately write errors. + */ +#define NVM_IMMEDIATE_WRITE_FATAL(obj) (NVM_IMMEDIATEWRITEFSM_ERROR == obj->runtime->immediateWriteJob->job) + +/*! \brief Define immediate read completion macros. + */ +#define NVM_IMMEDIATE_READ_FINISH(obj) (NVM_IMMEDIATEREADFSM_FINISH == obj->runtime->immediateReadJob->job) + +/*! \brief Define macros that immediately fail to read. + */ +#define NVM_IMMEDIATE_READ_FAIL(obj) (NVM_IMMEDIATEREADFSM_READERROR == obj->runtime->immediateReadJob->job) + +/*! \brief Define macros for immediate read errors. + */ +#define NVM_IMMEDIATE_READ_FATAL(obj) (NVM_IMMEDIATEREADFSM_ERROR == obj->runtime->immediateReadJob->job) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ +static void Nvm_StateMachine_Immediate_Read_Entry(const NvmType *obj, uint16_t blockIdx, uint16_t datasetIdx, uint8_t retry, NvmNotificationPtrType notificationPtr); +static void Nvm_StateMachine_Immediate_Read(const NvmType *obj); +static void Nvm_StateMachine_Immediate_Write_Entry(const NvmType *obj, uint16_t blockIdx, uint16_t datasetIdx, uint8_t retry, NvmNotificationPtrType notificationPtr); +static void Nvm_StateMachine_Immediate_Write(const NvmType *obj); + +/******************************************************************************* + * the functions + ******************************************************************************/ +void Nvm_StateMachine_Idle(const NvmType *obj) +{ + /* Check if the lower level module status is idle. */ + if(NVM_STATUS_IDLE == obj->method->getStatus()) + { + /* Check if the job queue is empty. */ + if(NVM_RETURN_NOT_OK == Nvm_Queue_CheckEmpty(obj->runtime->queue)) + { + /* Check if the header members of the queue are valid. */ + if(NVM_QUEUE_FISTMEMBER_VALID(obj->runtime->queue)) + { + /* Lock the header member of the queue */ + NVM_QUEUE_LOCK_FIRST_JOB(obj->runtime->queue); + /* Responding to job requests. */ + obj->runtime->nextState = NVM_QUEUE_FISTMEMBER_OP(obj->runtime->queue); + } + else + { + /* When the header member of the queue is an invalid request, the member will be removed. */ + Nvm_Queue_RemoveFirstItem(obj->runtime->queue); + } + } + } +} + +void Nvm_StateMachine_Read_Entry(const NvmType *obj) +{ + uint16_t localBlockIdx; + uint16_t localDatasetIdx; + + localBlockIdx = NVM_QUEUE_FIRST_JOB(obj->runtime->queue).blockIdx; + localDatasetIdx = NVM_QUEUE_FIRST_JOB(obj->runtime->queue).datasetIdx; + + Nvm_Block_SetState(obj->blockTable, localBlockIdx, localDatasetIdx, NVM_REQ_PENDING); + + obj->runtime->readJob->blockIdx = localBlockIdx; + obj->runtime->readJob->datasetIdx = localDatasetIdx; + obj->runtime->readJob->cpyBuff = NVM_BLOCK_GET_RAM_BUFF_PTR(obj->blockTable, localBlockIdx, localDatasetIdx); + obj->runtime->readJob->userBuff = NVM_QUEUE_FIRST_JOB(obj->runtime->queue).databuff; + obj->runtime->readJob->datasize = NVM_BLOCK_GET_DATASIZE(obj->blockTable, localBlockIdx); +} + +void Nvm_StateMachine_Read(const NvmType *obj) +{ + /* Verify the data validity of the block. */ + Nvm_Block_DataRepair(obj->blockTable, obj->method, obj->runtime->readJob->blockIdx, obj->runtime->readJob->datasetIdx); + + /* Copy block data to user buff. */ + memcpy((void *)obj->runtime->readJob->userBuff, obj->runtime->readJob->cpyBuff, obj->runtime->readJob->datasize); + + /* Mark the external state of the block as NVM_REQ_OK. */ + Nvm_Block_SetState(obj->blockTable, obj->runtime->readJob->blockIdx, obj->runtime->readJob->datasetIdx, NVM_REQ_OK); + /* Remove the request. */ + Nvm_Queue_RemoveFirstItem(obj->runtime->queue); + /* Switch nvm state to idle. */ + obj->runtime->nextState = NVM_STATE_IDLE; +} + +void Nvm_StateMachine_Write_Entry(const NvmType *obj) +{ + uint16_t localBlockIdx; + uint16_t localDatasetIdx; + + localBlockIdx = NVM_QUEUE_FIRST_JOB(obj->runtime->queue).blockIdx; + localDatasetIdx = NVM_QUEUE_FIRST_JOB(obj->runtime->queue).datasetIdx; + + Nvm_Block_SetState(obj->blockTable, localBlockIdx, localDatasetIdx, NVM_REQ_PENDING); + + obj->runtime->writeJob->blockIdx = localBlockIdx; + obj->runtime->writeJob->datasetIdx = localDatasetIdx; + obj->runtime->writeJob->blockDatabuff = NVM_BLOCK_GET_TEMP_RAM_BUFF_PTR(obj->blockTable, localBlockIdx); + obj->runtime->writeJob->userBuff = NVM_QUEUE_FIRST_JOB(obj->runtime->queue).databuff; + obj->runtime->writeJob->useSize = NVM_BLOCK_GET_DATASIZE(obj->blockTable, localBlockIdx); + obj->runtime->writeJob->job = NVM_WRITEFSM_INIT; + + Nvm_Block_SetTempRamBuffDefaultVal(obj->blockTable, localBlockIdx, localDatasetIdx); +} + +void Nvm_StateMachine_Write(const NvmType *obj) +{ + switch(obj->runtime->writeJob->job) + { + case NVM_WRITEFSM_INIT: + { + /* If the type of the block is REDUNDANT, the state machine will be marked as a redundant write state. */ + /* If not, it will be judged whether it is an immediate write state. */ + /* If not, the state machine will be marked as a normal write state. */ + /* Otherwise, it will be marked as an immediate write state. */ + memcpy((void *)obj->runtime->writeJob->blockDatabuff, (void *)obj->runtime->writeJob->userBuff, obj->runtime->writeJob->useSize); + + if(NVM_BLOCK_IS_REDUNDANT(obj->blockTable, obj->runtime->writeJob->blockIdx)) + { + obj->runtime->writeJob->job = NVM_WRITEFSM_REDUNDANT_MAIN; + } + else if(NVM_BLOCK_IS_IMMEDIATE(obj->blockTable, obj->runtime->writeJob->blockIdx)) + { + Nvm_StateMachine_Immediate_Write_Entry(obj, obj->runtime->writeJob->blockIdx, obj->runtime->writeJob->datasetIdx, NVM_BLOCK_RETRY_NUM, NULL); + obj->runtime->writeJob->job = NVM_WRITEFSM_IMMEDIATE; + } + else + { + obj->runtime->writeJob->job = NVM_WRITEFSM_NORMAL; + } + break; + } + case NVM_WRITEFSM_IMMEDIATE: + { + /* If the immediate write execution is successful or an error occurs, */ + /* mark the state machine to the read back state, otherwise mark the state machine to the normal state. */ + Nvm_StateMachine_Immediate_Write(obj); + if(NVM_IMMEDIATE_WRITE_FINISH(obj) || NVM_IMMEDIATE_WRITE_FATAL(obj)) + { + Nvm_StateMachine_Immediate_Read_Entry(obj, obj->runtime->writeJob->blockIdx, obj->runtime->writeJob->datasetIdx, NVM_BLOCK_RETRY_NUM, NULL); + obj->runtime->writeJob->job = NVM_WRITEFSM_READBACK; + } + else if(NVM_IMMEDIATE_WRITE_FAIL(obj)) + { + obj->runtime->writeJob->job = NVM_WRITEFSM_NORMAL; + } + break; + } + case NVM_WRITEFSM_REDUNDANT_MAIN: + { + /* Execute the write main area of a REDUNDANT type block. */ + obj->runtime->writeJob->blockBackUp = false; + obj->runtime->writeJob->datasetIdx = NVM_BLOCK_MAIN_IDX; + if(NVM_BLOCK_IS_IMMEDIATE(obj->blockTable, obj->runtime->writeJob->blockIdx)) + { + Nvm_StateMachine_Immediate_Write_Entry(obj, obj->runtime->writeJob->blockIdx, obj->runtime->writeJob->datasetIdx, NVM_BLOCK_RETRY_NUM, NULL); + obj->runtime->writeJob->job = NVM_WRITEFSM_IMMEDIATE; + } + else + { + obj->runtime->writeJob->job = NVM_WRITEFSM_NORMAL; + } + break; + } + case NVM_WRITEFSM_REDUNDANT_BACKUP: + { + /* Execute the write backup area of a REDUNDANT type block. */ + obj->runtime->writeJob->blockBackUp = true; + obj->runtime->writeJob->datasetIdx = NVM_BLOCK_BACKUP_IDX; + if(NVM_BLOCK_IS_IMMEDIATE(obj->blockTable, obj->runtime->writeJob->blockIdx)) + { + Nvm_StateMachine_Immediate_Write_Entry(obj, obj->runtime->writeJob->blockIdx, obj->runtime->writeJob->datasetIdx, NVM_BLOCK_RETRY_NUM, NULL); + obj->runtime->writeJob->job = NVM_WRITEFSM_IMMEDIATE; + } + else + { + obj->runtime->writeJob->job = NVM_WRITEFSM_NORMAL; + } + break; + } + case NVM_WRITEFSM_READBACK: + { + /* Performing operations to read back data. */ + Nvm_StateMachine_Immediate_Read(obj); + if(NVM_IMMEDIATE_READ_FINISH(obj) || NVM_IMMEDIATE_READ_FATAL(obj)) + { + obj->runtime->writeJob->job = NVM_WRITEFSM_CHECK; + } + else if(NVM_IMMEDIATE_READ_FAIL(obj)) + { + obj->runtime->writeJob->job = NVM_WRITEFSM_NORMAL; + } + break; + } + case NVM_WRITEFSM_CHECK: + { + /* Check the validity of data within the block. */ + Nvm_Block_DataRepair(obj->blockTable, obj->method, obj->runtime->writeJob->blockIdx, obj->runtime->writeJob->datasetIdx); + Nvm_Block_SetState(obj->blockTable, obj->runtime->writeJob->blockIdx, obj->runtime->writeJob->datasetIdx, NVM_BLOCK_GET_INT_STATE(obj->blockTable, obj->runtime->writeJob->blockIdx, obj->runtime->writeJob->datasetIdx)); + if(NVM_BLOCK_IS_REDUNDANT(obj->blockTable, obj->runtime->writeJob->blockIdx)) + { + if(obj->runtime->writeJob->blockBackUp) + { + obj->runtime->writeJob->job = NVM_WRITEFSM_FINISH; + }else + { + obj->runtime->writeJob->job = NVM_WRITEFSM_REDUNDANT_BACKUP; + } + } + else + { + obj->runtime->writeJob->job = NVM_WRITEFSM_FINISH; + } + break; + } + case NVM_WRITEFSM_NORMAL: + { + /* Write data to the ram area of the block. */ + Nvm_Block_WriteDataToRamBlock(obj->blockTable, obj->method, obj->runtime->writeJob->blockIdx, obj->runtime->writeJob->datasetIdx, obj->runtime->writeJob->userBuff); + Nvm_Block_SetState(obj->blockTable, obj->runtime->writeJob->blockIdx, obj->runtime->writeJob->datasetIdx, NVM_REQ_OK); + if(NVM_BLOCK_IS_REDUNDANT(obj->blockTable, obj->runtime->writeJob->blockIdx)) + { + if(obj->runtime->writeJob->blockBackUp) + { + obj->runtime->writeJob->job = NVM_WRITEFSM_FINISH; + } + else + { + obj->runtime->writeJob->job = NVM_WRITEFSM_REDUNDANT_BACKUP; + } + } + else + { + obj->runtime->writeJob->job = NVM_WRITEFSM_FINISH; + } + break; + } + case NVM_WRITEFSM_FINISH: + { + /* Complete response request. */ + Nvm_Queue_RemoveFirstItem(obj->runtime->queue); + obj->runtime->nextState = NVM_STATE_IDLE; + break; + } + case NVM_WRITEFSM_WRITEERROR: + { + /* Complete response request. */ + Nvm_Queue_RemoveFirstItem(obj->runtime->queue); + obj->runtime->nextState = NVM_STATE_IDLE; + break; + } + default: + { + break; + } + } +} + +void Nvm_StateMachine_ReadAll_Entry(const NvmType *obj) +{ + obj->runtime->readAllJob->job = NVM_READALLFSM_READBLOCK; + obj->runtime->readAllJob->blockIdx = 0; +} + +void Nvm_StateMachine_ReadAll(const NvmType *obj) +{ + switch(obj->runtime->readAllJob->job) + { + case NVM_READALLFSM_READBLOCK: + { + /* Mark the state machine as finished after traversing all blocks. */ + if(obj->runtime->readAllJob->blockIdx < obj->blockTable->itemsNum) + { + obj->runtime->readAllJob->datasetIdx = 0; + obj->runtime->readAllJob->job = NVM_READALLFSM_READENTRY; + } + else + { + obj->runtime->readAllJob->job = NVM_READALLFSM_FINISH; + } + break; + } + case NVM_READALLFSM_READENTRY: + { + /* Execute the preparation program before immediate reading. */ + if(obj->runtime->readAllJob->datasetIdx < NVM_BLOCK_GET_DATASETNUM(obj->blockTable, obj->runtime->readAllJob->blockIdx)) + { + Nvm_Block_SetState(obj->blockTable, obj->runtime->readAllJob->blockIdx, obj->runtime->readAllJob->datasetIdx, NVM_REQ_PENDING); + Nvm_StateMachine_Immediate_Read_Entry(obj, obj->runtime->readAllJob->blockIdx, obj->runtime->readAllJob->datasetIdx, NVM_BLOCK_RETRY_NUM, NULL); + obj->runtime->readAllJob->job = NVM_READALLFSM_READ; + } + else + { + obj->runtime->readAllJob->blockIdx++; + obj->runtime->readAllJob->job = NVM_READALLFSM_READBLOCK; + } + break; + } + case NVM_READALLFSM_READ: + { + /* Execute immediate read. */ + Nvm_StateMachine_Immediate_Read(obj); + if(NVM_IMMEDIATE_READ_FINISH(obj) || NVM_IMMEDIATE_READ_FAIL(obj) || NVM_IMMEDIATE_READ_FATAL(obj)) + { + obj->runtime->readAllJob->job = NVM_READALLFSM_CHECK; + } + break; + } + case NVM_READALLFSM_CHECK: + { + /* Check the validity of data within the block. */ + Nvm_Block_DataRepair(obj->blockTable, obj->method, obj->runtime->readAllJob->blockIdx, obj->runtime->readAllJob->datasetIdx); + Nvm_Block_SetState(obj->blockTable, obj->runtime->readAllJob->blockIdx, obj->runtime->readAllJob->datasetIdx, NVM_BLOCK_GET_INT_STATE(obj->blockTable, obj->runtime->readAllJob->blockIdx, obj->runtime->readAllJob->datasetIdx)); + obj->runtime->readAllJob->datasetIdx++; + obj->runtime->readAllJob->job = NVM_READALLFSM_READENTRY; + break; + } + case NVM_READALLFSM_FINISH: + { + /* Complete response request. */ + Nvm_Queue_RemoveFirstItem(obj->runtime->queue); + obj->runtime->nextState = NVM_STATE_IDLE; + break; + } + case NVM_READALLFSM_ERROR: + { + /* Complete response request. */ + Nvm_Queue_RemoveFirstItem(obj->runtime->queue); + obj->runtime->nextState = NVM_STATE_IDLE; + break; + } + default: + { + break; + } + } +} + +void Nvm_StateMachine_WriteAll_Entry(const NvmType *obj) +{ + obj->runtime->writeAllJob->job = NVM_WRITEALLFSM_WRITEBLOCK; + obj->runtime->writeAllJob->blockIdx = 0; +} + +void Nvm_StateMachine_WriteAll(const NvmType *obj) +{ + switch(obj->runtime->writeAllJob->job) + { + case NVM_WRITEALLFSM_WRITEBLOCK: + { + /* Mark the state machine as finished after traversing all blocks. */ + if(obj->runtime->writeAllJob->blockIdx < obj->blockTable->itemsNum) + { + if(NVM_BLOCK_IS_NORMAL(obj->blockTable, obj->runtime->writeAllJob->blockIdx)) + { + obj->runtime->writeAllJob->datasetIdx = 0; + obj->runtime->writeAllJob->job = NVM_WRITEALLFSM_WRITEENTRY; + } + else + { + obj->runtime->writeAllJob->blockIdx++; + } + } + else + { + obj->runtime->writeAllJob->job = NVM_WRITEALLFSM_FINISH; + } + break; + } + case NVM_WRITEALLFSM_WRITEENTRY: + { + /* Execute the preparation program before immediate writeing. */ + if(obj->runtime->writeAllJob->datasetIdx < NVM_BLOCK_GET_DATASETNUM(obj->blockTable, obj->runtime->writeAllJob->blockIdx)) + { + obj->runtime->writeAllJob->blockDatabuff = NVM_BLOCK_GET_TEMP_RAM_BUFF_PTR(obj->blockTable, obj->runtime->writeAllJob->blockIdx); + if(Nvm_Block_GetWriteData(obj->blockTable, obj->runtime->writeAllJob->blockIdx, obj->runtime->writeAllJob->datasetIdx, obj->method, obj->runtime->writeAllJob->blockDatabuff)) + { + Nvm_Block_SetState(obj->blockTable, obj->runtime->writeAllJob->blockIdx, obj->runtime->writeAllJob->datasetIdx, NVM_REQ_PENDING); + Nvm_StateMachine_Immediate_Write_Entry(obj, obj->runtime->writeAllJob->blockIdx, obj->runtime->writeAllJob->datasetIdx, NVM_BLOCK_RETRY_NUM, NULL); + obj->runtime->writeAllJob->job = NVM_WRITEALLFSM_WRITE; + } + else + { + obj->runtime->writeAllJob->datasetIdx++; + } + } + else + { + obj->runtime->writeAllJob->blockIdx++; + obj->runtime->writeAllJob->job = NVM_WRITEALLFSM_WRITEBLOCK; + } + break; + } + case NVM_WRITEALLFSM_WRITE: + { + /* Execute immediate write. */ + Nvm_StateMachine_Immediate_Write(obj); + if(NVM_IMMEDIATE_WRITE_FINISH(obj) || NVM_IMMEDIATE_WRITE_FAIL(obj) || NVM_IMMEDIATE_WRITE_FATAL(obj)) + { + Nvm_Block_SetState(obj->blockTable, obj->runtime->writeAllJob->blockIdx, obj->runtime->writeAllJob->datasetIdx, NVM_BLOCK_GET_INT_STATE(obj->blockTable, obj->runtime->writeAllJob->blockIdx, obj->runtime->writeAllJob->datasetIdx)); + obj->runtime->writeAllJob->datasetIdx++; + obj->runtime->writeAllJob->job = NVM_WRITEALLFSM_WRITEENTRY; + } + break; + } + case NVM_WRITEALLFSM_FINISH: + { + /* Complete response request. */ + Nvm_Queue_RemoveFirstItem(obj->runtime->queue); + obj->runtime->nextState = NVM_STATE_IDLE; + break; + } + case NVM_WRITEALLFSM_ERROR: + { + /* Complete response request. */ + Nvm_Queue_RemoveFirstItem(obj->runtime->queue); + obj->runtime->nextState = NVM_STATE_IDLE; + break; + } + default: + { + break; + } + } +} + +void Nvm_StateMachine_EraseAll_Entry(const NvmType *obj) +{ + obj->runtime->eraseAllJob->blockIdx = 0; + obj->runtime->eraseAllJob->job = NVM_ERASEALLFSM_ERASEBLOCK; +} + +void Nvm_StateMachine_EraseAll(const NvmType *obj) +{ + switch(obj->runtime->eraseAllJob->job) + { + case NVM_ERASEALLFSM_ERASEBLOCK: + { + /* Mark the state machine as finished after traversing all blocks. */ + if(obj->runtime->eraseAllJob->blockIdx < obj->blockTable->itemsNum) + { + obj->runtime->eraseAllJob->datasetIdx = 0; + obj->runtime->eraseAllJob->job = NVM_ERASEALLFSM_ERASEENTRY; + } + else + { + obj->runtime->eraseAllJob->job = NVM_ERASEALLFSM_FINISH; + } + break; + } + case NVM_ERASEALLFSM_ERASEENTRY: + { + /* Execute the preparation program before erasing immediately. */ + if(obj->runtime->eraseAllJob->datasetIdx < NVM_BLOCK_GET_DATASETNUM(obj->blockTable, obj->runtime->eraseAllJob->blockIdx)) + { + obj->runtime->eraseAllJob->blockDatabuff = NVM_BLOCK_GET_TEMP_RAM_BUFF_PTR(obj->blockTable, obj->runtime->eraseAllJob->blockIdx); + Nvm_Block_GetRomData(obj->blockTable, obj->runtime->eraseAllJob->blockIdx, obj->runtime->eraseAllJob->datasetIdx, obj->runtime->eraseAllJob->blockDatabuff); + Nvm_Block_SetState(obj->blockTable, obj->runtime->eraseAllJob->blockIdx, obj->runtime->eraseAllJob->datasetIdx, NVM_REQ_PENDING); + Nvm_StateMachine_Immediate_Write_Entry(obj, obj->runtime->eraseAllJob->blockIdx, obj->runtime->eraseAllJob->datasetIdx, NVM_BLOCK_RETRY_NUM, NULL); + obj->runtime->eraseAllJob->job = NVM_ERASEALLFSM_ERASE; + } + else + { + obj->runtime->eraseAllJob->blockIdx++; + obj->runtime->eraseAllJob->job = NVM_ERASEALLFSM_ERASEBLOCK; + } + break; + } + case NVM_ERASEALLFSM_ERASE: + { + /* Execute immediate erase. */ + Nvm_StateMachine_Immediate_Write(obj); + if(NVM_IMMEDIATE_WRITE_FINISH(obj) || NVM_IMMEDIATE_WRITE_FAIL(obj) || NVM_IMMEDIATE_WRITE_FATAL(obj)) + { + obj->runtime->eraseAllJob->job = NVM_ERASEALLFSM_READBACK; + } + break; + } + case NVM_ERASEALLFSM_READBACK: + { + /* Performing operations to read back data. */ + obj->runtime->eraseAllJob->blockRombuff = NVM_BLOCK_GET_ROM_BUFF_PTR(obj->blockTable, obj->runtime->eraseAllJob->blockIdx, obj->runtime->eraseAllJob->datasetIdx); + Nvm_Block_WriteDataToRamBlock(obj->blockTable, obj->method, obj->runtime->eraseAllJob->blockIdx, obj->runtime->eraseAllJob->datasetIdx, obj->runtime->eraseAllJob->blockRombuff); + Nvm_Block_SetState(obj->blockTable, obj->runtime->eraseAllJob->blockIdx, obj->runtime->eraseAllJob->datasetIdx, NVM_BLOCK_GET_INT_STATE(obj->blockTable, obj->runtime->eraseAllJob->blockIdx, obj->runtime->eraseAllJob->datasetIdx)); + obj->runtime->eraseAllJob->datasetIdx++; + obj->runtime->eraseAllJob->job = NVM_ERASEALLFSM_ERASEENTRY; + break; + } + case NVM_ERASEALLFSM_FINISH: + { + /* Complete response request. */ + Nvm_Queue_RemoveFirstItem(obj->runtime->queue); + obj->runtime->nextState = NVM_STATE_IDLE; + break; + } + case NVM_WRITEALLFSM_ERROR: + { + /* Complete response request. */ + Nvm_Queue_RemoveFirstItem(obj->runtime->queue); + obj->runtime->nextState = NVM_STATE_IDLE; + break; + } + default: + { + break; + } + } +} + +void Nvm_StateMachine_Erase_Entry(const NvmType *obj) +{ + uint16_t localBlockIdx; + uint16_t localDatasetIdx; + + localBlockIdx = obj->runtime->queue->members[0].blockIdx; + localDatasetIdx = obj->runtime->queue->members[0].datasetIdx; + + Nvm_Block_SetState(obj->blockTable, localBlockIdx, localDatasetIdx, NVM_REQ_PENDING); + + obj->runtime->eraseJob->blockIdx = localBlockIdx; + obj->runtime->eraseJob->datasetIdx = localDatasetIdx; + obj->runtime->eraseJob->blockDatabuff = NVM_BLOCK_GET_TEMP_RAM_BUFF_PTR(obj->blockTable, localBlockIdx); + obj->runtime->eraseJob->job = NVM_ERASEFSM_INIT; + + Nvm_Block_GetRomData(obj->blockTable, obj->runtime->eraseJob->blockIdx, obj->runtime->eraseJob->datasetIdx, obj->runtime->eraseJob->blockDatabuff); +} + +void Nvm_StateMachine_Erase(const NvmType *obj) +{ + switch(obj->runtime->eraseJob->job) + { + case NVM_ERASEFSM_INIT: + { + /* If the type of the block is REDUNDANT, the state machine will be marked as a redundant state. */ + /* If not, it will be judged whether it is an immediate state. */ + /* Otherwise, it will be marked as an immediate state. */ + if(NVM_BLOCK_IS_REDUNDANT(obj->blockTable, obj->runtime->eraseJob->blockIdx)) + { + obj->runtime->eraseJob->job = NVM_ERASEFSM_REDUNDANT_MAIN; + } + else + { + Nvm_StateMachine_Immediate_Write_Entry(obj, obj->runtime->eraseJob->blockIdx, obj->runtime->eraseJob->datasetIdx, NVM_BLOCK_RETRY_NUM, NULL); + obj->runtime->eraseJob->job = NVM_ERASEFSM_IMMEDIATE; + } + break; + } + case NVM_ERASEFSM_IMMEDIATE: + { + + /* If the immediate execution is successful or an error occurs, */ + /* mark the state machine to the read back state.*/ + Nvm_StateMachine_Immediate_Write(obj); + if(NVM_IMMEDIATE_WRITE_FINISH(obj) || NVM_IMMEDIATE_WRITE_FAIL(obj) || NVM_IMMEDIATE_WRITE_FATAL(obj)) + { + Nvm_StateMachine_Immediate_Read_Entry(obj, obj->runtime->eraseJob->blockIdx, obj->runtime->eraseJob->datasetIdx, NVM_BLOCK_RETRY_NUM, NULL); + obj->runtime->eraseJob->job = NVM_ERASEFSM_READBACK; + } + break; + } + case NVM_ERASEFSM_REDUNDANT_MAIN: + { + /* Execute the erase main area of a REDUNDANT type block. */ + obj->runtime->writeJob->blockBackUp = false; + obj->runtime->writeJob->datasetIdx = NVM_BLOCK_MAIN_IDX; + Nvm_StateMachine_Immediate_Write_Entry(obj, obj->runtime->writeJob->blockIdx, obj->runtime->writeJob->datasetIdx, NVM_BLOCK_RETRY_NUM, NULL); + obj->runtime->writeJob->job = NVM_WRITEFSM_IMMEDIATE; + break; + } + case NVM_ERASEFSM_REDUNDANT_BACKUP: + { + /* Execute the erase backup area of a REDUNDANT type block. */ + obj->runtime->writeJob->blockBackUp = true; + obj->runtime->writeJob->datasetIdx = NVM_BLOCK_BACKUP_IDX; + Nvm_StateMachine_Immediate_Write_Entry(obj, obj->runtime->writeJob->blockIdx, obj->runtime->writeJob->datasetIdx, NVM_BLOCK_RETRY_NUM, NULL); + obj->runtime->writeJob->job = NVM_WRITEFSM_IMMEDIATE; + break; + } + case NVM_ERASEFSM_READBACK: + { + /* Performing operations to read back data. */ + Nvm_StateMachine_Immediate_Read(obj); + if(NVM_IMMEDIATE_READ_FINISH(obj) || NVM_IMMEDIATE_READ_FAIL(obj) || NVM_IMMEDIATE_READ_FATAL(obj)) + { + obj->runtime->eraseJob->job = NVM_ERASEFSM_CHECK; + } + break; + } + case NVM_ERASEFSM_CHECK: + { + /* Check the validity of data within the block. */ + Nvm_Block_DataRepair(obj->blockTable, obj->method, obj->runtime->eraseJob->blockIdx, obj->runtime->eraseJob->datasetIdx); + Nvm_Block_SetState(obj->blockTable, obj->runtime->eraseJob->blockIdx, obj->runtime->eraseJob->datasetIdx, NVM_BLOCK_GET_INT_STATE(obj->blockTable, obj->runtime->eraseJob->blockIdx, obj->runtime->eraseJob->datasetIdx)); + /* Determine the type of block. */ + if(NVM_BLOCK_IS_REDUNDANT(obj->blockTable, obj->runtime->eraseJob->blockIdx)) + { + if(obj->runtime->eraseJob->blockBackUp) + { + obj->runtime->eraseJob->job = NVM_ERASEFSM_FINISH; + } + else + { + obj->runtime->eraseJob->job = NVM_ERASEFSM_REDUNDANT_BACKUP; + } + } + else + { + obj->runtime->eraseJob->job = NVM_ERASEFSM_FINISH; + } + break; + } + case NVM_ERASEFSM_FINISH: + { + /* Complete response request. */ + Nvm_Queue_RemoveFirstItem(obj->runtime->queue); + obj->runtime->nextState = NVM_STATE_IDLE; + break; + } + case NVM_ERASEFSM_ERASEERROR: + { + /* Complete response request. */ + Nvm_Queue_RemoveFirstItem(obj->runtime->queue); + obj->runtime->nextState = NVM_STATE_IDLE; + break; + } + default: + { + break; + } + } +} + +void Nvm_StateMachine_Immediate_Read_Entry(const NvmType *obj, uint16_t blockIdx, uint16_t datasetIdx, uint8_t retry, NvmNotificationPtrType notificationPtr) +{ + obj->runtime->immediateReadJob->job = NVM_IMMEDIATEREADFSM_MAIN; + + Nvm_Block_SetInternalState(obj->blockTable, blockIdx, datasetIdx, NVM_REQ_PENDING); + + Nvm_Block_ClrRamBuff(obj->blockTable, blockIdx, datasetIdx); + + obj->runtime->immediateReadJob->mainRetryCnt = retry; + obj->runtime->immediateReadJob->backupRetryCnt = retry; + obj->runtime->immediateReadJob->notificationPtr = notificationPtr; + obj->runtime->immediateReadJob->blockIdx = blockIdx; + obj->runtime->immediateReadJob->datasetIdx = datasetIdx; + obj->runtime->immediateReadJob->blockNumber = obj->blockTable->items[blockIdx].number + datasetIdx; + obj->runtime->immediateReadJob->blockDatabuff = NVM_BLOCK_GET_TEMP_RAM_BUFF_PTR(obj->blockTable, blockIdx); + obj->runtime->immediateReadJob->blockUseSize = ALIGN8BYTE(Nvm_Block_CalcUseSize(obj->blockTable, blockIdx)); +} + +static void Nvm_StateMachine_Immediate_Read(const NvmType *obj) +{ + switch(obj->runtime->immediateReadJob->job) + { + case NVM_IMMEDIATEREADFSM_MAIN: + { + /* Obtain lower level module status. */ + if(NVM_STATUS_IDLE == obj->method->getStatus()) + { + /* Request lower level module to read data. */ + if(obj->method->read(obj->runtime->immediateReadJob->blockNumber, NVM_BLOCK_MAIN_IDX, obj->runtime->immediateReadJob->blockDatabuff, obj->runtime->immediateReadJob->notificationPtr)) + { + /* Request successful, waiting for the response from the lower level module to complete. */ + obj->runtime->immediateReadJob->job = NVM_IMMEDIATEREADFSM_WMF; + } + else + { + /* If the request fails, it will be retried. */ + Nvm_Block_SetInternalState(obj->blockTable, obj->runtime->immediateReadJob->blockIdx, obj->runtime->immediateReadJob->datasetIdx, NVM_REQ_NOT_OK); + obj->runtime->immediateReadJob->job = NVM_IMMEDIATEREADFSM_MAIN_RETRY; + } + } + break; + } + case NVM_IMMEDIATEREADFSM_MAIN_RETRY: + { + /* Wait for an attempt to resend the request to the lower module. */ + if(obj->runtime->immediateReadJob->mainRetryCnt > 0) + { + obj->runtime->immediateReadJob->mainRetryCnt--; + obj->runtime->immediateReadJob->job = NVM_IMMEDIATEREADFSM_MAIN; + } + else + { + /* If the retry count exceeds the threshold, mark the state machine as an error. */ + obj->runtime->immediateReadJob->job = NVM_IMMEDIATEREADFSM_READERROR; + } + break; + } + case NVM_IMMEDIATEREADFSM_WMF: + { + /* Waiting for lower level request status to respond successfully, response not successful, response error. */ + if(NVM_JOB_RESULT_OK == obj->method->getJobResult()) + { + /* Wait for the lower level request status to respond successfully, then mark the internal management status of the block as FINISH. */ + Nvm_Block_WriteDataToBuff(obj->blockTable, obj->method, obj->runtime->immediateReadJob->blockIdx, obj->runtime->immediateReadJob->datasetIdx, obj->runtime->immediateReadJob->blockDatabuff); + Nvm_Block_SetInternalState(obj->blockTable, obj->runtime->immediateReadJob->blockIdx, obj->runtime->immediateReadJob->datasetIdx, NVM_REQ_OK); + obj->runtime->immediateReadJob->job = NVM_IMMEDIATEREADFSM_FINISH; + } + else if(NVM_JOB_RESULT_NOT_OK == obj->method->getJobResult()) + { + /* If the request status at the lower level is unsuccessful, mark the internal management status of the block as ERROR. */ + Nvm_Block_ClrBlockRamBuff(obj->blockTable, obj->runtime->immediateReadJob->blockIdx, obj->runtime->immediateReadJob->datasetIdx); + Nvm_Block_SetInternalState(obj->blockTable, obj->runtime->immediateReadJob->blockIdx, obj->runtime->immediateReadJob->datasetIdx, NVM_REQ_NOT_OK); + obj->runtime->immediateReadJob->job = NVM_IMMEDIATEREADFSM_READERROR; + } + else if(NVM_JOB_RESULT_BL_INCONSISTENT == obj->method->getJobResult()) + { + /* Wait for the lower level request status to be block integrity error, then mark the internal management status of the block as ERROR. */ + Nvm_Block_ClrBlockRamBuff(obj->blockTable, obj->runtime->immediateReadJob->blockIdx, obj->runtime->immediateReadJob->datasetIdx); + Nvm_Block_SetInternalState(obj->blockTable, obj->runtime->immediateReadJob->blockIdx, obj->runtime->immediateReadJob->datasetIdx, NVM_REQ_INTEGRITY_FAILED); + obj->runtime->immediateReadJob->job = NVM_IMMEDIATEREADFSM_READERROR; + } + else if(NVM_JOB_RESULT_BL_INVALID == obj->method->getJobResult()) + { + /* If the request status of the lower level is an undefined block, the internal management status of the block will be marked as ERROR. */ + Nvm_Block_ClrBlockRamBuff(obj->blockTable, obj->runtime->immediateReadJob->blockIdx, obj->runtime->immediateReadJob->datasetIdx); + Nvm_Block_SetInternalState(obj->blockTable, obj->runtime->immediateReadJob->blockIdx, obj->runtime->immediateReadJob->datasetIdx, NVM_REQ_UNINT); + obj->runtime->immediateReadJob->job = NVM_IMMEDIATEREADFSM_READERROR; + } + break; + } + case NVM_IMMEDIATEREADFSM_FINISH: + { + break; + } + case NVM_IMMEDIATEREADFSM_READERROR: + { + break; + } + default: + { + break; + } + } +} + +static void Nvm_StateMachine_Immediate_Write_Entry(const NvmType *obj, uint16_t blockIdx, uint16_t datasetIdx, uint8_t retry, NvmNotificationPtrType notificationPtr) +{ + uint16_t crcLen; + + + obj->runtime->immediateWriteJob->job = NVM_IMMEDIATEWRITEFSM_MAIN; + + Nvm_Block_SetInternalState(obj->blockTable, blockIdx, datasetIdx, NVM_REQ_PENDING); + + obj->runtime->immediateWriteJob->retry = retry; + obj->runtime->immediateWriteJob->notificationPtr = notificationPtr; + obj->runtime->immediateWriteJob->blockIdx = blockIdx; + obj->runtime->immediateWriteJob->datasetIdx = datasetIdx; + obj->runtime->immediateWriteJob->blockNumber = obj->blockTable->items[blockIdx].number + datasetIdx; + obj->runtime->immediateWriteJob->blockDatabuff = NVM_BLOCK_GET_TEMP_RAM_BUFF_PTR(obj->blockTable, blockIdx); + + if(NVM_BLOCK_IS_CRC(obj->blockTable, obj->runtime->writeJob->blockIdx)) + { + crcLen = NVM_BLOCK_GET_CRC_LEN(obj->blockTable, obj->runtime->writeJob->blockIdx); + obj->runtime->immediateWriteJob->blockDatabuff[crcLen] = obj->method->crc8(obj->runtime->immediateWriteJob->blockDatabuff, crcLen); + } +} + +static void Nvm_StateMachine_Immediate_Write(const NvmType *obj) +{ + switch(obj->runtime->immediateWriteJob->job) + { + case NVM_IMMEDIATEWRITEFSM_MAIN: + { + /* Obtain lower level module status. */ + if(NVM_STATUS_IDLE == obj->method->getStatus()) + { + /* Request lower level module to write data. */ + if(obj->method->write(obj->runtime->immediateWriteJob->blockNumber, obj->runtime->immediateWriteJob->blockDatabuff, obj->runtime->immediateWriteJob->notificationPtr)) + { + /* Request successful, waiting for the response from the lower level module to complete. */ + obj->runtime->immediateWriteJob->job = NVM_IMMEDIATEWRITEFSM_WMF; + } + else + { + /* If the request fails, it will be retried. */ + obj->runtime->immediateWriteJob->job = NVM_IMMEDIATEWRITEFSM_RETRY; + } + } + /* If the lower level module is in a state of responding to a request, calibrate the state machine to WAITMANAGE. */ + else if(NVM_STATUS_GC == obj->method->getStatus()) + { + obj->runtime->immediateWriteJob->job = NVM_IMMEDIATEWRITEFSM_WAITMANAGE; + } + else if(NVM_STATUS_READ == obj->method->getStatus()) + { + obj->runtime->immediateWriteJob->job = NVM_IMMEDIATEWRITEFSM_WAITMANAGE; + } + else if(NVM_STATUS_WRITE == obj->method->getStatus()) + { + obj->runtime->immediateWriteJob->job = NVM_IMMEDIATEWRITEFSM_WAITMANAGE; + } + else + { + obj->runtime->immediateWriteJob->job = NVM_IMMEDIATEWRITEFSM_ERROR; + } + break; + } + case NVM_IMMEDIATEWRITEFSM_RETRY: + { + /* Wait for an attempt to resend the request to the lower module. */ + if(obj->runtime->immediateWriteJob->retry > 0) + { + obj->runtime->immediateWriteJob->retry--; + obj->runtime->immediateWriteJob->job = NVM_IMMEDIATEWRITEFSM_MAIN; + } + else + { + /* If the retry count exceeds the threshold, mark the state machine as an error. */ + obj->runtime->immediateWriteJob->job = NVM_IMMEDIATEWRITEFSM_WRITEERROR; + } + break; + } + case NVM_IMMEDIATEWRITEFSM_WMF: + { + /* Waiting for lower level request status to respond successfully, response not successful, response error. */ + if(NVM_JOB_RESULT_OK == obj->method->getJobResult()) + { + /* Wait for the lower level request status to respond successfully, then mark the internal management status of the block as FINISH. */ + Nvm_Block_SetInternalState(obj->blockTable, obj->runtime->immediateWriteJob->blockIdx, obj->runtime->immediateWriteJob->datasetIdx, NVM_REQ_OK); + obj->runtime->immediateWriteJob->job = NVM_IMMEDIATEWRITEFSM_FINISH; + } + else if(NVM_JOB_RESULT_NOT_OK == obj->method->getJobResult()) + { + /* If the request status at the lower level is unsuccessful, mark the internal management status of the block as ERROR. */ + Nvm_Block_SetInternalState(obj->blockTable, obj->runtime->immediateWriteJob->blockIdx, obj->runtime->immediateWriteJob->datasetIdx, NVM_REQ_NOT_OK); + obj->runtime->immediateWriteJob->job = NVM_IMMEDIATEWRITEFSM_WRITEERROR; + } + else if(NVM_JOB_RESULT_BL_INCONSISTENT == obj->method->getJobResult()) + { + /* Wait for the lower level request status to be block integrity error, then mark the internal management status of the block as ERROR. */ + Nvm_Block_SetInternalState(obj->blockTable, obj->runtime->immediateWriteJob->blockIdx, obj->runtime->immediateWriteJob->datasetIdx, NVM_REQ_INTEGRITY_FAILED); + obj->runtime->immediateWriteJob->job = NVM_IMMEDIATEWRITEFSM_WRITEERROR; + } + else if(NVM_JOB_RESULT_BL_INVALID == obj->method->getJobResult()) + { + /* If the request status of the lower level is an undefined block, the internal management status of the block will be marked as ERROR. */ + Nvm_Block_SetInternalState(obj->blockTable, obj->runtime->immediateWriteJob->blockIdx, obj->runtime->immediateWriteJob->datasetIdx, NVM_REQ_UNINT); + obj->runtime->immediateWriteJob->job = NVM_IMMEDIATEWRITEFSM_WRITEERROR; + } + break; + } + case NVM_IMMEDIATEWRITEFSM_FINISH: + { + break; + } + case NVM_IMMEDIATEWRITEFSM_WRITEERROR: + { + break; + } + case NVM_IMMEDIATEWRITEFSM_WAITMANAGE: + { + /* When waiting for the status of the lower level module to be idle, mark the status as requesting the lower level module to write. */ + if(NVM_STATUS_IDLE == obj->method->getStatus()) + { + obj->runtime->immediateWriteJob->job = NVM_IMMEDIATEWRITEFSM_MAIN; + } + break; + } + default: + { + break; + } + } +} diff --git a/cva_asw_m0118/SDK/middleware/nvm/nvm_statemachine.h b/cva_asw_m0118/SDK/middleware/nvm/nvm_statemachine.h new file mode 100644 index 0000000..1318b74 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/nvm_statemachine.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _NVM_STATEMACHINE_H_ +#define _NVM_STATEMACHINE_H_ + +/*! \brief Contains public interface to various functions related + * to the NVM (NVRAM Manager) module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include +#include "nvm_types.h" + +/*! \addtogroup NVRAM Manager + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +void Nvm_StateMachine_Idle(const NvmType *obj); +void Nvm_StateMachine_Read_Entry(const NvmType *obj); +void Nvm_StateMachine_Read(const NvmType *obj); +void Nvm_StateMachine_Write_Entry(const NvmType *obj); +void Nvm_StateMachine_Write(const NvmType *obj); +void Nvm_StateMachine_ReadAll_Entry(const NvmType *obj); +void Nvm_StateMachine_ReadAll(const NvmType *obj); +void Nvm_StateMachine_WriteAll_Entry(const NvmType *obj); +void Nvm_StateMachine_WriteAll(const NvmType *obj); +void Nvm_StateMachine_EraseAll_Entry(const NvmType *obj); +void Nvm_StateMachine_EraseAll(const NvmType *obj); +void Nvm_StateMachine_Erase_Entry(const NvmType *obj); +void Nvm_StateMachine_Erase(const NvmType *obj); +void Nvm_ReadNotification(const NvmType *obj, NVM_NotificationType notificationNumber); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _NVM_STATEMACHINE_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/nvm/nvm_types.h b/cva_asw_m0118/SDK/middleware/nvm/nvm_types.h new file mode 100644 index 0000000..43c6ccb --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/nvm_types.h @@ -0,0 +1,419 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _NVM_TYPES_H_ +#define _NVM_TYPES_H_ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "nvm_extra.h" + +/*! \addtogroup NVRAM Manager + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +struct _NvmType_; + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +/*! \brief The return value type of the public method of the nvm module. + */ +typedef enum +{ + NVM_RETURN_OK = 0X00, + NVM_RETURN_NOT_OK = 0X01, +} Nvm_ReturnType; + +/*! \brief Define block types. + */ +typedef enum +{ + NVM_BLOCK_NORMAL = 0x00, + NVM_BLOCK_REDUNDANT = 0x01, + NVM_BLOCK_DATASET = 0x02, +} Nvm_BlockOpType; + +/*! \brief Used to define whether crc is required in a block. + */ +typedef enum +{ + NVM_CRC_NONE = 0x00, + NVM_CRC8 = 0x01, +} Nvm_BlockCrcType; + +/*! \brief Define the type of block state. + */ +typedef enum +{ + NVM_REQ_UNINT = 0X00, + NVM_REQ_PENDING = 0X01, + NVM_REQ_ERASE = 0x02, + NVM_REQ_NOT_OK = 0x03, + NVM_REQ_INTEGRITY_FAILED = 0x04, + NVM_REQ_OK = 0x05, + NVM_REQ_ERROR = 0xFF, +} Nvm_BlockState; + +/*! \brief Define the type of NVM module state. + */ +typedef enum +{ + NVM_STATE_UNINIT = 0x00, + NVM_STATE_IDLE = 0x01, + NVM_STATE_READ = 0x02, + NVM_STATE_WRITE = 0x03, + NVM_STATE_READALL = 0x04, + NVM_STATE_WRITEALL = 0x05, + NVM_STATE_ERASE = 0x06, + NVM_STATE_ERASEALL = 0x07, + FEE_STATE_INVALID = 0x08, +} Nvm_stateType; + +/*! \brief Define the type of queue member status markers. + */ +typedef enum +{ + NVM_QUEUEMEMBERSTATE_UNUSED = 0x01, + NVM_QUEUEMEMBERSTATE_USED = 0x02, + NVM_QUEUEMEMBERSTATE_LOCK = 0x03, +} Nvm_QueueMemberStateType; + +/*! \brief Define the type of state for NVM erase tasks. + */ +typedef enum +{ + NVM_ERASEFSM_INIT = 0x01, + NVM_ERASEFSM_IMMEDIATE = 0x02, + NVM_ERASEFSM_REDUNDANT_MAIN = 0X03, + NVM_ERASEFSM_REDUNDANT_BACKUP = 0X04, + NVM_ERASEFSM_READBACK = 0x05, + NVM_ERASEFSM_CHECK = 0x06, + NVM_ERASEFSM_FINISH = 0x07, + NVM_ERASEFSM_ERASEERROR = 0x08, + NVM_ERASEFSM_ERROR = 0xFF, +} NVM_EraseFsmType; + +/*! \brief Define the type of state that NVM writes to the job. + */ +typedef enum +{ + NVM_WRITEFSM_INIT = 0x01, + NVM_WRITEFSM_IMMEDIATE = 0x02, + NVM_WRITEFSM_READBACK = 0x03, + NVM_WRITEFSM_CHECK = 0x04, + NVM_WRITEFSM_NORMAL = 0x05, + NVM_WRITEFSM_REDUNDANT_MAIN = 0x06, + NVM_WRITEFSM_REDUNDANT_BACKUP = 0X07, + NVM_WRITEFSM_FINISH = 0x08, + NVM_WRITEFSM_WRITEERROR = 0x09, + NVM_WRITEFSM_ERROR = 0xFF, +} NVM_WriteFsmType; + +/*! \brief Define the type of NVM immediate read job status. + */ +typedef enum +{ + NVM_IMMEDIATEREADFSM_MAIN = 0x01, + NVM_IMMEDIATEREADFSM_MAIN_RETRY = 0x02, + NVM_IMMEDIATEREADFSM_WMF = 0x03, + NVM_IMMEDIATEREADFSM_FINISH = 0x04, + NVM_IMMEDIATEREADFSM_READERROR = 0x05, + NVM_IMMEDIATEREADFSM_ERROR = 0xFF, +} NVM_ImmediateReadFsmType; + +/*! \brief Define the type of state where NVM immediately writes jobs. + */ +typedef enum +{ + NVM_IMMEDIATEWRITEFSM_MAIN = 0x01, + NVM_IMMEDIATEWRITEFSM_RETRY = 0x02, + NVM_IMMEDIATEWRITEFSM_WMF = 0x03, + NVM_IMMEDIATEWRITEFSM_FINISH = 0x04, + NVM_IMMEDIATEWRITEFSM_WRITEERROR = 0x05, + NVM_IMMEDIATEWRITEFSM_WAITMANAGE = 0X06, + NVM_IMMEDIATEWRITEFSM_ERROR = 0xFF, +} NVM_ImmediateWriteFsmType; + +/*! \brief Define the type of state for nvm readAll job. + */ +typedef enum +{ + NVM_READALLFSM_READBLOCK = 0x01, + NVM_READALLFSM_READENTRY = 0x02, + NVM_READALLFSM_READ = 0x03, + NVM_READALLFSM_CHECK = 0x04, + NVM_READALLFSM_FINISH = 0x05, + NVM_READALLFSM_ERROR = 0xFF, +} NVM_ReadAllFsmType; + +/*! \brief Define the type of state for nvm writeAll job. + */ +typedef enum +{ + NVM_WRITEALLFSM_WRITEBLOCK = 0x01, + NVM_WRITEALLFSM_WRITEENTRY = 0x02, + NVM_WRITEALLFSM_WRITE = 0x03, + NVM_WRITEALLFSM_FINISH = 0x04, + NVM_WRITEALLFSM_ERROR = 0xFF, +} NVM_WriteAllFsmType; + +/*! \brief Define the type of state for nvm eraseAll job. + */ +typedef enum +{ + NVM_ERASEALLFSM_ERASEBLOCK = 0x01, + NVM_ERASEALLFSM_ERASEENTRY = 0x02, + NVM_ERASEALLFSM_ERASE = 0x03, + NVM_ERASEALLFSM_READBACK = 0x04, + NVM_ERASEALLFSM_FINISH = 0x05, + NVM_ERASEALLFSM_ERROR = 0xFF, +} NVM_EraseAllFsmType; + +/*! \brief Define the type of block management data. + */ +typedef struct _Nvm_BlockInfoType_ +{ + Nvm_BlockState state; + Nvm_BlockState internalState; + uint8_t integrity; +} Nvm_BlockInfoType; + +/*! \brief Define the type of block buff. + */ +typedef struct _Nvm_BlockBuffType_ +{ + const uint8_t* const romBuffPtr; + uint8_t* const ramBuffPtr; +} Nvm_BlockBuffType; + +/*! \brief Define the type of state function. + */ +typedef void (*Nvm_StateMachine_Fun_Type)(const struct _NvmType_ *obj); + +/*! \brief Define the types of queue members. + */ +typedef struct _Nvm_QueueMemberType_ +{ + uint16_t blockIdx; + uint8_t* databuff; + uint16_t datasetIdx; + Nvm_stateType op; + uint8_t priority; + Nvm_QueueMemberStateType state; +} Nvm_QueueMemberType; + +/*! \brief Define the type of queue. + */ +typedef struct _Nvm_QueueType_ +{ + uint16_t index; + const uint8_t memberNum; + struct _Nvm_QueueMemberType_* const members; +} Nvm_QueueType; + +/*! \brief Define the type of description block. + */ +typedef struct _Nvm_BlockItemType_ +{ + uint16_t number; + uint16_t dataSize; + Nvm_BlockOpType type; + uint8_t datasetNum; + bool immediate; + Nvm_BlockCrcType crc; + uint8_t priority; + const struct _Nvm_BlockBuffType_* buff; + struct _Nvm_BlockInfoType_* const info; + uint8_t* const tempRamBuffPtr; +} Nvm_BlockItemType; + +/*! \brief Define the type of blocks. + */ +typedef struct _Nvm_BlockType_ +{ + uint16_t itemsNum; + const struct _Nvm_BlockItemType_* items; +} Nvm_BlockType; + +/*! \brief Define the type of state machine. + */ +typedef struct _Nvm_StateMachineType_ +{ + Nvm_StateMachine_Fun_Type onEntry; + Nvm_StateMachine_Fun_Type fn; +} Nvm_StateMachineType; + +/*! \brief Define the type of erase job. + */ +typedef struct _Nvm_EraseJobType_ +{ + NVM_EraseFsmType job; + NVM_NotificationType result; + uint16_t blockIdx; + uint16_t blockNumber; + uint8_t datasetIdx; + bool blockBackUp; + uint8_t* blockDatabuff; + uint8_t* userBuff; + uint32_t useSize; +} Nvm_EraseJobType; + +/*! \brief Define the type of write job. + */ +typedef struct _Nvm_WriteJobType_ +{ + NVM_WriteFsmType job; + NVM_NotificationType result; + uint16_t blockIdx; + uint16_t blockNumber; + uint8_t datasetIdx; + bool blockBackUp; + uint8_t* blockDatabuff; + uint8_t* userBuff; + uint32_t useSize; +} Nvm_WriteJobType; + +/*! \brief Define the type of read job. + */ +typedef struct _Nvm_ReadJobType_ +{ + uint16_t blockIdx; + uint8_t datasetIdx; + uint32_t datasize; + uint8_t* userBuff; + uint8_t* cpyBuff; +} Nvm_ReadJobType; + +/*! \brief Define the type of writeAll job. + */ +typedef struct _Nvm_WriteAllJobType_ +{ + NVM_WriteAllFsmType job; + uint16_t blockIdx; + uint16_t blockNumber; + uint8_t datasetIdx; + bool blockBackUp; + uint8_t* blockDatabuff; + uint32_t blockUseSize; +} Nvm_WriteAllJobType; + +/*! \brief Define the type of eraseAll job. + */ +typedef struct _Nvm_EraseAllJobType_ +{ + NVM_EraseAllFsmType job; + uint16_t blockIdx; + uint16_t blockNumber; + uint8_t datasetIdx; + bool blockBackUp; + uint8_t* blockDatabuff; + uint8_t* blockRombuff; + uint32_t blockUseSize; +} Nvm_EraseAllJobType; + +/*! \brief Define the type of readAll job. + */ +typedef struct _Nvm_ReadAllJobType_ +{ + NVM_ReadAllFsmType job; + uint16_t blockIdx; + uint16_t blockNumber; + uint8_t datasetIdx; + bool blockBackUp; + uint8_t* blockDatabuff; + uint32_t blockUseSize; +} Nvm_ReadAllJobType; + +/*! \brief Define the type of immediateWrite job. + */ +typedef struct _Nvm_ImmediateWriteJobType_ +{ + NVM_ImmediateWriteFsmType job; + NvmNotificationPtrType notificationPtr; + uint16_t blockIdx; + uint16_t blockNumber; + uint8_t datasetIdx; + uint8_t* blockDatabuff; + uint8_t retry; +} Nvm_ImmediateWriteJobType; + +/*! \brief Define the type of immediateRead job. + */ +typedef struct _Nvm_ImmediateReadJobType_ +{ + NVM_ImmediateReadFsmType job; + NvmNotificationPtrType notificationPtr; + uint16_t blockIdx; + uint16_t blockNumber; + uint8_t datasetIdx; + uint8_t* blockDatabuff; + uint32_t blockUseSize; + uint8_t mainRetryCnt; + uint8_t backupRetryCnt; +} Nvm_ImmediateReadJobType; + +/*! \brief Define the type of NVM module runtime. + */ +typedef struct _Nvm_RunTimeType_ +{ + Nvm_stateType state; + Nvm_stateType nextState; + struct _Nvm_QueueType_* queue; + struct _Nvm_EraseJobType_* eraseJob; + struct _Nvm_ReadJobType_* readJob; + struct _Nvm_WriteJobType_* writeJob; + struct _Nvm_ReadAllJobType_* readAllJob; + struct _Nvm_WriteAllJobType_* writeAllJob; + struct _Nvm_EraseAllJobType_* eraseAllJob; + struct _Nvm_ImmediateReadJobType_* immediateReadJob; + struct _Nvm_ImmediateWriteJobType_* immediateWriteJob; +} Nvm_RunTimeType; + +/*! \brief Define the type of nvm. + */ +typedef struct _NvmType_ +{ + const struct _Nvm_BlockType_* blockTable; + const struct _Nvm_StateMachineType_* stateMachine; + const struct _Nvm_MethodType_* method; + struct _Nvm_RunTimeType_* runtime; +} NvmType; +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _NVM_TYPES_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/nvm/nvm_version.h b/cva_asw_m0118/SDK/middleware/nvm/nvm_version.h new file mode 100644 index 0000000..eb9bea4 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/nvm/nvm_version.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _NVM_VERSION_H_ +#define _NVM_VERSION_H_ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +/*! \addtogroup NVRAM Manager + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +/*! \brief Macro for the major version number of the software of the nvm module. + */ +#if(defined NVM_SW_MAJOR_VERSION) +#error NVM_SW_MAJOR_VERSION already defined +#endif +#define NVM_SW_MAJOR_VERSION (1U) + +/*! \brief Macro for the software version number of the nvm module. + */ +#if(defined NVM_SW_MINOR_VERSION) +#error NVM_SW_MINOR_VERSION already defined +#endif +#define NVM_SW_MINOR_VERSION (0U) + +/*! \brief Macro for the software patch version number of the nvm module. + */ +#if(defined NVM_SW_PATCH_VERSION) +#error NVM_SW_PATCH_VERSION already defined +#endif +#define NVM_SW_PATCH_VERSION (0U) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +/*! \brief Type of software version number of the nvm module. + */ +typedef struct _Nvm_VersionInfoType_ +{ + uint8_t sw_major_version; + uint8_t sw_minor_version; + uint8_t sw_patch_version; +} Nvm_VersionInfoType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _NVM_VERSION_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/uds/stack/stimer.h b/cva_asw_m0118/SDK/middleware/uds/stack/stimer.h new file mode 100644 index 0000000..7542cea --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/stack/stimer.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _STIMER_H_ +#define _STIMER_H_ + +/*! \brief Contains public interface to various functions related + * to the Software Timer (STIMER) object. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Declaration of STIMER object + */ +typedef struct _StimerType_ +{ + uint32_t counter; /*!< The counter register */ + uint32_t period; /*!< The period, time out will occur when count reach period */ + bool enable; /*!< Whether the timer is started */ + bool overflow; /*!< Whether the timer is overflow */ + +} StimerType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief The constructor of the timer object + * + * This function initialize the Stimer object + * + * \param[in] obj : pointer to Stimer instance + */ +static inline void Stimer_Init(StimerType *obj) +{ + obj->counter = 0; + obj->period = 0; + obj->enable = false; + obj->overflow = false; +} + +/*! \brief Start the timer for the period, this is one shot + * + * This function start the timer. This is one-shot. + * + * \note The real time is based on the time base running Ticker() + * \note Call this function if already started will restart the timer + * + * \param[in] obj : pointer to Stimer instance + * \param[in] period : the period value + */ +static inline void Stimer_Start(StimerType *obj, uint32_t period) +{ + obj->counter = 0; + obj->period = period; + obj->enable = true; + obj->overflow = false; +} + +/*! \brief The time base of the timer object + * + * This function provide the real time base of the stimer instance. + * + * \param[in] obj : pointer to Stimer instance + */ +static inline void Stimer_Tick(StimerType *obj) +{ + if(obj->enable && obj->overflow == false) + { + if(obj->counter < obj->period) + { + obj->counter++; + if(obj->counter == obj->period) + { + obj->overflow = true; + } + } + } +} + +/*! \brief Whether timeout + * + * This function returns whether it's timeout + * + * \param[in] obj : pointer to Stimer instance + * \return Whether it's timeout + * - true : the timer is time-out + * - false : the timer is not time-out + */ +static inline bool Stimer_Timeout(const StimerType *obj) +{ + return obj->overflow; +} + +/*! \brief Whether it's started + * + * This function returns whether the Timer instance is started + * + * \param[in] obj : pointer to Stimer instance + * \return Whether it's started + * - true : the timer is started + * - false : the timer is not started + */ +static inline bool Stimer_IsActive(StimerType *obj) +{ + return obj->enable; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _STIMER_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/uds/stack/uds.c b/cva_asw_m0118/SDK/middleware/uds/stack/uds.c new file mode 100644 index 0000000..20f9bc1 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/stack/uds.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds.h" + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define UDS_GET_SUB_FUNCTION_SUPPRESS_POSRSP(byte) (((byte) >> 7u)&0x01u) + + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + + +/******************************************************************************* + * the globals + ******************************************************************************/ + + +/******************************************************************************* + * the functions + ******************************************************************************/ + +static bool Uds_IsSidValid(UdsType *obj, uint8_t sid) +{ + uint16_t i=0; + for(i=0; iserviceNum; ++i) + { + if(obj->seviceTable[i].sid == sid) + { + return true; + } + } + return false; +} + + +void Uds_Init(UdsType *obj, const Uds_ParamsType *pParams) +{ + IsoTp_Init(&obj->isotp, &pParams->isotpParams); + + obj->session = 0x01; /* Default session */ + obj->securityLevel = 0; /* None security level */ + obj->suppressPosRsp = false; + obj->timeStamp_ms = 0; + obj->p2Server_ms = pParams->p2Server_ms; + obj->p2xServer_10ms = pParams->p2xServer_10ms; + obj->s3Server_ms = pParams->s3Server_ms; + + Stimer_Init(&obj->p2ServerTimer); + Stimer_Init(&obj->p2xServerTimer); + Stimer_Init(&obj->s3ServerTimer); + + uint32_t i=0; + for(i=0; ipayload[i] = 0; + } +} + + +void Uds_Run(UdsType *obj) +{ + uint16_t outSize = 0; + int8_t result = 0; + uint8_t sid = 0; + uint32_t i=0; + + IsoTp_Poll(&obj->isotp); + + result = IsoTp_Receive(&obj->isotp, &obj->isFuncAddr, obj->payload, UDS_MAX_PAYLOAD_SIZE, &outSize); + if (ISOTP_RET_OK == result) + { + /* Handle received message */ + sid = obj->payload[0]; + if(Uds_IsSidValid(obj, sid)) + { + for(i=0; iserviceNum; ++i) + { + if(obj->seviceTable[i].sid == sid) + { + if(obj->seviceTable[i].subFuncOwner) + { + obj->suppressPosRsp = UDS_GET_SUB_FUNCTION_SUPPRESS_POSRSP(obj->payload[1]); + } + else + { + obj->suppressPosRsp = 0; + } + + obj->curServiceIdx = i; + + obj->seviceTable[i].service(obj, obj->payload, outSize); + break; + } + } + } + else + { + Uds_NegativeResponse(obj, sid, NRC_SERVICE_NOT_SUPPORTED); + } + } + + if(true == Stimer_Timeout(&obj->s3ServerTimer)) + { + obj->session = 0x01; /* Default session */ + obj->securityLevel = 0; /* None security level */ + + Stimer_Init(&obj->s3ServerTimer); + } +} diff --git a/cva_asw_m0118/SDK/middleware/uds/stack/uds.h b/cva_asw_m0118/SDK/middleware/uds/stack/uds.h new file mode 100644 index 0000000..7b42941 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/stack/uds.h @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_H_ +#define _UDS_H_ + +/*! \brief Contains public interface to various functions related + * to the Unified Diagnostic Services (UDS) following ISO 14229 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include +#include +#include "stimer.h" +#include "isotp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define NRC_GENERAL_REJECT (0x10) +#define NRC_SERVICE_NOT_SUPPORTED (0x11) +#define NRC_SUBFUNCTION_NOT_SUPPORTED (0x12) +#define NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT (0x13) +#define NRC_RESPONSE_TOO_LONG (0x14) +#define NRC_CONDITIONS_NOT_CORRECT (0x22) +#define NRC_REQUEST_SEQUENCE_ERROR (0x24) +#define NRC_REQUEST_OUT_OF_RANGE (0x31) +#define NRC_SECURITY_ACCESS_DENIED (0x33) +#define NRC_INVALID_KEY (0x35) +#define NRC_EXCEEDED_NUMBER_OF_ATTEMPTS (0x36) +#define NRC_REQUIRED_TIME_DELAY_NOT_EXPIRED (0x37) +#define NRC_UPLOAD_DOWNNLOAD_NOT_ACCEPTED (0x70) +#define NRC_TRANSFER_DATA_SUSPENDED (0x71) +#define NRC_GENERAL_PROGRAMMING_FAILURE (0x72) +#define NRC_WRONG_BLOCK_SEQUENCE_COUNTER (0x73) +#define NRC_SERVICE_BUSY (0x78) +#define NRC_SUBFUNC_NOT_SUPPORTED_IN_ACTIVE_SESSION (0x7E) +#define NRC_SERVICE_NOT_SUPPORTED_IN_ACTIVE_SESSION (0x7F) + +#define POSITIVE_RSP (0x40) +#define NEGATIVE_RSP (0x7F) +#define UDS_GET_POSITIVE_RSP(sid) (POSITIVE_RSP + sid) + +#define UDS_MAX_PAYLOAD_SIZE (4096) + +#define UDS_SA_NONE (0) +#define UDS_SA_LEVEL_1 (0x01) +#define UDS_SA_LEVEL_3 (0x03) +#define UDS_SA_LEVEL_11 (0x11) +#define UDS_SA_LEVEL_63 (0x63) + +#define UDS_SESSION_DEFAULT (0x01) +#define UDS_SESSION_PROGRAMMING (0x02) +#define UDS_SESSION_EXTENDED (0x03) +#define UDS_SESSION_SAFTY (0x04) +#define UDS_SESSION_SUPPLIER (0x60) + +#define UDS_SERVICE_NUM (15) +#define UDS_SA_LEVEL_NUM (3) + +#define UDS_GET_SUB_FUNCTION(byte) ((byte)&0x7fu) + +#define BYTES_OF(x) (sizeof(x) / sizeof(uint8_t)) + +#define UDS_RSP_LEN_MAX (512) + +/* DID type */ +#define UDS_VAR_TYPE_NONVOL_STORAGE (1 << 0) /* set if non-volatile data */ +#define UDS_VAR_TYPE_MAY_READ (1 << 1) /* set if readable */ +#define UDS_VAR_TYPE_MAY_WRITE (1 << 2) /* set if writable */ +#define UDS_DID_TYPE_RAM_RW (UDS_VAR_TYPE_MAY_READ | UDS_VAR_TYPE_MAY_WRITE) +#define UDS_DID_TYPE_NVM_RW (UDS_VAR_TYPE_NONVOL_STORAGE | UDS_VAR_TYPE_MAY_READ | UDS_VAR_TYPE_MAY_WRITE) +#define UDS_DID_TYPE_NVM_WO (UDS_VAR_TYPE_NONVOL_STORAGE | UDS_VAR_TYPE_MAY_WRITE) +#define UDS_DID_TYPE_NVM_RO (UDS_VAR_TYPE_NONVOL_STORAGE | UDS_VAR_TYPE_MAY_READ) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Forward declaration of UDS object + */ +struct _UdsType_; +typedef struct _UdsType_ UdsType; + + +/*! \brief The Data-by-ID definition of UDS + */ +typedef struct _Uds_DidType_ +{ + uint16_t did; + uint8_t type; + uint8_t sessionLevel; + uint8_t securityLevel; + uint8_t *pBytes; + uint16_t length; + void (*function)(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen); +} Uds_DidType; + +/*! \brief The definition of UDS DID table + */ +typedef Uds_DidType *Uds_DidTable; + + +/*! \brief UDS service definition + */ +typedef struct _Uds_ServiceType_ +{ + uint8_t sid; + uint8_t minLen; + bool subFuncOwner; + void (*service)(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); +} Uds_ServiceType; + +/*! \brief The definition of UDS service table + */ +typedef const Uds_ServiceType *Uds_ServiceTable; + +/*! \brief The definition of UDS security table + * \note The table should be like table[SID number][security level number] + */ +typedef const bool *Uds_SecurityTableType; + +/*! \brief The definition of UDS initialization parameters + */ +typedef struct _Uds_ParamsType_ +{ + IsoTp_Params isotpParams; + uint16_t p2Server_ms; + uint16_t p2xServer_10ms; + uint16_t s3Server_ms; +} Uds_ParamsType; + +/*! \brief The UDS prototype definition + */ +struct _UdsType_ +{ + bool active; + uint8_t session; + uint8_t securityLevel; + uint32_t serviceNum; + Uds_ServiceTable seviceTable; + Uds_SecurityTableType securityTable; + Uds_DidTable didTable; + uint16_t didNum; + + IsoTpType isotp; + bool suppressPosRsp; + bool isFuncAddr; + uint8_t curServiceIdx; + uint8_t payload[UDS_MAX_PAYLOAD_SIZE]; + + int64_t timeStamp_ms; + + uint16_t p2Server_ms; + uint16_t p2xServer_10ms; + uint16_t s3Server_ms; + + StimerType p2ServerTimer; + StimerType p2xServerTimer; + StimerType s3ServerTimer; +}; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the UDS object. + */ +extern void Uds_Init(UdsType *obj, const Uds_ParamsType *pParams); + +/*! \brief The main service of UDS object. + * \note Suggest run every 1ms + */ +extern void Uds_Run(UdsType *obj); + +/*! \brief This function gives a positive response + */ +static inline void Uds_PositiveResponse(UdsType *obj, const uint8_t data[], uint16_t len) +{ + Stimer_Start(&obj->s3ServerTimer, obj->s3Server_ms); + if(obj->suppressPosRsp == true) + { + return; + } + IsoTp_Send(&obj->isotp, data, len); + return; +} + +/*! \brief This function gives a nagative response + */ +static inline void Uds_NegativeResponse(UdsType *obj, uint8_t sid, uint8_t rsp_nrc) +{ + uint8_t temp_buf[8] = {0}; + + if(rsp_nrc != NRC_SERVICE_BUSY) + { + Stimer_Start(&obj->s3ServerTimer, obj->s3Server_ms); + } + + if(obj->isFuncAddr && (rsp_nrc == NRC_SERVICE_NOT_SUPPORTED || rsp_nrc == NRC_SUBFUNCTION_NOT_SUPPORTED || rsp_nrc == NRC_REQUEST_OUT_OF_RANGE || rsp_nrc == NRC_SUBFUNC_NOT_SUPPORTED_IN_ACTIVE_SESSION || rsp_nrc == NRC_SERVICE_NOT_SUPPORTED_IN_ACTIVE_SESSION)) + { + return; + } + + temp_buf[0] = NEGATIVE_RSP; + temp_buf[1] = sid; + temp_buf[2] = rsp_nrc; + IsoTp_Send(&obj->isotp, temp_buf, 3); +} + +/*! \brief This function provide the time base for the UDS process + */ +static inline void Uds_Tick(UdsType *obj) +{ + obj->timeStamp_ms++; + + Stimer_Tick(&obj->p2ServerTimer); + Stimer_Tick(&obj->p2xServerTimer); + Stimer_Tick(&obj->s3ServerTimer); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_dtc.c b/cva_asw_m0118/SDK/middleware/uds/user/uds_dtc.c new file mode 100644 index 0000000..346c288 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_dtc.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_dtc.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define DTCG_EMISSION_START (0x00000000ul) /* 24Bit DTC define ISO-15031-6 DTC + ISO-15031-6 Failure Type, ISO14229-1 format */ +#define DTCG_EMISSION_END (0x000FFFFFul) +#define DTCG_POWERTRAIN_START (0x00100000ul) +#define DTCG_POWERTRAIN_END (0x003FFFFFul) +#define DTCG_CHASSIS_START (0x00400000ul) +#define DTCG_CHASSIS_END (0x007FFFFFul) +#define DTCG_BODY_START (0x00800000ul) +#define DTCG_BODY_END (0x00BFFFFFul) +#define DTCG_NETWORK_START (0x00C00000ul) +#define DTCG_NETWORK_END (0x00FFFFFFul) + +#define FAULTDT_MAX (127) /* refers to ISO14229-1 D.6 */ +#define FAULTDT_MIN (-128) /* refers to ISO14229-1 D.6 */ +#define AGING_MAX (40) /* refers to ISO14229-1 D.7 */ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/* the meaning of UDS DTC value refers to ISO 15031-6 */ +static Uds_DtcType udsDtcTable[DTC_MAX_COUNT] = { + {0x04621A, 0x50, 0x00, 0x00}, /* P0462 fuel level sensor "A" circuit resistance low */ + {0x04631B, 0x50, 0x00, 0x00}, /* P0463 fuel level sensor "A" circuit resistance high */ + {0xF00316, 0x50, 0x00, 0x00}, /* U3003 battery voltage low */ + {0xF00317, 0x50, 0x00, 0x00}, /* U3003 battery voltage high */ + {0xC07388, 0x50, 0x00, 0x00}, /* U0073 control module communication bus off */ + {0xC10001, 0x50, 0x00, 0x00}, /* U0100 lost communication with ECM/PCM "A" */ + {0xC10101, 0x50, 0x00, 0x00}, /* U0101 lost communication with TCM */ + {0xC12101, 0x50, 0x00, 0x00}, /* U0121 lost communication with ABS control module */ + {0xC12701, 0x50, 0x00, 0x00}, /* U0127 lost communication with tire pressure monitor module */ + {0xC12801, 0x50, 0x00, 0x00}, /* U0128 lost communication with park brake control module */ + {0xC12901, 0x50, 0x00, 0x00}, /* U0129 lost communication with brake system control module */ + {0xC13101, 0x50, 0x00, 0x00}, /* U0131 lost communication with power sterring control module */ + {0xC14100, 0x50, 0x00, 0x00}, /* U0141 lost communication with body control module "A" */ + {0xC15101, 0x50, 0x00, 0x00}, /* U0151 lost communication with restraints control module */ + {0xC16300, 0x50, 0x00, 0x00}, /* U0163 lost communication with navigation control module */ + {0xC16900, 0x50, 0x00, 0x00}, /* U0169 lost communication with sunroof control module */ + {0xC18101, 0x50, 0x00, 0x00}, /* U0181 lost communication with headlamp leveling control module */ + {0xC23601, 0x50, 0x00, 0x00}, /* U0236 lost communication with column lock module */ + {0xC16400, 0x50, 0x00, 0x00}, /* U0164 lost communication with HVAC control module */ + {0xC16700, 0x50, 0x00, 0x00}, /* U0167 lost communication with vehicle immobilizer control module */ +}; + +static bool dtcOffCtrl = false; + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void Uds_SetDtcOffCtrl(bool val) +{ + dtcOffCtrl = val; +} + +bool Uds_GetDtcOffCtrlState(void) +{ + return dtcOffCtrl; +} + +void Uds_ClearDtcByDtcIndex(uint16_t dtcIndex) +{ + if(dtcIndex >= DTC_MAX_COUNT) + { + return; + } + + udsDtcTable[dtcIndex].dtcStatus.all = 0; + udsDtcTable[dtcIndex].dtcStatus.bit.testNcmpSlc = 1; + udsDtcTable[dtcIndex].dtcStatus.bit.testNcmpToc = 1; + + udsDtcTable[dtcIndex].faultDtCnt = 0; + udsDtcTable[dtcIndex].AgingCnt = 0; +} + +void Uds_LoadDtc(void) +{ + /* code implemented by the user */ +} + +void Uds_SaveDtc(void) +{ + /* code implemented by the user */ +} + +uint16_t Uds_GetDtcNumberByStatusMask(uint8_t mask) +{ + uint16_t dtcCnt = 0; + uint8_t dtcState = 0; + uint16_t dtcNum = 0; + + for(dtcCnt = 0; dtcCnt < DTC_MAX_COUNT; dtcCnt++) + { + dtcState = (udsDtcTable[dtcCnt].dtcStatus.all & DTC_AVAILABILITY_STATUS_MASK); + if(0 != (dtcState & mask)) + { + dtcNum++; + } + } + + return dtcNum; +} + +uint16_t Uds_GetDtcByStatusMask(uint8_t *pDtcBuf, uint16_t bufLen, uint8_t mask) +{ + uint16_t dtcCnt = 0; + uint8_t dtcState = 0; + uint16_t dtcDlc = 0; + + for(dtcCnt = 0; dtcCnt < DTC_MAX_COUNT; dtcCnt++) + { + dtcState = udsDtcTable[dtcCnt].dtcStatus.all; + if(0 != (dtcState & mask)) + { + if((dtcDlc + 4) <= bufLen) + { + pDtcBuf[dtcDlc++] = (uint8_t)(udsDtcTable[dtcCnt].dtcCode >> 16); + pDtcBuf[dtcDlc++] = (uint8_t)(udsDtcTable[dtcCnt].dtcCode >> 8); + pDtcBuf[dtcDlc++] = (uint8_t)(udsDtcTable[dtcCnt].dtcCode >> 0); + pDtcBuf[dtcDlc++] = (dtcState & DTC_AVAILABILITY_STATUS_MASK); + } + else + { + break; + } + } + } + + return dtcDlc; +} + +uint16_t Uds_GetSupportedDtc(uint8_t *pDtcBuf, uint16_t bufLen) +{ + uint16_t dtcCnt = 0; + uint8_t dtcState = 0; + uint16_t dtcDlc = 0; + + for(dtcCnt = 0; dtcCnt < DTC_MAX_COUNT; dtcCnt++) + { + dtcState = udsDtcTable[dtcCnt].dtcStatus.all; + if((dtcDlc + 4) <= bufLen) + { + pDtcBuf[dtcDlc++] = (uint8_t)(udsDtcTable[dtcCnt].dtcCode >> 16); + pDtcBuf[dtcDlc++] = (uint8_t)(udsDtcTable[dtcCnt].dtcCode >> 8); + pDtcBuf[dtcDlc++] = (uint8_t)(udsDtcTable[dtcCnt].dtcCode >> 0); + pDtcBuf[dtcDlc++] = (dtcState & DTC_AVAILABILITY_STATUS_MASK); + } + else + { + break; + } + } + + return dtcDlc; +} + +void Uds_ClearDtcByGroup(uint32_t group) +{ + uint16_t dtcCnt = 0; + + switch(group) + { + case EMISSION_SYSTEM_GROUP: + for(dtcCnt = 0; dtcCnt < DTC_MAX_COUNT; dtcCnt++) + { + if(udsDtcTable[dtcCnt].dtcCode <= DTCG_EMISSION_END) + { + Uds_ClearDtcByDtcIndex(dtcCnt); + } + } + break; + case SAFETY_SYSTEM_GROUP: + for(dtcCnt = 0; dtcCnt < DTC_MAX_COUNT; dtcCnt++) + { + if((udsDtcTable[dtcCnt].dtcCode >= DTCG_CHASSIS_START) && (udsDtcTable[dtcCnt].dtcCode <= DTCG_CHASSIS_END)) + { + Uds_ClearDtcByDtcIndex(dtcCnt); + } + } + break; + case ALL_FUNC_SYSTEM_GROUP: + for(dtcCnt = 0; dtcCnt < DTC_MAX_COUNT; dtcCnt++) + { + Uds_ClearDtcByDtcIndex(dtcCnt); + } + break; + } +} diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_dtc.h b/cva_asw_m0118/SDK/middleware/uds/user/uds_dtc.h new file mode 100644 index 0000000..155c984 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_dtc.h @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_DTC_H_ +#define _UDS_DTC_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS application + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define EMISSION_SYSTEM_GROUP (0x00FFFF33) +#define SAFETY_SYSTEM_GROUP (0x00FFFFD0) +#define ALL_FUNC_SYSTEM_GROUP (0x00FFFFFF) + +#define REPORT_DTC_NUMBER_BY_STATUS_MASK (0x01) +#define REPORT_DTC_BY_STATUS_MASK (0x02) +#define REPORT_DTC_SNOPSHOT_IDENTIFICATION (0x03) +#define REPORT_DTC_SNOPSHOT_RECORD_BY_DTC_NUMBER (0x04) +#define REPORT_DTC_STORE_DATA_BY_RECORD_NUMBER (0x05) +#define REPORT_DTC_EXT_DATA_RECORD_BY_DTC_NUMBER (0x06) +#define REPORT_DTC_NUMBER_BY_SEVERITY_MASK_RECORD (0x07) +#define REPORT_DTC_BY_SEVERITY_MASK_RECORD (0x08) +#define REPORT_SUPPORTED_DTC (0x0a) + +#define DTC_FORMAT_15031 (0x00) +#define DTC_FORMAT_14229 (0x01) +#define DTC_FORMAT_J1939 (0x02) +#define DTC_FORMAT_11992 (0x03) + +#define DTC_AVAILABILITY_STATUS_MASK (0x7F) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The DTC Index name of UDS supported + */ +typedef enum _Uds_DtcIndexNameType_ +{ + DTC_FUEL_SENSOR_BELOW = 0, + DTC_FUEL_SENSOR_ABOVE, + DTC_BATT_VOLTAG_BELOW, + DTC_BATT_VOLTAG_ABOVE, + DTC_CAN_BUS_OFF, + DTC_COM_LOST_EMS, + DTC_COM_LOST_TCU, + DTC_COM_LOST_ABS, + DTC_COM_LOST_TPMS, + DTC_COM_LOST_EPB, + DTC_COM_LOST_ESP, + DTC_COM_LOST_EPS, + DTC_COM_LOST_BCM, + DTC_COM_LOST_SRS, + DTC_COM_LOST_DVD, + DTC_COM_LOST_PDC, + DTC_COM_LOST_ALS, + DTC_COM_LOST_PEPS, + DTC_COM_LOST_AC, + DTC_COM_LOST_AVM, + DTC_MAX_COUNT +} Uds_DtcIndexNameType; + +/*! \brief The DTC status definition refers to ISO14229-1 D.2.4 + * \note Bit 0, testFailed, clear by test pass or ClearDiagnosticInformation + * Bit 1, testFailedThisOperationCycle, clear by new OC or ClearDiagnosticInformation + * Bit 2, latch, pendingDTC, clear by fault never happened in cur OC or ClearDiagnosticInformation, if test not completed, must hold. + * Bit 3, latch, confirmedDTC, clear by ClearDiagnosticInformation, one(only by normal fault) or 40 OC not detect any fault. + * Bit 4, latch, testNotCompletedSinceLastClear, set by a new OC start or ClearDiagnosticInformation + * Bit 5, latch, testFailedSinceLastClear, clear by ClearDiagnosticInformation + * Bit 6, testNotCompletedThisOperationCycle + * Bit 7, warningIndicatorRequested(unsupported) + */ +typedef union _Uds_DtcStatusType_ +{ + uint8_t all; + struct + { + uint8_t testFailed : 1; + uint8_t testFailToc : 1; + uint8_t pending : 1; + uint8_t confirmed : 1; + uint8_t testNcmpSlc : 1; + uint8_t testFailSlc : 1; + uint8_t testNcmpToc : 1; + uint8_t wnIndreq : 1; + } bit; +} Uds_DtcStatusType; + +/*! \brief The DTC definition of UDS + */ +typedef struct _Uds_DtcType_ +{ + uint32_t dtcCode; + Uds_DtcStatusType dtcStatus; + int16_t faultDtCnt; /* refers to ISO14229-1 D.6 */ + uint8_t AgingCnt; /* refers to ISO14229-1 D.7 */ +} Uds_DtcType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief control DTC status updata stop and start + */ +extern void Uds_SetDtcOffCtrl(bool val); + +/*! \brief get control DTC status + */ +extern bool Uds_GetDtcOffCtrlState(void); + +/*! \brief clear DTC by dtc index + */ +extern void Uds_ClearDtcByDtcIndex(uint16_t dtcIndex); + +/*! \brief load dtc data from EEPROM + */ +extern void Uds_LoadDtc(void); + +/*! \brief save dtc data to EEPROM + */ +extern void Uds_SaveDtc(void); + +/*! \brief get DTC counter by dtc status mask + */ +extern uint16_t Uds_GetDtcNumberByStatusMask(uint8_t mask); + +/*! \brief get DTC data by dtc status mask + */ +extern uint16_t Uds_GetDtcByStatusMask(uint8_t *pDtcBuf, uint16_t bufLen, uint8_t mask); + +/*! \brief get all supported DTC data + */ +extern uint16_t Uds_GetSupportedDtc(uint8_t *pDtcBuf, uint16_t bufLen); + +/*! \brief clear DTC by dtc group + */ +extern void Uds_ClearDtcByGroup(uint32_t group); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_DTC_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service10.c b/cva_asw_m0118/SDK/middleware/uds/user/uds_service10.c new file mode 100644 index 0000000..2d92ba4 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service10.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_service10.h" + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void UdsService10_SessionControl(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint8_t subFunction; + uint8_t rspBuffer[8] = {0}; /* polyspace DEFECT:PARTIALLY_ACCESSED_ARRAY [No action planned:Low] "Still keep default though member6~7 is not written" */ + + if(msgLen != obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x10, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + subFunction = UDS_GET_SUB_FUNCTION (msgBuf[1]); + + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x10); + rspBuffer[1] = subFunction; + rspBuffer[2] = (uint8_t)(obj->p2Server_ms >> 8); + rspBuffer[3] = (uint8_t)(obj->p2Server_ms & 0x00ff); + rspBuffer[4] = (uint8_t)(obj->p2xServer_10ms >> 8); + rspBuffer[5] = (uint8_t)(obj->p2xServer_10ms & 0x00ff); + switch(subFunction) + { + case UDS_SESSION_DEFAULT: + obj->securityLevel = UDS_SA_NONE; + obj->session = subFunction; + Uds_PositiveResponse(obj, rspBuffer, 6); + break; + case UDS_SESSION_EXTENDED: + obj->securityLevel = UDS_SA_NONE; + obj->session = subFunction; + Uds_PositiveResponse(obj, rspBuffer, 6); + break; + case UDS_SESSION_PROGRAMMING: + obj->securityLevel = UDS_SA_NONE; + obj->session = subFunction; + Uds_PositiveResponse(obj, rspBuffer, 6); + break; + case UDS_SESSION_SAFTY: + obj->securityLevel = UDS_SA_NONE; + obj->session = subFunction; + Uds_PositiveResponse(obj, rspBuffer, 6); + break; + default: + Uds_NegativeResponse(obj, 0x10, NRC_SUBFUNCTION_NOT_SUPPORTED); + break; + } +} + diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service10.h b/cva_asw_m0118/SDK/middleware/uds/user/uds_service10.h new file mode 100644 index 0000000..995a8d9 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service10.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE10_H_ +#define _UDS_SERVICE10_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 10 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 10 processing + */ +extern void UdsService10_SessionControl(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE10_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service11.c b/cva_asw_m0118/SDK/middleware/uds/user/uds_service11.c new file mode 100644 index 0000000..1f17961 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service11.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_service11.h" +#include "extern.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The Reset type definition of Uds + */ +typedef enum _UdsResetType_ +{ + UDS_RESET_NONE = 0, + UDS_RESET_HARD, + UDS_RESET_KEYOFFON, + UDS_RESET_SOFT +} UdsResetType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void UdsService11_ResetEcu(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint8_t subFunction; + uint8_t rspBuffer[8] = {0}; /* polyspace DEFECT:PARTIALLY_ACCESSED_ARRAY [No action planned:Low] "Still keep default though member3~7 is not written" */ + uint8_t powerDownTime = 0xFF; + + if(msgLen != obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x11, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + subFunction = UDS_GET_SUB_FUNCTION(msgBuf[1]); + + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x11); + rspBuffer[1] = subFunction; + rspBuffer[2] = powerDownTime; + switch(subFunction) + { + case UDS_RESET_HARD: + Uds_PositiveResponse(obj, rspBuffer, 3); + /*add hardware reset code*/ + extHardwareReset(); + break; + case UDS_RESET_KEYOFFON: + Uds_PositiveResponse(obj, rspBuffer, 3); + /*add keyoffon reset code*/ + + break; + case UDS_RESET_SOFT: + Uds_PositiveResponse(obj, rspBuffer, 3); + /*add software reset code*/ + extSortwareReset(); + break; + default: + Uds_NegativeResponse(obj, 0x11, NRC_SUBFUNCTION_NOT_SUPPORTED); + break; + } +} diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service11.h b/cva_asw_m0118/SDK/middleware/uds/user/uds_service11.h new file mode 100644 index 0000000..ef4b0aa --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service11.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE11_H_ +#define _UDS_SERVICE11_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 11 + */ +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 11 processing + */ +extern void UdsService11_ResetEcu(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE11_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service14.c b/cva_asw_m0118/SDK/middleware/uds/user/uds_service14.c new file mode 100644 index 0000000..bd0e350 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service14.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_service14.h" +#include "uds_dtc.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void UdsService14_ClearDiagInfo(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint32_t dtcGroup = 0; + uint8_t rspBuffer[8] = {0}; + + if(msgLen != obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x14, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + dtcGroup |= ((uint32_t)msgBuf[1]) << 16; + dtcGroup |= ((uint32_t)msgBuf[2]) << 8; + dtcGroup |= ((uint32_t)msgBuf[3]) << 0; + + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x14); + + switch(dtcGroup) + { + case EMISSION_SYSTEM_GROUP: + case SAFETY_SYSTEM_GROUP: + case ALL_FUNC_SYSTEM_GROUP: + Uds_ClearDtcByGroup(dtcGroup); + Uds_PositiveResponse(obj, rspBuffer, 1); + break; + default: + Uds_NegativeResponse(obj, 0x14, NRC_REQUEST_OUT_OF_RANGE); + break; + } +} + + + diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service14.h b/cva_asw_m0118/SDK/middleware/uds/user/uds_service14.h new file mode 100644 index 0000000..d01d624 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service14.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE14_H_ +#define _UDS_SERVICE14_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 14 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 14 processing + */ +extern void UdsService14_ClearDiagInfo(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE14_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service19.c b/cva_asw_m0118/SDK/middleware/uds/user/uds_service19.c new file mode 100644 index 0000000..7787a63 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service19.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_service19.h" +#include "uds_dtc.h" + + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void UdsService19_ReadDtcInformation(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint8_t subFunction = 0; + uint8_t dtcStatusMask = 0; + uint16_t dtcCount = 0; + uint16_t dtcDlc = 0; + uint8_t rspBuffer[UDS_RSP_LEN_MAX] = {0}; + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x19, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + subFunction = UDS_GET_SUB_FUNCTION (msgBuf[1]); + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x19); + rspBuffer[1] = subFunction; + switch(subFunction) + { + case REPORT_DTC_NUMBER_BY_STATUS_MASK: + if(msgLen != 3) + { + Uds_NegativeResponse(obj, 0x19, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + dtcStatusMask = msgBuf[2]; + dtcCount = Uds_GetDtcNumberByStatusMask(dtcStatusMask); + rspBuffer[2] = DTC_AVAILABILITY_STATUS_MASK; + rspBuffer[3] = DTC_FORMAT_14229; + rspBuffer[4] = (dtcCount >> 8) & 0xFF; + rspBuffer[5] = (dtcCount >> 0) & 0xFF; + Uds_PositiveResponse(obj, rspBuffer, 6); + break; + case REPORT_DTC_BY_STATUS_MASK: + if(msgLen != 3) + { + Uds_NegativeResponse(obj, 0x19, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + dtcStatusMask = msgBuf[2]; + rspBuffer[2] = DTC_AVAILABILITY_STATUS_MASK; + dtcDlc = Uds_GetDtcByStatusMask(&rspBuffer[3], UDS_RSP_LEN_MAX - 3, dtcStatusMask); + Uds_PositiveResponse(obj, rspBuffer, dtcDlc + 3); + break; +#if 0 + case REPORT_DTC_SNOPSHOT_IDENTIFICATION: + if(msgLen != 6) + { + UDS_negativeResponse(obj, 0x19, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + /* add user code */ + + break; + case REPORT_DTC_SNOPSHOT_RECORD_BY_DTC_NUMBER: + if(msgLen != 6) + { + UDS_negativeResponse(obj, 0x19, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + /* add user code */ + + break; + case REPORT_DTC_STORE_DATA_BY_RECORD_NUMBER: + if(msgLen != 3) + { + UDS_negativeResponse(obj, 0x19, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + /* add user code */ + + break; + case REPORT_DTC_EXT_DATA_RECORD_BY_DTC_NUMBER: + if(msgLen != 6) + { + UDS_negativeResponse(obj, 0x19, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + /* add user code */ + + break; + case REPORT_DTC_NUMBER_BY_SEVERITY_MASK_RECORD: + if(msgLen != 4) + { + UDS_negativeResponse(obj, 0x19, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + /* add user code */ + + break; + case REPORT_DTC_BY_SEVERITY_MASK_RECORD: + if(msgLen != 4) + { + UDS_negativeResponse(obj, 0x19, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + /* add user code */ + + break; +#endif + case REPORT_SUPPORTED_DTC: + if(msgLen != 2) + { + Uds_NegativeResponse(obj, 0x19, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + dtcDlc = Uds_GetSupportedDtc(&rspBuffer[3], UDS_RSP_LEN_MAX - 3); + Uds_PositiveResponse(obj, rspBuffer, dtcDlc + 3); + break; + default: + Uds_NegativeResponse(obj, 0x19, NRC_SUBFUNCTION_NOT_SUPPORTED); + break; + } +} + + diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service19.h b/cva_asw_m0118/SDK/middleware/uds/user/uds_service19.h new file mode 100644 index 0000000..6179d1d --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service19.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE19_H_ +#define _UDS_SERVICE19_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 19 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 19 processing + */ +extern void UdsService19_ReadDtcInformation(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE19_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service22.c b/cva_asw_m0118/SDK/middleware/uds/user/uds_service22.c new file mode 100644 index 0000000..0c7500c --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service22.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ +#include +#include "uds_service22.h" + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void UdsService22_ReadDataByIdentifier(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint16_t didNum = 0; + uint16_t didValue = 0; + uint16_t rspLen = 0; + uint16_t msgPos = 0, didIdx = 0; + bool findDid = false; + uint8_t rspBuffer[UDS_RSP_LEN_MAX] = {0}; + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x22, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + if(0 != (msgLen - 1) % sizeof(uint16_t)) + { + Uds_NegativeResponse(obj, 0x22, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + didNum = msgLen / sizeof(uint16_t); + if(0 == didNum) + { + Uds_NegativeResponse(obj, 0x22, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + rspBuffer[rspLen++] = UDS_GET_POSITIVE_RSP(0x22); + + for(msgPos = 1; msgPos < msgLen; msgPos += 2) + { + didValue = ((uint16_t)msgBuf[msgPos]) << 8; + didValue |= msgBuf[msgPos + 1]; + + findDid = false; + for(didIdx = 0; didIdx < obj->didNum; didIdx++) + { + if(obj->didTable[didIdx].did == didValue) + { + if(obj->securityLevel != obj->didTable[didIdx].securityLevel) + { + Uds_NegativeResponse(obj, 0x22, NRC_SECURITY_ACCESS_DENIED); + return; + } + else if((rspLen + 2 + obj->didTable[didIdx].length) > UDS_RSP_LEN_MAX) + { + Uds_NegativeResponse(obj, 0x22, NRC_RESPONSE_TOO_LONG); + return; + } + + if((UDS_DID_TYPE_NVM_WO == obj->didTable[didIdx].type) || (obj->session < obj->didTable[didIdx].sessionLevel)) + { + Uds_NegativeResponse(obj, 0x22, NRC_CONDITIONS_NOT_CORRECT); + return; + } + obj->didTable[didIdx].function(obj, obj->didTable[didIdx].pBytes, obj->didTable[didIdx].length); + findDid = true; + rspBuffer[rspLen++] = msgBuf[msgPos]; + rspBuffer[rspLen++] = msgBuf[msgPos + 1]; + memcpy(&rspBuffer[rspLen], obj->didTable[didIdx].pBytes, obj->didTable[didIdx].length); + rspLen += obj->didTable[didIdx].length; + break; + } + } + if(false == findDid) + { + break; + } + } + + if(true == findDid) + { + Uds_PositiveResponse(obj, rspBuffer, rspLen); + } + else + { + Uds_NegativeResponse(obj, 0x22, NRC_REQUEST_OUT_OF_RANGE); + } + +} + + diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service22.h b/cva_asw_m0118/SDK/middleware/uds/user/uds_service22.h new file mode 100644 index 0000000..c1d11dd --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service22.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE22_H_ +#define _UDS_SERVICE22_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 22 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 22 processing + */ +extern void UdsService22_ReadDataByIdentifier(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE22_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service27.c b/cva_asw_m0118/SDK/middleware/uds/user/uds_service27.c new file mode 100644 index 0000000..281372b --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service27.c @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "uds_service27.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define SUPPORT_LEVEL_NUM 4 /* supported security level number */ + +#define MAX_ALLOW_ERROR_NUM 5 /* the max allow number of key error */ + +#define STARTUP_DELAY_MS 2000 /* the service allow access time delay after UDS start */ +#define ERR_EXCEED_DELAY_MS 10000 /* the service allow access time delay after error number exceed */ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +typedef struct _SecurityLevel_Param_ +{ + uint8_t level; + uint8_t keyErrorCnt; + uint8_t maxErrNum; + int64_t MaxErrTimeStamp; +} SecurityLevel_Param; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +SecurityLevel_Param scrtParam[SUPPORT_LEVEL_NUM] = { + {UDS_SA_LEVEL_1, 0, MAX_ALLOW_ERROR_NUM, 0}, + {UDS_SA_LEVEL_3, 0, MAX_ALLOW_ERROR_NUM, 0}, + {UDS_SA_LEVEL_11, 0, MAX_ALLOW_ERROR_NUM, 0}, + {UDS_SA_LEVEL_63, 0, MAX_ALLOW_ERROR_NUM, 0}, +}; + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +static void UdsSecurityAccess_GenerateSeed(UdsType *obj, uint8_t newLevel, uint8_t *outData, uint8_t outBufsize, uint16_t *outLen) +{ + /* seed is defined by user, It's usually a random value */ + uint8_t seed[4] = {1, 2, 3, 4}; + + if(outBufsize < sizeof(seed)) + { + return; + } + + *outLen = sizeof(seed); + if(newLevel == obj->securityLevel) + { + memset(outData, 0, sizeof(seed)); + } + else + { + memcpy(outData, seed, sizeof(seed)); + } +} + +static bool UdsSecurityAccess_ValidateKey(uint8_t seedLevel, const uint8_t *seed, uint16_t seedLen, const uint8_t *key, uint16_t keyLen) +{ + /* The encryption algorithm is provided by the vehicle manufacturer */ + + return true; +} + +void UdsService27_SecurityAccess(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + static uint8_t seedLevel = 0; + static uint8_t seedValue[8] = {0}; + static uint16_t seedLen = 0; + uint8_t subFunction; + uint8_t udx = 0; + uint8_t rspBuffer[8] = {0}; + uint16_t dataLen = 0, remainSize = 0; + bool ret = false; + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x27, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + if(obj->session == UDS_SESSION_DEFAULT) + { + Uds_NegativeResponse(obj, 0x27, NRC_CONDITIONS_NOT_CORRECT); + return; + } + + if(obj->timeStamp_ms < STARTUP_DELAY_MS) + { + Uds_NegativeResponse(obj, 0x27, NRC_REQUIRED_TIME_DELAY_NOT_EXPIRED); + return; + } + + subFunction = UDS_GET_SUB_FUNCTION(msgBuf[1]); + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x27); + rspBuffer[1] = subFunction; + if(subFunction % 2) + { + seedLevel = 0; + for(udx = 0; udx < SUPPORT_LEVEL_NUM; udx++) + { + if(subFunction == scrtParam[udx].level) + { + if(scrtParam[udx].keyErrorCnt > scrtParam[udx].maxErrNum) + { + if(obj->timeStamp_ms - scrtParam[udx].MaxErrTimeStamp < ERR_EXCEED_DELAY_MS) + { + Uds_NegativeResponse(obj, 0x27, NRC_EXCEEDED_NUMBER_OF_ATTEMPTS); + return; + } + else + { + scrtParam[udx].keyErrorCnt = 0; + } + } + break; + } + } + + if(udx >= SUPPORT_LEVEL_NUM) + { + Uds_NegativeResponse(obj, 0x27, NRC_REQUEST_OUT_OF_RANGE); + return; + } + + remainSize = sizeof(rspBuffer) - 2; + UdsSecurityAccess_GenerateSeed(obj, subFunction, &rspBuffer[2], remainSize, &dataLen); + if(dataLen > 0) + { + Uds_PositiveResponse(obj, rspBuffer, dataLen + 2); + + seedLevel = subFunction; + seedLen = dataLen; + memcpy(seedValue, &rspBuffer[2], dataLen); + } + else + { + Uds_NegativeResponse(obj, 0x27, NRC_REQUEST_OUT_OF_RANGE); + } + } + else + { + if(subFunction != seedLevel + 1) + { + Uds_NegativeResponse(obj, 0x27, NRC_REQUEST_SEQUENCE_ERROR); + return; + } + + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still reserve though it's maybe unreachable" */ + ret = UdsSecurityAccess_ValidateKey(seedLevel, seedValue, seedLen, &msgBuf[2], msgLen - 2); + if(ret == true) + { + Uds_PositiveResponse(obj, rspBuffer, 2); + + seedLevel = 0; + obj->securityLevel = subFunction - 1; + + for(udx = 0; udx < SUPPORT_LEVEL_NUM; udx++) + { + if(subFunction == scrtParam[udx].level) + { + scrtParam[udx].keyErrorCnt = 0; + } + } + } + else + { + Uds_NegativeResponse(obj, 0x27, NRC_INVALID_KEY); + + for(udx = 0; udx < SUPPORT_LEVEL_NUM; udx++) + { + if(seedLevel == scrtParam[udx].level) + { + scrtParam[udx].keyErrorCnt++; + if(scrtParam[udx].keyErrorCnt > scrtParam[udx].maxErrNum) + { + scrtParam[udx].MaxErrTimeStamp = obj->timeStamp_ms; + } + } + } + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still reserve though it's maybe unreachable" */ + } +} diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service27.h b/cva_asw_m0118/SDK/middleware/uds/user/uds_service27.h new file mode 100644 index 0000000..8d04ec9 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service27.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE27_H_ +#define _UDS_SERVICE27_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 27 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 27 processing + */ +extern void UdsService27_SecurityAccess(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE27_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service28.c b/cva_asw_m0118/SDK/middleware/uds/user/uds_service28.c new file mode 100644 index 0000000..8fbcf7b --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service28.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_service28.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The uds communication type definition of UDS + */ +typedef enum _UdsComType_ +{ + UDS_CC_TYPE_NONE = 0, + UDS_CC_TYPE_NORMAL, /* normal message */ + UDS_CC_TYPE_NM, /* network management */ + UDS_CC_TYPE_NOR_NM, /* normal and network management message */ +} UdsComType; + +/*! \brief The uds communication control mode definition of UDS + */ +typedef enum _UdsComCtrlMode_ +{ + UDS_CC_MODE_RX_TX = 0, + UDS_CC_MODE_RX_NO, + UDS_CC_MODE_NO_TX, + UDS_CC_MODE_NO_NO +} UdsComCtrMode; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +static uint8_t udsComCtrlType = 0; + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +uint8_t Uds_GetCommunicationControlMode(void) +{ + return udsComCtrlType; +} + +void UdsService28_CommunicationControl(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint8_t subFunction; + uint8_t rspBuffer[8] = {0}; /* polyspace DEFECT:PARTIALLY_ACCESSED_ARRAY [No action planned:Low] "Still keep default though member2~7 is not written" */ + uint8_t ccType = 0; + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x28, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + if(obj->session == UDS_SESSION_DEFAULT) + { + Uds_NegativeResponse(obj, 0x28, NRC_CONDITIONS_NOT_CORRECT); + return; + } + + subFunction = UDS_GET_SUB_FUNCTION(msgBuf[1]); + ccType = msgBuf[2]; + + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x28); + rspBuffer[1] = subFunction; + switch(subFunction) + { + case UDS_CC_MODE_RX_TX: + if(ccType == UDS_CC_TYPE_NORMAL || ccType == UDS_CC_TYPE_NM || ccType == UDS_CC_TYPE_NOR_NM) + { + udsComCtrlType = UDS_CC_MODE_RX_TX; + + Uds_PositiveResponse(obj, rspBuffer, 2); + } + else + { + Uds_NegativeResponse(obj, 0x28, NRC_REQUEST_OUT_OF_RANGE); + } + break; + case UDS_CC_MODE_RX_NO: + if(ccType == UDS_CC_TYPE_NORMAL || ccType == UDS_CC_TYPE_NM || ccType == UDS_CC_TYPE_NOR_NM) + { + udsComCtrlType = UDS_CC_MODE_RX_NO; + + Uds_PositiveResponse(obj, rspBuffer, 2); + } + else + { + Uds_NegativeResponse(obj, 0x28, NRC_REQUEST_OUT_OF_RANGE); + } + break; + case UDS_CC_MODE_NO_TX: + if(ccType == UDS_CC_TYPE_NORMAL || ccType == UDS_CC_TYPE_NM || ccType == UDS_CC_TYPE_NOR_NM) + { + udsComCtrlType = UDS_CC_MODE_NO_TX; + + Uds_PositiveResponse(obj, rspBuffer, 2); + } + else + { + Uds_NegativeResponse(obj, 0x28, NRC_REQUEST_OUT_OF_RANGE); + } + break; + case UDS_CC_MODE_NO_NO: + if(ccType == UDS_CC_TYPE_NORMAL || ccType == UDS_CC_TYPE_NM || ccType == UDS_CC_TYPE_NOR_NM) + { + udsComCtrlType = UDS_CC_MODE_NO_NO; + + Uds_PositiveResponse(obj, rspBuffer, 2); + } + else + { + Uds_NegativeResponse(obj, 0x28, NRC_REQUEST_OUT_OF_RANGE); + } + break; + default: + Uds_NegativeResponse(obj, 0x28, NRC_SUBFUNCTION_NOT_SUPPORTED); + break; + } +} diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service28.h b/cva_asw_m0118/SDK/middleware/uds/user/uds_service28.h new file mode 100644 index 0000000..7e3c098 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service28.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE28_H_ +#define _UDS_SERVICE28_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 28 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Get Communication Control Mode + */ +uint8_t Uds_GetCommunicationControlMode(void); + +/*! \brief Uds Service 28 processing + */ +extern void UdsService28_CommunicationControl(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE28_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service2E.c b/cva_asw_m0118/SDK/middleware/uds/user/uds_service2E.c new file mode 100644 index 0000000..0dcc7a0 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service2E.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "uds_service2E.h" + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void UdsService2E_WriteDataByIdentifier(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint16_t didValue = 0; + uint16_t didIdx = 0; + uint8_t rspBuffer[8] = {0}; + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x2E, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + didValue = ((uint16_t)msgBuf[1]) << 8; + didValue |= msgBuf[2]; + + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x2E); + rspBuffer[1] = msgBuf[1]; + rspBuffer[2] = msgBuf[2]; + for(didIdx = 0; didIdx < obj->didNum; didIdx++) + { + if(obj->didTable[didIdx].did == didValue) + { + if((obj->didTable[didIdx].securityLevel != UDS_SA_NONE) && (obj->securityLevel != obj->didTable[didIdx].securityLevel)) + { + Uds_NegativeResponse(obj, 0x22, NRC_SECURITY_ACCESS_DENIED); + return; + } + else if((msgLen - 3) != obj->didTable[didIdx].length) + { + Uds_NegativeResponse(obj, 0x2E, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + if((UDS_DID_TYPE_NVM_RO == obj->didTable[didIdx].type) || (obj->session < obj->didTable[didIdx].sessionLevel)) + { + Uds_NegativeResponse(obj, 0x2E, NRC_CONDITIONS_NOT_CORRECT); + return; + } + + memcpy(obj->didTable[didIdx].pBytes, &msgBuf[3], obj->didTable[didIdx].length); + /* add user code to save data */ + + /* check save data success */ + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still reserve though it's maybe unreachable" */ + if(1) + { + Uds_PositiveResponse(obj, rspBuffer, 3); + return; + } + else + { + Uds_NegativeResponse(obj, 0x2E, NRC_GENERAL_PROGRAMMING_FAILURE); + return; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still reserve though it's maybe unreachable" */ + } + } + + Uds_NegativeResponse(obj, 0x2E, NRC_REQUEST_OUT_OF_RANGE); +} + + + diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service2E.h b/cva_asw_m0118/SDK/middleware/uds/user/uds_service2E.h new file mode 100644 index 0000000..f35f493 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service2E.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE2E_H_ +#define _UDS_SERVICE2E_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 2E + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 2E processing + */ +extern void UdsService2E_WriteDataByIdentifier(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE2E_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service2F.c b/cva_asw_m0118/SDK/middleware/uds/user/uds_service2F.c new file mode 100644 index 0000000..9023068 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service2F.c @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "uds_service2F.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The Uds IO control type + */ +typedef enum _UdsIoCtrlType_ +{ + UDS_IOCTRL_RETURN_TO_ECU = 0x00, + UDS_IOCTRL_RETSET_TO_DEFAULT = 0x01, + UDS_IOCTRL_FREEZE_CURRENT_STATE = 0x02, + UDS_IOCTRL_SHORT_ADJUSTMENT = 0x03 +} UdsIoCtrlType; + +/*! \brief The Uds IO control struct + */ +typedef struct _Uds_IoCtrl_ +{ + uint16_t did; + uint8_t securityLevel; + uint8_t *pData; + uint8_t dataLen; + uint8_t defaultValue; + uint8_t step; + bool enable; + void (*IoCtrl_Init)(void); + void (*IoCtrl_Stop)(void); +} Uds_IoCtrl; + +/*! \brief The IoControl-by-ID definition of UDS + */ +typedef struct _Uds_IoCtrlBuf_ +{ + uint8_t backlightLevel[2]; + uint8_t buzzer[2]; +} Uds_IoCtrlBuf; + +/******************************************************************************* + * the constants + ******************************************************************************/ + +static void IoCtrl_InitBackLight(void); +static void IoCtrl_StopBacklight(void); +static void IoCtrl_InitBuzzer(void); +static void IoCtrl_StopBuzzer(void); + +/******************************************************************************* + * the globals + ******************************************************************************/ + +Uds_IoCtrlBuf udsIoCtrlBuffer; + +Uds_IoCtrl udsIoCtrlTable[] = { + {0xF092, UDS_SA_NONE, udsIoCtrlBuffer.backlightLevel, 2, 0, 0, 0, &IoCtrl_InitBackLight, &IoCtrl_StopBacklight}, + {0xF020, UDS_SA_NONE, udsIoCtrlBuffer.buzzer, 2, 0, 0, 0, &IoCtrl_InitBuzzer, &IoCtrl_StopBuzzer }, +}; + +/******************************************************************************* + * the functions + ******************************************************************************/ + +static void IoCtrl_InitBackLight(void) +{ + /* user add back light control code */ +} + +static void IoCtrl_StopBacklight(void) +{ + /* user add back light stop code */ +} + +static void IoCtrl_InitBuzzer(void) +{ + /* user add buzzer control code */ +} + +static void IoCtrl_StopBuzzer(void) +{ + /* user add buzzer stop code */ +} + +void UdsService2F_InputOutputCtrlById(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint16_t ioCtrlId = 0; + uint8_t ioCtrlParam = 0; + uint8_t ioCtrlIndex = 0; + uint8_t ioCtrlNum = sizeof(udsIoCtrlTable) / sizeof(udsIoCtrlTable[0]); + uint8_t rspBuffer[UDS_RSP_LEN_MAX] = {0}; + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x2F, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + if(obj->session == UDS_SESSION_DEFAULT) + { + Uds_NegativeResponse(obj, 0x2F, NRC_CONDITIONS_NOT_CORRECT); + return; + } + + ioCtrlId = ((uint16_t)msgBuf[1] << 8) + msgBuf[2]; + ioCtrlParam = msgBuf[3]; + + for(ioCtrlIndex = 0; ioCtrlIndex < ioCtrlNum; ioCtrlIndex++) + { + if(udsIoCtrlTable[ioCtrlIndex].did == ioCtrlId) + { + if((udsIoCtrlTable[ioCtrlIndex].securityLevel != UDS_SA_NONE) && (udsIoCtrlTable[ioCtrlIndex].securityLevel != obj->securityLevel)) + { + Uds_NegativeResponse(obj, 0x2F, NRC_SECURITY_ACCESS_DENIED); + return; + } + + break; + } + } + + if(ioCtrlIndex >= ioCtrlNum) + { + Uds_NegativeResponse(obj, 0x2F, NRC_REQUEST_OUT_OF_RANGE); + return; + } + + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x2F); + rspBuffer[1] = msgBuf[1]; + rspBuffer[2] = msgBuf[2]; + rspBuffer[3] = msgBuf[3]; + switch(ioCtrlParam) + { + case UDS_IOCTRL_RETURN_TO_ECU: + /* add user code */ + udsIoCtrlTable[ioCtrlIndex].enable = false; + if(udsIoCtrlTable[ioCtrlIndex].IoCtrl_Stop != NULL) + { + udsIoCtrlTable[ioCtrlIndex].IoCtrl_Stop(); + Uds_PositiveResponse(obj, rspBuffer, 4); + } + + break; + case UDS_IOCTRL_SHORT_ADJUSTMENT: + /* add user code */ + if(msgLen < (udsIoCtrlTable[ioCtrlIndex].dataLen + 4)) + { + Uds_NegativeResponse(obj, 0x2F, NRC_CONDITIONS_NOT_CORRECT); + return; + } + + udsIoCtrlTable[ioCtrlIndex].enable = true; + memcpy(udsIoCtrlTable[ioCtrlIndex].pData, &msgBuf[4], udsIoCtrlTable[ioCtrlIndex].dataLen); + if(udsIoCtrlTable[ioCtrlIndex].IoCtrl_Init != NULL) + { + udsIoCtrlTable[ioCtrlIndex].IoCtrl_Init(); + Uds_PositiveResponse(obj, rspBuffer, 4); + } + break; + default: + Uds_NegativeResponse(obj, 0x2F, NRC_REQUEST_OUT_OF_RANGE); + break; + } +} diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service2F.h b/cva_asw_m0118/SDK/middleware/uds/user/uds_service2F.h new file mode 100644 index 0000000..77ea61b --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service2F.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE2F_H_ +#define _UDS_SERVICE2F_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 2F + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 2F processing + */ +extern void UdsService2F_InputOutputCtrlById(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE2F_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service31.c b/cva_asw_m0118/SDK/middleware/uds/user/uds_service31.c new file mode 100644 index 0000000..38a8d9b --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service31.c @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_service31.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The Uds routine control type + */ +typedef enum _UdsRoutineCtrlType_ +{ + UDS_ROUTINE_CTRL_NONE = 0, + UDS_ROUTINE_CTRL_START = 0x01, + UDS_ROUTINE_CTRL_STOP = 0x02, + UDS_ROUTINE_CTRL_REQUEST_RESULT = 0x03 +} UdsRoutineCtrlType; + +/*! \brief The Uds routine control status + */ +typedef enum _UdsRtnCtrlStatus_ +{ + UDS_RTN_ST_IDLE = 0x00, + UDS_RTN_ST_RUNNING = 0x01, +} UdsRtnCtrlStatus; + +/*! \brief The Uds routine control struct + */ +typedef struct _Uds_RtnCtrl_ +{ + uint16_t rtnCtrlId; + uint8_t sessionLevel; + uint8_t securityLevel; + UdsRtnCtrlStatus rtnStatus; + void (*Routine_Start)(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); + void (*Routine_Stop)(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); + void (*Routine_Result)(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); +} Uds_RtnCtrl; + +/******************************************************************************* + * the constants + ******************************************************************************/ + +static void Routine_StartEreaseMemory(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); +static void Routine_StopEreaseMemory(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); +static void Routine_EreaseMemoryResult(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); +static void Routine_StartCheckProgramDependencies(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); +static void Routine_StopCheckProgramDependencies(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); +static void Routine_CheckProgramDependenciesResult(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); +static void Routine_StartEreaseMirrorMemDtcs(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); +static void Routine_StopEreaseMirrorMemDtcs(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); +static void Routine_EreaseMirrorMemDtcsResult(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); + +/******************************************************************************* + * the globals + ******************************************************************************/ + +Uds_RtnCtrl udsRtnCtrlTable[] = { + {0xFF00, UDS_SESSION_EXTENDED, UDS_SA_LEVEL_1, UDS_RTN_ST_IDLE, &Routine_StartEreaseMemory, &Routine_StopEreaseMemory, &Routine_EreaseMemoryResult }, + {0xFF01, UDS_SESSION_EXTENDED, UDS_SA_LEVEL_1, UDS_RTN_ST_IDLE, &Routine_StartCheckProgramDependencies, &Routine_StopCheckProgramDependencies, &Routine_CheckProgramDependenciesResult}, + {0xFF02, UDS_SESSION_EXTENDED, UDS_SA_LEVEL_1, UDS_RTN_ST_IDLE, &Routine_StartEreaseMirrorMemDtcs, &Routine_StopEreaseMirrorMemDtcs, &Routine_EreaseMirrorMemDtcsResult }, +}; + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void Routine_StatusInit(uint16_t routineId) +{ + uint8_t rtnIndex = 0; + uint8_t rntNum = sizeof(udsRtnCtrlTable) / sizeof(Uds_RtnCtrl); + + for(rtnIndex = 0; rtnIndex < rntNum; rtnIndex++) + { + if(udsRtnCtrlTable[rtnIndex].rtnCtrlId == routineId) + { + udsRtnCtrlTable[rtnIndex].rtnStatus = UDS_RTN_ST_IDLE; + } + } +} + +static void Routine_StartEreaseMemory(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + if(pdata == NULL) + { + return; + } + /* user add start erease memory code */ +} + +static void Routine_StopEreaseMemory(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + if(pdata == NULL) + { + return; + } + /* user add stop erease memory code */ +} + +static void Routine_EreaseMemoryResult(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + if(pdata == NULL) + { + return; + } + /* user add erease memory result code */ +} + +static void Routine_StartCheckProgramDependencies(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + if(pdata == NULL) + { + return; + } + /* user add start check program dependencies code */ +} + +static void Routine_StopCheckProgramDependencies(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + if(pdata == NULL) + { + return; + } + /* user add stop check program dependencies code */ +} + +static void Routine_CheckProgramDependenciesResult(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + if(pdata == NULL) + { + return; + } + /* user add check program dependencies result code */ +} + +static void Routine_StartEreaseMirrorMemDtcs(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + if(pdata == NULL) + { + return; + } + /* user add start erease mirror memory Dtcs code */ +} + +static void Routine_StopEreaseMirrorMemDtcs(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + if(pdata == NULL) + { + return; + } + /* user add stop erease mirror memory Dtcs code */ +} + +static void Routine_EreaseMirrorMemDtcsResult(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + if(pdata == NULL) + { + return; + } + /* user add erease mirror memory Dtcs resultl code */ +} + +void UdsService31_RoutineControl(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + const uint8_t *pOptionParam = NULL; + uint8_t subFunction = 0; + uint16_t optionParamLen = 0; + uint16_t routineId = 0; + uint8_t rtnIndex = 0; + uint8_t rntNum = sizeof(udsRtnCtrlTable) / sizeof(Uds_RtnCtrl); + uint8_t rspBuffer[UDS_RSP_LEN_MAX] = {0}; + uint16_t rspLen = 0; + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x31, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + subFunction = UDS_GET_SUB_FUNCTION(msgBuf[1]); + routineId = ((uint16_t)msgBuf[2] << 8) + msgBuf[3]; + optionParamLen = msgLen - 4; + if(optionParamLen > 0) + { + pOptionParam = &msgBuf[4]; + } + + for(rtnIndex = 0; rtnIndex < rntNum; rtnIndex++) + { + if(udsRtnCtrlTable[rtnIndex].rtnCtrlId == routineId) + { + if(obj->session == udsRtnCtrlTable[rtnIndex].sessionLevel) + { + if((udsRtnCtrlTable[rtnIndex].securityLevel != UDS_SA_NONE) && (udsRtnCtrlTable[rtnIndex].securityLevel != obj->securityLevel)) + { + Uds_NegativeResponse(obj, 0x31, NRC_SECURITY_ACCESS_DENIED); + return; + } + + break; + } + else + { + Uds_NegativeResponse(obj, 0x31, NRC_CONDITIONS_NOT_CORRECT); + return; + } + } + } + + if(rtnIndex >= rntNum) + { + Uds_NegativeResponse(obj, 0x31, NRC_REQUEST_OUT_OF_RANGE); + return; + } + + memset(rspBuffer, 0, UDS_RSP_LEN_MAX); + + switch(subFunction) + { + case UDS_ROUTINE_CTRL_START: + udsRtnCtrlTable[rtnIndex].Routine_Start(pOptionParam, optionParamLen, rspBuffer, UDS_RSP_LEN_MAX, &rspLen); + udsRtnCtrlTable[rtnIndex].rtnStatus = UDS_RTN_ST_RUNNING; + break; + case UDS_ROUTINE_CTRL_STOP: + if(udsRtnCtrlTable[rtnIndex].rtnStatus != UDS_RTN_ST_IDLE) + { + udsRtnCtrlTable[rtnIndex].Routine_Stop(pOptionParam, optionParamLen, rspBuffer, UDS_RSP_LEN_MAX, &rspLen); + udsRtnCtrlTable[rtnIndex].rtnStatus = UDS_RTN_ST_IDLE; + } + break; + case UDS_ROUTINE_CTRL_REQUEST_RESULT: + if(udsRtnCtrlTable[rtnIndex].rtnStatus != UDS_RTN_ST_IDLE) + { + udsRtnCtrlTable[rtnIndex].Routine_Result(pOptionParam, optionParamLen, rspBuffer, UDS_RSP_LEN_MAX, &rspLen); + } + break; + default: + Uds_NegativeResponse(obj, 0x31, NRC_SUBFUNCTION_NOT_SUPPORTED); + return; + } + + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still reserve though it's maybe unreachable" */ + if((rspLen >= 4) && (rspBuffer[0] == UDS_GET_POSITIVE_RSP(0x31))) + { + Uds_PositiveResponse(obj, rspBuffer, rspLen); + } + else if((rspLen == 3) && (rspBuffer[0] == NEGATIVE_RSP)) + { + Uds_NegativeResponse(obj, 0x31, rspBuffer[2]); + } + else + { + Uds_NegativeResponse(obj, 0x31, NRC_REQUEST_SEQUENCE_ERROR); + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still reserve though it's maybe unreachable" */ +} diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service31.h b/cva_asw_m0118/SDK/middleware/uds/user/uds_service31.h new file mode 100644 index 0000000..a51729d --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service31.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE31_H_ +#define _UDS_SERVICE31_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 31 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 31 processing + */ +extern void UdsService31_RoutineControl(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +/*! \brief Routine status init + */ +extern void Routine_StatusInit(uint16_t routineId); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE31_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service34.c b/cva_asw_m0118/SDK/middleware/uds/user/uds_service34.c new file mode 100644 index 0000000..554a7e1 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service34.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_service34.h" +#include "uds_service36.h" + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +uint32_t Uds_GetMaxfBlockSize(void) +{ + /* user add code to get max num of block length */ + + return 128; +} + +uint8_t Uds_GetValidBytesNumOfData(uint32_t data) +{ + uint8_t index = 0; + uint8_t bytesNum = 0; + + for(index = 1; index <= 4; index++) + { + if(data >> ((4 - index) * 8)) + { + bytesNum = 4 - index + 1; + break; + } + } + + return bytesNum; +} + +void UdsService34_RequestDownload(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint32_t memAddress = 0; + uint8_t memAddrLen = 0; + uint32_t memSize = 0; + uint8_t memSizeLen = 0; + uint8_t maxBlockSizeLen = 0; + uint32_t maxBlockSize = 0; + uint8_t index = 0; + uint16_t rspLen = 0; + uint8_t rspBuffer[8]; + + if(obj->session == UDS_SESSION_DEFAULT) + { + Uds_NegativeResponse(obj, 0x34, NRC_CONDITIONS_NOT_CORRECT); + return; + } + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x34, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + memAddrLen = msgBuf[2] & 0x0F; + memSizeLen = msgBuf[2] >> 4; + + if((memAddrLen == 0) || (memAddrLen > sizeof(memAddress)) || (memSizeLen == 0) || (memSizeLen > sizeof(memSize))) + { + Uds_NegativeResponse(obj, 0x34, NRC_REQUEST_OUT_OF_RANGE); + return; + } + + for(index = 0; index < memAddrLen; index++) + { + memAddress <<= 8; + memAddress += msgBuf[3 + index]; + } + + for(index = 0; index < memSizeLen; index++) + { + memSize <<= 8; + memSize += msgBuf[3 + memAddrLen + index]; + } + + if(memSize == 0) + { + Uds_NegativeResponse(obj, 0x34, NRC_CONDITIONS_NOT_CORRECT); + return; + } + + /* user add judge code for the security level */ + if(0) + { + Uds_NegativeResponse(obj, 0x34, NRC_SECURITY_ACCESS_DENIED); + return; + } + + Uds_SetMemAddr(memAddress); + Uds_SetMemSize(memSize); + + Uds_SetDataTransferDirect(UDS_TRANSFER_DIR_DOWNLOAD); + + maxBlockSize = Uds_GetMaxfBlockSize(); + maxBlockSizeLen = Uds_GetValidBytesNumOfData(maxBlockSize); + + rspBuffer[rspLen++] = UDS_GET_POSITIVE_RSP(0x34); + rspBuffer[rspLen++] = maxBlockSizeLen << 4; + for(index = 1; index <= maxBlockSizeLen; index++) + { + rspBuffer[rspLen++] = maxBlockSize >> (8 * (maxBlockSizeLen - index)); + } + + Uds_PositiveResponse(obj, rspBuffer, rspLen); +} + + + diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service34.h b/cva_asw_m0118/SDK/middleware/uds/user/uds_service34.h new file mode 100644 index 0000000..072140b --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service34.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE34_H_ +#define _UDS_SERVICE34_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 34 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 34 processing + */ +extern void UdsService34_RequestDownload(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE34_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service36.c b/cva_asw_m0118/SDK/middleware/uds/user/uds_service36.c new file mode 100644 index 0000000..cea934a --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service36.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_service36.h" + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +static uint32_t s_memAddr = 0; +static uint32_t s_memSize = 0; +static UdsTransDirType s_dataTransDir = UDS_TRANSFER_DIR_NONE; + +static uint8_t s_curRcvSequence = 0; +static uint8_t s_lastRcvSqunce = 0; +static uint32_t s_rcvDataTotalLen = 0; + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void Uds_SetMemAddr(uint32_t addr) +{ + s_memAddr = addr; +} + +uint32_t Uds_GetMemAddr(void) +{ + return s_memAddr; +} + +void Uds_SetMemSize(uint32_t size) +{ + s_memSize = size; +} + +uint32_t Uds_GetMemSize(void) +{ + return s_memSize; +} + +void Uds_SetDataTransferDirect(UdsTransDirType dirType) +{ + s_dataTransDir = dirType; + + /* clear sequence number */ + s_lastRcvSqunce = 0x00; + s_curRcvSequence = 0x00; + + /* clear receive data total number */ + s_rcvDataTotalLen = 0x00; +} + +UdsTransDirType Uds_GetDataTransferDirect(void) +{ + return s_dataTransDir; +} + +uint32_t Uds_GetRcvDataTotalLen(void) +{ + return s_rcvDataTotalLen; +} + +void UdsService36_TransferData(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint16_t rspLen = 0; + uint8_t rspBuffer[UDS_RSP_LEN_MAX] = {0}; /* polyspace DEFECT:PARTIALLY_ACCESSED_ARRAY [No action planned:Low] "Still reserve though member2~511 is not written" */ + + if(obj->session == UDS_SESSION_DEFAULT) + { + Uds_NegativeResponse(obj, 0x36, NRC_CONDITIONS_NOT_CORRECT); + return; + } + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x36, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + switch(s_dataTransDir) + { + case UDS_TRANSFER_DIR_DOWNLOAD: + s_curRcvSequence = msgBuf[1]; + + if((s_curRcvSequence != s_lastRcvSqunce) && (s_curRcvSequence != ((uint8_t)(s_lastRcvSqunce + 1)))) + { + Uds_NegativeResponse(obj, 0x36, NRC_WRONG_BLOCK_SEQUENCE_COUNTER); + return; + } + + rspBuffer[rspLen++] = UDS_GET_POSITIVE_RSP(0x36); + rspBuffer[rspLen++] = msgBuf[1]; + if(s_curRcvSequence == s_lastRcvSqunce) + { + Uds_PositiveResponse(obj, rspBuffer, rspLen); + return; + } + + if((s_rcvDataTotalLen + msgLen - 2) > s_memSize) + { + Uds_NegativeResponse(obj, 0x36, NRC_TRANSFER_DATA_SUSPENDED); + return; + } + + /* user add code to deal with download data */ + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still reserve though it's maybe unreachable" */ + if(1) /* deal success */ + { + s_rcvDataTotalLen += msgLen - 2; + s_lastRcvSqunce = s_curRcvSequence; + Uds_PositiveResponse(obj, rspBuffer, rspLen); + } + else + { + Uds_NegativeResponse(obj, 0x36, NRC_GENERAL_PROGRAMMING_FAILURE); + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still reserve though it's maybe unreachable" */ + break; + case UDS_TRANSFER_DIR_UPLOAD: + Uds_NegativeResponse(obj, 0x36, NRC_REQUEST_OUT_OF_RANGE); + break; + default: + Uds_NegativeResponse(obj, 0x36, NRC_REQUEST_SEQUENCE_ERROR); + break; + } +} + + + diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service36.h b/cva_asw_m0118/SDK/middleware/uds/user/uds_service36.h new file mode 100644 index 0000000..a0dd723 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service36.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE36_H_ +#define _UDS_SERVICE36_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 36 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The Uds IO control type + */ +typedef enum _UdsTransDirType_ +{ + UDS_TRANSFER_DIR_NONE = 0x00, + UDS_TRANSFER_DIR_DOWNLOAD = 0x01, + UDS_TRANSFER_DIR_UPLOAD = 0x02, +} UdsTransDirType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief set memery start address + */ +extern void Uds_SetMemAddr(uint32_t addr); + +/*! \brief get memery start address + */ +extern uint32_t Uds_GetMemAddr(void); + +/*! \brief set memery size + */ +extern void Uds_SetMemSize(uint32_t size); + +/*! \brief get memery size + */ +extern uint32_t Uds_GetMemSize(void); + +/*! \brief set data transfer direct + */ +extern void Uds_SetDataTransferDirect(UdsTransDirType dirType); + +/*! \brief get data transfer direct + */ +extern UdsTransDirType Uds_GetDataTransferDirect(void); + +/*! \brief get receive data total len + */ +extern uint32_t Uds_GetRcvDataTotalLen(void); + +/*! \brief Uds Service 10 processing + */ +extern void UdsService36_TransferData(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE36_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service37.c b/cva_asw_m0118/SDK/middleware/uds/user/uds_service37.c new file mode 100644 index 0000000..f94681d --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service37.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ +#include "uds_service36.h" +#include "uds_service37.h" + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void UdsService37_RequestTransferExit(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint16_t rspLen = 0; + uint8_t rspBuffer[8] ={0}; /* polyspace DEFECT:PARTIALLY_ACCESSED_ARRAY [No action planned:Low] "Still reserve though member1~7 is not written" */ + + if(obj->session == UDS_SESSION_DEFAULT) + { + Uds_NegativeResponse(obj, 0x37, NRC_CONDITIONS_NOT_CORRECT); + return; + } + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x37, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + rspBuffer[rspLen++] = UDS_GET_POSITIVE_RSP(0x37); + switch(Uds_GetDataTransferDirect()) + { + case UDS_TRANSFER_DIR_DOWNLOAD: + if(Uds_GetRcvDataTotalLen() != Uds_GetMemSize()) + { + Uds_NegativeResponse(obj, 0x37, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + break; + } + + /* user add process code, example data CRC */ + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still reserve though it's maybe unreachable" */ + if(1) /* result check correct */ + { + Uds_PositiveResponse(obj, rspBuffer, rspLen); + } + else + { + Uds_NegativeResponse(obj, 0x37, NRC_GENERAL_PROGRAMMING_FAILURE); + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still reserve though it's maybe unreachable" */ + break; + case UDS_TRANSFER_DIR_UPLOAD: + Uds_NegativeResponse(obj, 0x37, NRC_REQUEST_OUT_OF_RANGE); + break; + default: + Uds_NegativeResponse(obj, 0x37, NRC_REQUEST_SEQUENCE_ERROR); + break; + } + + Uds_SetDataTransferDirect(UDS_TRANSFER_DIR_NONE); +} + + + diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service37.h b/cva_asw_m0118/SDK/middleware/uds/user/uds_service37.h new file mode 100644 index 0000000..cd6da79 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service37.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE37_H_ +#define _UDS_SERVICE37_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 37 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 37 processing + */ +void UdsService37_RequestTransferExit(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE37_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service3E.c b/cva_asw_m0118/SDK/middleware/uds/user/uds_service3E.c new file mode 100644 index 0000000..e371eb8 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service3E.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_service3E.h" + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void UdsService3E_TesterPresent(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint8_t subFunction; + uint8_t rspBuffer[8] = {0}; /* polyspace DEFECT:PARTIALLY_ACCESSED_ARRAY [No action planned:Low] "Still keep default though member2~7 is not written" */ + + if(msgLen != obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x3E, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + subFunction = UDS_GET_SUB_FUNCTION (msgBuf[1]); + + if(subFunction == 0) + { + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x3E); + rspBuffer[1] = subFunction; + Uds_PositiveResponse(obj, rspBuffer, 2); + } + else + { + Uds_NegativeResponse(obj, 0x3E, NRC_SUBFUNCTION_NOT_SUPPORTED); + } + +} + + diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service3E.h b/cva_asw_m0118/SDK/middleware/uds/user/uds_service3E.h new file mode 100644 index 0000000..d714e26 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service3E.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE3E_H_ +#define _UDS_SERVICE3E_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 3E + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 3E processing + */ +extern void UdsService3E_TesterPresent(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE3E_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service85.c b/cva_asw_m0118/SDK/middleware/uds/user/uds_service85.c new file mode 100644 index 0000000..570654b --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service85.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_service85.h" +#include "uds_dtc.h" + + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void UdsService85_ControlDtcSetting(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint8_t subFunction; + uint8_t rspBuffer[8] = {0}; /* polyspace DEFECT:PARTIALLY_ACCESSED_ARRAY [No action planned:Low] "Still keep default though member2~7 is not written" */ + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x85, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + if(obj->session == UDS_SESSION_DEFAULT) + { + Uds_NegativeResponse(obj, 0x85, NRC_CONDITIONS_NOT_CORRECT); + return; + } + + subFunction = UDS_GET_SUB_FUNCTION (msgBuf[1]); + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x85); + rspBuffer[1] = subFunction; + switch(subFunction) + { + case 1: + Uds_SetDtcOffCtrl(true); + Uds_PositiveResponse(obj, rspBuffer, 2); + break; + case 2: + Uds_SetDtcOffCtrl(false); + Uds_PositiveResponse(obj, rspBuffer, 2); + break; + default: + Uds_NegativeResponse(obj, 0x85, NRC_SUBFUNCTION_NOT_SUPPORTED); + break; + } + +} diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_service85.h b/cva_asw_m0118/SDK/middleware/uds/user/uds_service85.h new file mode 100644 index 0000000..0d55da3 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_service85.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE85_H_ +#define _UDS_SERVICE85_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 85 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 85 processing + */ +extern void UdsService85_ControlDtcSetting(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE85_H_ */ diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_user.c b/cva_asw_m0118/SDK/middleware/uds/user/uds_user.c new file mode 100644 index 0000000..54c2078 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_user.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_user.h" +#include "extern.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ +void DID_F180_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen); +void DID_F186_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen); +void DID_F187_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen); +void DID_F193_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen); +void DID_F195_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen); +void DID_F191_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen); + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The Data-by-ID definition of UDS + */ +typedef struct _Uds_DidBuffer_ +{ + uint8_t buffer_F186[1]; + uint8_t buffer_F187[8];//ecu name + uint8_t buffer_F180[8];//boot version + uint8_t buffer_F193[4];//hw version + uint8_t buffer_F195[16];//sw version + uint8_t buffer_F191[24];//buildtime +} Uds_DidBuffer; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +Uds_DidBuffer udsDidBuf; + +/******************************************************************************* + * the constants + ******************************************************************************/ + +static const Uds_ServiceType udsServiceTable[UDS_SERVICE_NUM] = { + {0x10, 2, true, UdsService10_SessionControl }, + {0x11, 2, true, UdsService11_ResetEcu }, + {0x27, 2, true, UdsService27_SecurityAccess }, + {0x28, 3, true, UdsService28_CommunicationControl }, + {0x3E, 2, true, UdsService3E_TesterPresent }, + {0x85, 2, true, UdsService85_ControlDtcSetting }, + {0x22, 3, false, UdsService22_ReadDataByIdentifier }, + {0x2E, 4, false, UdsService2E_WriteDataByIdentifier}, + {0x14, 4, false, UdsService14_ClearDiagInfo }, + {0x19, 3, true, UdsService19_ReadDtcInformation }, + {0x2F, 3, false, UdsService2F_InputOutputCtrlById }, + {0x31, 4, true, UdsService31_RoutineControl }, + {0x34, 5, false, UdsService34_RequestDownload }, + {0x36, 2, false, UdsService36_TransferData }, + {0x37, 1, false, UdsService37_RequestTransferExit }, +}; + +static const bool udsSecurityTable[UDS_SERVICE_NUM][UDS_SA_LEVEL_NUM] = { + {false, false, false}, /* 0x10 */ + {false, false, false}, /* 0x11 */ + {false, false, false}, /* 0x27 */ + {false, false, false}, /* 0x28 */ + {false, false, false}, /* 0x3E */ + {false, false, false}, /* 0x85 */ + {false, false, false}, /* 0x22 */ + {false, false, false}, /* 0x2E */ + {false, false, false}, /* 0x14 */ + {false, false, false}, /* 0x19 */ + {false, false, false}, /* 0x2F */ + {false, false, false}, /* 0x31 */ + {false, false, false}, /* 0x34 */ + {false, false, false}, /* 0x36 */ + {false, false, false}, /* 0x37 */ +}; + +Uds_DidType udsDidTable[] = { + {0xF186, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F186, BYTES_OF(udsDidBuf.buffer_F186),DID_F186_func}, + {0xF187, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F187, BYTES_OF(udsDidBuf.buffer_F187),DID_F187_func}, + {0xF180, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F180, BYTES_OF(udsDidBuf.buffer_F180),DID_F180_func}, + {0xF193, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F193, BYTES_OF(udsDidBuf.buffer_F193),DID_F193_func}, + {0xF195, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F195, BYTES_OF(udsDidBuf.buffer_F195),DID_F195_func}, + {0xF191, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F191, BYTES_OF(udsDidBuf.buffer_F191),DID_F191_func}, +}; + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void Uds_UserInit(UdsType *obj, const Uds_ParamsType *pParams) +{ + Uds_Init(obj, pParams); + + obj->seviceTable = udsServiceTable; + obj->securityTable = &udsSecurityTable[0][0]; + obj->serviceNum = UDS_SERVICE_NUM; + obj->didTable = udsDidTable; + obj->didNum = sizeof(udsDidTable) / sizeof(Uds_DidType); +} + +/******************************DID FUNC****************************************/ +void DID_F180_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen) +{ + getBL_VERSION(dataBuf); +} +void DID_F186_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen) +{ + dataBuf[0] = obj->session; +} +void DID_F187_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen) +{ + getEcuName(dataBuf); +} +void DID_F193_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen) +{ + getHW_VERSION(dataBuf); +} +void DID_F195_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen) +{ + getSW_VERSION(dataBuf); +} + +void DID_F191_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen) +{ + getBuildTime(dataBuf); +} \ No newline at end of file diff --git a/cva_asw_m0118/SDK/middleware/uds/user/uds_user.h b/cva_asw_m0118/SDK/middleware/uds/user/uds_user.h new file mode 100644 index 0000000..1925d50 --- /dev/null +++ b/cva_asw_m0118/SDK/middleware/uds/user/uds_user.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_USER_H_ +#define _UDS_USER_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS application + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" +#include "uds_service10.h" +#include "uds_service11.h" +#include "uds_service14.h" +#include "uds_service19.h" +#include "uds_service22.h" +#include "uds_service27.h" +#include "uds_service28.h" +#include "uds_service2E.h" +#include "uds_service2F.h" +#include "uds_service31.h" +#include "uds_service34.h" +#include "uds_service36.h" +#include "uds_service37.h" +#include "uds_service3E.h" +#include "uds_service85.h" +#include "uds_dtc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the UDS object + */ +extern void Uds_UserInit(UdsType *obj, const Uds_ParamsType *pParams); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_USER_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/CVM011x_features.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/CVM011x_features.h new file mode 100644 index 0000000..3585225 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/CVM011x_features.h @@ -0,0 +1,352 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CVM011X_FEATURES_H_ +#define _CVM011X_FEATURES_H_ + +/*! \brief Contains public interface to various functions related + * to the features definition of CVM011x series chips + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#if defined(MCU_CVM0118FMLF) || defined(MCU_CVM0118LMLF) + +#ifdef FEATURE_PFLASH_SIZE +#undef FEATURE_PFLASH_SIZE +#endif +#define FEATURE_PFLASH_SIZE (0x38000) + +#ifdef FEATURE_RAM_SIZE +#undef FEATURE_RAM_SIZE +#endif +#define FEATURE_RAM_SIZE (0x6400) + +#ifdef FEATURE_DFLASH_SIZE +#undef FEATURE_DFLASH_SIZE +#endif +#define FEATURE_DFLASH_SIZE (0x8000) + +#ifdef FEATURE_EEPROM_SIZE +#undef FEATURE_EEPROM_SIZE +#endif +#define FEATURE_EEPROM_SIZE (0x800) + +#ifdef FEATURE_CAN_FD_INSTANCE_NUM +#undef FEATURE_CAN_FD_INSTANCE_NUM +#endif +#define FEATURE_CAN_FD_INSTANCE_NUM (1) + +#ifdef FEATURE_CAN_2_0_INSTANCE_NUM +#undef FEATURE_CAN_2_0_INSTANCE_NUM +#endif +#define FEATURE_CAN_2_0_INSTANCE_NUM (0) + +#ifdef FEATURE_UART_INSTANCE_NUM +#undef FEATURE_UART_INSTANCE_NUM +#endif +#define FEATURE_UART_INSTANCE_NUM (3) + +#elif defined(MCU_CVM0118BMLF) || defined(MCU_CVM0118AMLF) + +#ifdef FEATURE_PFLASH_SIZE +#undef FEATURE_PFLASH_SIZE +#endif +#define FEATURE_PFLASH_SIZE (0x38000) + +#ifdef FEATURE_RAM_SIZE +#undef FEATURE_RAM_SIZE +#endif +#define FEATURE_RAM_SIZE (0x6400) + +#ifdef FEATURE_DFLASH_SIZE +#undef FEATURE_DFLASH_SIZE +#endif +#define FEATURE_DFLASH_SIZE (0x8000) + +#ifdef FEATURE_EEPROM_SIZE +#undef FEATURE_EEPROM_SIZE +#endif +#define FEATURE_EEPROM_SIZE (0x800) + +#ifdef FEATURE_CAN_FD_INSTANCE_NUM +#undef FEATURE_CAN_FD_INSTANCE_NUM +#endif +#define FEATURE_CAN_FD_INSTANCE_NUM (0) + +#ifdef FEATURE_CAN_2_0_INSTANCE_NUM +#undef FEATURE_CAN_2_0_INSTANCE_NUM +#endif +#define FEATURE_CAN_2_0_INSTANCE_NUM (1) + +#ifdef FEATURE_UART_INSTANCE_NUM +#undef FEATURE_UART_INSTANCE_NUM +#endif +#define FEATURE_UART_INSTANCE_NUM (3) + +#elif defined(MCU_CVM0118FMFM) || defined(MCU_CVM0118LMFM) + +#ifdef FEATURE_PFLASH_SIZE +#undef FEATURE_PFLASH_SIZE +#endif +#define FEATURE_PFLASH_SIZE (0x38000) + +#ifdef FEATURE_RAM_SIZE +#undef FEATURE_RAM_SIZE +#endif +#define FEATURE_RAM_SIZE (0x6400) + +#ifdef FEATURE_DFLASH_SIZE +#undef FEATURE_DFLASH_SIZE +#endif +#define FEATURE_DFLASH_SIZE (0x8000) + +#ifdef FEATURE_EEPROM_SIZE +#undef FEATURE_EEPROM_SIZE +#endif +#define FEATURE_EEPROM_SIZE (0x800) + +#ifdef FEATURE_CAN_FD_INSTANCE_NUM +#undef FEATURE_CAN_FD_INSTANCE_NUM +#endif +#define FEATURE_CAN_FD_INSTANCE_NUM (1) + +#ifdef FEATURE_CAN_2_0_INSTANCE_NUM +#undef FEATURE_CAN_2_0_INSTANCE_NUM +#endif +#define FEATURE_CAN_2_0_INSTANCE_NUM (0) + +#ifdef FEATURE_UART_INSTANCE_NUM +#undef FEATURE_UART_INSTANCE_NUM +#endif +#define FEATURE_UART_INSTANCE_NUM (2) + +#elif defined(MCU_CVM0118BMFM) || defined(MCU_CVM0118AMFM) + +#ifdef FEATURE_PFLASH_SIZE +#undef FEATURE_PFLASH_SIZE +#endif +#define FEATURE_PFLASH_SIZE (0x38000) + +#ifdef FEATURE_RAM_SIZE +#undef FEATURE_RAM_SIZE +#endif +#define FEATURE_RAM_SIZE (0x6400) + +#ifdef FEATURE_DFLASH_SIZE +#undef FEATURE_DFLASH_SIZE +#endif +#define FEATURE_DFLASH_SIZE (0x8000) + +#ifdef FEATURE_EEPROM_SIZE +#undef FEATURE_EEPROM_SIZE +#endif +#define FEATURE_EEPROM_SIZE (0x800) + +#ifdef FEATURE_CAN_FD_INSTANCE_NUM +#undef FEATURE_CAN_FD_INSTANCE_NUM +#endif +#define FEATURE_CAN_FD_INSTANCE_NUM (0) + +#ifdef FEATURE_CAN_2_0_INSTANCE_NUM +#undef FEATURE_CAN_2_0_INSTANCE_NUM +#endif +#define FEATURE_CAN_2_0_INSTANCE_NUM (1) + +#ifdef FEATURE_UART_INSTANCE_NUM +#undef FEATURE_UART_INSTANCE_NUM +#endif +#define FEATURE_UART_INSTANCE_NUM (2) + +#elif defined(MCU_CVM0116FMFM) || defined(MCU_CVM0116LMFM) + +#ifdef FEATURE_PFLASH_SIZE +#undef FEATURE_PFLASH_SIZE +#endif +#define FEATURE_PFLASH_SIZE (0x20000) + +#ifdef FEATURE_RAM_SIZE +#undef FEATURE_RAM_SIZE +#endif +#define FEATURE_RAM_SIZE (0x4400) + +#ifdef FEATURE_DFLASH_SIZE +#undef FEATURE_DFLASH_SIZE +#endif +#define FEATURE_DFLASH_SIZE (0x8000) + +#ifdef FEATURE_EEPROM_SIZE +#undef FEATURE_EEPROM_SIZE +#endif +#define FEATURE_EEPROM_SIZE (0x800) + +#ifdef FEATURE_CAN_FD_INSTANCE_NUM +#undef FEATURE_CAN_FD_INSTANCE_NUM +#endif +#define FEATURE_CAN_FD_INSTANCE_NUM (1) + +#ifdef FEATURE_CAN_2_0_INSTANCE_NUM +#undef FEATURE_CAN_2_0_INSTANCE_NUM +#endif +#define FEATURE_CAN_2_0_INSTANCE_NUM (0) + +#ifdef FEATURE_UART_INSTANCE_NUM +#undef FEATURE_UART_INSTANCE_NUM +#endif +#define FEATURE_UART_INSTANCE_NUM (2) + +#elif defined(MCU_CVM0116BMFM) || defined(MCU_CVM0116AMFM) + +#ifdef FEATURE_PFLASH_SIZE +#undef FEATURE_PFLASH_SIZE +#endif +#define FEATURE_PFLASH_SIZE (0x20000) + +#ifdef FEATURE_RAM_SIZE +#undef FEATURE_RAM_SIZE +#endif +#define FEATURE_RAM_SIZE (0x4400) + +#ifdef FEATURE_DFLASH_SIZE +#undef FEATURE_DFLASH_SIZE +#endif +#define FEATURE_DFLASH_SIZE (0x8000) + +#ifdef FEATURE_EEPROM_SIZE +#undef FEATURE_EEPROM_SIZE +#endif +#define FEATURE_EEPROM_SIZE (0x800) + +#ifdef FEATURE_CAN_FD_INSTANCE_NUM +#undef FEATURE_CAN_FD_INSTANCE_NUM +#endif +#define FEATURE_CAN_FD_INSTANCE_NUM (0) + +#ifdef FEATURE_CAN_2_0_INSTANCE_NUM +#undef FEATURE_CAN_2_0_INSTANCE_NUM +#endif +#define FEATURE_CAN_2_0_INSTANCE_NUM (1) + +#ifdef FEATURE_UART_INSTANCE_NUM +#undef FEATURE_UART_INSTANCE_NUM +#endif +#define FEATURE_UART_INSTANCE_NUM (2) + +#elif defined(MCU_CVM0114BMFM) + +#ifdef FEATURE_PFLASH_SIZE +#undef FEATURE_PFLASH_SIZE +#endif +#define FEATURE_PFLASH_SIZE (0x10000) + +#ifdef FEATURE_RAM_SIZE +#undef FEATURE_RAM_SIZE +#endif +#define FEATURE_RAM_SIZE (0x4400) + +#ifdef FEATURE_DFLASH_SIZE +#undef FEATURE_DFLASH_SIZE +#endif +#define FEATURE_DFLASH_SIZE (0x8000) + +#ifdef FEATURE_EEPROM_SIZE +#undef FEATURE_EEPROM_SIZE +#endif +#define FEATURE_EEPROM_SIZE (0x800) + +#ifdef FEATURE_CAN_FD_INSTANCE_NUM +#undef FEATURE_CAN_FD_INSTANCE_NUM +#endif +#define FEATURE_CAN_FD_INSTANCE_NUM (0) + +#ifdef FEATURE_CAN_2_0_INSTANCE_NUM +#undef FEATURE_CAN_2_0_INSTANCE_NUM +#endif +#define FEATURE_CAN_2_0_INSTANCE_NUM (1) + +#ifdef FEATURE_UART_INSTANCE_NUM +#undef FEATURE_UART_INSTANCE_NUM +#endif +#define FEATURE_UART_INSTANCE_NUM (2) + +#elif defined(MCU_CVM0118TVLF) + +#ifdef FEATURE_PFLASH_SIZE +#undef FEATURE_PFLASH_SIZE +#endif +#define FEATURE_PFLASH_SIZE (0x38000) + +#ifdef FEATURE_RAM_SIZE +#undef FEATURE_RAM_SIZE +#endif +#define FEATURE_RAM_SIZE (0x6400) + +#ifdef FEATURE_DFLASH_SIZE +#undef FEATURE_DFLASH_SIZE +#endif +#define FEATURE_DFLASH_SIZE (0x8000) + +#ifdef FEATURE_EEPROM_SIZE +#undef FEATURE_EEPROM_SIZE +#endif +#define FEATURE_EEPROM_SIZE (0x800) + +#ifdef FEATURE_CAN_FD_INSTANCE_NUM +#undef FEATURE_CAN_FD_INSTANCE_NUM +#endif +#define FEATURE_CAN_FD_INSTANCE_NUM (0) + +#ifdef FEATURE_CAN_2_0_INSTANCE_NUM +#undef FEATURE_CAN_2_0_INSTANCE_NUM +#endif +#define FEATURE_CAN_2_0_INSTANCE_NUM (1) + +#ifdef FEATURE_UART_INSTANCE_NUM +#undef FEATURE_UART_INSTANCE_NUM +#endif +#define FEATURE_UART_INSTANCE_NUM (2) + +#else +#error "No correct chip defined" +#endif + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _CVM011X_FEATURES_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/adc/adc_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/adc/adc_drv.c new file mode 100644 index 0000000..af1b740 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/adc/adc_drv.c @@ -0,0 +1,348 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "adc_drv.h" +#include "adc_reg.h" +#include "sim_reg.h" +#include "../cpu/cpu_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ +#define ADC_INTERLEAVE_ENABLE (1U) +#define ADC_LEN_PWR_ON_DEFAULT (11U) +#define ADC_LEN_SMPL_1ST_DEFAULT (48U) +#define ADC_LEN_SMPL_DEFAULT (4U) +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief ADC type of enable selection + */ +typedef enum +{ + ADCDRV_POWER_ON = 0x0U, + ADCDRV_POWER_DOWN = 0x1U, +} AdcDrv_PowerEnable; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void AdcDrv_Init(AdcDrvType *obj, struct _AdcRegType_ *adcReg, struct _SimRegType_ *simReg) +{ + obj->adcReg = adcReg; + obj->simReg = simReg; +} + +void AdcDrv_GetCmpCfg(AdcDrvType *obj, AdcDrv_CmpCfgType *currentConfig) +{ + bool acfe = AdcReg_GetSc2Acfe(obj->adcReg); + bool acfgt = AdcReg_GetSc2AcFgt(obj->adcReg); + bool acren = AdcReg_GetSc2AcREn(obj->adcReg); + uint16_t cv1 = AdcReg_GetCv1Cv(obj->adcReg); + uint16_t cv2 = AdcReg_GetCv2Cv(obj->adcReg); + if(acfe == false) + { + currentConfig->cmpMode = ADCDRV_CMPMODE_NO_COMPARE; + currentConfig->lowerLim = 0; + currentConfig->upperLim = 0; + } + else + { + if(acfgt == false && acren == false) + { + currentConfig->cmpMode = ADCDRV_CMPMODE_LESSTHAN; + currentConfig->lowerLim = cv1; + currentConfig->upperLim = 0; + } + else if(acfgt == true && acren == false) + { + currentConfig->cmpMode = ADCDRV_CMPMODE_GREATER_OR_EQUTHAN; + currentConfig->lowerLim = cv1; + currentConfig->upperLim = 0; + } + else if(acfgt == false && acren == true && cv1 <= cv2) + { + currentConfig->cmpMode = ADCDRV_CMPMODE_OUTSIDE_EXCLUDE_BOUNDARIES; + currentConfig->lowerLim = cv1; + currentConfig->upperLim = cv2; + } + else if(acfgt == false && acren == true && cv1 > cv2) + { + currentConfig->cmpMode = ADCDRV_CMPMODE_INSIDE_EXCLUDE_BOUNDARIES; + currentConfig->lowerLim = cv2; + currentConfig->upperLim = cv1; + } + else if(acfgt == true && acren == true && cv1 <= cv2) + { + currentConfig->cmpMode = ADCDRV_CMPMODE_INSIDE_INCLUDE_BOUNDARIES; + currentConfig->lowerLim = cv1; + currentConfig->upperLim = cv2; + } + else if(acfgt == true && acren == true && cv1 > cv2) + { + currentConfig->cmpMode = ADCDRV_CMPMODE_OUTSIDE_INCLUDE_BOUNDARIES; + currentConfig->lowerLim = cv2; + currentConfig->upperLim = cv1; + } + } +} + +void AdcDrv_CfgCompare(AdcDrvType *obj, const AdcDrv_CmpCfgType *userConfig) +{ + switch(userConfig->cmpMode) + { + case(ADCDRV_CMPMODE_NO_COMPARE): + AdcReg_SetSc2Acfe(obj->adcReg, false); + break; + case(ADCDRV_CMPMODE_LESSTHAN): + AdcReg_SetSc2Acfe(obj->adcReg, true); + AdcReg_SetSc2AcFgt(obj->adcReg, false); + AdcReg_SetSc2AcREn(obj->adcReg, false); + AdcReg_SetCv1Cv(obj->adcReg, userConfig->lowerLim); + AdcReg_SetCv2Cv(obj->adcReg, 0u); + break; + case(ADCDRV_CMPMODE_GREATER_OR_EQUTHAN): + AdcReg_SetSc2Acfe(obj->adcReg, true); + AdcReg_SetSc2AcFgt(obj->adcReg, true); + AdcReg_SetSc2AcREn(obj->adcReg, false); + AdcReg_SetCv1Cv(obj->adcReg, userConfig->lowerLim); + AdcReg_SetCv2Cv(obj->adcReg, 0u); + break; + case(ADCDRV_CMPMODE_OUTSIDE_EXCLUDE_BOUNDARIES): + AdcReg_SetSc2Acfe(obj->adcReg, true); + AdcReg_SetSc2AcFgt(obj->adcReg, false); + AdcReg_SetSc2AcREn(obj->adcReg, true); + AdcReg_SetCv1Cv(obj->adcReg, userConfig->lowerLim); + AdcReg_SetCv2Cv(obj->adcReg, userConfig->upperLim); + break; + case(ADCDRV_CMPMODE_INSIDE_EXCLUDE_BOUNDARIES): + AdcReg_SetSc2Acfe(obj->adcReg, true); + AdcReg_SetSc2AcFgt(obj->adcReg, false); + AdcReg_SetSc2AcREn(obj->adcReg, true); + AdcReg_SetCv1Cv(obj->adcReg, userConfig->upperLim); + AdcReg_SetCv2Cv(obj->adcReg, userConfig->lowerLim); + break; + case(ADCDRV_CMPMODE_INSIDE_INCLUDE_BOUNDARIES): + AdcReg_SetSc2Acfe(obj->adcReg, true); + AdcReg_SetSc2AcFgt(obj->adcReg, true); + AdcReg_SetSc2AcREn(obj->adcReg, true); + AdcReg_SetCv1Cv(obj->adcReg, userConfig->lowerLim); + AdcReg_SetCv2Cv(obj->adcReg, userConfig->upperLim); + break; + case(ADCDRV_CMPMODE_OUTSIDE_INCLUDE_BOUNDARIES): + AdcReg_SetSc2Acfe(obj->adcReg, true); + AdcReg_SetSc2AcFgt(obj->adcReg, true); + AdcReg_SetSc2AcREn(obj->adcReg, true); + AdcReg_SetCv1Cv(obj->adcReg, userConfig->upperLim); + AdcReg_SetCv2Cv(obj->adcReg, userConfig->lowerLim); + break; + default: + /* Impossible case */ + break; + } +} + +void AdcDrv_Configure(AdcDrvType *obj, const AdcDrv_ConfigType *userConfig) +{ + /* disable ADC first */ + AdcReg_SetSc3AdcPD(obj->adcReg, ADCDRV_POWER_DOWN); + + /* select the conversion conversionMode */ + AdcReg_SetCfg1Mode(obj->adcReg, (uint8_t)userConfig->conversionMode); + + /* select the ADC sample length */ + AdcReg_SetCfg2LenSmpl(obj->adcReg, userConfig->sampleLen); + + /* select the ADC sample length after the 1st cycle + * change the input channel select(ADCH) */ + AdcReg_SetCfg2LenSmpl1st(obj->adcReg, userConfig->firstSampleLen); + + /* select the ADC sample length after power on */ + AdcReg_SetCfg2LenPwrOn(obj->adcReg, userConfig->pwrOnLen); + + /* enable DMA */ + AdcReg_SetSc2DmaEn(obj->adcReg, userConfig->dmaEnable); + + /* Enable trigger */ + AdcReg_SetSc2AdTrg(obj->adcReg, 1); + + /* select hardware trigger source */ + SimReg_SetAdcTrgSrc(obj->simReg, (uint8_t)userConfig->trgSrcCfg.hwTrgSrc); + + /* select software pretrigger source */ + SimReg_SetAdcPreTrgSwSrc(obj->simReg, (uint8_t)userConfig->trgSrcCfg.swPretrgSrc); + + /* set pretrigger source */ + SimReg_SetAdcPreTrgSrc(obj->simReg, (uint8_t)userConfig->trgSrcCfg.pretrgSrc); + + /* select the continuous / one shot conversion */ + AdcReg_SetSc3Adco(obj->adcReg, (uint8_t)userConfig->continuousMode); + + /* configure the ADC compare function */ + AdcDrv_CfgCompare(obj, &(userConfig->cmpCfg)); + + /* enable hardware average sample */ + AdcReg_SetSc3AvgE(obj->adcReg, userConfig->avgEnable); + if(userConfig->avgEnable) + { + /* select the hardware average sample number */ + AdcReg_SetSc3AvgS(obj->adcReg, (uint8_t)userConfig->avgSamplesSel); + } + + /* configure for each ADC channel */ + uint8_t i; + for(i = 0; i < ADCDRV_CHANNEL_NUM; i++) + { + /* select the ADC channel input */ + AdcReg_SetScAdCh(obj->adcReg, i, (uint8_t)userConfig->chnCfg[i].chnSel); + + /* enable the interrupt for ADC channel */ + AdcReg_SetScAIEn(obj->adcReg, i, userConfig->chnCfg[i].intEnable); + } + + /* enable ADC */ + AdcReg_SetSc3AdcPD(obj->adcReg, ADCDRV_POWER_ON); +} + +void AdcDrv_GetDefaultConfig(AdcDrv_ConfigType *userConfig) +{ + uint8_t i = 0U; + + userConfig->conversionMode = ADCDRV_CONVERSION_12BIT; + userConfig->sampleLen = ADC_LEN_SMPL_DEFAULT; + userConfig->firstSampleLen = ADC_LEN_SMPL_1ST_DEFAULT; + userConfig->pwrOnLen = ADC_LEN_PWR_ON_DEFAULT; + userConfig->dmaEnable = false; + userConfig->cmpCfg.lowerLim = 0; + userConfig->cmpCfg.upperLim = 0; + userConfig->cmpCfg.cmpMode = ADCDRV_CMPMODE_NO_COMPARE; + userConfig->continuousMode = ADCDRV_ONESHOT; + userConfig->avgSamplesSel = ADCDRV_AVERAGE_4; + userConfig->avgEnable = true; + + userConfig->trgSrcCfg.hwTrgSrc = ADCDRV_HW_TRGSRC_PDB; + userConfig->trgSrcCfg.swPretrgSrc = ADCDRV_SWPRETRG_PRETRIGGER_0; + userConfig->trgSrcCfg.pretrgSrc = ADCDRV_PRETRG_PDB_PRETRIGGER; + + for(i = 0; i < ADCDRV_CHANNEL_NUM; i++) + { + userConfig->chnCfg[i].chnSel = (AdcDrv_InChnType)i; + userConfig->chnCfg[i].intEnable = false; + } +} + +void AdcDrv_ClrLockTrg(AdcDrvType *obj) +{ + AdcReg_ClrTrg(obj->adcReg); +} + +uint16_t AdcDrv_GetRn(AdcDrvType *obj, uint8_t chn) +{ + return (AdcReg_GetRData(obj->adcReg, (uint8_t)chn)); +} + +bool AdcDrv_GetCocon(AdcDrvType *obj, uint8_t chn) +{ + if(AdcReg_GetScCoCo(obj->adcReg, (uint8_t)chn) > 0) + { + return (true); + } + else + { + return (false); + } +} + +void AdcDrv_DisableAdc(AdcDrvType *obj) +{ + AdcReg_SetSc3AdcPD(obj->adcReg, ADCDRV_POWER_DOWN); +} + +void AdcDrv_EnableAdc(AdcDrvType *obj) +{ + AdcReg_SetSc3AdcPD(obj->adcReg, ADCDRV_POWER_ON); +} + +void AdcDrv_AbortChn(AdcDrvType *obj, uint8_t chn) +{ + AdcReg_AbortChn(obj->adcReg, chn); +} + +void AdcDrv_ConfigureChn(AdcDrvType *obj, uint8_t chn, AdcDrv_InChnType state) +{ + AdcReg_SetScAdCh(obj->adcReg, chn, state); +} + +void AdcDrv_GetConfig(AdcDrvType *obj, AdcDrv_ConfigType *currentConfig) +{ + /* get the conversion conversionMode */ + currentConfig->conversionMode = (AdcDrv_ConversionMode)AdcReg_GetCfg1Mode(obj->adcReg); + + /* get the ADC sample length */ + currentConfig->sampleLen = AdcReg_GetCfg2LenSmpl(obj->adcReg); + + /* get the ADC sample length after the 1st cycle + * change the input channel select(ADCH) */ + currentConfig->firstSampleLen = AdcReg_GetCfg2LenSmpl1st(obj->adcReg); + + /* get the ADC sample length after power on */ + currentConfig->pwrOnLen = AdcReg_GetCfg2LenPwrOn(obj->adcReg); + + /* get enable DMA */ + currentConfig->dmaEnable = AdcReg_GetSc2DmaEn(obj->adcReg); + + /* get hardware trigger source */ + currentConfig->trgSrcCfg.hwTrgSrc = (AdcDrv_HwTrgSrc)SimReg_GetAdcTrgSrc(obj->simReg); + + /* get software pretrigger source */ + currentConfig->trgSrcCfg.swPretrgSrc = (ADCDRV_SwPretrgSrc)SimReg_GetAdcPreTrgSwSrc(obj->simReg); + + /* get pretrigger source */ + currentConfig->trgSrcCfg.pretrgSrc = (ADCDRV_PretrgSrc)SimReg_GetAdcPreTrgSrc(obj->simReg); + + /* get the continuous mode */ + currentConfig->continuousMode = (AdcDrv_ContinuousMode)AdcReg_GetSc3Adco(obj->adcReg); + + /* get configuration the ADC compare function */ + AdcDrv_GetCmpCfg(obj, ¤tConfig->cmpCfg); + + /* get hardware average sample configuration*/ + currentConfig->avgEnable = AdcReg_GetSc3AvgE(obj->adcReg); + + /* get the hardware average sample number */ + currentConfig->avgSamplesSel = (AdcDrv_AverageMode)AdcReg_GetSc3AvgS(obj->adcReg); + + /* get configuration for each ADC channel */ + uint8_t i; + for(i = 0; i < ADCDRV_CHANNEL_NUM; i++) + { + /* get the ADC channel input */ + currentConfig->chnCfg[i].chnSel = (AdcDrv_InChnType)AdcReg_GetScAdCh(obj->adcReg, i); + + /* get the interrupt for ADC channel state*/ + currentConfig->chnCfg[i].intEnable = AdcReg_GetScAIEn(obj->adcReg, i); + } +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/adc/adc_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/adc/adc_drv.h new file mode 100644 index 0000000..3d7152e --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/adc/adc_drv.h @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _ADC_DRV_H_ +#define _ADC_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of ADC (Analog-to-digital conversion) + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup adc_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +#define ADCDRV_CHANNEL_NUM (16) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief ADC type of hardware average times selection + */ +typedef enum +{ + ADCDRV_AVERAGE_4 = 0x0U, /*!< Hardware average of 4 samples.*/ + ADCDRV_AVERAGE_8 = 0x1U, /*!< Hardware average of 8 samples.*/ + ADCDRV_AVERAGE_16 = 0x2U, /*!< Hardware average of 16 samples.*/ + ADCDRV_AVERAGE_32 = 0x3U, /*!< Hardware average of 32 samples.*/ +} AdcDrv_AverageMode; + +/*! \brief ADC type of self-test channel selection + */ +typedef enum +{ + ADCDRV_SELF_TEST_VALUE_AVSS = 0x0U, /*!< ADC self-test channel select AVSS.*/ + ADCDRV_SELF_TEST_VALUE_ONE_EIGHTH_AVSS = 0x1U, /*!< ADC self-test channel select 1/8*VREF.*/ + ADCDRV_SELF_TEST_VALUE_HALF_AVSS = 0x2U, /*!< ADC self-test channel select 1/2*VREF.*/ + ADCDRV_SELF_TEST_VALUE_SEVEN_EIGHTH_AVSS = 0x3U, /*!< ADC self-test channel select 7/8*VREF.*/ + +} AdcDrv_SelfTestValue; + +/*! \brief ADC type of resolution selection + */ +typedef enum +{ + ADCDRV_CONVERSION_8BIT = 0x0U, /*!< Selects the ADC resolution to 8-bit conversion.*/ + ADCDRV_CONVERSION_12BIT = 0x1U, /*!< Selects the ADC resolution to 12-bit conversion.*/ + ADCDRV_CONVERSION_10BIT = 0x2U, /*!< Selects the ADC resolution to 10-bit conversion.*/ + ADCDRV_CONVERSION_12BIT_2 = 0x3U, /*!< Selects the ADC resolution to 12-bit conversion.*/ +} AdcDrv_ConversionMode; + +/*! \brief ADC type of compare mode + */ +typedef enum +{ + ADCDRV_CMPMODE_NO_COMPARE = 0x0U, /*!< ADC disable compare function.*/ + ADCDRV_CMPMODE_LESSTHAN = 0x1U, /*!< Automatic compare with interrupt for less-than.*/ + ADCDRV_CMPMODE_GREATER_OR_EQUTHAN = 0x2U, /*!< Automatic compare with interrupt for greater-than or equal-to.*/ + ADCDRV_CMPMODE_OUTSIDE_EXCLUDE_BOUNDARIES = 0x3U, /*!< Automatic compare with interrupt for out-of-range(Does not contain boundaries).*/ + ADCDRV_CMPMODE_INSIDE_EXCLUDE_BOUNDARIES = 0x4U, /*!< Automatic compare with interrupt for within range(Does not contain boundaries).*/ + ADCDRV_CMPMODE_INSIDE_INCLUDE_BOUNDARIES = 0x5U, /*!< Automatic compare with interrupt for within range(Contain boundaries).*/ + ADCDRV_CMPMODE_OUTSIDE_INCLUDE_BOUNDARIES = 0x6U, /*!< Automatic compare with interrupt for out-of-range range(Contain boundaries).*/ +} AdcDrv_CmpMode; + +/*! \brief ADC type of input channel selection. + */ +typedef enum +{ + ADCDRV_INCHN_EXT0 = 0x0U, /*!< External channel 0.*/ + ADCDRV_INCHN_EXT1 = 0x1U, /*!< External channel 1.*/ + ADCDRV_INCHN_EXT3 = 0x3U, /*!< External channel 3.*/ + ADCDRV_INCHN_EXT4 = 0x4U, /*!< External channel 4.*/ + ADCDRV_INCHN_EXT5 = 0x5U, /*!< External channel 5.*/ + ADCDRV_INCHN_EXT6 = 0x6U, /*!< External channel 6.*/ + ADCDRV_INCHN_EXT7 = 0x7U, /*!< External channel 7.*/ + ADCDRV_INCHN_BG = 0x8U, /*!< Inner BG voltage.*/ + ADCDRV_INCHN_EXT9 = 0x9U, /*!< External channel 9.*/ + ADCDRV_INCHN_EXT10 = 0xAU, /*!< External channel 10.*/ + ADCDRV_INCHN_EXT11 = 0xBU, /*!< External channel 11.*/ + ADCDRV_INCHN_EXT12 = 0xCU, /*!< External channel 12.*/ + ADCDRV_INCHN_EXT13 = 0xDU, /*!< External channel 13.*/ + ADCDRV_INCHN_EXT14 = 0xEU, /*!< External channel 14.*/ + ADCDRV_INCHN_SELF_TEST = 0xFU, /*!< Inner self test voltage.*/ +} AdcDrv_InChnType; + +/*! \brief ADC type of continuous conversion mode selection. + */ +typedef enum +{ + ADCDRV_ONESHOT = 0x0U, /*!< One conversion will be performed (or one set of conversions, if AVGE is set) after a conversion is initiated.*/ + ADCDRV_CONTINUOUS = 0x1U, /*!< Continuous conversions will be performed (or continuous sets of conversions, if AVGE is set) after a conversion is initiated.*/ +} AdcDrv_ContinuousMode; + +/*! \brief ADC type of hardware trigger source selection. + */ +typedef enum +{ + ADCDRV_HW_TRGSRC_PDB = 0x0U, /*!< Select PDB output for trigger source.*/ + ADCDRV_HW_TRGSRC_TRGMUX = 0x1U, /*!< Select TRGMUX output output for trigger source.*/ +} AdcDrv_HwTrgSrc; + +/*! \brief ADC type of software pretrigger source selection. + */ +typedef enum +{ + ADCDRV_SWPRETRG_PRETRIGGER_0 = 0x4U, /*!< Select PRETRIGGER_0 for software pretrigger sources.*/ + ADCDRV_SWPRETRG_PRETRIGGER_1 = 0x5U, /*!< Select PRETRIGGER_1 for software pretrigger sources.*/ + ADCDRV_SWPRETRG_PRETRIGGER_2 = 0x6U, /*!< Select PRETRIGGER_2 for software pretrigger sources.*/ + ADCDRV_SWPRETRG_PRETRIGGER_3 = 0x7U, /*!< Select PRETRIGGER_3 for software pretrigger sources.*/ +} ADCDRV_SwPretrgSrc; + +/*! \brief ADC type of hardware pretrigger source selection. + */ +typedef enum +{ + ADCDRV_PRETRG_PDB_PRETRIGGER = 0x0U, /*!< Select PDB pretrigger for ADC pretrigger sources.*/ + ADCDRV_PRETRG_TRGMUX_PRETRIGGER = 0x1U, /*!< Select TRGMUX pretrigger for ADC pretrigger sources.*/ + ADCDRV_PRETRG_SOFTWARE_PRETRIGGER = 0x2U, /*!< Select SOFTWARE pretrigger for ADC pretrigger sources.*/ +} ADCDRV_PretrgSrc; + +/*! \brief Definition of configuration of ADC trigger/pretrigger. + */ +typedef struct _AdcDrv_TrgSrcCfgType_ +{ + AdcDrv_HwTrgSrc hwTrgSrc; /*!< Selects hardware trigger source for ADC.*/ + ADCDRV_SwPretrgSrc swPretrgSrc; /*!< Selects software pretrigger sources for ADC*/ + ADCDRV_PretrgSrc pretrgSrc; /*!< Selects pretrigger sources for ADC*/ +} AdcDrv_TrgSrcCfgType; + +/*! \brief Definition of configuration of ADC channel + */ +typedef struct _AdcDrv_ChnCfgType_ +{ + AdcDrv_InChnType chnSel; /*!< Input channel select.*/ + bool intEnable; /*!< Interrupt enable.*/ +} AdcDrv_ChnCfgType; + +/*! \brief Definition of configuration of ADC compare function + */ +typedef struct _AdcDrv_CmpCfgType_ +{ + uint16_t lowerLim; /*!< Lower limiting value in ADC compare function.*/ + uint16_t upperLim; /*!< Upper limiting value in ADC compare function.*/ + AdcDrv_CmpMode cmpMode; /*!< Select compare mode.*/ +} AdcDrv_CmpCfgType; + +/*! \brief Definition of configuration of ADC driver + */ +typedef struct _AdcDrv_ConfigType_ +{ + AdcDrv_ConversionMode conversionMode; /*!< Conversion mode select.*/ + uint8_t sampleLen; /*!< ADC sampling time.*/ + uint8_t firstSampleLen; /*!< First sample delay time.*/ + uint8_t pwrOnLen; /*!< Power on sample delay time.*/ + bool dmaEnable; /*!< Switch DMA enable.*/ + AdcDrv_CmpCfgType cmpCfg; /*!< Compare function configuration*/ + AdcDrv_ContinuousMode continuousMode; /*!< Switch continuous conversion enable*/ + AdcDrv_AverageMode avgSamplesSel; /*!< Hardware average select*/ + bool avgEnable; /*!< Switch hardware average enable*/ + AdcDrv_ChnCfgType chnCfg[ADCDRV_CHANNEL_NUM]; /*!< ADC channel configuration*/ + AdcDrv_TrgSrcCfgType trgSrcCfg; /*!< ADC trigger source configuration*/ +} AdcDrv_ConfigType; + +/* Forward declaration of ADC register */ +struct _AdcRegType_; + +/* Forward declaration of SIm register */ +struct _SimRegType_; + +/*! \brief The definition of ADC driver class + */ +typedef struct _AdcDrvType_ +{ + struct _AdcRegType_ *adcReg; + struct _SimRegType_ *simReg; +} AdcDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the ADC driver module + * + * This function initializes ADC driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to ADC driver instance + * \param[in] pdbReg : pointer to ADC register instance + * \param[in] simReg : pointer to SIM register instance + * \param[in] initParams : pointer to ADC initialization parameters + */ +extern void AdcDrv_Init(AdcDrvType *obj, struct _AdcRegType_ *adcReg, struct _SimRegType_ *simReg); + +/*! \brief Get default configures the ADC module for configuration structure + * + * This function gets default configures the ADC module for user configuration structure + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void AdcDrv_GetDefaultConfig(AdcDrv_ConfigType *userConfig); + +/*! \brief Configures the ADC module from a user configuration structure + * + * This function configures the ADC module from a user configuration structure + * + * \param[in] obj : pointer to ADC driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void AdcDrv_Configure(AdcDrvType *obj, const AdcDrv_ConfigType *userConfig); + +/*! \brief Get configures of the ADC module + * + * This function get configures of the ADC module + * + * \param[in] obj : pointer to ADC driver instance + * \param[out] currentConfig : pointer to configuration structure + */ +extern void AdcDrv_GetConfig(AdcDrvType *obj, AdcDrv_ConfigType *currentConfig); + +/*! \brief ADC clear lock trigger + * + * This function for ADC clear lock trigger + * + * \param[in] obj : pointer to ADC driver instance + */ +extern void AdcDrv_ClrLockTrg(AdcDrvType *obj); + +/*! \brief Get ADC data result + * + * This function for get ADC data result + * + * \param[in] obj : pointer to ADC driver instance + * \param[in] chn : channel number + * \return ADC data result. + */ +extern uint16_t AdcDrv_GetRn(AdcDrvType *obj, uint8_t chn); + +/*! \brief Get ADC conversion complete flag + * + * This function for get ADC conversion complete flag. + * + * \param[in] obj : pointer to ADC driver instance + * \param[in] chn : channel number + * \return ADC data result. + */ +extern bool AdcDrv_GetCocon(AdcDrvType *obj, uint8_t chn); + +/*! \brief Disable ADC + * + * This function for disable ADC + * + * \param[in] obj : pointer to ADC driver instance + */ +extern void AdcDrv_DisableAdc(AdcDrvType *obj); + +/*! \brief Enable ADC + * + * This function for enable ADC + * + * \param[in] obj : pointer to ADC driver instance + */ +extern void AdcDrv_EnableAdc(AdcDrvType *obj); + +/*! \brief Abort ADC channel n + * + * This function for abort ADC channel n + * + * \param[in] obj : pointer to ADC driver instance + * \param[in] chn : channel number + */ +extern void AdcDrv_AbortChn(AdcDrvType *obj, uint8_t chn); + +/*! \brief Selects one of the input channels. + * + * This function for selects one of the input channels. + * + * \param[in] obj : pointer to ADC driver instance + * \param[in] chn : channel number + * \param[in] state : input channel selection. + */ +extern void AdcDrv_ConfigureChn(AdcDrvType *obj, uint8_t chn, AdcDrv_InChnType state); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _ADC_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/clock/clock_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/clock/clock_drv.c new file mode 100644 index 0000000..71d31c7 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/clock/clock_drv.c @@ -0,0 +1,2596 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "clock_drv.h" +#include "rcm_reg.h" +#include "scg0_reg.h" +#include "scg1_reg.h" +#include "scg2_reg.h" +#include "pcc0_reg.h" +#include "pcc1_reg.h" +#include "../../CVM011x_features.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* Definitions for LPO frequencies */ +#define LPO_128K_FREQUENCY (128000UL) +#define LPO_32K_FREQUENCY (32000UL) +#define LPO_1K_FREQUENCY (1000UL) + +/* Definitions for all the get and set clock interface */ +#define GET_FREQ_FUNC_DEF(module) static inline bool ClockDrv_Get##module##Freq(const ClockDrvType *obj, uint32_t *frequency) +#define GET_FREQ_FUNC(module) ClockDrv_Get##module##Freq +#define CONFIG_CLOCK_FUNC_DEF(module) static inline bool ClockDrv_Set##module##Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +#define CONFIG_CLOCK_FUNC(module) ClockDrv_Set##module##Clock + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Module clock function table element definition + */ +typedef struct _ClockDrv_ModuleClkFuncType_ +{ + bool (*getFreqFunc)(const ClockDrvType *, uint32_t *); + bool (*setClockFunc)(ClockDrvType *, const ClockDrv_ModuleClkConfigType *); +} ClockDrv_ModuleClkFuncType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/* Forward decleratios for all get and set clock interface */ +GET_FREQ_FUNC_DEF(Sosc); +CONFIG_CLOCK_FUNC_DEF(Sosc); +GET_FREQ_FUNC_DEF(Sirc); +GET_FREQ_FUNC_DEF(Pll); +CONFIG_CLOCK_FUNC_DEF(Pll); +GET_FREQ_FUNC_DEF(SoscDiv); +CONFIG_CLOCK_FUNC_DEF(SoscDiv); +GET_FREQ_FUNC_DEF(SoscDivMft); +CONFIG_CLOCK_FUNC_DEF(SoscDivMft); +GET_FREQ_FUNC_DEF(SircDiv); +CONFIG_CLOCK_FUNC_DEF(SircDiv); +GET_FREQ_FUNC_DEF(SircDivMft); +CONFIG_CLOCK_FUNC_DEF(SircDivMft); +GET_FREQ_FUNC_DEF(PllDiv); +CONFIG_CLOCK_FUNC_DEF(PllDiv); +GET_FREQ_FUNC_DEF(PllDivMft); +CONFIG_CLOCK_FUNC_DEF(PllDivMft); +GET_FREQ_FUNC_DEF(Sys); +CONFIG_CLOCK_FUNC_DEF(Sys); +GET_FREQ_FUNC_DEF(Core); +CONFIG_CLOCK_FUNC_DEF(Core); +GET_FREQ_FUNC_DEF(Apb); +CONFIG_CLOCK_FUNC_DEF(Apb); +GET_FREQ_FUNC_DEF(Fls); +CONFIG_CLOCK_FUNC_DEF(Fls); +GET_FREQ_FUNC_DEF(ClkOut); +CONFIG_CLOCK_FUNC_DEF(ClkOut); +GET_FREQ_FUNC_DEF(RtcPadIn); +GET_FREQ_FUNC_DEF(Lpo1k); +CONFIG_CLOCK_FUNC_DEF(Lpo1k); +GET_FREQ_FUNC_DEF(Lpo32k); +CONFIG_CLOCK_FUNC_DEF(Lpo32k); +GET_FREQ_FUNC_DEF(Lpo128k); +CONFIG_CLOCK_FUNC_DEF(Lpo32k); +GET_FREQ_FUNC_DEF(Cmp); +CONFIG_CLOCK_FUNC_DEF(Cmp); +GET_FREQ_FUNC_DEF(PortA); +CONFIG_CLOCK_FUNC_DEF(PortA); +GET_FREQ_FUNC_DEF(PortB); +CONFIG_CLOCK_FUNC_DEF(PortB); +GET_FREQ_FUNC_DEF(PortC); +CONFIG_CLOCK_FUNC_DEF(PortC); +GET_FREQ_FUNC_DEF(PortD); +CONFIG_CLOCK_FUNC_DEF(PortD); +GET_FREQ_FUNC_DEF(PortE); +CONFIG_CLOCK_FUNC_DEF(PortE); +GET_FREQ_FUNC_DEF(Lptmr); +CONFIG_CLOCK_FUNC_DEF(Lptmr); +GET_FREQ_FUNC_DEF(Lpit); +CONFIG_CLOCK_FUNC_DEF(Lpit); +GET_FREQ_FUNC_DEF(RtcCnt); +CONFIG_CLOCK_FUNC_DEF(RtcCnt); +GET_FREQ_FUNC_DEF(PortAFlt); +CONFIG_CLOCK_FUNC_DEF(PortAFlt); +GET_FREQ_FUNC_DEF(PortBFlt); +CONFIG_CLOCK_FUNC_DEF(PortBFlt); +GET_FREQ_FUNC_DEF(PortCFlt); +CONFIG_CLOCK_FUNC_DEF(PortCFlt); +GET_FREQ_FUNC_DEF(PortDFlt); +CONFIG_CLOCK_FUNC_DEF(PortDFlt); +GET_FREQ_FUNC_DEF(PortEFlt); +CONFIG_CLOCK_FUNC_DEF(PortEFlt); +GET_FREQ_FUNC_DEF(ExtFlt); +CONFIG_CLOCK_FUNC_DEF(ExtFlt); +GET_FREQ_FUNC_DEF(Dma); +CONFIG_CLOCK_FUNC_DEF(Dma); +GET_FREQ_FUNC_DEF(Mscm); +CONFIG_CLOCK_FUNC_DEF(Mscm); +GET_FREQ_FUNC_DEF(Crc); +CONFIG_CLOCK_FUNC_DEF(Crc); +GET_FREQ_FUNC_DEF(Eim); +CONFIG_CLOCK_FUNC_DEF(Eim); +GET_FREQ_FUNC_DEF(Erm); +CONFIG_CLOCK_FUNC_DEF(Erm); +GET_FREQ_FUNC_DEF(Fhu); +CONFIG_CLOCK_FUNC_DEF(Fhu); +GET_FREQ_FUNC_DEF(Adc); +CONFIG_CLOCK_FUNC_DEF(Adc); +GET_FREQ_FUNC_DEF(Pdb); +CONFIG_CLOCK_FUNC_DEF(Pdb); +GET_FREQ_FUNC_DEF(Spi0); +CONFIG_CLOCK_FUNC_DEF(Spi0); +GET_FREQ_FUNC_DEF(Spi1); +CONFIG_CLOCK_FUNC_DEF(Spi1); +GET_FREQ_FUNC_DEF(Uart0); +CONFIG_CLOCK_FUNC_DEF(Uart0); +GET_FREQ_FUNC_DEF(Uart1); +CONFIG_CLOCK_FUNC_DEF(Uart1); +GET_FREQ_FUNC_DEF(Uart2); +CONFIG_CLOCK_FUNC_DEF(Uart2); +GET_FREQ_FUNC_DEF(I2C); +CONFIG_CLOCK_FUNC_DEF(I2C); +GET_FREQ_FUNC_DEF(I2SM); +CONFIG_CLOCK_FUNC_DEF(I2SM); +GET_FREQ_FUNC_DEF(I2SS); +CONFIG_CLOCK_FUNC_DEF(I2SS); +GET_FREQ_FUNC_DEF(PwmLite0); +CONFIG_CLOCK_FUNC_DEF(PwmLite0); +GET_FREQ_FUNC_DEF(PwmLite1); +CONFIG_CLOCK_FUNC_DEF(PwmLite1); +GET_FREQ_FUNC_DEF(Mft0); +CONFIG_CLOCK_FUNC_DEF(Mft0); +GET_FREQ_FUNC_DEF(Mft1); +CONFIG_CLOCK_FUNC_DEF(Mft1); +GET_FREQ_FUNC_DEF(Cmus); +CONFIG_CLOCK_FUNC_DEF(Cmus); +GET_FREQ_FUNC_DEF(Cmup); +CONFIG_CLOCK_FUNC_DEF(Cmup); +GET_FREQ_FUNC_DEF(Tclk0); +GET_FREQ_FUNC_DEF(Tclk1); +GET_FREQ_FUNC_DEF(Tclk2); +GET_FREQ_FUNC_DEF(ExtMft0); +CONFIG_CLOCK_FUNC_DEF(ExtMft0); +GET_FREQ_FUNC_DEF(ExtMft1); +CONFIG_CLOCK_FUNC_DEF(ExtMft1); +GET_FREQ_FUNC_DEF(FixMft0); +CONFIG_CLOCK_FUNC_DEF(FixMft0); +GET_FREQ_FUNC_DEF(FixMft1); +CONFIG_CLOCK_FUNC_DEF(FixMft1); +GET_FREQ_FUNC_DEF(Mpu); +CONFIG_CLOCK_FUNC_DEF(Mpu); + +/* Function table for all get and set clock interface */ +const ClockDrv_ModuleClkFuncType c_clockFuncTable[CLOCKDRV_CLOCK_NUM] = { + {GET_FREQ_FUNC(Sosc), CONFIG_CLOCK_FUNC(Sosc) }, /* CLOCKDRV_SOSC */ + {GET_FREQ_FUNC(Sirc), NULL }, /* CLOCKDRV_SIRC */ + {GET_FREQ_FUNC(Pll), CONFIG_CLOCK_FUNC(Pll) }, /* CLOCKDRV_PLL */ + {GET_FREQ_FUNC(SoscDiv), CONFIG_CLOCK_FUNC(SoscDiv) }, /* CLOCKDRV_SOSC_DIV */ + {GET_FREQ_FUNC(SoscDivMft), CONFIG_CLOCK_FUNC(SoscDivMft)}, /* CLOCKDRV_SOSC_DIV_MFT */ + {GET_FREQ_FUNC(SircDiv), CONFIG_CLOCK_FUNC(SircDiv) }, /* CLOCKDRV_SIRC_DIV */ + {GET_FREQ_FUNC(SircDivMft), CONFIG_CLOCK_FUNC(SircDivMft)}, /* CLOCKDRV_SIRC_DIV_MFT */ + {GET_FREQ_FUNC(PllDiv), CONFIG_CLOCK_FUNC(PllDiv) }, /* CLOCKDRV_PLL_DIV */ + {GET_FREQ_FUNC(PllDivMft), CONFIG_CLOCK_FUNC(PllDivMft) }, /* CLOCKDRV_PLL_DIV_MFT */ + {GET_FREQ_FUNC(Sys), CONFIG_CLOCK_FUNC(Sys) }, /* CLOCKDRV_SYS */ + {GET_FREQ_FUNC(Core), CONFIG_CLOCK_FUNC(Core) }, /* CLOCKDRV_CORE */ + {GET_FREQ_FUNC(Apb), CONFIG_CLOCK_FUNC(Apb) }, /* CLOCKDRV_APB */ + {GET_FREQ_FUNC(Fls), CONFIG_CLOCK_FUNC(Fls) }, /* CLOCKDRV_FLS */ + {GET_FREQ_FUNC(ClkOut), CONFIG_CLOCK_FUNC(ClkOut) }, /* CLOCKDRV_CLKOUT */ + {GET_FREQ_FUNC(RtcPadIn), NULL }, /* CLOCKDRV_RTC_PADIN */ + {GET_FREQ_FUNC(Lpo1k), CONFIG_CLOCK_FUNC(Lpo1k) }, /* CLOCKDRV_LPO_1K */ + {GET_FREQ_FUNC(Lpo32k), CONFIG_CLOCK_FUNC(Lpo32k) }, /* CLOCKDRV_LPO_32K */ + {GET_FREQ_FUNC(Lpo128k), NULL }, /* CLOCKDRV_LPO_128K */ + {GET_FREQ_FUNC(Cmp), CONFIG_CLOCK_FUNC(Cmp) }, /* CLOCKDRV_CMP */ + {GET_FREQ_FUNC(PortA), CONFIG_CLOCK_FUNC(PortA) }, /* CLOCKDRV_PORTA */ + {GET_FREQ_FUNC(PortB), CONFIG_CLOCK_FUNC(PortB) }, /* CLOCKDRV_PORTB */ + {GET_FREQ_FUNC(PortC), CONFIG_CLOCK_FUNC(PortC) }, /* CLOCKDRV_PORTC */ + {GET_FREQ_FUNC(PortD), CONFIG_CLOCK_FUNC(PortD) }, /* CLOCKDRV_PORTD */ + {GET_FREQ_FUNC(PortE), CONFIG_CLOCK_FUNC(PortE) }, /* CLOCKDRV_PORTE */ + {GET_FREQ_FUNC(Lptmr), CONFIG_CLOCK_FUNC(Lptmr) }, /* CLOCKDRV_LPTMR */ + {GET_FREQ_FUNC(Lpit), CONFIG_CLOCK_FUNC(Lpit) }, /* CLOCKDRV_LPIT */ + {GET_FREQ_FUNC(RtcCnt), CONFIG_CLOCK_FUNC(RtcCnt) }, /* CLOCKDRV_RTC_CNT */ + {GET_FREQ_FUNC(PortAFlt), CONFIG_CLOCK_FUNC(PortAFlt) }, /* CLOCKDRV_PORTA_FLT */ + {GET_FREQ_FUNC(PortBFlt), CONFIG_CLOCK_FUNC(PortBFlt) }, /* CLOCKDRV_PORTB_FLT */ + {GET_FREQ_FUNC(PortCFlt), CONFIG_CLOCK_FUNC(PortCFlt) }, /* CLOCKDRV_PORTC_FLT */ + {GET_FREQ_FUNC(PortDFlt), CONFIG_CLOCK_FUNC(PortDFlt) }, /* CLOCKDRV_PORTD_FLT */ + {GET_FREQ_FUNC(PortEFlt), CONFIG_CLOCK_FUNC(PortEFlt) }, /* CLOCKDRV_PORTE_FLT */ + {GET_FREQ_FUNC(ExtFlt), CONFIG_CLOCK_FUNC(ExtFlt) }, /* CLOCKDRV_EXT_FLT */ + {GET_FREQ_FUNC(Dma), CONFIG_CLOCK_FUNC(Dma) }, /* CLOCKDRV_DMA */ + {GET_FREQ_FUNC(Mscm), CONFIG_CLOCK_FUNC(Mscm) }, /* CLOCKDRV_MSCM */ + {GET_FREQ_FUNC(Crc), CONFIG_CLOCK_FUNC(Crc) }, /* CLOCKDRV_CRC */ + {GET_FREQ_FUNC(Eim), CONFIG_CLOCK_FUNC(Eim) }, /* CLOCKDRV_EIM */ + {GET_FREQ_FUNC(Erm), CONFIG_CLOCK_FUNC(Erm) }, /* CLOCKDRV_ERM */ + {GET_FREQ_FUNC(Fhu), CONFIG_CLOCK_FUNC(Fhu) }, /* CLOCKDRV_FHU */ + {GET_FREQ_FUNC(Adc), CONFIG_CLOCK_FUNC(Adc) }, /* CLOCKDRV_ADC */ + {GET_FREQ_FUNC(Pdb), CONFIG_CLOCK_FUNC(Pdb) }, /* CLOCKDRV_PDB */ + {GET_FREQ_FUNC(Spi0), CONFIG_CLOCK_FUNC(Spi0) }, /* CLOCKDRV_SPI0 */ + {GET_FREQ_FUNC(Spi1), CONFIG_CLOCK_FUNC(Spi1) }, /* CLOCKDRV_SPI1 */ + {GET_FREQ_FUNC(Uart0), CONFIG_CLOCK_FUNC(Uart0) }, /* CLOCKDRV_UART0 */ + {GET_FREQ_FUNC(Uart1), CONFIG_CLOCK_FUNC(Uart1) }, /* CLOCKDRV_UART1 */ + {GET_FREQ_FUNC(Uart2), CONFIG_CLOCK_FUNC(Uart2) }, /* CLOCKDRV_UART2 */ + {GET_FREQ_FUNC(I2C), CONFIG_CLOCK_FUNC(I2C) }, /* CLOCKDRV_I2C */ + {GET_FREQ_FUNC(I2SM), CONFIG_CLOCK_FUNC(I2SM) }, /* CLOCKDRV_I2SM */ + {GET_FREQ_FUNC(I2SS), CONFIG_CLOCK_FUNC(I2SS) }, /* CLOCKDRV_I2SS */ + {GET_FREQ_FUNC(PwmLite0), CONFIG_CLOCK_FUNC(PwmLite0) }, /* CLOCKDRV_PWMLITE0 */ + {GET_FREQ_FUNC(PwmLite1), CONFIG_CLOCK_FUNC(PwmLite1) }, /* CLOCKDRV_PWMLITE1 */ + {GET_FREQ_FUNC(Mft0), CONFIG_CLOCK_FUNC(Mft0) }, /* CLOCKDRV_MFT0 */ + {GET_FREQ_FUNC(Mft1), CONFIG_CLOCK_FUNC(Mft1) }, /* CLOCKDRV_MFT1 */ + {GET_FREQ_FUNC(Cmus), CONFIG_CLOCK_FUNC(Cmus) }, /* CLOCKDRV_CMUS */ + {GET_FREQ_FUNC(Cmup), CONFIG_CLOCK_FUNC(Cmup) }, /* CLOCKDRV_CMUP */ + {GET_FREQ_FUNC(Tclk0), NULL }, /* CLOCKDRV_TCLK0 */ + {GET_FREQ_FUNC(Tclk1), NULL }, /* CLOCKDRV_TCLK1 */ + {GET_FREQ_FUNC(Tclk2), NULL }, /* CLOCKDRV_TCLK2 */ + {GET_FREQ_FUNC(ExtMft0), CONFIG_CLOCK_FUNC(ExtMft0) }, /* CLOCKDRV_EXT_MFT0 */ + {GET_FREQ_FUNC(ExtMft1), CONFIG_CLOCK_FUNC(ExtMft1) }, /* CLOCKDRV_EXT_MFT1 */ + {GET_FREQ_FUNC(FixMft0), CONFIG_CLOCK_FUNC(FixMft0) }, /* CLOCKDRV_FIX_MFT0 */ + {GET_FREQ_FUNC(FixMft1), CONFIG_CLOCK_FUNC(FixMft1) }, /* CLOCKDRV_FIX_MFT1 */ + {GET_FREQ_FUNC(Mpu), CONFIG_CLOCK_FUNC(Mpu) }, /* CLOCKDRV_MPU */ +}; + +/******************************************************************************* + * the functions + ******************************************************************************/ + +static inline bool ClockDrv_GetSoscFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Scg0Reg_GetOscCtrlEnSosc(obj->scg0Reg) && Scg0Reg_GetStatusSoscRdy(obj->scg0Reg)) + { + *frequency = obj->xtalClkFreq; + return true; + } + return false; +} + +static inline bool ClockDrv_SetSoscClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + /* Disable SOSC first, before configure */ + Scg0Reg_SetOscCtrlEnSosc(obj->scg0Reg, 0); + + /* Enable SOSC if required */ + if(moduleClkConfig->gating) + { + uint8_t soscRange = obj->xtalClkFreq == 4000000 ? 0 : (obj->xtalClkFreq <= 8000000 ? 1 : (obj->xtalClkFreq <= 24000000 ? 2 : (obj->xtalClkFreq <= 40000000 ? 3 : 4))); + if(4 == soscRange) + { + return false; + } + /* Set SOSC frequency range */ + Scg0Reg_SetOscCtrlRange(obj->scg0Reg, soscRange); + /* Disable external EXTAL clock in, cannot enable at the same time */ + Scg0Reg_SetOscCtrlEnExtClk(obj->scg0Reg, 0); + /* Enable SOSC */ + Scg0Reg_SetOscCtrlEnSosc(obj->scg0Reg, 1); + while(Scg0Reg_GetStatusSoscRdy(obj->scg0Reg) == 0) + { + ; /* Wait until SOSC is locked */ + } + } + + return true; +} + +static inline bool ClockDrv_GetSircFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + /* SIRC always enabled */ + if(Scg0Reg_GetStatusSircRdy(obj->scg0Reg)) + { + *frequency = obj->sircFreq; + return true; + } + return false; +} + +static inline bool ClockDrv_GetPllFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Scg0Reg_GetPllCtrl0PllEn(obj->scg0Reg) && Scg0Reg_GetStatusPllLock(obj->scg0Reg)) + { + uint32_t freq; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Scg0Reg_GetPllCtrl1PllClkinSel(obj->scg0Reg)) + { + case 0: /* SOSC clock as source */ + retval = ClockDrv_GetSoscFreq(obj, &freq); + break; + case 1: /* SIRC clock as source */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + /* If the source clock is valid */ + if(false == retval) + { + return false; + } + + /* Get the PLL pre-divider */ + uint32_t preDiv = 1; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Scg0Reg_GetPllCtrl0PllPreDiv(obj->scg0Reg)) + { + case 0: + preDiv = 1; + break; + case 1: + preDiv = 2; + break; + case 2: + preDiv = 4; + break; + case 3: + preDiv = 8; + break; + default: + /* should not get here */ + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + /* Get the PLL feedback divider setting */ + uint32_t mult = Scg0Reg_GetPllCtrl0PllM(obj->scg0Reg); + mult = (mult == 0 ? 128 : mult); + /* Get the PLL feedback divider setting */ + uint32_t postDiv = Scg0Reg_GetPllCtrl0PllPosDiv(obj->scg0Reg); + postDiv = (postDiv == 0 ? 8 : postDiv); + /* Get the PLL Feedback clock divider pre-scaler */ + uint32_t fblSel = Scg0Reg_GetPllCtrl0PllFdkSel(obj->scg0Reg); + fblSel = fblSel + 1; + + /* Calculate the final PLL frequency */ + *frequency = (freq * mult * fblSel) / (2 * preDiv * postDiv); + + retval = true; + } + + return retval; +} + +bool ClockDrv_SetPllClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + /* Disable PLL first, before configure */ + Scg0Reg_SetPllCtrl0PllEn(obj->scg0Reg, 0); + + bool retval = true; + switch(moduleClkConfig->source) + { + case CLOCKDRV_SOSC: /* SOSC clock as source */ + Scg0Reg_SetPllCtrl1PllClkinSel(obj->scg0Reg, 0); + break; + case CLOCKDRV_SIRC: /* SIRC clock as source */ + Scg0Reg_SetPllCtrl1PllClkinSel(obj->scg0Reg, 1); + break; + default: + retval = false; + break; + } + /* If the source clock is valid */ + if(false == retval) + { + return false; + } + + /* Set the PLL pre-divider */ + uint8_t preDiv = moduleClkConfig->pllConfig.preDiv == 1 ? 0 : (moduleClkConfig->pllConfig.preDiv == 2 ? 1 : (moduleClkConfig->pllConfig.preDiv == 4 ? 2 : (moduleClkConfig->pllConfig.preDiv == 8 ? 3 : 0xff))); + /* If PLL pre-divider is valid */ + if(0xff == preDiv) + { + return false; + } + Scg0Reg_SetPllCtrl0PllPreDiv(obj->scg0Reg, preDiv); + + /* Set the PLL feedback divider */ + if(moduleClkConfig->mult >= 1 && moduleClkConfig->mult <= 128) + { + Scg0Reg_SetPllCtrl0PllM(obj->scg0Reg, moduleClkConfig->mult == 128 ? 0 : moduleClkConfig->mult); + } + else + { + return false; + } + + /* Set the post-divider */ + if(moduleClkConfig->pllConfig.postDiv >= 1 && moduleClkConfig->pllConfig.postDiv <= 8) + { + Scg0Reg_SetPllCtrl0PllPosDiv(obj->scg0Reg, moduleClkConfig->pllConfig.postDiv == 8 ? 0 : moduleClkConfig->pllConfig.postDiv); + } + else + { + return false; + } + + /* Set the feedback clock divider pre-scaler */ + if(moduleClkConfig->pllConfig.fblSel == 1 || moduleClkConfig->pllConfig.fblSel == 2) + { + Scg0Reg_SetPllCtrl0PllFdkSel(obj->scg0Reg, moduleClkConfig->pllConfig.fblSel - 1); + } + else + { + return false; + } + + /* Enable PLL if required */ + if(moduleClkConfig->gating) + { + Scg0Reg_SetPllCtrl0PllEn(obj->scg0Reg, 1); + while(Scg0Reg_GetStatusPllLock(obj->scg0Reg) == 0) + { + ; /* Wait until PLL is locked */ + } + } + + return retval; +} + +static inline bool ClockDrv_GetSoscDivFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetSoscCfgEn(obj->scg2Reg)) + { + retval = ClockDrv_GetSoscFreq(obj, &freq); + if(retval) + { + uint32_t div = ((uint32_t)1UL) << Scg2Reg_GetSoscCfgDiv(obj->scg2Reg); + if(div <= 64) + { + *frequency = freq / div; + } + else + { + retval = false; + } + } + } + + return retval; +} + +static inline bool ClockDrv_SetSoscDivClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Scg2Reg_SetSoscCfgEn(obj->scg2Reg, 0); + + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : (moduleClkConfig->div == 16 ? 4 : (moduleClkConfig->div == 32 ? 5 : (moduleClkConfig->div == 64 ? 6 : 7)))))); + if(div != 7) + { + Scg2Reg_SetSoscCfgDiv(obj->scg2Reg, div); + retval = true; + } + /* Enable if required */ + Scg2Reg_SetSoscCfgEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetSoscDivMftFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetSoscMftEn(obj->scg2Reg)) + { + retval = ClockDrv_GetSoscFreq(obj, &freq); + if(retval) + { + uint32_t div = ((uint32_t)1UL) << Scg2Reg_GetSoscMftDiv(obj->scg2Reg); + if(div <= 64) + { + *frequency = freq / div; + } + else + { + retval = false; + } + } + } + + return retval; +} + +static inline bool ClockDrv_SetSoscDivMftClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Scg2Reg_SetSoscMftEn(obj->scg2Reg, 0); + + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : (moduleClkConfig->div == 16 ? 4 : (moduleClkConfig->div == 32 ? 5 : (moduleClkConfig->div == 64 ? 6 : 7)))))); + if(div != 7) + { + Scg2Reg_SetSoscMftDiv(obj->scg2Reg, div); + retval = true; + } + /* Enable if required */ + Scg2Reg_SetSoscMftEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetSircDivFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetSircCfgEn(obj->scg2Reg)) + { + retval = ClockDrv_GetSircFreq(obj, &freq); + if(retval) + { + uint32_t div = ((uint32_t)1UL) << Scg2Reg_GetSircCfgDiv(obj->scg2Reg); + if(div <= 64) + { + *frequency = freq / div; + } + else + { + retval = false; + } + } + } + + return retval; +} + +static inline bool ClockDrv_SetSircDivClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Scg2Reg_SetSircCfgEn(obj->scg2Reg, 0); + + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : (moduleClkConfig->div == 16 ? 4 : (moduleClkConfig->div == 32 ? 5 : (moduleClkConfig->div == 64 ? 6 : 7)))))); + if(div != 7) + { + Scg2Reg_SetSircCfgDiv(obj->scg2Reg, div); + retval = true; + } + /* Enable if required */ + Scg2Reg_SetSircCfgEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetSircDivMftFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetSircMftEn(obj->scg2Reg)) + { + retval = ClockDrv_GetSircFreq(obj, &freq); + if(retval) + { + uint32_t div = ((uint32_t)1UL) << Scg2Reg_GetSircMftDiv(obj->scg2Reg); + if(div <= 64) + { + *frequency = freq / div; + } + else + { + retval = false; + } + } + } + + return retval; +} + +static inline bool ClockDrv_SetSircDivMftClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Scg2Reg_SetSircMftEn(obj->scg2Reg, 0); + + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : (moduleClkConfig->div == 16 ? 4 : (moduleClkConfig->div == 32 ? 5 : (moduleClkConfig->div == 64 ? 6 : 7)))))); + if(div != 7) + { + Scg2Reg_SetSircMftDiv(obj->scg2Reg, div); + retval = true; + } + /* Enable if required */ + Scg2Reg_SetSircMftEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetPllDivFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetPllCfgEn(obj->scg2Reg)) + { + retval = ClockDrv_GetPllFreq(obj, &freq); + if(retval) + { + uint32_t div = ((uint32_t)1UL) << Scg2Reg_GetPllCfgDiv(obj->scg2Reg); + if(div <= 64) + { + *frequency = freq / div; + } + else + { + retval = false; + } + } + } + + return retval; +} + +static inline bool ClockDrv_SetPllDivClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Scg2Reg_SetPllCfgEn(obj->scg2Reg, 0); + + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : (moduleClkConfig->div == 16 ? 4 : (moduleClkConfig->div == 32 ? 5 : (moduleClkConfig->div == 64 ? 6 : 7)))))); + if(div != 7) + { + Scg2Reg_SetPllCfgDiv(obj->scg2Reg, div); + retval = true; + } + /* Enable if required */ + Scg2Reg_SetPllCfgEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetPllDivMftFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetPllMftEn(obj->scg2Reg)) + { + retval = ClockDrv_GetPllFreq(obj, &freq); + if(retval) + { + uint32_t div = ((uint32_t)1UL) << Scg2Reg_GetPllMftDiv(obj->scg2Reg); + if(div <= 64) + { + *frequency = freq / div; + } + else + { + retval = false; + } + } + } + + return retval; +} + +static inline bool ClockDrv_SetPllDivMftClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Scg2Reg_SetPllMftEn(obj->scg2Reg, 0); + + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : (moduleClkConfig->div == 16 ? 4 : (moduleClkConfig->div == 32 ? 5 : (moduleClkConfig->div == 64 ? 6 : 7)))))); + if(div != 7) + { + Scg2Reg_SetPllMftDiv(obj->scg2Reg, div); + retval = true; + } + /* Enable if required */ + Scg2Reg_SetPllMftEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetSysFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + + /* Get system clock freq */ + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Scg2Reg_GetCsrSysSt(obj->scg2Reg)) + { + case 0: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, frequency); + break; + case 1: /* clk_sosc */ + retval = ClockDrv_GetSoscFreq(obj, frequency); + break; + case 2: /* clk_pll */ + retval = ClockDrv_GetPllFreq(obj, frequency); + break; + case 3: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, frequency); + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetSysClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL ? 2 : 0xff)); + if(select == 0xff) + { + return false; + } + + Scg2Reg_SetCsrSrcSys(obj->scg2Reg, select); + while(Scg2Reg_GetCsrSysSt(obj->scg2Reg) != select) + { + ; + } + + return true; +} + +static inline bool ClockDrv_GetCoreFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + /* Get system clock freq */ + uint32_t sysFreq; + retval = ClockDrv_GetSysFreq(obj, &sysFreq); + if(false == retval) + { + return false; + } + /* Get core clock freq */ + *frequency = sysFreq / (Scg1Reg_GetCkSrcSysDiv(obj->scg1Reg) + 1U); + + return retval; +} + +static inline bool ClockDrv_SetCoreClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + /* The clock source is clk_sys */ + if(moduleClkConfig->div >= 1 && moduleClkConfig->div <= 16) + { + Scg1Reg_SetCkSrcSysDiv(obj->scg1Reg, moduleClkConfig->div - 1); + return true; + } + return false; +} + +static inline bool ClockDrv_GetApbFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + /* Get core clock freq */ + uint32_t coreFreq; + retval = ClockDrv_GetCoreFreq(obj, &coreFreq); + if(false == retval) + { + return false; + } + /* Get APB clock freq */ + *frequency = coreFreq / (Scg2Reg_GetCsrDivAips(obj->scg2Reg) + 1U); + + return retval; +} + +static inline bool ClockDrv_SetApbClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + /* The clock source is core clock */ + if(moduleClkConfig->div >= 1 && moduleClkConfig->div <= 16) + { + Scg2Reg_SetCsrDivAips(obj->scg2Reg, moduleClkConfig->div - 1); + return true; + } + return false; +} + +static inline bool ClockDrv_GetFlsFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + /* Get core clock freq */ + uint32_t srcFreq; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetFlsCtlCntSrc(obj->pcc1Reg)) + { + case 0: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &srcFreq); + break; + case 1: /* clk_sosc */ + retval = ClockDrv_GetSoscFreq(obj, &srcFreq); + break; + case 2: /* clk_pll */ + retval = ClockDrv_GetPllFreq(obj, &srcFreq); + break; + case 3: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &srcFreq); + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + if(false == retval) + { + return false; + } + /* Get flash clock freq */ + if(Pcc1Reg_GetFlsCtlCkEn(obj->pcc1Reg)) + { + *frequency = srcFreq / (Pcc1Reg_GetFlsCtlCntDiv(obj->pcc1Reg) + 1U); + } + else + { + retval = false; + } + + return retval; +} + +static inline bool ClockDrv_SetFlsClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + /* The clock source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL ? 2 : 0xff)); + if(select == 0xff) + { + return false; + } + + if(moduleClkConfig->div >= 1 && moduleClkConfig->div <= 16) + { + Pcc1Reg_SetFlsCtlCntSrc(obj->pcc1Reg, select); + Pcc1Reg_SetFlsCtlCntDiv(obj->pcc1Reg, moduleClkConfig->div - 1); + Pcc1Reg_SetFlsCtlCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; + } + return false; +} + +static inline bool ClockDrv_GetClkOutFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Scg2Reg_GetClkOutEn(obj->scg2Reg) == 0) + { + return false; + } + + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetClkOutSrc1(obj->scg2Reg) == 0) + { + /* SCG out selected */ + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Scg2Reg_GetClkOutSrc0(obj->scg2Reg)) + { + case 0: + /* clk_cnt_fls */ + retval = ClockDrv_GetFlsFreq(obj, &freq); + break; + case 1: + /* clk_sosc */ + retval = ClockDrv_GetSoscFreq(obj, &freq); + break; + case 2: + /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + case 3: + /* clk_pll */ + retval = ClockDrv_GetPllFreq(obj, &freq); + break; + case 4: + /* clk_core */ + retval = ClockDrv_GetCoreFreq(obj, &freq); + break; + case 5: + /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, &freq); + break; + case 6: + /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, &freq); + break; + case 7: + /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, &freq); + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + } + else + { + switch(Scg2Reg_GetClkOutSrc1(obj->scg2Reg)) + { + case 1: + /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, &freq); + break; + case 2: + /* clk_lpo128, this is alway available */ + retval = ClockDrv_GetLpo128kFreq(obj, &freq); + break; + case 3: + /* clk_lpo32 */ + retval = ClockDrv_GetLpo32kFreq(obj, &freq); + break; + case 4: + /* clk_lpo1 */ + retval = ClockDrv_GetLpo1kFreq(obj, &freq); + break; + case 5: + /* clk_rtc_cnt */ + retval = ClockDrv_GetRtcCntFreq(obj, &freq); + break; + case 6: + /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + case 7: + /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + default: + break; + } + } + + if(true == retval) + { + *frequency = freq / (Scg2Reg_GetClkOutDiv(obj->scg2Reg) + 1); + } + + return retval; +} + +static inline bool ClockDrv_SetClkOutClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + + /* Disable first before configure */ + Scg2Reg_SetClkOutEn(obj->scg2Reg, 0); + + switch(moduleClkConfig->source) + { + case CLOCKDRV_FLS: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 0); + break; + case CLOCKDRV_SOSC: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 1); + break; + case CLOCKDRV_SIRC: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 2); + break; + case CLOCKDRV_PLL: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 3); + break; + case CLOCKDRV_CORE: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 4); + break; + case CLOCKDRV_APB: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 5); + break; + case CLOCKDRV_SOSC_DIV: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 6); + break; + case CLOCKDRV_SIRC_DIV: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 7); + break; + case CLOCKDRV_PLL_DIV: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 1); + break; + case CLOCKDRV_LPO_128K: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 2); + break; + case CLOCKDRV_LPO_32K: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 3); + break; + case CLOCKDRV_LPO_1K: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 4); + break; + case CLOCKDRV_RTC_CNT: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 5); + break; + default: + retval = false; + break; + } + + if(retval) + { + if(moduleClkConfig->div >= 1 && moduleClkConfig->div <= 8) + { + Scg2Reg_SetClkOutDiv(obj->scg2Reg, moduleClkConfig->div - 1); + } + else + { + retval = false; + } + } + + /* Enable if required */ + Scg2Reg_SetClkOutEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetRtcPadInFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + (void)obj; /* Unused, avoid warning */ + *frequency = obj->rtcClkInFreq; + return true; +} + +static inline bool ClockDrv_GetLpo1kFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc0Reg_GetLpo1Cken(obj->pcc0Reg)) + { + *frequency = LPO_1K_FREQUENCY; + return true; + } + return false; +} + +static inline bool ClockDrv_SetLpo1kClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetLpo1Cken(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetLpo32kFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc0Reg_GetLpo32Cken(obj->pcc0Reg)) + { + *frequency = LPO_32K_FREQUENCY; + return true; + } + return false; +} + +static inline bool ClockDrv_SetLpo32kClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetLpo32Cken(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetLpo128kFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + (void)obj; /* Unused, avoid warning */ + *frequency = LPO_128K_FREQUENCY; + return true; +} + +static inline bool ClockDrv_GetCmpFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + + /* Check if the cmp clock is enable */ + if(Pcc0Reg_GetCmpCkEn(obj->pcc0Reg) == 0) + { + return false; + } + + if(Pcc0Reg_GetCmpSrc(obj->pcc0Reg) == 0) + { /* clk_core */ + retval = ClockDrv_GetCoreFreq(obj, frequency); + } + else if(Pcc0Reg_GetCmpSrc(obj->pcc0Reg) == 1) + { /* clk_lptmr */ + retval = ClockDrv_GetLptmrFreq(obj, frequency); + } + + return retval; +} + +static inline bool ClockDrv_SetCmpClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + + /* Disable first before configure */ + Pcc0Reg_SetCmpCkEn(obj->pcc0Reg, 0); + + if(moduleClkConfig->source == CLOCKDRV_CORE) + { + Pcc0Reg_SetCmpSrc(obj->pcc0Reg, 0); + retval = true; + } + else if(moduleClkConfig->source == CLOCKDRV_LPTMR) + { + Pcc0Reg_SetCmpSrc(obj->pcc0Reg, 1); + retval = true; + } + + Pcc0Reg_SetCmpCkEn(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetPortAFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortACkEn(obj->pcc0Reg)) + { + retval = ClockDrv_GetApbFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortAClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetPortACkEn(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetPortBFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortBCkEn(obj->pcc0Reg)) + { + retval = ClockDrv_GetApbFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortBClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetPortBCkEn(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetPortCFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortCCkEn(obj->pcc0Reg)) + { + retval = ClockDrv_GetApbFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortCClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetPortCCkEn(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetPortDFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortDCkEn(obj->pcc0Reg)) + { + retval = ClockDrv_GetApbFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortDClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetPortDCkEn(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetPortEFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortECkEn(obj->pcc0Reg)) + { + retval = ClockDrv_GetApbFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortEClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetPortECkEn(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetLptmrFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + /* Check if the lptmr clock is enable */ + if(Pcc0Reg_GetLptmrCken(obj->pcc0Reg) == 0) + { + return false; + } + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc0Reg_GetLptmrSrc(obj->pcc0Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, &freq); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, &freq); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, &freq); + break; + case 3: /* clk_lpo128 */ + retval = ClockDrv_GetLpo128kFreq(obj, &freq); + break; + case 4: /* clk_lpo1 */ + retval = ClockDrv_GetLpo1kFreq(obj, &freq); + break; + case 5: /* clk_lpo32 */ + retval = ClockDrv_GetLpo32kFreq(obj, &freq); + break; + case 6: /* RTC_CLKIN from PAD_PTA7 */ + retval = ClockDrv_GetRtcPadInFreq(obj, &freq); + break; + case 7: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, &freq); + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + if(retval) + { + uint32_t div = Pcc0Reg_GetLptmrDiv(obj->pcc0Reg) + 1; + *frequency = freq / div; + } + + return retval; +} + +static inline bool ClockDrv_SetLptmrClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + + /* Disable first before configure */ + Pcc0Reg_SetLptmrCken(obj->pcc0Reg, 0); + + switch(moduleClkConfig->source) + { + case CLOCKDRV_SIRC_DIV: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 0); + /* Actually 7 also works */ + break; + case CLOCKDRV_SOSC_DIV: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 1); + break; + case CLOCKDRV_PLL_DIV: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 2); + break; + case CLOCKDRV_LPO_128K: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 3); + break; + case CLOCKDRV_LPO_1K: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 4); + break; + case CLOCKDRV_LPO_32K: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 5); + break; + case CLOCKDRV_RTC_PADIN: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 6); + break; + default: + retval = false; + break; + } + + if(moduleClkConfig->div >= 1 && moduleClkConfig->div <= 8) + { + Pcc0Reg_SetLptmrDiv(obj->pcc0Reg, moduleClkConfig->div - 1); + } + else + { + retval = false; + } + + Pcc0Reg_SetLptmrCken(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetLpitFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + + /* Check if the lpit clock is enable */ + if(Pcc0Reg_GetLpitCken(obj->pcc0Reg) == 0) + { + return false; + } + + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc0Reg_GetLpitSrc(obj->pcc0Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 2: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 3: /* clk_lpo128 */ + *frequency = LPO_128K_FREQUENCY; + retval = true; + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetLpitClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + + /* Disable first before configure */ + Pcc0Reg_SetLpitCken(obj->pcc0Reg, 0); + + switch(moduleClkConfig->source) + { + case CLOCKDRV_SIRC_DIV: + Pcc0Reg_SetLpitSrc(obj->pcc0Reg, 0); + break; + case CLOCKDRV_PLL_DIV: + Pcc0Reg_SetLpitSrc(obj->pcc0Reg, 1); + break; + case CLOCKDRV_SOSC_DIV: + Pcc0Reg_SetLpitSrc(obj->pcc0Reg, 2); + break; + case CLOCKDRV_LPO_128K: + Pcc0Reg_SetLpitSrc(obj->pcc0Reg, 3); + break; + default: + retval = false; + break; + } + + Pcc0Reg_SetLpitCken(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetRtcCntFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + + /* Check if the rtc function clock is enable */ + if(Pcc0Reg_GetRtcCntCken(obj->pcc0Reg) == 0) + { + return false; + } + + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc0Reg_GetRtcCntSrc(obj->pcc0Reg)) + { + case 0: /* clk_lpo32 */ + retval = ClockDrv_GetLpo32kFreq(obj, frequency); + break; + case 1: /* PAD RTC_CLKIN */ + retval = ClockDrv_GetRtcPadInFreq(obj, frequency); + break; + case 2: /* lpo1 */ + retval = ClockDrv_GetLpo1kFreq(obj, frequency); + break; + case 3: /* lpo1 */ + retval = ClockDrv_GetLpo1kFreq(obj, frequency); + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetRtcCntClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + + /* Disable first before configure */ + Pcc0Reg_SetRtcCntCken(obj->pcc0Reg, 0); + + if(moduleClkConfig->source == CLOCKDRV_LPO_32K) + { + Pcc0Reg_SetRtcCntSrc(obj->pcc0Reg, 0); + retval = true; + } + else if(moduleClkConfig->source == CLOCKDRV_RTC_PADIN) + { + Pcc0Reg_SetRtcCntSrc(obj->pcc0Reg, 1); + retval = true; + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_1K) + { + Pcc0Reg_SetRtcCntSrc(obj->pcc0Reg, 2); + /* Actually 3 is also workable */ + retval = true; + } + + Pcc0Reg_SetRtcCntCken(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetPortAFltFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortAFltSrc(obj->pcc0Reg) == 0) + { /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, frequency); + } + else if(Pcc0Reg_GetPortAFltSrc(obj->pcc0Reg) == 1) + { /* clk_lpo128 */ + retval = ClockDrv_GetLpo128kFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortAFltClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + if(moduleClkConfig->source == CLOCKDRV_APB) + { /* clk_apb */ + Pcc0Reg_SetPortAFltSrc(obj->pcc0Reg, 0); + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_128K) + { /* clk_lpo128 */ + Pcc0Reg_SetPortAFltSrc(obj->pcc0Reg, 1); + } + return retval; +} + +static inline bool ClockDrv_GetPortBFltFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortBFltSrc(obj->pcc0Reg) == 0) + { /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, frequency); + } + else if(Pcc0Reg_GetPortBFltSrc(obj->pcc0Reg) == 1) + { /* clk_lpo128 */ + retval = ClockDrv_GetLpo128kFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortBFltClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + if(moduleClkConfig->source == CLOCKDRV_APB) + { /* clk_apb */ + Pcc0Reg_SetPortBFltSrc(obj->pcc0Reg, 0); + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_128K) + { /* clk_lpo128 */ + Pcc0Reg_SetPortBFltSrc(obj->pcc0Reg, 1); + } + return retval; +} + +static inline bool ClockDrv_GetPortCFltFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortCFltSrc(obj->pcc0Reg) == 0) + { /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, frequency); + } + else if(Pcc0Reg_GetPortCFltSrc(obj->pcc0Reg) == 1) + { /* clk_lpo128 */ + retval = ClockDrv_GetLpo128kFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortCFltClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + if(moduleClkConfig->source == CLOCKDRV_APB) + { /* clk_apb */ + Pcc0Reg_SetPortCFltSrc(obj->pcc0Reg, 0); + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_128K) + { /* clk_lpo128 */ + Pcc0Reg_SetPortCFltSrc(obj->pcc0Reg, 1); + } + return retval; +} + +static inline bool ClockDrv_GetPortDFltFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortDFltSrc(obj->pcc0Reg) == 0) + { /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, frequency); + } + else if(Pcc0Reg_GetPortDFltSrc(obj->pcc0Reg) == 1) + { /* clk_lpo128 */ + retval = ClockDrv_GetLpo128kFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortDFltClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + if(moduleClkConfig->source == CLOCKDRV_APB) + { /* clk_apb */ + Pcc0Reg_SetPortDFltSrc(obj->pcc0Reg, 0); + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_128K) + { /* clk_lpo128 */ + Pcc0Reg_SetPortDFltSrc(obj->pcc0Reg, 1); + } + return retval; +} + +static inline bool ClockDrv_GetPortEFltFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortEFltSrc(obj->pcc0Reg) == 0) + { /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, frequency); + } + else if(Pcc0Reg_GetPortEFltSrc(obj->pcc0Reg) == 1) + { /* clk_lpo128 */ + retval = ClockDrv_GetLpo128kFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortEFltClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + if(moduleClkConfig->source == CLOCKDRV_APB) + { /* clk_apb */ + Pcc0Reg_SetPortEFltSrc(obj->pcc0Reg, 0); + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_128K) + { /* clk_lpo128 */ + Pcc0Reg_SetPortEFltSrc(obj->pcc0Reg, 1); + } + return retval; +} + +static inline bool ClockDrv_GetExtFltFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + + if(RcmReg_GetExtRstFltCk(obj->rcmReg) == 0) + { + /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, frequency); + } + else if(RcmReg_GetExtRstFltCk(obj->rcmReg) == 1) + { + /* clk_lpo128 */ + *frequency = LPO_128K_FREQUENCY; + retval = true; + } + + return retval; +} + +static inline bool ClockDrv_SetExtFltClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + + if(moduleClkConfig->source == CLOCKDRV_APB) + { + RcmReg_SetExtRstFltCk(obj->rcmReg, 0); + retval = true; + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_128K) + { + RcmReg_SetExtRstFltCk(obj->rcmReg, 1); + retval = true; + } + + return retval; +} + +static inline bool ClockDrv_GetDmaFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetDmaCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetCoreFreq(obj, frequency); +} + +static inline bool ClockDrv_SetDmaClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetDmaCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetMscmFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetMscmCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetMscmClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetMscmCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetCrcFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetCrcCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetCrcClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetCrcCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetEimFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetEimCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetEimClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetEimCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetErmFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetErmCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetCoreFreq(obj, frequency); +} + +static inline bool ClockDrv_SetErmClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetErmCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetFhuFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetFhuCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetFhuClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetFhuCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetAdcFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetAdcCkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + uint32_t freq = 0; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetAdcSrc(obj->pcc1Reg)) + { + case 0: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + case 1: /* clk_sosc */ + retval = ClockDrv_GetSoscFreq(obj, &freq); + break; + case 2: /* clk_pll */ + retval = ClockDrv_GetPllFreq(obj, &freq); + break; + case 3: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + /* Divider */ + uint32_t div = (uint32_t)(1UL << Pcc1Reg_GetAdcDiv(obj->pcc1Reg)); + *frequency = freq / div; + + return retval; +} + +static inline bool ClockDrv_SetAdcClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetAdcCkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetAdcSrc(obj->pcc1Reg, select); + retval = true; + } + + /* Divider */ + if(true == retval) + { + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : 0xff))); + if(div != 0xff) + { + Pcc1Reg_SetAdcDiv(obj->pcc1Reg, div); + } + else + { + retval = false; + } + } + + /* Enable if required */ + Pcc1Reg_SetAdcCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetPdbFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetPdbCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetPdbClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetPdbCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetSpi0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetSpi0CkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetSpi0Src(obj->pcc1Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 3: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetSpi0Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetSpi0CkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC_DIV ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC_DIV ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL_DIV ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetSpi0Src(obj->pcc1Reg, select); + retval = true; + } + + Pcc1Reg_SetSpi0CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetSpi1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetSpi1CkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetSpi1Src(obj->pcc1Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 3: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetSpi1Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetSpi1CkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC_DIV ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC_DIV ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL_DIV ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetSpi1Src(obj->pcc1Reg, select); + retval = true; + } + + Pcc1Reg_SetSpi1CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetUart0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetUart0CkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetUart0Src(obj->pcc1Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 3: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetUart0Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetUart0CkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC_DIV ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC_DIV ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL_DIV ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetUart0Src(obj->pcc1Reg, select); + retval = true; + } + + Pcc1Reg_SetUart0CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetUart1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ +#if FEATURE_UART_INSTANCE_NUM == 3 + if(Pcc1Reg_GetUart1CkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetUart1Src(obj->pcc1Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 3: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +#else + /* UART1 is not available */ + return false; +#endif +} + +static inline bool ClockDrv_SetUart1Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ +#if FEATURE_UART_INSTANCE_NUM == 3 + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetUart1CkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC_DIV ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC_DIV ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL_DIV ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetUart1Src(obj->pcc1Reg, select); + retval = true; + } + + Pcc1Reg_SetUart1CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +#else + /* UART1 is not available */ + return false; +#endif +} + +static inline bool ClockDrv_GetUart2Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetUart2CkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetUart2Src(obj->pcc1Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 3: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetUart2Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetUart2CkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC_DIV ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC_DIV ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL_DIV ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetUart2Src(obj->pcc1Reg, select); + retval = true; + } + + Pcc1Reg_SetUart2CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetI2CFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetI2CCkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetI2CSrc(obj->pcc1Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 3: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetI2CClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetI2CCkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC_DIV ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC_DIV ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL_DIV ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetI2CSrc(obj->pcc1Reg, select); + retval = true; + } + + Pcc1Reg_SetI2CCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetI2SMFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetI2SMCkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + uint32_t freq = 0; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetI2SMSrc(obj->pcc1Reg)) + { + case 0: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + case 1: /* clk_sosc */ + retval = ClockDrv_GetSoscFreq(obj, &freq); + break; + case 2: /* clk_pll */ + retval = ClockDrv_GetPllFreq(obj, &freq); + break; + case 3: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + /* Divider */ + uint32_t div = Pcc1Reg_GetI2SMDiv(obj->pcc1Reg) + 1; + if(div < 2) + { + div = 2; + } + *frequency = freq / div; + + return retval; +} + +static inline bool ClockDrv_SetI2SMClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetI2SMCkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetI2SMSrc(obj->pcc1Reg, select); + retval = true; + } + + /* Divider */ + if(true == retval) + { + if(moduleClkConfig->div >= 2 && moduleClkConfig->div <= 64) + { + Pcc1Reg_SetI2SMDiv(obj->pcc1Reg, moduleClkConfig->div - 1); + } + else + { + retval = false; + } + } + + /* Enable if required */ + Pcc1Reg_SetI2SMCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetI2SSFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + /* Can not get the frequency of I2S slave */ + return false; +} + +static inline bool ClockDrv_SetI2SSClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetI2SSCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetPwmLite0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetPwm0CkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetPwmLite0Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetPwm0CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetPwmLite1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetPwm1CkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetPwmLite1Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetPwm1CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetMft0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetMft0CkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetCoreFreq(obj, frequency); +} + +static inline bool ClockDrv_SetMft0Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetMft0CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetMft1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetMft1CkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetCoreFreq(obj, frequency); +} + +static inline bool ClockDrv_SetMft1Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetMft1CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetCmusFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetCmusCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetSoscFreq(obj, frequency); +} + +static inline bool ClockDrv_SetCmusClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetCmusCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetCmupFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetCmupCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetPllFreq(obj, frequency); +} + +static inline bool ClockDrv_SetCmupClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetCmupCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetTclk0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + (void)obj; /* Unused, avoid warning */ + *frequency = obj->tclkFreq[0]; + return true; +} + +static inline bool ClockDrv_GetTclk1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + (void)obj; /* Unused, avoid warning */ + *frequency = obj->tclkFreq[1]; + return true; +} + +static inline bool ClockDrv_GetTclk2Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + (void)obj; /* Unused, avoid warning */ + *frequency = obj->tclkFreq[2]; + return true; +} + +static inline bool ClockDrv_GetExtMft0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetExtMft0Src(obj->pcc1Reg)) + { + case 0: /* TCLK0 */ + retval = ClockDrv_GetTclk0Freq(obj, frequency); + break; + case 1: /* TCLK1 */ + retval = ClockDrv_GetTclk1Freq(obj, frequency); + break; + case 2: /* TCLK2 */ + retval = ClockDrv_GetTclk2Freq(obj, frequency); + break; + case 3: /* clk_sirc_div_mft */ + retval = ClockDrv_GetSircDivMftFreq(obj, frequency); + break; + case 4: /* clk_sosc_div_mft */ + retval = ClockDrv_GetSoscDivMftFreq(obj, frequency); + break; + case 5: /* clk_pll_div_mft */ + retval = ClockDrv_GetPllDivMftFreq(obj, frequency); + break; + case 6: /* clk_sirc_div_mft */ + case 7: /* clk_sirc_div_mft */ + retval = ClockDrv_GetSircDivMftFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetExtMft0Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + + /* Select source */ + switch(moduleClkConfig->source) + { + case CLOCKDRV_TCLK0: /* TCLK0 */ + Pcc1Reg_SetExtMft0Src(obj->pcc1Reg, 0); + break; + case CLOCKDRV_TCLK1: /* TCLK1 */ + Pcc1Reg_SetExtMft0Src(obj->pcc1Reg, 1); + break; + case CLOCKDRV_TCLK2: /* TCLK2 */ + Pcc1Reg_SetExtMft0Src(obj->pcc1Reg, 2); + break; + case CLOCKDRV_SIRC_DIV_MFT: /* clk_sirc_div_mft */ + Pcc1Reg_SetExtMft0Src(obj->pcc1Reg, 3); + /* Actually it can also be 6 or 7 */ + break; + case CLOCKDRV_SOSC_DIV_MFT: /* clk_sosc_div_mft */ + Pcc1Reg_SetExtMft0Src(obj->pcc1Reg, 4); + break; + case CLOCKDRV_PLL_DIV_MFT: /* clk_pll_div_mft */ + Pcc1Reg_SetExtMft0Src(obj->pcc1Reg, 5); + break; + default: + retval = false; + break; + } + + return retval; +} + +static inline bool ClockDrv_GetExtMft1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetExtMft1Src(obj->pcc1Reg)) + { + case 0: /* TCLK0 */ + retval = ClockDrv_GetTclk0Freq(obj, frequency); + break; + case 1: /* TCLK1 */ + retval = ClockDrv_GetTclk1Freq(obj, frequency); + break; + case 2: /* TCLK2 */ + retval = ClockDrv_GetTclk2Freq(obj, frequency); + break; + case 3: /* clk_sirc_div_mft */ + retval = ClockDrv_GetSircDivMftFreq(obj, frequency); + break; + case 4: /* clk_sosc_div_mft */ + retval = ClockDrv_GetSoscDivMftFreq(obj, frequency); + break; + case 5: /* clk_pll_div_mft */ + retval = ClockDrv_GetPllDivMftFreq(obj, frequency); + break; + case 6: /* clk_sirc_div_mft */ + case 7: /* clk_sirc_div_mft */ + retval = ClockDrv_GetSircDivMftFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetExtMft1Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + /* Select source */ + switch(moduleClkConfig->source) + { + case CLOCKDRV_TCLK0: /* TCLK0 */ + Pcc1Reg_SetExtMft1Src(obj->pcc1Reg, 0); + break; + case CLOCKDRV_TCLK1: /* TCLK1 */ + Pcc1Reg_SetExtMft1Src(obj->pcc1Reg, 1); + break; + case CLOCKDRV_TCLK2: /* TCLK2 */ + Pcc1Reg_SetExtMft1Src(obj->pcc1Reg, 2); + break; + case CLOCKDRV_SIRC_DIV_MFT: /* clk_sirc_div_mft */ + Pcc1Reg_SetExtMft1Src(obj->pcc1Reg, 3); + /* Actually it can also be 6 or 7 */ + break; + case CLOCKDRV_SOSC_DIV_MFT: /* clk_sosc_div_mft */ + Pcc1Reg_SetExtMft1Src(obj->pcc1Reg, 4); + break; + case CLOCKDRV_PLL_DIV_MFT: /* clk_pll_div_mft */ + Pcc1Reg_SetExtMft1Src(obj->pcc1Reg, 5); + break; + default: + retval = false; + break; + } + + return retval; +} + +static inline bool ClockDrv_GetFixMft0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetFixMft0Src(obj->pcc1Reg)) + { + case 0: /* clk_lpo32 */ + retval = ClockDrv_GetLpo32kFreq(obj, frequency); + break; + case 1: /* RTC_CLKIN */ + retval = ClockDrv_GetRtcPadInFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetFixMft0Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + + /* Select source */ + switch(moduleClkConfig->source) + { + case CLOCKDRV_LPO_32K: /* clk_lpo32 */ + Pcc1Reg_SetFixMft0Src(obj->pcc1Reg, 0); + break; + case CLOCKDRV_RTC_PADIN: /* RTC_CLKIN */ + Pcc1Reg_SetFixMft0Src(obj->pcc1Reg, 1); + break; + default: + retval = false; + break; + } + + return retval; +} + +static inline bool ClockDrv_GetFixMft1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetFixMft1Src(obj->pcc1Reg)) + { + case 0: /* clk_lpo32 */ + retval = ClockDrv_GetLpo32kFreq(obj, frequency); + break; + case 1: /* RTC_CLKIN */ + retval = ClockDrv_GetRtcPadInFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetFixMft1Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + + /* Select source */ + switch(moduleClkConfig->source) + { + case CLOCKDRV_LPO_32K: /* clk_lpo32 */ + Pcc1Reg_SetFixMft1Src(obj->pcc1Reg, 0); + break; + case CLOCKDRV_RTC_PADIN: /* RTC_CLKIN */ + Pcc1Reg_SetFixMft1Src(obj->pcc1Reg, 1); + break; + default: + retval = false; + break; + } + + return retval; +} + +static inline bool ClockDrv_GetMpuFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetMpuCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetCoreFreq(obj, frequency); +} + +static inline bool ClockDrv_SetMpuClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetMpuCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +void ClockDrv_Init(ClockDrvType *obj, + struct _RcmRegType_ *rcmReg, + struct _Pcc0RegType_ *pcc0Reg, + struct _Scg0RegType_ *scg0Reg, + struct _Scg1RegType_ *scg1Reg, + struct _Pcc1RegType_ *pcc1Reg, + struct _Scg2RegType_ *scg2Reg, + const ClockDrv_InitParamsType *initParams) +{ + obj->rcmReg = rcmReg; + obj->pcc0Reg = pcc0Reg; + obj->scg0Reg = scg0Reg; + obj->scg1Reg = scg1Reg; + obj->pcc1Reg = pcc1Reg; + obj->scg2Reg = scg2Reg; + obj->sircFreq = initParams->sircFreq; + obj->xtalClkFreq = initParams->xtalClkFreq; + obj->rtcClkInFreq = initParams->rtcClkInFreq; + uint8_t i = 0; + for(i = 0; i < TCLK_INPUTS_NUM; ++i) + { + obj->tclkFreq[i] = initParams->tclkFreq[i]; + } +} + +bool ClockDrv_GetFreq(const ClockDrvType *obj, ClockDrv_NamesType clockName, uint32_t *frequency) +{ + if(clockName >= CLOCKDRV_CLOCK_NUM) + { + return false; + } + + bool retval = false; + if(c_clockFuncTable[clockName].getFreqFunc != NULL) + { + retval = c_clockFuncTable[clockName].getFreqFunc(obj, frequency); + } + return retval; +} + +bool ClockDrv_ConfigureClock(ClockDrvType *obj, ClockDrv_NamesType clockName, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + if(clockName >= CLOCKDRV_CLOCK_NUM) + { + return false; + } + + bool retval = false; + if(c_clockFuncTable[clockName].setClockFunc != NULL) + { + Pcc0Reg_SetKey(obj->pcc0Reg, 0x55534552); /* Unlock PCC0, PCC1 */ + Scg0Reg_SetKey(obj->scg0Reg, 0x19962020); /* Unlock SCG0, SCG1, SCG2 */ + RcmReg_SetKey(obj->rcmReg, 0x52434D4B); /* Unlock RCM */ + retval = c_clockFuncTable[clockName].setClockFunc(obj, moduleClkConfig); + Pcc0Reg_SetKey(obj->pcc0Reg, 0); /* Lock PCC0, PCC1 again */ + Scg0Reg_SetKey(obj->scg0Reg, 0); /* Lock SCG0, SCG1, SCG2 again */ + RcmReg_SetKey(obj->rcmReg, 0); /* Lock RCM again */ + } + + return retval; +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/clock/clock_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/clock/clock_drv.h new file mode 100644 index 0000000..d29a52f --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/clock/clock_drv.h @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CLOCK_DRV_H_ +#define _CLOCK_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of Clock + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup clock_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* TCLK clock number */ +#define TCLK_INPUTS_NUM (3U) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Definition of Clock names. + */ +typedef enum +{ + /* Source clocks */ + CLOCKDRV_SOSC = 0, /* system crystal oscillator clock*/ + CLOCKDRV_SIRC, /* slow internal reference clock */ + CLOCKDRV_PLL, /* PLL clock */ + CLOCKDRV_SOSC_DIV, /* SOSC_DIV clock */ + CLOCKDRV_SOSC_DIV_MFT, /* SOSC_DIV_MFT clock */ + CLOCKDRV_SIRC_DIV, /* SIRC_DIV clock */ + CLOCKDRV_SIRC_DIV_MFT, /* SIRC_DIV_MFT clock */ + CLOCKDRV_PLL_DIV, /* PLL_DIV clock */ + CLOCKDRV_PLL_DIV_MFT, /* PLL_DIV_MFT clock */ + CLOCKDRV_SYS, /* system clock */ + CLOCKDRV_CORE, /* core clock */ + CLOCKDRV_APB, /* bus clock */ + CLOCKDRV_FLS, /* flash clock */ + CLOCKDRV_CLKOUT, /* CLKOUT clock */ + CLOCKDRV_RTC_PADIN, /* RTC pad input clock */ + CLOCKDRV_LPO_1K, /* LPO 1KHz clock */ + CLOCKDRV_LPO_32K, /* LPO 32KHz clock */ + CLOCKDRV_LPO_128K, /* LPO 128KHz clock */ + /* Always-on clocks */ + CLOCKDRV_CMP, /* CMP clock */ + CLOCKDRV_PORTA, /* PORTA clock */ + CLOCKDRV_PORTB, /* PORTB clock */ + CLOCKDRV_PORTC, /* PORTC clock */ + CLOCKDRV_PORTD, /* PORTD clock */ + CLOCKDRV_PORTE, /* PORTE clock */ + CLOCKDRV_LPTMR, /* LPTMR clock */ + CLOCKDRV_LPIT, /* LPIT clock */ + CLOCKDRV_RTC_CNT, /* RTC module clock for counter */ + CLOCKDRV_PORTA_FLT, /* PORTA digital filter clock */ + CLOCKDRV_PORTB_FLT, /* PORTB digital filter clock */ + CLOCKDRV_PORTC_FLT, /* PORTC digital filter clock */ + CLOCKDRV_PORTD_FLT, /* PORTD digital filter clock */ + CLOCKDRV_PORTE_FLT, /* PORTE digital filter clock */ + CLOCKDRV_EXT_FLT, /* External Reset pin digital Filter clock */ + /* Peripheral clocks */ + CLOCKDRV_DMA, /* DMA clock */ + CLOCKDRV_MSCM, /* MSCM clock */ + CLOCKDRV_CRC, /* CRC clock */ + CLOCKDRV_EIM, /* EIM clock */ + CLOCKDRV_ERM, /* ERM clock */ + CLOCKDRV_FHU, /* FHU clock */ + CLOCKDRV_ADC, /* ADC clock */ + CLOCKDRV_PDB, /* PDB clock */ + CLOCKDRV_SPI0, /* SPI0 clock */ + CLOCKDRV_SPI1, /* SPI1 clock */ + CLOCKDRV_UART0, /* UART0 clock */ + CLOCKDRV_UART1, /* UART1 clock */ + CLOCKDRV_UART2, /* UART2 clock */ + CLOCKDRV_I2C, /* I2C clock */ + CLOCKDRV_I2SM, /* I2S Mater clock */ + CLOCKDRV_I2SS, /* I2S Slave clock */ + CLOCKDRV_PWMLITE0, /* PWM_LITE0 clock */ + CLOCKDRV_PWMLITE1, /* PWM_LITE1 clock */ + CLOCKDRV_MFT0, /* MFT0 input clock, please note this is not MFT functional clock */ + CLOCKDRV_MFT1, /* MFT1 input clock, please note this is not MFT functional clock */ + CLOCKDRV_CMUS, /* CMUS clock */ + CLOCKDRV_CMUP, /* CMUP clock */ + CLOCKDRV_TCLK0, /* TCLK0 clock */ + CLOCKDRV_TCLK1, /* TCLK1 clock */ + CLOCKDRV_TCLK2, /* TCLK2 clock */ + CLOCKDRV_EXT_MFT0, /* EXT_MFT0 clock */ + CLOCKDRV_EXT_MFT1, /* EXT_MFT1 clock */ + CLOCKDRV_FIX_MFT0, /* FIX_MFT0 clock */ + CLOCKDRV_FIX_MFT1, /* FIX_MFT1 clock */ + CLOCKDRV_MPU, /* MPU clock */ + + CLOCKDRV_CLOCK_NUM +} ClockDrv_NamesType; + +/*! \brief module clock configuration. + */ +typedef struct _ClockDrv_ModuleClkConfigType_ +{ + bool gating; /*!< Clock gating. */ + ClockDrv_NamesType source; /*!< Clock source input (some modules don't have protocol clock) */ + uint16_t mult; /*!< Multiplier (some modules don't have fractional) */ + uint16_t div; /*!< Divider (some modules don't have divider) */ + + /* Only PLL clock has following configures */ + struct + { + uint32_t fblSel; /*!< feedback clock divider pre-scaler */ + uint32_t preDiv; /*!< pre-divider */ + uint32_t postDiv; /*!< post-divider */ + } pllConfig; /*!< PLL related config */ +} ClockDrv_ModuleClkConfigType; + +/*! \brief Initial parameters + */ +typedef struct _ClockDrv_InitParamsType_ +{ + uint32_t sircFreq; /*!< SIRC frequency */ + uint32_t xtalClkFreq; /*!< XTAL clock frequency. */ + uint32_t rtcClkInFreq; /*!< RTC_CLKIN clock frequency. */ + uint32_t tclkFreq[TCLK_INPUTS_NUM]; /*!< TCLKx clocks */ +} ClockDrv_InitParamsType; + +/* Forward declaration of related register */ +struct _RcmRegType_; +struct _Pcc0RegType_; +struct _Scg0RegType_; +struct _Scg1RegType_; +struct _Pcc1RegType_; +struct _Scg2RegType_; + +/*! \brief The definition of LPIT driver class + */ +typedef struct _ClockDrvType_ +{ + struct _RcmRegType_ *rcmReg; /*!< pointer to RCM register */ + struct _Pcc0RegType_ *pcc0Reg; /*!< pointer to PCC0 register */ + struct _Scg0RegType_ *scg0Reg; /*!< pointer to SCG0 register */ + struct _Scg1RegType_ *scg1Reg; /*!< pointer to SCG1 register */ + struct _Pcc1RegType_ *pcc1Reg; /*!< pointer to PCC1 register */ + struct _Scg2RegType_ *scg2Reg; /*!< pointer to SCG2 register */ + uint32_t sircFreq; /*!< SIRC frequency */ + uint32_t xtalClkFreq; /*!< XTAL clock frequency */ + uint32_t rtcClkInFreq; /*!< RTC_CLKIN clock frequency */ + uint32_t tclkFreq[TCLK_INPUTS_NUM]; /*!< TCLKx clocks */ +} ClockDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the Clock driver module + * + * This function initializes Clock driver by setting the register + * instances to it. + * + * \param[in] obj : pointer to Clock driver instance + * \param[in] rcmReg : pointer to RCM register instance + * \param[in] pcc0Reg : pointer to PCC0 register instance + * \param[in] scg0Reg : pointer to SCG0 register instance + * \param[in] scg1Reg : pointer to SCG1 register instance + * \param[in] pcc1Reg : pointer to PCC1 register instance + * \param[in] scg2Reg : pointer to SCG2 register instance + * \param[in] initParams : pointer to clock initialization parameters + */ +extern void ClockDrv_Init(ClockDrvType *obj, + struct _RcmRegType_ *rcmReg, + struct _Pcc0RegType_ *pcc0Reg, + struct _Scg0RegType_ *scg0Reg, + struct _Scg1RegType_ *scg1Reg, + struct _Pcc1RegType_ *pcc1Reg, + struct _Scg2RegType_ *scg2Reg, + const ClockDrv_InitParamsType *initParams); + +/*! \brief Gets the clock frequency for a specific clock name. + * + * This function checks the current clock configurations and then calculates + * the clock frequency for a specific clock name defined in ClockDrv_NamesType. + * Clock modules must be properly configured before using this function. + * If it cannot find the clock name or the clock is not enabled or + * it's not configured properly, it returns false. + * + * \note If return false, don't trust the value of out parameter "frequency" + * even if it's changed. + * + * \param[in] obj : pointer to Clock driver instance + * \param[in] clockName : Clock names defined + * \param[out] frequency : clock frequency value in Hertz + * \return The result of the operation + * - false : Failed to get the frequency + * - true : Success + */ +extern bool ClockDrv_GetFreq(const ClockDrvType *obj, ClockDrv_NamesType clockName, uint32_t *frequency); + +/*! \brief Configures module clock + * + * This function configures a module clock according to the configuration. + * + * \note If the target clock do not have mul or div, the corresponding configuration in + * moduleClkConfig will be ignored. + * + * \param[in] obj : pointer to Clock driver instance + * \param[in] clockName : Clock name of the configured module clock + * \param[in] moduleClkConfig : Pointer to the configuration structure. + * \return The result of the operation + * - false : configure failed + * - true : success + */ +extern bool ClockDrv_ConfigureClock(ClockDrvType *obj, ClockDrv_NamesType clockName, const ClockDrv_ModuleClkConfigType *moduleClkConfig); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _CLOCK_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cmp/cmp_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cmp/cmp_drv.c new file mode 100644 index 0000000..6736f6a --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cmp/cmp_drv.c @@ -0,0 +1,554 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "cmp_drv.h" +#include "cmp_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define CMP_TEST_VOLTAGE_ENABLE (0U) +#define CMP_TEST_VOLTAGE_DISABLE (1U) +#define CMP_STATE_SE_SHIFT (0U) +#define CMP_STATE_WE_SHIFT (1U) +#define CMP_STATE_EN_SHIFT (2U) + +#define CMP_TRIGGER_FALLING_SHIFT (0U) +#define CMP_TRIGGER_RISING_SHIFT (1U) +#define CMP_TRIGGER_MASK (1U) + +#define CMP_CHANNELSTATE_MASK (1U) +#define CMP_CHANNEL_PRESTATE_MASK (1U) +#define CMP_CHNF_MASK (1U) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +typedef enum +{ + CMPDRV_STATE_DISABLE0 = 0U, + CMPDRV_STATE_DISABLE1 = 1U, + CMPDRV_STATE_DISABLE2 = 2U, + CMPDRV_STATE_DISABLE3 = 3U, + CMPDRV_STATE_NOSAMPLE = 4U, + CMPDRV_STATE_SE = 5U, + CMPDRV_STATE_WE = 6U, + CMPDRV_STATE_WE_SE = 7U, +} CmpDrv_StateType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +/* Forward declaration */ +CmpDrv_TriggerType CmpDrv_GetTriggerMode(const CmpDrvType *obj); + +void CmpDrv_SetTriggerMode(CmpDrvType *obj, const CmpDrv_TriggerType mode); + +CmpDrv_ModeType CmpDrv_GetMode(const CmpDrvType *obj); + +void CmpDrv_SetMode(CmpDrvType *obj, const CmpDrv_ModeType mode, const uint8_t filter_sample_count, const uint8_t filter_sample_period); + +uint8_t CmpDrv_GetChannelState(const CmpDrvType *obj); + +void CmpDrv_SetChannelState(CmpDrvType *obj, const uint8_t channelState); + +uint8_t CmpDrv_GetChannelPreState(const CmpDrvType *obj); + +/* Forward declaration end */ + +void CmpDrv_Init(CmpDrvType *obj, struct _CmpRegType_ *reg) +{ + obj->reg = reg; +} + +void CmpDrv_ConfigureNormal(CmpDrvType *obj, const CmpDrv_ConfigType *userConfig) +{ + /* Unclock CMP */ + CmpReg_UnlockReg(obj->reg); + + /* Disable CMP */ + CmpReg_SetEnReg(obj->reg, false); + + /* Get configuration of normal modes */ + CmpReg_SetDmaenReg(obj->reg, userConfig->normalCfg.dmaEnable); + CmpDrv_SetTriggerMode(obj, userConfig->normalCfg.triggerMode); + CmpDrv_SetMode(obj, userConfig->normalCfg.mode, userConfig->normalCfg.filterSampleCount, userConfig->normalCfg.filterSamplePeriod); + CmpReg_SetPmodeReg(obj->reg, userConfig->normalCfg.powerMode); + CmpReg_SetInvtReg(obj->reg, userConfig->normalCfg.inverterState); + CmpReg_SetOpeReg(obj->reg, userConfig->normalCfg.pinState); + CmpReg_SetCosReg(obj->reg, userConfig->normalCfg.outputSelect); + CmpReg_SetHystctrReg(obj->reg, userConfig->normalCfg.hystLvl); + CmpReg_SetOffsetReg(obj->reg, userConfig->normalCfg.hystOffsetState); + CmpReg_SetLpfselReg(obj->reg, userConfig->normalCfg.lpfsel); + + /* Configuration of DAC */ + CmpReg_SetVrselReg(obj->reg, userConfig->dacCfg.dacVoltInSel); + CmpReg_SetVoselReg(obj->reg, userConfig->dacCfg.dacVoltScale); + CmpReg_SetDacenReg(obj->reg, userConfig->dacCfg.state); + + /* Configuration of analog mux */ + CmpReg_SetInpselReg(obj->reg, userConfig->muxCfg.posPortMux); + CmpReg_SetInnselReg(obj->reg, userConfig->muxCfg.negPortMux); + CmpReg_SetPselReg(obj->reg, userConfig->muxCfg.posInputMux); + CmpReg_SetMselReg(obj->reg, userConfig->muxCfg.negInputMux); + + /* Disable Round-Robin mode & disable Round-Robin interrupt */ + CmpReg_SetRreReg(obj->reg, false); + CmpReg_SetRrieReg(obj->reg, false); + + /* Clear all flags*/ + CmpDrv_ClearOutputFlags(obj); + CmpDrv_ClearInputFlags(obj); + + /* lock CMP */ + CmpReg_LockReg(obj->reg); + + /*! \note When enable CMP depend on user(use CmpDrv_SetCmpState for enable CMP) */ +} + +void CmpDrv_ConfigureTriggerMode(CmpDrvType *obj, const CmpDrv_ConfigType *userConfig) +{ + /* Unclock CMP */ + CmpReg_UnlockReg(obj->reg); + + /* Disable CMP */ + CmpReg_SetEnReg(obj->reg, false); + + /* Get configuration of normal modes*/ + CmpReg_SetDmaenReg(obj->reg, userConfig->normalCfg.dmaEnable); + CmpDrv_SetTriggerMode(obj, userConfig->normalCfg.triggerMode); + CmpDrv_SetMode(obj, CMP_CONTINUOUS, userConfig->normalCfg.filterSampleCount, userConfig->normalCfg.filterSamplePeriod); + CmpReg_SetPmodeReg(obj->reg, userConfig->normalCfg.powerMode); + CmpReg_SetInvtReg(obj->reg, userConfig->normalCfg.inverterState); + CmpReg_SetOpeReg(obj->reg, userConfig->normalCfg.pinState); + CmpReg_SetCosReg(obj->reg, userConfig->normalCfg.outputSelect); + CmpReg_SetHystctrReg(obj->reg, userConfig->normalCfg.hystLvl); + CmpReg_SetOffsetReg(obj->reg, userConfig->normalCfg.hystOffsetState); + CmpReg_SetLpfselReg(obj->reg, userConfig->normalCfg.lpfsel); + + /* Configuration of DAC */ + CmpReg_SetVrselReg(obj->reg, userConfig->dacCfg.dacVoltInSel); + CmpReg_SetVoselReg(obj->reg, userConfig->dacCfg.dacVoltScale); + CmpReg_SetDacenReg(obj->reg, userConfig->dacCfg.state); + + /* Configuration of analog mux */ + CmpReg_SetInpselReg(obj->reg, userConfig->muxCfg.posPortMux); + CmpReg_SetInnselReg(obj->reg, userConfig->muxCfg.negPortMux); + CmpReg_SetPselReg(obj->reg, userConfig->muxCfg.posInputMux); + CmpReg_SetMselReg(obj->reg, userConfig->muxCfg.negInputMux); + + /* Configuration of round robin modes(disable) */ + CmpReg_SetRreReg(obj->reg, true); + CmpReg_SetRrieReg(obj->reg, userConfig->rrCfg.intrEnable); + CmpReg_SetFxmpReg(obj->reg, userConfig->rrCfg.fixedMuxPort); + CmpReg_SetFxmxchReg(obj->reg, userConfig->rrCfg.fixedChnSel); + CmpReg_SetNsamReg(obj->reg, userConfig->rrCfg.sampleCnt); + CmpReg_SetInitmodReg(obj->reg, userConfig->rrCfg.initDelayCnt); + CmpDrv_SetChannelState(obj, userConfig->rrCfg.channelState); + CmpDrv_SetChannelPreState(obj, userConfig->rrCfg.channelPreState); + + /* Clear all flags */ + CmpDrv_ClearOutputFlags(obj); + CmpDrv_ClearInputFlags(obj); + + /* lock CMP */ + CmpReg_LockReg(obj->reg); + + /*! \note When enable CMP depend on user(use CmpDrv_SetCmpState for enable CMP)*/ +} + +void CmpDrv_GetConfig(const CmpDrvType *obj, CmpDrv_ConfigType *userConfig) +{ + /* Get configuration of normal modes */ + userConfig->normalCfg.dmaEnable = CmpReg_GetDmaenReg(obj->reg); + userConfig->normalCfg.triggerMode = CmpDrv_GetTriggerMode(obj); + userConfig->normalCfg.mode = CmpDrv_GetMode(obj); + userConfig->normalCfg.filterSamplePeriod = CmpReg_GetFprReg(obj->reg); + userConfig->normalCfg.filterSampleCount = CmpReg_GetFilterCntReg(obj->reg); + userConfig->normalCfg.powerMode = (CmpDrv_PmodeType)(CmpReg_GetPmodeReg(obj->reg)); + userConfig->normalCfg.inverterState = (CmpDrv_InvtType)(CmpReg_GetInvtReg(obj->reg)); + userConfig->normalCfg.pinState = CmpReg_GetOpeReg(obj->reg); + userConfig->normalCfg.outputSelect = (CmpDrv_CosType)(CmpReg_GetCosReg(obj->reg)); + userConfig->normalCfg.hystLvl = (CmpDrv_HystctrType)(CmpReg_GetHystctrReg(obj->reg)); + userConfig->normalCfg.hystOffsetState = (CmpDrv_OffsetType)(CmpReg_GetOffsetReg(obj->reg)); + userConfig->normalCfg.lpfsel = (CmpDrv_LpfselType)(CmpReg_GetLpfselReg(obj->reg)); + + /* Configuration of DAC */ + userConfig->dacCfg.dacVoltInSel = (CmpDrv_VrselType)(CmpReg_GetVrselReg(obj->reg)); + userConfig->dacCfg.dacVoltScale = CmpReg_GetVoselReg(obj->reg); + userConfig->dacCfg.state = CmpReg_GetDacenReg(obj->reg); + + /* Get configuration of analog mux */ + userConfig->muxCfg.posPortMux = (CmpDrv_InPortType)(CmpReg_GetInpselReg(obj->reg)); + userConfig->muxCfg.negPortMux = (CmpDrv_InPortType)(CmpReg_GetInnselReg(obj->reg)); + userConfig->muxCfg.posInputMux = (CmpDrv_ChSelType)(CmpReg_GetPselReg(obj->reg)); + userConfig->muxCfg.negInputMux = (CmpDrv_ChSelType)(CmpReg_GetMselReg(obj->reg)); + + /* Configuration of round robin modes */ + userConfig->rrCfg.intrEnable = CmpReg_GetRrieReg(obj->reg); + userConfig->rrCfg.fixedMuxPort = (CmpDrv_FxmpType)(CmpReg_GetFxmpReg(obj->reg)); + userConfig->rrCfg.fixedChnSel = (CmpDrv_ChSelType)(CmpReg_GetFxmxchReg(obj->reg)); + userConfig->rrCfg.sampleCnt = CmpReg_GetNsamReg(obj->reg); + userConfig->rrCfg.initDelayCnt = CmpReg_GetInitmodReg(obj->reg); + userConfig->rrCfg.channelState = CmpDrv_GetChannelState(obj); + userConfig->rrCfg.channelPreState = CmpDrv_GetChannelPreState(obj); +} + +void CmpDrv_GetDefaultConfig(CmpDrv_ConfigType *userConfig) +{ + /* Configuration of normal modes */ + userConfig->normalCfg.dmaEnable = false; + userConfig->normalCfg.triggerMode = CMP_BOTH_EDGES; + userConfig->normalCfg.mode = CMP_CONTINUOUS; + userConfig->normalCfg.filterSamplePeriod = 0; + userConfig->normalCfg.filterSampleCount = 0; + userConfig->normalCfg.powerMode = CMPDRV_PMODE_LS; + userConfig->normalCfg.inverterState = CMPDRV_INVT_NORMAL; + userConfig->normalCfg.pinState = false; + userConfig->normalCfg.outputSelect = CMPDRV_COS_COUT; + userConfig->normalCfg.hystLvl = CMPDRV_HYSTCTR_LEVEL_0; + userConfig->normalCfg.hystOffsetState = CMPDRV_OFFSET_LEVEL_0; + userConfig->normalCfg.lpfsel = CMPDRV_LPFSEL_10MHz; + + /* Configuration of DAC */ + userConfig->dacCfg.dacVoltInSel = CMPDRV_VRSEL_VIN1; + userConfig->dacCfg.dacVoltScale = 127U; + userConfig->dacCfg.state = true; + + /* Configuration of analog mux */ + userConfig->muxCfg.posPortMux = CMPDRV_MUX; + userConfig->muxCfg.negPortMux = CMPDRV_DAC; + + /*! \note Advise to make posInputMux = negInputMux when using DAC */ + userConfig->muxCfg.posInputMux = CMPDRV_CHANNEL_IN1; + userConfig->muxCfg.negInputMux = CMPDRV_CHANNEL_IN1; +} + +CmpDrv_TriggerType CmpDrv_GetTriggerMode(const CmpDrvType *obj) +{ + uint8_t IER = CmpReg_GetIerReg(obj->reg); + uint8_t IEF = CmpReg_GetIefReg(obj->reg); + return ((CmpDrv_TriggerType)((IER << CMP_TRIGGER_RISING_SHIFT) | (IEF << CMP_TRIGGER_FALLING_SHIFT))); +} + +void CmpDrv_SetTriggerMode(CmpDrvType *obj, const CmpDrv_TriggerType mode) +{ + uint8_t IER = (mode >> CMP_TRIGGER_RISING_SHIFT) & CMP_TRIGGER_MASK; + uint8_t IEF = (mode >> CMP_TRIGGER_FALLING_SHIFT) & CMP_TRIGGER_MASK; + CmpReg_SetIerReg(obj->reg, IER); + CmpReg_SetIefReg(obj->reg, IEF); +} + +CmpDrv_ModeType CmpDrv_GetMode(const CmpDrvType *obj) +{ + uint8_t state; + CmpDrv_ModeType mode = CMP_DISABLED; + state = CmpReg_GetEnReg(obj->reg) << CMP_STATE_EN_SHIFT; + state |= CmpReg_GetWeReg(obj->reg) << CMP_STATE_WE_SHIFT; + state |= CmpReg_GetSeReg(obj->reg) << CMP_STATE_SE_SHIFT; + uint8_t filter_sample_period = CmpReg_GetFprReg(obj->reg); + uint8_t filter_sample_count = CmpReg_GetFilterCntReg(obj->reg); + + switch(state) + { + case CMPDRV_STATE_NOSAMPLE: + if((filter_sample_period == 0U) || (filter_sample_count == 0U)) + { + mode = CMP_CONTINUOUS; + } + else if(filter_sample_count == 1U) + { + mode = CMP_SAMPLED_NONFILTRED_INT_CLK; + } + else + { + mode = CMP_SAMPLED_FILTRED_INT_CLK; + } + break; + case CMPDRV_STATE_SE: + if(filter_sample_count == 1U) + { + mode = CMP_SAMPLED_NONFILTRED_EXT_CLK; + } + else + { + mode = CMP_SAMPLED_FILTRED_EXT_CLK; + } + break; + case CMPDRV_STATE_WE: + if((filter_sample_period == 0U) || (filter_sample_count == 0U)) + { + mode = CMP_WINDOWED; + } + else if(filter_sample_count == 1U) + { + mode = CMP_WINDOWED_RESAMPLED; + } + else + { + mode = CMP_WINDOWED_FILTRED; + } + break; + case CMPDRV_STATE_WE_SE: + /*! \note If a write to this register sets both bits to 1, then ONLY SE will be treated as valid and WE is ignored*/ + if(filter_sample_count == 1U) + { + mode = CMP_SAMPLED_NONFILTRED_EXT_CLK; + } + else + { + mode = CMP_SAMPLED_FILTRED_EXT_CLK; + } + break; + default: + /* Disable case */ + break; + } + + return (mode); +} + +void CmpDrv_SetMode(CmpDrvType *obj, const CmpDrv_ModeType mode, const uint8_t filter_sample_count, const uint8_t filter_sample_period) +{ + switch(mode) + { + case CMP_DISABLED: + break; + case CMP_CONTINUOUS: + CmpReg_SetWeReg(obj->reg, false); + CmpReg_SetSeReg(obj->reg, false); + /*! \note: filter_sample_count or filter_sample_period should equal to 0*/ + CmpReg_SetFprReg(obj->reg, 0U); + CmpReg_SetFilterCntReg(obj->reg, 0U); + break; + case CMP_SAMPLED_NONFILTRED_INT_CLK: + CmpReg_SetWeReg(obj->reg, false); + CmpReg_SetSeReg(obj->reg, false); + CmpReg_SetFilterCntReg(obj->reg, 1U); + CmpReg_SetFprReg(obj->reg, filter_sample_period); + break; + case CMP_SAMPLED_NONFILTRED_EXT_CLK: + CmpReg_SetWeReg(obj->reg, false); + CmpReg_SetSeReg(obj->reg, true); + CmpReg_SetFilterCntReg(obj->reg, 1U); + CmpReg_SetFprReg(obj->reg, filter_sample_period); + break; + case CMP_SAMPLED_FILTRED_INT_CLK: + CmpReg_SetWeReg(obj->reg, false); + CmpReg_SetSeReg(obj->reg, false); + CmpReg_SetFilterCntReg(obj->reg, filter_sample_count); + CmpReg_SetFprReg(obj->reg, filter_sample_period); + break; + case CMP_SAMPLED_FILTRED_EXT_CLK: + CmpReg_SetWeReg(obj->reg, false); + CmpReg_SetSeReg(obj->reg, true); + CmpReg_SetFilterCntReg(obj->reg, filter_sample_count); + CmpReg_SetFprReg(obj->reg, filter_sample_period); + break; + case CMP_WINDOWED: + CmpReg_SetWeReg(obj->reg, true); + CmpReg_SetSeReg(obj->reg, false); + /*! \note: filter_sample_count or filter_sample_period should equal to 0*/ + CmpReg_SetFprReg(obj->reg, 0U); + CmpReg_SetFilterCntReg(obj->reg, 0U); + break; + case CMP_WINDOWED_RESAMPLED: + CmpReg_SetWeReg(obj->reg, true); + CmpReg_SetSeReg(obj->reg, false); + CmpReg_SetFilterCntReg(obj->reg, 1U); + CmpReg_SetFprReg(obj->reg, filter_sample_period); + break; + case CMP_WINDOWED_FILTRED: + CmpReg_SetWeReg(obj->reg, true); + CmpReg_SetSeReg(obj->reg, false); + CmpReg_SetFilterCntReg(obj->reg, filter_sample_count); + CmpReg_SetFprReg(obj->reg, filter_sample_period); + break; + default: + /* Impossible case*/ + break; + } +} + +uint8_t CmpDrv_GetChannelState(const CmpDrvType *obj) +{ + uint8_t tmp; + tmp = ((CmpReg_GetChn0Reg(obj->reg) & CMP_CHANNELSTATE_MASK) << CMPDRV_CHANNEL_IN0) + | ((CmpReg_GetChn1Reg(obj->reg) & CMP_CHANNELSTATE_MASK) << CMPDRV_CHANNEL_IN1) + | ((CmpReg_GetChn2Reg(obj->reg) & CMP_CHANNELSTATE_MASK) << CMPDRV_CHANNEL_IN2) + | ((CmpReg_GetChn3Reg(obj->reg) & CMP_CHANNELSTATE_MASK) << CMPDRV_CHANNEL_IN3) + | ((CmpReg_GetChn4Reg(obj->reg) & CMP_CHANNELSTATE_MASK) << CMPDRV_CHANNEL_IN4) + | ((CmpReg_GetChn5Reg(obj->reg) & CMP_CHANNELSTATE_MASK) << CMPDRV_CHANNEL_IN5) + | ((CmpReg_GetChn6Reg(obj->reg) & CMP_CHANNELSTATE_MASK) << CMPDRV_CHANNEL_IN6) + | ((CmpReg_GetChn7Reg(obj->reg) & CMP_CHANNELSTATE_MASK) << CMPDRV_CHANNEL_IN7); + return (tmp); +} + +void CmpDrv_SetChannelState(CmpDrvType *obj, const uint8_t channelState) +{ + CmpReg_SetChn0Reg(obj->reg, (channelState >> CMPDRV_CHANNEL_IN0) & CMP_CHANNELSTATE_MASK); + CmpReg_SetChn1Reg(obj->reg, (channelState >> CMPDRV_CHANNEL_IN1) & CMP_CHANNELSTATE_MASK); + CmpReg_SetChn2Reg(obj->reg, (channelState >> CMPDRV_CHANNEL_IN2) & CMP_CHANNELSTATE_MASK); + CmpReg_SetChn3Reg(obj->reg, (channelState >> CMPDRV_CHANNEL_IN3) & CMP_CHANNELSTATE_MASK); + CmpReg_SetChn4Reg(obj->reg, (channelState >> CMPDRV_CHANNEL_IN4) & CMP_CHANNELSTATE_MASK); + CmpReg_SetChn5Reg(obj->reg, (channelState >> CMPDRV_CHANNEL_IN5) & CMP_CHANNELSTATE_MASK); + CmpReg_SetChn6Reg(obj->reg, (channelState >> CMPDRV_CHANNEL_IN6) & CMP_CHANNELSTATE_MASK); + CmpReg_SetChn7Reg(obj->reg, (channelState >> CMPDRV_CHANNEL_IN7) & CMP_CHANNELSTATE_MASK); +} + +uint8_t CmpDrv_GetChannelPreState(const CmpDrvType *obj) +{ + uint8_t tmp; + tmp = ((CmpReg_GetAco0Reg(obj->reg) & CMP_CHANNEL_PRESTATE_MASK) << CMPDRV_CHANNEL_IN0) + | ((CmpReg_GetAco1Reg(obj->reg) & CMP_CHANNEL_PRESTATE_MASK) << CMPDRV_CHANNEL_IN1) + | ((CmpReg_GetAco2Reg(obj->reg) & CMP_CHANNEL_PRESTATE_MASK) << CMPDRV_CHANNEL_IN2) + | ((CmpReg_GetAco3Reg(obj->reg) & CMP_CHANNEL_PRESTATE_MASK) << CMPDRV_CHANNEL_IN3) + | ((CmpReg_GetAco4Reg(obj->reg) & CMP_CHANNEL_PRESTATE_MASK) << CMPDRV_CHANNEL_IN4) + | ((CmpReg_GetAco5Reg(obj->reg) & CMP_CHANNEL_PRESTATE_MASK) << CMPDRV_CHANNEL_IN5) + | ((CmpReg_GetAco6Reg(obj->reg) & CMP_CHANNEL_PRESTATE_MASK) << CMPDRV_CHANNEL_IN6) + | ((CmpReg_GetAco7Reg(obj->reg) & CMP_CHANNEL_PRESTATE_MASK) << CMPDRV_CHANNEL_IN7); + return (tmp); +} + +void CmpDrv_SetChannelPreState(CmpDrvType *obj, const uint8_t channelPreState) +{ + CmpReg_SetAco0Reg(obj->reg, (channelPreState >> CMPDRV_CHANNEL_IN0) & CMP_CHANNEL_PRESTATE_MASK); + CmpReg_SetAco1Reg(obj->reg, (channelPreState >> CMPDRV_CHANNEL_IN1) & CMP_CHANNEL_PRESTATE_MASK); + CmpReg_SetAco2Reg(obj->reg, (channelPreState >> CMPDRV_CHANNEL_IN2) & CMP_CHANNEL_PRESTATE_MASK); + CmpReg_SetAco3Reg(obj->reg, (channelPreState >> CMPDRV_CHANNEL_IN3) & CMP_CHANNEL_PRESTATE_MASK); + CmpReg_SetAco4Reg(obj->reg, (channelPreState >> CMPDRV_CHANNEL_IN4) & CMP_CHANNEL_PRESTATE_MASK); + CmpReg_SetAco5Reg(obj->reg, (channelPreState >> CMPDRV_CHANNEL_IN5) & CMP_CHANNEL_PRESTATE_MASK); + CmpReg_SetAco6Reg(obj->reg, (channelPreState >> CMPDRV_CHANNEL_IN6) & CMP_CHANNEL_PRESTATE_MASK); + CmpReg_SetAco7Reg(obj->reg, (channelPreState >> CMPDRV_CHANNEL_IN7) & CMP_CHANNEL_PRESTATE_MASK); +} + +void CmpDrv_SetCmpState(CmpDrvType *obj, const bool state) +{ + /* Unclock CMP */ + CmpReg_UnlockReg(obj->reg); + + /* Set CMP state */ + CmpReg_SetEnReg(obj->reg, state); + + /* lock CMP */ + CmpReg_LockReg(obj->reg); +} + +CmpDrv_TriggerType CmpDrv_GetOutputFlags(const CmpDrvType *obj) +{ + uint8_t CFF; + uint8_t CFR; + CFF = CmpReg_GetCffReg(obj->reg) & CMP_TRIGGER_MASK; + CFR = CmpReg_GetCfrReg(obj->reg) & CMP_TRIGGER_MASK; + return ((CmpDrv_TriggerType)((CFF << CMP_TRIGGER_FALLING_SHIFT) | (CFR << CMP_TRIGGER_RISING_SHIFT))); +} + +void CmpDrv_ClearOutputFlags(CmpDrvType *obj) +{ + CmpReg_ClearCffReg(obj->reg); + CmpReg_ClearCfrReg(obj->reg); +} + +uint8_t CmpDrv_GetInputFlags(const CmpDrvType *obj) +{ + uint8_t tmp; + tmp = ((CmpReg_GetCh0fReg(obj->reg) & CMP_CHNF_MASK) << CMPDRV_CHANNEL_IN0) + | ((CmpReg_GetCh1fReg(obj->reg) & CMP_CHNF_MASK) << CMPDRV_CHANNEL_IN1) + | ((CmpReg_GetCh2fReg(obj->reg) & CMP_CHNF_MASK) << CMPDRV_CHANNEL_IN2) + | ((CmpReg_GetCh3fReg(obj->reg) & CMP_CHNF_MASK) << CMPDRV_CHANNEL_IN3) + | ((CmpReg_GetCh4fReg(obj->reg) & CMP_CHNF_MASK) << CMPDRV_CHANNEL_IN4) + | ((CmpReg_GetCh5fReg(obj->reg) & CMP_CHNF_MASK) << CMPDRV_CHANNEL_IN5) + | ((CmpReg_GetCh6fReg(obj->reg) & CMP_CHNF_MASK) << CMPDRV_CHANNEL_IN6) + | ((CmpReg_GetCh7fReg(obj->reg) & CMP_CHNF_MASK) << CMPDRV_CHANNEL_IN7); + return (tmp); +} + +void CmpDrv_ClearInputFlags(CmpDrvType *obj) +{ + CmpReg_ClearCh0fReg(obj->reg); + CmpReg_ClearCh1fReg(obj->reg); + CmpReg_ClearCh2fReg(obj->reg); + CmpReg_ClearCh3fReg(obj->reg); + CmpReg_ClearCh4fReg(obj->reg); + CmpReg_ClearCh5fReg(obj->reg); + CmpReg_ClearCh6fReg(obj->reg); + CmpReg_ClearCh7fReg(obj->reg); +} + +void CmpDrv_ConfigureDac(CmpDrvType *obj, const CmpDrv_DacCfgType *userConfig) +{ + /* Unclock CMP */ + CmpReg_UnlockReg(obj->reg); + + /* Disable CMP first */ + CmpReg_SetEnReg(obj->reg, false); + + /* Configuration of DAC */ + CmpReg_SetVrselReg(obj->reg, userConfig->dacVoltInSel); + CmpReg_SetVoselReg(obj->reg, userConfig->dacVoltScale); + CmpReg_SetDacenReg(obj->reg, userConfig->state); + + /* lock CMP */ + CmpReg_LockReg(obj->reg); + + /*! \note When enable CMP depend on user(use CmpDrv_SetCmpState for enable CMP)*/ +} + +void CmpDrv_GetDacConfig(const CmpDrvType *obj, CmpDrv_DacCfgType *userConfig) +{ + userConfig->dacVoltInSel = (CmpDrv_VrselType)(CmpReg_GetVrselReg(obj->reg)); + userConfig->dacVoltScale = CmpReg_GetVoselReg(obj->reg); + userConfig->state = CmpReg_GetDacenReg(obj->reg); +} + +void CmpDrv_ConfigureMux(CmpDrvType *obj, const CmpDrv_MuxCfgType *userConfig) +{ + /* Unclock CMP */ + CmpReg_UnlockReg(obj->reg); + + /* Disable CMP */ + CmpReg_SetEnReg(obj->reg, false); + + /* Configuration of analog mux */ + CmpReg_SetInpselReg(obj->reg, userConfig->posPortMux); + CmpReg_SetInnselReg(obj->reg, userConfig->negPortMux); + CmpReg_SetPselReg(obj->reg, userConfig->posInputMux); + CmpReg_SetMselReg(obj->reg, userConfig->negInputMux); + + /* lock CMP*/ + CmpReg_LockReg(obj->reg); + + /*! \note When enable CMP depend on user(use CmpDrv_SetCmpState for enable CMP)*/ +} + +void CmpDrv_GetMuxConfig(const CmpDrvType *obj, CmpDrv_MuxCfgType *userConfig) +{ + userConfig->posPortMux = (CmpDrv_InPortType)(CmpReg_GetInpselReg(obj->reg)); + userConfig->negPortMux = (CmpDrv_InPortType)(CmpReg_GetInnselReg(obj->reg)); + userConfig->posInputMux = (CmpDrv_ChSelType)(CmpReg_GetPselReg(obj->reg)); + userConfig->negInputMux = (CmpDrv_ChSelType)(CmpReg_GetMselReg(obj->reg)); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cmp/cmp_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cmp/cmp_drv.h new file mode 100644 index 0000000..c22bc0d --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cmp/cmp_drv.h @@ -0,0 +1,391 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CMP_DRV_H_ +#define _CMP_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of CMP module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup cmp_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + *******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief CMP type of comparator output invert selection + */ +typedef enum +{ + CMPDRV_INVT_NORMAL = 0U, /*!< Output signal isn't inverted */ + CMPDRV_INVT_INVERT = 1U, /*!< Output signal is inverted. */ +} CmpDrv_InvtType; + +/*! \brief CMP type of input channel low-pass filer cut-off frequency select signal + */ +typedef enum +{ + CMPDRV_LPFSEL_23MHz = 0U, /*!< 23MHz */ + CMPDRV_LPFSEL_16MHz = 1U, /*!< 16MHz */ + CMPDRV_LPFSEL_13MHz = 2U, /*!< 13MHz */ + CMPDRV_LPFSEL_10MHz = 3U, /*!< 10MHz */ +} CmpDrv_LpfselType; + +/*! \brief CMP type of power Mode + */ +typedef enum +{ + CMPDRV_PMODE_LS = 0U, /*!< Low Speed (LS) comparison mode is selected */ + CMPDRV_PMODE_HS = 1U, /*!< High Speed (HS) comparison mode is selected*/ +} CmpDrv_PmodeType; + +/*! \brief CMP type of comparator output + */ +typedef enum +{ + CMPDRV_COS_COUT = 0U, /*!< Set CMPO to equal COUT (filtered comparator output) */ + CMPDRV_COS_COUTA = 1U, /*!< Set CMPO to equal COUTA (unfiltered comparator output)*/ +} CmpDrv_CosType; + +/*! \brief CMP type of comparator hard block offset control + */ +typedef enum +{ + CMPDRV_OFFSET_LEVEL_0 = 0U, /*!< The comparator hard block output has level 0 offset internally*/ + CMPDRV_OFFSET_LEVEL_1 = 1U, /*!< The comparator hard block output has level 1 offset internally*/ +} CmpDrv_OffsetType; + +/*! \brief CMP type of hard block hysteresis control + */ +typedef enum +{ + CMPDRV_HYSTCTR_LEVEL_0 = 0U, /*!< The hard block output has level 0 hysteresis internally*/ + CMPDRV_HYSTCTR_LEVEL_1 = 1U, /*!< The hard block output has level 1 hysteresis internally*/ + CMPDRV_HYSTCTR_LEVEL_2 = 2U, /*!< The hard block output has level 2 hysteresis internally*/ + CMPDRV_HYSTCTR_LEVEL_3 = 3U, /*!< The hard block output has level 3 hysteresis internally*/ +} CmpDrv_HystctrType; + +/*! \brief CMP type of selection of the input to the positive or negative port of the comparator + */ +typedef enum +{ + CMPDRV_DAC = 0U, /*!< IN0, from the 8-bit DAC output*/ + CMPDRV_MUX = 1U, /*!< IN1, from the analog 8-1 mux(P/N MUX)*/ +} CmpDrv_InPortType; + +/*! \brief CMP type of channel selection. + */ +typedef enum +{ + CMPDRV_CHANNEL_IN0 = 0U, /*!< Select IN0 from the analog 8-1 mux */ + CMPDRV_CHANNEL_IN1 = 1U, /*!< Select IN1 from the analog 8-1 mux */ + CMPDRV_CHANNEL_IN2 = 2U, /*!< Select IN2 from the analog 8-1 mux */ + CMPDRV_CHANNEL_IN3 = 3U, /*!< Select IN3 from the analog 8-1 mux */ + CMPDRV_CHANNEL_IN4 = 4U, /*!< Select IN4 from the analog 8-1 mux */ + CMPDRV_CHANNEL_IN5 = 5U, /*!< Select IN5 from the analog 8-1 mux */ + CMPDRV_CHANNEL_IN6 = 6U, /*!< Select IN6 from the analog 8-1 mux */ + CMPDRV_CHANNEL_IN7 = 7U, /*!< Select IN7 from the analog 8-1 mux */ +} CmpDrv_ChSelType; + +/*! \brief CMP type of supply voltage reference source + */ +typedef enum +{ + CMPDRV_VRSEL_VIN1 = 0U, /*!< Vin1 is selected as resistor ladder network supply reference Vin*/ + CMPDRV_VRSEL_VIN2 = 1U, /*!< Vin2 is selected as resistor ladder network supply reference Vin*/ +} CmpDrv_VrselType; + +/*! \brief CMP type of fix the analog mux port for the round-robin mode + */ +typedef enum +{ + CMPDRV_FXMP_PLUS = 0U, /*!< The Plus port is fixed. Only the inputs to the Minus port are swept in each round*/ + CMPDRV_FXMP_MINUS = 1U, /*!< The Minus port is fixed. Only the inputs to the Plus port are swept in each round*/ +} CmpDrv_FxmpType; + +/*! \brief CMP type of output interrupt configuration + */ +typedef enum +{ + CMP_NO_EVENT = 0U, /*!< Comparator output interrupts are disabled OR no event occurred. */ + CMP_FALLING_EDGE = 1U, /*!< Comparator output interrupts will be generated only on falling edge OR only falling edge event occurred. */ + CMP_RISING_EDGE = 2U, /*!< Comparator output interrupts will be generated only on rising edge OR only rising edge event occurred. */ + CMP_BOTH_EDGES = 3U, /*!< Comparator output interrupts will be generated on both edges OR both edges event occurred. */ +} CmpDrv_TriggerType; + +/*! \brief CMP type of functional modes + */ +typedef enum +{ + CMP_DISABLED = 0U, /*!< CMP is disabled */ + CMP_CONTINUOUS = 1U, /*!< Continuous mode */ + CMP_SAMPLED_NONFILTRED_INT_CLK = 2U, /*!< Sampled, Non-Filtered mode with interior clock */ + CMP_SAMPLED_NONFILTRED_EXT_CLK = 3U, /*!< Sampled, Non-Filtered mode with exterior clock */ + CMP_SAMPLED_FILTRED_INT_CLK = 4U, /*!< Sampled, Filtered mode with interior clock */ + CMP_SAMPLED_FILTRED_EXT_CLK = 5U, /*!< Sampled, Filtered mode with exterior clock */ + CMP_WINDOWED = 6U, /*!< Windowed mode */ + CMP_WINDOWED_RESAMPLED = 7U, /*!< Windowed/Resampled mode */ + CMP_WINDOWED_FILTRED = 8U, /*!< Windowed/Filtered mode */ +} CmpDrv_ModeType; + +/*! \brief Definition of configuration of CMP driver in normal modes + */ +typedef struct _CmpDrv_NormalCfgType_ +{ + bool dmaEnable; /*!< Enables the DMA transfer triggered from the CMP module*/ + CmpDrv_TriggerType triggerMode; /*!< Interrupt configuration*/ + CmpDrv_ModeType mode; /*!< The comparator functional mode*/ + uint8_t filterSamplePeriod; /*!< Filter sample period */ + uint8_t filterSampleCount; /*!< Number of sample count for filtering */ + CmpDrv_PmodeType powerMode; /*!< Power mode select */ + CmpDrv_InvtType inverterState; /*!< Comparator invert */ + bool pinState; /*!< Comparator output pin enable */ + CmpDrv_CosType outputSelect; /*!< Comparator output select */ + CmpDrv_HystctrType hystLvl; /*!< Comparator hard block hysteresis control */ + CmpDrv_OffsetType hystOffsetState; /*!< Comparator hard block offset control */ + CmpDrv_LpfselType lpfsel; /*!< CMP input channel low-pass filer cut-off frequency select signal */ +} CmpDrv_NormalCfgType; + +/*! \brief Definition of configuration of CMP driver of the analog mux + */ +typedef struct _CmpDrv_MuxCfgType_ +{ + CmpDrv_InPortType posPortMux; /*!< Select positive port signal*/ + CmpDrv_InPortType negPortMux; /*!< Select negative port signal*/ + CmpDrv_ChSelType posInputMux; /*!< Select which channel is selected for the plus mux*/ + CmpDrv_ChSelType negInputMux; /*!< Select which channel is selected for the minus mux*/ +} CmpDrv_MuxCfgType; + +/*! \brief Definition of configuration of CMP driver in round robin modes + */ +typedef struct _CmpDrv_RoundRobinCfgType_ +{ + bool intrEnable; /*!< Round - Robin interrupt enable*/ + CmpDrv_FxmpType fixedMuxPort; /*!< Fixed the analog mux port for the round-robin mode*/ + CmpDrv_ChSelType fixedChnSel; /*!< Select channel in the mux port is fixed in a given round-robin mode*/ + uint8_t sampleCnt; /*!< Select number of round-robin clock cycles for a given channel*/ + uint8_t initDelayCnt; /*!< Comparator and DAC initialization delay modulus*/ + uint8_t channelState; /*!< One bit for each channel state*/ + /*!< |---------|---------|-----|---------|---------|*/ + /*!< |CH7_state|CH6_state|.....|CH1_state|CH0_state|*/ + /*!< |---------|---------|-----|---------|---------|*/ + uint8_t channelPreState; /*!< One bit for each channel pre-set state*/ +} CmpDrv_RoundRobinCfgType; + +/*! \brief Definition of configuration of DAC + */ +typedef struct _CmpDrv_DacCfgType_ +{ + CmpDrv_VrselType dacVoltInSel; /*!< Supply Voltage Reference Source Select*/ + uint8_t dacVoltScale; /*!< DAC Output Voltage Select*/ + bool state; /*!< DAC Enable*/ +} CmpDrv_DacCfgType; + +/*! \brief Definition of configuration of CMP driver + */ +typedef struct _CmpDrv_ConfigType_ +{ + CmpDrv_NormalCfgType normalCfg; + CmpDrv_RoundRobinCfgType rrCfg; + CmpDrv_DacCfgType dacCfg; + CmpDrv_MuxCfgType muxCfg; +} CmpDrv_ConfigType; + +/* Forward declaration of CMP register */ +struct _CmpRegType_; + +/*! \brief The definition of CMP driver class + */ +typedef struct _CmpDrvType_ +{ + struct _CmpRegType_ *reg; +} CmpDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the CMP driver module + * + * This function initializes CMP driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to CMP driver instance + * \param[in] reg : pointer to CMP register instance + */ +extern void CmpDrv_Init(CmpDrvType *obj, struct _CmpRegType_ *reg); + +/*! \brief Configures the CMP normal module from a user configuration structure + * + * This function configures the CMP normal module from a user configuration structure + * + * \param[in] obj : pointer to CMP driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void CmpDrv_ConfigureNormal(CmpDrvType *obj, const CmpDrv_ConfigType *userConfig); + +/*! \brief Configures the CMP round robin module from a user configuration structure + * + * This function configures the CMP round robin module from a user configuration structure + * + * \param[in] obj : pointer to CMP driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void CmpDrv_ConfigureTriggerMode(CmpDrvType *obj, const CmpDrv_ConfigType *userConfig); + +/*! \brief Get configures of the CMP module currently + * + * This function gets configures of the CMP module currently + * + * \param[in] obj : pointer to CMP driver instance + * \param[out] userConfig : pointer to configuration structure + */ +extern void CmpDrv_GetConfig(const CmpDrvType *obj, CmpDrv_ConfigType *userConfig); + +/*! \brief Get default configures the CMP module for configuration structure + * + * This function gets default configures the CMP module for user configuration structure + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void CmpDrv_GetDefaultConfig(CmpDrv_ConfigType *userConfig); + +/*! \brief Set state for CMP + * + * This function for enable or disable CMP + * + * \param[in] obj : pointer to CMP driver instance + * \param[in] state : state for CMP + */ +extern void CmpDrv_SetCmpState(CmpDrvType *obj, const bool state); + +/*! \brief Get state from CMP + * + * This function for get state from CMP + * + * \param[in] obj : pointer to CMP driver instance + * \param[out] bool : CMP current state + */ +extern bool CmpDrv_GetCmpState(const CmpDrvType *obj); + +/*! \brief Get CMP output flags + * + * This function for get CMP output flags + * + * \param[in] obj : pointer to CMP driver instance + * \param[out] CmpDrv_TriggerType : CMP current output flags + */ +extern CmpDrv_TriggerType CmpDrv_GetOutputFlags(const CmpDrvType *obj); + +/*! \brief Clear CMP output flags + * + * This function for clear CMP output flags + * + * \param[in] obj : pointer to CMP driver instance + */ +extern void CmpDrv_ClearOutputFlags(CmpDrvType *obj); + +/*! \brief Clear CMP input flags + * + * This function for clear CMP input flags + * + * \param[in] obj : pointer to CMP driver instance + */ +extern void CmpDrv_ClearInputFlags(CmpDrvType *obj); + +/*! \brief Get CMP input flags + * + * This function for get CMP input flags + * + * \param[in] obj : pointer to CMP driver instance + * \param[out] uint8_t : CMP input flags + */ +extern uint8_t CmpDrv_GetInputFlags(const CmpDrvType *obj); + +/*! \brief Configures the CMP DAC from a user configuration structure + * + * This function configures the CMP DAC from a user configuration structure + * + * \param[in] obj : pointer to CMP driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void CmpDrv_ConfigureDac(CmpDrvType *obj, const CmpDrv_DacCfgType *userConfig); + +/*! \brief Get configuration the CMP DAC from a user configuration structure + * + * This function configures the CMP DAC from a user configuration structure + * + * \param[in] obj : pointer to CMP driver instance + * \param[out] userConfig : pointer to configuration structure + */ +extern void CmpDrv_GetDacConfig(const CmpDrvType *obj, CmpDrv_DacCfgType *userConfig); + +/*! \brief Configures the CMP analog mux from a user configuration structure + * + * This function configures the CMP analog mux from a user configuration structure + * + * \param[in] obj : pointer to CMP driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void CmpDrv_ConfigureMux(CmpDrvType *obj, const CmpDrv_MuxCfgType *userConfig); + +/*! \brief Get configuration the CMP analog mux from a user configuration structure + * + * This function configures the CMP analog mux from a user configuration structure + * + * \param[in] obj : pointer to CMP driver instance + * \param[out] userConfig : pointer to configuration structure + */ +extern void CmpDrv_GetMuxConfig(const CmpDrvType *obj, CmpDrv_MuxCfgType *userConfig); + +/*! \brief Configures the CMP ACO from a user configuration structure + * + * This function configures the CMP ACO from a user configuration structure + * + * \param[in] obj : pointer to CMP driver instance + * \param[in] channelPreState : defines the pre-set state of channel n. + */ +extern void CmpDrv_SetChannelPreState(CmpDrvType *obj, const uint8_t channelPreState); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _CMP_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cmu/cmu_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cmu/cmu_drv.c new file mode 100644 index 0000000..e4aa971 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cmu/cmu_drv.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "cmu_drv.h" +#include "cmu_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void CmuDrv_Init(CmuDrvType *obj, struct _CmuRegType_ *reg) +{ + obj->reg = reg; +} + +void CmuDrv_Configure(CmuDrvType *obj, const CmuDrv_ConfigType *userConfig) +{ + /* Set referency frequency cnt */ + CmuReg_SetRefCnt(obj->reg, userConfig->refClkCnt); + /* Set the high threshold value */ + CmuReg_SetFreqHighRefValue(obj->reg, userConfig->highRefFreq); + /* Set the low threshold value */ + CmuReg_SetFreqLowRefValue(obj->reg, userConfig->lowRefFreq); + /* Set high event state */ + CmuReg_SetFreqHighEventState(obj->reg, (uint8_t)userConfig->highFreqEventSt); + /* Set low event state */ + CmuReg_SetFreqLowEventState(obj->reg, (uint8_t)userConfig->lowFreqEventSt); +} + +void CmuDrv_GetConfig(const CmuDrvType *obj, CmuDrv_ConfigType *userConfig) +{ + /* Get referency frequency cnt */ + userConfig->refClkCnt = CmuReg_GetRefCnt(obj->reg); + /* Get the high threshold value */ + userConfig->highRefFreq = CmuReg_GetFreqHighRefValue(obj->reg); + /* Get the low threshold value */ + userConfig->lowRefFreq = CmuReg_GetFreqLowRefValue(obj->reg); + /* Get high event state */ + userConfig->highFreqEventSt = (CmuDrv_EventStateType)CmuReg_GetFreqHighEventState(obj->reg); + /* Get low event state */ + userConfig->lowFreqEventSt = (CmuDrv_EventStateType)CmuReg_GetFreqLowEventState(obj->reg); +} + +void CmuDrv_GetDefaultConfig(CmuDrv_ConfigType *userConfig) +{ + /* Get referency frequency cnt */ + userConfig->refClkCnt = 0U; + /* Get the high threshold value */ + userConfig->highRefFreq = 0U; + /* Get the low threshold value */ + userConfig->lowRefFreq = 0U; + /* Get high event state */ + userConfig->highFreqEventSt = CMUDRV_DISABLE_INT_AND_RST; + /* Get low event state */ + userConfig->lowFreqEventSt = CMUDRV_DISABLE_INT_AND_RST; +} + +bool CmuDrv_IsFreqCheckEnable(const CmuDrvType *obj) +{ + /* Get CMU enable state */ + return (bool)(CmuReg_GetEnable(obj->reg)); +} + +void CmuDrv_EnableFreqCheck(const CmuDrvType *obj, bool enable) +{ + /* Set CMU enable state */ + CmuReg_SetEnable(obj->reg, enable); +} + +bool CmuDrv_IsCmuRun(const CmuDrvType *obj) +{ + /* Get CMU run state */ + return (bool)(CmuReg_GetRunStatus(obj->reg)); +} + +bool CmuDrv_IsFreqHighEventAcvt(const CmuDrvType *obj) +{ + /* Get the frequency high event flag */ + return (bool)(CmuReg_GetFreqHighEventFlag(obj->reg)); +} + +void CmuDrv_ClearFreqHighEventFlag(CmuDrvType *obj) +{ + /* Clear the frequency high event flag */ + CmuReg_ClearFreqHighEventFlag(obj->reg); +} + +bool CmuDrv_IsFreqLowEventAcvt(const CmuDrvType *obj) +{ + /* Get the frequency low event flag */ + return (bool)(CmuReg_GetFreqLowEventFlag(obj->reg)); +} + +void CmuDrv_ClearFreqLowEventFlag(CmuDrvType *obj) +{ + /* Clear the frequency low event flag */ + CmuReg_ClearFreqLowEventFlag(obj->reg); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cmu/cmu_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cmu/cmu_drv.h new file mode 100644 index 0000000..7373e7e --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cmu/cmu_drv.h @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CMU_DRV_H_ +#define _CMU_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of CMU module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup cmu_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief CMU type of interrupt or reset enable + */ +typedef enum +{ + CMUDRV_DISABLE_INT_AND_RST = 0, /*!< disable interrupt, disable reset */ + CMUDRV_ENABLE_INT_DISABLE_RST = 1, /*!< enable interrupt, disable reset */ + CMUDRV_DISABLE_INT_ENABLE_RST = 2, /*!< disable interrupt, enable reset */ +} CmuDrv_EventStateType; + +/*! \brief Definition of configuration of CMU driver + */ +typedef struct _CmuDrv_ConfigType_ +{ + uint32_t refClkCnt; /*!< Reference frequency cnt Max Value. */ + uint32_t highRefFreq; /*!< high frequency threshod value. */ + uint32_t lowRefFreq; /*!< low frequency threshod value. */ + CmuDrv_EventStateType highFreqEventSt; /*!< State of high interrupt or reset enable. */ + CmuDrv_EventStateType lowFreqEventSt; /*!< State of low interrupt or reset enable. */ +} CmuDrv_ConfigType; + +/* Forward declaration of CMU register */ +struct _CmuRegType_; + +/*! \brief The definition of CMU driver class + */ +typedef struct _CmuDrvType_ +{ + struct _CmuRegType_ *reg; +} CmuDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the CMU driver module + * + * This function initializes CMU driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to CMU driver instance + * \param[in] reg : pointer to CMU register instance + */ +extern void CmuDrv_Init(CmuDrvType *obj, struct _CmuRegType_ *reg); + +/*! \brief Configures the CMU module from a user configuration structure + * + * This function configures the CMU module from a user configuration structure + * + * \param[in] obj : pointer to CMU driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void CmuDrv_Configure(CmuDrvType *obj, const CmuDrv_ConfigType *userConfig); + +/*! \brief Get configures of the CMU module currently + * + * This function gets configures of the CMU module currently + * + * \param[in] obj : pointer to CMU driver instance + * \param[out] userConfig : pointer to configuration structure + */ +extern void CmuDrv_GetConfig(const CmuDrvType *obj, CmuDrv_ConfigType *userConfig); + +/*! \brief Get default configures the CMU module for configuration structure + * + * This function gets default configures the CMU module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void CmuDrv_GetDefaultConfig(CmuDrv_ConfigType *userConfig); + +/*! \brief Get the state of frequency check enable + * + * This function gets the state of frequency check enable + * + * \param[in] obj : pointer to CMU driver instance + * \return state of frequency check enable + */ +extern bool CmuDrv_IsFreqCheckEnable(const CmuDrvType *obj); + +/*! \brief Set the state of frequency check enable + * + * This function sets the state of frequency check enable + * + * \param[in] obj : pointer to frequency check driver instance + * \param[in] state of CMU enable + */ +extern void CmuDrv_EnableFreqCheck(const CmuDrvType *obj, bool enable); + +/*! \brief Get the state of CMU run + * + * This function gets the state of CMU run + * + * \param[in] obj : pointer to CMU driver instance + * \return state of CMU run + */ +extern bool CmuDrv_IsCmuRun(const CmuDrvType *obj); + +/*! \brief Get the flag of frequency high + * + * This function gets the flag of frequency high + * + * \param[in] obj : pointer to CMU driver instance + * \return the flag of frequency high + */ +extern bool CmuDrv_IsFreqHighEventAcvt(const CmuDrvType *obj); + +/*! \brief Clear the flag of frequency high + * + * This function clears the flag of frequency high + * + * \param[in] obj : pointer to CMU driver instance + * \return none + */ +extern void CmuDrv_ClearFreqHighEventFlag(CmuDrvType *obj); + +/*! \brief Get the flag of frequency low + * + * This function gets the flag of frequency low + * + * \param[in] obj : pointer to CMU driver instance + * \return the flag of frequency low + */ +extern bool CmuDrv_IsFreqLowEventAcvt(const CmuDrvType *obj); + +/*! \brief Clear the flag of frequency low + * + * This function clears the flag of frequency low + * + * \param[in] obj : pointer to CMU driver instance + * \return none + */ +extern void CmuDrv_ClearFreqLowEventFlag(CmuDrvType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _CMU_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/arm_common_tables.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/arm_common_tables.h new file mode 100644 index 0000000..8742a56 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/arm_common_tables.h @@ -0,0 +1,136 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2014 ARM Limited. All rights reserved. +* +* $Date: 19. October 2015 +* $Revision: V.1.4.5 a +* +* Project: CMSIS DSP Library +* Title: arm_common_tables.h +* +* Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions +* +* Target Processor: Cortex-M4/Cortex-M3 +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* - Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* - Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* - Neither the name of ARM LIMITED nor the names of its contributors +* may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* -------------------------------------------------------------------- */ + +#ifndef _ARM_COMMON_TABLES_H +#define _ARM_COMMON_TABLES_H + +#include "arm_math.h" + +extern const uint16_t armBitRevTable[1024]; +extern const q15_t armRecipTableQ15[64]; +extern const q31_t armRecipTableQ31[64]; +/* extern const q31_t realCoefAQ31[1024]; */ +/* extern const q31_t realCoefBQ31[1024]; */ +extern const float32_t twiddleCoef_16[32]; +extern const float32_t twiddleCoef_32[64]; +extern const float32_t twiddleCoef_64[128]; +extern const float32_t twiddleCoef_128[256]; +extern const float32_t twiddleCoef_256[512]; +extern const float32_t twiddleCoef_512[1024]; +extern const float32_t twiddleCoef_1024[2048]; +extern const float32_t twiddleCoef_2048[4096]; +extern const float32_t twiddleCoef_4096[8192]; +#define twiddleCoef twiddleCoef_4096 +extern const q31_t twiddleCoef_16_q31[24]; +extern const q31_t twiddleCoef_32_q31[48]; +extern const q31_t twiddleCoef_64_q31[96]; +extern const q31_t twiddleCoef_128_q31[192]; +extern const q31_t twiddleCoef_256_q31[384]; +extern const q31_t twiddleCoef_512_q31[768]; +extern const q31_t twiddleCoef_1024_q31[1536]; +extern const q31_t twiddleCoef_2048_q31[3072]; +extern const q31_t twiddleCoef_4096_q31[6144]; +extern const q15_t twiddleCoef_16_q15[24]; +extern const q15_t twiddleCoef_32_q15[48]; +extern const q15_t twiddleCoef_64_q15[96]; +extern const q15_t twiddleCoef_128_q15[192]; +extern const q15_t twiddleCoef_256_q15[384]; +extern const q15_t twiddleCoef_512_q15[768]; +extern const q15_t twiddleCoef_1024_q15[1536]; +extern const q15_t twiddleCoef_2048_q15[3072]; +extern const q15_t twiddleCoef_4096_q15[6144]; +extern const float32_t twiddleCoef_rfft_32[32]; +extern const float32_t twiddleCoef_rfft_64[64]; +extern const float32_t twiddleCoef_rfft_128[128]; +extern const float32_t twiddleCoef_rfft_256[256]; +extern const float32_t twiddleCoef_rfft_512[512]; +extern const float32_t twiddleCoef_rfft_1024[1024]; +extern const float32_t twiddleCoef_rfft_2048[2048]; +extern const float32_t twiddleCoef_rfft_4096[4096]; + + +/* floating-point bit reversal tables */ +#define ARMBITREVINDEXTABLE__16_TABLE_LENGTH ((uint16_t)20 ) +#define ARMBITREVINDEXTABLE__32_TABLE_LENGTH ((uint16_t)48 ) +#define ARMBITREVINDEXTABLE__64_TABLE_LENGTH ((uint16_t)56 ) +#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208 ) +#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440 ) +#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448 ) +#define ARMBITREVINDEXTABLE1024_TABLE_LENGTH ((uint16_t)1800) +#define ARMBITREVINDEXTABLE2048_TABLE_LENGTH ((uint16_t)3808) +#define ARMBITREVINDEXTABLE4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE__16_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE__32_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE__64_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE1024_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE2048_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE4096_TABLE_LENGTH]; + +/* fixed-point bit reversal tables */ +#define ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH ((uint16_t)12 ) +#define ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH ((uint16_t)24 ) +#define ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH ((uint16_t)56 ) +#define ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH ((uint16_t)112 ) +#define ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH ((uint16_t)240 ) +#define ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH ((uint16_t)480 ) +#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992 ) +#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984) +#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH]; + +/* Tables for Fast Math Sine and Cosine */ +extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1]; +extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1]; +extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1]; + +#endif /* ARM_COMMON_TABLES_H */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/arm_const_structs.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/arm_const_structs.h new file mode 100644 index 0000000..726d06e --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/arm_const_structs.h @@ -0,0 +1,79 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2014 ARM Limited. All rights reserved. +* +* $Date: 19. March 2015 +* $Revision: V.1.4.5 +* +* Project: CMSIS DSP Library +* Title: arm_const_structs.h +* +* Description: This file has constant structs that are initialized for +* user convenience. For example, some can be given as +* arguments to the arm_cfft_f32() function. +* +* Target Processor: Cortex-M4/Cortex-M3 +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* - Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* - Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* - Neither the name of ARM LIMITED nor the names of its contributors +* may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* -------------------------------------------------------------------- */ + +#ifndef _ARM_CONST_STRUCTS_H +#define _ARM_CONST_STRUCTS_H + +#include "arm_math.h" +#include "arm_common_tables.h" + + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096; + + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096; + + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096; + +#endif diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/arm_math.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/arm_math.h new file mode 100644 index 0000000..d33f8a9 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/arm_math.h @@ -0,0 +1,7154 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2015 ARM Limited. All rights reserved. +* +* $Date: 20. October 2015 +* $Revision: V1.4.5 b +* +* Project: CMSIS DSP Library +* Title: arm_math.h +* +* Description: Public header file for CMSIS DSP Library +* +* Target Processor: Cortex-M7/Cortex-M4/Cortex-M3/Cortex-M0 +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* - Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* - Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* - Neither the name of ARM LIMITED nor the names of its contributors +* may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. + * -------------------------------------------------------------------- */ + +/** + \mainpage CMSIS DSP Software Library + * + * Introduction + * ------------ + * + * This user manual describes the CMSIS DSP software library, + * a suite of common signal processing functions for use on Cortex-M processor based devices. + * + * The library is divided into a number of functions each covering a specific category: + * - Basic math functions + * - Fast math functions + * - Complex math functions + * - Filters + * - Matrix functions + * - Transforms + * - Motor control functions + * - Statistical functions + * - Support functions + * - Interpolation functions + * + * The library has separate functions for operating on 8-bit integers, 16-bit integers, + * 32-bit integer and 32-bit floating-point values. + * + * Using the Library + * ------------ + * + * The library installer contains prebuilt versions of the libraries in the Lib folder. + * - arm_cortexM7lfdp_math.lib (Little endian and Double Precision Floating Point Unit on Cortex-M7) + * - arm_cortexM7bfdp_math.lib (Big endian and Double Precision Floating Point Unit on Cortex-M7) + * - arm_cortexM7lfsp_math.lib (Little endian and Single Precision Floating Point Unit on Cortex-M7) + * - arm_cortexM7bfsp_math.lib (Big endian and Single Precision Floating Point Unit on Cortex-M7) + * - arm_cortexM7l_math.lib (Little endian on Cortex-M7) + * - arm_cortexM7b_math.lib (Big endian on Cortex-M7) + * - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4) + * - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4) + * - arm_cortexM4l_math.lib (Little endian on Cortex-M4) + * - arm_cortexM4b_math.lib (Big endian on Cortex-M4) + * - arm_cortexM3l_math.lib (Little endian on Cortex-M3) + * - arm_cortexM3b_math.lib (Big endian on Cortex-M3) + * - arm_cortexM0l_math.lib (Little endian on Cortex-M0 / CortexM0+) + * - arm_cortexM0b_math.lib (Big endian on Cortex-M0 / CortexM0+) + * + * The library functions are declared in the public file arm_math.h which is placed in the Include folder. + * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single + * public header file arm_math.h for Cortex-M7/M4/M3/M0/M0+ with little endian and big endian. Same header file will be used for floating point unit(FPU) variants. + * Define the appropriate pre processor MACRO ARM_MATH_CM7 or ARM_MATH_CM4 or ARM_MATH_CM3 or + * ARM_MATH_CM0 or ARM_MATH_CM0PLUS depending on the target processor in the application. + * + * Examples + * -------- + * + * The library ships with a number of examples which demonstrate how to use the library functions. + * + * Toolchain Support + * ------------ + * + * The library has been developed and tested with MDK-ARM version 5.14.0.0 + * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. + * + * Building the Library + * ------------ + * + * The library installer contains a project file to re build libraries on MDK-ARM Tool chain in the CMSIS\\DSP_Lib\\Source\\ARM folder. + * - arm_cortexM_math.uvprojx + * + * + * The libraries can be built by opening the arm_cortexM_math.uvprojx project in MDK-ARM, selecting a specific target, and defining the optional pre processor MACROs detailed above. + * + * Pre-processor Macros + * ------------ + * + * Each library project have differant pre-processor macros. + * + * - UNALIGNED_SUPPORT_DISABLE: + * + * Define macro UNALIGNED_SUPPORT_DISABLE, If the silicon does not support unaligned memory access + * + * - ARM_MATH_BIG_ENDIAN: + * + * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. + * + * - ARM_MATH_MATRIX_CHECK: + * + * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices + * + * - ARM_MATH_ROUNDING: + * + * Define macro ARM_MATH_ROUNDING for rounding on support functions + * + * - ARM_MATH_CMx: + * + * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target + * and ARM_MATH_CM0 for building library on Cortex-M0 target, ARM_MATH_CM0PLUS for building library on Cortex-M0+ target, and + * ARM_MATH_CM7 for building the library on cortex-M7. + * + * - __FPU_PRESENT: + * + * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for M4bf and M4lf libraries + * + *
+ * CMSIS-DSP in ARM::CMSIS Pack + * ----------------------------- + * + * The following files relevant to CMSIS-DSP are present in the ARM::CMSIS Pack directories: + * |File/Folder |Content | + * |------------------------------|------------------------------------------------------------------------| + * |\b CMSIS\\Documentation\\DSP | This documentation | + * |\b CMSIS\\DSP_Lib | Software license agreement (license.txt) | + * |\b CMSIS\\DSP_Lib\\Examples | Example projects demonstrating the usage of the library functions | + * |\b CMSIS\\DSP_Lib\\Source | Source files for rebuilding the library | + * + *
+ * Revision History of CMSIS-DSP + * ------------ + * Please refer to \ref ChangeLog_pg. + * + * Copyright Notice + * ------------ + * + * Copyright (C) 2010-2015 ARM Limited. All rights reserved. + */ + + +/** + * @defgroup groupMath Basic Math Functions + */ + +/** + * @defgroup groupFastMath Fast Math Functions + * This set of functions provides a fast approximation to sine, cosine, and square root. + * As compared to most of the other functions in the CMSIS math library, the fast math functions + * operate on individual values and not arrays. + * There are separate functions for Q15, Q31, and floating-point data. + * + */ + +/** + * @defgroup groupCmplxMath Complex Math Functions + * This set of functions operates on complex data vectors. + * The data in the complex arrays is stored in an interleaved fashion + * (real, imag, real, imag, ...). + * In the API functions, the number of samples in a complex array refers + * to the number of complex values; the array contains twice this number of + * real values. + */ + +/** + * @defgroup groupFilters Filtering Functions + */ + +/** + * @defgroup groupMatrix Matrix Functions + * + * This set of functions provides basic matrix math operations. + * The functions operate on matrix data structures. For example, + * the type + * definition for the floating-point matrix structure is shown + * below: + *
+ *     typedef struct
+ *     {
+ *       uint16_t numRows;     // number of rows of the matrix.
+ *       uint16_t numCols;     // number of columns of the matrix.
+ *       float32_t *pData;     // points to the data of the matrix.
+ *     } arm_matrix_instance_f32;
+ * 
+ * There are similar definitions for Q15 and Q31 data types. + * + * The structure specifies the size of the matrix and then points to + * an array of data. The array is of size numRows X numCols + * and the values are arranged in row order. That is, the + * matrix element (i, j) is stored at: + *
+ *     pData[i*numCols + j]
+ * 
+ * + * \par Init Functions + * There is an associated initialization function for each type of matrix + * data structure. + * The initialization function sets the values of the internal structure fields. + * Refer to the function arm_mat_init_f32(), arm_mat_init_q31() + * and arm_mat_init_q15() for floating-point, Q31 and Q15 types, respectively. + * + * \par + * Use of the initialization function is optional. However, if initialization function is used + * then the instance structure cannot be placed into a const data section. + * To place the instance structure in a const data + * section, manually initialize the data structure. For example: + *
+ * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
+ * 
+ * where nRows specifies the number of rows, nColumns + * specifies the number of columns, and pData points to the + * data array. + * + * \par Size Checking + * By default all of the matrix functions perform size checking on the input and + * output matrices. For example, the matrix addition function verifies that the + * two input matrices and the output matrix all have the same number of rows and + * columns. If the size check fails the functions return: + *
+ *     ARM_MATH_SIZE_MISMATCH
+ * 
+ * Otherwise the functions return + *
+ *     ARM_MATH_SUCCESS
+ * 
+ * There is some overhead associated with this matrix size checking. + * The matrix size checking is enabled via the \#define + *
+ *     ARM_MATH_MATRIX_CHECK
+ * 
+ * within the library project settings. By default this macro is defined + * and size checking is enabled. By changing the project settings and + * undefining this macro size checking is eliminated and the functions + * run a bit faster. With size checking disabled the functions always + * return ARM_MATH_SUCCESS. + */ + +/** + * @defgroup groupTransforms Transform Functions + */ + +/** + * @defgroup groupController Controller Functions + */ + +/** + * @defgroup groupStats Statistics Functions + */ +/** + * @defgroup groupSupport Support Functions + */ + +/** + * @defgroup groupInterpolation Interpolation Functions + * These functions perform 1- and 2-dimensional interpolation of data. + * Linear interpolation is used for 1-dimensional data and + * bilinear interpolation is used for 2-dimensional data. + */ + +/** + * @defgroup groupExamples Examples + */ +#ifndef _ARM_MATH_H +#define _ARM_MATH_H + +/* ignore some GCC warnings */ +#if defined ( __GNUC__ ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +#define __CMSIS_GENERIC /* disable NVIC and Systick functions */ + +#if defined(ARM_MATH_CM7) + #include "core_cm7.h" +#elif defined (ARM_MATH_CM4) + #include "core_cm4.h" +#elif defined (ARM_MATH_CM3) + #include "core_cm3.h" +#elif defined (ARM_MATH_CM0) + #include "core_cm0.h" + #define ARM_MATH_CM0_FAMILY +#elif defined (ARM_MATH_CM0PLUS) + #include "core_cm0plus.h" + #define ARM_MATH_CM0_FAMILY +#else + #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS or ARM_MATH_CM0" +#endif + +#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */ +#include "string.h" +#include "math.h" +#ifdef __cplusplus +extern "C" +{ +#endif + + + /** + * @brief Macros required for reciprocal calculation in Normalized LMS + */ + +#define DELTA_Q31 (0x100) +#define DELTA_Q15 0x5 +#define INDEX_MASK 0x0000003F +#ifndef PI +#define PI 3.14159265358979f +#endif + + /** + * @brief Macros required for SINE and COSINE Fast math approximations + */ + +#define FAST_MATH_TABLE_SIZE 512 +#define FAST_MATH_Q31_SHIFT (32 - 10) +#define FAST_MATH_Q15_SHIFT (16 - 10) +#define CONTROLLER_Q31_SHIFT (32 - 9) +#define TABLE_SIZE 256 +#define TABLE_SPACING_Q31 0x400000 +#define TABLE_SPACING_Q15 0x80 + + /** + * @brief Macros required for SINE and COSINE Controller functions + */ + /* 1.31(q31) Fixed value of 2/360 */ + /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ +#define INPUT_SPACING 0xB60B61 + + /** + * @brief Macro for Unaligned Support + */ +#ifndef UNALIGNED_SUPPORT_DISABLE + #define ALIGN4 +#else + #if defined (__GNUC__) + #define ALIGN4 __attribute__((aligned(4))) + #else + #define ALIGN4 __align(4) + #endif +#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */ + + /** + * @brief Error status returned by some functions in the library. + */ + + typedef enum + { + ARM_MATH_SUCCESS = 0, /**< No error */ + ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ + ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ + ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */ + ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ + ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */ + ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ + } arm_status; + + /** + * @brief 8-bit fractional data type in 1.7 format. + */ + typedef int8_t q7_t; + + /** + * @brief 16-bit fractional data type in 1.15 format. + */ + typedef int16_t q15_t; + + /** + * @brief 32-bit fractional data type in 1.31 format. + */ + typedef int32_t q31_t; + + /** + * @brief 64-bit fractional data type in 1.63 format. + */ + typedef int64_t q63_t; + + /** + * @brief 32-bit floating-point type definition. + */ + typedef float float32_t; + + /** + * @brief 64-bit floating-point type definition. + */ + typedef double float64_t; + + /** + * @brief definition to read/write two 16 bit values. + */ +#if defined __CC_ARM + #define __SIMD32_TYPE int32_t __packed + #define CMSIS_UNUSED __attribute__((unused)) + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED __attribute__((unused)) + +#elif defined __GNUC__ + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED __attribute__((unused)) + +#elif defined __ICCARM__ + #define __SIMD32_TYPE int32_t __packed + #define CMSIS_UNUSED + +#elif defined __CSMC__ + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED + +#elif defined __TASKING__ + #define __SIMD32_TYPE __unaligned int32_t + #define CMSIS_UNUSED + +#else + #error Unknown compiler +#endif + +#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) +#define __SIMD32_CONST(addr) ((__SIMD32_TYPE *)(addr)) +#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE *) (addr)) +#define __SIMD64(addr) (*(int64_t **) & (addr)) + +#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) + /** + * @brief definition to pack two 16 bit values. + */ +#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ + (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) +#define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ + (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) + +#endif + + + /** + * @brief definition to pack four 8 bit values. + */ +#ifndef ARM_MATH_BIG_ENDIAN + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) +#else + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) + +#endif + + + /** + * @brief Clips Q63 to Q31 values. + */ + static __INLINE q31_t clip_q63_to_q31( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; + } + + /** + * @brief Clips Q63 to Q15 values. + */ + static __INLINE q15_t clip_q63_to_q15( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); + } + + /** + * @brief Clips Q31 to Q7 values. + */ + static __INLINE q7_t clip_q31_to_q7( + q31_t x) + { + return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? + ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; + } + + /** + * @brief Clips Q31 to Q15 values. + */ + static __INLINE q15_t clip_q31_to_q15( + q31_t x) + { + return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? + ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; + } + + /** + * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. + */ + + static __INLINE q63_t mult32x64( + q63_t x, + q31_t y) + { + return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + + (((q63_t) (x >> 32) * y))); + } + +/* + #if defined (ARM_MATH_CM0_FAMILY) && defined ( __CC_ARM ) + #define __CLZ __clz + #endif + */ +/* note: function can be removed when all toolchain support __CLZ for Cortex-M0 */ +#if defined (ARM_MATH_CM0_FAMILY) && ((defined (__ICCARM__)) ) + static __INLINE uint32_t __CLZ( + q31_t data); + + static __INLINE uint32_t __CLZ( + q31_t data) + { + uint32_t count = 0; + uint32_t mask = 0x80000000; + + while((data & mask) == 0) + { + count += 1u; + mask = mask >> 1u; + } + + return (count); + } +#endif + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type. + */ + + static __INLINE uint32_t arm_recip_q31( + q31_t in, + q31_t * dst, + q31_t * pRecipTable) + { + q31_t out; + uint32_t tempVal; + uint32_t index, i; + uint32_t signBits; + + if(in > 0) + { + signBits = ((uint32_t) (__CLZ( in) - 1)); + } + else + { + signBits = ((uint32_t) (__CLZ(-in) - 1)); + } + + /* Convert input sample to 1.31 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 24); + index = (index & INDEX_MASK); + + /* 1.31 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0u; i < 2u; i++) + { + tempVal = (uint32_t) (((q63_t) in * out) >> 31); + tempVal = 0x7FFFFFFFu - tempVal; + /* 1.31 with exp 1 */ + /* out = (q31_t) (((q63_t) out * tempVal) >> 30); */ + out = clip_q63_to_q31(((q63_t) out * tempVal) >> 30); + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1u); + } + + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type. + */ + static __INLINE uint32_t arm_recip_q15( + q15_t in, + q15_t * dst, + q15_t * pRecipTable) + { + q15_t out = 0; + uint32_t tempVal = 0; + uint32_t index = 0, i = 0; + uint32_t signBits = 0; + + if(in > 0) + { + signBits = ((uint32_t)(__CLZ( in) - 17)); + } + else + { + signBits = ((uint32_t)(__CLZ(-in) - 17)); + } + + /* Convert input sample to 1.15 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 8); + index = (index & INDEX_MASK); + + /* 1.15 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0u; i < 2u; i++) + { + tempVal = (uint32_t) (((q31_t) in * out) >> 15); + tempVal = 0x7FFFu - tempVal; + /* 1.15 with exp 1 */ + out = (q15_t) (((q31_t) out * tempVal) >> 14); + /* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */ + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1); + } + + + /* + * @brief C custom defined intrinisic function for only M0 processors + */ +#if defined(ARM_MATH_CM0_FAMILY) + static __INLINE q31_t __SSAT( + q31_t x, + uint32_t y) + { + int32_t posMax, negMin; + uint32_t i; + + posMax = 1; + for (i = 0; i < (y - 1); i++) + { + posMax = posMax * 2; + } + + if(x > 0) + { + posMax = (posMax - 1); + + if(x > posMax) + { + x = posMax; + } + } + else + { + negMin = -posMax; + + if(x < negMin) + { + x = negMin; + } + } + return (x); + } +#endif /* end of ARM_MATH_CM0_FAMILY */ + + + /* + * @brief C custom defined intrinsic function for M3 and M0 processors + */ +#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) + + /* + * @brief C custom defined QADD8 for M3 and M0 processors + */ + static __INLINE uint32_t __QADD8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) + (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) + (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) + (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) + (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QSUB8 for M3 and M0 processors + */ + static __INLINE uint32_t __QSUB8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) - (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) - (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) - (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) - (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QADD16 for M3 and M0 processors + */ + static __INLINE uint32_t __QADD16( + uint32_t x, + uint32_t y) + { +/* q31_t r, s; without initialisation 'arm_offset_q15 test' fails but 'intrinsic' tests pass! for armCC */ + q31_t r = 0, s = 0; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHADD16 for M3 and M0 processors + */ + static __INLINE uint32_t __SHADD16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSUB16 for M3 and M0 processors + */ + static __INLINE uint32_t __QSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSUB16 for M3 and M0 processors + */ + static __INLINE uint32_t __SHSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QASX for M3 and M0 processors + */ + static __INLINE uint32_t __QASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHASX for M3 and M0 processors + */ + static __INLINE uint32_t __SHASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSAX for M3 and M0 processors + */ + static __INLINE uint32_t __QSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSAX for M3 and M0 processors + */ + static __INLINE uint32_t __SHSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SMUSDX for M3 and M0 processors + */ + static __INLINE uint32_t __SMUSDX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + /* + * @brief C custom defined SMUADX for M3 and M0 processors + */ + static __INLINE uint32_t __SMUADX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + + /* + * @brief C custom defined QADD for M3 and M0 processors + */ + static __INLINE int32_t __QADD( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x + (q31_t)y))); + } + + + /* + * @brief C custom defined QSUB for M3 and M0 processors + */ + static __INLINE int32_t __QSUB( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x - (q31_t)y))); + } + + + /* + * @brief C custom defined SMLAD for M3 and M0 processors + */ + static __INLINE uint32_t __SMLAD( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLADX for M3 and M0 processors + */ + static __INLINE uint32_t __SMLADX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLSDX for M3 and M0 processors + */ + static __INLINE uint32_t __SMLSDX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALD for M3 and M0 processors + */ + static __INLINE uint64_t __SMLALD( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + ((q15_t) x * (q15_t) y)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALDX for M3 and M0 processors + */ + static __INLINE uint64_t __SMLALDX( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + ((q15_t) x * (q15_t) (y >> 16)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMUAD for M3 and M0 processors + */ + static __INLINE uint32_t __SMUAD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SMUSD for M3 and M0 processors + */ + static __INLINE uint32_t __SMUSD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SXTB16 for M3 and M0 processors + */ + static __INLINE uint32_t __SXTB16( + uint32_t x) + { + return ((uint32_t)(((((q31_t)x << 24) >> 24) & (q31_t)0x0000FFFF) | + ((((q31_t)x << 8) >> 8) & (q31_t)0xFFFF0000) )); + } + +#endif /* defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ + + + /** + * @brief Instance structure for the Q7 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q7; + + /** + * @brief Instance structure for the Q15 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_f32; + + + /** + * @brief Processing function for the Q7 FIR filter. + * @param[in] S points to an instance of the Q7 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q7( + const arm_fir_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 FIR filter. + * @param[in,out] S points to an instance of the Q7 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed. + */ + void arm_fir_init_q7( + arm_fir_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR filter. + * @param[in] S points to an instance of the Q15 FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR filter. + * @param[in,out] S points to an instance of the Q15 FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if + * numTaps is not a supported value. + */ + arm_status arm_fir_init_q15( + arm_fir_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR filter. + * @param[in] S points to an instance of the Q31 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR filter. + * @param[in,out] S points to an instance of the Q31 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_q31( + arm_fir_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR filter. + * @param[in] S points to an instance of the floating-point FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_f32( + const arm_fir_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR filter. + * @param[in,out] S points to an instance of the floating-point FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_f32( + arm_fir_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 Biquad cascade filter. + */ + typedef struct + { + int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q15; + + /** + * @brief Instance structure for the Q31 Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q31; + + /** + * @brief Instance structure for the floating-point Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_casd_df1_inst_f32; + + + /** + * @brief Processing function for the Q15 Biquad cascade filter. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q15( + arm_biquad_casd_df1_inst_q15 * S, + uint8_t numStages, + q15_t * pCoeffs, + q15_t * pState, + int8_t postShift); + + + /** + * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 Biquad cascade filter + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q31( + arm_biquad_casd_df1_inst_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q31_t * pState, + int8_t postShift); + + + /** + * @brief Processing function for the floating-point Biquad cascade filter. + * @param[in] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_f32( + const arm_biquad_casd_df1_inst_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point Biquad cascade filter. + * @param[in,out] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df1_init_f32( + arm_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float32_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f32; + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float64_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f64; + + /** + * @brief Instance structure for the Q15 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q15_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q15; + + /** + * @brief Instance structure for the Q31 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q31_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q31; + + + /** + * @brief Floating-point matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pScratch); + + + /** + * @brief Q31, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_f32( + const arm_matrix_instance_f32 * pSrc, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_q15( + const arm_matrix_instance_q15 * pSrc, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_q31( + const arm_matrix_instance_q31 * pSrc, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + + /** + * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_fast_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + + /** + * @brief Q31 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_fast_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix scaling. + * @param[in] pSrc points to the input matrix + * @param[in] scale scale factor + * @param[out] pDst points to the output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_f32( + const arm_matrix_instance_f32 * pSrc, + float32_t scale, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_q15( + const arm_matrix_instance_q15 * pSrc, + q15_t scaleFract, + int32_t shift, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_q31( + const arm_matrix_instance_q31 * pSrc, + q31_t scaleFract, + int32_t shift, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Q31 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_q31( + arm_matrix_instance_q31 * S, + uint16_t nRows, + uint16_t nColumns, + q31_t * pData); + + + /** + * @brief Q15 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_q15( + arm_matrix_instance_q15 * S, + uint16_t nRows, + uint16_t nColumns, + q15_t * pData); + + + /** + * @brief Floating-point matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_f32( + arm_matrix_instance_f32 * S, + uint16_t nRows, + uint16_t nColumns, + float32_t * pData); + + + + /** + * @brief Instance structure for the Q15 PID Control. + */ + typedef struct + { + q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ +#ifdef ARM_MATH_CM0_FAMILY + q15_t A1; + q15_t A2; +#else + q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/ +#endif + q15_t state[3]; /**< The state array of length 3. */ + q15_t Kp; /**< The proportional gain. */ + q15_t Ki; /**< The integral gain. */ + q15_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q15; + + /** + * @brief Instance structure for the Q31 PID Control. + */ + typedef struct + { + q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + q31_t A2; /**< The derived gain, A2 = Kd . */ + q31_t state[3]; /**< The state array of length 3. */ + q31_t Kp; /**< The proportional gain. */ + q31_t Ki; /**< The integral gain. */ + q31_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q31; + + /** + * @brief Instance structure for the floating-point PID Control. + */ + typedef struct + { + float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + float32_t A2; /**< The derived gain, A2 = Kd . */ + float32_t state[3]; /**< The state array of length 3. */ + float32_t Kp; /**< The proportional gain. */ + float32_t Ki; /**< The integral gain. */ + float32_t Kd; /**< The derivative gain. */ + } arm_pid_instance_f32; + + + + /** + * @brief Initialization function for the floating-point PID Control. + * @param[in,out] S points to an instance of the PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_f32( + arm_pid_instance_f32 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + */ + void arm_pid_reset_f32( + arm_pid_instance_f32 * S); + + + /** + * @brief Initialization function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q31( + arm_pid_instance_q31 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q31 PID Control structure + */ + + void arm_pid_reset_q31( + arm_pid_instance_q31 * S); + + + /** + * @brief Initialization function for the Q15 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q15( + arm_pid_instance_q15 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q15 PID Control. + * @param[in,out] S points to an instance of the q15 PID Control structure + */ + void arm_pid_reset_q15( + arm_pid_instance_q15 * S); + + + /** + * @brief Instance structure for the floating-point Linear Interpolate function. + */ + typedef struct + { + uint32_t nValues; /**< nValues */ + float32_t x1; /**< x1 */ + float32_t xSpacing; /**< xSpacing */ + float32_t *pYData; /**< pointer to the table of Y values */ + } arm_linear_interp_instance_f32; + + /** + * @brief Instance structure for the floating-point bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + float32_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_f32; + + /** + * @brief Instance structure for the Q31 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q31_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q31; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q15_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q15; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q7_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q7; + + + /** + * @brief Q7 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q15( + arm_cfft_radix2_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q15( + const arm_cfft_radix2_instance_q15 * S, + q15_t * pSrc); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q15( + arm_cfft_radix4_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_q15( + const arm_cfft_radix4_instance_q15 * S, + q15_t * pSrc); + + /** + * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q31; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q31( + arm_cfft_radix2_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q31( + const arm_cfft_radix2_instance_q31 * S, + q31_t * pSrc); + + /** + * @brief Instance structure for the Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q31; + +/* Deprecated */ + void arm_cfft_radix4_q31( + const arm_cfft_radix4_instance_q31 * S, + q31_t * pSrc); + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q31( + arm_cfft_radix4_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix2_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_f32( + arm_cfft_radix2_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_f32( + const arm_cfft_radix2_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix4_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_f32( + arm_cfft_radix4_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_f32( + const arm_cfft_radix4_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q15_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_q15; + +void arm_cfft_q15( + const arm_cfft_instance_q15 * S, + q15_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_q31; + +void arm_cfft_q31( + const arm_cfft_instance_q31 * S, + q31_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_f32; + + void arm_cfft_f32( + const arm_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the Q15 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q15; + + arm_status arm_rfft_init_q15( + arm_rfft_instance_q15 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q15( + const arm_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + /** + * @brief Instance structure for the Q31 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q31; + + arm_status arm_rfft_init_q31( + arm_rfft_instance_q31 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q31( + const arm_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint16_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_f32; + + arm_status arm_rfft_init_f32( + arm_rfft_instance_f32 * S, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_f32( + const arm_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ +typedef struct + { + arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ + uint16_t fftLenRFFT; /**< length of the real sequence */ + float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ + } arm_rfft_fast_instance_f32 ; + +arm_status arm_rfft_fast_init_f32 ( + arm_rfft_fast_instance_f32 * S, + uint16_t fftLen); + +void arm_rfft_fast_f32( + arm_rfft_fast_instance_f32 * S, + float32_t * p, float32_t * pOut, + uint8_t ifftFlag); + + /** + * @brief Instance structure for the floating-point DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + float32_t normalize; /**< normalizing factor. */ + float32_t *pTwiddle; /**< points to the twiddle factor table. */ + float32_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_f32; + + + /** + * @brief Initialization function for the floating-point DCT4/IDCT4. + * @param[in,out] S points to an instance of floating-point DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of floating-point RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of floating-point CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. + */ + arm_status arm_dct4_init_f32( + arm_dct4_instance_f32 * S, + arm_rfft_instance_f32 * S_RFFT, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint16_t N, + uint16_t Nby2, + float32_t normalize); + + + /** + * @brief Processing function for the floating-point DCT4/IDCT4. + * @param[in] S points to an instance of the floating-point DCT4/IDCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_f32( + const arm_dct4_instance_f32 * S, + float32_t * pState, + float32_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q31 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q31_t normalize; /**< normalizing factor. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + q31_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q31; + + + /** + * @brief Initialization function for the Q31 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q31 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q31 RFFT/RIFFT structure + * @param[in] S_CFFT points to an instance of Q31 CFFT/CIFFT structure + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q31( + arm_dct4_instance_q31 * S, + arm_rfft_instance_q31 * S_RFFT, + arm_cfft_radix4_instance_q31 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q31_t normalize); + + + /** + * @brief Processing function for the Q31 DCT4/IDCT4. + * @param[in] S points to an instance of the Q31 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q31( + const arm_dct4_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q15 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q15_t normalize; /**< normalizing factor. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + q15_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q15; + + + /** + * @brief Initialization function for the Q15 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q15 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q15 RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of Q15 CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q15( + arm_dct4_instance_q15 * S, + arm_rfft_instance_q15 * S_RFFT, + arm_cfft_radix4_instance_q15 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q15_t normalize); + + + /** + * @brief Processing function for the Q15 DCT4/IDCT4. + * @param[in] S points to an instance of the Q15 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q15( + const arm_dct4_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer); + + + /** + * @brief Floating-point vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a floating-point vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scale scale factor to be applied + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_f32( + float32_t * pSrc, + float32_t scale, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q7 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q7( + q7_t * pSrc, + q7_t scaleFract, + int8_t shift, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q15 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q15( + q15_t * pSrc, + q15_t scaleFract, + int8_t shift, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q31 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q31( + q31_t * pSrc, + q31_t scaleFract, + int8_t shift, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Dot product of floating-point vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t blockSize, + float32_t * result); + + + /** + * @brief Dot product of Q7 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q7( + q7_t * pSrcA, + q7_t * pSrcB, + uint32_t blockSize, + q31_t * result); + + + /** + * @brief Dot product of Q15 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Dot product of Q31 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Shifts the elements of a Q7 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q7( + q7_t * pSrc, + int8_t shiftBits, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q15 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q15( + q15_t * pSrc, + int8_t shiftBits, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q31 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q31( + q31_t * pSrc, + int8_t shiftBits, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_f32( + float32_t * pSrc, + float32_t offset, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q7( + q7_t * pSrc, + q7_t offset, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q15( + q15_t * pSrc, + q15_t offset, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q31( + q31_t * pSrc, + q31_t offset, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a floating-point vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q7 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a floating-point vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_f32( + float32_t value, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q7 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q7( + q7_t value, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q15 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q15( + q15_t value, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q31 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q31( + q31_t value, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + void arm_conv_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + void arm_conv_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Partial convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q7 sequences + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Instance structure for the Q15 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_f32; + + + /** + * @brief Processing function for the floating-point FIR decimator. + * @param[in] S points to an instance of the floating-point FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_f32( + const arm_fir_decimate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR decimator. + * @param[in,out] S points to an instance of the floating-point FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_f32( + arm_fir_decimate_instance_f32 * S, + uint16_t numTaps, + uint8_t M, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR decimator. + * @param[in,out] S points to an instance of the Q15 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q15( + arm_fir_decimate_instance_q15 * S, + uint16_t numTaps, + uint8_t M, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR decimator. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q31( + const arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q31( + arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR decimator. + * @param[in,out] S points to an instance of the Q31 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q31( + arm_fir_decimate_instance_q31 * S, + uint16_t numTaps, + uint8_t M, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ + } arm_fir_interpolate_instance_f32; + + + /** + * @brief Processing function for the Q15 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q15( + const arm_fir_interpolate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR interpolator. + * @param[in,out] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q15( + arm_fir_interpolate_instance_q15 * S, + uint8_t L, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q31( + const arm_fir_interpolate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR interpolator. + * @param[in,out] S points to an instance of the Q31 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q31( + arm_fir_interpolate_instance_q31 * S, + uint8_t L, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR interpolator. + * @param[in] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_f32( + const arm_fir_interpolate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR interpolator. + * @param[in,out] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_f32( + arm_fir_interpolate_instance_f32 * S, + uint8_t L, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the high precision Q31 Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ + } arm_biquad_cas_df1_32x64_ins_q31; + + + /** + * @param[in] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cas_df1_32x64_q31( + const arm_biquad_cas_df1_32x64_ins_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @param[in,out] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cas_df1_32x64_init_q31( + arm_biquad_cas_df1_32x64_ins_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q63_t * pState, + uint8_t postShift); + + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_stereo_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f64; + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f32( + const arm_biquad_cascade_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_stereo_df2T_f32( + const arm_biquad_cascade_stereo_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f64( + const arm_biquad_cascade_df2T_instance_f64 * S, + float64_t * pSrc, + float64_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_stereo_df2T_init_f32( + arm_biquad_cascade_stereo_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f64( + arm_biquad_cascade_df2T_instance_f64 * S, + uint8_t numStages, + float64_t * pCoeffs, + float64_t * pState); + + + /** + * @brief Instance structure for the Q15 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_f32; + + + /** + * @brief Initialization function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q15( + arm_fir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pCoeffs, + q15_t * pState); + + + /** + * @brief Processing function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q15( + const arm_fir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q31( + arm_fir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pCoeffs, + q31_t * pState); + + + /** + * @brief Processing function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q31( + const arm_fir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_f32( + arm_fir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Processing function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_f32( + const arm_fir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_f32; + + + /** + * @brief Processing function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_f32( + const arm_iir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize-1. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_init_f32( + arm_iir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pkCoeffs, + float32_t * pvCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q31( + const arm_iir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_init_q31( + arm_iir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pkCoeffs, + q31_t * pvCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the Q15 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q15( + const arm_iir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the fixed-point Q15 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process per call. + */ + void arm_iir_lattice_init_q15( + arm_iir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pkCoeffs, + q15_t * pvCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the floating-point LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that controls filter coefficient updates. */ + } arm_lms_instance_f32; + + + /** + * @brief Processing function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_f32( + const arm_lms_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_init_f32( + arm_lms_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q15; + + + /** + * @brief Initialization function for the Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q15( + arm_lms_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Processing function for Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q15( + const arm_lms_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q31; + + + /** + * @brief Processing function for Q31 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q31( + const arm_lms_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 LMS filter. + * @param[in] S points to an instance of the Q31 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q31( + arm_lms_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Instance structure for the floating-point normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that control filter coefficient updates. */ + float32_t energy; /**< saves previous frame energy. */ + float32_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_f32; + + + /** + * @brief Processing function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_f32( + arm_lms_norm_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_init_f32( + arm_lms_norm_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q31_t *recipTable; /**< points to the reciprocal initial value table. */ + q31_t energy; /**< saves previous frame energy. */ + q31_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q31; + + + /** + * @brief Processing function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q31( + arm_lms_norm_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q31( + arm_lms_norm_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Instance structure for the Q15 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< Number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q15_t *recipTable; /**< Points to the reciprocal initial value table. */ + q15_t energy; /**< saves previous frame energy. */ + q15_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q15; + + + /** + * @brief Processing function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q15( + arm_lms_norm_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q15( + arm_lms_norm_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Correlation of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Correlation of Q15 sequences + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ + void arm_correlate_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + + void arm_correlate_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + + void arm_correlate_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ + void arm_correlate_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_correlate_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Instance structure for the floating-point sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_f32; + + /** + * @brief Instance structure for the Q31 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q31; + + /** + * @brief Instance structure for the Q15 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q15; + + /** + * @brief Instance structure for the Q7 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q7; + + + /** + * @brief Processing function for the floating-point sparse FIR filter. + * @param[in] S points to an instance of the floating-point sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_f32( + arm_fir_sparse_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + float32_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point sparse FIR filter. + * @param[in,out] S points to an instance of the floating-point sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_f32( + arm_fir_sparse_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 sparse FIR filter. + * @param[in] S points to an instance of the Q31 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q31( + arm_fir_sparse_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + q31_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 sparse FIR filter. + * @param[in,out] S points to an instance of the Q31 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q31( + arm_fir_sparse_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 sparse FIR filter. + * @param[in] S points to an instance of the Q15 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q15( + arm_fir_sparse_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + q15_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 sparse FIR filter. + * @param[in,out] S points to an instance of the Q15 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q15( + arm_fir_sparse_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q7 sparse FIR filter. + * @param[in] S points to an instance of the Q7 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q7( + arm_fir_sparse_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + q7_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 sparse FIR filter. + * @param[in,out] S points to an instance of the Q7 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q7( + arm_fir_sparse_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Floating-point sin_cos function. + * @param[in] theta input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cos output. + */ + void arm_sin_cos_f32( + float32_t theta, + float32_t * pSinVal, + float32_t * pCosVal); + + + /** + * @brief Q31 sin_cos function. + * @param[in] theta scaled input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cosine output. + */ + void arm_sin_cos_q31( + q31_t theta, + q31_t * pSinVal, + q31_t * pCosVal); + + + /** + * @brief Floating-point complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup PID PID Motor Control + * + * A Proportional Integral Derivative (PID) controller is a generic feedback control + * loop mechanism widely used in industrial control systems. + * A PID controller is the most commonly used type of feedback controller. + * + * This set of functions implements (PID) controllers + * for Q15, Q31, and floating-point data types. The functions operate on a single sample + * of data and each call to the function returns a single processed value. + * S points to an instance of the PID control data structure. in + * is the input sample value. The functions return the output value. + * + * \par Algorithm: + *
+   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+   *    A0 = Kp + Ki + Kd
+   *    A1 = (-Kp ) - (2 * Kd )
+   *    A2 = Kd  
+ * + * \par + * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant + * + * \par + * \image html PID.gif "Proportional Integral Derivative Controller" + * + * \par + * The PID controller calculates an "error" value as the difference between + * the measured output and the reference input. + * The controller attempts to minimize the error by adjusting the process control inputs. + * The proportional value determines the reaction to the current error, + * the integral value determines the reaction based on the sum of recent errors, + * and the derivative value determines the reaction based on the rate at which the error has been changing. + * + * \par Instance Structure + * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. + * A separate instance structure must be defined for each PID Controller. + * There are separate instance structure declarations for each of the 3 supported data types. + * + * \par Reset Functions + * There is also an associated reset function for each data type which clears the state array. + * + * \par Initialization Functions + * There is also an associated initialization function for each data type. + * The initialization function performs the following operations: + * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. + * - Zeros out the values in the state buffer. + * + * \par + * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. + * + * \par Fixed-Point Behavior + * Care must be taken when using the fixed-point versions of the PID Controller functions. + * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup PID + * @{ + */ + + /** + * @brief Process function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + */ + static __INLINE float32_t arm_pid_f32( + arm_pid_instance_f32 * S, + float32_t in) + { + float32_t out; + + /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ + out = (S->A0 * in) + + (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + + /** + * @brief Process function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q31 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 64-bit accumulator. + * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. + * Thus, if the accumulator result overflows it wraps around rather than clip. + * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. + * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. + */ + static __INLINE q31_t arm_pid_q31( + arm_pid_instance_q31 * S, + q31_t in) + { + q63_t acc; + q31_t out; + + /* acc = A0 * x[n] */ + acc = (q63_t) S->A0 * in; + + /* acc += A1 * x[n-1] */ + acc += (q63_t) S->A1 * S->state[0]; + + /* acc += A2 * x[n-2] */ + acc += (q63_t) S->A2 * S->state[1]; + + /* convert output to 1.31 format to add y[n-1] */ + out = (q31_t) (acc >> 31u); + + /* out += y[n-1] */ + out += S->state[2]; + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + + /** + * @brief Process function for the Q15 PID Control. + * @param[in,out] S points to an instance of the Q15 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using a 64-bit internal accumulator. + * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. + * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. + * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. + * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. + * Lastly, the accumulator is saturated to yield a result in 1.15 format. + */ + static __INLINE q15_t arm_pid_q15( + arm_pid_instance_q15 * S, + q15_t in) + { + q63_t acc; + q15_t out; + +#ifndef ARM_MATH_CM0_FAMILY + __SIMD32_TYPE *vstate; + + /* Implementation of PID controller */ + + /* acc = A0 * x[n] */ + acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in); + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + vstate = __SIMD32_CONST(S->state); + acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)*vstate, (uint64_t)acc); +#else + /* acc = A0 * x[n] */ + acc = ((q31_t) S->A0) * in; + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc += (q31_t) S->A1 * S->state[0]; + acc += (q31_t) S->A2 * S->state[1]; +#endif + + /* acc += y[n-1] */ + acc += (q31_t) S->state[2] << 15; + + /* saturate the output */ + out = (q15_t) (__SSAT((acc >> 15), 16)); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + /** + * @} end of PID group + */ + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f32( + const arm_matrix_instance_f32 * src, + arm_matrix_instance_f32 * dst); + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f64( + const arm_matrix_instance_f64 * src, + arm_matrix_instance_f64 * dst); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup clarke Vector Clarke Transform + * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. + * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents + * in the two-phase orthogonal stator axis Ialpha and Ibeta. + * When Ialpha is superposed with Ia as shown in the figure below + * \image html clarke.gif Stator current space vector and its components in (a,b). + * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta + * can be calculated using only Ia and Ib. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeFormula.gif + * where Ia and Ib are the instantaneous stator phases and + * pIalpha and pIbeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup clarke + * @{ + */ + + /** + * + * @brief Floating-point Clarke transform + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + */ + static __INLINE void arm_clarke_f32( + float32_t Ia, + float32_t Ib, + float32_t * pIalpha, + float32_t * pIbeta) + { + /* Calculate pIalpha using the equation, pIalpha = Ia */ + *pIalpha = Ia; + + /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ + *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); + } + + + /** + * @brief Clarke transform for Q31 version + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + static __INLINE void arm_clarke_q31( + q31_t Ia, + q31_t Ib, + q31_t * pIalpha, + q31_t * pIbeta) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIalpha from Ia by equation pIalpha = Ia */ + *pIalpha = Ia; + + /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); + + /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ + product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); + + /* pIbeta is calculated by adding the intermediate products */ + *pIbeta = __QADD(product1, product2); + } + + /** + * @} end of clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q31( + q7_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_clarke Vector Inverse Clarke Transform + * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeInvFormula.gif + * where pIa and pIb are the instantaneous stator phases and + * Ialpha and Ibeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_clarke + * @{ + */ + + /** + * @brief Floating-point Inverse Clarke transform + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] pIa points to output three-phase coordinate a + * @param[out] pIb points to output three-phase coordinate b + */ + static __INLINE void arm_inv_clarke_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pIa, + float32_t * pIb) + { + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ + *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta; + } + + + /** + * @brief Inverse Clarke transform for Q31 version + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] pIa points to output three-phase coordinate a + * @param[out] pIb points to output three-phase coordinate b + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the subtraction, hence there is no risk of overflow. + */ + static __INLINE void arm_inv_clarke_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pIa, + q31_t * pIb) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); + + /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); + + /* pIb is calculated by subtracting the products */ + *pIb = __QSUB(product2, product1); + } + + /** + * @} end of inv_clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q15( + q7_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup park Vector Park Transform + * + * Forward Park transform converts the input two-coordinate vector to flux and torque components. + * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents + * from the stationary to the moving reference frame and control the spatial relationship between + * the stator vector current and rotor flux vector. + * If we consider the d axis aligned with the rotor flux, the diagram below shows the + * current vector and the relationship from the two reference frames: + * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkFormula.gif + * where Ialpha and Ibeta are the stator vector components, + * pId and pIq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup park + * @{ + */ + + /** + * @brief Floating-point Park transform + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * The function implements the forward Park transform. + * + */ + static __INLINE void arm_park_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pId, + float32_t * pIq, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ + *pId = Ialpha * cosVal + Ibeta * sinVal; + + /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ + *pIq = -Ialpha * sinVal + Ibeta * cosVal; + } + + + /** + * @brief Park transform for Q31 version + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition and subtraction, hence there is no risk of overflow. + */ + static __INLINE void arm_park_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pId, + q31_t * pIq, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Ialpha * cosVal) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * sinVal) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Ialpha * sinVal) */ + product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * cosVal) */ + product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); + + /* Calculate pId by adding the two intermediate products 1 and 2 */ + *pId = __QADD(product1, product2); + + /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ + *pIq = __QSUB(product4, product3); + } + + /** + * @} end of park group + */ + + /** + * @brief Converts the elements of the Q7 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q7_to_float( + q7_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_park Vector Inverse Park transform + * Inverse Park transform converts the input flux and torque components to two-coordinate vector. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkInvFormula.gif + * where pIalpha and pIbeta are the stator vector components, + * Id and Iq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_park + * @{ + */ + + /** + * @brief Floating-point Inverse Park transform + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + */ + static __INLINE void arm_inv_park_f32( + float32_t Id, + float32_t Iq, + float32_t * pIalpha, + float32_t * pIbeta, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ + *pIalpha = Id * cosVal - Iq * sinVal; + + /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ + *pIbeta = Id * sinVal + Iq * cosVal; + } + + + /** + * @brief Inverse Park transform for Q31 version + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + static __INLINE void arm_inv_park_q31( + q31_t Id, + q31_t Iq, + q31_t * pIalpha, + q31_t * pIbeta, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Id * cosVal) */ + product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Iq * sinVal) */ + product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Id * sinVal) */ + product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Iq * cosVal) */ + product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); + + /* Calculate pIalpha by using the two intermediate products 1 and 2 */ + *pIalpha = __QSUB(product1, product2); + + /* Calculate pIbeta by using the two intermediate products 3 and 4 */ + *pIbeta = __QADD(product4, product3); + } + + /** + * @} end of Inverse park group + */ + + + /** + * @brief Converts the elements of the Q31 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_float( + q31_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup LinearInterpolate Linear Interpolation + * + * Linear interpolation is a method of curve fitting using linear polynomials. + * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line + * + * \par + * \image html LinearInterp.gif "Linear interpolation" + * + * \par + * A Linear Interpolate function calculates an output value(y), for the input(x) + * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) + * + * \par Algorithm: + *
+   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+   *       where x0, x1 are nearest values of input x
+   *             y0, y1 are nearest values to output y
+   * 
+ * + * \par + * This set of functions implements Linear interpolation process + * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single + * sample of data and each call to the function returns a single processed value. + * S points to an instance of the Linear Interpolate function data structure. + * x is the input sample value. The functions returns the output value. + * + * \par + * if x is outside of the table boundary, Linear interpolation returns first value of the table + * if x is below input range and returns last value of table if x is above range. + */ + + /** + * @addtogroup LinearInterpolate + * @{ + */ + + /** + * @brief Process function for the floating-point Linear Interpolation Function. + * @param[in,out] S is an instance of the floating-point Linear Interpolation structure + * @param[in] x input sample to process + * @return y processed output sample. + * + */ + static __INLINE float32_t arm_linear_interp_f32( + arm_linear_interp_instance_f32 * S, + float32_t x) + { + float32_t y; + float32_t x0, x1; /* Nearest input values */ + float32_t y0, y1; /* Nearest output values */ + float32_t xSpacing = S->xSpacing; /* spacing between input values */ + int32_t i; /* Index variable */ + float32_t *pYData = S->pYData; /* pointer to output table */ + + /* Calculation of index */ + i = (int32_t) ((x - S->x1) / xSpacing); + + if(i < 0) + { + /* Iniatilize output for below specified range as least output value of table */ + y = pYData[0]; + } + else if((uint32_t)i >= S->nValues) + { + /* Iniatilize output for above specified range as last output value of table */ + y = pYData[S->nValues - 1]; + } + else + { + /* Calculation of nearest input values */ + x0 = S->x1 + i * xSpacing; + x1 = S->x1 + (i + 1) * xSpacing; + + /* Read of nearest output values */ + y0 = pYData[i]; + y1 = pYData[i + 1]; + + /* Calculation of output */ + y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); + + } + + /* returns output value */ + return (y); + } + + + /** + * + * @brief Process function for the Q31 Linear Interpolation Function. + * @param[in] pYData pointer to Q31 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + static __INLINE q31_t arm_linear_interp_q31( + q31_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q31_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (q31_t)0xFFF00000) >> 20); + + if(index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if(index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* shift left by 11 to keep fract in 1.31 format */ + fract = (x & 0x000FFFFF) << 11; + + /* Read two nearest output values from the index in 1.31(q31) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 2.30 format */ + y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); + + /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ + y += ((q31_t) (((q63_t) y1 * fract) >> 32)); + + /* Convert y to 1.31 format */ + return (y << 1u); + } + } + + + /** + * + * @brief Process function for the Q15 Linear Interpolation Function. + * @param[in] pYData pointer to Q15 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + static __INLINE q15_t arm_linear_interp_q15( + q15_t * pYData, + q31_t x, + uint32_t nValues) + { + q63_t y; /* output */ + q15_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (int32_t)0xFFF00000) >> 20); + + if(index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if(index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 13.35 format */ + y = ((q63_t) y0 * (0xFFFFF - fract)); + + /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ + y += ((q63_t) y1 * (fract)); + + /* convert y to 1.15 format */ + return (q15_t) (y >> 20); + } + } + + + /** + * + * @brief Process function for the Q7 Linear Interpolation Function. + * @param[in] pYData pointer to Q7 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + */ + static __INLINE q7_t arm_linear_interp_q7( + q7_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q7_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + uint32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + if (x < 0) + { + return (pYData[0]); + } + index = (x >> 20) & 0xfff; + + if(index >= (nValues - 1)) + { + return (pYData[nValues - 1]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index and are in 1.7(q7) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ + y = ((y0 * (0xFFFFF - fract))); + + /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ + y += (y1 * fract); + + /* convert y to 1.7(q7) format */ + return (q7_t) (y >> 20); + } + } + + /** + * @} end of LinearInterpolate group + */ + + /** + * @brief Fast approximation to the trigonometric sine function for floating-point data. + * @param[in] x input value in radians. + * @return sin(x). + */ + float32_t arm_sin_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q31_t arm_sin_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q15_t arm_sin_q15( + q15_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for floating-point data. + * @param[in] x input value in radians. + * @return cos(x). + */ + float32_t arm_cos_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q31_t arm_cos_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q15_t arm_cos_q15( + q15_t x); + + + /** + * @ingroup groupFastMath + */ + + + /** + * @defgroup SQRT Square Root + * + * Computes the square root of a number. + * There are separate functions for Q15, Q31, and floating-point data types. + * The square root function is computed using the Newton-Raphson algorithm. + * This is an iterative algorithm of the form: + *
+   *      x1 = x0 - f(x0)/f'(x0)
+   * 
+ * where x1 is the current estimate, + * x0 is the previous estimate, and + * f'(x0) is the derivative of f() evaluated at x0. + * For the square root function, the algorithm reduces to: + *
+   *     x0 = in/2                         [initial guess]
+   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
+   * 
+ */ + + + /** + * @addtogroup SQRT + * @{ + */ + + /** + * @brief Floating-point square root function. + * @param[in] in input value. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + static __INLINE arm_status arm_sqrt_f32( + float32_t in, + float32_t * pOut) + { + if(in >= 0.0f) + { + +#if (__FPU_USED == 1) && defined ( __CC_ARM ) + *pOut = __sqrtf(in); +#elif (__FPU_USED == 1) && (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) + *pOut = __builtin_sqrtf(in); +#elif (__FPU_USED == 1) && defined(__GNUC__) + *pOut = __builtin_sqrtf(in); +#elif (__FPU_USED == 1) && defined ( __ICCARM__ ) && (__VER__ >= 6040000) + __ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(in)); +#else + *pOut = sqrtf(in); +#endif + + return (ARM_MATH_SUCCESS); + } + else + { + *pOut = 0.0f; + return (ARM_MATH_ARGUMENT_ERROR); + } + } + + + /** + * @brief Q31 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q31( + q31_t in, + q31_t * pOut); + + + /** + * @brief Q15 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q15( + q15_t in, + q15_t * pOut); + + /** + * @} end of SQRT group + */ + + + /** + * @brief floating-point Circular write function. + */ + static __INLINE void arm_circularWrite_f32( + int32_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const int32_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + + /** + * @brief floating-point Circular Read function. + */ + static __INLINE void arm_circularRead_f32( + int32_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + int32_t * dst, + int32_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (int32_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q15 Circular write function. + */ + static __INLINE void arm_circularWrite_q15( + q15_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q15_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q15 Circular Read function. + */ + static __INLINE void arm_circularRead_q15( + q15_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q15_t * dst, + q15_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (q15_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update wOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q7 Circular write function. + */ + static __INLINE void arm_circularWrite_q7( + q7_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q7_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q7 Circular Read function. + */ + static __INLINE void arm_circularRead_q7( + q7_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q7_t * dst, + q7_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (q7_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Sum of the squares of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q31( + q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q15( + q15_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q7( + q7_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult); + + + /** + * @brief Mean value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Mean value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Variance of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Standard deviation of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Floating-point complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t numSamples, + q31_t * realResult, + q31_t * imagResult); + + + /** + * @brief Q31 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t numSamples, + q63_t * realResult, + q63_t * imagResult); + + + /** + * @brief Floating-point complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t numSamples, + float32_t * realResult, + float32_t * imagResult); + + + /** + * @brief Q15 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q15( + q15_t * pSrcCmplx, + q15_t * pSrcReal, + q15_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q31( + q31_t * pSrcCmplx, + q31_t * pSrcReal, + q31_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_f32( + float32_t * pSrcCmplx, + float32_t * pSrcReal, + float32_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Minimum value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] result is output pointer + * @param[in] index is the array index of the minimum value in the input buffer. + */ + void arm_min_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * result, + uint32_t * index); + + + /** + * @brief Minimum value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[in] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q7 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q15 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q31 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a floating-point vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Q15 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Converts the elements of the floating-point vector to Q31 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q31 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q31( + float32_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q15 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q15( + float32_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q7 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q7 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q7( + float32_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q15 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q15( + q31_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q7( + q31_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_float( + q15_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q31 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q31( + q15_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q7( + q15_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup BilinearInterpolate Bilinear Interpolation + * + * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. + * The underlying function f(x, y) is sampled on a regular grid and the interpolation process + * determines values between the grid points. + * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. + * Bilinear interpolation is often used in image processing to rescale images. + * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. + * + * Algorithm + * \par + * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. + * For floating-point, the instance structure is defined as: + *
+   *   typedef struct
+   *   {
+   *     uint16_t numRows;
+   *     uint16_t numCols;
+   *     float32_t *pData;
+   * } arm_bilinear_interp_instance_f32;
+   * 
+ * + * \par + * where numRows specifies the number of rows in the table; + * numCols specifies the number of columns in the table; + * and pData points to an array of size numRows*numCols values. + * The data table pTable is organized in row order and the supplied data values fall on integer indexes. + * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers. + * + * \par + * Let (x, y) specify the desired interpolation point. Then define: + *
+   *     XF = floor(x)
+   *     YF = floor(y)
+   * 
+ * \par + * The interpolated output point is computed as: + *
+   *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
+   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
+   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
+   * 
+ * Note that the coordinates (x, y) contain integer and fractional components. + * The integer components specify which portion of the table to use while the + * fractional components control the interpolation processor. + * + * \par + * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. + */ + + /** + * @addtogroup BilinearInterpolate + * @{ + */ + + + /** + * + * @brief Floating-point bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate. + * @param[in] Y interpolation coordinate. + * @return out interpolated value. + */ + static __INLINE float32_t arm_bilinear_interp_f32( + const arm_bilinear_interp_instance_f32 * S, + float32_t X, + float32_t Y) + { + float32_t out; + float32_t f00, f01, f10, f11; + float32_t *pData = S->pData; + int32_t xIndex, yIndex, index; + float32_t xdiff, ydiff; + float32_t b1, b2, b3, b4; + + xIndex = (int32_t) X; + yIndex = (int32_t) Y; + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 || yIndex > (S->numCols - 1)) + { + return (0); + } + + /* Calculation of index for two nearest points in X-direction */ + index = (xIndex - 1) + (yIndex - 1) * S->numCols; + + + /* Read two nearest points in X-direction */ + f00 = pData[index]; + f01 = pData[index + 1]; + + /* Calculation of index for two nearest points in Y-direction */ + index = (xIndex - 1) + (yIndex) * S->numCols; + + + /* Read two nearest points in Y-direction */ + f10 = pData[index]; + f11 = pData[index + 1]; + + /* Calculation of intermediate values */ + b1 = f00; + b2 = f01 - f00; + b3 = f10 - f00; + b4 = f00 - f01 - f10 + f11; + + /* Calculation of fractional part in X */ + xdiff = X - xIndex; + + /* Calculation of fractional part in Y */ + ydiff = Y - yIndex; + + /* Calculation of bi-linear interpolated output */ + out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; + + /* return to application */ + return (out); + } + + + /** + * + * @brief Q31 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + static __INLINE q31_t arm_bilinear_interp_q31( + arm_bilinear_interp_instance_q31 * S, + q31_t X, + q31_t Y) + { + q31_t out; /* Temporary output */ + q31_t acc = 0; /* output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q31_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q31_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* shift left xfract by 11 to keep 1.31 format */ + xfract = (X & 0x000FFFFF) << 11u; + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + (int32_t)nCols * (cI) ]; + x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1]; + + /* 20 bits for the fractional part */ + /* shift left yfract by 11 to keep 1.31 format */ + yfract = (Y & 0x000FFFFF) << 11u; + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + (int32_t)nCols * (cI + 1) ]; + y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ + out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); + acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); + + /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); + + /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* Convert acc to 1.31(q31) format */ + return ((q31_t)(acc << 2)); + } + + + /** + * @brief Q15 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + static __INLINE q15_t arm_bilinear_interp_q15( + arm_bilinear_interp_instance_q15 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q15_t x1, x2, y1, y2; /* Nearest output values */ + q31_t xfract, yfract; /* X, Y fractional parts */ + int32_t rI, cI; /* Row and column indices */ + q15_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ + + /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ + /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ + out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u); + acc = ((q63_t) out * (0xFFFFF - yfract)); + + /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u); + acc += ((q63_t) out * (xfract)); + + /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u); + acc += ((q63_t) out * (yfract)); + + /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u); + acc += ((q63_t) out * (yfract)); + + /* acc is in 13.51 format and down shift acc by 36 times */ + /* Convert out to 1.15 format */ + return ((q15_t)(acc >> 36)); + } + + + /** + * @brief Q7 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + static __INLINE q7_t arm_bilinear_interp_q7( + arm_bilinear_interp_instance_q7 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q7_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q7_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ + out = ((x1 * (0xFFFFF - xfract))); + acc = (((q63_t) out * (0xFFFFF - yfract))); + + /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ + out = ((x2 * (0xFFFFF - yfract))); + acc += (((q63_t) out * (xfract))); + + /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y1 * (0xFFFFF - xfract))); + acc += (((q63_t) out * (yfract))); + + /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y2 * (yfract))); + acc += (((q63_t) out * (xfract))); + + /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ + return ((q7_t)(acc >> 40)); + } + + /** + * @} end of BilinearInterpolate group + */ + + +/* SMMLAR */ +#define multAcc_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMLSR */ +#define multSub_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMULR */ +#define mult_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32) + +/* SMMLA */ +#define multAcc_32x32_keep32(a, x, y) \ + a += (q31_t) (((q63_t) x * y) >> 32) + +/* SMMLS */ +#define multSub_32x32_keep32(a, x, y) \ + a -= (q31_t) (((q63_t) x * y) >> 32) + +/* SMMUL */ +#define mult_32x32_keep32(a, x, y) \ + a = (q31_t) (((q63_t) x * y ) >> 32) + + +#if defined ( __CC_ARM ) + /* Enter low optimization region - place directly above function definition */ + #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("push") \ + _Pragma ("O1") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) + #define LOW_OPTIMIZATION_EXIT \ + _Pragma ("pop") + #else + #define LOW_OPTIMIZATION_EXIT + #endif + + /* Enter low optimization region - place directly above function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__GNUC__) + #define LOW_OPTIMIZATION_ENTER __attribute__(( optimize("-O1") )) + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__ICCARM__) + /* Enter low optimization region - place directly above function definition */ + #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define LOW_OPTIMIZATION_EXIT + + /* Enter low optimization region - place directly above function definition */ + #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__CSMC__) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__TASKING__) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#endif + + +#ifdef __cplusplus +} +#endif + + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic pop +#endif + +#endif /* _ARM_MATH_H */ + +/** + * + * End of file. + */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_armcc.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_armcc.h new file mode 100644 index 0000000..4d9d064 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_armcc.h @@ -0,0 +1,865 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use Arm Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \ + (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) ) + #define __ARM_ARCH_6M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1)) + #define __ARM_ARCH_7M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) + #define __ARM_ARCH_7EM__ 1 +#endif + + /* __ARM_ARCH_8M_BASE__ not applicable */ + /* __ARM_ARCH_8M_MAIN__ not applicable */ + + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE static __forceinline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT __packed struct +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION __packed union +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); */ + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xFFU); +} + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 0xFFU); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1U); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() do {\ + __schedule_barrier();\ + __isb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() do {\ + __schedule_barrier();\ + __dsb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() do {\ + __schedule_barrier();\ + __dmb(0xF);\ + __schedule_barrier();\ + } while (0U) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + return result; +} +#endif + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32U) ) >> 32U)) + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_H */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_armclang.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_armclang.h new file mode 100644 index 0000000..162a400 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_armclang.h @@ -0,0 +1,1869 @@ +/**************************************************************************//** + * @file cmsis_armclang.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +#ifndef __ARM_COMPAT_H +#include /* Compatibility header for Arm Compiler 5 intrinsics */ +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); see arm_compat.h */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); see arm_compat.h */ + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq /* see arm_compat.h */ + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq /* see arm_compat.h */ + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF); + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF); + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF); + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ (uint8_t)__builtin_clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#if 0 +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_compiler.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_compiler.h new file mode 100644 index 0000000..617fab3 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_compiler.h @@ -0,0 +1,266 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include "cmsis_iccarm.h" + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed)) + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_gcc.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_gcc.h new file mode 100644 index 0000000..0a745fb --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_gcc.h @@ -0,0 +1,2085 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.0.4 + * @date 09. April 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_GCC_H +#define __CMSIS_GCC_H +/* polyspace-begin MISRA2012:* */ +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) :: "memory"); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) :: "memory"); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#endif +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI() __ASM volatile ("wfi") + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE() __ASM volatile ("wfe") + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV() __ASM volatile ("sev") + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return result; +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ (uint8_t)__builtin_clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ + __extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#if 0 +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop +/* polyspace-end MISRA2012:* */ +#endif /* __CMSIS_GCC_H */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_iccarm.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_iccarm.h new file mode 100644 index 0000000..11c4af0 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_iccarm.h @@ -0,0 +1,935 @@ +/**************************************************************************//** + * @file cmsis_iccarm.h + * @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file + * @version V5.0.7 + * @date 19. June 2018 + ******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017-2018 IAR Systems +// +// Licensed under the Apache License, Version 2.0 (the "License") +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//------------------------------------------------------------------------------ + + +#ifndef __CMSIS_ICCARM_H__ +#define __CMSIS_ICCARM_H__ + +#ifndef __ICCARM__ + #error This file should only be compiled by ICCARM +#endif + +#pragma system_include + +#define __IAR_FT _Pragma("inline=forced") __intrinsic + +#if (__VER__ >= 8000000) + #define __ICCARM_V8 1 +#else + #define __ICCARM_V8 0 +#endif + +#ifndef __ALIGNED + #if __ICCARM_V8 + #define __ALIGNED(x) __attribute__((aligned(x))) + #elif (__VER__ >= 7080000) + /* Needs IAR language extensions */ + #define __ALIGNED(x) __attribute__((aligned(x))) + #else + #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. + #define __ALIGNED(x) + #endif +#endif + + +/* Define compiler macros for CPU architecture, used in CMSIS 5. + */ +#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__ +/* Macros already defined */ +#else + #if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M' + #if __ARM_ARCH == 6 + #define __ARM_ARCH_6M__ 1 + #elif __ARM_ARCH == 7 + #if __ARM_FEATURE_DSP + #define __ARM_ARCH_7EM__ 1 + #else + #define __ARM_ARCH_7M__ 1 + #endif + #endif /* __ARM_ARCH */ + #endif /* __ARM_ARCH_PROFILE == 'M' */ +#endif + +/* Alternativ core deduction for older ICCARM's */ +#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \ + !defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__) + #if defined(__ARM6M__) && (__CORE__ == __ARM6M__) + #define __ARM_ARCH_6M__ 1 + #elif defined(__ARM7M__) && (__CORE__ == __ARM7M__) + #define __ARM_ARCH_7M__ 1 + #elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__) + #define __ARM_ARCH_7EM__ 1 + #elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #else + #error "Unknown target." + #endif +#endif + + + +#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1 + #define __IAR_M0_FAMILY 1 +#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1 + #define __IAR_M0_FAMILY 1 +#else + #define __IAR_M0_FAMILY 0 +#endif + + +#ifndef __ASM + #define __ASM __asm +#endif + +#ifndef __INLINE + #define __INLINE inline +#endif + +#ifndef __NO_RETURN + #if __ICCARM_V8 + #define __NO_RETURN __attribute__((__noreturn__)) + #else + #define __NO_RETURN _Pragma("object_attribute=__noreturn") + #endif +#endif + +#ifndef __PACKED + #if __ICCARM_V8 + #define __PACKED __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED __packed + #endif +#endif + +#ifndef __PACKED_STRUCT + #if __ICCARM_V8 + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_STRUCT __packed struct + #endif +#endif + +#ifndef __PACKED_UNION + #if __ICCARM_V8 + #define __PACKED_UNION union __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_UNION __packed union + #endif +#endif + +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +#ifndef __FORCEINLINE + #define __FORCEINLINE _Pragma("inline=forced") +#endif + +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE +#endif + +#ifndef __UNALIGNED_UINT16_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint16_t __iar_uint16_read(void const *ptr) +{ + return *(__packed uint16_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) +#endif + + +#ifndef __UNALIGNED_UINT16_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) +{ + *(__packed uint16_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint32_t __iar_uint32_read(void const *ptr) +{ + return *(__packed uint32_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) +{ + *(__packed uint32_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32 /* deprecated */ +#pragma language=save +#pragma language=extended +__packed struct __iar_u32 { uint32_t v; }; +#pragma language=restore +#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) +#endif + +#ifndef __USED + #if __ICCARM_V8 + #define __USED __attribute__((used)) + #else + #define __USED _Pragma("__root") + #endif +#endif + +#ifndef __WEAK + #if __ICCARM_V8 + #define __WEAK __attribute__((weak)) + #else + #define __WEAK _Pragma("__weak") + #endif +#endif + + +#ifndef __ICCARM_INTRINSICS_VERSION__ + #define __ICCARM_INTRINSICS_VERSION__ 0 +#endif + +#if __ICCARM_INTRINSICS_VERSION__ == 2 + + #if defined(__CLZ) + #undef __CLZ + #endif + #if defined(__REVSH) + #undef __REVSH + #endif + #if defined(__RBIT) + #undef __RBIT + #endif + #if defined(__SSAT) + #undef __SSAT + #endif + #if defined(__USAT) + #undef __USAT + #endif + + #include "iccarm_builtin.h" + + #define __disable_fault_irq __iar_builtin_disable_fiq + #define __disable_irq __iar_builtin_disable_interrupt + #define __enable_fault_irq __iar_builtin_enable_fiq + #define __enable_irq __iar_builtin_enable_interrupt + #define __arm_rsr __iar_builtin_rsr + #define __arm_wsr __iar_builtin_wsr + + + #define __get_APSR() (__arm_rsr("APSR")) + #define __get_BASEPRI() (__arm_rsr("BASEPRI")) + #define __get_CONTROL() (__arm_rsr("CONTROL")) + #define __get_FAULTMASK() (__arm_rsr("FAULTMASK")) + + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #define __get_FPSCR() (__arm_rsr("FPSCR")) + #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE))) + #else + #define __get_FPSCR() ( 0 ) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #define __get_IPSR() (__arm_rsr("IPSR")) + #define __get_MSP() (__arm_rsr("MSP")) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __get_MSPLIM() (0U) + #else + #define __get_MSPLIM() (__arm_rsr("MSPLIM")) + #endif + #define __get_PRIMASK() (__arm_rsr("PRIMASK")) + #define __get_PSP() (__arm_rsr("PSP")) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __get_PSPLIM() (0U) + #else + #define __get_PSPLIM() (__arm_rsr("PSPLIM")) + #endif + + #define __get_xPSR() (__arm_rsr("xPSR")) + + #define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE))) + #define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE))) + #define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE))) + #define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE))) + #define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __set_MSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE))) + #endif + #define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE))) + #define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE))) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __set_PSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE))) + #endif + + #define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS")) + #define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE))) + #define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS")) + #define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE))) + #define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS")) + #define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE))) + #define __TZ_get_SP_NS() (__arm_rsr("SP_NS")) + #define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE))) + #define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS")) + #define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE))) + #define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS")) + #define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE))) + #define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS")) + #define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __TZ_get_PSPLIM_NS() (0U) + #define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE)) + #else + #define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS")) + #define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE))) + #endif + + #define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS")) + #define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE))) + + #define __NOP __iar_builtin_no_operation + + #define __CLZ __iar_builtin_CLZ + #define __CLREX __iar_builtin_CLREX + + #define __DMB __iar_builtin_DMB + #define __DSB __iar_builtin_DSB + #define __ISB __iar_builtin_ISB + + #define __LDREXB __iar_builtin_LDREXB + #define __LDREXH __iar_builtin_LDREXH + #define __LDREXW __iar_builtin_LDREX + + #define __RBIT __iar_builtin_RBIT + #define __REV __iar_builtin_REV + #define __REV16 __iar_builtin_REV16 + + __IAR_FT int16_t __REVSH(int16_t val) + { + return (int16_t) __iar_builtin_REVSH(val); + } + + #define __ROR __iar_builtin_ROR + #define __RRX __iar_builtin_RRX + + #define __SEV __iar_builtin_SEV + + #if !__IAR_M0_FAMILY + #define __SSAT __iar_builtin_SSAT + #endif + + #define __STREXB __iar_builtin_STREXB + #define __STREXH __iar_builtin_STREXH + #define __STREXW __iar_builtin_STREX + + #if !__IAR_M0_FAMILY + #define __USAT __iar_builtin_USAT + #endif + + #define __WFE __iar_builtin_WFE + #define __WFI __iar_builtin_WFI + + #if __ARM_MEDIA__ + #define __SADD8 __iar_builtin_SADD8 + #define __QADD8 __iar_builtin_QADD8 + #define __SHADD8 __iar_builtin_SHADD8 + #define __UADD8 __iar_builtin_UADD8 + #define __UQADD8 __iar_builtin_UQADD8 + #define __UHADD8 __iar_builtin_UHADD8 + #define __SSUB8 __iar_builtin_SSUB8 + #define __QSUB8 __iar_builtin_QSUB8 + #define __SHSUB8 __iar_builtin_SHSUB8 + #define __USUB8 __iar_builtin_USUB8 + #define __UQSUB8 __iar_builtin_UQSUB8 + #define __UHSUB8 __iar_builtin_UHSUB8 + #define __SADD16 __iar_builtin_SADD16 + #define __QADD16 __iar_builtin_QADD16 + #define __SHADD16 __iar_builtin_SHADD16 + #define __UADD16 __iar_builtin_UADD16 + #define __UQADD16 __iar_builtin_UQADD16 + #define __UHADD16 __iar_builtin_UHADD16 + #define __SSUB16 __iar_builtin_SSUB16 + #define __QSUB16 __iar_builtin_QSUB16 + #define __SHSUB16 __iar_builtin_SHSUB16 + #define __USUB16 __iar_builtin_USUB16 + #define __UQSUB16 __iar_builtin_UQSUB16 + #define __UHSUB16 __iar_builtin_UHSUB16 + #define __SASX __iar_builtin_SASX + #define __QASX __iar_builtin_QASX + #define __SHASX __iar_builtin_SHASX + #define __UASX __iar_builtin_UASX + #define __UQASX __iar_builtin_UQASX + #define __UHASX __iar_builtin_UHASX + #define __SSAX __iar_builtin_SSAX + #define __QSAX __iar_builtin_QSAX + #define __SHSAX __iar_builtin_SHSAX + #define __USAX __iar_builtin_USAX + #define __UQSAX __iar_builtin_UQSAX + #define __UHSAX __iar_builtin_UHSAX + #define __USAD8 __iar_builtin_USAD8 + #define __USADA8 __iar_builtin_USADA8 + #define __SSAT16 __iar_builtin_SSAT16 + #define __USAT16 __iar_builtin_USAT16 + #define __UXTB16 __iar_builtin_UXTB16 + #define __UXTAB16 __iar_builtin_UXTAB16 + #define __SXTB16 __iar_builtin_SXTB16 + #define __SXTAB16 __iar_builtin_SXTAB16 + #define __SMUAD __iar_builtin_SMUAD + #define __SMUADX __iar_builtin_SMUADX + #define __SMMLA __iar_builtin_SMMLA + #define __SMLAD __iar_builtin_SMLAD + #define __SMLADX __iar_builtin_SMLADX + #define __SMLALD __iar_builtin_SMLALD + #define __SMLALDX __iar_builtin_SMLALDX + #define __SMUSD __iar_builtin_SMUSD + #define __SMUSDX __iar_builtin_SMUSDX + #define __SMLSD __iar_builtin_SMLSD + #define __SMLSDX __iar_builtin_SMLSDX + #define __SMLSLD __iar_builtin_SMLSLD + #define __SMLSLDX __iar_builtin_SMLSLDX + #define __SEL __iar_builtin_SEL + #define __QADD __iar_builtin_QADD + #define __QSUB __iar_builtin_QSUB + #define __PKHBT __iar_builtin_PKHBT + #define __PKHTB __iar_builtin_PKHTB + #endif + +#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #define __CLZ __cmsis_iar_clz_not_active + #define __SSAT __cmsis_iar_ssat_not_active + #define __USAT __cmsis_iar_usat_not_active + #define __RBIT __cmsis_iar_rbit_not_active + #define __get_APSR __cmsis_iar_get_APSR_not_active + #endif + + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #define __get_FPSCR __cmsis_iar_get_FPSR_not_active + #define __set_FPSCR __cmsis_iar_set_FPSR_not_active + #endif + + #ifdef __INTRINSICS_INCLUDED + #error intrinsics.h is already included previously! + #endif + + #include + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #undef __CLZ + #undef __SSAT + #undef __USAT + #undef __RBIT + #undef __get_APSR + + __STATIC_INLINE uint8_t __CLZ(uint32_t data) + { + if (data == 0U) { return 32U; } + + uint32_t count = 0U; + uint32_t mask = 0x80000000U; + + while ((data & mask) == 0U) + { + count += 1U; + mask = mask >> 1U; + } + return count; + } + + __STATIC_INLINE uint32_t __RBIT(uint32_t v) + { + uint8_t sc = 31U; + uint32_t r = v; + for (v >>= 1U; v; v >>= 1U) + { + r <<= 1U; + r |= v & 1U; + sc--; + } + return (r << sc); + } + + __STATIC_INLINE uint32_t __get_APSR(void) + { + uint32_t res; + __asm("MRS %0,APSR" : "=r" (res)); + return res; + } + + #endif + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #undef __get_FPSCR + #undef __set_FPSCR + #define __get_FPSCR() (0) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #pragma diag_suppress=Pe940 + #pragma diag_suppress=Pe177 + + #define __enable_irq __enable_interrupt + #define __disable_irq __disable_interrupt + #define __NOP __no_operation + + #define __get_xPSR __get_PSR + + #if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0) + + __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) + { + return __LDREX((unsigned long *)ptr); + } + + __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) + { + return __STREX(value, (unsigned long *)ptr); + } + #endif + + + /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + #if (__CORTEX_M >= 0x03) + + __IAR_FT uint32_t __RRX(uint32_t value) + { + uint32_t result; + __ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc"); + return(result); + } + + __IAR_FT void __set_BASEPRI_MAX(uint32_t value) + { + __asm volatile("MSR BASEPRI_MAX,%0"::"r" (value)); + } + + + #define __enable_fault_irq __enable_fiq + #define __disable_fault_irq __disable_fiq + + + #endif /* (__CORTEX_M >= 0x03) */ + + __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) + { + return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); + } + + #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + __IAR_FT uint32_t __get_MSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,MSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_MSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR MSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __get_PSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_PSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_CONTROL_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,CONTROL_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_CONTROL_NS(uint32_t value) + { + __asm volatile("MSR CONTROL_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PSP_NS(uint32_t value) + { + __asm volatile("MSR PSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_MSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSP_NS(uint32_t value) + { + __asm volatile("MSR MSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_SP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,SP_NS" : "=r" (res)); + return res; + } + __IAR_FT void __TZ_set_SP_NS(uint32_t value) + { + __asm volatile("MSR SP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PRIMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PRIMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value) + { + __asm volatile("MSR PRIMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_BASEPRI_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,BASEPRI_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value) + { + __asm volatile("MSR BASEPRI_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value) + { + __asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSPLIM_NS(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM_NS" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM_NS,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_MSPLIM_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSPLIM_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value) + { + __asm volatile("MSR MSPLIM_NS,%0" :: "r" (value)); + } + + #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + +#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) + +#if __IAR_M0_FAMILY + __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) + { + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; + } + + __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) + { + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; + } +#endif + +#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + + __IAR_FT uint8_t __LDRBT(volatile uint8_t *addr) + { + uint32_t res; + __ASM("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDRHT(volatile uint16_t *addr) + { + uint32_t res; + __ASM("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDRT(volatile uint32_t *addr) + { + uint32_t res; + __ASM("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return res; + } + + __IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr) + { + __ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr) + { + __ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr) + { + __ASM("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory"); + } + +#endif /* (__CORTEX_M >= 0x03) */ + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + + __IAR_FT uint8_t __LDAB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDA(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr) + { + __ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr) + { + __ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr) + { + __ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + +#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#undef __IAR_FT +#undef __IAR_M0_FAMILY +#undef __ICCARM_V8 + +#pragma diag_default=Pe940 +#pragma diag_default=Pe177 + +#endif /* __CMSIS_ICCARM_H__ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_version.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_version.h new file mode 100644 index 0000000..660f612 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_version.h @@ -0,0 +1,39 @@ +/**************************************************************************//** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.2 + * @date 19. April 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_VERSION_H +#define __CMSIS_VERSION_H + +/* CMSIS Version definitions */ +#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ +#define __CM_CMSIS_VERSION_SUB ( 1U) /*!< [15:0] CMSIS Core(M) sub version */ +#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ + __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ +#endif diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/core_cm0plus.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/core_cm0plus.h new file mode 100644 index 0000000..47032b2 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/core_cm0plus.h @@ -0,0 +1,1083 @@ +/**************************************************************************//** + * @file core_cm0plus.h + * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File + * @version V5.0.6 + * @date 28. May 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0PLUS_H_GENERIC +#define __CORE_CM0PLUS_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ +/* polyspace-begin DEFECT:* MISRA2012:* */ + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex-M0+ + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM0+ definitions */ +#define __CM0PLUS_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0PLUS_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \ + __CM0PLUS_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (0U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0PLUS_H_DEPENDANT +#define __CORE_CM0PLUS_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0PLUS_REV + #define __CM0PLUS_REV 0x0000U + #warning "__CM0PLUS_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex-M0+ */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0+ header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0+ */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; + +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + +/* polyspace-end DEFECT:* MISRA2012:* */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/mpu_armv7.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/mpu_armv7.h new file mode 100644 index 0000000..0142203 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/mpu_armv7.h @@ -0,0 +1,270 @@ +/****************************************************************************** + * @file mpu_armv7.h + * @brief CMSIS MPU API for Armv7-M MPU + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV7_H +#define ARM_MPU_ARMV7_H + +#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes +#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes +#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes +#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes +#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes +#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte +#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes +#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes +#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes +#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes +#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes +#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes +#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes +#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes +#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes +#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte +#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes +#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes +#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes +#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes +#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes +#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes +#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes +#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes +#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes +#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte +#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes +#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes + +#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access +#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only +#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only +#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access +#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only +#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access + +/** MPU Region Base Address Register Value +* +* \param Region The region to be configured, number 0 to 15. +* \param BaseAddress The base address for the region. +*/ +#define ARM_MPU_RBAR(Region, BaseAddress) \ + (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ + ((Region) & MPU_RBAR_REGION_Msk) | \ + (MPU_RBAR_VALID_Msk)) + +/** +* MPU Memory Access Attributes +* +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +*/ +#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ + ((((TypeExtField ) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ + (((IsShareable ) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ + (((IsCacheable ) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ + (((IsBufferable ) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ + ((((DisableExec ) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ + (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ + (((AccessAttributes) ) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ + ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) + +/** +* MPU Memory Access Attribute for strongly ordered memory. +* - TEX: 000b +* - Shareable +* - Non-cacheable +* - Non-bufferable +*/ +#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) + +/** +* MPU Memory Access Attribute for device memory. +* - TEX: 000b (if non-shareable) or 010b (if shareable) +* - Shareable or non-shareable +* - Non-cacheable +* - Bufferable (if shareable) or non-bufferable (if non-shareable) +* +* \param IsShareable Configures the device memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) + +/** +* MPU Memory Access Attribute for normal memory. +* - TEX: 1BBb (reflecting outer cacheability rules) +* - Shareable or non-shareable +* - Cacheable or non-cacheable (reflecting inner cacheability rules) +* - Bufferable or non-bufferable (reflecting inner cacheability rules) +* +* \param OuterCp Configures the outer cache policy. +* \param InnerCp Configures the inner cache policy. +* \param IsShareable Configures the memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) & 2U), ((InnerCp) & 1U)) + +/** +* MPU Memory Access Attribute non-cacheable policy. +*/ +#define ARM_MPU_CACHEP_NOCACHE 0U + +/** +* MPU Memory Access Attribute write-back, write and read allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_WRA 1U + +/** +* MPU Memory Access Attribute write-through, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WT_NWA 2U + +/** +* MPU Memory Access Attribute write-back, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_NWA 3U + + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; //!< The region base address register value (RBAR) + uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DSB(); + __ISB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DSB(); + __ISB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + MPU->RNR = rnr; + MPU->RASR = 0U; +} + +/** Configure an MPU region. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) +{ + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) +{ + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + while (cnt > MPU_TYPE_RALIASES) { + orderedCpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); + table += MPU_TYPE_RALIASES; + cnt -= MPU_TYPE_RALIASES; + } + orderedCpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); +} + +#endif diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cpu_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cpu_drv.h new file mode 100644 index 0000000..1128406 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cpu_drv.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CPU_DRV_H_ +#define _CPU_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the CPU + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "cva/CVM011x.h" +#include "irq/irq_drv.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************************* + * the defines + ******************************************************************************/ + + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + + +/******************************************************************************* + * the globals + ******************************************************************************/ + + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Enter supervisor mode + * + * This function convert CPU into supervisor mode. + * + */ +static inline void CpuDrv_EnterSupervisorMode(void) +{ + /* if CPU in user mode */ + if ((__get_CONTROL() & 0x1) == 1) + { + /* change to privilege mode */ + __asm("svc #0x32"); + } +} + +/*! \brief Change to supervisor mode + * + * This function change the CPU into supervisor mode. + * + */ +static inline void CpuDrv_ChangeToSupervisorMode(void) +{ + __asm(" MOVS R0, #0x0 "); + __asm(" MSR CONTROL, R0 "); + __asm("DSB"); + __asm("ISB"); +} + +/*! \brief Enter user mode + * + * This function change the CPU into user mode. + * + */ +static inline void CpuDrv_EnterUserMode(void) +{ + __asm(" MOVS R0, #0x1 "); + __asm(" MSR CONTROL, R0 "); + __asm("DSB"); + __asm("ISB"); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + + +#endif /* _CPU_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cva/CVM011x.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cva/CVM011x.h new file mode 100644 index 0000000..0ee19f4 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cva/CVM011x.h @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CVM011X_H_ +#define _CVM011X_H_ + +/*! \brief Contains public interface to various functions related + * to all the registers of CVM011x series chips + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the Interrupt Number Definition + ******************************************************************************/ + +typedef enum +{ + /* Core interrupts */ + NonMaskableInt_IRQn = -14, /**< Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< Cortex-M0 SV Hard Fault Interrupt */ + SVCall_IRQn = -5, /**< Cortex-M0 SV Call Interrupt */ + PendSV_IRQn = -2, /**< Cortex-M0 Pend SV Interrupt */ + SysTick_IRQn = -1, /**< Cortex-M0 System Tick Interrupt */ + + /* CVM011x specific interrupts */ + DMA01_IRQn = 0u, /**< DMA channel 0,1 transfer complete */ + DMA23_IRQn = 1u, /**< DMA channel 2,3 transfer complete */ + DMA_Error_IRQn = 2u, /**< DMA error interrupt channels 0-3 */ + FHU_IRQn = 3u, /**< FHU Interrupt, ERM single bit error correction */ + RTC_Alarm_IRQn = 4u, /**< RTC alarm interrupt */ + RTC_Seconds_IRQn = 5u, /**< RTC seconds interrupt */ + LPTMR_IRQn = 6u, /**< LPTIMER interrupt request */ + PORT_IRQn = 7u, /**< Port ABCDE pin detect interrupt */ + CAN_ORed_IRQn = 8u, /**< CAN OR'ed [BusOff\BusOffDone\TransWarning\ReceiveWarning\..... ] */ + CAN_ORed_0_31_MB_IRQn = 9u, /**< CAN OR'ed Message buffer (0-31) */ + CAN_ORed_32_63_MB_IRQn = 10u, /**< CAN OR'ed Message buffer (32-63) */ + MFT0_Ch0_Ch7_IRQn = 11u, /**< MFT0 Channel 0 to 7 interrupt */ + MFT0_Fault_IRQn = 12u, /**< MFT0 Fault interrupt */ + MFT0_Ovf_Reload_IRQn = 13u, /**< MFT0 Counter overflow and Reload interrupt */ + MFT1_Ch0_Ch7_IRQn = 14u, /**< MFT1 Channel 0 to 7 interrupt */ + MFT1_Fault_IRQn = 15u, /**< MFT1 Fault interrupt */ + MFT1_Ovf_Reload_IRQn = 16u, /**< MFT1 Counter overflow and Reload interrupt */ + FTFC_IRQn = 17u, /**< FTFC Command done,read collision,err response interrupt */ + PDB_IRQn = 18u, /**< PDB interrupt */ + LPIT_IRQn = 19u, /**< LPIT interrupt */ + CMU_IRQn = 20u, /**< CMU PLL,SOSC interrupt */ + WDOG_IRQn = 21u, /**< Interrupt request out before wdg reset out */ + RCM_IRQn = 22u, /**< RCM Asynchronous Interrupt, Reset interrutpt */ + I2C_IRQn = 23u, /**< I2C Interrupt */ + SPI0_IRQn = 24u, /**< SPI0 Interrupt */ + SPI1_IRQn = 25u, /**< SPI1 Interrupt */ + ADC_IRQn = 26u, /**< ADC interrupt request. */ + CMP_IRQn = 27u, /**< CMP interrupt request */ + I2S_SLV_MST_IRQn = 28u, /**< I2S Slave and Master interrupt */ + UART0_RxTx_IRQn = 29u, /**< UART0 Transmit / Receive Interrupt */ + UART1_RxTx_IRQn = 30u, /**< UART1 Transmit / Receive Interrupt */ + UART2_RxTx_IRQn = 31u, /**< UART2 Transmit / Receive Interrupt */ +} IRQn_Type; + +/******************************************************************************* + * the Processor and Core Peripheral Section + ******************************************************************************/ + +#define __NVIC_PRIO_BITS 2 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +/* ToDo: define __FPU_PRESENT if your devise is a CORTEX-M4 */ +#define __FPU_PRESENT 0 /*!< FPU present or not */ + +#define __VTOR_PRESENT 1 + +#include "../cmsis/core_cm0plus.h" + +/******************************************************************************* + * the Device Specific Peripheral registers structures + ******************************************************************************/ + +#include "mscm_reg.h" +#include "cmu_reg.h" +#include "fhu_reg.h" +#include "edma_reg.h" +#include "crc_reg.h" +#include "mpu_reg.h" +#include "erm_reg.h" +#include "eim_reg.h" +#include "ftfc_reg.h" +#include "dmamux_reg.h" +#include "axbs_reg.h" +#include "adc_reg.h" +#include "pdb_reg.h" +#include "spi_reg.h" +#include "mft_reg.h" +#include "gpio_reg.h" +#include "flexcan_reg.h" +#include "pwmlite_reg.h" +#include "trgmux_reg.h" +#include "sim_reg.h" +#include "port_reg.h" +#include "i2c_reg.h" +#include "uart_reg.h" +#include "scg0_reg.h" +#include "scg1_reg.h" +#include "scg2_reg.h" +#include "pcc0_reg.h" +#include "pcc1_reg.h" +#include "i2sm_reg.h" +#include "i2ss_reg.h" +#include "cmp_reg.h" +#include "lptmr_reg.h" +#include "lpit_reg.h" +#include "rtc_reg.h" +#include "wdg_reg.h" +#include "pmc_reg.h" +#include "rcm_reg.h" + +/******************************************************************************* + * the Peripheral memory map + ******************************************************************************/ + +/* MSCM module */ +#define MSCM_BASE (0x40001000u) +#define MSCM ((MscmRegType *)MSCM_BASE) + +/* CMU module */ +#define CMU_PLL_BASE (0x40003000u) +#define CMU_PLL ((CmuRegType *)CMU_PLL_BASE) +#define CMU_SOSC_BASE (0x40004000u) +#define CMU_SOSC ((CmuRegType *)CMU_SOSC_BASE) + +/* FHU module */ +#define FHU_BASE (0x40005000u) +#define FHU ((FhuRegType *)FHU_BASE) + +/* DMA module */ +#define DMA_BASE (0x40008000u) +#define DMA ((EDmaRegType *)DMA_BASE) + +/* CRC module */ +#define CRC_BASE (0x4000C000u) +#define CRC ((CrcRegType *)CRC_BASE) + +/* MPU module */ +#define MPU_BASE (0x4000D000u) +#define MPU ((MpuRegType *)MPU_BASE) + +/* ERM module */ +#define ERM_BASE (0x40018000u) +#define ERM ((ErmRegType *)ERM_BASE) + +/* EIM module */ +#define EIM_BASE (0x40019000u) +#define EIM ((EimRegType *)EIM_BASE) + +/* FTFC module */ +#define FTFC_BASE (0x40020000u) +#define FTFC ((FtfcRegType *)FTFC_BASE) + +/* DMAMUX module */ +#define DMAMUX_BASE (0x40021000u) +#define DMAMUX ((DmamuxRegType *)DMAMUX_BASE) + +/* AXBS module */ +#define AXBS_BASE (0x40022000u) +#define AXBS ((AxbsRegType *)AXBS_BASE) + +/* ADC modules */ +#define ADC_BASE (0x40024000u) +#define ADC ((AdcRegType *)ADC_BASE) + +/* PDB modules */ +#define PDB_BASE (0x40026000u) +#define PDB ((PdbRegType *)PDB_BASE) + +/* SPI modules */ +#define SPI0_BASE (0x4002C000u) +#define SPI0 ((SpiRegType *)SPI0_BASE) +#define SPI1_BASE (0x4002D000u) +#define SPI1 ((SpiRegType *)SPI1_BASE) + +/* MFT modules */ +#define MFT0_BASE (0x40030000u) +#define MFT0 ((MftRegType *)MFT0_BASE) +#define MFT1_BASE (0x40031000u) +#define MFT1 ((MftRegType *)MFT1_BASE) + +/* GPIO modules */ +#define GPIOA_BASE (0x40035000u) +#define GPIOA ((GpioRegType *)GPIOA_BASE) +#define GPIOB_BASE (0x40035040u) +#define GPIOB ((GpioRegType *)GPIOB_BASE) +#define GPIOC_BASE (0x40035080u) +#define GPIOC ((GpioRegType *)GPIOC_BASE) +#define GPIOD_BASE (0x400350C0u) +#define GPIOD ((GpioRegType *)GPIOD_BASE) +#define GPIOE_BASE (0x40035100u) +#define GPIOE ((GpioRegType *)GPIOE_BASE) + +/* CAN modules */ +#define CAN_BASE (0x40038000u) +#define CAN ((FlexCanRegType *)CAN_BASE) + +/* PWMLITE modules */ +#define PWMLITE0_BASE (0x40058000u) +#define PWMLITE0 ((PwmLiteRegType *)PWMLITE0_BASE) +#define PWMLITE1_BASE (0x40059000u) +#define PWMLITE1 ((PwmLiteRegType *)PWMLITE1_BASE) + +/* TRGMUX module */ +#define TRGMUX_BASE (0x4005E000u) +#define TRGMUX ((TrgMuxRegType *)TRGMUX_BASE) + +/* SIM module */ +#define SIM_BASE (0x4005F000u) +#define SIM ((SimRegType *)SIM_BASE) + +/* PORT modules */ +#define PORTA_BASE (0x40060000u) +#define PORTA ((PortRegType *)PORTA_BASE) +#define PORTB_BASE (0x40061000u) +#define PORTB ((PortRegType *)PORTB_BASE) +#define PORTC_BASE (0x40062000u) +#define PORTC ((PortRegType *)PORTC_BASE) +#define PORTD_BASE (0x40063000u) +#define PORTD ((PortRegType *)PORTD_BASE) +#define PORTE_BASE (0x40064000u) +#define PORTE ((PortRegType *)PORTE_BASE) + +/* I2C modules */ +#define I2C_BASE (0x40066000u) +#define I2C ((I2cRegType *)I2C_BASE) + +/* UART module */ +#define UART0_BASE (0x4006A000u) +#define UART0 ((UartRegType *)UART0_BASE) +#define UART1_BASE (0x4006B000u) +#define UART1 ((UartRegType *)UART1_BASE) +#define UART2_BASE (0x4006C000u) +#define UART2 ((UartRegType *)UART2_BASE) + +/* SCG0 module */ +#define SCG0_BASE (0x4006E000u) +#define SCG0 ((Scg0RegType *)SCG0_BASE) +/* SCG1 module */ +#define SCG1_BASE (0x4006E400u) +#define SCG1 ((Scg1RegType *)SCG1_BASE) +/* SCG2 module */ +#define SCG2_BASE (0x4006E800u) +#define SCG2 ((Scg2RegType *)SCG2_BASE) + +/* PCC0 module */ +#define PCC0_BASE (0x4006F000u) +#define PCC0 ((Pcc0RegType *)PCC0_BASE) +/* PCC1 module */ +#define PCC1_BASE (0x4006F800u) +#define PCC1 ((Pcc1RegType *)PCC1_BASE) + +/* I2SM module */ +#define I2SM_BASE (0x40072000u) +#define I2SM ((I2smRegType *)I2SM_BASE) + +/* I2SS module */ +#define I2SS_BASE (0x40073000u) +#define I2SS ((I2ssRegType *)I2SS_BASE) + +/* CMP module */ +#define CMP_BASE (0x40074000u) +#define CMP ((CmpRegType *)CMP_BASE) + +/* LPTMR module */ +#define LPTMR_BASE (0x40075000u) +#define LPTMR ((LptmrRegType *)LPTMR_BASE) + +/* LPIT module */ +#define LPIT_BASE (0x40077000u) +#define LPIT ((LpitRegType *)LPIT_BASE) + +/* RTC module */ +#define RTC_BASE (0x40078000u) +#define RTC ((RtcRegType *)RTC_BASE) + +/* WDG module */ +#define WDG_BASE (0x4007A000u) +#define WDG ((WdgRegType *)WDG_BASE) + +/* PMC module */ +#define PMC_BASE (0x4007D000u) +#define PMC ((PmcRegType *)PMC_BASE) + +/* RCM module */ +#define RCM_BASE (0x4007F000u) +#define RCM ((RcmRegType *)RCM_BASE) + +/* GPIO_IOP modules */ +#define GPIOA_IOP_BASE (0xF8000000u) +#define GPIOA_IOP ((GpioRegType *)GPIOA_IOP_BASE) +#define GPIOB_IOP_BASE (0xF8000040u) +#define GPIOB_IOP ((GpioRegType *)GPIOB_IOP_BASE) +#define GPIOC_IOP_BASE (0xF8000080u) +#define GPIOC_IOP ((GpioRegType *)GPIOC_IOP_BASE) +#define GPIOD_IOP_BASE (0xF80000C0u) +#define GPIOD_IOP ((GpioRegType *)GPIOD_IOP_BASE) +#define GPIOE_IOP_BASE (0xF8000100u) +#define GPIOE_IOP ((GpioRegType *)GPIOE_IOP_BASE) + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _CVM011X_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/irq/irq_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/irq/irq_drv.c new file mode 100644 index 0000000..3193ce7 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/irq/irq_drv.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "irq_drv.h" +#include "../cva/CVM011x.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* The last IRQn defined by this chip */ +#define LAST_IRQn (UART2_RxTx_IRQn) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/*! Those symbols are defined in the startup code */ +#if defined(__ARMCC_VERSION) +extern uint32_t __VECTOR_RAM; +extern uint32_t __VECTOR_ROM; +extern uint32_t __DATA_ROM; +extern uint32_t __RAM_START; +#else +#if defined(__ICCARM__) +extern uint32_t __RAM_START[]; +#pragma section = "__CODE_ROM" +extern uint32_t CODE_ROM_SECTION_START = (uint32_t)__section_begin("__CODE_ROM"); +#endif +extern uint32_t __VECTOR_RAM[((uint32_t)(LAST_IRQn)) + 16U + 1U]; +extern uint32_t __VECTOR_TABLE[((uint32_t)(LAST_IRQn)) + 16U + 1U]; +extern uint32_t __DATA_ROM[]; +extern uint32_t __DATA_END[]; +#endif + +/*! Counter to manage the nested callings of global disable/enable interrupt. */ +static int32_t s_interruptDisableCount = 0; + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void IrqDrv_InstallHandler(uint16_t irqNumber, IrqHandlerType newHandler, IrqHandlerType *oldHandler) +{ + const uint32_t *aVectorRam = (uint32_t *)__VECTOR_RAM; +#if defined(__ARMCC_VERSION) + const uint32_t *aVectorTable = (uint32_t *)__VECTOR_ROM; +#else + const uint32_t *aVectorTable = (uint32_t *)__VECTOR_TABLE; +#endif + + /* Check whether there is vector table in RAM */ +#if defined(__ARMCC_VERSION) + if((aVectorRam != aVectorTable) || (__DATA_ROM > __RAM_START)) /* polyspace DEFECT:USELESS_IF [No action planned:Low] "Depend on link script" */ +#elif(defined(__ICCARM__)) + if((aVectorRam != aVectorTable) || ((uint32_t)CODE_ROM_SECTION_START > (uint32_t)__RAM_START)) /* polyspace DEFECT:USELESS_IF [No action planned:Low] "Depend on link script" */ +#else + const uint32_t *aDataRom = (uint32_t *)__DATA_ROM; + const uint32_t *aDataRam = (uint32_t *)__DATA_END; + if((aVectorRam != aVectorTable) || (aDataRom == aDataRam)) /* polyspace DEFECT:USELESS_IF [No action planned:Low] "Depend on link script" */ +#endif + { + uint32_t *pVectorRam = (uint32_t *)__VECTOR_RAM; + /* Save the former handler pointer */ + if(oldHandler != (IrqHandlerType *)0) + { + *oldHandler = (IrqHandlerType)pVectorRam[((int32_t)irqNumber) + 16]; + } + /* Set handler into vector table */ + pVectorRam[((int32_t)irqNumber) + 16] = (uint32_t)newHandler; + } +} + +void IrqDrv_EnableGlobalInterrupt(void) +{ + /* Check and update */ + if(s_interruptDisableCount > 0) + { + s_interruptDisableCount--; + if(s_interruptDisableCount <= 0) + { +/* Enable the global interrupt*/ +#if defined(__GNUC__) + __asm volatile("cpsie i" + : + : + : "memory"); +#else + __asm("cpsie i"); +#endif + } + } +} + +void IrqDrv_DisableGlobalInterrupt(void) +{ +/* Disable the global interrupt */ +#if defined(__GNUC__) + __asm volatile("cpsid i" + : + : + : "memory"); +#else + __asm("cpsid i"); +#endif + /* Update counter*/ + s_interruptDisableCount++; +} + +void IrqDrv_EnableIrq(uint16_t irqNumber) +{ + NVIC_EnableIRQ((IRQn_Type)irqNumber); +} + +void IrqDrv_DisableIrq(uint16_t irqNumber) +{ + NVIC_DisableIRQ((IRQn_Type)irqNumber); +} + +void IrqDrv_SetPriority(uint16_t irqNumber, uint32_t preemptPriority, uint32_t subPriority) +{ + NVIC_SetPriority((IRQn_Type)irqNumber, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), preemptPriority, subPriority)); +} + +void IrqDrv_GetPriority(uint16_t irqNumber, uint32_t *pPreemptPriority, uint32_t *pSubPriority) +{ + NVIC_DecodePriority(NVIC_GetPriority((IRQn_Type)irqNumber), NVIC_GetPriorityGrouping(), pPreemptPriority, pSubPriority); +} + +void IrqDrv_ClearPending(uint16_t irqNumber) +{ + NVIC_ClearPendingIRQ((IRQn_Type)irqNumber); +} + +void IrqDrv_SetPending(uint16_t irqNumber) +{ + NVIC_SetPendingIRQ((IRQn_Type)irqNumber); +} + +bool IrqDrv_IsPending(uint16_t irqNumber) +{ + return NVIC_GetPendingIRQ((IRQn_Type)irqNumber) == 1; +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/irq/irq_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/irq/irq_drv.h new file mode 100644 index 0000000..152b219 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/irq/irq_drv.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _IRQ_DRV_H_ +#define _IRQ_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of interrupt requests + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup irq_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Interrupt handler type */ +typedef void (*IrqHandlerType)(void); + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Installs an interrupt handler routine for a given IRQ number. + * + * This function lets the application register/replace the interrupt + * handler for a specified IRQ number. See a chip-specific reference + * manual for details and the startup_.s file for each chip + * family to find out the default interrupt handler for each device. + * + * \note This method is applicable only if interrupt vector is copied in RAM. + * + * \param[in] irqNumber : IRQ number + * \param[in] newHandler : New interrupt handler routine address pointer + * \param[in] oldHandler : Pointer to a location to store current interrupt handler + */ +extern void IrqDrv_InstallHandler(uint16_t irqNumber, IrqHandlerType newHandler, IrqHandlerType *oldHandler); + +/*! \brief Enables system interrupt. + * + * This function enables the global interrupt by calling the core API. + * + */ +extern void IrqDrv_EnableGlobalInterrupt(void); + +/*! \brief Disable system interrupt. + * + * This function disables the global interrupt by calling the core API. + * + */ +extern void IrqDrv_DisableGlobalInterrupt(void); + +/*! \brief Enables an interrupt for a given IRQ number. + * + * This function enables the individual interrupt for a specified IRQ number. + * + * \param[in] irqNumber : IRQ number + */ +extern void IrqDrv_EnableIrq(uint16_t irqNumber); + +/*! \brief Disables an interrupt for a given IRQ number. + * + * This function disables the individual interrupt for a specified IRQ number. + * + * \param[in] irqNumber : IRQ number + */ +extern void IrqDrv_DisableIrq(uint16_t irqNumber); + +/*! \brief Set Interrupt Priority + * + * The function sets the priority of an interrupt. + * + * \param[in] irqNumber : Interrupt number + * \param[in] preemptPriority : Preemptive priority value (starting from 0). + * \param[in] subPriority : Subpriority value (starting from 0). + */ +extern void IrqDrv_SetPriority(uint16_t irqNumber, uint32_t preemptPriority, uint32_t subPriority); + +/*! \brief Get Interrupt Priority + * + * The function gets the priority of an interrupt. + * + * \param[in] irqNumber : Interrupt number. + * \param[out] pPreemptPriority : Preemptive priority value (starting from 0). + * \param[out] pSubPriority : Subpriority value (starting from 0). + */ +extern void IrqDrv_GetPriority(uint16_t irqNumber, uint32_t *pPreemptPriority, uint32_t *pSubPriority); + +/*! \brief Clear Pending Interrupt + * + * The function clears the pending bit of a peripheral interrupt + * or a directed interrupt to this CPU (if available). + * + * \param[in] irqNumber : IRQ number + */ +extern void IrqDrv_ClearPending(uint16_t irqNumber); + +/*! \brief Set Pending Interrupt + * + * The function configures the pending bit of a peripheral interrupt. + * + * \param[in] irqNumber : IRQ number + */ +extern void IrqDrv_SetPending(uint16_t irqNumber); + +/*! \brief Whether the Interrupt is Pending + * + * The function gets the pending bit of a peripheral interrupt + * or a directed interrupt to this CPU (if available). + * + * \param[in] irqNumber : IRQ number + * \return pending status + * - false : Interrupt status is not pending. + * - true : Interrupt status is pending. + */ +extern bool IrqDrv_IsPending(uint16_t irqNumber); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _IRQ_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/startup.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/startup.c new file mode 100644 index 0000000..259a5eb --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/startup.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "startup.h" +#include +#include "../cva/CVM011x.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void init_data_bss(void) +{ + uint32_t n; +/* For ARMC we are using the library method of initializing DATA, Custom Section and + * Code RAM sections so the below variables are not needed */ +#if !defined(__ARMCC_VERSION) + /* Declare pointers for various data sections. These pointers + * are initialized using values pulled in from the linker file */ + uint8_t* data_ram; + uint8_t* code_ram; + uint8_t* bss_start; + uint8_t* custom_ram; + const uint8_t *data_rom, *data_rom_end; + const uint8_t *code_rom, *code_rom_end; + const uint8_t* bss_end; + const uint8_t *custom_rom, *custom_rom_end; +#endif + /* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */ + +#if defined(__ARMCC_VERSION) + extern uint32_t __RAM_VECTOR_TABLE_SIZE; + extern uint32_t __VECTOR_ROM; + extern uint32_t __VECTOR_RAM; +#else + extern uint32_t __RAM_VECTOR_TABLE_SIZE[]; + extern uint32_t __VECTOR_TABLE[]; + extern uint32_t __VECTOR_RAM[]; +#endif + /* Get section information from linker files */ +#if defined(__ICCARM__) + /* Data */ + data_ram = __section_begin(".data"); + data_rom = __section_begin(".data_init"); + data_rom_end = __section_end(".data_init"); + +/* CODE RAM */ +#pragma section = "__CODE_ROM" +#pragma section = "__CODE_RAM" + code_ram = __section_begin("__CODE_RAM"); + code_rom = __section_begin("__CODE_ROM"); + code_rom_end = __section_end("__CODE_ROM"); + + /* BSS */ + bss_start = __section_begin(".bss"); + bss_end = __section_end(".bss"); + + custom_ram = __section_begin(".customSection"); + custom_rom = __section_begin(".customSection_init"); + custom_rom_end = __section_end(".customSection_init"); + +#elif defined(__ARMCC_VERSION) + /* VECTOR TABLE*/ + uint8_t *vector_table_size = (uint8_t *)__RAM_VECTOR_TABLE_SIZE; + uint32_t *vector_rom = (uint32_t *)__VECTOR_ROM; + uint32_t *vector_ram = (uint32_t *)__VECTOR_RAM; +#else + extern uint32_t __DATA_ROM[]; + extern uint32_t __DATA_RAM[]; + extern uint32_t __DATA_END[]; + + extern uint32_t __CODE_RAM[]; + extern uint32_t __CODE_ROM[]; + extern uint32_t __CODE_END[]; + + extern uint32_t __BSS_START[]; + extern uint32_t __BSS_END[]; + + extern uint32_t __CUSTOM_ROM[]; + extern uint32_t __CUSTOM_END[]; + + /* Data */ + data_ram = (uint8_t *)__DATA_RAM; + data_rom = (uint8_t *)__DATA_ROM; + data_rom_end = (uint8_t *)__DATA_END; + /* CODE RAM */ + code_ram = (uint8_t *)__CODE_RAM; + code_rom = (uint8_t *)__CODE_ROM; + code_rom_end = (uint8_t *)__CODE_END; + /* BSS */ + bss_start = (uint8_t *)__BSS_START; + bss_end = (uint8_t *)__BSS_END; + + /* Custom section */ + custom_ram = CUSTOMSECTION_SECTION_START; + custom_rom = (uint8_t *)__CUSTOM_ROM; + custom_rom_end = (uint8_t *)__CUSTOM_END; + +#endif + +#if !defined(__ARMCC_VERSION) + /* Copy initialized data from ROM to RAM */ + while(data_rom_end != data_rom) + { + *data_ram = *data_rom; + data_ram++; + data_rom++; + } + + /* Copy functions from ROM to RAM */ + while(code_rom_end != code_rom) + { + *code_ram = *code_rom; + code_ram++; + code_rom++; + } + + /* Clear the zero-initialized data section */ + while(bss_end != bss_start) + { + *bss_start = 0; + bss_start++; + } + + /* Copy customsection rom to ram */ + while(custom_rom_end != custom_rom) + { + *custom_ram = *custom_rom; + custom_rom++; + custom_ram++; + } +#endif +#if defined(__ARMCC_VERSION) + /* Copy the vector table from ROM to RAM */ + /* Workaround */ + if(vector_ram != vector_rom) + { + for(n = 0; n < (((uint32_t)(vector_table_size)) / sizeof(uint32_t)); n++) + { + vector_ram[n] = vector_rom[n]; + } + /* Point the VTOR to the position of vector table */ + SCB->VTOR = (uint32_t)__VECTOR_RAM; + } + else + { + /* Point the VTOR to the position of vector table */ + SCB->VTOR = (uint32_t)__VECTOR_ROM; + } +#else + /* Check if VECTOR_TABLE copy is needed */ + if(__VECTOR_RAM != __VECTOR_TABLE) /* polyspace DEFECT:DEAD_CODE [No action planned:Low] "Depend on link script" */ + { + /* Copy the vector table from ROM to RAM */ + for(n = 0; n < (((uint32_t)__RAM_VECTOR_TABLE_SIZE) / sizeof(uint32_t)); n++) + { + __VECTOR_RAM[n] = __VECTOR_TABLE[n]; + } + /* Point the VTOR to the position of vector table */ + SCB->VTOR = (uint32_t)__VECTOR_RAM; + } + else + { + /* Point the VTOR to the position of vector table */ + SCB->VTOR = (uint32_t)__VECTOR_TABLE; + } +#endif +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/startup.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/startup.h new file mode 100644 index 0000000..4d0e3c6 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/startup.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _STARTUP_H_ +#define _STARTUP_H_ + +#include + +/*! \brief Contains public interface to various functions related + * to the startup of this chip + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/*! \brief define symbols that specific start and end addres of some basic sections. + */ +#if(defined(__ICCARM__)) +#define INTERRUPTS_SECTION_START __section_begin(".intvec") +#define INTERRUPTS_SECTION_END __section_end(".intvec") +#define BSS_SECTION_START __section_begin(".bss") +#define BSS_SECTION_END __section_end(".bss") +#define DATA_SECTION_START __section_begin(".data") +#define DATA_SECTION_END __section_end(".data") +#define CUSTOMSECTION_SECTION_START __section_begin(".customSection") +#define CUSTOMSECTION_SECTION_END __section_end(".customSection") +#define CODE_RAM_SECTION_START __section_begin("__CODE_RAM") +#define CODE_RAM_SECTION_END __section_end("__CODE_RAM") +#define DATA_INIT_SECTION_START __section_begin(".data_init") +#define DATA_INIT_SECTION_END __section_end(".data_init") +#define CODE_ROM_SECTION_START __section_begin("__CODE_ROM") +#define CODE_ROM_SECTION_END __section_end("__CODE_ROM") + +#elif(defined(__ARMCC_VERSION)) +#define INTERRUPTS_SECTION_START (uint8_t *)__VECTOR_ROM_START +#define INTERRUPTS_SECTION_END (uint8_t *)__VECTOR_ROM_END +#define BSS_SECTION_START (uint8_t *)__BSS_START +#define BSS_SECTION_END (uint8_t *)__BSS_END +#define DATA_SECTION_START (uint8_t *)__DATA_RAM_START +#define DATA_SECTION_END (uint8_t *)__DATA_RAM_END +#define CUSTOMSECTION_SECTION_START (uint8_t *)__CUSTOM_SECTION_START +#define CUSTOMSECTION_SECTION_END (uint8_t *)__CUSTOM_SECTION_END +#define CODE_RAM_SECTION_START (uint8_t *)__CODE_RAM_START +#define CODE_RAM_SECTION_END (uint8_t *)__CODE_RAM_END + +extern uint32_t __VECTOR_ROM_START; +extern uint32_t __VECTOR_ROM_END; +extern uint32_t __BSS_START; +extern uint32_t __BSS_END; +extern uint32_t __DATA_RAM_START; +extern uint32_t __DATA_RAM_END; +extern uint32_t __CUSTOM_SECTION_START; +extern uint32_t __CUSTOM_SECTION_END; +extern uint32_t __CODE_RAM_START; +extern uint32_t __CODE_RAM_END; +#else +#define INTERRUPTS_SECTION_START (uint8_t *)&__interrupts_start__ +#define INTERRUPTS_SECTION_END (uint8_t *)&__interrupts_end__ +#define BSS_SECTION_START (uint8_t *)&__bss_start__ +#define BSS_SECTION_END (uint8_t *)&__bss_end__ +#define DATA_SECTION_START (uint8_t *)&__data_start__ +#define DATA_SECTION_END (uint8_t *)&__data_end__ +#define CUSTOMSECTION_SECTION_START (uint8_t *)&__customSection_start__ +#define CUSTOMSECTION_SECTION_END (uint8_t *)&__customSection_end__ +#define CODE_RAM_SECTION_START (uint8_t *)&__code_ram_start__ +#define CODE_RAM_SECTION_END (uint8_t *)&__code_ram_end__ + +extern uint32_t __interrupts_start__; +extern uint32_t __interrupts_end__; +extern uint32_t __bss_start__; +extern uint32_t __bss_end__; +extern uint32_t __data_start__; +extern uint32_t __data_end__; +extern uint32_t __customSection_start__; +extern uint32_t __customSection_end__; +extern uint32_t __code_ram_start__; +extern uint32_t __code_ram_end__; +#endif + +#if(defined(__ICCARM__)) +#pragma section = ".data" +#pragma section = ".data_init" +#pragma section = ".bss" +#pragma section = ".intvec" +#pragma section = ".customSection" +#pragma section = ".customSection_init" +#pragma section = "__CODE_RAM" +#pragma section = "__CODE_ROM" +#endif + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Make necessary initializations for RAM. + * + * - Copy initialized data from ROM to RAM. + * - Clear the zero-initialized data section. + * - Copy the vector table from ROM to RAM. This could be an option. + */ +void init_data_bss(void); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _STARTUP_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/startup_M011x.S b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/startup_M011x.S new file mode 100644 index 0000000..0fb0063 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/startup_M011x.S @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/*****************************************************************************/ +/* Version: GNU Compiler Collection */ +/*****************************************************************************/ + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:ROOT(2) + + EXTERN main + EXTERN SystemInit + EXTERN init_data_bss + PUBLIC __vector_table + PUBLIC __vector_table_0x1c + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA + +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; Non Maskable Interrupt + DCD HardFault_Handler ; Cortex-M0 SV Hard Fault Interrupt + DCD 0 + DCD 0 + DCD 0 +__vector_table_0x1c + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD SVC_Handler ; Cortex-M0 SV Call Interrupt + DCD 0 + DCD 0 + DCD PendSV_Handler ; Cortex-M0 Pend SV Interrupt + DCD SysTick_Handler ; Cortex-M0 System Tick Interrupt + + + DCD DMA01_Handler /* 0 (040H) DMA channel 0,1 transfer complete*/ + DCD DMA23_Handler /* 1 (044H) DMA channel 2,3 transfer complete*/ + DCD DMA_Error_Handler /* 2 (048H) DMA error interrupt channels 0-3*/ + DCD FHU_Handler /* 3 (04CH) FHU Interrupt, ERM single bit error correction*/ + DCD RTC_Alarm_Handler /* 4 (050H) RTC alarm interrupt*/ + DCD RTC_Seconds_Handler /* 5 (054H) RTC seconds interrupt*/ + DCD LPTMR_Handler /* 6 (058H) LPTIMER interrupt request*/ + DCD PORT_Handler /* 7 (05CH) Port ABCDE pin detect interrupt */ + DCD CAN_ORed_Handler /* 8 (060H) CAN OR'ed [BusOff\BusOffDone\TransWarning\ReceiveWarning\..... ] */ + DCD CAN_ORed_0_31_MB_Handler /* 9 (064H) CAN OR'ed Message buffer (0-31) */ + DCD CAN_ORed_32_63_MB_Handler /* 10 (068H) CAN OR'ed Message buffer (32-63) */ + DCD MFT0_Ch0_Ch7_Handler /* 11 (06CH) MFT0 Channel 0 to 7 interrupt */ + DCD MFT0_Fault_Handler /* 12 (070H) MFT0 Fault interrupt */ + DCD MFT0_Ovf_Reload_Handler /* 13 (074H) MFT0 Counter overflow and Reload interrupt */ + DCD MFT1_Ch0_Ch7_Handler /* 14 (078H) MFT1 Channel 0 to 7 interrupt */ + DCD MFT1_Fault_Handler /* 15 (07CH) MFT1 Fault interrupt */ + DCD MFT1_Ovf_Reload_Handler /* 16 (080H) MFT1 Counter overflow and Reload interrupt */ + DCD FTFC_Handler /* 17 (084H) FTFC Command done,read collision,err response interrupt */ + DCD PDB_Handler /* 18 (088H) PDB interrupt */ + DCD LPIT_Handler /* 19 (08CH) LPIT interrupt */ + DCD CMU_Handler /* 20 (090H) CMU PLL,SOSC interrupt */ + DCD WDOG_Handler /* 21 (094H) Interrupt request out before wdg reset out */ + DCD RCM_Handler /* 22 (098H) RCM Asynchronous Interrupt, Reset interrutpt */ + DCD I2C_Handler /* 23 (09CH) I2C Interrupt */ + DCD SPI0_Handler /* 24 (0A0H) SPI0 Interrupt */ + DCD SPI1_Handler /* 25 (0A4H) SPI1 Interrupt */ + DCD ADC_Handler /* 26 (0A8H) ADC interrupt request. */ + DCD CMP_Handler /* 27 (0ACH) CMP interrupt request */ + DCD I2S_SLV_MST_Handler /* 28 (0B0H) I2S Slave and Master interrupt */ + DCD UART0_RxTx_Handler /* 29 (0B4H) UART0 Transmit / Receive Interrupt */ + DCD UART1_RxTx_Handler /* 30 (0B8H) UART1 Transmit / Receive Interrupt */ + DCD UART2_RxTx_Handler /* 31 (0BCH) UART2 Transmit / Receive Interrupt */ +__Vectors_End + + SECTION FlashConfig:CODE +__FlashConfig + DCD 0xD28FC027 + DCD 0xDC4DD3A0 + DCD 0x00000000 + DCD 0xFFFF0000 + DCD 0xFFFFFFBF + DCD 0xFFFFFFFF + DCD 0xBEE688FE + DCD 0x8E5BA230 +__FlashConfig_End + +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:REORDER:NOROOT(2) +Reset_Handler + CPSID I ; Mask interrupts + ;; Init the rest of the registers + LDR R1,=0 + LDR R2,=0 + LDR R3,=0 + LDR R4,=0 + LDR R5,=0 + LDR R6,=0 + LDR R7,=0 + MOV R8,R7 + MOV R9,R7 + MOV R10,R7 + MOV R11,R7 + MOV R12,R7 + +#ifdef START_FROM_FLASH + IMPORT __RAM_START, __RAM_END + ;; INIT ECC RAM + + LDR R1, =__RAM_START + LDR R2, =__RAM_END + + SUBS R2, R2, R1 + SUBS R2, #1 + BLE .LC5 + + MOVS R0, #0 + MOVS R3, #4 + .LC4: + STR R0, [R1] + ADD R1, R1, R3 + SUBS R2, #4 + BGE .LC4 + .LC5: +#endif + ;; Initialize the stack pointer + LDR R0, =sfe(CSTACK) + MOV R13,R0 + +#ifndef __NO_SYSTEM_INIT + ;; Call the CMSIS system init routine + LDR R0, =SystemInit + BLX R0 +#endif + + ;; Init .data and .bss sections + LDR R0, =init_data_bss + BLX R0 + CPSIE I ; Unmask interrupts + BL main +JumpToSelf + B JumpToSelf + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler + B . + + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +HardFault_Handler + B . + + + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SVC_Handler + B . + + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +PendSV_Handler + B . + + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SysTick_Handler + B . + + PUBWEAK DMA01_Handler + PUBWEAK DMA23_Handler + PUBWEAK DMA_Error_Handler + PUBWEAK FHU_Handler + PUBWEAK RTC_Alarm_Handler + PUBWEAK RTC_Seconds_Handler + PUBWEAK LPTMR_Handler + PUBWEAK PORT_Handler + PUBWEAK CAN_ORed_Handler + PUBWEAK CAN_ORed_0_31_MB_Handler + PUBWEAK CAN_ORed_32_63_MB_Handler + PUBWEAK MFT0_Ch0_Ch7_Handler + PUBWEAK MFT0_Fault_Handler + PUBWEAK MFT0_Ovf_Reload_Handler + PUBWEAK MFT1_Ch0_Ch7_Handler + PUBWEAK MFT1_Fault_Handler + PUBWEAK MFT1_Ovf_Reload_Handler + PUBWEAK FTFC_Handler + PUBWEAK PDB_Handler + PUBWEAK LPIT_Handler + PUBWEAK CMU_Handler + PUBWEAK WDOG_Handler + PUBWEAK RCM_Handler + PUBWEAK I2C_Handler + PUBWEAK SPI0_Handler + PUBWEAK SPI1_Handler + PUBWEAK ADC_Handler + PUBWEAK CMP_Handler + PUBWEAK I2S_SLV_MST_Handler + PUBWEAK UART0_RxTx_Handler + PUBWEAK UART1_RxTx_Handler + PUBWEAK UART2_RxTx_Handler + PUBWEAK DefaultISR + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler +HardFault_Handler +SVC_Handler +PendSV_Handler +SysTick_Handler +DMA01_Handler +DMA23_Handler +DMA_Error_Handler +FHU_Handler +RTC_Alarm_Handler +RTC_Seconds_Handler +LPTMR_Handler +PORT_Handler +CAN_ORed_Handler +CAN_ORed_0_31_MB_Handler +CAN_ORed_32_63_MB_Handler +MFT0_Ch0_Ch7_Handler +MFT0_Fault_Handler +MFT0_Ovf_Reload_Handler +MFT1_Ch0_Ch7_Handler +MFT1_Fault_Handler +MFT1_Ovf_Reload_Handler +FTFC_Handler +PDB_Handler +LPIT_Handler +CMU_Handler +WDOG_Handler +RCM_Handler +I2C_Handler +SPI0_Handler +SPI1_Handler +ADC_Handler +CMP_Handler +I2S_SLV_MST_Handler +UART0_RxTx_Handler +UART1_RxTx_Handler +UART2_RxTx_Handler +DefaultISR + + END diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/system_M011x.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/system_M011x.c new file mode 100644 index 0000000..6caaf18 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/system_M011x.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "system_M011x.h" +#include "../cpu_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void SystemInit(void) +{ + /* PFLASH prefetch */ + SimReg_SetFlashPFlsFlushEn(SIM, 1); /* Enable Flush PFLASH pre-fetch */ + SimReg_SetFlashPFlsPfbEn(SIM, 1); /* Enable PFLASH pre-fetch*/ + SimReg_SetFlashPFlsFlushEn(SIM, 0); /* Disable Flush PFLASH prefetch */ + + /* Unlock SCG */ + Scg0Reg_SetKey(SCG0, 0x19962020); + Scg1Reg_SetCkSrcSysDiv(SCG1, 1); + + /* Unlock PCC */ + Pcc0Reg_SetKey(PCC0, 0x55534552); + + /* Switch system clock to default clock */ + if(Scg2Reg_GetCsrSysSt(SCG2) == 2) + { + /* Flash AHB bus read access time configure */ + FtfcReg_SetFcnfgBusReadTm(FTFC, 0); /* 1T required */ + Scg2Reg_SetCsrSrcSys(SCG2, 0); + while(Scg2Reg_GetCsrSysSt(SCG2) != 0) + { + ; + } + } + +#ifdef _USE_EXT_OSC_ + /* Use External oscillator */ + Scg0Reg_SetOscCtrlRange(SCG0, 3); /* set SOSC frequency range(use max value when SOSC as the clock source of the PLL) */ + Scg0Reg_SetOscCtrlEnSosc(SCG0, 1); /* enable SOSC */ + while(Scg0Reg_GetStatusSoscRdy(SCG0) == 0) + { + ; /* wait until SOSC is ready */ + } + + /* Disable PLL */ + Scg0Reg_SetPllCtrl0PllEn(SCG0, 0); + /* PLL configuration: + * - PLL input clock source : SOSC + * - PLL pre-divider : 1 + * - feedback divider : 40 + * - PLL Feedback clock divider pre-scaler : 1 + * - PLL post-divider setting : 4 + * Final PLL output frequency is 16M(SOSC) * 40 / 4 / 2 = 80M + */ + Scg0Reg_SetPllCtrl1PllClkinSel(SCG0, 0); + Scg0Reg_SetPllCtrl0PllPreDiv(SCG0, 0); + Scg0Reg_SetPllCtrl0PllM(SCG0, 40); + Scg0Reg_SetPllCtrl0PllFdkSel(SCG0, 0); + Scg0Reg_SetPllCtrl0PllPosDiv(SCG0, 4); + /* Enable PLL */ + Scg0Reg_SetPllCtrl0PllEn(SCG0, 1); + + /* Use systick for delay */ + SysTick->LOAD = 8000U; + SysTick->VAL = 0U; + SysTick->CTRL = 5U; /* SysTick uses the processor clock and enable sysTick */ + while(SysTick->CTRL < 0x10000) + { + ; /* wait for COUNTFLAG setting*/ + } + /*recover sysTick register*/ + SysTick->CTRL = 4U; + SysTick->LOAD = 0U; + SysTick->VAL = 0U; + + while(Scg0Reg_GetStatusPllLock(SCG0) == 0) + { + ; + } + + /* Set the Flash cnt clock source same as system clock and at 8M */ + Pcc1Reg_SetFlsCtlCntSrc(PCC1, 2); + Pcc1Reg_SetFlsCtlCntDiv(PCC1, 9); + Pcc1Reg_SetFlsCtlCkEn(PCC1, 1); + + /* Flash AHB bus read access time configure */ + FtfcReg_SetFcnfgBusReadTm(FTFC, 1); /* 2T required for 80M AHB */ + + /* Set clk_pll as system clock */ + Scg2Reg_SetCsrSrcSys(SCG2, 2); + while(Scg2Reg_GetCsrSysSt(SCG2) != 2) + { + ; + } +#else + /* Disable PLL */ + Scg0Reg_SetPllCtrl0PllEn(SCG0, 0); + /* PLL configuration: + * - PLL input clock source : SIRC + * - PLL pre-divider : 1 + * - feedback divider : 80 + * - PLL Feedback clock divider pre-scaler : 1 + * - PLL post-divider setting : 4 + * Final PLL output frequency is 8M(SIRC) * 80 / 4 / 2 = 80M + */ + Scg0Reg_SetPllCtrl1PllClkinSel(SCG0, 1); + Scg0Reg_SetPllCtrl0PllPreDiv(SCG0, 0); + Scg0Reg_SetPllCtrl0PllM(SCG0, 80); + Scg0Reg_SetPllCtrl0PllFdkSel(SCG0, 0); + Scg0Reg_SetPllCtrl0PllPosDiv(SCG0, 4); + /* Enable PLL */ + Scg0Reg_SetPllCtrl0PllEn(SCG0, 1); + while(Scg0Reg_GetStatusPllLock(SCG0) == 0) + { + ; + } + + /* Set the Flash cnt clock source same as system clock and at 8M */ + Pcc1Reg_SetFlsCtlCntSrc(PCC1, 2); + Pcc1Reg_SetFlsCtlCntDiv(PCC1, 9); + Pcc1Reg_SetFlsCtlCkEn(PCC1, 1); + + /* Flash AHB bus read access time configure */ + FtfcReg_SetFcnfgBusReadTm(FTFC, 1); /* 2T required for 80M AHB */ + + /* Set clk_pll as system clock */ + Scg2Reg_SetCsrSrcSys(SCG2, 2); + while(Scg2Reg_GetCsrSysSt(SCG2) != 2) + { + ; + } +#endif + + /* Set Core and APB clock source divider */ + Scg1Reg_SetCkSrcSysDiv(SCG1, 0); /* Divide-by-1 */ + Scg2Reg_SetCsrDivAips(SCG2, 0); /* Divide-by-1 */ + + /* Finish setting up the clock */ + Scg0Reg_SetKey(SCG0, 0); /* lock SCG again */ + Pcc0Reg_SetKey(PCC0, 0); /* lock PCC again */ +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/system_M011x.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/system_M011x.h new file mode 100644 index 0000000..7f8d62c --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/system_M011x.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _SYSTEM_M011X_H_ +#define _SYSTEM_M011X_H_ + +/*! \brief Contains public interface to various functions related + * to the System module of CVM011x series chips + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* Value of the external crystal or oscillator clock frequency in Hz */ +#define CPU_XTAL_CLK_HZ (8000000u) +#if (CPU_XTAL_CLK_HZ > 40000000) || (CPU_XTAL_CLK_HZ < 4000000) +#error "The external crystal or oscillator clock frequency is out of range." +#endif + +/* Value of the slow internal oscillator clock frequency in Hz */ +#define CPU_INT_SLOW_CLK_HZ (8000000u) + +/* Default System clock value for the user code after SystemInit called */ +#define DEFAULT_SYSTEM_CLOCK (80000000u) + + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + + +/******************************************************************************* + * the globals + ******************************************************************************/ + + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Setup the SoC. + * + * This function disables the watchdog, enables FPU. + * if the corresponding feature macro is enabled. + * SystemInit is called from startup_device file. + */ +extern void SystemInit(void); + + +#ifdef __cplusplus +} +#endif /* extern "C" */ + + +#endif /* _SYSTEM_M011X_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/crc/crc_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/crc/crc_drv.c new file mode 100644 index 0000000..01878e0 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/crc/crc_drv.c @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "crc_drv.h" +#include "crc_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define CRCDRV_FIFO_MAX (4) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void CrcDrv_Init(CrcDrvType *obj, struct _CrcRegType_ *reg) +{ + obj->reg = reg; +} + +void CrcDrv_Configure(CrcDrvType *obj, const CrcDrv_ConfigType *userConfig) +{ + /* Set CRC mode */ + CrcReg_SetCrProtocolWidth(obj->reg, (uint8_t)userConfig->crcWidth); + /* Set transposes options */ + CrcReg_SetCrReverseOut(obj->reg, (uint8_t)userConfig->readTranspose); + /* Set CRC polynomial */ + CrcReg_SetPolyReg(obj->reg, userConfig->polynomial); + /* Set writes transposes */ + CrcReg_SetCrReverseIn(obj->reg, (uint8_t)userConfig->writeTranspose); + /* Sets complement or inversion checksum */ + CrcReg_SetCrFXor(obj->reg, userConfig->complementChecksum); + /* Write a seed - initial checksum */ + CrcReg_SetInitReg(obj->reg, userConfig->seed); +} + +void CrcDrv_GetConfig(const CrcDrvType *obj, CrcDrv_ConfigType *userConfig) +{ + /* Gets CRC mode */ + userConfig->crcWidth = (CrcDrv_BitWidthType)CrcReg_GetCrProtocolWidth(obj->reg); + /* Gets transposes and complement options */ + userConfig->readTranspose = (CrcDrv_TransposeType)CrcReg_GetCrReverseOut(obj->reg); + /* Get a polynomial */ + userConfig->polynomial = CrcReg_GetPolyReg(obj->reg); + /* Gets transposes options */ + userConfig->writeTranspose = (CrcDrv_TransposeType)CrcReg_GetCrReverseIn(obj->reg); + /* Gets complement or inversion checksum */ + userConfig->complementChecksum = CrcReg_GetCrFXor(obj->reg); + /* Get a seed - initial checksum */ + userConfig->seed = CrcReg_GetInitReg(obj->reg); +} + +void CrcDrv_GetDefaultConfig(CrcDrv_ConfigType *userConfig) +{ + /* Gets CRC mode default is 16 bit */ + userConfig->crcWidth = CRCDRV_BITWIDTH_16; + /* Gets default a polynomial default is reset value */ + userConfig->polynomial = 0x1021U; + /* Gets default read transposes none */ + userConfig->readTranspose = CRCDRV_TRANSPOSE_NONE; + /* Gets default write transpose none */ + userConfig->writeTranspose = CRCDRV_TRANSPOSE_NONE; + /* Gets default no complement or inversion checksum */ + userConfig->complementChecksum = false; + /* Gets default a seed - initial checksum */ + userConfig->seed = 0xFFFFFFFFU; +} + +void CrcDrv_SetNewSeed(CrcDrvType *obj, uint32_t seed) +{ + /* Write a seed - initial checksum */ + CrcReg_SetInitReg(obj->reg, seed); +} + +void CrcDrv_CrcReset(CrcDrvType *obj) +{ + /* execute CRC rsset */ + CrcReg_SetCrReset(obj->reg); + + /* wait until CRC rsset execute completely */ + while(CrcReg_GetCrReset(obj->reg) != 0) + { + } +} + +uint32_t CrcDrv_GetCrcResult(CrcDrvType *obj) +{ + CrcDrv_BitWidthType width = (CrcDrv_BitWidthType)(CrcReg_GetCrProtocolWidth(obj->reg)); + CrcDrv_TransposeType transpose; + uint32_t result; + + if(width == CRCDRV_BITWIDTH_16) + { + transpose = (CrcDrv_TransposeType)(CrcReg_GetCrReverseOut(obj->reg)); + if((transpose == CRCDRV_TRANSPOSE_BITS_AND_BYTES) || (transpose == CRCDRV_TRANSPOSE_BYTES)) + { + /* Wait until no remaining data in FIFO */ + while(CrcReg_GetDataNumInFifo(obj->reg) != 0) + { + } + /* Returns upper 16 bits of CRC because of transposition in 16-bit mode */ + result = (uint32_t)((CrcReg_GetDataReg(obj->reg) >> 16) & 0xFFFF); + } + else + { + /* Wait until no remaining data in FIFO */ + while(CrcReg_GetDataNumInFifo(obj->reg) != 0) + { + } + /* Get the lower 16 bits */ + result = (uint32_t)(CrcReg_GetDataReg(obj->reg) & 0xFFFF); + } + } + else + { + /* Wait until no remaining data in FIFO */ + while(CrcReg_GetDataNumInFifo(obj->reg) != 0) + { + } + result = CrcReg_GetDataReg(obj->reg); + } + + return result; +} + +void CrcDrv_WriteData8(CrcDrvType *obj, const uint8_t *data, uint32_t dataSize) +{ + uint32_t group = 0; + uint32_t groupNum = dataSize / CRCDRV_FIFO_MAX; + uint32_t left = dataSize - groupNum * CRCDRV_FIFO_MAX; + uint32_t i = 0; + + /* 8-bit writes till end of data buffer */ + for(group = 0; group < groupNum; ++group) + { + /* Wait until no remaining data in FIFO */ + while(CrcReg_GetDataNumInFifo(obj->reg) != 0) + { + } + /* Write as many as possible until FIFO is full */ + for(i = 0; i < CRCDRV_FIFO_MAX; ++i) + { + CrcReg_SetData8Reg(obj->reg, data[group * CRCDRV_FIFO_MAX + i]); + } + } + /* If still data buffering, wait until no remaining data in FIFO */ + while(left != 0 && CrcReg_GetDataNumInFifo(obj->reg) != 0) + { + } + for(i = 0; i < left; ++i) + { + CrcReg_SetData8Reg(obj->reg, data[dataSize - left + i]); + } +} + +void CrcDrv_WriteData16(CrcDrvType *obj, const uint16_t *data, uint32_t dataSize) +{ + uint32_t group = 0; + uint32_t groupNum = dataSize / CRCDRV_FIFO_MAX; + uint32_t left = dataSize - groupNum * CRCDRV_FIFO_MAX; + uint32_t i = 0; + + /* 8-bit writes till end of data buffer */ + for(group = 0; group < groupNum; ++group) + { + /* Wait until no remaining data in FIFO */ + while(CrcReg_GetDataNumInFifo(obj->reg) != 0) + { + } + /* Write as many as possible until FIFO is full */ + for(i = 0; i < CRCDRV_FIFO_MAX; ++i) + { + CrcReg_SetData16Reg(obj->reg, data[group * CRCDRV_FIFO_MAX + i]); + } + } + /* If still data buffering, wait until no remaining data in FIFO */ + while(left != 0 && CrcReg_GetDataNumInFifo(obj->reg) != 0) + { + } + for(i = 0; i < left; ++i) + { + CrcReg_SetData16Reg(obj->reg, data[dataSize - left + i]); + } +} + +void CrcDrv_WriteData32(CrcDrvType *obj, const uint32_t *data, uint32_t dataSize) +{ + uint32_t group = 0; + uint32_t groupNum = dataSize / CRCDRV_FIFO_MAX; + uint32_t left = dataSize - groupNum * CRCDRV_FIFO_MAX; + uint32_t i = 0; + + /* 8-bit writes till end of data buffer */ + for(group = 0; group < groupNum; ++group) + { + /* Wait until no remaining data in FIFO */ + while(CrcReg_GetDataNumInFifo(obj->reg) != 0) + { + } + /* Write as many as possible until FIFO is full */ + for(i = 0; i < CRCDRV_FIFO_MAX; ++i) + { + CrcReg_SetDataReg(obj->reg, data[group * CRCDRV_FIFO_MAX + i]); + } + } + /* If still data buffering, wait until no remaining data in FIFO */ + while(left != 0 && CrcReg_GetDataNumInFifo(obj->reg) != 0) + { + } + for(i = 0; i < left; ++i) + { + CrcReg_SetDataReg(obj->reg, data[dataSize - left + i]); + } +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/crc/crc_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/crc/crc_drv.h new file mode 100644 index 0000000..d522d56 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/crc/crc_drv.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CRC_DRV_H_ +#define _CRC_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of CRC module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup crc_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief CRC type of transpose of read write data + */ +typedef enum +{ + CRCDRV_TRANSPOSE_NONE = 0, /*!< No transpose */ + CRCDRV_TRANSPOSE_BITS = 1, /*!< Transpose bits in bytes */ + CRCDRV_TRANSPOSE_BITS_AND_BYTES = 2, /*!< Transpose bytes and bits in bytes */ + CRCDRV_TRANSPOSE_BYTES = 3, /*!< Transpose bytes */ +} CrcDrv_TransposeType; + +/*! \brief CRC bit width + */ +typedef enum +{ + CRCDRV_BITWIDTH_16 = 0, /*!< No transpose */ + CRCDRV_BITWIDTH_32 = 1, /*!< Transpose bits in bytes */ +} CrcDrv_BitWidthType; + +/*! \brief Definition of configuration of CRC driver + */ +typedef struct _CrcDrv_ConfigType_ +{ + CrcDrv_BitWidthType crcWidth; /*!< Selects 16-bit or 32-bit CRC protocol. */ + uint32_t polynomial; /*!< CRC Polynomial, MSBit first. */ + CrcDrv_TransposeType readTranspose; /*!< Type of transpose when reading CRC result. */ + CrcDrv_TransposeType writeTranspose; /*!< Type of transpose when writing CRC input data. */ + bool complementChecksum; /*!< True if the result shall be complement of the actual checksum. */ + uint32_t seed; /*!< Starting checksum value. */ +} CrcDrv_ConfigType; + +/* Forward declaration of CRC register */ +struct _CrcRegType_; + +/*! \brief The definition of CRC driver class + */ +typedef struct _CrcDrvType_ +{ + struct _CrcRegType_ *reg; +} CrcDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the CRC driver module + * + * This function initializes CRC driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to CRC driver instance + * \param[in] reg : pointer to CRC register instance + */ +extern void CrcDrv_Init(CrcDrvType *obj, struct _CrcRegType_ *reg); + +/*! \brief Configures the CRC module from a user configuration structure + * + * This function configures the CRC module from a user configuration structure + * + * \param[in] obj : pointer to CRC driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void CrcDrv_Configure(CrcDrvType *obj, const CrcDrv_ConfigType *userConfig); + +/*! \brief Get configures of the CRC module currently + * + * This function gets configures of the CRC module currently + * + * \param[in] obj : pointer to CRC driver instance + * \param[out] userConfig : pointer to configuration structure + */ +extern void CrcDrv_GetConfig(const CrcDrvType *obj, CrcDrv_ConfigType *userConfig); + +/*! \brief Get default configures the CRC module for configuration structure + * + * This function gets default configures the CRC module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void CrcDrv_GetDefaultConfig(CrcDrv_ConfigType *userConfig); + +/*! \brief Sets a new seed to register CRC_INIT + * + * This function sets a new seed to register CRC_INIT + * This operation will cause the value of register CRC_DR to be updated to the value of register CRC_INIT + * + * \param[in] obj : pointer to CRC driver instance + * \param[in] seed : new seed will writed to CRC_INIT + */ +extern void CrcDrv_SetNewSeed(CrcDrvType *obj, uint32_t seed); + +/*! \brief Executes CRC reset operation + * + * This function executes CRC reset operation + * This opration will cause the value of register CRC_DR to be updated to the value of register CRC_INIT + * + * \param[in] obj : pointer to CRC driver instance + */ +extern void CrcDrv_CrcReset(CrcDrvType *obj); + +/*! \brief Get the current result of the CRC calculation. + * + * This function returns the current result of the CRC calculation. + * + * \param[in] obj : pointer to CRC register instance + * \return the current CRC calculation result + */ +extern uint32_t CrcDrv_GetCrcResult(CrcDrvType *obj); + +/*! \brief Appends a block of 8 bits data to the current CRC calculation + * + * This function appends a block of 8 bits data to the current CRC calculation + * + * \param[in] obj : pointer to CRC driver instance + * \param[in] data : pointer to input data for CRC calculation + * \param[in] dataSize : length of 8 bits data to be calculated + */ +extern void CrcDrv_WriteData8(CrcDrvType *obj, const uint8_t *data, uint32_t dataSize); + +/*! \brief Appends a block of 16 bits data to the current CRC calculation + * + * This function appends a block of 16 bits data to the current CRC calculation + * + * \param[in] obj : pointer to CRC driver instance + * \param[in] data : pointer to input data for CRC calculation + * \param[in] dataSize : length of 16 bits data to be calculated + */ +extern void CrcDrv_WriteData16(CrcDrvType *obj, const uint16_t *data, uint32_t dataSize); + +/*! \brief Appends a block of 32 bits data to the current CRC calculation + * + * This function appends a block of 32 bits data to the current CRC calculation + * + * \param[in] obj : pointer to CRC driver instance + * \param[in] data : pointer to input data for CRC calculation + * \param[in] dataSize : length of 32 bits data to be calculated + */ +extern void CrcDrv_WriteData32(CrcDrvType *obj, const uint32_t *data, uint32_t dataSize); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _CRC_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/edma/edma_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/edma/edma_drv.c new file mode 100644 index 0000000..d89c367 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/edma/edma_drv.c @@ -0,0 +1,893 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "dmamux_reg.h" +#include "edma_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static void EDmaDrv_ClearIntStatus(EDmaDrvType *obj, uint8_t channel); +static void EDmaDrv_ClearSoftwareTCD(EDmaDrv_SoftwareTcdType *stcd); +static void EDmaDrv_ClearStructure(uint8_t *sructPtr, size_t size); + +/******************************************************************************* + * Code + ******************************************************************************/ +void EDmaDrv_BaseInit(EDmaDrvType *obj) +{ + uint8_t i; + /* Clear the bit of CR register */ + uint32_t regValTemp; + regValTemp = obj->edmaReg->CR; + regValTemp &= ~(EDMA_CR_CLM_MASK); + regValTemp &= ~(EDMA_CR_CX_MASK); + regValTemp &= ~(EDMA_CR_ECX_MASK); + regValTemp &= ~(EDMA_CR_EDBG_MASK); + regValTemp &= ~(EDMA_CR_EMLM_MASK); + regValTemp &= ~(EDMA_CR_ERCA_MASK); + obj->edmaReg->CR = regValTemp; + + for(i = 0; i < EDMA_CHANNELS; i++) + { + EDmaReg_ClearTcdReg(obj->edmaReg, i); + } +} + +void EDmaDrv_Init(EDmaDrvType *obj, struct _EDmaRegType_ *dmaReg, struct _DmamuxRegType_ *dmamuxReg) +{ + obj->edmaReg = dmaReg; + obj->dmamuxReg = dmamuxReg; +} + +void EDmaDrv_GetDefaultConfigure(EDmaDrv_ModuleConfigType *userConfig) +{ + userConfig->chnArbitration = EDMADRV_ARBITRATION_FIXED_PRIORITY; + userConfig->haltOnError = false; + userConfig->channelPriority[0] = EDMADRV_CHN_PRIORITY_0; + userConfig->channelPriority[1] = EDMADRV_CHN_PRIORITY_1; + userConfig->channelPriority[2] = EDMADRV_CHN_PRIORITY_2; + userConfig->channelPriority[3] = EDMADRV_CHN_PRIORITY_3; +} + +void EDmaDrv_GetDefaultChannelConfigure(EDmaDrv_ChannelConfigType *channelConfig) +{ + channelConfig->channelPriority = EDMADRV_CHN_DEFAULT_PRIORITY; + channelConfig->chnConfig = 0; + channelConfig->source = EDMA_REQ_DISABLED; + channelConfig->callback = NULL; + channelConfig->callbackParam = NULL; + channelConfig->enableTrigger = false; +} + +EDmaDrv_Status EDmaDrv_Configure(EDmaDrvType *obj, EDmaDrv_StateType *edmaState, const EDmaDrv_ModuleConfigType *userConfig) +{ + uint32_t index = 0U; + + EDmaDrv_Status edmaStatus = STATUS_SUCCESS; + + obj->dmaState = edmaState; + +#ifdef DMAMUX_AVAILABLE + /* Initialize all DMAMUX instances */ + DmamuxReg_Init(obj->dmamuxReg); +#endif + + /* Clear the state structure. */ + EDmaDrv_ClearStructure((uint8_t *)obj->dmaState, sizeof(EDmaDrv_StateType)); + + /* Init eDMA module on hardware level. */ + EDmaDrv_BaseInit(obj); + + /* Set arbitration mode */ + EDmaReg_SetChannelArbitrationMode(obj->edmaReg, userConfig->chnArbitration); + + if(EDmaReg_GetChannelArbitrationMode(obj->edmaReg) == EDMADRV_ARBITRATION_FIXED_PRIORITY) + { + for(index = 0U; index < EDMA_CHANNELS_INTERRUPT_LINES; index++) + { + EDmaReg_SetChannelPriority(obj->edmaReg, index, (userConfig->channelPriority[index])); + } + } + + /* Set 'Halt on error' configuration */ + EDmaReg_SetHaltOnErrorCmd(obj->edmaReg, userConfig->haltOnError); + + return edmaStatus; +} + +EDmaDrv_Status EDmaDrv_ConfigureChannel(EDmaDrvType *obj, + EDmaDrv_ChnStateType *const chnStateArray[], + const EDmaDrv_ChannelConfigType *const chnConfig) +{ + EDmaDrv_Status edmaStatus = STATUS_SUCCESS; + + /* Initialize the channels based on configuration list */ + if((chnStateArray != NULL) && (chnConfig != NULL)) + { + edmaStatus = EDmaDrv_ChannelInit(obj, chnStateArray[chnConfig->chnConfig], chnConfig); + } + else + { + edmaStatus = STATUS_ERROR; + } + return edmaStatus; +} + +EDmaDrv_Status EDmaDrv_Deinit(EDmaDrvType *obj) +{ + uint32_t index = 0U; + + if(obj->dmaState != NULL) + { + /* Release all edma channel. */ + for(index = 0U; index < (uint32_t)EDMA_CHANNELS; index++) + { + /* Release all channels. */ + if(obj->dmaState->chnState[index] != NULL) + { + (void)EDmaDrv_ReleaseChannel(obj, index); + } + } + } + + obj->dmaState = NULL; + + return STATUS_SUCCESS; +} + +EDmaDrv_Status EDmaDrv_ChannelInit(EDmaDrvType *obj, + EDmaDrv_ChnStateType *edmaChannelState, + const EDmaDrv_ChannelConfigType *edmaChannelConfig) +{ + uint8_t channel = edmaChannelConfig->chnConfig; + + /* Get status */ + EDmaDrv_Status retStatus = STATUS_SUCCESS; + /* Reset the channel state structure to default value. */ + EDmaDrv_ClearStructure((uint8_t *)(edmaChannelState), sizeof(EDmaDrv_ChnStateType)); + +#ifdef DMAMUX_AVAILABLE + if(edmaChannelConfig->source != EDMA_REQ_DISABLED) + { + retStatus = EDmaDrv_SetChannelRequestAndTrigger(obj, + edmaChannelConfig->chnConfig, + (uint8_t)edmaChannelConfig->source, + edmaChannelConfig->enableTrigger); + } +#endif + + /* Clear the TCD registers for this channel */ + EDmaReg_ClearTcdReg(obj->edmaReg, channel); + + /* polyspace-begin DEFECT:USELESS_IF [ Not a defect: Low ] "Still keep this if statement." */ + if(retStatus == STATUS_SUCCESS) + { + obj->dmaState->chnState[channel] = edmaChannelState; + obj->dmaState->chnState[channel]->chn = channel; + obj->dmaState->chnState[channel]->status = DMA_CHN_NORMAL; + + /* Set the channel priority, as defined in the configuration, only if fixed arbitration mode is selected */ + if((EDmaReg_GetChannelArbitrationMode(obj->edmaReg) == EDMADRV_ARBITRATION_FIXED_PRIORITY) + && (edmaChannelConfig->channelPriority != EDMADRV_CHN_DEFAULT_PRIORITY)) + { + EDmaReg_SetChannelPriority(obj->edmaReg, channel, edmaChannelConfig->channelPriority); + } + /* Install the user callback */ + obj->dmaState->chnState[channel]->callback = edmaChannelConfig->callback; + obj->dmaState->chnState[channel]->parameter = edmaChannelConfig->callbackParam; + } + /* polyspace-end DEFECT:USELESS_IF [ Not a defect: Low ] "Still keep this if statement." */ + + return retStatus; +} + +EDmaDrv_Status EDmaDrv_InstallCallback(EDmaDrvType *obj, uint8_t channel, EDmaDrv_CallBackType callback, void *parameter) +{ + obj->dmaState->chnState[channel]->callback = callback; + obj->dmaState->chnState[channel]->parameter = parameter; + return STATUS_SUCCESS; +} + +EDmaDrv_Status EDmaDrv_ReleaseChannel(EDmaDrvType *obj, uint8_t channel) +{ + /* Stop edma channel. */ + EDmaReg_SetDmaRequestCmd(obj->edmaReg, channel, false); + + /* Reset the channel state structure to default value. */ + EDmaDrv_ClearStructure((uint8_t *)obj->dmaState->chnState[channel], sizeof(EDmaDrv_ChnStateType)); + + obj->dmaState->chnState[channel] = NULL; + + return STATUS_SUCCESS; +} + +static void EDmaDrv_ClearIntStatus(EDmaDrvType *obj, uint8_t channel) +{ + EDmaReg_ClearDoneStatusFlag(obj->edmaReg, channel); + EDmaReg_ClearIntStatusFlag(obj->edmaReg, channel); +} + +static void EDmaDrv_ClearSoftwareTCD(EDmaDrv_SoftwareTcdType *stcd) +{ + EDmaDrv_ClearStructure((uint8_t *)stcd, sizeof(EDmaDrv_SoftwareTcdType)); +} + +void EDmaDrv_IRQHandler(EDmaDrvType *obj, uint8_t channel) +{ + const EDmaDrv_ChnStateType *chnState = obj->dmaState->chnState[channel]; + + EDmaDrv_ClearIntStatus(obj, channel); + + if(chnState != NULL) + { + if(chnState->callback != NULL) + { + chnState->callback(chnState->parameter, chnState->status); + } + } +} + +void EDmaDrv_ErrorIRQHandler(EDmaDrvType *obj, uint8_t channel) +{ + EDmaReg_SetDmaRequestCmd(obj->edmaReg, channel, false); + EDmaDrv_ChnStateType *chnState = obj->dmaState->chnState[channel]; + if(chnState != NULL) + { + EDmaDrv_ClearIntStatus(obj, channel); + EDmaReg_ClearErrorIntStatusFlag(obj->edmaReg, channel); + chnState->status = DMA_CHN_ERROR; + if(chnState->callback != NULL) + { + chnState->callback(chnState->parameter, chnState->status); + } + } +} + +EDmaDrv_Status EDmaDrv_ConfigSingleBlockTransfer(EDmaDrvType *obj, + uint8_t channel, + EDmaDrv_TransferType type, + uint32_t srcAddr, + uint32_t destAddr, + EDmaDrv_TransferSizeType transferSize, + uint32_t dataBufferSize, + bool enableHwClrDone) +{ + EDmaDrv_Status retStatus = STATUS_SUCCESS; + + /* Compute the transfer offset, based on transfer size. + * The number of bytes transferred in each source read/destination write + * is obtained with the following formula: + * source_read_size = 2^SSIZE + * destination_write_size = 2^DSIZE + */ + uint8_t transferOffset = (uint8_t)(1U << ((uint8_t)transferSize)); + + /* The number of bytes to be transferred (buffer size) must + * be a multiple of the source read/destination write size + */ + if((dataBufferSize % transferOffset) != 0U) + { + retStatus = STATUS_ERROR; + } + + if(retStatus == STATUS_SUCCESS) + { + /* Clear transfer control descriptor for the current channel */ + EDmaReg_ClearTcdReg(obj->edmaReg, channel); + + EDmaReg_SetMinorLoopMappingCmd(obj->edmaReg, true); + + /* Configure source and destination addresses */ + EDmaReg_SetTcdSrcAddr(obj->edmaReg, channel, srcAddr); + EDmaReg_SetTcdDestAddr(obj->edmaReg, channel, destAddr); + + /* Set transfer size (1B/2B/4B/16B/32B) */ + EDmaReg_SetTcdAttribute(obj->edmaReg, channel, EDMADRV_MODULO_OFF, EDMADRV_MODULO_OFF, transferSize); + + /* Configure source/destination offset. */ + switch(type) + { + case EDMADRV_TRANSFER_PERIPH2MEM: + EDmaReg_SetTcdSrcOffset(obj->edmaReg, channel, 0); + EDmaReg_SetTcdDestOffset(obj->edmaReg, channel, (int8_t)transferOffset); + break; + case EDMADRV_TRANSFER_MEM2PERIPH: + EDmaReg_SetTcdSrcOffset(obj->edmaReg, channel, (int8_t)transferOffset); + EDmaReg_SetTcdDestOffset(obj->edmaReg, channel, 0); + break; + case EDMADRV_TRANSFER_MEM2MEM: + EDmaReg_SetTcdSrcOffset(obj->edmaReg, channel, (int8_t)transferOffset); + EDmaReg_SetTcdDestOffset(obj->edmaReg, channel, (int8_t)transferOffset); + break; + case EDMADRV_TRANSFER_PERIPH2PERIPH: + EDmaReg_SetTcdSrcOffset(obj->edmaReg, channel, 0); + EDmaReg_SetTcdDestOffset(obj->edmaReg, channel, 0); + break; + default: + /* This should never be reached - all the possible values have been handled. */ + break; + } + + /* Set the total number of bytes to be transfered */ + EDmaReg_SetTcdNbytes(obj->edmaReg, channel, dataBufferSize); + + /* Set major iteration count to 1 (single block mode) */ + EDmaReg_SetTcdMajorCount(obj->edmaReg, channel, 1U); + + /* Enable interrupt when the transfer completes */ + EDmaReg_SetTcdMajorCompleteIntCmd(obj->edmaReg, channel, true); + + EDmaReg_SetTcdHardClrDoneCmd(obj->edmaReg, channel, enableHwClrDone); + /* Set channel status to normal */ + obj->dmaState->chnState[channel]->status = DMA_CHN_NORMAL; + } + + return retStatus; +} + +EDmaDrv_Status EDmaDrv_ConfigMultiBlockTransfer(EDmaDrvType *obj, + uint8_t channel, + EDmaDrv_TransferType type, + uint32_t srcAddr, + uint32_t destAddr, + EDmaDrv_TransferSizeType transferSize, + uint32_t blockSize, + uint32_t blockCount, + bool enableHwClrDone, + bool disableReqOnCompletion) +{ + EDmaDrv_Status retStatus = STATUS_SUCCESS; + + /* Configure the transfer for one data block */ + retStatus = EDmaDrv_ConfigSingleBlockTransfer(obj, channel, type, srcAddr, destAddr, transferSize, blockSize, enableHwClrDone); + + if(retStatus == STATUS_SUCCESS) + { + /* Set the number of data blocks */ + EDmaReg_SetTcdMajorCount(obj->edmaReg, channel, blockCount); + + /* Enable/disable requests upon completion */ + EDmaReg_SetTcdDisableDmaRequestAfterTcdDoneCmd(obj->edmaReg, channel, disableReqOnCompletion); + } + + return retStatus; +} + +EDmaDrv_Status EDmaDrv_ConfigLoopTransfer(EDmaDrvType *obj, uint8_t channel, const EDmaDrv_TransferConfigType *transferConfig) +{ + EDmaReg_SetMinorLoopMappingCmd(obj->edmaReg, true); + + /* Write the configuration in the transfer control descriptor registers */ + EDmaDrv_PushConfigToReg(obj, channel, transferConfig); + + /* Set channel status to normal */ + obj->dmaState->chnState[channel]->status = DMA_CHN_NORMAL; + + return STATUS_SUCCESS; +} + +EDmaDrv_Status EDmaDrv_ConfigScatterGatherTransfer(EDmaDrvType *obj, + uint8_t channel, + EDmaDrv_SoftwareTcdType *stcd, + EDmaDrv_TransferSizeType transferSize, + uint32_t bytesOnEachRequest, + bool hardClrDone, + const EDmaDrv_ScatterGatherListType *srcList, + const EDmaDrv_ScatterGatherListType *destList, + const EDmaDrv_LoopTransferConfigType *loopTransferList, + uint8_t tcdCount) +{ + uint8_t i = 0U; + uint16_t transferOffset = 0U; + uint32_t stcdAlignedAddr = STCD_ADDR(stcd); + EDmaDrv_SoftwareTcdType *edmaSwTcdAddr = (EDmaDrv_SoftwareTcdType *)stcdAlignedAddr; + EDmaDrv_LoopTransferConfigType edmaLoopConfig; + EDmaDrv_TransferConfigType edmaTransferConfig; + EDmaDrv_Status retStatus = STATUS_SUCCESS; + + /* Set channel status to normal */ + obj->dmaState->chnState[channel]->status = DMA_CHN_NORMAL; + + /* Compute the transfer offset, based on transfer size. + * The number of bytes transferred in each source read/destination write + * is obtained with the following formula: + * source_read_size = 2^SSIZE + * destination_write_size = 2^DSIZE + */ + transferOffset = (uint16_t)(1UL << ((uint16_t)transferSize)); + + /* The number of bytes to be transferred on each request must + * be a multiple of the source read/destination write size + */ + if((bytesOnEachRequest % transferOffset) != 0U) + { + retStatus = STATUS_ERROR; + } + + /* Clear the configuration structures before initializing them. */ + EDmaDrv_ClearStructure((uint8_t *)(&edmaTransferConfig), sizeof(EDmaDrv_TransferConfigType)); + EDmaDrv_ClearStructure((uint8_t *)(&edmaLoopConfig), sizeof(EDmaDrv_LoopTransferConfigType)); + + /* Configure the transfer for scatter/gather mode. */ + edmaTransferConfig.srcLastAddrAdjust = 0; + edmaTransferConfig.destLastAddrAdjust = 0; + edmaTransferConfig.srcModulo = EDMADRV_MODULO_OFF; + edmaTransferConfig.destModulo = EDMADRV_MODULO_OFF; + edmaTransferConfig.srcDestTransferSize = transferSize; + edmaTransferConfig.minorByteTransferCount = bytesOnEachRequest; + edmaTransferConfig.interruptEnable = true; + edmaTransferConfig.scatterGatherEnable = true; + edmaTransferConfig.hardClrDone = hardClrDone; + edmaTransferConfig.loopTransferConfig = &edmaLoopConfig; + edmaTransferConfig.loopTransferConfig->srcOffsetEnable = false; + edmaTransferConfig.loopTransferConfig->dstOffsetEnable = false; + + + /* Copy scatter/gather lists to transfer configuration*/ + for(i = 0U; (i < tcdCount) && (retStatus == STATUS_SUCCESS); i++) + { + if(loopTransferList != NULL) + { + edmaTransferConfig.loopTransferConfig->minorLoopChnLinkEnable = loopTransferList[i].minorLoopChnLinkEnable; + edmaTransferConfig.loopTransferConfig->majorLoopChnLinkEnable = loopTransferList[i].majorLoopChnLinkEnable; + edmaTransferConfig.loopTransferConfig->minorLoopChnLinkNumber = loopTransferList[i].minorLoopChnLinkNumber; + edmaTransferConfig.loopTransferConfig->majorLoopChnLinkNumber = loopTransferList[i].majorLoopChnLinkNumber; + } + else + { + edmaTransferConfig.loopTransferConfig->minorLoopChnLinkEnable = false; + edmaTransferConfig.loopTransferConfig->majorLoopChnLinkEnable = false; + edmaTransferConfig.loopTransferConfig->minorLoopChnLinkNumber = 0; + edmaTransferConfig.loopTransferConfig->majorLoopChnLinkNumber = 0; + } + + edmaTransferConfig.srcAddr = srcList[i].address; + edmaTransferConfig.destAddr = destList[i].address; + if((srcList[i].length != destList[i].length) || (srcList[i].type != destList[i].type)) + { + retStatus = STATUS_ERROR; + break; + } + edmaTransferConfig.loopTransferConfig->majorLoopIterationCount = srcList[i].length / bytesOnEachRequest; + + switch(srcList[i].type) + { + case EDMADRV_TRANSFER_PERIPH2MEM: + /* Configure Source Read. */ + edmaTransferConfig.srcOffset = 0; + /* Configure Dest Write. */ + edmaTransferConfig.destOffset = (int16_t)transferOffset; + break; + case EDMADRV_TRANSFER_MEM2PERIPH: + /* Configure Source Read. */ + edmaTransferConfig.srcOffset = (int16_t)transferOffset; + /* Configure Dest Write. */ + edmaTransferConfig.destOffset = 0; + break; + case EDMADRV_TRANSFER_MEM2MEM: + /* Configure Source Read. */ + edmaTransferConfig.srcOffset = (int16_t)transferOffset; + /* Configure Dest Write. */ + edmaTransferConfig.destOffset = (int16_t)transferOffset; + break; + case EDMADRV_TRANSFER_PERIPH2PERIPH: + /* Configure Source Read. */ + edmaTransferConfig.srcOffset = 0; + /* Configure Dest Write. */ + edmaTransferConfig.destOffset = 0; + break; + default: + /* This should never be reached - all the possible values have been handled. */ + break; + } + + /* Configure the pointer to next software TCD structure; for the last one, this address should be 0 */ + EDmaDrv_SoftwareTcdType *ptNextAddr; + + if(i == ((uint8_t)(tcdCount - 1U))) + { + ptNextAddr = &edmaSwTcdAddr[0]; + } + else + { + ptNextAddr = &edmaSwTcdAddr[i + 1]; + } + edmaTransferConfig.scatterGatherNextDescAddr = ((uint32_t)ptNextAddr); + + if(i == 0U) + { + /* Push the configuration for the first descriptor to registers */ + EDmaDrv_PushConfigToReg(obj, channel, &edmaTransferConfig); + } + EDmaDrv_PushConfigToSTcd(&edmaTransferConfig, &edmaSwTcdAddr[i]); + } + + return retStatus; +} + +EDmaDrv_Status EDmaDrv_StartChannel(EDmaDrvType *obj, uint8_t channel) +{ + /* Enable requests for current channel */ + EDmaReg_SetDmaRequestCmd(obj->edmaReg, channel, true); + + return STATUS_SUCCESS; +} + +EDmaDrv_Status EDmaDrv_StopChannel(EDmaDrvType *obj, uint8_t channel) +{ + /* Disable requests for current channel */ + EDmaReg_SetDmaRequestCmd(obj->edmaReg, channel, false); + + return STATUS_SUCCESS; +} + +EDmaDrv_Status EDmaDrv_SetChannelRequestAndTrigger(EDmaDrvType *obj, uint8_t channel, uint8_t request, bool enableTrigger) +{ +#ifdef DMAMUX_AVAILABLE + /* Get request index for the corresponding DMAMUX instance */ + uint8_t dmaMuxRequest = (uint8_t)request; + + /* Set request and trigger */ + DmamuxReg_SetChannelCmd(obj->dmamuxReg, channel, false); + DmamuxReg_SetChannelSource(obj->dmamuxReg, channel, dmaMuxRequest); +#ifdef DMAMUX_HAS_TRIG + DmamuxReg_SetChannelTrigger(obj->dmamuxReg, channel, enableTrigger); +#else + (void)enableTrigger; +#endif + DmamuxReg_SetChannelCmd(obj->dmamuxReg, channel, true); + + return STATUS_SUCCESS; +#else + (void)channel; + (void)request; + (void)enableTrigger; + return STATUS_UNSUPPORTED; +#endif +} + +void EDmaDrv_ClearTcd(EDmaDrvType *obj, uint8_t channel) +{ + /* Clear the TCD memory */ + EDmaReg_ClearTcdReg(obj->edmaReg, channel); +} + +void EDmaDrv_SetSrcAddr(EDmaDrvType *obj, uint8_t channel, uint32_t address) +{ + /* Set channel TCD source address */ + EDmaReg_SetTcdSrcAddr(obj->edmaReg, channel, address); +} + +void EDmaDrv_SetSrcOffset(EDmaDrvType *obj, uint8_t channel, int16_t offset) +{ + /* Set channel TCD source offset */ + EDmaReg_SetTcdSrcOffset(obj->edmaReg, channel, (uint16_t)offset); +} + +void EDmaDrv_SetSrcReadDestWriteChunkSize(EDmaDrvType *obj, uint8_t channel, EDmaDrv_TransferSizeType size) +{ + /* Set channel TCD source transfer size */ + EDmaReg_SetTcdSrcDesTransferSize(obj->edmaReg, channel, size); +} + +void EDmaDrv_SetSrcLastAddrAdjustment(EDmaDrvType *obj, uint8_t channel, int32_t adjust) +{ + /* Set channel TCD source last adjustment */ + EDmaReg_SetTcdSrcLastAdjust(obj->edmaReg, channel, (uint32_t)adjust); +} + +void EDmaDrv_SetDestLastAddrAdjustment(EDmaDrvType *obj, uint8_t channel, int32_t adjust) +{ + /* Set channel TCD source last adjustment */ + EDmaReg_SetTcdDestLastAdjust(obj->edmaReg, channel, (uint32_t)adjust); +} + +void EDmaDrv_SetDestAddr(EDmaDrvType *obj, uint8_t channel, uint32_t address) +{ + /* Set channel TCD destination address */ + EDmaReg_SetTcdDestAddr(obj->edmaReg, channel, address); +} + +void EDmaDrv_SetDestOffset(EDmaDrvType *obj, uint8_t channel, int16_t offset) +{ + /* Set channel TCD destination offset */ + EDmaReg_SetTcdDestOffset(obj->edmaReg, channel, (uint16_t)offset); +} + +void EDmaDrv_SetMinorLoopBlockSize(EDmaDrvType *obj, uint8_t channel, uint32_t nbytes) +{ + /* Set channel TCD minor loop block size */ + EDmaReg_SetTcdNbytes(obj->edmaReg, channel, nbytes); +} + +void EDmaDrv_SetMajorLoopIterationCount(EDmaDrvType *obj, uint8_t channel, uint32_t majorLoopCount) +{ + /* Set the major loop iteration count */ + EDmaReg_SetTcdMajorCount(obj->edmaReg, channel, majorLoopCount); +} + +uint32_t EDmaDrv_GetRemainingMajorIterationsCount(EDmaDrvType *obj, uint8_t channel) +{ + /* Retrieve the number of minor loops yet to be triggered */ + uint32_t count = EDmaReg_GetTcdCurrentMajorCount(obj->edmaReg, channel); + + return count; +} + +void EDmaDrv_SetScatterGatherLink(EDmaDrvType *obj, uint8_t channel, uint32_t nextTCDAddr) +{ + /* Configures the memory address of the next TCD */ + EDmaReg_SetTcdScatterGatherLink(obj->edmaReg, channel, nextTCDAddr); +} + +void EDmaDrv_DisableRequestsOnTransferComplete(EDmaDrvType *obj, uint8_t channel, bool disable) +{ + /* Disables/Enables the DMA request upon TCD completion */ + EDmaReg_SetTcdDisableDmaRequestAfterTcdDoneCmd(obj->edmaReg, channel, disable); +} + +void EDmaDrv_ConfigureInterrupt(EDmaDrvType *obj, uint8_t channel, EDmaDrv_ChannelInterruptType intSrc, bool enable) +{ + /* Disables/Enables the channel interrupt requests. */ + switch(intSrc) + { + case EDMADRV_CHN_ERR_INT: + /* Enable channel interrupt request when error conditions occur */ + EDmaReg_SetErrorIntCmd(obj->edmaReg, channel, enable); + break; + case EDMADRV_CHN_HALF_MAJOR_LOOP_INT: + /* Enable channel interrupt request when major iteration count reaches halfway point */ + EDmaReg_SetTcdMajorHalfCompleteIntCmd(obj->edmaReg, channel, enable); + break; + case EDMADRV_CHN_MAJOR_LOOP_INT: + /* Enable channel interrupt request when major iteration count reaches zero */ + EDmaReg_SetTcdMajorCompleteIntCmd(obj->edmaReg, channel, enable); + break; + default: + /* This branch should never be reached if driver API is used properly */ + break; + } +} + +void EDmaDrv_CancelTransfer(EDmaDrvType *obj, bool error) +{ + /* Cancel the running transfer. */ + if(error) + { + EDmaReg_CancelTransferWithError(obj->edmaReg); + } + else + { + EDmaReg_CancelTransfer(obj->edmaReg); + } +} + +void EDmaDrv_TriggerSwRequest(EDmaDrvType *obj, uint8_t channel) +{ + /* Trigger the channel transfer. */ + EDmaReg_SetChannelStartFlag(obj->edmaReg, channel); +} + +void EDmaDrv_PushConfigToSTcd(const EDmaDrv_TransferConfigType *config, EDmaDrv_SoftwareTcdType *stcd) +{ + if((config != NULL) && (stcd != NULL)) + { + /* Clear the array of software TCDs passed by the user */ + EDmaDrv_ClearSoftwareTCD(stcd); + + /* Set the software TCD fields */ + stcd->ATTR = (uint16_t)(EDMA_TCD_ATTR_SMOD(config->srcModulo) | EDMA_TCD_ATTR_SDSIZE(config->srcDestTransferSize) + | EDMA_TCD_ATTR_DMOD(config->destModulo)); + stcd->SADDR = config->srcAddr; + stcd->SOFF = config->srcOffset; + stcd->NBYTES = config->minorByteTransferCount; + stcd->SLAST = config->srcLastAddrAdjust; + stcd->DADDR = config->destAddr; + stcd->DOFF = config->destOffset; + stcd->CITER = (uint16_t)config->loopTransferConfig->majorLoopIterationCount; + stcd->BITER = (uint16_t)config->loopTransferConfig->majorLoopIterationCount; + if(config->scatterGatherEnable) + { + stcd->DLAST_SGA = (int32_t)config->scatterGatherNextDescAddr; + } + else + { + stcd->DLAST_SGA = config->destLastAddrAdjust; + } + stcd->CSR = (uint16_t)(((config->interruptEnable ? 1UL : 0UL) << EDMA_TCD_CSR_INTMAJOR_SHIFT) + | ((config->scatterGatherEnable ? 1UL : 0UL) << EDMA_TCD_CSR_ESG_SHIFT)); + + if (config->hardClrDone) + { + stcd->CSR |= EDMA_TCD_CSR_HARD_CLR_DONE_MASK; + } + else + { + stcd->CSR &= ~EDMA_TCD_CSR_HARD_CLR_DONE_MASK; + } + + + if(config->loopTransferConfig->majorLoopChnLinkEnable) + { + stcd->CSR |= (uint16_t)((EDMA_TCD_CSR_MAJORELINK_MASK) + | (config->loopTransferConfig->majorLoopChnLinkNumber << EDMA_TCD_CSR_MAJORLINKCH_SHIFT)); + } + else + { + stcd->CSR &= ~((uint16_t)EDMA_TCD_CSR_MAJORELINK_MASK); + stcd->CSR &= ~((uint16_t)EDMA_TCD_CSR_MAJORLINKCH_MASK); + } + + if(config->loopTransferConfig->minorLoopChnLinkEnable) + { + uint16_t biterElinkTemp; + biterElinkTemp = stcd->CITER; + biterElinkTemp |= EDMA_TCD_BITER_ELINKYES_ELINK_MASK; + biterElinkTemp &= (uint16_t) ~(EDMA_TCD_BITER_ELINKYES_LINKCH_MASK); + biterElinkTemp |= (((uint16_t)(((uint16_t)(config->loopTransferConfig->minorLoopChnLinkNumber)) << EDMA_TCD_BITER_ELINKYES_LINKCH_SHIFT)) & EDMA_TCD_BITER_ELINKYES_LINKCH_MASK); + stcd->CITER = biterElinkTemp; + stcd->BITER = biterElinkTemp; + } + else + { + stcd->CITER &= (uint16_t) ~(EDMA_TCD_BITER_ELINKYES_LINKCH_MASK); + stcd->BITER &= (uint16_t) ~(EDMA_TCD_BITER_ELINKYES_LINKCH_MASK); + stcd->CITER &= ~EDMA_TCD_BITER_ELINKYES_ELINK_MASK; + stcd->BITER &= ~EDMA_TCD_BITER_ELINKYES_ELINK_MASK; + } + } +} + +void EDmaDrv_PushConfigToReg(EDmaDrvType *obj, uint8_t channel, const EDmaDrv_TransferConfigType *tcd) +{ + /* Clear TCD registers */ + EDmaReg_ClearTcdReg(obj->edmaReg, channel); + + /* Set source and destination addresses */ + EDmaReg_SetTcdSrcAddr(obj->edmaReg, channel, tcd->srcAddr); + EDmaReg_SetTcdDestAddr(obj->edmaReg, channel, tcd->destAddr); + /* Set source/destination modulo feature and transfer size */ + EDmaReg_SetTcdAttribute(obj->edmaReg, channel, tcd->srcModulo, tcd->destModulo, tcd->srcDestTransferSize); + /* Set source/destination offset and last adjustment; for scatter/gather operation, destination + * last adjustment is the address of the next TCD structure to be loaded by the eDMA engine */ + EDmaReg_SetTcdSrcOffset(obj->edmaReg, channel, (uint16_t)tcd->srcOffset); + EDmaReg_SetTcdDestOffset(obj->edmaReg, channel, (uint16_t)tcd->destOffset); + EDmaReg_SetTcdSrcLastAdjust(obj->edmaReg, channel, (uint32_t)tcd->srcLastAddrAdjust); + + if(tcd->scatterGatherEnable) + { + EDmaReg_SetTcdScatterGatherCmd(obj->edmaReg, channel, true); + EDmaReg_SetTcdScatterGatherLink(obj->edmaReg, channel, tcd->scatterGatherNextDescAddr); + } + else + { + EDmaReg_SetTcdScatterGatherCmd(obj->edmaReg, channel, false); + EDmaReg_SetTcdDestLastAdjust(obj->edmaReg, channel, (uint32_t)tcd->destLastAddrAdjust); + } + + /* Configure channel interrupt */ + EDmaReg_SetTcdMajorCompleteIntCmd(obj->edmaReg, channel, tcd->interruptEnable); + + /* Configure channel clear done automatically*/ + EDmaReg_SetTcdHardClrDoneCmd(obj->edmaReg, channel, tcd->hardClrDone); + + /* If loop configuration is available, copy minor/major loop setup to registers */ + if(tcd->loopTransferConfig != NULL) + { + EDmaReg_SetTcdSrcMinorLoopOffsetCmd(obj->edmaReg, channel, tcd->loopTransferConfig->srcOffsetEnable); + EDmaReg_SetTcdDestMinorLoopOffsetCmd(obj->edmaReg, channel, tcd->loopTransferConfig->dstOffsetEnable); + EDmaReg_SetTcdMinorLoopOffset(obj->edmaReg, channel, tcd->loopTransferConfig->minorLoopOffset); + EDmaReg_SetTcdNbytes(obj->edmaReg, channel, tcd->minorByteTransferCount); + + EDmaReg_SetTcdChannelMinorLink(obj->edmaReg, + channel, + tcd->loopTransferConfig->minorLoopChnLinkNumber, + tcd->loopTransferConfig->minorLoopChnLinkEnable); + EDmaReg_SetTcdChannelMajorLink(obj->edmaReg, + channel, + tcd->loopTransferConfig->majorLoopChnLinkNumber, + tcd->loopTransferConfig->majorLoopChnLinkEnable); + + EDmaReg_SetTcdMajorCount(obj->edmaReg, channel, tcd->loopTransferConfig->majorLoopIterationCount); + } + else + { + EDmaReg_SetTcdNbytes(obj->edmaReg, channel, tcd->minorByteTransferCount); + } + + if (EDmaReg_GetChannelErrorStatusFlag(obj->edmaReg, channel)) + { + EDmaReg_ClearErrorIntStatusFlag(obj->edmaReg, channel); + } +} + +#if defined(CUSTOM_DEVASSERT) || defined(DEV_ERROR_DETECT) +/*FUNCTION********************************************************************** + * + * Function Name : EDMA_DRV_ValidTransferSize + * Description : Check if the transfer size value is legal (0/1/2/4/5). + * + *END**************************************************************************/ +static bool EDmaDrv_ValidTransferSize(edma_transfer_size_t size) +{ + bool isValid; + switch(size) + { + case EDMA_TRANSFER_SIZE_1B: + case EDMA_TRANSFER_SIZE_2B: + case EDMA_TRANSFER_SIZE_4B: +#ifdef FEATURE_DMA_TRANSFER_SIZE_8B + case EDMA_TRANSFER_SIZE_8B: +#endif +#ifdef FEATURE_DMA_TRANSFER_SIZE_16B + case EDMA_TRANSFER_SIZE_16B: +#endif +#ifdef FEATURE_DMA_TRANSFER_SIZE_32B + case EDMA_TRANSFER_SIZE_32B: +#endif +#ifdef FEATURE_DMA_TRANSFER_SIZE_64B + case EDMA_TRANSFER_SIZE_64B: +#endif + isValid = true; + break; + default: + isValid = false; + break; + } + return isValid; +} +#endif + +EDmaDrv_ChnStatusType EDmaDrv_GetChannelStatus(EDmaDrvType *obj, uint8_t channel) +{ + return obj->dmaState->chnState[channel]->status; +} + +static void EDmaDrv_ClearStructure(uint8_t *sructPtr, size_t size) +{ + while(size > 0U) + { + *sructPtr = 0; + sructPtr++; + size--; + } +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/edma/edma_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/edma/edma_drv.h new file mode 100644 index 0000000..9aadead --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/edma/edma_drv.h @@ -0,0 +1,835 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _DMA_DRV_H_ +#define _DMA_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the DMA (Direct Memory Access) module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "edma_reg.h" + +/*! \addtogroup edma_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +/*! \brief Macro for the memory size needed for the software TCD. + * + * Software TCD is aligned to 32 bytes. We don't need a software TCD structure for the first + * descriptor, since the configuration is pushed directly to registers. + * To make sure the software TCD can meet the eDMA module requirement regarding alignment, + * allocate memory for the remaining descriptors with extra 31 bytes. + */ +#define STCD_SIZE(number) (((number)*32U) - 1U) +#define STCD_ADDR(address) (((uint32_t)address + 31UL) & ~0x1FUL) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +/*! \brief Status return codes. + * Common error codes will be a unified enumeration (C enum) that will contain all error codes + * (common and specific). There will be separate "error values spaces" (or slots), each of 256 + * positions, allocated per functionality. + */ +typedef enum +{ + /* Generic error codes */ + STATUS_SUCCESS = 0x000U, /*!< Generic operation success status */ + STATUS_ERROR = 0x001U, /*!< Generic operation failure status */ + STATUS_BUSY = 0x002U, /*!< Generic operation busy status */ + STATUS_TIMEOUT = 0x003U, /*!< Generic operation timeout status */ + STATUS_UNSUPPORTED = 0x004U, /*!< Generic operation unsupported status */ +} EDmaDrv_Status; + +/*! \brief eDMA channel priority setting + */ +typedef enum +{ + EDMADRV_CHN_PRIORITY_0 = 0U, + EDMADRV_CHN_PRIORITY_1 = 1U, + EDMADRV_CHN_PRIORITY_2 = 2U, + EDMADRV_CHN_PRIORITY_3 = 3U, +#ifndef FEATURE_DMA_4_CH_PRIORITIES + EDMADRV_CHN_PRIORITY_4 = 4U, + EDMADRV_CHN_PRIORITY_5 = 5U, + EDMADRV_CHN_PRIORITY_6 = 6U, + EDMADRV_CHN_PRIORITY_7 = 7U, +#ifndef FEATURE_DMA_8_CH_PRIORITIES + EDMADRV_CHN_PRIORITY_8 = 8U, + EDMADRV_CHN_PRIORITY_9 = 9U, + EDMADRV_CHN_PRIORITY_10 = 10U, + EDMADRV_CHN_PRIORITY_11 = 11U, + EDMADRV_CHN_PRIORITY_12 = 12U, + EDMADRV_CHN_PRIORITY_13 = 13U, + EDMADRV_CHN_PRIORITY_14 = 14U, + EDMADRV_CHN_PRIORITY_15 = 15U, +#endif +#endif + EDMADRV_CHN_DEFAULT_PRIORITY = 255U +} EDmaDrv_ChannelPriorityType; + +/*! \brief eDMA channel interrupts. + */ +typedef enum +{ + EDMADRV_CHN_ERR_INT = 0U, /*!< Error interrupt */ + EDMADRV_CHN_HALF_MAJOR_LOOP_INT, /*!< Half major loop interrupt. */ + EDMADRV_CHN_MAJOR_LOOP_INT /*!< Complete major loop interrupt. */ +} EDmaDrv_ChannelInterruptType; + +/*! \brief eDMA channel arbitration mode used for selection among channels. + */ +typedef enum +{ + EDMADRV_ARBITRATION_FIXED_PRIORITY = 0U, /*!< Fixed Priority */ + EDMADRV_ARBITRATION_ROUND_ROBIN /*!< Round-Robin arbitration */ +} EDmaDrv_ArbitrationModeType; + +/*! \brief eDMA modulo configuration + */ +typedef enum +{ + EDMADRV_MODULO_OFF = 0U, + EDMADRV_MODULO_2B, + EDMADRV_MODULO_4B, + EDMADRV_MODULO_8B, + EDMADRV_MODULO_16B, + EDMADRV_MODULO_32B, + EDMADRV_MODULO_64B, + EDMADRV_MODULO_128B, + EDMADRV_MODULO_256B, + EDMADRV_MODULO_512B, + EDMADRV_MODULO_1KB, + EDMADRV_MODULO_2KB, + EDMADRV_MODULO_4KB +} EDmaDrv_ModuloType; + +/*! \brief eDMA transfer configuration + */ +typedef enum +{ + EDMADRV_TRANSFER_SIZE_1B = 0x0U, + EDMADRV_TRANSFER_SIZE_2B = 0x1U, + EDMADRV_TRANSFER_SIZE_4B = 0x2U, + EDMADRV_TRANSFER_SIZE_16B = 0x4U, + EDMADRV_TRANSFER_SIZE_32B = 0x5U +} EDmaDrv_TransferSizeType; + +/*! \brief eDMA loop transfer configuration. + * + * This structure configures the basic minor/major loop attributes. + */ +typedef struct _EDmaDrv_LoopTransferConfigType_ +{ + uint32_t majorLoopIterationCount; /*!< Number of major loop iterations. */ + bool srcOffsetEnable; /*!< Selects whether the minor loop offset is applied to the + source address upon minor loop completion. */ + bool dstOffsetEnable; /*!< Selects whether the minor loop offset is applied to the + destination address upon minor loop completion. */ + int32_t minorLoopOffset; /*!< Sign-extended offset applied to the source or destination address + to form the next-state value after the minor loop completes. */ + bool minorLoopChnLinkEnable; /*!< Enables channel-to-channel linking on minor loop complete. */ + uint8_t minorLoopChnLinkNumber; /*!< The number of the next channel to be started by DMA + engine when minor loop completes. */ + bool majorLoopChnLinkEnable; /*!< Enables channel-to-channel linking on major loop complete. */ + uint8_t majorLoopChnLinkNumber; /*!< The number of the next channel to be started by DMA + engine when major loop completes. */ +} EDmaDrv_LoopTransferConfigType; + +/*! \brief eDMA transfer size configuration. + * + * This structure configures the basic source/destination transfer attribute. + */ +typedef struct _EDmaDrv_TransferConfigType_ +{ + uint32_t srcAddr; /*!< Memory address pointing to the source data. */ + uint32_t destAddr; /*!< Memory address pointing to the destination data. */ + EDmaDrv_TransferSizeType srcDestTransferSize; /*!< Source/Destination data transfer size. */ + int16_t srcOffset; /*!< Sign-extended offset applied to the current source address + to form the next-state value as each source read/write + is completed. */ + int16_t destOffset; /*!< Sign-extended offset applied to the current destination + address to form the next-state value as each source + read/write is completed. */ + int32_t srcLastAddrAdjust; /*!< Last source address adjustment. */ + int32_t destLastAddrAdjust; /*!< Last destination address adjustment. Note here it is only + valid when scatter/gather feature is not enabled. */ + EDmaDrv_ModuloType srcModulo; /*!< Source address modulo. */ + EDmaDrv_ModuloType destModulo; /*!< Destination address modulo. */ + uint32_t minorByteTransferCount; /*!< Number of bytes to be transferred in each service request + of the channel. */ + bool scatterGatherEnable; /*!< Enable scatter gather feature. */ + uint32_t scatterGatherNextDescAddr; /*!< The address of the next descriptor to be used, when + scatter/gather feature is enabled. + Note: this value is not used when scatter/gather + feature is disabled. */ + bool interruptEnable; /*!< Enable the interrupt request when the major loop + count completes */ + bool hardClrDone; /*!< Enable Hard clear Done*/ + EDmaDrv_LoopTransferConfigType *loopTransferConfig; /*!< Pointer to loop transfer configuration structure + (defines minor/major loop attributes) + Note: this field is only used when minor loop mapping is + enabled from DMA configuration. */ +} EDmaDrv_TransferConfigType; + +typedef struct _EDmaDrv_SoftwareTcdType_ +{ + uint32_t SADDR; + int16_t SOFF; + uint16_t ATTR; + uint32_t NBYTES; + int32_t SLAST; + uint32_t DADDR; + int16_t DOFF; + uint16_t CITER; + int32_t DLAST_SGA; + uint16_t CSR; + uint16_t BITER; +} EDmaDrv_SoftwareTcdType; + +/*! \brief The user configuration structure for the eDMA driver. + * + * Use an instance of this structure with the EDmaDrv_Init() function. This allows the user to configure + * settings of the EDMA peripheral with a single function call. + */ +typedef struct _EDmaDrv_UserConfigType_ +{ + EDmaDrv_ChannelPriorityType channelPriority[EDMA_CHANNELS_INTERRUPT_LINES]; + EDmaDrv_ArbitrationModeType chnArbitration; /*!< eDMA channel arbitration. */ + bool haltOnError; /*!< Any error causes the HALT bit to set. Subsequently, all + service requests are ignored until the HALT bit is cleared. */ +} EDmaDrv_ModuleConfigType; + +/*! \brief Channel status for eDMA channel. + * + * A structure describing the eDMA channel status. The user can get the status by callback parameter + * or by calling EDmaDrv_getStatus() function. + */ +typedef enum +{ + DMA_CHN_NORMAL = 0U, /*!< eDMA channel normal state. */ + DMA_CHN_ERROR /*!< An error occurred in the eDMA channel. */ +} EDmaDrv_ChnStatusType; + +/*! \brief Definition for the eDMA channel callback function. + * + * Prototype for the callback function registered in the eDMA driver. + */ +typedef void (*EDmaDrv_CallBackType)(void *parameter, EDmaDrv_ChnStatusType status); + +/*! \brief Data structure for the eDMA channel state. + */ +typedef struct _DmaDrv_ChnStateType_ +{ + uint8_t chn; /*!< Channel number. */ + EDmaDrv_CallBackType callback; /*!< Callback function pointer for the eDMA channel. It will + be called at the eDMA channel complete and eDMA channel + error. */ + void *parameter; /*!< Parameter for the callback function pointer. */ + volatile EDmaDrv_ChnStatusType status; /*!< eDMA channel status. */ +} EDmaDrv_ChnStateType; + +/*! \brief Runtime state structure for the eDMA driver. + * + * This structure holds data that is used by the eDMA peripheral driver to manage + * multi eDMA channels. + * The user passes the memory for this run-time state structure and the eDMA + * driver populates the members. + */ +typedef struct _EDmaDrv_StateType_ +{ + EDmaDrv_ChnStateType *volatile chnState[(uint32_t)EDMA_CHANNELS]; /*!< Pointer array storing channel state. */ +} EDmaDrv_StateType; + +/*! \brief Definition of configuration of Dma driver + */ +typedef struct _EDmaDrv_ChannelConfigType_ +{ + uint8_t chnConfig; /*!< eDMA channel number */ + EDmaDrv_ChannelPriorityType channelPriority; /*!< eDMA channel priority - only used when channel + arbitration mode is 'Fixed priority'. */ + EDma_RequestSourceType source; /*!< Selects the source of the DMA request for this channel */ + EDmaDrv_CallBackType callback; /*!< Callback that will be registered for this channel */ + void *callbackParam; /*!< Parameter passed to the channel callback */ + bool enableTrigger; /*!< Enables the periodic trigger capability for the DMA channel. */ +} EDmaDrv_ChannelConfigType; + +/*! \brief Transfer type for the DMA transfer. + */ +typedef enum +{ + EDMADRV_TRANSFER_PERIPH2MEM = 0U, /*!< Transfer from peripheral to memory */ + EDMADRV_TRANSFER_MEM2PERIPH, /*!< Transfer from memory to peripheral */ + EDMADRV_TRANSFER_MEM2MEM, /*!< Transfer from memory to memory */ + EDMADRV_TRANSFER_PERIPH2PERIPH /*!< Transfer from peripheral to peripheral */ +} EDmaDrv_TransferType; + +/*! \brief Data structure for configuring a discrete memory transfer. + */ +typedef struct _EDmaDrv_ScatterGatherListType_ +{ + uint32_t address; /*!< Address of buffer. */ + uint32_t length; /*!< Length of buffer. */ + EDmaDrv_TransferType type; /*!< Type of the DMA transfer */ +} EDmaDrv_ScatterGatherListType; + +/* Forward declaration of DMA register */ +struct _EDmaRegType_; + +/* Forward declaration of DMAMUX register */ +struct _DmamuxRegType_; + +/*! \brief The definition of DMA driver class + */ +typedef struct _EDmaDrvType_ +{ + EDmaDrv_StateType *dmaState; + struct _EDmaRegType_ *edmaReg; + struct _DmamuxRegType_ *dmamuxReg; +} EDmaDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ +/*! \brief Initializes the eDMA driver module + * + * This function initializes eDMA driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] dmaReg : pointer to eDMA register instance + * \param[in] dmaReg : pointer to DMAMUX register instance + */ +extern void EDmaDrv_Init(EDmaDrvType *obj, struct _EDmaRegType_ *dmaReg, struct _DmamuxRegType_ *dmamuxReg); + +/*! \brief Configures the eDMA module from a module configuration structure + * + * This function configures the eDMA module from a module configuration structure + * + * \param[out] moduleConfig : pointer to configuration structure + */ +extern void EDmaDrv_GetDefaultConfigure(EDmaDrv_ModuleConfigType *moduleConfig); + +/*! \brief Configures the eDMA module from a channel configuration structure + * + * This function configures the eDMA module from a channel configuration structure + * + * \param[out] channelConfig : pointer to configuration structure + */ +extern void EDmaDrv_GetDefaultChannelConfigure(EDmaDrv_ChannelConfigType *channelConfig); + +/*! \brief Configure the eDMA module. + * + * This function initializes the run-time state structure to provide the eDMA channel allocation + * release, protect, and track the state for channels. This function also resets the eDMA modules, + * initializes the module to user-defined settings and default settings. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] edmaState: The pointer to the eDMA peripheral driver state structure. The user passes + * the memory for this run-time state structure and the eDMA peripheral driver populates the + * members. This run-time state structure keeps track of the eDMA channels status. The memory must + * be kept valid before calling the EDmaDrv_DeInit. + * \param[in] moduleConfig: User configuration structure for eDMA peripheral drivers. The user populates the + * members of this structure and passes the pointer of this structure into the function. + * + * \return STATUS_ERROR or STATUS_SUCCESS. + */ +extern EDmaDrv_Status EDmaDrv_Configure(EDmaDrvType *obj, EDmaDrv_StateType *edmaState, const EDmaDrv_ModuleConfigType *moduleConfig); + +/*! \brief Configure the eDMA module. + * + * This function initializes the run-time state structure to provide the eDMA channel allocation + * release, protect, and track the state for channels. This function also resets the eDMA modules, + * initializes the module to user-defined settings and default settings. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] chnStateArray : Array of pointers to run-time state structures for eDMA channels; + * will populate the state structures inside the eDMA driver state structure. + * \param[in] chnConfig : pointers to channel initialization structures. + * + * \return STATUS_ERROR or STATUS_SUCCESS. + */ +extern EDmaDrv_Status EDmaDrv_ConfigureChannel(EDmaDrvType *obj, + EDmaDrv_ChnStateType *const chnStateArray[], + const EDmaDrv_ChannelConfigType *const chnConfig); + +/*! \brief De-initializes the eDMA module. + * + * This function resets the eDMA module to reset state and disables the interrupt to the core. + * + * \param[in] obj : pointer to eDMA driver instance + * \return STATUS_ERROR or STATUS_SUCCESS. + */ +extern EDmaDrv_Status EDmaDrv_Deinit(EDmaDrvType *obj); + +/*! \brief Initializes an eDMA channel. + * + * This function initializes the run-time state structure for a eDMA channel, based on user + * configuration. It will request the channel, set up the channel priority and install the + * callback. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] edmaChannelState : Pointer to the eDMA channel state structure. The user passes + * the memory for this run-time state structure and the eDMA peripheral driver populates the + * members. This run-time state structure keeps track of the eDMA channel status. The memory must + * be kept valid before calling the EDmaDrv_ReleaseChannel. + * \param[in] edmaChannelConfig : User configuration structure for eDMA channel. The user populates the + * members of this structure and passes the pointer of this structure into the function. + * + * \return STATUS_ERROR or STATUS_SUCCESS. + */ +extern EDmaDrv_Status EDmaDrv_ChannelInit(EDmaDrvType *obj, + EDmaDrv_ChnStateType *edmaChannelState, + const EDmaDrv_ChannelConfigType *edmaChannelConfig); + +/*! \brief Releases an eDMA channel. + * + * This function stops the eDMA channel and disables the interrupt of this channel. The channel state + * structure can be released after this function is called. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * + * \return STATUS_ERROR or STATUS_SUCCESS. + */ +extern EDmaDrv_Status EDmaDrv_ReleaseChannel(EDmaDrvType *obj, uint8_t channel); + +/*! \brief Copies the channel configuration to the TCD registers. + * + * \param[in] channel : eDMA channel number + * \param[in] tcd Pointer to the channel configuration structure. + */ +void EDmaDrv_PushConfigToReg(EDmaDrvType *obj, uint8_t channel, const EDmaDrv_TransferConfigType *tcd); + +/*! \brief Copies the channel configuration to the software TCD structure. + * + * This function copies the properties from the channel configuration to the software TCD structure; the address + * of the software TCD can be used to enable scatter/gather operation (pointer to the next TCD). + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] config : Pointer to the channel configuration structure. + * \param[in] stcd : Pointer to the software TCD structure. + */ +void EDmaDrv_PushConfigToSTcd(const EDmaDrv_TransferConfigType *config, EDmaDrv_SoftwareTcdType *stcd); + +/*! \brief Configures a simple single block data transfer with DMA. + * + * This function configures the descriptor for a single block transfer. + * The function considers contiguous memory blocks, thus it configures the TCD + * source/destination offset fields to cover the data buffer without gaps, + * according to "transferSize" parameter (the offset is equal to the number of + * bytes transferred in a source read/destination write). + * + * NOTE: For memory-to-peripheral or peripheral-to-memory transfers, make sure + * the transfer size is equal to the data buffer size of the peripheral used, + * otherwise only truncated chunks of data may be transferred (e.g. for a + * communication IP with an 8-bit data register the transfer size should be 1B, + * whereas for a 32-bit data register, the transfer size should be 4B). The + * rationale of this constraint is that, on the peripheral side, the address + * offset is set to zero, allowing to read/write data from/to the peripheral + * in a single source read/destination write operation. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] type : Transfer type (M->M, P->M, M->P, P->P). + * \param[in] srcAddr : A source register address or a source memory address. + * \param[in] destAddr : A destination register address or a destination memory address. + * \param[in] transferSize : The number of bytes to be transferred on every DMA write/read. + * Source/Dest share the same write/read size. + * \param[in] dataBufferSize : The total number of bytes to be transferred. + * + * \return STATUS_ERROR or STATUS_SUCCESS + */ +extern EDmaDrv_Status EDmaDrv_ConfigSingleBlockTransfer(EDmaDrvType *obj, + uint8_t channel, + EDmaDrv_TransferType type, + uint32_t srcAddr, + uint32_t destAddr, + EDmaDrv_TransferSizeType transferSize, + uint32_t dataBufferSize, + bool enableHwClrDone); + +/*! \brief Configures a multiple block data transfer with DMA. + * + * This function configures the descriptor for a multi-block transfer. + * The function considers contiguous memory blocks, thus it configures the TCD + * source/destination offset fields to cover the data buffer without gaps, + * according to "transferSize" parameter (the offset is equal to the number of + * bytes transferred in a source read/destination write). The buffer is divided + * in multiple block, each block being transferred upon a single DMA request. + * + * NOTE: For transfers to/from peripherals, make sure + * the transfer size is equal to the data buffer size of the peripheral used, + * otherwise only truncated chunks of data may be transferred (e.g. for a + * communication IP with an 8-bit data register the transfer size should be 1B, + * whereas for a 32-bit data register, the transfer size should be 4B). The + * rationale of this constraint is that, on the peripheral side, the address + * offset is set to zero, allowing to read/write data from/to the peripheral + * in a single source read/destination write operation. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] type : Transfer type (M->M, P->M, M->P, P->P). + * \param[in] srcAddr : A source register address or a source memory address. + * \param[in] destAddr : A destination register address or a destination memory address. + * \param[in] transferSize : The number of bytes to be transferred on every DMA write/read. + * Source/Dest share the same write/read size. + * \param[in] blockSize : The total number of bytes inside a block. + * \param[in] blockCount : The total number of data blocks (one block is transferred upon a DMA request). + * \param[in] disableReqOnCompletion : This parameter specifies whether the DMA channel should + * be disabled when the transfer is complete (further requests will remain untreated). + * + * \return STATUS_ERROR or STATUS_SUCCESS + */ +extern EDmaDrv_Status EDmaDrv_ConfigMultiBlockTransfer(EDmaDrvType *obj, + uint8_t channel, + EDmaDrv_TransferType type, + uint32_t srcAddr, + uint32_t destAddr, + EDmaDrv_TransferSizeType transferSize, + uint32_t blockSize, + uint32_t blockCount, + bool enableHwClrDone, + bool disableReqOnCompletion); + +/*! \brief Configures the DMA transfer in loop mode. + * + * This function configures the DMA transfer in a loop chain. The user passes a block of memory into this + * function that configures the loop transfer properties (minor/major loop count, address offsets, channel linking). + * The DMA driver copies the configuration to TCD registers, only when the loop properties are set up correctly + * and minor loop mapping is enabled for the eDMA module. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] transferConfig : Pointer to the transfer configuration strucutre; this structure defines fields for setting + * up the basic transfer and also a pointer to a memory strucure that defines the loop chain properties (minor/major). + * + * \return STATUS_ERROR or STATUS_SUCCESS + */ +extern EDmaDrv_Status EDmaDrv_ConfigLoopTransfer(EDmaDrvType *obj, uint8_t channel, const EDmaDrv_TransferConfigType *transferConfig); + +/*! \brief Configures the DMA transfer in a scatter-gather mode. + * + * This function configures the descriptors into a single-ended chain. The user passes blocks of memory into + * this function. The interrupt is triggered only when the last memory block is completed. The memory block + * information is passed with the edma_scatter_gather_list_t data structure, which can tell + * the memory address and length. + * The DMA driver configures the descriptor for each memory block, transfers the descriptor from the + * first one to the last one, and stops. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] stcd : Array of empty software TCD structures. The user must prepare this memory block. We don't need a + * software TCD structure for the first descriptor, since the configuration is pushed directly to registers.The "stcd" + * buffer must align with 32 bytes; if not, an error occurs in the eDMA driver. Thus, the required + * memory size for "stcd" is equal to tcdCount * size_of(edma_software_tcd_t) - 1; the driver will take + * care of the memory alignment if the provided memory buffer is big enough. For proper allocation of the + * "stcd" buffer it is recommended to use STCD_SIZE macro. + * \param[in] transferSize : The number of bytes to be transferred on every DMA write/read. + * \param[in] bytesOnEachRequest Bytes to be transferred in each DMA request. + * \param[in] srcList : Data structure storing the address, length and type of transfer (M->M, M->P, P->M, P->P) for + * the bytes to be transferred for source memory blocks. If the source memory is peripheral, the length + * is not used. + * \param[in] destList : Data structure storing the address, length and type of transfer (M->M, M->P, P->M, P->P) for + * the bytes to be transferred for destination memory blocks. In the memory-to-memory transfer mode, the + * user must ensure that the length of the destination scatter gather list is equal to the source + * scatter gather list. If the destination memory is a peripheral register, the length is not used. + * \param[in] tcdCount : The number of TCD memory blocks contained in the scatter gather list. + * + * \return STATUS_ERROR or STATUS_SUCCESS + */ +extern EDmaDrv_Status EDmaDrv_ConfigScatterGatherTransfer(EDmaDrvType *obj, + uint8_t channel, + EDmaDrv_SoftwareTcdType *stcd, + EDmaDrv_TransferSizeType transferSize, + uint32_t bytesOnEachRequest, + bool hardClrDone, + const EDmaDrv_ScatterGatherListType *srcList, + const EDmaDrv_ScatterGatherListType *destList, + const EDmaDrv_LoopTransferConfigType *loopTransferList, + uint8_t tcdCount); + +/*! \brief Cancel the running transfer. + * + * This function cancels the current transfer, optionally signalling an error. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] bool : error If true, an error will be logged for the current transfer. + */ +void EDmaDrv_CancelTransfer(EDmaDrvType *obj, bool error); + +/*! \brief Starts an eDMA channel. + * + * This function enables the eDMA channel DMA request. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * + * \return STATUS_ERROR or STATUS_SUCCESS. + */ +extern EDmaDrv_Status EDmaDrv_StartChannel(EDmaDrvType *obj, uint8_t channel); + +/*! \brief Stops the eDMA channel. + * + * This function disables the eDMA channel DMA request. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * + * \return STATUS_ERROR or STATUS_SUCCESS. + */ +extern EDmaDrv_Status EDmaDrv_StopChannel(EDmaDrvType *obj, uint8_t channel); + +/*! \brief Configures the DMA request for the eDMA channel. + * + * Selects which DMA source is routed to a DMA channel. The DMA sources are defined in the file + * _Features.h + * Configures the periodic trigger capability for the triggered DMA channel. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] request : DMA request source. + * \param[in] enableTrigger : DMA channel periodic trigger. + * + * \return STATUS_SUCCESS or STATUS_UNSUPPORTED. + */ +extern EDmaDrv_Status EDmaDrv_SetChannelRequestAndTrigger(EDmaDrvType *obj, uint8_t channel, uint8_t request, bool enableTrigger); + +/*! \brief Clears all registers to 0 for the channel's TCD. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + */ +extern void EDmaDrv_ClearTcd(EDmaDrvType *obj, uint8_t channel); + +/*! \brief Configures the source address for the eDMA channel. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] address : The pointer to the source memory address. + */ +extern void EDmaDrv_SetSrcAddr(EDmaDrvType *obj, uint8_t channel, uint32_t address); + +/*! \brief Configures the source address signed offset for the eDMA channel. + * + * Sign-extended offset applied to the current source address to form the next-state value as each + * source read is complete. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] offset : Signed-offset for source address. + */ +extern void EDmaDrv_SetSrcOffset(EDmaDrvType *obj, uint8_t channel, int16_t offset); + +/*! \brief Configures the source data chunk size (transferred in a read sequence). + * + * Source data read transfer size (1/2/4/16/32 bytes). + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] size : Source transfer size. + */ +extern void EDmaDrv_SetSrcReadDestWriteChunkSize(EDmaDrvType *obj, uint8_t channel, EDmaDrv_TransferSizeType size); + +/*! \brief Configures the source address last adjustment. + * + * Adjustment value added to the source address at the completion of the major iteration count. This + * value can be applied to restore the source address to the initial value, or adjust the address to + * reference the next data structure. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] adjust : Adjustment value. + */ +extern void EDmaDrv_SetSrcLastAddrAdjustment(EDmaDrvType *obj, uint8_t channel, int32_t adjust); + +/*! \brief Configures the destination address for the eDMA channel. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] address : The pointer to the destination memory address. + */ +extern void EDmaDrv_SetDestAddr(EDmaDrvType *obj, uint8_t channel, uint32_t address); + +/*! \brief Configures the destination address signed offset for the eDMA channel. + * + * Sign-extended offset applied to the current destination address to form the next-state value as each + * destination write is complete. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] offset : signed-offset + */ +extern void EDmaDrv_SetDestOffset(EDmaDrvType *obj, uint8_t channel, int16_t offset); + +/*! \brief Configures the destination address last adjustment. + * + * Adjustment value added to the destination address at the completion of the major iteration count. This + * value can be applied to restore the destination address to the initial value, or adjust the address to + * reference the next data structure. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] adjust : Adjustment value. + */ +extern void EDmaDrv_SetDestLastAddrAdjustment(EDmaDrvType *obj, uint8_t channel, int32_t adjust); + +/*! \brief Configures the number of bytes to be transferred in each service request of the channel. + * + * Sets the number of bytes to be transferred each time a request is received (one major loop iteration). + * This number needs to be a multiple of the source/destination transfer size, as the data block will be + * transferred within multiple read/write sequences (minor loops). + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] nbytes : Number of bytes to be transferred in each service request of the channel + */ +extern void EDmaDrv_SetMinorLoopBlockSize(EDmaDrvType *obj, uint8_t channel, uint32_t nbytes); + +/*! \brief Configures the number of major loop iterations. + * + * Sets the number of major loop iterations; each major loop iteration will be served upon a request + * for the current channel, transferring the data block configured for the minor loop (NBYTES). + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] majorLoopCount : Number of major loop iterations. + */ +extern void EDmaDrv_SetMajorLoopIterationCount(EDmaDrvType *obj, uint8_t channel, uint32_t majorLoopCount); + +/*! \brief Returns the remaining major loop iteration count. + * + * Gets the number minor loops yet to be triggered (major loop iterations). + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \return number of major loop iterations yet to be triggered + */ +extern uint32_t EDmaDrv_GetRemainingMajorIterationsCount(EDmaDrvType *obj, uint8_t channel); + +/*! \brief Configures the memory address of the next TCD, in scatter/gather mode. + * + * This function configures the address of the next TCD to be loaded form memory, when scatter/gather + * feature is enabled. This address points to the beginning of a 0-modulo-32 byte region containing + * the next transfer TCD to be loaded into this channel. The channel reload is performed as the + * major iteration count completes. The scatter/gather address must be 0-modulo-32-byte. Otherwise, + * a configuration error is reported. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] nextTCDAddr : The address of the next TCD to be linked to this TCD. + */ +extern void EDmaDrv_SetScatterGatherLink(EDmaDrvType *obj, uint8_t channel, uint32_t nextTCDAddr); + +/*! \brief Disables/Enables the DMA request after the major loop completes for the TCD. + * + * If disabled, the eDMA hardware automatically clears the corresponding DMA request when the + * current major iteration count reaches zero. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] disable : Disable (true)/Enable (false) DMA request after TCD complete. + */ +extern void EDmaDrv_DisableRequestsOnTransferComplete(EDmaDrvType *obj, uint8_t channel, bool disable); + +/*! \brief Disables/Enables the channel interrupt requests. + * + * This function enables/disables error, half major loop and complete major loop interrupts + * for the current channel. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] interrupt : Interrupt event (error/half major loop/complete major loop). + * \param[in] enable : Enable (true)/Disable (false) interrupts for the current channel. + */ +extern void EDmaDrv_ConfigureInterrupt(EDmaDrvType *obj, uint8_t channel, EDmaDrv_ChannelInterruptType intSrc, bool enable); + +/*! \brief Triggers a sw request for the current channel. + * + * This function starts a transfer using the current channel (sw request). + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + */ +extern void EDmaDrv_TriggerSwRequest(EDmaDrvType *obj, uint8_t channel); + +/*! \brief Registers the callback function and the parameter for eDMA channel. + * + * This function registers the callback function and the parameter into the eDMA channel state structure. + * The callback function is called when the channel is complete or a channel error occurs. The eDMA + * driver passes the channel status to this callback function to indicate whether it is caused by the + * channel complete event or the channel error event. + * + * To un-register the callback function, set the callback function to "NULL" and call this + * function. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number. + * \param[in] callback : The pointer to the callback function. + * \param[in] parameter : The pointer to the callback function's parameter. + * + * \return STATUS_ERROR or STATUS_SUCCESS. + */ +extern EDmaDrv_Status EDmaDrv_InstallCallback(EDmaDrvType *obj, uint8_t channel, EDmaDrv_CallBackType callback, void *parameter); + +/*! \brief Gets the eDMA channel status. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number. + * + * \return Channel status. + */ +extern EDmaDrv_ChnStatusType EDmaDrv_GetChannelStatus(EDmaDrvType *obj, uint8_t channel); + +/*! \brief DMA channel interrupt handler, implemented in driver c file. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number. + */ +extern void EDmaDrv_IRQHandler(EDmaDrvType *obj, uint8_t Channel); + +/*! \brief DMA error interrupt handler, implemented in driver c file. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number. + */ +extern void EDmaDrv_ErrorIRQHandler(EDmaDrvType *obj, uint8_t channel); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _DMA_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/eim/eim_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/eim/eim_drv.c new file mode 100644 index 0000000..b3fb7dc --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/eim/eim_drv.c @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "eim_drv.h" +#include "eim_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +#define EIM_LENGTH_CHK (8) +#define EIM_LENGTH_DATA (32) +#define EIM_LENGTH_ADDR (32) + + +uint8_t arr_data2reg_chk[EIM_LENGTH_CHK] = { + 0, 1, 3, 7, 15, 31, /* REG_DATA */ + 31, /* REG_ADDR */ + 7 /* REG_CHK */ +}; + +uint8_t arr_data2reg_data[EIM_LENGTH_DATA] = { + 2, 4, 5, 6, 8, 9, 10, 11, 12, /* REG_DATA */ + 13, 14, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, + 0, 1, 2, 3, 4, 5 /* REG_ADDR */ + +}; + +uint8_t arr_data2reg_addr[EIM_LENGTH_ADDR] = { + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* REG_ADDR */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, + 0, 1, 2, 3, 4, 5, 6 /* REG_CHK */ +}; + + + +uint8_t arr_reg2data_chk[EIM_LENGTH_CHK] = { + 25, 26, 27, 28, 29, 30, 31, /* REG_ADDR */ + 7 /* REG_CHK */ +}; + +uint8_t arr_reg2data_data[EIM_LENGTH_DATA] = { + 0, 1, /* REG_CHK */ + 0, /* REG_DATA */ + 2, /* REG_CHK */ + 1, 2, 3, /* REG_DATA */ + 3, /* REG_CHK */ + 4, 5, 6, 7, 8, 9, 10, /* REG_DATA */ + 4, /* REG_CHK */ + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, /* REG_DATA */ + 5 /* REG_CHK */ + +}; + +uint8_t arr_reg2data_addr[EIM_LENGTH_ADDR] = { + 26, 27, 28, 29, 30, 31, /* REG_DATA */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* REG_ADDR */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, + 6 /* REG_CHK */ +}; + +static void EimDrv_RegToDataConvert(EimDrv_SramType *sramType, EimDrv_SramType *sramType_temp) +{ + uint8_t i; + uint8_t length = EIM_LENGTH_CHK; + + for (i = 0; i < length; i++) + { + if ((sramType_temp->data_h >> i) & 0x01) + { + if ( i <= 6 ) sramType->data_m |= 1 << arr_reg2data_chk[i]; + if (i > 6 && i < length ) sramType->data_h |= 1 << arr_reg2data_chk[i]; + } + } + + length = EIM_LENGTH_DATA; + for (i = 0; i < length; i++) + { + if ((sramType_temp->data_l >> i) & 0x01) + { + if (i <= 1 ) sramType->data_h |= 1 << arr_reg2data_data[i]; + if (i == 2 ) sramType->data_l |= 1 << arr_reg2data_data[i]; + if (i == 3 ) sramType->data_h |= 1 << arr_reg2data_data[i]; + if (i > 3 && i <= 6 ) sramType->data_l |= 1 << arr_reg2data_data[i]; + if (i == 7 ) sramType->data_h |= 1 << arr_reg2data_data[i]; + if (i > 7 && i <= 14 ) sramType->data_l |= 1 << arr_reg2data_data[i]; + if (i == 15 ) sramType->data_h |= 1 << arr_reg2data_data[i]; + if (i > 16 && i <= 30 ) sramType->data_l |= 1 << arr_reg2data_data[i]; + if (i == 31 ) sramType->data_h |= 1 << arr_reg2data_data[i]; + } + } + + length = EIM_LENGTH_ADDR; + for (i = 0; i < length; i++) + { + if ((sramType_temp->data_m >> i) & 0x01) + { + if (i <= 5 ) sramType->data_l |= 1 << arr_reg2data_addr[i]; + if (i > 5 && i <= 30 ) sramType->data_m |= 1 << arr_reg2data_addr[i]; + if (i == 31 ) sramType->data_h |= 1 << arr_reg2data_addr[i]; + } + } +} + +static void EimDrv_DataToRegConvert(EimDrv_SramType *sramType, EimDrv_SramType *sramType_temp) +{ + uint8_t i; + uint8_t length = EIM_LENGTH_CHK; + + for (i = 0; i < length; i++) + { + if ((sramType->data_h >> i) & 0x01) + { + if (i <= 5 ) sramType_temp->data_l |= 1 << arr_data2reg_chk[i]; + if (i > 5 && i <= 6 ) sramType_temp->data_m |= 1 << arr_data2reg_chk[i]; + if (i > 6 && i < length ) sramType_temp->data_h |= 1 << arr_data2reg_chk[i]; + } + } + + length = EIM_LENGTH_DATA; + for (i = 0; i < length; i++) + { + if ((sramType->data_l >> i) & 0x01) + { + if (i <= 26 ) sramType_temp->data_l |= 1 << arr_data2reg_data[i]; + if (i > 26 && i < length ) sramType_temp->data_m |= 1 << arr_data2reg_data[i]; + } + } + + length = EIM_LENGTH_ADDR; + for (i = 0; i < length; i++) + { + if ((sramType->data_m >> i) & 0x01) + { + if (i <= 24 ) sramType_temp->data_m |= 1 << arr_data2reg_addr[i]; + if (i > 24 && i < length ) sramType_temp->data_h |= 1 << arr_data2reg_addr[i]; + } + } +} + +void EimDrv_Init(EimDrvType *obj, struct _EimRegType_ *eimReg) +{ + obj->reg = eimReg; +} + +void EimDrv_GetDefaultConfig(EimDrv_ChnCfgType *userConfig) +{ + /* Get Error in global enable status, default: false */ + userConfig->globalEnable = false; + + /* Get Error in channel num enable status, default: false */ + userConfig->chnNumStatus = false; + + /* Get Error in sram data high, default: 0 */ + userConfig->accSramCfg.data_h = 0; + /* Get Error in sram data middle, default: 0 */ + userConfig->accSramCfg.data_m = 0; + /* Get Error in sram data low, default: 0 */ + userConfig->accSramCfg.data_l = 0; +} + +bool EimDrv_GetChnGlobalEnable(EimDrvType *obj) +{ + /* Get Error in global enable */ + return EimReg_GetCrGeiEn(obj->reg); +} + +void EimDrv_EnableGlobalChn(EimDrvType *obj, bool enable) +{ + /* Config Error in global enable */ + EimReg_SetCrGeiEn(obj->reg, (uint8_t)enable); +} + +bool EimDrv_GetChnNumEnable(EimDrvType *obj) +{ + /* Get Error in channel num enable */ + return (bool)EimReg_GetChEnCh0(obj->reg); +} + +void EimDrv_EnableChannel(EimDrvType *obj, bool enable) +{ + /* Set Error in channel num enable */ + EimReg_SetChEnCh0(obj->reg, (uint8_t)enable); +} + +void EimDrv_GetSramErrInStatus(EimDrvType *obj, EimDrv_SramType *sramType) +{ + EimDrv_SramType sramType_temp = {0}; + + /* get error in access sram data high */ + sramType_temp.data_h = EimReg_GetCh0DataH(obj->reg); + /* get error in access sram data middle */ + sramType_temp.data_m = EimReg_GetCh0DataM(obj->reg); + /* get error in access sram low */ + sramType_temp.data_l = EimReg_GetCh0DataL(obj->reg); + + EimDrv_RegToDataConvert(sramType, &sramType_temp); +} + +void EimDrv_SetSramErrInStatus(EimDrvType *obj, EimDrv_SramType *sramType) +{ + EimDrv_SramType sramType_temp = {0}; + + EimDrv_DataToRegConvert(sramType, &sramType_temp); + + /* set error in access sram data high */ + EimReg_SetCh0DataH(obj->reg, sramType_temp.data_h); + /* set error in access sram data middle */ + EimReg_SetCh0DataM(obj->reg, sramType_temp.data_m); + /* set error in access sram low */ + EimReg_SetCh0DataL(obj->reg, sramType_temp.data_l); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/eim/eim_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/eim/eim_drv.h new file mode 100644 index 0000000..0f3cdea --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/eim/eim_drv.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _EIM_DRV_H_ +#define _EIM_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of EIM + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup eim_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/* Forward declaration of related register */ +struct _EimRegType_; + +/*! \brief The definition of EIM driver class + */ +typedef struct _EimDrvType_ +{ + struct _EimRegType_ *reg; /*!< pointer to EIM register */ +} EimDrvType; + +/*! \brief struct of EIM Sram channel control + */ +typedef struct _EimDrv_ErrInSramType_ +{ + uint8_t data_h; /*!< Access Sram Error in data high */ + uint32_t data_m; /*!< Access Sram Error in data middle */ + uint32_t data_l; /*!< Access Sram Error in data low */ +} EimDrv_SramType; + +/*! \brief struct of EIM Config + */ +typedef struct _EimDrv_ChnCfgType_ +{ + bool globalEnable; /*!< Eim global enable status */ + bool chnNumStatus; /*!< Eim channel num enable status */ + EimDrv_SramType accSramCfg; /*!< Access Sram Error in config */ +} EimDrv_ChnCfgType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the EIM driver module + * + * This function initializes EIM driver by setting the register + * instances to it. + * + * \param[in] obj : pointer to EIM driver instance + * \param[in] eimReg : pointer to EIM register instance + */ +extern void EimDrv_Init(EimDrvType *obj, struct _EimRegType_ *eimReg); + +/*! \brief Get EIM Default config paramter + * + * This function get EIM config paramter. + * + * \param[in] userConfig : pointer to default parameter + */ +extern void EimDrv_GetDefaultConfig(EimDrv_ChnCfgType *userConfig); + +/*! \brief Get EIM Global Channel Enable Status + * + * This function get global Channel enable status. + * + * \param[in] obj : pointer to EIM driver instance + */ +extern bool EimDrv_GetChnGlobalEnable(EimDrvType *obj); + +/*! \brief Set EIM Global Channel Enable Status + * + * This function set global Channel enable status. + * + * \param[in] obj : pointer to EIM driver instance + * \param[in] enable : + * - true : enable global channel + * - false : disable global channel + * + */ +extern void EimDrv_EnableGlobalChn(EimDrvType *obj, bool enable); + +/*! \brief Get EIM Channel Number Enable Status + * + * This function get global Channel number enable status. + * + * \param[in] obj : pointer to EIM driver instance + */ +extern bool EimDrv_GetChnNumEnable(EimDrvType *obj); + +/*! \brief Set EIM Channel Number Enable Status + * + * This function set global Channel number enable status. + * + * \param[in] obj : pointer to EIM driver instance + * \param[in] chnNum : select the channel set status + * \param[in] enable : + * - true : enable selected channel + * - false : disable selected channel + */ +extern void EimDrv_EnableChannel(EimDrvType *obj, bool enable); + +/*! \brief Get Access Sram EIM Config + * + * This function get access sram EIM config parameter + * + * \param[in] obj : pointer to EIM driver instance + * \param[in] sramType : pointer to get access sram paramter chk/data/addr + */ +extern void EimDrv_GetSramErrInStatus(EimDrvType *obj, EimDrv_SramType *sramType); + +/*! \brief Set Access Sram EIM Config + * + * This function set access sram EIM config parameter + * + * \param[in] obj : pointer to EIM driver instance + * \param[in] sramType : pointer to set access sram paramter chk/data/addr + */ +extern void EimDrv_SetSramErrInStatus(EimDrvType *obj, EimDrv_SramType *sramType); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _EIM_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/erm/erm_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/erm/erm_drv.c new file mode 100644 index 0000000..d241d62 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/erm/erm_drv.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "erm_drv.h" +#include "erm_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void ErmDrv_Init(ErmDrvType *obj, struct _ErmRegType_ *ermReg) +{ + obj->reg = ermReg; +} + +void ErmDrv_GetDefaultConfig(ErmDrv_ChnErrConfigType *userConfig) +{ + uint8_t chnNum; + uint8_t ctrlChnNum; + + for(chnNum = 0; chnNum < ERMDRV_CH_TOTAL_NUM; chnNum++) + { + /* ERM channel Irq enable, default: false */ + userConfig->chnIrq[chnNum] = false; + /* ERM channel error status, default: false */ + userConfig->chnEvent[chnNum] = false; + } + + for(ctrlChnNum = 0; ctrlChnNum < ERMDRV_CH_CTRL_TOTAL_NUM; ctrlChnNum++) + { + /* ERM channel 0~3 control error address, default: 0 */ + userConfig->chnStatus[ctrlChnNum].errAddr = 0; + /* ERM channel 0~3 control error position, default: 0 */ + userConfig->chnStatus[ctrlChnNum].errPos = 0; + /* ERM channel 0~3 control recover error num, default: 0 */ + userConfig->chnStatus[ctrlChnNum].errRecoverNum = 0; + } +} + +void ErmDrv_SetChnErrIrqEnable(ErmDrvType *obj, ErmDrv_ChnNumType chnNum, bool enable) +{ + switch(chnNum) + { + case ERMDRV_CH0_RECOVER_SRAM_IRQ: + /* set ERM enable SRAM single bit recover channel */ + ErmReg_SetCr0Escie0(obj->reg, (uint8_t)enable); + break; + case ERMDRV_CH0_NONRECOVER_SRAM_IRQ: + /* set ERM enable SRAM multi bits non-recover channel */ + ErmReg_SetCr0Encie0(obj->reg, (uint8_t)enable); + break; + case ERMDRV_CH1_RECOVER_FTFC_IRQ: + /* set ERM enable FTFC single bit recover channel */ + ErmReg_SetCr0Escie1(obj->reg, (uint8_t)enable); + break; + case ERMDRV_CH1_NONRECOVER_FTFC_IRQ: + /* set ERM enable FTFC multi bits non-recover channel */ + ErmReg_SetCr0Encie1(obj->reg, (uint8_t)enable); + break; + default: + break; + } +} + +bool ErmDrv_GetChnErrIrqEnable(ErmDrvType *obj, ErmDrv_ChnNumType chnNum) +{ + switch(chnNum) + { + case ERMDRV_CH0_RECOVER_SRAM_IRQ: + /* get ERM enable SRAM single bit recover channel status */ + return (bool)ErmReg_GetCr0Escie0(obj->reg); + case ERMDRV_CH0_NONRECOVER_SRAM_IRQ: + /* get ERM enable SRAM multi bits non-recover channel status */ + return (bool)ErmReg_GetCr0Encie0(obj->reg); + case ERMDRV_CH1_RECOVER_FTFC_IRQ: + /* get ERM enable FTFC single bit recover channel status */ + return (bool)ErmReg_GetCr0Escie1(obj->reg); + case ERMDRV_CH1_NONRECOVER_FTFC_IRQ: + /* get ERM enable FTFC multi bits non-recover channel status */ + return (bool)ErmReg_GetCr0Encie1(obj->reg); + default: + return ERMDRV_CH_TOTAL_NUM; + } +} + +bool ErmDrv_GetChnErrInfoStatus(ErmDrvType *obj, ErmDrv_ChnNumType chnNum) +{ + switch(chnNum) + { + case ERMDRV_CH0_RECOVER_SRAM_IRQ: + /* get ERM enable SRAM single bit recover channel status */ + return (bool)ErmReg_GetSrSbc0(obj->reg); + case ERMDRV_CH0_NONRECOVER_SRAM_IRQ: + /* get ERM enable SRAM multi bits non-recover channel status */ + return (bool)ErmReg_GetSrNce0(obj->reg); + case ERMDRV_CH1_RECOVER_FTFC_IRQ: + /* get ERM enable FTFC single bit recover channel status */ + return (bool)ErmReg_GetSrSbc1(obj->reg); + case ERMDRV_CH1_NONRECOVER_FTFC_IRQ: + /* get ERM enable FTFC multi bits non-recover channel status */ + return (bool)ErmReg_GetSrNce1(obj->reg); + default: + return ERMDRV_CH_TOTAL_NUM; + } +} + +void ErmDrv_ClrChnErrInfoStatus(ErmDrvType *obj, ErmDrv_ChnNumType chnNum) +{ + switch(chnNum) + { + case ERMDRV_CH0_RECOVER_SRAM_IRQ: + /* clear ERM enable SRAM single bit recover channel */ + ErmReg_SetSrSbc0(obj->reg, 0x01); + break; + case ERMDRV_CH0_NONRECOVER_SRAM_IRQ: + /* clear ERM enable SRAM multi bits non-recover channel */ + ErmReg_SetSrNce0(obj->reg, 0x01); + break; + case ERMDRV_CH1_RECOVER_FTFC_IRQ: + /* clear ERM enable FTFC single bit recover channel */ + ErmReg_SetSrSbc1(obj->reg, 0x01); + break; + case ERMDRV_CH1_NONRECOVER_FTFC_IRQ: + /* clear ERM enable FTFC multi bits non-recover channel */ + ErmReg_SetSrNce1(obj->reg, 0x01); + break; + default: + break; + } +} + +void ErmDrv_GetChnNumCfg(ErmDrvType *obj, ErmDrv_ChnNumInfoType *chnNumInfo, ErmDrv_CtrlChnNumType ctrlChnNum) +{ + if(ctrlChnNum == ERMDRV_CH0) + { + /* Get channel 0 error address */ + chnNumInfo->errAddr = ErmReg_GetCh0St0Adr0(obj->reg); + /* Get channel 0 error position */ + chnNumInfo->errPos = ErmReg_GetCh0St1Syn0(obj->reg); + /* Get channel 0 error total num */ + chnNumInfo->errRecoverNum = ErmReg_GetCh0St2CorrCnt0(obj->reg); + } + else if(ctrlChnNum == ERMDRV_CH1) + { + /* Get channel 0 error address */ + chnNumInfo->errAddr = ErmReg_GetCh1St0Adr1(obj->reg); + /* Get channel 0 error position */ + chnNumInfo->errPos = ErmReg_GetCh1St1Syn1(obj->reg); + /* Get channel 0 error total num */ + chnNumInfo->errRecoverNum = ErmReg_GetCh1St2CorrCnt1(obj->reg); + } + else + { + return; + } +} + +void ErmDrv_ClrChnNumCfg(ErmDrvType *obj, ErmDrv_CtrlChnNumType ctrlChnNum) +{ + if(ctrlChnNum == ERMDRV_CH0) + { + /* Clear channel 0 error total num */ + ErmReg_SetCh0St2CorrCnt0(obj->reg, ERMDRV_RECOVER_ERRNUM_CLR); + } + else if(ctrlChnNum == ERMDRV_CH1) + { + /* Clear channel 1 error total num */ + ErmReg_SetCh1St2CorrCnt1(obj->reg); + } + else + { + return; + } +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/erm/erm_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/erm/erm_drv.h new file mode 100644 index 0000000..c94db87 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/erm/erm_drv.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _ERM_DRV_H_ +#define _ERM_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of ERM + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup erm_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* ERM error clear */ +#define ERMDRV_RECOVER_ERRNUM_CLR (0) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Definition ERM channel number + */ +typedef enum +{ + ERMDRV_CH0_RECOVER_SRAM_IRQ = 0U, /*!< ERM channel0 SRAM single recover Irq enable */ + ERMDRV_CH0_NONRECOVER_SRAM_IRQ = 1U, /*!< ERM channel0 SRAM single non-recover Irq enable */ + ERMDRV_CH1_RECOVER_FTFC_IRQ = 2U, /*!< ERM channel1 FTFC single recover Irq enable */ + ERMDRV_CH1_NONRECOVER_FTFC_IRQ = 3U, /*!< ERM channel1 FTFC single non-recover Irq enabl */ + ERMDRV_CH_TOTAL_NUM = 4U /*!< ERM channel total num */ +} ErmDrv_ChnNumType; + +/*! \brief Definition ERM channel number + */ +typedef enum +{ + ERMDRV_CH0 = 0U, /*!< ERM channel0 SRAM */ + ERMDRV_CH1 = 1U, /*!< ERM channel1 FTFC */ + ERMDRV_CH_CTRL_TOTAL_NUM = 2U /*!< ERM channel total num */ +} ErmDrv_CtrlChnNumType; + +/* Forward declaration of related register */ +struct _ErmRegType_; + +/*! \brief The definition of ERM driver class + */ +typedef struct _ErmDrvType_ +{ + struct _ErmRegType_ *reg; /*!< pointer to ERM register */ +} ErmDrvType; + +/*! \brief ERM channel status config + */ +typedef struct _ErmDrv_ChnNumInfoType_ +{ + uint32_t errAddr; /*!< error report address */ + uint32_t errPos; /*!< error report position */ + uint32_t errRecoverNum; /*!< error report recover */ +} ErmDrv_ChnNumInfoType; + +/*! \brief channel status and channel num error info + */ +typedef struct _ErmDrv_ChnErrConfigType_ +{ + bool chnEvent[ERMDRV_CH_TOTAL_NUM]; /*!< channel correction event status get */ + bool chnIrq[ERMDRV_CH_TOTAL_NUM]; /*!< channel interrupt notification set */ + ErmDrv_ChnNumInfoType chnStatus[ERMDRV_CH_CTRL_TOTAL_NUM]; /*!< channel status info */ +} ErmDrv_ChnErrConfigType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the ERM driver module + * + * This function initializes ERM driver by setting the register + * instances to it. + * + * \param[in] obj : pointer to ERM driver instance + * \param[in] ermReg : pointer to ERM register instance + */ +extern void ErmDrv_Init(ErmDrvType *obj, struct _ErmRegType_ *ermReg); + +/*! \brief Get ERM Default Config Parameter + * + * This function initializes ERM config parameter + * + * \param[in] userConfig : pointer to get ERM default config parameter + */ +extern void ErmDrv_GetDefaultConfig(ErmDrv_ChnErrConfigType *userConfig); + +/*! \brief Set ERM Channel Error Irq Enable + * + * This function set channel error interrupt enable + * + * \param[in] obj : pointer to ERM driver instance + * \param[in] chnNum : select config channel + * \param[in] enable : + * - true : enable select channel + * - false : disable select channel + */ +extern void ErmDrv_SetChnErrIrqEnable(ErmDrvType *obj, ErmDrv_ChnNumType chnNum, bool enable); + +/*! \brief Get ERM Channel Error Irq Enable + * + * This function get channel error interrupt enable + * + * \param[in] obj : pointer to ERM driver instance + * \param[in] chnNum : select config channel + * + * \return The result of configuring channel + * - true : enable select channel + * - false : disable select channel + */ +extern bool ErmDrv_GetChnErrIrqEnable(ErmDrvType *obj, ErmDrv_ChnNumType chnNum); + +/*! \brief Get ERM Channel Error Status + * + * This function get channel error status + * + * \param[in] obj : pointer to ERM driver instance + * \param[in] chnNum : select config channel + * + * \return The result of configuring channel + * - true : select channel error happened + * - false : select channel none error + */ +extern bool ErmDrv_GetChnErrInfoStatus(ErmDrvType *obj, ErmDrv_ChnNumType chnNum); + +/*! \brief Clear ERM Channel Error Status + * + * This function clear channel error status + * + * \param[in] obj : pointer to ERM driver instance + * \param[in] chnNum : clear select config channel + * + * \return none + */ +extern void ErmDrv_ClrChnErrInfoStatus(ErmDrvType *obj, ErmDrv_ChnNumType chnNum); + +/*! \brief Get ERM Channel Config Parameter + * + * This function get channel error config parameter + * + * \param[in] obj : pointer to ERM driver instance + * \param[in] chnNumInfo : pointer to current channel config info + * \param[in] chnNum : select config channel + */ +extern void ErmDrv_GetChnNumCfg(ErmDrvType *obj, ErmDrv_ChnNumInfoType *chnNumInfo, ErmDrv_CtrlChnNumType ctrlChnNum); + +/*! \brief Clear ERM Channel Config Parameter + * + * This function clear channel error config parameter + * + * \param[in] obj : pointer to ERM driver instance + * \param[in] chnNumInfo : pointer to current channel config info + * \param[in] chnNum : select config channel + */ +extern void ErmDrv_ClrChnNumCfg(ErmDrvType *obj, ErmDrv_CtrlChnNumType ctrlChnNum); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _ERM_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/fhu/fhu_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/fhu/fhu_drv.c new file mode 100644 index 0000000..cbbd4f2 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/fhu/fhu_drv.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "fhu_drv.h" +#include "fhu_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void FhuDrv_Init(FhuDrvType *obj, struct _FhuRegType_ *fhuReg) +{ + obj->reg = fhuReg; +} + +void FhuDrv_GetDefaultConfig(FhuDrv_ConfigType *cfg) +{ + cfg->chnEn = 0; + cfg->irqEn = 0; + cfg->rstEn = 0; + cfg->nmiEn = 0; +} + +bool FhuDrv_GetUserLockSts(FhuDrvType *obj) +{ + return (bool)FhuReg_GetUserLock(obj->reg); +} + +void FhuDrv_Config(FhuDrvType *obj, const FhuDrv_ConfigType *cfg) +{ + FhuReg_SetUserKey(obj->reg, FHUDRV_USER_KEY_UNLOCK); + + FhuReg_SetChCtl(obj->reg, cfg->chnEn); + FhuReg_SetIntCtl(obj->reg, cfg->irqEn); + FhuReg_SetRstCtl(obj->reg, cfg->rstEn); + FhuReg_SetNmiCtl(obj->reg, cfg->nmiEn); + + FhuReg_SetUserKey(obj->reg, ~FHUDRV_USER_KEY_UNLOCK); +} + +uint16_t FhuDrv_GetChnSts(FhuDrvType *obj) +{ + return FhuReg_GetChnRcd(obj->reg); +} + +void FhuDrv_ClearChnSts(FhuDrvType *obj, uint16_t clrValue) +{ + FhuReg_SetUserKey(obj->reg, FHUDRV_USER_KEY_UNLOCK); + FhuReg_SetChnRcd(obj->reg, clrValue); +} + +uint8_t FhuDrv_AnalogRealTimeChnSts(FhuDrvType *obj) +{ + return FhuReg_GetAdRcd(obj->reg); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/fhu/fhu_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/fhu/fhu_drv.h new file mode 100644 index 0000000..daa8d02 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/fhu/fhu_drv.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FHU_DRV_H_ +#define _FHU_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of FHU + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup fhu_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +#define FHUDRV_USER_KEY_UNLOCK (0x97D356BA) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +typedef enum +{ + FHUDRV_CHNID_AD_LVD = 0x0U, /*!< fault channel low voltage detection */ + FHUDRV_CHNID_AD_LVW = 0x1U, /*!< fault channel low voltage warning */ + FHUDRV_CHNID_AD_FLDO_RDY = 0x2U, /*!< fault channel Flash LDO ready */ + FHUDRV_CHNID_AD_FLDO_LVD = 0x3U, /*!< fault channel Flash LDO Low voltage */ + FHUDRV_CHNID_AD_OTP = 0x4U, /*!< fault channel Flash LDO over tempreture */ + FHUDRV_CHNID_SRAM_SEC = 0x5U, /*!< fault channel sram single bit error */ + FHUDRV_CHNID_SRAM_DED = 0x6U, /*!< fault channel sram multi bits error */ + FHUDRV_CHNID_FLS_SEC = 0x7U, /*!< fault channel falsh single bit error */ + FHUDRV_CHNID_FLS_DED = 0x8U, /*!< fault channel falsh multi bits error */ + FHUDRV_CHNID_NUM = 0x9U +}FhuDrv_ChnIdType; + +typedef struct _FhuDrv_ConfigType_ +{ + uint16_t chnEn; /*!< fault channel enable config */ + uint16_t irqEn; /*!< fault channel interrupt config */ + uint16_t rstEn; /*!< fault channel reset config */ + uint16_t nmiEn; /*!< fault channel NMI config */ +}FhuDrv_ConfigType; + +/* Forward declaration of related register */ +struct _FhuRegType_; + +/*! \brief The definition of FHU driver class + */ +typedef struct _FhuDrvType_ +{ + struct _FhuRegType_ *reg; /*!< pointer to FHU register */ +} FhuDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the FHU driver module + * + * This function initializes FHU driver by setting the register + * instances to it. + * + * \param[in] obj : pointer to FHU driver instance + * \param[in] fhuReg : pointer to FHU register instance + */ +extern void FhuDrv_Init(FhuDrvType *obj, struct _FhuRegType_ *fhuReg); + +/*! \brief Get FHU Module default config + * + * This function Get FHU default config from registers. + * + * \param[in] *cfg : pointer to get FHU register default value + */ +extern void FhuDrv_GetDefaultConfig(FhuDrv_ConfigType *cfg); + +/*! \brief Get FHU user lock status + * + * This function get FHU user lock status + * + * \param[in] obj : pointer to FHU driver instance + */ +extern bool FhuDrv_GetUserLockSts(FhuDrvType *obj); + +/*! \brief Set FHU initial config + * + * This function FHU initial user config + * + * \param[in] obj : pointer to FHU driver instance + * \param[in] *cfg : pointer to set FHU register default value + */ +extern void FhuDrv_Config(FhuDrvType *obj, const FhuDrv_ConfigType *cfg); + +/*! \brief Get FHU channel status + * + * This function Get FHU channel status + * + * \param[in] obj : pointer to FHU driver instance + */ +extern uint16_t FhuDrv_GetChnSts(FhuDrvType *obj); + +/*! \brief clear FHU channel error status + * + * This function clear FHU channel error in status + * + * \param[in] obj : pointer to FHU driver instance + * \param[in] clrValue : corresponding bit set 1 to clear + * corresponding bit set 0 to reserve + */ +extern void FhuDrv_ClearChnSts(FhuDrvType *obj, uint16_t clrValue); + +/*! \brief get FHU analog channel error status + * + * This function get FHU analog channel error in status + * for real time. + * + * \param[in] obj : pointer to FHU driver instance + */ +extern uint8_t FhuDrv_AnalogRealTimeChnSts(FhuDrvType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _FHU_DRV_H_ */ + diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/flash/flash_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/flash/flash_drv.c new file mode 100644 index 0000000..0caf47a --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/flash/flash_drv.c @@ -0,0 +1,924 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#include "scg0_reg.h" +#include "ftfc_reg.h" +#include "flash_drv.h" +#include "../../CVM011x_features.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +static void FlashDrv_ClearCommandState(FlashDrvType *obj); +static FlashDrv_Status FlashDrv_CommandSequence(FlashDrvType *obj); +static void FlashDrv_EeeUpdateSequence(FlashDrvType *obj); + +/******************************************************************************* + * Code + ******************************************************************************/ + +void FlashDrv_Init(FlashDrvType *obj, struct _FtfcRegType_ *reg, struct _Scg0RegType_ *scg0Reg) +{ + obj->reg = reg; + obj->scg0Reg = scg0Reg; + obj->pflashbase = 0x0; + obj->pflashsize = FEATURE_PFLASH_SIZE; + obj->dflashbase = 0x10000000; + obj->dflashsize = FEATURE_DFLASH_SIZE; + obj->eeevld = FlashDrv_GetEeeEn(obj); + obj->callback = NULL; + if(obj->eeevld) + { + obj->dflashsize = 0x0; + } + + FlashDrv_ClearCommandState(obj); +} + +void FlashDrv_GetDefaultConfig(FlashDrv_ConfigType *userconfig) +{ + userconfig->pflashbase = 0x0; + userconfig->pflashsize = FEATURE_PFLASH_SIZE; + userconfig->dflashbase = 0x10000000; + userconfig->dflashsize = FEATURE_DFLASH_SIZE; + userconfig->eeevld = false; + userconfig->callback = NULL; +} + +void FlashDrv_Configure(FlashDrvType *obj, + const FlashDrv_ConfigType *userconfig) +{ + obj->pflashbase = 0x0; + obj->pflashsize = FEATURE_PFLASH_SIZE; + obj->dflashbase = 0x10000000; + obj->dflashsize = FEATURE_DFLASH_SIZE; + /* DFlash size only has one fixed configuration */ + obj->eeevld = FlashDrv_GetEeeEn(obj); + obj->callback = userconfig->callback; + if(obj->eeevld) + { + obj->dflashsize = 0x0; + } + + FlashDrv_ClearCommandState(obj); +} + +void FlashDrv_GetConfig(const FlashDrvType *obj, + FlashDrv_ConfigType *userconfig) +{ + userconfig->pflashbase = obj->pflashbase; + userconfig->pflashsize = obj->pflashsize; + userconfig->dflashbase = obj->dflashbase; + userconfig->dflashsize = obj->dflashsize; + userconfig->eeevld = obj->eeevld; + userconfig->callback = obj->callback; +} + +static void FlashDrv_ClearCommandState(FlashDrvType *obj) +{ + FtfcReg_SetFstatRspErrF(obj->reg, 1); + FtfcReg_SetFstatProtViolF(obj->reg, 1); + FtfcReg_SetFstatAccErrF(obj->reg, 1); + FtfcReg_SetFstatRdColF(obj->reg, 1); + FtfcReg_SetFstatSecF(obj->reg, 1); + FtfcReg_SetFstatDedF(obj->reg, 1); +} + +static FlashDrv_Status FlashDrv_CommandSequence(FlashDrvType *obj) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + + FtfcReg_SetFstatCcif(obj->reg, 1); + + while(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + } + + if(FtfcReg_GetFstatAccErrF(obj->reg) || FtfcReg_GetFstatProtViolF(obj->reg) || FtfcReg_GetFstatMgStat(obj->reg)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + return ret; +} + +static void FlashDrv_EeeUpdateSequence(FlashDrvType *obj) +{ + while(0 == FtfcReg_GetFstatEeeRamRdy(obj->reg)) + { + } + if(FtfcReg_GetFstatEeeTlov(obj->reg) == 1) + { + FlashDrv_SetFlexRam(obj, false); + FlashDrv_SetEeeAutoGcEn(obj, true); + FlashDrv_SetFlexRam(obj, true); + FlashDrv_SetEeeAutoGcEn(obj, false); + } +} + +FlashDrv_Status FlashDrv_Read1sBlock(FlashDrvType *obj, uint32_t *destaddr) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t dest = (uint32_t)destaddr; + + dest = ALIGNED(dest, 8); + + if((dest >= (obj->pflashbase + obj->pflashsize) && dest < obj->dflashbase) || (obj->dflashsize > 0 && dest >= (obj->dflashbase + obj->dflashsize)) || (dest >= obj->dflashbase && obj->eeevld)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_BLKRD1S); + FtfcReg_SetFccob(obj->reg, 1, FCCOBADDRLOW(dest)); + FtfcReg_SetFccob(obj->reg, 2, FCCOBADDRMDLOW(dest)); + FtfcReg_SetFccob(obj->reg, 3, FCCOBADDRMDHIG(dest)); + FtfcReg_SetFccob(obj->reg, 4, FCCOBADDRHIG(dest)); + + ret = FlashDrv_CommandSequence(obj); + } + } + + return ret; +} + +FlashDrv_Status FlashDrv_Read1sSection(FlashDrvType *obj, uint32_t *destaddr, uint32_t rdsize) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t dest = (uint32_t)destaddr; + + if(!IS_ALIGNED(dest, 8) || !IS_ALIGNED(rdsize, 8)) + { + ret = FLASHDRV_STATUS_ERROR; + } + if(ALIGNED(dest + rdsize - 1, FLASHDRV_SECTOR_SIZE) > ALIGNED(dest, FLASHDRV_SECTOR_SIZE)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if((dest >= (obj->pflashbase + obj->pflashsize) && dest < obj->dflashbase) || (obj->dflashsize > 0 && dest >= (obj->dflashbase + obj->dflashsize)) || (dest >= obj->dflashbase && obj->eeevld)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_SCTRD1S); + FtfcReg_SetFccob(obj->reg, 1, FCCOBADDRLOW(dest)); + FtfcReg_SetFccob(obj->reg, 2, FCCOBADDRMDLOW(dest)); + FtfcReg_SetFccob(obj->reg, 3, FCCOBADDRMDHIG(dest)); + FtfcReg_SetFccob(obj->reg, 4, FCCOBADDRHIG(dest)); + FtfcReg_SetFccob(obj->reg, 5, (rdsize / FLASHDRV_PHRASE_SIZE) - 1); + + ret = FlashDrv_CommandSequence(obj); + } + } + + return ret; +} + +FlashDrv_Status FlashDrv_CheckPhrase(FlashDrvType *obj, uint32_t *destaddr, uint8_t *expdata) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t dest = (uint32_t)destaddr; + uint32_t i = 0; + + if(!IS_ALIGNED(dest, 8)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if((dest >= (obj->pflashbase + obj->pflashsize) && dest < obj->dflashbase) || (obj->dflashsize > 0 && dest >= (obj->dflashbase + obj->dflashsize)) || (dest >= obj->dflashbase && obj->eeevld)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(expdata == NULL) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_PRSCHK); + FtfcReg_SetFccob(obj->reg, 1, FCCOBADDRLOW(dest)); + FtfcReg_SetFccob(obj->reg, 2, FCCOBADDRMDLOW(dest)); + FtfcReg_SetFccob(obj->reg, 3, FCCOBADDRMDHIG(dest)); + FtfcReg_SetFccob(obj->reg, 4, FCCOBADDRHIG(dest)); + + for(i = 0; i < FLASHDRV_PHRASE_SIZE; i++) + { + FtfcReg_SetFccob(obj->reg, 5 + i, expdata[i]); + } + ret = FlashDrv_CommandSequence(obj); + } + } + return ret; +} + +FlashDrv_Status FlashDrv_CheckEccState(FlashDrvType *obj, uint32_t *destaddr) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t dest = (uint32_t)destaddr; + uint32_t i = 0; + + if(!IS_ALIGNED(dest, 8)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if((dest >= (obj->pflashbase + obj->pflashsize) && dest < obj->dflashbase) || (obj->dflashsize > 0 && dest >= (obj->dflashbase + obj->dflashsize)) || (dest >= obj->dflashbase && obj->eeevld)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_PRSCHK); + FtfcReg_SetFccob(obj->reg, 1, FCCOBADDRLOW(dest)); + FtfcReg_SetFccob(obj->reg, 2, FCCOBADDRMDLOW(dest)); + FtfcReg_SetFccob(obj->reg, 3, FCCOBADDRMDHIG(dest)); + FtfcReg_SetFccob(obj->reg, 4, FCCOBADDRHIG(dest)); + + for(i = 0; i < FLASHDRV_PHRASE_SIZE; i++) + { + FtfcReg_SetFccob(obj->reg, 5 + i, 0xFF); + } + FlashDrv_CommandSequence(obj); + ret = ((FtfcReg_GetFstatSecF(obj->reg) | FtfcReg_GetFstatDedF(obj->reg)) == 1) ? FLASHDRV_STATUS_ERROR : FLASHDRV_STATUS_SUCCESS; + } + } + return ret; +} + +FlashDrv_Status FlashDrv_ProgramPhrase(FlashDrvType *obj, uint32_t *destaddr, uint8_t *expdata, bool hweccen) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t dest = (uint32_t)destaddr; + uint32_t i = 0; + + if(!IS_ALIGNED(dest, 8)) + { + ret = FLASHDRV_STATUS_ERROR; + } + if((dest >= (obj->pflashbase + obj->pflashsize) && dest < obj->dflashbase) || (obj->dflashsize > 0 && dest >= (obj->dflashbase + obj->dflashsize)) || (dest >= obj->dflashbase && obj->eeevld)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(expdata == NULL) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_PRSPGM); + FtfcReg_SetFccob(obj->reg, 1, FCCOBADDRLOW(dest)); + FtfcReg_SetFccob(obj->reg, 2, FCCOBADDRMDLOW(dest)); + FtfcReg_SetFccob(obj->reg, 3, FCCOBADDRMDHIG(dest)); + FtfcReg_SetFccob(obj->reg, 4, FCCOBADDRHIG(dest)); + FtfcReg_SetFccob(obj->reg, 5, (hweccen ? 1 : 0)); + for(i = 0; i < FLASHDRV_PHRASE_SIZE; i++) + { + FtfcReg_SetFccob(obj->reg, 6 + i, expdata[i]); + } + if(!hweccen) + { + FtfcReg_SetFccob(obj->reg, 14, expdata[8]); + } + + ret = FlashDrv_CommandSequence(obj); + } + } + return ret; +} + +FlashDrv_Status FlashDrv_EraseBlock(FlashDrvType *obj, uint32_t *destaddr, FlashDrv_SectorErase_t erasetype) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t dest = (uint32_t)destaddr; + + dest = ALIGNED(dest, 8); + + if((dest >= (obj->pflashbase + obj->pflashsize) && dest < obj->dflashbase) || (obj->dflashsize > 0 && dest >= (obj->dflashbase + obj->dflashsize)) || (dest >= obj->dflashbase && obj->eeevld)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_BLKERS); + FtfcReg_SetFccob(obj->reg, 1, FCCOBADDRLOW(dest)); + FtfcReg_SetFccob(obj->reg, 2, FCCOBADDRMDLOW(dest)); + FtfcReg_SetFccob(obj->reg, 3, FCCOBADDRMDHIG(dest)); + FtfcReg_SetFccob(obj->reg, 4, FCCOBADDRHIG(dest)); + FtfcReg_SetFccob(obj->reg, 5, erasetype); + + ret = FlashDrv_CommandSequence(obj); + } + } + + return ret; +} + +FlashDrv_Status FlashDrv_EraseSector(FlashDrvType *obj, uint32_t *destaddr, FlashDrv_SectorErase_t erasetype) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t dest = (uint32_t)destaddr; + + dest = ALIGNED(dest, 8); + + if((dest >= (obj->pflashbase + obj->pflashsize) && dest < obj->dflashbase) || (obj->dflashsize > 0 && dest >= (obj->dflashbase + obj->dflashsize)) || (dest >= obj->dflashbase && obj->eeevld)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_SCTERS); + FtfcReg_SetFccob(obj->reg, 1, FCCOBADDRLOW(dest)); + FtfcReg_SetFccob(obj->reg, 2, FCCOBADDRMDLOW(dest)); + FtfcReg_SetFccob(obj->reg, 3, FCCOBADDRMDHIG(dest)); + FtfcReg_SetFccob(obj->reg, 4, FCCOBADDRHIG(dest)); + FtfcReg_SetFccob(obj->reg, 5, erasetype); + ret = FlashDrv_CommandSequence(obj); + } + } + + return ret; +} + +FlashDrv_Status FlashDrv_ProgramSection(FlashDrvType *obj, uint32_t *destaddr, uint32_t len, uint8_t *databuf) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t dest = (uint32_t)destaddr; + uint32_t i = 0, offset = 0; + bool eeeramrdy = false; + uint8_t *pfastram, *pdata; + + if(!IS_ALIGNED(dest, 256) || !IS_ALIGNED(len, 256)) + { + ret = FLASHDRV_STATUS_ERROR; + } + if(ALIGNED(dest + len - 1, FLASHDRV_SECTOR_SIZE) > ALIGNED(dest, FLASHDRV_SECTOR_SIZE)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if((dest >= (obj->pflashbase + obj->pflashsize) && dest < obj->dflashbase) || (obj->dflashsize > 0 && dest >= (obj->dflashbase + obj->dflashsize)) || (dest >= obj->dflashbase && obj->eeevld)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + eeeramrdy = (FtfcReg_GetFstatEeeRamRdy(obj->reg) == 1); + + if(eeeramrdy) + { + FlashDrv_SetFlexRam(obj, false); + } + + offset = dest & (FLASHDRV_SECTOR_SIZE - 1); + pfastram = (uint8_t *)(FLASHDRV_FLEXRAM_ADDR + offset); + pdata = databuf; + for(i = 0; i < len; i++) + { + *pfastram = *pdata; + pfastram++; + pdata++; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_SCTPGM); + FtfcReg_SetFccob(obj->reg, 1, FCCOBADDRLOW(dest)); + FtfcReg_SetFccob(obj->reg, 2, FCCOBADDRMDLOW(dest)); + FtfcReg_SetFccob(obj->reg, 3, FCCOBADDRMDHIG(dest)); + FtfcReg_SetFccob(obj->reg, 4, FCCOBADDRHIG(dest)); + FtfcReg_SetFccob(obj->reg, 5, (len / FLASHDRV_PHRASE_SIZE) - 1); + ret = FlashDrv_CommandSequence(obj); + } + } + + if(eeeramrdy) + { + FlashDrv_SetFlexRam(obj, true); + } + return ret; +} + +FlashDrv_Status FlashDrv_ProgramSectionFast(FlashDrvType *obj, uint32_t *destaddr, uint32_t len) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t dest = (uint32_t)destaddr; + + if(!IS_ALIGNED(dest, 256) || !IS_ALIGNED(len, 256)) + { + ret = FLASHDRV_STATUS_ERROR; + } + if(ALIGNED(dest + len - 1, FLASHDRV_SECTOR_SIZE) > ALIGNED(dest, FLASHDRV_SECTOR_SIZE)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if((dest >= (obj->pflashbase + obj->pflashsize) && dest < obj->dflashbase) || (obj->dflashsize > 0 && dest >= (obj->dflashbase + obj->dflashsize)) || (dest >= obj->dflashbase && obj->eeevld)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_SCTPGM); + FtfcReg_SetFccob(obj->reg, 1, FCCOBADDRLOW(dest)); + FtfcReg_SetFccob(obj->reg, 2, FCCOBADDRMDLOW(dest)); + FtfcReg_SetFccob(obj->reg, 3, FCCOBADDRMDHIG(dest)); + FtfcReg_SetFccob(obj->reg, 4, FCCOBADDRHIG(dest)); + FtfcReg_SetFccob(obj->reg, 5, (len / FLASHDRV_PHRASE_SIZE) - 1); + ret = FlashDrv_CommandSequence(obj); + } + } + + return ret; +} + +FlashDrv_Status FlashDrv_Read1sAllBlock(FlashDrvType *obj) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_ALBLKRD1S); + ret = FlashDrv_CommandSequence(obj); + } + return ret; +} + +FlashDrv_Status FlashDrv_ReadInfoRegion(FlashDrvType *obj, + FlashDrv_InfoRegion_t regionid, + uint8_t phraseid, + uint8_t *databuf) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t i = 0; + + if(phraseid >= 64) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(databuf == NULL) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_RDINFORG); + FtfcReg_SetFccob(obj->reg, 1, phraseid); + + ret = FlashDrv_CommandSequence(obj); + } + } + if(ret == FLASHDRV_STATUS_SUCCESS) + { + for(i = 0; i < FLASHDRV_PHRASE_SIZE; i++) + { + databuf[i] = FtfcReg_GetFccob(obj->reg, 7 + i); + } + } + return ret; +} + +FlashDrv_Status FlashDrv_ProgramInfoRegion(FlashDrvType *obj, + FlashDrv_InfoRegion_t regionid, + uint32_t phraseid, + uint8_t *databuf) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t i = 0; + + if(phraseid >= 64) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(databuf == NULL) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_PGMINFORG); + FtfcReg_SetFccob(obj->reg, 1, (uint8_t)phraseid); + + for(i = 0; i < FLASHDRV_PHRASE_SIZE; i++) + { + FtfcReg_SetFccob(obj->reg, (uint8_t)(2 + i), databuf[i]); + } + + ret = FlashDrv_CommandSequence(obj); + } + } + + return ret; +} + +FlashDrv_Status FlashDrv_EraseAllBlock(FlashDrvType *obj) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_ALBLKERS); + ret = FlashDrv_CommandSequence(obj); + } + return ret; +} + +FlashDrv_Status FlashDrv_EraseAllBlockUnsecure(FlashDrvType *obj) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, (uint8_t)FLASHDRV_OPCMD_ALBLKUERS); + ret = FlashDrv_CommandSequence(obj); + } + return ret; +} + +FlashDrv_Status FlashDrv_VerifyUserKey(FlashDrvType *obj, uint8_t *expdata) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t i = 0; + + if(expdata == NULL) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_VRFYKEY); + + for(i = 0; i < FLASHDRV_PHRASE_SIZE; i++) + { + FtfcReg_SetFccob(obj->reg, 1 + i, expdata[i]); + } + ret = FlashDrv_CommandSequence(obj); + } + } + return ret; +} + +void FlashDrv_IrqHandler(FlashDrvType *obj) +{ + FtfcReg_SetFstatCcifClr(obj->reg, 1); + if(obj->callback != NULL) + { + obj->callback(); + } +} + +void FlashDrv_SetCmdDoneIrqEn(FlashDrvType *obj, bool en) +{ + FtfcReg_SetFcnfgCcifIE(obj->reg, en ? 1 : 0); +} + +FlashDrv_Status FlashDrv_SetFlexRam(FlashDrvType *obj, bool eeeramen) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + bool gctrg = false; + + if(FtfcReg_GetFstatEeeRamRdy(obj->reg) == 0 && eeeramen == true && Scg0Reg_GetTrimAutoGcEn(obj->scg0Reg) == 1) + { + gctrg = true; + } + + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_SETFRAM); + FtfcReg_SetFccob(obj->reg, 1, eeeramen ? 1 : 0); + ret = FlashDrv_CommandSequence(obj); + + if(eeeramen && !FtfcReg_GetFstatEeeRamRdy(obj->reg)) + { + ret |= FLASHDRV_STATUS_ERROR; + } + + if(!eeeramen && !FtfcReg_GetFstatRamRdy(obj->reg)) + { + ret |= FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS && gctrg == true) + { + FtfcReg_SetFstatEeeTlov(obj->reg, 1); + } + } + + return ret; +} + +FlashDrv_Status FlashDrv_UpdateEeeRam(FlashDrvType *obj, uint32_t offset, uint8_t *srcdata, uint32_t sz) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + + uint8_t *pdsteram8 = 0; + uint16_t *pdsteram16 = 0; + uint32_t *pdsteram32 = 0; + uint8_t *psrc8 = 0; + uint16_t *psrc16 = 0; + uint32_t *psrc32 = 0; + uint32_t i = 0, cnt = 0; + + if(!(obj->eeevld) || FtfcReg_GetFstatRamRdy(obj->reg) == 1 || FtfcReg_GetEfProtecion(obj->reg) != 0x0) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(offset + sz > FLASHDRV_FLEXRAM_SIZE) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret != FLASHDRV_STATUS_SUCCESS) + { + return ret; + } + + if(FlashDrv_GetEeeAutoGcEn(obj)) + { + FlashDrv_SetEeeAutoGcEn(obj, false); + } + + while(0 == FtfcReg_GetFstatEeeRamRdy(obj->reg)) + { + } + + pdsteram8 = (uint8_t *)(FLASHDRV_FLEXRAM_ADDR + offset); + if(IS_ALIGNED(offset, (uint32_t)4) && IS_ALIGNED(sz, (uint32_t)4)) + { + pdsteram32 = (uint32_t *)pdsteram8; + psrc32 = (uint32_t *)srcdata; + cnt = sz / 4; + for(i = 0; i < cnt; i++) + { + pdsteram32[i] = psrc32[i]; + FlashDrv_EeeUpdateSequence(obj); + } + } + else if(IS_ALIGNED(offset, (uint32_t)2) && IS_ALIGNED(sz, (uint32_t)2)) + { + pdsteram16 = (uint16_t *)pdsteram8; + psrc16 = (uint16_t *)srcdata; + cnt = sz / 2; + for(i = 0; i < cnt; i++) + { + pdsteram16[i] = psrc16[i]; + FlashDrv_EeeUpdateSequence(obj); + } + } + else + { + psrc8 = (uint8_t *)srcdata; + cnt = sz; + for(i = 0; i < cnt; i++) + { + pdsteram8[i] = psrc8[i]; + FlashDrv_EeeUpdateSequence(obj); + } + } + + if(FtfcReg_GetFstatEeeFlov(obj->reg) == 1) + { + ret = FLASHDRV_STATUS_ERROR; + } + + return ret; +} + +bool FlashDrv_GetEeeAutoGcEn(FlashDrvType *obj) +{ + bool eeegcen = false; + + eeegcen = (Scg0Reg_GetTrimAutoGcEn(obj->scg0Reg) == 1); + + return eeegcen; +} + +void FlashDrv_SetEeeAutoGcEn(FlashDrvType *obj, bool eeegcen) +{ + Scg0Reg_SetKey(obj->scg0Reg, 0x19962020); + Scg0Reg_SetTrimAutoGcEn(obj->scg0Reg, eeegcen ? 1 : 0); + Scg0Reg_SetKey(obj->scg0Reg, 0); +} + +bool FlashDrv_GetEeeEn(FlashDrvType *obj) +{ + uint8_t data[8] = {0x0}; + bool eeeen = false; + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + + data[0] = 0xFF; + ret = FlashDrv_ReadInfoRegion(obj, FLASHDRV_INFORG0, 0, data); + + if(ret == FLASHDRV_STATUS_SUCCESS && (data[0] & 0x2) == 0x0) + { + eeeen = true; + } + return eeeen; +} + +bool FlashDrv_GetEeeRamRdy(FlashDrvType *obj) +{ + bool eeeramrdy = false; + + eeeramrdy = (FtfcReg_GetFstatEeeRamRdy(obj->reg) == 1); + + return eeeramrdy; +} + +FlashDrv_Status FlashDrv_GetEeeRamProtection(FlashDrvType *obj, uint8_t *protectstatus) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + + if(!(obj->eeevld)) + { + ret = FLASHDRV_STATUS_UNSUPPORTED; + } + else + { + *protectstatus = FtfcReg_GetEfProtecion(obj->reg); + } + + return ret; +} + +FlashDrv_Status FlashDrv_GetPFlashProtection(FlashDrvType *obj, uint32_t *protectstatus) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + + *protectstatus = FtfcReg_GetPfProtecion(obj->reg); + + return ret; +} + +FlashDrv_Status FlashDrv_GetDFlashProtection(FlashDrvType *obj, uint8_t *protectstatus) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + + if(obj->dflashsize == 0x0) + { + ret = FLASHDRV_STATUS_UNSUPPORTED; + } + else + { + *protectstatus = FtfcReg_GetDfProtecion(obj->reg); + } + + return ret; +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/flash/flash_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/flash/flash_drv.h new file mode 100644 index 0000000..5fadda8 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/flash/flash_drv.h @@ -0,0 +1,582 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FLASH_DRV_H_ +#define _FLASH_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of FLASH + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +/*! \brief Macro for high and low position separation of the memory address. + * + * The 32-bit address need to be sperated to 8-bit and then programmed to + * specific fccob registers. + */ +#define FCCOBADDRLOW(addr) ((uint8_t)(((uint32_t)(addr)) & 0xFFU)) +#define FCCOBADDRMDLOW(addr) ((uint8_t)((((uint32_t)(addr)) >> 8) & 0xFFU)) +#define FCCOBADDRMDHIG(addr) ((uint8_t)((((uint32_t)(addr)) >> 16) & 0xFFU)) +#define FCCOBADDRHIG(addr) ((uint8_t)(((uint32_t)(addr)) >> 24)) + +/*! \brief Macro for the alignment requirement. + * + * The address need to be aligned. + */ +#define ALIGNED(val, alncnt) (((uint32_t)val) & ~(alncnt - 1)) +#define IS_ALIGNED(val, alncnt) ((((uint32_t)val) & (alncnt - 1)) == 0x0 ? true : false) + +/*! \brief Macro for sector size + * + * Sector size is 1024. + */ +#define FLASHDRV_SECTOR_SIZE (1024U) + +/*! \brief Macro for the byte count of phrase-write and phrase-read + * + * phrase-write/phrase-read size + */ +#define FLASHDRV_PHRASE_SIZE (8U) + +/*! \brief Macro for the flexram address + * + * flexram address + */ +#define FLASHDRV_FLEXRAM_ADDR (0x14000000UL) + +/*! \brief Macro for the flexram size + * + * flexram size + */ +#define FLASHDRV_FLEXRAM_SIZE (2048U) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Status return codes. + * Common error codes will be a unified enumeration (C enum) that will contain + * all error codes (common and specific). There will be separate "error values + * spaces" (or slots), each of 256 positions, allocated per functionality. + */ +typedef enum +{ + /* Generic error codes */ + FLASHDRV_STATUS_SUCCESS = 0x000U, /*!< Generic operation success status */ + FLASHDRV_STATUS_ERROR = 0x001U, /*!< Generic operation failure status */ + FLASHDRV_STATUS_BUSY = 0x002U, /*!< Generic operation busy status */ + FLASHDRV_STATUS_TIMEOUT = 0x003U, /*!< Generic operation timeout status */ + FLASHDRV_STATUS_UNSUPPORTED = 0x004U, /*!< Generic operation unsupported status */ +} FlashDrv_Status; + +/*! \brief FLASH type of operation cmd + */ +typedef enum +{ + FLASHDRV_OPCMD_BLKRD1S = 0x00, /*!< Block Read 1s command*/ + FLASHDRV_OPCMD_SCTRD1S = 0x01, /*!< Section Read 1s command*/ + FLASHDRV_OPCMD_PRSCHK = 0x02, /*!< Phrase check command*/ + FLASHDRV_OPCMD_PRSPGM = 0x03, /*!< Phrase Program command*/ + FLASHDRV_OPCMD_BLKERS = 0x04, /*!< Block Erase command*/ + FLASHDRV_OPCMD_SCTERS = 0x05, /*!< Sector Erase command*/ + FLASHDRV_OPCMD_SCTPGM = 0x06, /*!< Program section command*/ + FLASHDRV_OPCMD_ALBLKRD1S = 0x07, /*!< Read 1s ALL Blocks command*/ + FLASHDRV_OPCMD_RDINFORG = 0x08, /*!< Read once command: for info region*/ + FLASHDRV_OPCMD_PGMINFORG = 0x09, /*!< Program once command: for info region*/ + FLASHDRV_OPCMD_ALBLKERS = 0x0A, /*!< Erase ALL blocks command*/ + FLASHDRV_OPCMD_VRFYKEY = 0x0B, /*!< Verify backdoor access key command*/ + FLASHDRV_OPCMD_ALBLKUERS = 0x0C, /*!< Erase All Blocks unsecure command*/ + FLASHDRV_OPCMD_SETFRAM = 0x0D, /*!< Set Flexram command*/ +} FlashDrv_Opcmd_t; + +/*! \brief FLASH info region type + */ +typedef enum +{ + FLASHDRV_INFORG0 = 0x00, /*!< info region,512bytes, phrase_index: 0~ 63, no erase cmd*/ +} FlashDrv_InfoRegion_t; + +/*! \brief FLASH sector erase type + */ +typedef enum +{ + FLASHDRV_SCTERS_ONEPULSE = 0x00, /*!< one-pulse erase */ + FLASHDRV_SCTERS_RETRY = 0x01, /*!< retry erase */ +} FlashDrv_SectorErase_t; + +/*! \brief Definition for the flash cmd done callback function. + * + * Prototype for the callback function registered in the flash driver. + */ +typedef void (*FlashDrv_CallBackType)(void); + +/*! \brief Definition of configuration of FLASH driver + */ +typedef struct _FlashDrv_ConfigType_ +{ + uint32_t pflashbase; /*!< The base address of P-Flash memory */ + uint32_t pflashsize; /*!< The size in byte of P-Flash memory */ + uint32_t dflashbase; /*!< The base address of D-Flash memory */ + uint32_t dflashsize; /*!< The size in byte of P-Flash memory */ + bool eeevld; /*!< emualted ee function valid flag*/ + FlashDrv_CallBackType callback; /*!< Call back function to service the time critical events. Any code reachable from this function + * must not be placed in a Flash block targeted for a program/erase operation */ +} FlashDrv_ConfigType; + +/* Forward declaration of flash ftfc register */ +struct _FtfcRegType_; +/* Forward declaration of Scg0 register */ +struct _Scg0RegType_; + +/*! \brief The definition of flash driver class + */ +typedef struct _FlashDrvType_ +{ + struct _FtfcRegType_ *reg; + struct _Scg0RegType_ *scg0Reg; + uint32_t pflashbase; /*!< The base address of P-Flash memory */ + uint32_t pflashsize; /*!< The size in byte of P-Flash memory */ + uint32_t dflashbase; /*!< The base address of D-Flash memory */ + uint32_t dflashsize; /*!< The size in byte of P-Flash memory */ + bool eeevld; /*!< emualted ee function valid flag*/ + FlashDrv_CallBackType callback; /*!< Call back function to service the time critical events. Any code reachable from this function + * must not be placed in a Flash block targeted for a program/erase operation */ +} FlashDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the Flash driver module + * + * This function initializes Flash driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] reg : pointer to Flash register instance + * \param[in] scg0Reg : pointer to SCG0 register instance + */ +extern void FlashDrv_Init(FlashDrvType *obj, struct _FtfcRegType_ *reg, struct _Scg0RegType_ *scg0Reg); + +/*! \brief Get configures of the Flash module currently + * + * This function gets configures of the Flash module currently + * + * \param[in] obj : pointer to Flash driver instance + * \param[out] userConfig : pointer to configuration structure + */ +extern void FlashDrv_GetConfig(const FlashDrvType *obj, + FlashDrv_ConfigType *userconfig); + +/*! \brief Get default configures the Flash module for configuration structure + * + * This function gets default configures the Flash module for user configuration + * structure + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void FlashDrv_GetDefaultConfig(FlashDrv_ConfigType *userconfig); + +/*! \brief Configures the Flash module from a user configuration structure + * + * This function configures the Flash module from a user configuration structure + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void FlashDrv_Configure(FlashDrvType *obj, + const FlashDrv_ConfigType *userconfig); + +/*! \brief Verify the Pflash or Dfalsh(keysector included) erased + * + * This function verify pflash or dflash is erased. + * + * NOTE:if targeted block is the eee backup region, + * the read1s seqeunce will be aborted + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] destaddr : pointer to a memory address in pflash/dflash + */ +extern FlashDrv_Status FlashDrv_Read1sBlock(FlashDrvType *obj, + uint32_t *destaddr); + +/*! \brief Verify a section erased + * + * This function verify a section erased. The section should located in a sector + * or should be a total sector. Both the start addr and the size of the section + * are supposed to be 8-aligned. + * + * NOTE:if targeted section is in the eee backup region, the + * erase sequence will be aborted. + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] destaddr : pointer to a memory address in pflash or dflash:8-aligned. + * \param[in] rdsize : length of read/verified memory in bytes:8-aligned. + */ +extern FlashDrv_Status FlashDrv_Read1sSection(FlashDrvType *obj, + uint32_t *destaddr, + uint32_t rdsize); + +/*! \brief Check a phrase programmed as expected value + * + * This function checked a phrase-data[8bytes] progrmmed as expected value. + * The phrase addr is supposed to be 8-aligned. + * + * NOTE:if targeted phrase is in the eee backup region, the + * checkphrase sequence will be aborted. + * + * \param[in] obj : pointer to Flash driver instance. + * \param[in] destaddr : pointer to a phrase address in pflash or dflash,8-aligned. + * \param[in] expdata : pointor to expected data, 8 bytes + */ +extern FlashDrv_Status FlashDrv_CheckPhrase(FlashDrvType *obj, + uint32_t *destaddr, + uint8_t *expdata); + +/*! \brief Check a phrase has ecc error + * + * This function checked a phrase-data[8bytes] has ecc error. + * + * + * \param[in] obj : pointer to Flash driver instance. + * \param[in] destaddr : pointer to a memory address in pflash or dflash, 8-aligned. + */ +extern FlashDrv_Status FlashDrv_CheckEccState(FlashDrvType *obj, + uint32_t *destaddr); + +/*! \brief Program a phrase as expected value + * + * This function checked a phrase-data[8bytes/9bytes] progrmmed as expected + * value. The phrase addr is supposed to be 8-aligned. + * + * NOTE: 1.make sure targeted phrase is erased and not proteted before + * programmed; 2.if the target section is in the eee backup region, + * the program sequence will be aborted. + * + * \param[in] obj : pointer to Flash driver instance. + * \param[in] destaddr : pointer to a memory address in pflash or dflash,8-aligned. + * \param[in] expdata : pointor to expected data, 8 bytes or 9 bytes + * \param[in] hweccen : true: first 8 bytes will be programmed,ecc byte programmed by hardware; + * false: 9 bytes(ecc byte included) will be programmed; + */ +extern FlashDrv_Status FlashDrv_ProgramPhrase(FlashDrvType *obj, + uint32_t *destaddr, + uint8_t *expdata, + bool hweccen); + +/*! \brief Erase Pflash or Dfalsh + * + * This function erase pflash or dflash. + * + * NOTE: + * 1.Any code reachable from this function must not be placed in a Flash + * block targeted for this erase operation. 2.Between the POR and Pflash-erased + * operations, remind to program pflash-cfg-feild[0x400~0x41f] to proper + * value.Otherwise, system will enter security state, swd cannot be connected. + * 3.if there is protection region in targeted block, the erase + * sequence will be aborted; 4.if targeted flash is the eee backup region, + * the erase sequence will be aborted. + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] destaddr : pointer to a address in pflash or dflash, 8-aligned + * \param[in] erasetype: erase type + */ +extern FlashDrv_Status FlashDrv_EraseBlock(FlashDrvType *obj, + uint32_t *destaddr, + FlashDrv_SectorErase_t erasetype); + +/*! \brief Erases a sector + * + * This function erases a sector located in pflash or dflash. + * + * NOTE: + * 1.Any code reachable from this function must not be placed in the targeted setcor. + * 2.if the sector[address:0x400~0x7ff] erased, before the POR, remind to program + * pflash-cfg-feild[0x400~0x41f] to proper value.Otherwise, system will enter security state, + * swd cannot be connected anymore + * 3.if the sector is in the eee backup region, the erase sequence will + * be aborted. + * 4.if the targeted sector is in protection region,the erase sequence will be aborted + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] destaddr : pointer to a address in the targeted sector + * \param[in] erasetype: erase type + */ +extern FlashDrv_Status FlashDrv_EraseSector(FlashDrvType *obj, + uint32_t *destaddr, + FlashDrv_SectorErase_t erasetype); + +/*! \brief Programs a section + * + * This function programs a section. The section should located in a sector or + * should be a total sector. Both the start addr and the size of the section are + * supposed to be 256-aligned. + * + * NOTE: 1.make sure targeted section is erased and not proteted before + * programmed; 2.if the target section is in the eee backup region, + * the program sequence will be aborted. + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] destaddr : pointer to a memory address in the targeted sector,256-aligned + * \param[in] len : length of programmed data in bytes, 256-aligned + * \param[in] databuf : pointer to source data + */ +extern FlashDrv_Status FlashDrv_ProgramSection(FlashDrvType *obj, + uint32_t *destaddr, + uint32_t len, + uint8_t *databuf); + +/*! \brief Programs a section + * + * This function programs a section fastly. The section should located in a sector or + * should be a total sector. Both the start addr and the size of the section are + * supposed to be 256-aligned. The programmed data is supposed to be prepared already in the flexram. + * + * NOTE: 1.make sure targeted section is erased and not proteted before + * programmed; 2.if the target section is in the eee backup region, + * the program sequence will be aborted.3.the programmed data has been placed in the flexram with + * correct offset(offset = dest & (FLASHDRV_SECTOR_SIZE - 1)) while ram ready. + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] destaddr : pointer to a memory address in the targeted sector,256-aligned + * \param[in] len : length of programmed data in bytes, 256-aligned + */ +extern FlashDrv_Status FlashDrv_ProgramSectionFast(FlashDrvType *obj, + uint32_t *destaddr, + uint32_t len); + +/*! \brief verify all blocks(pflash,dflash/e-flash) erased. + * + * This function verify all blocks [pflash,dflash]erased. + * + * NOTE: 1.make sure no proteted region in flash, otherwise the read1s sequence will + * be aborted; + * + * \param[in] obj : pointer to Flash driver instance + */ +extern FlashDrv_Status FlashDrv_Read1sAllBlock(FlashDrvType *obj); + +/*! \brief Reads a phrase(8 bytes) from flash info_region + * + * This function Read a phrase(8 bytes) from pflash info region or dflash info + * region. + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] regionid : FLASHDRV_INFORGN0 + * \param[in] phraseid : index of the phrase in the info region sector, 0 ~ 63 + * \param[in] databuf : pointer to a 8-byte-len buffer which data read from info region and write to + */ +extern FlashDrv_Status FlashDrv_ReadInfoRegion(FlashDrvType *obj, + FlashDrv_InfoRegion_t regionid, + uint8_t phraseid, + uint8_t *databuf); + +/*! \brief Programs a phrase(8 bytes) into flash info_region + * + * This function programs a phrase(8 bytes) into flash info_region + * + * NOTE: 1.make sure the targeted phrase can be programmed only one time through the lifecycle; + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] regionid : FLASHDRV_INFORGN0 + * \param[in] phraseid : index of the phrase in the info region sector, 0 ~ 63 + * \param[in] databuf : pointer to a 8-byte-len buffer which data read from info region and write to + */ +extern FlashDrv_Status FlashDrv_ProgramInfoRegion(FlashDrvType *obj, + FlashDrv_InfoRegion_t regionid, + uint32_t phraseid, + uint8_t *databuf); + +/*! \brief Erases all blocks(pflash, dflash/eflash, info-region). + * + * This function erases pflash, dflash/eflash, info-region. + * + * NOTE: + * 1.Any code reachable from this function must not be placed in a Flash + * block targeted for this erase operation. 2.Between the POR and + * allblock-erased operations, remind to program pflash-cfg-feild[0x400~0x41f] + * to proper value.Otherwise, system will enter security state, swd cannot be + * connected anymore. 3.if there is protection region in flash, the erase sequence + * will be aborted + * + * \param[in] obj : pointer to Flash driver instance + */ +extern FlashDrv_Status FlashDrv_EraseAllBlock(FlashDrvType *obj); + +/*! \brief Erases all blocks and update security bit in flash security info + * field. + * + * This function erase pflash,dflash/eflash, flash-info region ,and then program + * the security bit in flash security info field. + * + * NOTE: + * 1.Any code reachable from this function must not be placed in a Flash + * block targeted for this erase operation. 2.if MEEN disbled, the erase sequence + * will be aborted + * + * \param[in] obj : pointer to Flash driver instance + */ +extern FlashDrv_Status FlashDrv_EraseAllBlockUnsecure(FlashDrvType *obj); + +/*! \brief Verify the user backdoor key and make the system enter unsecurity + * state if pass. + * + * This function verify the user backdoor key stored in 0x400 with expected + * data.If the verified pass,the system will enter un-security state. + * + * NOTE: 1.if the KEY-EN disabled, this sequence will be aborted; + * + * \param[in] obj : pointer to Flash driver instance. + * \param[in] expdata : pointor to expected key-value, 8 bytes, supposed not to + * be all-0s or all-1s. + */ +extern FlashDrv_Status FlashDrv_VerifyUserKey(FlashDrvType *obj, + uint8_t *expdata); + +/*! \brief flash command done interrupt handler. + * + * \param[in] obj : pointer to Flash driver instance. + */ +extern void FlashDrv_IrqHandler(FlashDrvType *obj); + +/*! \brief flash command done interrupt enable in flash driver side. + * + * \param[in] obj : pointer to Flash driver instance. + * \param[in] en : control flag for the flash command done interrupter enable or disable + */ +extern void FlashDrv_SetCmdDoneIrqEn(FlashDrvType *obj, bool en); + +/*! \brief Get eee enable state + * + * This function gets the eee enable state + * + * \param[in] obj : pointer to Flash driver instance + * \return eee enable state + * - false : eee not enabled in Eeprom Cfg field.If EEE enable expected, progroram InfoRegion with correct data and then POR + * - true : eee enabled in Eeprom Cfg field + */ +extern bool FlashDrv_GetEeeEn(FlashDrvType *obj); + +/*! \brief Get eee_ram ready state + * + * This function gets the eeerst enable state + * + * \param[in] obj : pointer to Flash driver instance + * \return Eee_ram ready state + * - false : eee_ram not ready. + * - true : eee_ram ready. + */ +extern bool FlashDrv_GetEeeRamRdy(FlashDrvType *obj); + +/*! \brief sets the flexram as eee_ram or system_ram. + * + * \param[in] obj : pointer to Flash driver instance. + * \param[in] eeeramen : control eee_ram enabled or disabled, + * -false : the flex_ram will be used as system_ram + * -true : the flex_ram will be used as eeeram, UpdateEeeRam will take effect + */ +extern FlashDrv_Status FlashDrv_SetFlexRam(FlashDrvType *obj, bool eeeramen); + +/*! \brief updates eee_ram, data will be stored in flash. + * + *NOTE: 1.makesure the auto_gc(SCG0_Inst:TRIM_AUTO_GC_EN) enabled before this function called to + * avoid data overflowing and lost + * 2.makesure the eee_ram is enabled otherwise the new data will be lost + * + * \param[in] obj : pointer to Flash driver instance. + * \param[in] offset : indicates the targeted position in the eee_ram, range is [0 ~ 2048] + * \param[in] srcdata : pointer to srcdata which will be wrote into eee_ram + * \param[in] sz: len of srcdata in byte + */ +extern FlashDrv_Status FlashDrv_UpdateEeeRam(FlashDrvType *obj, uint32_t offset, uint8_t *srcdata, uint32_t sz); + +/*! \brief Gets eee auto GC enable state + * + * This function gets the eee auto GC enable state + * + * \param[in] obj : pointer to Flash driver instance + * \return eee auto GC enable state + * - false : eee auto GC disabled + * - true : eee auto GC enabled + */ +extern bool FlashDrv_GetEeeAutoGcEn(FlashDrvType *obj); + +/*! \brief Sets eee auto GC enable + * + * This function sets the eee auto GC enabled or disabled + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] eeegcen : control eee auto gc enabled or disabled, + * -false : the eee auto gc disabled + * -true : the eee auto gc enabled + */ +extern void FlashDrv_SetEeeAutoGcEn(FlashDrvType *obj, bool eeegcen); + +/*! \brief Gets eee_ram protection property + * + * This function gets the eee_ram protection property + * + * \param[in] obj : pointer to Flash driver instance + * \param[out] protectStatus : pointer to protection status + * - 0b : unprotect + * - 1b : protect + */ +extern FlashDrv_Status FlashDrv_GetEeeRamProtection(FlashDrvType *obj, uint8_t *protectstatus); + +/*! \brief Gets PFlash protection property + * + * This function gets the PFlash protection property + * + * \param[in] obj : pointer to Flash driver instance + * \param[out] protectStatus : pointer to protection status + * - 0b : unprotect + * - 1b : protect + */ +extern FlashDrv_Status FlashDrv_GetPFlashProtection(FlashDrvType *obj, uint32_t *protectstatus); + +/*! \brief Gets DFlash protection property + * + * This function gets the DFlash protection property + * + * \param[in] obj : pointer to Flash driver instance + * \param[out] protectStatus : pointer to protection status + * - 0b : unprotect + * - 1b : protect + */ +extern FlashDrv_Status FlashDrv_GetDFlashProtection(FlashDrvType *obj, uint8_t *protectstatus); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _FLASH_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/flexcan/flexcan_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/flexcan/flexcan_drv.c new file mode 100644 index 0000000..bbc753f --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/flexcan/flexcan_drv.c @@ -0,0 +1,1253 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "flexcan_drv.h" +#include "flexcan_reg.h" +#include "pcc0_reg.h" +#include "pcc1_reg.h" +#include "scg0_reg.h" +#include "scg2_reg.h" +#include "sim_reg.h" +#include "../../CVM011x_features.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define FLEXCAN_DRV_CAN_RAM_SIZE (512U) + +#define RX_FIFO_FILT_TABLE_ADD_OFFSET (0xE0U) + +#define TX_PENDING_ABORT_SUCCESS 1 +#define TX_PENDING_ABORT_NO_TRANSFER 0 +#define TX_PENDING_ABORT_FAILED (0xFFU) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +static inline uint8_t FlexCanDrv_ConvertMsgBufSizeSel(uint8_t MBSizeCode) +{ + uint8_t result = 0; + + switch(MBSizeCode) + { + case FLEXCANDRV_MB_SIZE_BYTE_8: + result = 16; + break; + case FLEXCANDRV_MB_SIZE_BYTE_16: + result = 24; + break; + case FLEXCANDRV_MB_SIZE_BYTE_32: + result = 40; + break; + case FLEXCANDRV_MB_SIZE_BYTE_64: + result = 72; + break; + } + + return result; +} + +static inline uint32_t FlexCanDrv_GetMsgBufStartAddr(FlexCanDrvType *obj, uint16_t msgBufId) +{ + /* get the first message buffer start address */ + uint32_t addr = FlexCanReg_GetMsgBufferStartAddr(obj->flexCanReg); + uint8_t msgBufSize = 0; + + /* get the message buffer size */ +#if FEATURE_CAN_FD_INSTANCE_NUM == 0 && FEATURE_CAN_2_0_INSTANCE_NUM == 1 + uint8_t msgBufSizeSel = FLEXCANDRV_MB_SIZE_BYTE_8; +#elif FEATURE_CAN_FD_INSTANCE_NUM == 1 && FEATURE_CAN_2_0_INSTANCE_NUM == 0 + uint8_t msgBufSizeSel = FlexCanReg_GetRegionDataSizeSel(obj->flexCanReg, 0); +#else +#error "Not matching CVM011x chip definition." +#endif + msgBufSize = FlexCanDrv_ConvertMsgBufSizeSel(msgBufSizeSel) / 4; + + if(msgBufSizeSel == FLEXCANDRV_MB_SIZE_BYTE_8) + { + addr += (msgBufSize * msgBufId) * 4; + } + else if(msgBufSizeSel == FLEXCANDRV_MB_SIZE_BYTE_16) + { + addr += (msgBufSize * msgBufId + (2 * (msgBufId / 21))) * 4; + } + else if(msgBufSizeSel == FLEXCANDRV_MB_SIZE_BYTE_32) + { + addr += (msgBufSize * msgBufId + (8 * (msgBufId / 12))) * 4; + } + else + { + addr += (msgBufSize * msgBufId + (2 * (msgBufId / 7))) * 4; + } + + return addr; +} + +static inline uint8_t FlexCanDrv_DLC2DataLen(FlexCanDrv_DLCType dlc) +{ + uint8_t dataLen = 0; + + switch(dlc) + { + case DLC_BYTE_0: + case DLC_BYTE_1: + case DLC_BYTE_2: + case DLC_BYTE_3: + case DLC_BYTE_4: + case DLC_BYTE_5: + case DLC_BYTE_6: + case DLC_BYTE_7: + case DLC_BYTE_8: + dataLen = (uint8_t)dlc; + break; + case DLC_BYTE_12: + dataLen = 12; + break; + case DLC_BYTE_16: + dataLen = 16; + break; + case DLC_BYTE_20: + dataLen = 20; + break; + case DLC_BYTE_24: + dataLen = 24; + break; + case DLC_BYTE_32: + dataLen = 32; + break; + case DLC_BYTE_48: + dataLen = 48; + break; + case DLC_BYTE_64: + dataLen = 64; + break; + default: + break; + } + + return dataLen; +} + +static inline uint8_t FlexCanDrv_GetMsgBufDataLen(FlexCanDrvType *obj, uint16_t msgBufId) +{ + uint32_t *msgBufPtr; + uint8_t dlc = 0; + uint8_t dataLen = 0; + + /* get current message buffer start address */ + msgBufPtr = (uint32_t *)FlexCanDrv_GetMsgBufStartAddr(obj, msgBufId); + + /* get DLC code from message buffer */ + dlc = (*msgBufPtr & MESSAGE_BUFFER_CS_DLC_MASK) >> MESSAGE_BUFFER_CS_DLC_SHIFT; + + /* convert DLC code to data length */ + dataLen = FlexCanDrv_DLC2DataLen((FlexCanDrv_DLCType)dlc); + + return dataLen; +} + +static inline void FlexCanDrv_SetMsgId(uint32_t *msgBufPtr, uint32_t msgId, bool isExt) +{ + uint32_t tempVar = 0; + + if(isExt) + { + /* set extended message ID bit (IDE) */ + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] |= (MESSAGE_BUFFER_CS_IDE_MASK | MESSAGE_BUFFER_CS_SRR_MASK); + + /* set extended message ID */ + tempVar = msgBufPtr[MESSAGE_BUFFER_ID_WORD_NUM]; + tempVar &= ~(MESSAGE_BUFFER_ID_EXT_ID_MASK); + tempVar |= ((msgId << MESSAGE_BUFFER_ID_EXT_ID_SHIFT) & MESSAGE_BUFFER_ID_EXT_ID_MASK); + msgBufPtr[MESSAGE_BUFFER_ID_WORD_NUM] = tempVar; + } + else + { + /* clear extended message ID bit (IDE) */ + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] &= ~(MESSAGE_BUFFER_CS_IDE_MASK | MESSAGE_BUFFER_CS_SRR_MASK); + + /* load standard message ID */ + tempVar = msgBufPtr[MESSAGE_BUFFER_ID_WORD_NUM]; + tempVar &= ~(MESSAGE_BUFFER_ID_STD_ID_MASK); + tempVar |= ((msgId << MESSAGE_BUFFER_ID_STD_ID_SHIFT) & MESSAGE_BUFFER_ID_STD_ID_MASK); + msgBufPtr[MESSAGE_BUFFER_ID_WORD_NUM] = tempVar; + } +} + +static inline void FlexCanDrv_SetMsgDLC(uint32_t *msgBufPtr, FlexCanDrv_DLCType dlc) +{ + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] &= (~MESSAGE_BUFFER_CS_DLC_MASK); + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] |= (((uint32_t)dlc) << MESSAGE_BUFFER_CS_DLC_SHIFT & MESSAGE_BUFFER_CS_DLC_MASK); +} + +static inline void FlexCanDrv_SetFDEnable(uint32_t *msgBufPtr, bool fdEnable) +{ + /* clear EDL bit */ + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] &= (~MESSAGE_BUFFER_CS_EDL_MASK); + /* clear BRS bit */ + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] &= (~MESSAGE_BUFFER_CS_BRS_MASK); + + if(fdEnable) + { + /* set EDL bit */ + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] |= MESSAGE_BUFFER_CS_EDL_MASK; + /* set BRS bit */ + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] |= MESSAGE_BUFFER_CS_BRS_MASK; + } + else + { + /* non CAN-FD keep EDL, BRS bit clear */ + } +} + +static inline void FlexCanDrv_SetMsgType(uint32_t *msgBufPtr, FlexCanDrv_MsgType_t msgType) +{ + if(msgType == FLEXCANDRV_MSGTYPE_TX) + { + /* tx message set CODE as INACTIVE */ + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] &= (~MESSAGE_BUFFER_CS_CODE_MASK); + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] |= ((FLEXCANDRV_MSG_BUF_CODE_INACTIVE << MESSAGE_BUFFER_CS_CODE_SHIFT) & MESSAGE_BUFFER_CS_CODE_MASK); + } + else if(msgType == FLEXCANDRV_MSGTYPE_RX) + { + /* rx message set CODE as RX_ACTIVE */ + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] &= (~MESSAGE_BUFFER_CS_CODE_MASK); + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] |= ((FLEXCANDRV_MSG_BUF_CODE_RX_ACTIVE << MESSAGE_BUFFER_CS_CODE_SHIFT) & MESSAGE_BUFFER_CS_CODE_MASK); + } + else + { + } +} + +static inline void FlexCanDrv_InitCanRAM(FlexCanDrvType *obj) +{ + uint32_t *u32Ptr = (uint32_t *)FlexCanReg_GetMsgBufferStartAddr(obj->flexCanReg); + uint32_t *tempPtr; + uint32_t i = 0; + + /* 0x80 - 0x480: message buffer 512 byte * 2 region */ + for(i = 0; i < 128 * obj->initHwPar.canRamNum; i++) + { + tempPtr = (u32Ptr + i); + *tempPtr = 0; + } +} + +static inline void FlexCanDrv_EnableCanCfgClk(FlexCanDrvType *obj) +{ + /* unlock PCC key */ + Pcc0Reg_SetKey(obj->pcc0Reg, 0x55534552); + /* enable CAN CFG clock */ + Pcc1Reg_SetCanCfgCkEn(obj->pcc1Reg, 1); + /* lock PCC key again */ + Pcc0Reg_SetKey(obj->pcc0Reg, 0); +} + +static inline void FlexCanDrv_EnableCanOperationClk(FlexCanDrvType *obj) +{ + /* unlock PCC key */ + Pcc0Reg_SetKey(obj->pcc0Reg, 0x55534552); + /* enable CAN operation clock */ + Pcc1Reg_SetCanCkEn(obj->pcc1Reg, 1); + /* lock PCC key again */ + Pcc0Reg_SetKey(obj->pcc0Reg, 0); +} + +void FlexCanDrv_Init(FlexCanDrvType *obj, + struct _FlexCanRegType_ *flexCanReg, + struct _Pcc1RegType_ *pcc1Reg, + struct _Pcc0RegType_ *pcc0Reg, + struct _Scg0RegType_ *scg0Reg, + struct _Scg2RegType_ *scg2Reg, + struct _SimRegType_ *simReg, + FlexCanDrv_InitHwParType *initHwPar) +{ + obj->initHwPar.canRamNum = initHwPar->canRamNum; + obj->flexCanReg = flexCanReg; + obj->pcc1Reg = pcc1Reg; + obj->pcc0Reg = pcc0Reg; + obj->scg0Reg = scg0Reg; + obj->scg2Reg = scg2Reg; + obj->simReg = simReg; +} + +void FlexCanDrv_GetDefaultCfg(FlexCanDrv_ControllerCfgType *controllerCfg) +{ + uint8_t i = 0; + + controllerCfg->bitTiming.prescalerDiv = 0; + controllerCfg->bitTiming.propSeg = 0; + controllerCfg->bitTiming.phaseSeg1 = 0; + controllerCfg->bitTiming.phaseSeg2 = 0; + controllerCfg->bitTiming.resyncJumpWidth = 0; + controllerCfg->fdBitTiming.prescalerDiv = 0; + controllerCfg->fdBitTiming.propSeg = 0; + controllerCfg->fdBitTiming.phaseSeg1 = 0; + controllerCfg->fdBitTiming.phaseSeg2 = 0; + controllerCfg->fdBitTiming.resyncJumpWidth = 0; + controllerCfg->clkSrc = FLEXCANDRV_CLKSRC_CHICLK; + controllerCfg->fifoEnable = 0; + controllerCfg->dmaEnable = 0; + controllerCfg->rxMBGlobalMask = 0xFFFFFFFF; + controllerCfg->rxMB14Mask = 0xFFFFFFFF; + controllerCfg->rxMB15Mask = 0xFFFFFFFF; + controllerCfg->rxFifoGlobalMask = 0xFFFFFFFF; + controllerCfg->rxFifoFiltFormat = FLEXCANDRV_RXFIFO_FILTFORMAT_A; + controllerCfg->rxFifoFilterNum = 0; + controllerCfg->individualMaskEnable = 0; + controllerCfg->rxFifoIndivMskNum = 8; + for(i = 0; i < 32; i ++) + { + controllerCfg->rxFifoIndivMsk[i] = 0xFFFFFFFF; + } + controllerCfg->fdEnable = 0; + controllerCfg->fdISOEnable = 0; + controllerCfg->msgBufDataLenSel = FLEXCANDRV_MB_SIZE_BYTE_8; + controllerCfg->loopbackEnable = 0; + controllerCfg->tdcEnable = 0; + controllerCfg->tdcOffset = 0; + controllerCfg->txAbortEnable = 0; + controllerCfg->edgeWkupEnable = 0; + controllerCfg->busoffIntEnable = 0; + controllerCfg->errorIntEnable = 0; + controllerCfg->msgNum = 0; + controllerCfg->msgCfg = (void *)0; +} + +void FlexCanDrv_Start(FlexCanDrvType *obj) +{ + /* set freeze mode disable */ + FlexCanReg_SetFreezeMode(obj->flexCanReg, false); + /* set halt mode disable */ + FlexCanReg_SetHaltMode(obj->flexCanReg, false); + + /* wait for synchronization */ + while(FlexCanReg_GetFreezeAck(obj->flexCanReg)) + { + } +} + +void FlexCanDrv_SoftReset(FlexCanDrvType *obj) +{ + /* check for low power mode */ + if(FlexCanReg_GetLowPowerAck(obj->flexCanReg)) + { + /* Enable clock */ + FlexCanReg_SetModuleDisable(obj->flexCanReg, false); + /* wait until enabled */ + while(FlexCanReg_GetLowPowerAck(obj->flexCanReg)) + { + /* enable CAN operation clock */ + FlexCanDrv_EnableCanOperationClk(obj); + } + } + + /* Reset the CAN module */ + FlexCanReg_SetSoftResetRequest(obj->flexCanReg, true); + /* Wait for reset cycle to complete */ + while(FlexCanReg_GetSoftResetRequest(obj->flexCanReg)) + { + } + + /* set freeze mode enable */ + FlexCanReg_SetFreezeMode(obj->flexCanReg, true); + /* set halt mode enable */ + FlexCanReg_SetHaltMode(obj->flexCanReg, true); + + /* check for freeze Ack */ + while((FlexCanReg_GetFreezeAck(obj->flexCanReg) == 0) || (FlexCanReg_GetNotReadyFlag(obj->flexCanReg) == 0)) + { + /* soft reset failed */ + } +} + +void FlexCanDrv_CfgMsgObj(FlexCanDrvType *obj, const FlexCanDrv_MsgCfgType *msgCfg, uint8_t msgBufId) +{ + FlexCanDrv_MsgObjType msgObj; + uint32_t *msgBufPtr; + + /* get current message buffer start address */ + msgBufPtr = (uint32_t *)FlexCanDrv_GetMsgBufStartAddr(obj, msgBufId); + + /* set message ID */ + FlexCanDrv_SetMsgId(msgBufPtr, msgCfg->msgId, msgCfg->isExtMsgId); + + /* set message DLC */ + FlexCanDrv_SetMsgDLC(msgBufPtr, msgCfg->dlc); + + /* set FD configures */ + FlexCanDrv_SetFDEnable(msgBufPtr, msgCfg->isFd); + + /* set message type */ + FlexCanDrv_SetMsgType(msgBufPtr, msgCfg->msgType); + + if(msgCfg->intEnable) + { + msgObj.msgBufId = msgBufId; + /* set message buffer interrupt enable */ + FlexCanDrv_EnableMsgObjInterrupt(obj, &msgObj); + } + else + { + /* message buffer interrupt disable, do nothing */ + } + + if(msgCfg->msgType == FLEXCANDRV_MSGTYPE_RX) + { + /* set message buffer individual mask */ + FlexCanReg_SetRxIndividualMask(obj->flexCanReg, msgBufId, msgCfg->individualMask); + } + else + { + /* current message buffer is Tx message no need to configure individual mask */ + } +} + +void FlexCanDrv_Configure(FlexCanDrvType *obj, const FlexCanDrv_ControllerCfgType *controllerCfg) +{ + uint8_t msgBufSize; + uint8_t msgBufNum = 0; + uint8_t i = 0; + + /* enable CAN CFG clock */ + FlexCanDrv_EnableCanCfgClk(obj); + + /* disable FlexCan module */ + FlexCanReg_SetModuleDisable(obj->flexCanReg, true); + + /* make sure that the module has enter into low power mode successfully */ + while(FlexCanReg_GetLowPowerAck(obj->flexCanReg) == 0) + { + + } + + /* configure FlexCan clock source */ + FlexCanReg_SetClockSource(obj->flexCanReg, controllerCfg->clkSrc); + + /* reset CAN internal status */ + FlexCanDrv_SoftReset(obj); + + /* switch to supervisor mode */ + FlexCanReg_SetAccessMode(obj->flexCanReg, FLEXCANDRV_CAN_ACCESS_MODE_SUP); + + /* enable write access in freeze mode */ + FlexCanReg_SetFreezeModeWriteAcc(obj->flexCanReg, true); + + /* initial can ram */ + FlexCanDrv_InitCanRAM(obj); + + /* calculate the total message number according to the message + * buffer size per region */ + msgBufSize = FlexCanDrv_ConvertMsgBufSizeSel(controllerCfg->msgBufDataLenSel); + if(msgBufSize != 0) + { + msgBufNum = (FLEXCAN_DRV_CAN_RAM_SIZE / msgBufSize) * obj->initHwPar.canRamNum; + } + /* set message buffer maximum number */ + FlexCanReg_SetMaxMsgBufferNum(obj->flexCanReg, msgBufNum); + + /* + * set standard CAN bit timing + */ + /* enable CAN extended bit timing */ + FlexCanReg_SetExtendedBitTimingEnable(obj->flexCanReg, true); + /* set prescaler division */ + FlexCanReg_SetExtPresalerDivision(obj->flexCanReg, controllerCfg->bitTiming.prescalerDiv - 1); + /* set resync jump width */ + FlexCanReg_SetExtResyncJumpWidth(obj->flexCanReg, controllerCfg->bitTiming.resyncJumpWidth - 1); + /* set propagation segment */ + FlexCanReg_SetExtPorpSeg(obj->flexCanReg, controllerCfg->bitTiming.propSeg - 1); + /* set phase segment 1 */ + FlexCanReg_SetExtPhaseSeg1(obj->flexCanReg, controllerCfg->bitTiming.phaseSeg1 - 1); + /* set phase segment 2 */ + FlexCanReg_SetExtPhaseSeg2(obj->flexCanReg, controllerCfg->bitTiming.phaseSeg2 - 1); + + if(controllerCfg->fifoEnable) + { + /* set Rx FIFO enable */ + FlexCanReg_SetRxFIFOEnalbe(obj->flexCanReg, true); + /* set Rx FIFO DMA enable */ + FlexCanReg_SetRxFIFODmaEnable(obj->flexCanReg, controllerCfg->dmaEnable); + /* set Rx FIFO global mask */ + FlexCanReg_SetRxFifoGlobalMask(obj->flexCanReg, controllerCfg->rxFifoGlobalMask); + /* set Rx FIFO ID filter format */ + FlexCanReg_SetRxFifoFiltMode(obj->flexCanReg, controllerCfg->rxFifoFiltFormat); + /* set Rx FIFO filter number code */ + FlexCanReg_SetRxFifoFilterNum(obj->flexCanReg, controllerCfg->rxFifoFilterNum); + /* set Rx Individual mask dedicated for Rx FIFO */ + if(controllerCfg->individualMaskEnable == true) + { + for(i = 0; i < controllerCfg->rxFifoIndivMskNum; i ++) + { + FlexCanReg_SetRxIndividualMask(obj->flexCanReg, i, controllerCfg->rxFifoIndivMsk[i]); + } + } + } + else + { + /* set Rx FIFO disable */ + FlexCanReg_SetRxFIFOEnalbe(obj->flexCanReg, false); + /* disable Rx FIFO DMA */ + FlexCanReg_SetRxFIFODmaEnable(obj->flexCanReg, false); + } + +#if FEATURE_CAN_FD_INSTANCE_NUM == 1 && FEATURE_CAN_2_0_INSTANCE_NUM == 0 + if(controllerCfg->fdEnable) + { + /* set CAN FD operation enable */ + FlexCanReg_SetFdEnable(obj->flexCanReg, controllerCfg->fdEnable); + /* enable FD rate switch */ + FlexCanReg_SetFdRateSwitch(obj->flexCanReg, true); + + /* set FD prescaler division */ + FlexCanReg_SetFdPrescalerDivision(obj->flexCanReg, controllerCfg->fdBitTiming.prescalerDiv - 1); + /* set FD resync jump width */ + FlexCanReg_SetFdResyncJumpWidth(obj->flexCanReg, controllerCfg->fdBitTiming.resyncJumpWidth - 1); + /* set FD propagation segment */ + FlexCanReg_SetFdPorpSeg(obj->flexCanReg, controllerCfg->fdBitTiming.propSeg); + /* set FD phase segment 1 */ + FlexCanReg_SetFdPhaseSeg1(obj->flexCanReg, controllerCfg->fdBitTiming.phaseSeg1 - 1); + /* set FD phase segment 2 */ + FlexCanReg_SetFdPhaseSeg2(obj->flexCanReg, controllerCfg->fdBitTiming.phaseSeg2 - 1); + + /* set region 0 data size selection */ + FlexCanReg_SetRegionDataSizeSel(obj->flexCanReg, 0, controllerCfg->msgBufDataLenSel); + /* set region 1 data size selection */ + FlexCanReg_SetRegionDataSizeSel(obj->flexCanReg, 1, controllerCfg->msgBufDataLenSel); + /* set region 2 data size selection */ + FlexCanReg_SetRegionDataSizeSel(obj->flexCanReg, 2, controllerCfg->msgBufDataLenSel); + /* set region 3 data size selection */ + FlexCanReg_SetRegionDataSizeSel(obj->flexCanReg, 3, controllerCfg->msgBufDataLenSel); + + /* set TDC enable */ + FlexCanReg_SetTdcEnable(obj->flexCanReg, controllerCfg->tdcEnable); + /* set TDC offset */ + FlexCanReg_SetTdcOffset(obj->flexCanReg, controllerCfg->tdcOffset); + + /* set CAN-FD ISO enable */ + FlexCanReg_SetIsoFdEnalbe(obj->flexCanReg, controllerCfg->fdISOEnable); + } +#endif + + /* set rx mailbox global mask */ + FlexCanReg_SetRxMailboxGlobalMask(obj->flexCanReg, controllerCfg->rxMBGlobalMask); + /* set rx mailbox 14 mask */ + FlexCanReg_SetRxMailbox14Mask(obj->flexCanReg, controllerCfg->rxMB14Mask); + /* set rx mailbox 15 mask */ + FlexCanReg_SetRxMailbox15Mask(obj->flexCanReg, controllerCfg->rxMB15Mask); + /* set individual Rx masking and queue enable */ + FlexCanReg_SetIndividualMaskEnable(obj->flexCanReg, controllerCfg->individualMaskEnable); + + /* loopback mode configuration */ + if(controllerCfg->loopbackEnable) + { + FlexCanReg_SetSelfReceptionDisable(obj->flexCanReg, false); /* enable self reception (0) */ + FlexCanReg_SetLoopbackMode(obj->flexCanReg, true); /* enable loop-back */ + } + else + { + FlexCanReg_SetSelfReceptionDisable(obj->flexCanReg, true); /* disable self reception (1) */ + FlexCanReg_SetLoopbackMode(obj->flexCanReg, false); /* disable loop-back */ + } + + /* edge wakeup configuration */ + if(controllerCfg->edgeWkupEnable) + { + /* enable edge(self) wakeup */ + FlexCanReg_SetSelfWakeupEnable(obj->flexCanReg, 1U); + /* enable edge(self) wakeup interrupt */ + FlexCanReg_SetWakeupIntMask(obj->flexCanReg, 1U); + /* enable doze mode request */ + FlexCanReg_SetDozeMode(obj->flexCanReg, 1U); + /* enable sleep wakeup in SIM */ + SimReg_SetCanWkupSrcSel(obj->simReg, 1); + } + else + { + /* disable edge(self) wakeup */ + FlexCanReg_SetSelfWakeupEnable(obj->flexCanReg, 0U); + /* disable edge(self) wakeup interrupt */ + FlexCanReg_SetWakeupIntMask(obj->flexCanReg, 0U); + /* disable doze mode request */ + FlexCanReg_SetDozeMode(obj->flexCanReg, 0U); + /* disable sleep wakeup in SIM */ + SimReg_SetCanWkupSrcSel(obj->simReg, 0); + } + + /* set Tx message abort enable */ + FlexCanReg_SetTxAbortEnable(obj->flexCanReg, controllerCfg->txAbortEnable); + + /* set busoff interrupt enable mask */ + FlexCanReg_SetBusOffIntEnable(obj->flexCanReg, controllerCfg->busoffIntEnable); + /* set error interrupt enable mask */ + FlexCanReg_SetErrorIntEnable(obj->flexCanReg, controllerCfg->errorIntEnable); + + /* configure messages */ + for(i = 0; i < controllerCfg->msgNum; i++) + { + uint16_t j = 0; + /* configure messages according to the message buffer Id and message buffer length parameters */ + for(j = controllerCfg->msgCfg[i].msgBufId; j < controllerCfg->msgCfg[i].msgBufId + controllerCfg->msgCfg[i].msgBufLen; j++) + { + FlexCanDrv_CfgMsgObj(obj, &controllerCfg->msgCfg[i], j); + } + } + + /* clear all message buffer flags */ + FlexCanDrv_ClearAllMsgObjFlags(obj); + + /* enable FlexCan module */ + FlexCanDrv_Start(obj); + + /* switch to user mode */ + FlexCanReg_SetAccessMode(obj->flexCanReg, FLEXCANDRV_CAN_ACCESS_MODE_USER); +} + +void FlexCanDrv_TransmitMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj) +{ + uint32_t *msgBufPtr; + + /* get current message buffer start address */ + msgBufPtr = (uint32_t *)FlexCanDrv_GetMsgBufStartAddr(obj, msgObj->msgBufId); + + /* set transmit code for the message buffer and start transmitting */ + *msgBufPtr |= (((uint32_t)FLEXCANDRV_MSG_BUF_CODE_TX_REQUEST) << FLEXCANDRV_MSG_BUF_CODE_SHIFT); +} + +void FlexCanDrv_SetTxMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj) +{ + uint32_t *msgBufPtr; + uint32_t dataLen; + + /* get current message buffer start address */ + msgBufPtr = (uint32_t *)FlexCanDrv_GetMsgBufStartAddr(obj, msgObj->msgBufId); + /* add data field address offset (2 * 32 bit) */ + msgBufPtr += 2; + + /* get data length from message buffer DLC */ + dataLen = FlexCanDrv_GetMsgBufDataLen(obj, msgObj->msgBufId); + + /* load the data into message buffer */ + uint8_t i = 0; + for(i = 0; i < dataLen; i++) + { + /* load the data in byte length */ + if((i % 4) == 0) + { + /* clean the old data */ + *msgBufPtr = 0; + + /* lowest byte in 32-bit */ + *msgBufPtr |= (((uint32_t)msgObj->data[i]) << 24); + } + else if((i % 4) == 1) + { + /* 2nd byte in 32-bit */ + *msgBufPtr |= (((uint32_t)msgObj->data[i]) << 16); + } + else if((i % 4) == 2) + { + /* 3rd byte in 32-bit */ + *msgBufPtr |= (((uint32_t)msgObj->data[i]) << 8); + } + else if((i % 4) == 3) + { + /* highest byte in 32-bit */ + *msgBufPtr |= ((uint32_t)msgObj->data[i]); + + /* increment the 32-bit data pointer */ + msgBufPtr++; + } + } +} + +void FlexCanDrv_GetRxMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj) +{ + uint32_t *msgBufPtr; + uint8_t dataLen; + bool isExtMsgId; + + /* get current message buffer start address */ + msgBufPtr = (uint32_t *)FlexCanDrv_GetMsgBufStartAddr(obj, msgObj->msgBufId); + + /* get the rx message DLC */ + msgObj->dlc = FlexCanDrv_DLC2DataLen((FlexCanDrv_DLCType)((*msgBufPtr & MESSAGE_BUFFER_CS_DLC_MASK) >> MESSAGE_BUFFER_CS_DLC_SHIFT)); + /* get extended message ID bit (CS.IDE) */ + isExtMsgId = (*msgBufPtr & MESSAGE_BUFFER_CS_IDE_MASK) >> MESSAGE_BUFFER_CS_IDE_SHIFT; + + /* set message buffer pointer to ID field */ + msgBufPtr++; + + /* get message ID */ + if(isExtMsgId == true) + { + msgObj->msgId = (*msgBufPtr & MESSAGE_BUFFER_ID_EXT_ID_MASK) >> MESSAGE_BUFFER_ID_EXT_ID_SHIFT; + } + else + { + msgObj->msgId = (*msgBufPtr & MESSAGE_BUFFER_ID_STD_ID_MASK) >> MESSAGE_BUFFER_ID_STD_ID_SHIFT; + } + + /* set the message buffer pointer to data field */ + msgBufPtr++; + + /* get data length from message buffer DLC */ + dataLen = FlexCanDrv_GetMsgBufDataLen(obj, msgObj->msgBufId); + + /* load the data from message buffer to data array */ + uint8_t i = 0; + for(i = 0; i < dataLen; i++) + { + if((i % 4) == 0) + { + /* load 1 byte data from highest byte in 32-bit */ + msgObj->data[i] = (*msgBufPtr >> 24); + } + else if((i % 4) == 1) + { + /* load 1 byte data from 2nd highest byte in 32-bit */ + msgObj->data[i] = (*msgBufPtr >> 16); + } + else if((i % 4) == 2) + { + /* load 1 byte data from 3nd highest byte in 32-bit */ + msgObj->data[i] = (*msgBufPtr >> 8); + } + /* when (i % 4) == 3 */ + else + { + /* load 1 byte data from lowest byte in 32-bit */ + msgObj->data[i] = (*msgBufPtr >> 0); + + /* increment message buffer 32-bit data pointer */ + msgBufPtr++; + } + } + + /* unlock mailbox globally */ + FlexCanReg_GetFreeRunningTimer(obj->flexCanReg); +} + +void FlexCanDrv_GetRxFifoMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj) +{ + bool isExtMsgId; + FlexCanDrv_MsgObjType tempMsgObj; + + /* get Rx FIFO out port start address (message buffer 0) */ + uint32_t *msgBufPtr = (uint32_t *)FlexCanDrv_GetMsgBufStartAddr(obj, 0); + + /* get the rx message DLC */ + msgObj->dlc = FlexCanDrv_DLC2DataLen((FlexCanDrv_DLCType)((*msgBufPtr & MESSAGE_BUFFER_CS_DLC_MASK) >> MESSAGE_BUFFER_CS_DLC_SHIFT)); + /* get extended message ID bit (CS.IDE) */ + isExtMsgId = (*msgBufPtr & MESSAGE_BUFFER_CS_IDE_MASK) >> MESSAGE_BUFFER_CS_IDE_SHIFT; + + /* set message buffer pointer to ID field */ + msgBufPtr++; + + /* get message ID */ + if(isExtMsgId == true) + { + msgObj->msgId = (*msgBufPtr & MESSAGE_BUFFER_ID_EXT_ID_MASK) >> MESSAGE_BUFFER_ID_EXT_ID_SHIFT; + } + else + { + msgObj->msgId = (*msgBufPtr & MESSAGE_BUFFER_ID_STD_ID_MASK) >> MESSAGE_BUFFER_ID_STD_ID_SHIFT; + } + + /* set message buffer pointer to DATA field */ + msgBufPtr++; + + /* load the data from message buffer to data array */ + uint8_t i = 0; + for(i = 0; i < 8; i++) + { + if((i % 4) == 0) + { + /* load 1 byte data from highest byte in 32-bit */ + msgObj->data[i] = (*msgBufPtr >> 24); + } + else if((i % 4) == 1) + { + /* load 1 byte data from 2nd highest byte in 32-bit */ + msgObj->data[i] = (*msgBufPtr >> 16); + } + else if((i % 4) == 2) + { + /* load 1 byte data from 3nd highest byte in 32-bit */ + msgObj->data[i] = (*msgBufPtr >> 8); + } + /* when (i % 4) == 3 */ + else + { + /* load 1 byte data from lowest byte in 32-bit */ + msgObj->data[i] = (*msgBufPtr >> 0); + + /* increment message buffer 32-bit data pointer */ + msgBufPtr++; + } + } + + /* clear Rx FIFO available flag to update Rx FIFO */ + tempMsgObj.msgBufId = 5; + FlexCanDrv_ClearMsgObjFlag(obj, &tempMsgObj); +} + +void FlexCanDrv_ClearMsgObjFlag(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj) +{ + uint32_t temp, temp1 = 0; + + temp1 = msgObj->msgBufId % 32; + temp = 0x00000001 << temp1; + + if(msgObj->msgBufId > 63) + { + FlexCanReg_SetMsgBufInterruptFlagReg(obj->flexCanReg, 2, temp); + } + else if(msgObj->msgBufId > 31) + { + FlexCanReg_SetMsgBufInterruptFlagReg(obj->flexCanReg, 1, temp); + } + else + { + FlexCanReg_SetMsgBufInterruptFlagReg(obj->flexCanReg, 0, temp); + } +} + +uint8_t FlexCanDrv_GetMsgObjFlag(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj) +{ + uint32_t temp, temp1 = 0; + temp1 = msgObj->msgBufId % 32; + temp = 0x00000001 << temp1; + + if(msgObj->msgBufId > 63) + { + temp &= FlexCanReg_GetMsgBufInterruptFlagReg(obj->flexCanReg, 2); + } + else if(msgObj->msgBufId > 31) + { + temp &= FlexCanReg_GetMsgBufInterruptFlagReg(obj->flexCanReg, 1); + } + else + { + temp &= FlexCanReg_GetMsgBufInterruptFlagReg(obj->flexCanReg, 0); + } + + if(temp) + { + return (1); + } + else + { + return (0); + } +} + +void FlexCanDrv_ClearAllMsgObjFlags(FlexCanDrvType *obj) +{ + if(obj->initHwPar.canRamNum == 3) + { + FlexCanReg_SetMsgBufInterruptFlagReg(obj->flexCanReg, 2, 0xFFFFFFFF); + FlexCanReg_SetMsgBufInterruptFlagReg(obj->flexCanReg, 1, 0xFFFFFFFF); + FlexCanReg_SetMsgBufInterruptFlagReg(obj->flexCanReg, 0, 0xFFFFFFFF); + } + else if(obj->initHwPar.canRamNum == 2) + { + FlexCanReg_SetMsgBufInterruptFlagReg(obj->flexCanReg, 1, 0xFFFFFFFF); + FlexCanReg_SetMsgBufInterruptFlagReg(obj->flexCanReg, 0, 0xFFFFFFFF); + } + else if(obj->initHwPar.canRamNum == 1) + { + FlexCanReg_SetMsgBufInterruptFlagReg(obj->flexCanReg, 0, 0xFFFFFFFF); + } +} + +void FlexCanDrv_EnableMsgObjInterrupt(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj) +{ + uint32_t temp, temp1 = 0; + temp1 = msgObj->msgBufId % 32; + temp = 0x00000001 << temp1; + if(msgObj->msgBufId > 63) + { + FlexCanReg_SetMsgBufInterruptEnable(obj->flexCanReg, 2, temp); + } + else if(msgObj->msgBufId > 31) + { + FlexCanReg_SetMsgBufInterruptEnable(obj->flexCanReg, 1, temp); + } + else + { + FlexCanReg_SetMsgBufInterruptEnable(obj->flexCanReg, 0, temp); + } +} + +void FlexCanDrv_DisableMsgObjInterrupt(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj) +{ + uint32_t temp, temp1 = 0; + temp1 = msgObj->msgBufId % 32; + temp = ~(0x00000001 << temp1); + if(msgObj->msgBufId > 63) + { + FlexCanReg_SetMsgBufInterruptDisable(obj->flexCanReg, 2, temp); + } + else if(msgObj->msgBufId > 31) + { + FlexCanReg_SetMsgBufInterruptDisable(obj->flexCanReg, 1, temp); + } + else + { + FlexCanReg_SetMsgBufInterruptDisable(obj->flexCanReg, 0, temp); + } +} + +FlexCanDrv_NodeStatType FlexCanDrv_GetNodeStatus(FlexCanDrvType *obj) +{ + FlexCanDrv_NodeStatType ret; + + if(FlexCanReg_GetTxState(obj->flexCanReg)) + { + ret = FLEXCANDRV_NODESTAT_TRANSMITTING; + } + else if(FlexCanReg_GetRxState(obj->flexCanReg)) + { + ret = FLEXCANDRV_NODESTAT_RECEIVING; + } + else if(FlexCanReg_GetIdleState(obj->flexCanReg)) + { + ret = FLEXCANDRV_NODESTAT_IDLE; + } + else + { + } + + return ret; +} + +void FlexCanDrv_GetErrorStates(FlexCanDrvType *obj, FlexCanDrv_ErrStsType *errSts) +{ + uint8_t tempSts; + + tempSts = FlexCanReg_GetFltConfinementState(obj->flexCanReg); + if(tempSts & 0x2) + { + errSts->fltConfSts = FLEXCANDRV_FLTCONFSTS_BUSOFF; + } + else + { + errSts->fltConfSts = (FlexCanDrv_FltConfStsType)tempSts; + } + + errSts->bit1Err = FlexCanReg_GetBit1Error(obj->flexCanReg); + errSts->bit0Err = FlexCanReg_GetBit0Error(obj->flexCanReg); + errSts->ackErr = FlexCanReg_GetAckError(obj->flexCanReg); + errSts->crcErr = FlexCanReg_GetCrcError(obj->flexCanReg); + errSts->formErr = FlexCanReg_GetFormError(obj->flexCanReg); + errSts->stuffErr = FlexCanReg_GetStuffError(obj->flexCanReg); +#if FEATURE_CAN_FD_INSTANCE_NUM == 1 && FEATURE_CAN_2_0_INSTANCE_NUM == 0 + errSts->bit1FastErr = FlexCanReg_GetBit1FastError(obj->flexCanReg); + errSts->bit0FastErr = FlexCanReg_GetBit0FastError(obj->flexCanReg); + errSts->crcFastErr = FlexCanReg_GetCrcFastError(obj->flexCanReg); + errSts->formFastErr = FlexCanReg_GetFormFastError(obj->flexCanReg); + errSts->stuffFastErr = FlexCanReg_GetStuffFastError(obj->flexCanReg); +#endif +} + +void FlexCanDrv_EnterLowPwrMode(FlexCanDrvType *obj, FlexCanDrv_LowPwrModeType lowPwrMode) +{ + /* set FlexCan into low power mode in SIM */ + if(lowPwrMode == FLEXCANDRV_LOWPWRMODE_DOZE) + { + SimReg_SetCanIpgDoze(obj->simReg, 1); + } + else if(lowPwrMode == FLEXCANDRV_LOWPWRMODE_STOP) + { + SimReg_SetCanIpgStop(obj->simReg, 1); + } + else + { + } +} + +void FlexCanDrv_ExitLowPwrMode(FlexCanDrvType *obj, FlexCanDrv_LowPwrModeType lowPwrMode) +{ + /* Clear FlexCan into low power mode in SIM */ + if(lowPwrMode == FLEXCANDRV_LOWPWRMODE_DOZE) + { + SimReg_SetCanIpgDoze(obj->simReg, 0); + } + else if(lowPwrMode == FLEXCANDRV_LOWPWRMODE_STOP) + { + SimReg_SetCanIpgStop(obj->simReg, 0); + } + else + { + } +} + +uint8_t FlexCanDrv_AbortPendingTxMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj) +{ + uint32_t *msgBufPtr; + volatile uint32_t msgBufCode; + uint8_t ret; + + /* disable message buffer interrupt */ + FlexCanDrv_DisableMsgObjInterrupt(obj, msgObj); + + /* clear message buffer flag */ + FlexCanDrv_ClearMsgObjFlag(obj, msgObj); + + /* get current message buffer start address */ + msgBufPtr = (uint32_t *)FlexCanDrv_GetMsgBufStartAddr(obj, msgObj->msgBufId); + /* clear message buffer CS.CODE field */ + *msgBufPtr &= (~FLEXCANDRV_MSG_BUF_CODE_MASK << FLEXCANDRV_MSG_BUF_CODE_SHIFT); + /* set the message buffer code as TX ABORT */ + *msgBufPtr |= (((uint32_t)FLEXCANDRV_MSG_BUF_CODE_ABORT) << FLEXCANDRV_MSG_BUF_CODE_SHIFT); + + /* wait until message buffer flag assert */ + while(FlexCanDrv_GetMsgObjFlag(obj, msgObj) == 0) + { + } + + msgBufCode = (*msgBufPtr >> FLEXCANDRV_MSG_BUF_CODE_SHIFT) & FLEXCANDRV_MSG_BUF_CODE_MASK; + + /* check the tx pending message abort result */ + if(msgBufCode == FLEXCANDRV_MSG_BUF_CODE_ABORT) + { + ret = TX_PENDING_ABORT_SUCCESS; + } + else if(msgBufCode == FLEXCANDRV_MSG_BUF_CODE_TX_INACTIVE) + { + ret = TX_PENDING_ABORT_NO_TRANSFER; + } + else + { + ret = TX_PENDING_ABORT_FAILED; + } + + /* clear message buffer flag */ + FlexCanDrv_ClearMsgObjFlag(obj, msgObj); + + return ret; +} + +void FlexCanDrv_BitTimingCalc(FlexCanDrv_BitTimingType *bitTimingPara, + uint32_t moduleFreq, + uint32_t baudrate, + uint16_t samplePoint, + uint16_t sjw, + uint8_t isFd) +{ + int32_t maxPrescaler, maxTseg1, minTseg1, maxTseg2, maxNumTq, minNumTq; + int32_t tempPrescaler, tempSjw, tempTseg1, tempNumTq; + float bestErr = 0; + + /* set default best value for all bit timing parameters */ + int32_t bestPrescaler = 1, bestSjw = 1, bestNumTq = 8, bestTseg1 = 3, bestTseg2 = 2; + + /* set the optimal value for baudrate error, number of time quatna */ + const int32_t optNumTq = 20; + const float optBaudrateErr = 0.1; + const float optSamplePntToler = 0.25; + + /* set the maximum & minimum value for all bit timing parameters */ + if(isFd == false) + { + maxPrescaler = FLEXCAN_CBT_EPRESDIV_MASK >> FLEXCAN_CBT_EPRESDIV_SHIFT; + maxTseg1 = (FLEXCAN_CBT_EPROPSEG_MASK >> FLEXCAN_CBT_EPROPSEG_SHIFT) + (FLEXCAN_CBT_EPSEG1_MASK >> FLEXCAN_CBT_EPSEG1_SHIFT); + minTseg1 = 3; + maxTseg2 = FLEXCAN_CBT_EPSEG2_MASK >> FLEXCAN_CBT_EPSEG2_SHIFT; + + maxNumTq = maxTseg1 + maxTseg2 + 1; + minNumTq = 8; + } + else + { + maxPrescaler = FLEXCAN_FDCBT_FPRESDIV_MASK >> FLEXCAN_FDCBT_FPRESDIV_SHIFT; + maxTseg1 = (FLEXCAN_FDCBT_FPROPSEG_MASK >> FLEXCAN_FDCBT_FPROPSEG_SHIFT) + (FLEXCAN_FDCBT_FPSEG1_MASK >> FLEXCAN_FDCBT_FPSEG1_SHIFT); + minTseg1 = 3; + maxTseg2 = FLEXCAN_FDCBT_FPSEG2_MASK >> FLEXCAN_FDCBT_FPSEG2_SHIFT; + + maxNumTq = maxTseg1 + maxTseg2 + 1; + minNumTq = 8; + } + + /* calculate prescaler, number of Tq */ + bestErr = (float)baudrate; + for(tempPrescaler = 1; tempPrescaler <= maxPrescaler; tempPrescaler++) + { + /* get the quanta frequency */ + float Fq = (float)moduleFreq / tempPrescaler; + /* get the number of time quanta */ + tempNumTq = (int32_t)(Fq / baudrate); + + /* To avoid division by 0 and number of Tq less than minmum number of Tq */ + if((tempNumTq == 0) || (tempNumTq < minNumTq)) + { + break; + } + + /* calculate temp baudrate */ + float tempBaudrate = Fq / tempNumTq; + /* calculate temp baudrate error */ + float tempErr = ((tempBaudrate - baudrate) > 0) ? (tempBaudrate - baudrate) : (baudrate - tempBaudrate); + + if((tempNumTq <= maxNumTq) && (tempErr <= bestErr)) + { + /* set temporary prescaler, number of Tq, baudrate error as the best value */ + bestPrescaler = tempPrescaler; + bestNumTq = tempNumTq; + bestErr = tempErr; + + /* check if get the optimal condition */ + if((tempNumTq <= optNumTq) && tempErr < optBaudrateErr) + { + break; + } + } + } + + /* calculate sample point (time segment 1) */ + bestErr = samplePoint * optSamplePntToler; + + /* saturate max time segment 1 value */ + if(bestNumTq < maxTseg1) + { + maxTseg1 = bestNumTq; + } + for(tempTseg1 = maxTseg1; tempTseg1 >= minTseg1; tempTseg1--) + { + /* get the temporary sample point */ + int32_t tempSamplePnt = ((tempTseg1 + 1) * 10000) / bestNumTq; + /* get the temporary sample point error */ + int32_t tempErr = (tempSamplePnt - samplePoint) > 0 ? (tempSamplePnt - samplePoint) : (samplePoint - tempSamplePnt); + + /* break the for loop if the temporary sample point less + than the user required sample point */ + if(tempSamplePnt < samplePoint) + { + break; + } + + /* update the best T_seg1 and best error if met the tolerance */ + if(tempErr < bestErr) + { + bestTseg1 = tempTseg1; + bestErr = tempErr; + } + } + + /* calculate time segment 2 */ + bestTseg2 = bestNumTq - bestTseg1 - 1; + + /* calculate best SJW */ + bestErr = 10000; + for(tempSjw = 1; tempSjw <= bestTseg2; tempSjw++) + { + /* get the temporary synchronize jump width percentage */ + int32_t tempSjwPercent = (tempSjw * 10000) / bestNumTq; + int32_t tempErr = ((tempSjwPercent - sjw) > 0) ? (tempSjwPercent - sjw) : (sjw - tempSjwPercent); + + /* */ + if(tempErr < bestErr) + { + bestSjw = tempSjw; + bestErr = tempErr; + } + } + + bitTimingPara->prescalerDiv = bestPrescaler; + bitTimingPara->propSeg = (uint32_t)(bestTseg1 * 0.6); + bitTimingPara->phaseSeg1 = bestTseg1 - bitTimingPara->propSeg; + bitTimingPara->phaseSeg2 = bestTseg2; + bitTimingPara->resyncJumpWidth = bestSjw; +} + +void FlexCanDrv_SetRxFifoFlitElement(FlexCanDrvType *obj, uint8_t filtEleId, bool isExtId, uint32_t filtId) +{ + /* get the rx fifo filter format mode */ + FlexCanDrv_RxFifoFiltFormatType filtFormat = FlexCanReg_GetRxFifoFiltMode(obj->flexCanReg); + /* get the rx fifo filter table start address */ + uint32_t *rxFifoFiltTable = (uint32_t *)(((uint32_t)obj->flexCanReg) + RX_FIFO_FILT_TABLE_ADD_OFFSET); + uint32_t temp = 0; + uint8_t tempFiltEleId = 0; + uint8_t tempOffset = 0; + + + if(filtFormat == FLEXCANDRV_RXFIFO_FILTFORMAT_A) + { + /* clear the rx fifo filter element */ + rxFifoFiltTable[filtEleId] = 0; + /* set the rx fifo filter element bit 1 to 29 as filter ID */ + rxFifoFiltTable[filtEleId] |= filtId << (isExtId ? 1 : 19); + /* set the rx fifo filter element bit 30 as IDE */ + rxFifoFiltTable[filtEleId] |= ((uint32_t)isExtId) << 30; + } + else if (filtFormat == FLEXCANDRV_RXFIFO_FILTFORMAT_B) + { + /* get the filter element ID and offset counter based on 16-bit width */ + tempFiltEleId = filtEleId / 2; + tempOffset = (filtEleId % 2) * 16 ; + + /* get the existing value from the current two filter element */ + temp = rxFifoFiltTable[tempFiltEleId]; + /* clear the target filter element 16-bit */ + temp &= ~(0xFFFFUL << tempOffset); + + /* set the ID to the filter element */ + temp |= ((isExtId ? (filtId >> 15) : (filtId << 3)) << tempOffset); + /* set the IDE bit to the filter element */ + temp |= (((uint32_t)isExtId) << 14 << tempOffset); + + /* set the 16-bit value to the target filter element ID */ + rxFifoFiltTable[tempFiltEleId] = temp; + } + else if (filtFormat == FLEXCANDRV_RXFIFO_FILTFORMAT_C) + { + /* get the filter element ID and offset counter based on 8-bit width */ + tempFiltEleId = filtEleId / 4; + tempOffset = (filtEleId % 4) * 8 ; + + /* get the existing value from the current 4 filter element */ + temp = rxFifoFiltTable[tempFiltEleId]; + /* clear the target filter element 8-bit */ + temp &= ~(0xFFUL << tempOffset); + + /* set the first rx filter Id to rx fifo filter element */ + temp |= ((isExtId ? (filtId >> 21) : (filtId >> 3)) << tempOffset); + + /* set the 8-bit value to the target filter element ID */ + rxFifoFiltTable[tempFiltEleId] = temp; + } + else + { + + } +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/flexcan/flexcan_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/flexcan/flexcan_drv.h new file mode 100644 index 0000000..5acd91f --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/flexcan/flexcan_drv.h @@ -0,0 +1,536 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FLEXCAN_DRV_H_ +#define _FLEXCAN_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the FlexCAN (Flex Controller Area Network) module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup flexcan_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +/*! \brief Macro for select message buffer data size for CAN message buffer region + * + * The size of each message buffer data will affect the total message buffer number + */ +#define FLEXCANDRV_MB_SIZE_BYTE_8 (0) +#define FLEXCANDRV_MB_SIZE_BYTE_16 (1) +#define FLEXCANDRV_MB_SIZE_BYTE_32 (2) +#define FLEXCANDRV_MB_SIZE_BYTE_64 (3) + +/*! \brief Macro for message buffer code + * + * The code field was located in message buffer and can be accessed by CPU and by FlexCAN + * module as part of the message buffer matching and arbitration process. + */ +#define FLEXCANDRV_MSG_BUF_CODE_INACTIVE (0x0U) +#define FLEXCANDRV_MSG_BUF_CODE_RX_ACTIVE (0x4U) +#define FLEXCANDRV_MSG_BUF_CODE_TX_REQUEST (0xCU) +#define FLEXCANDRV_MSG_BUF_CODE_TX_INACTIVE (0x8U) +#define FLEXCANDRV_MSG_BUF_CODE_ABORT (0x9U) +#define FLEXCANDRV_MSG_BUF_CODE_MASK (0xFU) +#define FLEXCANDRV_MSG_BUF_CODE_SHIFT (24U) + +/*! \brief Macro for FlexCan access mode + * + * The access mode will affect the some of the FlexCan registers access permission + */ +#define FLEXCANDRV_CAN_ACCESS_MODE_USER (0) +#define FLEXCANDRV_CAN_ACCESS_MODE_SUP (1) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +/*! \brief type for data length code (DLC) + */ +typedef enum +{ + DLC_BYTE_0 = 0x00, /*!< 0 byte(s) data length code */ + DLC_BYTE_1 = 0x01, /*!< 1 byte(s) data length code */ + DLC_BYTE_2 = 0x02, /*!< 2 byte(s) data length code */ + DLC_BYTE_3 = 0x03, /*!< 3 byte(s) data length code */ + DLC_BYTE_4 = 0x04, /*!< 4 byte(s) data length code */ + DLC_BYTE_5 = 0x05, /*!< 5 byte(s) data length code */ + DLC_BYTE_6 = 0x06, /*!< 6 byte(s) data length code */ + DLC_BYTE_7 = 0x07, /*!< 7 byte(s) data length code */ + DLC_BYTE_8 = 0x08, /*!< 8 byte(s) data length code */ + DLC_BYTE_12 = 0x09, /*!< 12 byte(s) data length code */ + DLC_BYTE_16 = 0x0A, /*!< 16 byte(s) data length code */ + DLC_BYTE_20 = 0x0B, /*!< 20 byte(s) data length code */ + DLC_BYTE_24 = 0x0C, /*!< 24 byte(s) data length code */ + DLC_BYTE_32 = 0x0D, /*!< 32 byte(s) data length code */ + DLC_BYTE_48 = 0x0E, /*!< 48 byte(s) data length code */ + DLC_BYTE_64 = 0x0F /*!< 64 byte(s) data length code */ +} FlexCanDrv_DLCType; + +/*! \brief type for FlexCan clock source + */ +typedef enum +{ + FLEXCANDRV_CLKSRC_OSC = 0x00, /*!< oscillator clock source */ + FLEXCANDRV_CLKSRC_CHICLK = 0x01 /*!< peripherial clock source */ +} FlexCanDrv_ClkSrcType; + +/*! \brief type for FlexCan message type + */ +typedef enum +{ + FLEXCANDRV_MSGTYPE_TX, /*!< Tx message type */ + FLEXCANDRV_MSGTYPE_RX /*!< Rx message type */ +} FlexCanDrv_MsgType_t; + +/*! \brief type for FlexCan node state type + */ +typedef enum +{ + FLEXCANDRV_NODESTAT_IDLE, /*!< idle bus state */ + FLEXCANDRV_NODESTAT_RECEIVING, /*!< receving bus state */ + FLEXCANDRV_NODESTAT_TRANSMITTING, /*!< transmitting bus state*/ +} FlexCanDrv_NodeStatType; + +/*! \brief type for FlexCan fault confinment state type + */ +typedef enum +{ + FLEXCANDRV_FLTCONFSTS_ERRACTIVE = 0, /*!< error active state */ + FLEXCANDRV_FLTCONFSTS_ERRPASSIVE = 1, /*!< error passive state */ + FLEXCANDRV_FLTCONFSTS_BUSOFF = 2, /*!< bus off state */ +} FlexCanDrv_FltConfStsType; + +/*! \brief type for FlexCan low power mode + */ +typedef enum +{ + FLEXCANDRV_LOWPWRMODE_DOZE, /*!< Doze mode */ + FLEXCANDRV_LOWPWRMODE_STOP, /*!< Stop mode */ +} FlexCanDrv_LowPwrModeType; + +/*! \brief type for FlexCan Rx FIFO filer format */ +typedef enum +{ + FLEXCANDRV_RXFIFO_FILTFORMAT_A, /*!< Format A - One full ID (standard and extended) per ID Filter Table element */ + FLEXCANDRV_RXFIFO_FILTFORMAT_B, /*!< Format B - Two full standard IDs or two partial 14-bit (standard and extended) IDs per ID filter table element */ + FLEXCANDRV_RXFIFO_FILTFORMAT_C, /*!< Format C - Four partial 8-bit standard IDs per ID filter table element */ + FLEXCANDRV_RXFIFO_FILTFORMAT_D, /*!< Format D - All frames rejected */ +} FlexCanDrv_RxFifoFiltFormatType; + +/*! \brief FlexCan message configuration data structure + * + * This structure configures the static attributes for a generic CAN message + */ +typedef struct _FlexCanDrv_MsgCfgType_ +{ + uint16_t msgBufId; /*!< Message buffer index to handle this message object */ + uint16_t msgBufLen; /*!< Defines number of message buffer to handle this specific + message object configuration, if msgBufLen = 1, then only + single message buffer allocated to this message object, + which is also a common use case, if msgBuf > 1, then multiple + message buffer will allocated to this message object, which + will operating as a software message buffer with depth n */ + uint32_t msgId; /*!< Message ID can be either 11-bit or 29-bit depends on the + configuration of isExtMsgId */ + bool isExtMsgId; /*!< Select extended message ID (29-bit) or standard message + ID (11-bit) */ + FlexCanDrv_MsgType_t msgType; /*!< Select message type as Tx message or Rx message */ + FlexCanDrv_DLCType dlc; /*!< Message data length code */ + bool isFd; /*!< Select message as classic CAN message or flexible data rate + message */ + bool intEnable; /*!< Message Tx / Rx complete interrupt enable */ + uint32_t individualMask; /*!< Rx indivudual mask for mailbox n */ +} FlexCanDrv_MsgCfgType; + +/*! \brief FlexCan message object data structure + * + * This structure configures the dynamic attributes for a CAN message which can + * be varied at runtime + */ +typedef struct _FlexCanDrv_MsgObjType_ +{ + uint8_t msgBufId; /*!< Unique ID for message where it located in message buffer */ + uint32_t msgId; /*!< 11-bit or 29-bit message ID */ + uint8_t data[64]; /*!< Message data field. Maximum 64 bytes, the valid length was + determined by message DLC */ + uint8_t dlc; /*!< Message DLC get from the latest received message */ +} FlexCanDrv_MsgObjType; + +/*! \brief FlexCan bit timing configure data structure (CAN / CANFD) + * + * This structure configures the CAN / CANFD bit timing parameters + */ +typedef struct _FlexCanDrv_BitTimingType_ +{ + uint32_t prescalerDiv; /*!< Pre-scaler division factor, defines the ratio between CAN module + clock frequency and the serial clock frequency in the data bit + rate portion */ + uint32_t resyncJumpWidth; /*!< Re-sync jump width, the maximum number of time quanta that a bit + time can be changed by one re-synchronization */ + uint32_t propSeg; /*!< Propagation segment, defines the length of propagation segment in + the bit time */ + uint32_t phaseSeg1; /*!< Phase segment 1, defines the length of phase segment 1 in bit time */ + uint32_t phaseSeg2; /*!< Phase segment 2, defines the length of phase segment 2 in bit time */ +} FlexCanDrv_BitTimingType; + +typedef struct _FlexCanDrv_InitHwParType_ +{ + uint8_t canRamNum; /*!< CAN message buffer RAM number (each RAM block has 512 bytes) */ +} FlexCanDrv_InitHwParType; + +/*! \brief FlexCan controller (node) configuration data structure + * + * This structure configures static attributes for a FlexCAN controller + */ +typedef struct _FlexCanDrv_ControllerCfgType_ +{ + FlexCanDrv_ClkSrcType clkSrc; /*!< Select the clock source for CAN module */ + bool fdEnable; /*!< Flexible data rate enable */ + bool fdISOEnable; /*!< ISO CAN FD enable */ + bool fifoEnable; /*!< Rx FIFO enable */ + bool dmaEnable; /*!< Rx FIFO DMA enable */ + FlexCanDrv_BitTimingType bitTiming; /*!< nominal CAN bit timing struct */ + FlexCanDrv_BitTimingType fdBitTiming; /*!< FD CAN bit timing struct */ + uint8_t msgBufDataLenSel; /*!< Message buffer data size selection */ + uint32_t rxMBGlobalMask; /*!< Rx mailbox global mask */ + uint32_t rxMB14Mask; /*!< Rx mailbox 14 mask (only effect in global mask mode) */ + uint32_t rxMB15Mask; /*!< Rx mailbox 15 mask (only effect in global mask mode) */ + uint32_t rxFifoGlobalMask; /*!< Rx fifo global mask */ + FlexCanDrv_RxFifoFiltFormatType rxFifoFiltFormat; /*!< Rx fifo filter format */ + uint8_t rxFifoFilterNum; /*!< Rx fifo filter number code */ + uint8_t rxFifoIndivMskNum; /*!< Rx fifo individual mask valid number */ + uint32_t rxFifoIndivMsk[32]; /*!< Rx fifo individual mask arrary */ + bool individualMaskEnable; /*!< Rx individual mask enable */ + bool loopbackEnable; /*!< Loopback mode enable */ + bool tdcEnable; /*!< Transceiver delay compensation enable */ + uint8_t tdcOffset; /*!< Transceiver delay compensation offset */ + uint8_t msgNum; /*!< number of messages */ + const FlexCanDrv_MsgCfgType * msgCfg; /*!< message configuration array */ + bool edgeWkupEnable; /*!< CAN edge wakeup enable */ + bool txAbortEnable; /*!< Tx pending message abort mechanism enable */ + bool busoffIntEnable; /*!< Busoff interrupt enable */ + bool errorIntEnable; /*!< Error interrupt enable */ +} FlexCanDrv_ControllerCfgType; + +/*! \brief FlexCan error states data structure + * + * This structure indicating the error states for a FlexCAN controller + */ +typedef struct _FlexCanDrv_ErrStsType_ +{ + FlexCanDrv_FltConfStsType fltConfSts; /*!< fault confinement state */ + uint8_t bit1FastErr; /*!< bit 1 error in FD message data phase */ + uint8_t bit0FastErr; /*!< bit 0 error in FD message data phase */ + uint8_t crcFastErr; /*!< crc error in FD message data phase */ + uint8_t formFastErr; /*!< form error in FD message data phase */ + uint8_t stuffFastErr; /*!< stuff error in FD message data phase */ + uint8_t bit1Err; /*!< bit 1 error */ + uint8_t bit0Err; /*!< bit 0 error */ + uint8_t ackErr; /*!< acknowledgement error */ + uint8_t crcErr; /*!< crc error */ + uint8_t formErr; /*!< form error */ + uint8_t stuffErr; /*!< stuff error */ +} FlexCanDrv_ErrStsType; + +struct _FlexCanRegType_; + +typedef struct _FlexCanDrvType_ +{ + struct _FlexCanRegType_ *flexCanReg; + struct _Pcc1RegType_ *pcc1Reg; + struct _Pcc0RegType_ *pcc0Reg; + struct _Scg0RegType_ *scg0Reg; + struct _Scg2RegType_ *scg2Reg; + struct _SimRegType_ *simReg; + FlexCanDrv_InitHwParType initHwPar; +} FlexCanDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the flexCan driver module + * + * This function initializes flexCan driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to FlexCan driver instance + * \param[in] reg : pointer to FlexCan register instance + * \param[in] initHwPar: pointer to FlexCan hardware init parameter struct + */ +extern void FlexCanDrv_Init(FlexCanDrvType *obj, + struct _FlexCanRegType_ *flexCanReg, + struct _Pcc1RegType_ *pcc1Reg, + struct _Pcc0RegType_ *pcc0Reg, + struct _Scg0RegType_ *scg0Reg, + struct _Scg2RegType_ *scg2Reg, + struct _SimRegType_ *simReg, + FlexCanDrv_InitHwParType *initHwPar); +/*! \brief Soft reset FlexCAN module + * + * This function issues a softreset to FlexCAN module + * + * \param[in] obj : pointer to FlexCAN driver instance + */ +extern void FlexCanDrv_SoftReset(FlexCanDrvType *obj); + +/*! \brief Start FlexCAN module + * + * This function starts the specified FlexCAN device + * + * \param[in] obj : pointer to FlexCAN driver instance + */ +extern void FlexCanDrv_Start(FlexCanDrvType *obj); + +/*! \brief Configure and initialize FlexCAN controller from user configuration + * + * This function configure and initialize the FlexCAN controller from user + * configuration, it also init FlexCAN RAM area, disable FlexCAN RAM ECC feature + * and enable the entire FlexCAN module + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] controllerCfg : pointer to FlexCAN controller configuration structure + */ +extern void FlexCanDrv_Configure(FlexCanDrvType *obj, const FlexCanDrv_ControllerCfgType *controllerCfg); + +/*! \brief Configure message object and register the specified CAN message buffer + * + * This function configure and initialize the CAN message object for its' message ID + * direction, DLC, FD properties and message buffer interrupt enable. All the above + * configuration will be stored in the specified message buffer located in CAN RAM + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgCfg : pointer to message object configuration + * \param[in] msgBufId : message buffer index to store the message object + */ +extern void FlexCanDrv_CfgMsgObj(FlexCanDrvType *obj, const FlexCanDrv_MsgCfgType *msgCfg, uint8_t msgBufId); + +/*! \brief Transmit the message unconditionally once + * + * This function transmit message unconditionally once by the set the CODE in CS field, + * this operation shall be performed after message object initialized in message buffer + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgObj : message buffer object pointer + */ +extern void FlexCanDrv_TransmitMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj); + +/*! \brief Set the transmit message object into message buffer + * + * This function load the transmit message object into message buffer data field, the data byte order + * will be re-odered to adapt the message buffer data field format. The data length to load + * will retrieved from the DLC stored in the specified message buffer + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgObj : message buffer object pointer + */ +extern void FlexCanDrv_SetTxMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj); + +/*! \brief Get the message object from message buffer + * + * This function load the message buffer received data and DLC into message object data buffer. + * The data length to load will retrieved from the DLC stored in the specified message buffer + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgObj : message buffer object pointer + */ +extern void FlexCanDrv_GetRxMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj); + +/*! \brief Get the message object from Rx FIFO + * + * This function load the Rx FIFO received data and DLC into message object data buffer. + * The data length to load will retrieved from the DLC stored in the specified message buffer + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgObj : message buffer object pointer + */ +extern void FlexCanDrv_GetRxFifoMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj); + +/*! \brief Get message object flag, indicating a successful Rx / Tx operation completed + * + * This function returns the flag to indicating a successful Rx / Tx operation completed. + * A clear operation need to be done once the flag is asserted. + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgObj : message buffer object pointer + * \return message buffer Tx / Rx operation complete flag + * - 0: the corresponding buffer has no occurrence of successfully + * completed transmission or reception + * - 1: the corresponding buffer has successfully completed transmission + * or reception + */ +extern uint8_t FlexCanDrv_GetMsgObjFlag(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj); + +/*! \brief Get the message object from Rx FIFO + * + * This function load the Rx FIFO received data and DLC into message object data buffer. + * The data length to load will retrieved from the DLC stored in the specified message buffer + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgObj : message buffer object pointer + */ +extern void FlexCanDrv_GetRxFifoMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj); + +/*! \brief Clear message object flag + * + * This function clear the correspongding message object flag + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgObj : message buffer object pointer + */ +extern void FlexCanDrv_ClearMsgObjFlag(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj); + +/*! \brief Clear all message object flags + * + * This function clear all message object flags + * + * \param[in] obj : pointer to FlexCAN driver instance + */ +extern void FlexCanDrv_ClearAllMsgObjFlags(FlexCanDrvType *obj); + +/*! \brief Enable interrupt for the corresponding message buffer + * + * This function enable interrupt for the corresponding message buffer + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgObj : message buffer object pointer + */ +extern void FlexCanDrv_EnableMsgObjInterrupt(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj); + +/*! \brief Disable interrupt for the corresponding message buffer + * + * This function disable interrupt for the corresponding message buffer + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgObj : message buffer object pointer + */ +extern void FlexCanDrv_DisableMsgObjInterrupt(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj); + +/*! \brief Get the default FlexCan controller configuration parameters + * + * This function get the default FlexCan controller configuration parameters + * + * \param[in] controllerCfg : controller configure pointer + */ +extern void FlexCanDrv_GetDefaultCfg(FlexCanDrv_ControllerCfgType *controllerCfg); + +/*! \brief Calculate the CAN bit timing parameters + * + * This function calculate the CAN bit timing parameters for both classic and FD CAN + * + * \param[out] bitTimingPara : pointer to bit timing parameter group + * \param[in] clkFreq : FlexCan module frequency + * \param[in] samplePoint : Can bit sample point (0 - 10000 -> 0 - 100%) + * \param[in] sjw : Synchronize jump width (0 - 10000 -> 0 - 100%) + * \param[in] isFd : Is the bit timing parameter group for CAN-FD + */ +extern void FlexCanDrv_BitTimingCalc(FlexCanDrv_BitTimingType *bitTimingPara, + uint32_t clkFreq, + uint32_t baudrate, + uint16_t samplePoint, + uint16_t sjw, + uint8_t isFd); + +/*! \brief Get FlexCan error states + * + * This function get the FlexCan error states + * + * \param[in] obj : pointer to FlexCAN driver instance + * \return : node status + * + */ +FlexCanDrv_NodeStatType FlexCanDrv_GetNodeStatus(FlexCanDrvType *obj); + +/*! \brief Get FlexCan error states + * + * This function get the FlexCan error states + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[out] errSts: pointer to FlexCan error states + * + */ +void FlexCanDrv_GetErrorStates(FlexCanDrvType *obj, FlexCanDrv_ErrStsType *errSts); + +/*! \brief Enter FlexCan controller low power mode + * + * This function enter FlexCan controller low power mode + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] lowPwrMode: low power mode to be entered + * + */ +void FlexCanDrv_EnterLowPwrMode(FlexCanDrvType *obj, FlexCanDrv_LowPwrModeType lowPwrMode); + +/*! \brief Exit FlexCan controller low power mode + * + * This function exit FlexCan controller low power mode + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] lowPwrMode: low power mode to be exited + * + */ +void FlexCanDrv_ExitLowPwrMode(FlexCanDrvType *obj, FlexCanDrv_LowPwrModeType lowPwrMode); + +/*! \brief Abort pending Tx message + * + * This function abort the pending Tx message + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgObj: message buffer object pointer + * \return Pending Tx message abort result + * - 0: no Tx message transfer pending + * - 1: pending Tx message abort success + * + */ +extern uint8_t FlexCanDrv_AbortPendingTxMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj); + +/*! \brief Set Rx Fifo filter element + * + * This function set the fields of the rx fifo flter element according to the filter format configuration + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] filtEleId: rx fifo filter element ID, this ID calcualtion according to the filter format (32, 16, 8 bit) + * \param[in] isExtId: extended frame indicator + * \param[in] filtId: filter message ID + * + */ +extern void FlexCanDrv_SetRxFifoFlitElement(FlexCanDrvType *obj, uint8_t filtEleId, bool isExtId, uint32_t filtId); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* #ifndef _FLEXCAN_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/i2c/i2c_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/i2c/i2c_drv.c new file mode 100644 index 0000000..6f09502 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/i2c/i2c_drv.c @@ -0,0 +1,627 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/****************************************************************************** + * the includes + *****************************************************************************/ + +#include "i2c_drv.h" + +/****************************************************************************** + * the defines + *****************************************************************************/ + +#define I2CDRV_MILLI_RATE (1000ul) + +/****************************************************************************** + * the typedefs + *****************************************************************************/ + +/****************************************************************************** + * the globals + *****************************************************************************/ + +/****************************************************************************** + * the static function declarations + *****************************************************************************/ +static void I2cDrv_InitBasicParameters(I2cRegType *pReg, const I2cDrv_BasicParametersType *pBasicParameters); +static void I2cDrv_InitExtendParameters(I2cRegType *pReg, const I2cDrv_ExtendFeaturesType *pExtendFeatures, const I2cDrv_ExtendParametersType *pExtendParameters, uint32_t busClockFreq); + +/****************************************************************************** + * the functions + *****************************************************************************/ + +/*! \brief Config the basic parameter and features + * + * This function initialize the basic features with the parameters + * + * \param[in] pReg: pointer to I2C driver instance + * \param[in] pBasicParameters: the conbination of basic parameters + * \return: void + */ +static void I2cDrv_InitBasicParameters(I2cRegType *pReg, const I2cDrv_BasicParametersType *pBasicParameters) +{ + if(pBasicParameters->nodeMode == I2CDRV_NODE_MODE_AS_MASTER) + { + /* Node as Master */ + I2cReg_SetMasterMode(pReg, true); + + /* Set address mode: 7bits or 10bits */ + I2cReg_SetMasterAddressMode(pReg, pBasicParameters->addressMode); + + /* Set target address */ + I2cReg_SetTargetAddress(pReg, pBasicParameters->targetAddress); + + I2cReg_SetMasterRestartEnable(pReg, pBasicParameters->restartBitEn); + + I2cReg_SetSlaveModeDisable(pReg, true); + } + else + { + I2cReg_SetMasterMode(pReg, false); + + I2cReg_SetSlaveAddressMode(pReg, pBasicParameters->addressMode); + + I2cReg_SetSlaveAddress(pReg, pBasicParameters->ownAddress); + + I2cReg_SetSlaveModeDisable(pReg, false); + } + + I2cReg_SetSpeedMode(pReg, pBasicParameters->speedMode); + + if(pBasicParameters->speedMode == I2CDRV_SPEED_MODE_STANDARD_100KBIT) + { + if(pBasicParameters->sclFreq <= I2CDRV_STANDARDSPEED_UPPER_FREQ_VALUE) + { + uint16_t tCnt = 0; + + tCnt = (uint16_t)(pBasicParameters->busClockFreq / pBasicParameters->sclFreq); + + /* 50% + 50% */ + tCnt >>= 1; + + I2cReg_SetStandardModeHighLevelCount(pReg, tCnt); + + I2cReg_SetStandardModeLowLevelCount(pReg, tCnt); + } + } + else if(pBasicParameters->speedMode == I2CDRV_SPEED_MODE_FAST_400KBIT_1000KBIT) + { + if(pBasicParameters->sclFreq <= I2CDRV_FASTSPEED_UPPER_FREQ_VALUE) + { + uint16_t tCnt = 0; + + tCnt = (uint16_t)(pBasicParameters->busClockFreq / pBasicParameters->sclFreq); + + /* 50% + 50% */ + tCnt >>= 1; + + I2cReg_SetFastModeHighLevelCount(pReg, tCnt); + + I2cReg_SetFastModeLowLevelCount(pReg, tCnt); + } + } + else + { + /* Not support high-speed mode feature */ + } +} + +/*! \brief Config the module extend parameters and features + * + * This function initializes the extend features with the parameters + * + * \param[in] pReg: pointer to I2C driver instance + * \param[in] pExtendFeatures: the conbination of extend parameters + * \param[in] pExtendParameters: the conbination of extendFeatures + * \param[in] busClockFreq: the bus clock for i2c module + * \return: void + */ +static void I2cDrv_InitExtendParameters(I2cRegType *pReg, const I2cDrv_ExtendFeaturesType *pExtendFeatures, const I2cDrv_ExtendParametersType *pExtendParameters, uint32_t busClockFreq) +{ + if(pExtendFeatures->dmaRxEn == true) + { + I2cReg_SetDmaRxLevel(pReg, pExtendParameters->dmaRxDataLevel); + } + + I2cReg_SetRxDmaEnable(pReg, pExtendFeatures->dmaRxEn); + + if(pExtendFeatures->dmaTxEn == true) + { + I2cReg_SetDmaTxLevel(pReg, pExtendParameters->dmaTxDataLevel); + } + + I2cReg_SetTxDmaEnable(pReg, pExtendFeatures->dmaTxEn); + + /* Special cmd selection config */ + I2cReg_SetSpecialCommand(pReg, pExtendFeatures->specialCmdEn); + + if(pExtendFeatures->specialCmdEn == true) + { + I2cReg_SetSpecialCmdType(pReg, pExtendParameters->specialCmdType); + } + + I2cReg_SetAckForGeneralCall(pReg, pExtendFeatures->ackForGeneralCallEn); + + I2cReg_SetTxEmptyCtrl(pReg, pExtendParameters->txEmptyCtrl); + + { + /* Spike suppression */ + uint32_t tSpikCnt = 0; + + tSpikCnt = ((uint32_t)pExtendParameters->spikeSuppressionTime_ns / ((I2CDRV_MILLI_RATE * I2CDRV_MILLI_RATE) / (busClockFreq / I2CDRV_MILLI_RATE))); + I2cReg_SetSpikeLen(pReg, (tSpikCnt & 0xFF)); + } + + { + uint16_t tCnt = 0; + uint16_t tHighLevelCnt = 0; + uint16_t tLowLevelCnt = 0; + uint8_t tSpkLen = 0; + I2cDrv_SpeedModeType tSpeedMode; + + tSpeedMode = (I2cDrv_SpeedModeType)I2cReg_GetSpeedMode(pReg); + + tSpkLen = I2cReg_GetSpikeLen(pReg); + + if(tSpeedMode == I2CDRV_SPEED_MODE_STANDARD_100KBIT) + { + tHighLevelCnt = I2cReg_GetStandardModeHighLevelCount(pReg); + tLowLevelCnt = I2cReg_GetStandardModeLowLevelCount(pReg); + + /* modify the high counter, accord to the datasheet */ + if(tHighLevelCnt > (tSpkLen + 3u)) + { + I2cReg_SetStandardModeHighLevelCount(pReg, tHighLevelCnt - tSpkLen - 3u); + tHighLevelCnt = I2cReg_GetStandardModeHighLevelCount(pReg); + } + } + else if(tSpeedMode == I2CDRV_SPEED_MODE_FAST_400KBIT_1000KBIT) + { + tHighLevelCnt = I2cReg_GetFastModeHighLevelCount(pReg); + tLowLevelCnt = I2cReg_GetFastModeLowLevelCount(pReg); + + /* modify the high counter, accord to the datasheet */ + if(tHighLevelCnt > (tSpkLen + 3u)) + { + I2cReg_SetFastModeHighLevelCount(pReg, tHighLevelCnt - tSpkLen - 3u); + + tHighLevelCnt = I2cReg_GetFastModeHighLevelCount(pReg); + } + } + else + { + /* Not support high-speed mode */ + } + + if(I2cReg_GetModuleAsMaster(pReg) == true) + { + /* Rx Hold time */ + tCnt = (uint16_t)((uint32_t)pExtendParameters->rxHoldTime_ns / ((I2CDRV_MILLI_RATE * I2CDRV_MILLI_RATE) / (busClockFreq / I2CDRV_MILLI_RATE))); + if(tCnt <= (tHighLevelCnt - tSpkLen - 3u)) + { + I2cReg_SetRxDataHoldTime(pReg, tCnt); + } + + /* Tx Hold time */ + tCnt = (uint16_t)((uint32_t)pExtendParameters->txHoldTime_ns / ((I2CDRV_MILLI_RATE * I2CDRV_MILLI_RATE) / (busClockFreq / I2CDRV_MILLI_RATE))); + if(tCnt < (tLowLevelCnt - 2u)) + { + I2cReg_SetTxDataHoldTime(pReg, tCnt); + } + } + else + { + /* TODO: Rx Hold time, < tf (scl from high to low duration ) */ + tCnt = (uint16_t)((uint32_t)pExtendParameters->rxHoldTime_ns / ((I2CDRV_MILLI_RATE * I2CDRV_MILLI_RATE) / (busClockFreq / I2CDRV_MILLI_RATE))); + if(tCnt < (tHighLevelCnt - tSpkLen - 3u)) + { + I2cReg_SetRxDataHoldTime(pReg, tCnt); + } + + /* Tx Hold time */ + tCnt = (uint16_t)((uint32_t)pExtendParameters->txHoldTime_ns / ((I2CDRV_MILLI_RATE * I2CDRV_MILLI_RATE) / (busClockFreq / I2CDRV_MILLI_RATE))); + if((tCnt >= (tSpkLen + 7u)) && (tCnt < (tLowLevelCnt - 2u))) + { + I2cReg_SetTxDataHoldTime(pReg, tCnt); + } + else + { + I2cReg_SetTxDataHoldTime(pReg, (tSpkLen + 7u)); + } + + I2cReg_SetSlaveDetectStopBitMode(pReg, pExtendParameters->slaveDetectStopBitCondition); + } + } + + if(I2cReg_GetModuleAsMaster(pReg) == false) + { + uint16_t tCnt = 0; + + /* Data setup time,The IC_SDA_SETUP register is only used by the DW_apb_i2c when operating as a slave transmitter */ + tCnt = (uint16_t)((uint32_t)pExtendParameters->dataSetUpTime_ns / ((I2CDRV_MILLI_RATE * I2CDRV_MILLI_RATE) / (busClockFreq / I2CDRV_MILLI_RATE))); + + I2cReg_SetDataSetUpTime(pReg, (uint8_t)(tCnt + 1u)); + } +} + +/*! \brief Enable or Disable one or more than one interrupt source + * + * This function set the interrupt request action if condition matched + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] isrSrc :can used the more than one interrupt source once + * \param[in] isrEn :True(Enable) or false(Disable) + * \return: void + */ +void I2cDrv_SetInterruptReq(I2cDrvType *obj, uint32_t isrSrc, bool isrEn) +{ + if(isrSrc > I2CDRV_ISR_SRC_ALL) + { + return; + } + I2cReg_SetInterruptMask(obj->reg, isrSrc, isrEn); +} + +/*! \brief Clear one interrupt flag + * + * This function clear the interrupt flag if condition matched + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] isrSrc :can use one interrupt source once + * \return: void + */ +void I2cDrv_ClrInterruptFlag(I2cDrvType *obj, uint32_t isrSrc) +{ + if(isrSrc > I2CDRV_ISR_SRC_ALL) + { + return; + } + switch(isrSrc) + { + case I2CDRV_ISR_SRC_ALL: + I2cReg_ClearAllInterruptStatus(obj->reg); + break; + case I2CDRV_ISR_SRC_RX_UNDER: + I2cReg_ClearRxUnderStatus(obj->reg); + break; + case I2CDRV_ISR_SRC_RX_OVER: + I2cReg_ClearRxOverStatus(obj->reg); + break; + case I2CDRV_ISR_SRC_TX_OVER: + I2cReg_ClearTxOverStatus(obj->reg); + break; + case I2CDRV_ISR_SRC_RD_REQ: + I2cReg_ClearReadReqStatus(obj->reg); + break; + case I2CDRV_ISR_SRC_TX_ABRT: + I2cReg_ClearTxAbortStatus(obj->reg); + break; + case I2CDRV_ISR_SRC_RX_DONE: + I2cReg_ClearRxDoneStatus(obj->reg); + break; + case I2CDRV_ISR_SRC_ACTIVITY: + I2cReg_ClearActivityStatus(obj->reg); + break; + case I2CDRV_ISR_SRC_STOP_DET: + I2cReg_ClearStopBitDetectStatus(obj->reg); + break; + case I2CDRV_ISR_SRC_START_DET: + I2cReg_ClearStartBitDetectStatus(obj->reg); + break; + case I2CDRV_ISR_SRC_GEN_CALL: + I2cReg_ClearGeneralCallStatus(obj->reg); + break; + + default: + break; + } +} + +/*! \brief Get the current interrupt status + * + * This function get the current inyrttupy is enabled or disabled + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] isrSrc: Interrupt source + * \return: bool + * true: is enabled + * false: is disabled + */ +bool I2cDrv_GetInterruptIsEnabled(I2cDrvType *obj, I2cDrv_IsrSrcType isrSrc) +{ + return I2cReg_GetInterruptIsEnabled(obj->reg, isrSrc); +} + +/*! \brief Get I2C interrupt status + * + * this function get the special interrupt status + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] isrSrc: Interrupt source + * \return: bool + * 0h: inactive + * 1h: active + */ +bool I2cDrv_GetInterruptStatus(I2cDrvType *obj, I2cDrv_IsrSrcType isrSrc) +{ + return I2cReg_GetInterruptStatus(obj->reg, isrSrc); +} + +/*! \brief Get I2C raw interrupt status + * + * this function get the interrupt raw status + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] isrSrc: Interrupt source + * \return: bool + * 0h: inactive + * 1h: active + */ +bool I2cDrv_GetInterruptRawStatus(I2cDrvType *obj, I2cDrv_IsrSrcType isrSrc) +{ + return I2cReg_GetInterruptRawStatus(obj->reg, isrSrc); +} + +/*! \brief Contains the number of valid data entries in the receive FIFO. + * + * this function get the number of valid data entries in the receive FIFO. + * + * \param[in] obj :pointer to I2C driver instance + * \return: the number of valid data entries in the receive FIFO. + */ +uint8_t I2cDrv_GetRxFifoLevel(I2cDrvType *obj) +{ + return I2cReg_GetRxFifoLevel(obj->reg); +} + +/*! \brief Set RX FIFO threshold + * + * I2C RX FIFO threshold FIFO depth is 16 + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] rxFifoThreshold: RX FIFO threshold value + * \return: void + */ +void I2cDrv_SetRxFifoThreshold(I2cDrvType *obj, uint8_t rxFifoThreshold) +{ + I2cReg_SetRxFifoThreshold(obj->reg, rxFifoThreshold); +} + +/*! \brief Set TX FIFO threshold + * + * I2C TX FIFO threshold FIFO depth is 16 + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] txFifoThreshold: TX FIFO threshold value + * \return: void + */ +void I2cDrv_SetTxFifoThreshold(I2cDrvType *obj, uint8_t txFifoThreshold) +{ + I2cReg_SetTxFifoThreshold(obj->reg, txFifoThreshold); +} + +/*! \brief Get default configures the I2C module for configuration structure + * + * This function gets default configures the I2C module for user configuration structure + * + * \param[in] pInitCfg: pointer to configuration structure + * \return: void + */ +void I2cDrv_GetDefaultConfig(I2cDrv_InitCfgType *pInitCfg) +{ + pInitCfg->basicParameters.busClockFreq = 48000000ul; + pInitCfg->basicParameters.sclFreq = 20000; + pInitCfg->basicParameters.addressMode = I2CDRV_ADDR_MODE_7BIT; + pInitCfg->basicParameters.nodeMode = I2CDRV_NODE_MODE_AS_MASTER; + pInitCfg->basicParameters.ownAddress = 0x75; + pInitCfg->basicParameters.targetAddress = 0x28; + pInitCfg->basicParameters.restartBitEn = true; + pInitCfg->basicParameters.speedMode = I2CDRV_SPEED_MODE_STANDARD_100KBIT; + + pInitCfg->extendFeatures.dmaRxEn = false; + pInitCfg->extendFeatures.dmaTxEn = false; + pInitCfg->extendFeatures.ackForGeneralCallEn = false; + pInitCfg->extendFeatures.specialCmdEn = false; + + pInitCfg->extendParameters.spikeSuppressionTime_ns = 50; + pInitCfg->extendParameters.rxHoldTime_ns = 2; + pInitCfg->extendParameters.txHoldTime_ns = 100; + pInitCfg->extendParameters.dataSetUpTime_ns = 100; + pInitCfg->extendParameters.dmaTxDataLevel = 0; + pInitCfg->extendParameters.dmaRxDataLevel = 0; + pInitCfg->extendParameters.specialCmdType = I2CDRV_SPECIAL_CMD_GENERAL_CALL; + pInitCfg->extendParameters.slaveDetectStopBitCondition = I2CDRV_SLAVE_DETECT_STOPBIT_CONDITION_IN_ADDR_MATCH; + pInitCfg->extendParameters.txEmptyCtrl = I2CDRV_TX_EMPTY_AT_TXFIFO_LESSTHAN_TXTL; +} + +/*! \brief Set the module function with the configuration + * + * This function initializes the run-time state structure to provide for module configuration + * + * \param[in] obj : pointer to I2C driver instance + * \param[in] pInitCfg : point to the I2C initialize configuration + * \return: void + */ +void I2cDrv_SetConfig(I2cDrvType *obj, const I2cDrv_InitCfgType *pInitCfg) +{ + I2cReg_SetModuleEnable(obj->reg, false); + + /* Disable all interrupt req */ + I2cReg_SetInterruptMask(obj->reg, 0xFFFFFFFF, false); + + /* Clear all status that can be cleared by software except be cleared by hardware */ + I2cReg_ClearAllInterruptStatus(obj->reg); + + if(pInitCfg->basicParameters.nodeMode == I2CDRV_NODE_MODE_AS_SLAVE) + { + /* Disable slave mode */ + I2cReg_SetSlaveModeDisable(obj->reg, true); + } + + I2cDrv_InitBasicParameters(obj->reg, &pInitCfg->basicParameters); + + I2cDrv_InitExtendParameters(obj->reg, &pInitCfg->extendFeatures, &pInitCfg->extendParameters, pInitCfg->basicParameters.busClockFreq); + + I2cReg_SetModuleEnable(obj->reg, true); +} + +/*! \brief Resets the I2C internal logic and registers to their default settings + * + * This function initializes I2C driver by setting the register instance to it. + * + * \param[in] obj: pointer to I2C driver instance + * \param[in] pReg: pointer to I2C register instance + * \return: void + */ +void I2cDrv_Init(I2cDrvType *obj, I2cRegType *pReg) +{ + obj->reg = pReg; + + /* Disable module to make sure some register have been configurated successfully */ + I2cReg_SetModuleEnable(obj->reg, false); + + /* Clear all status that can be cleared by software except be cleared by hardware */ + I2cReg_ClearAllInterruptStatus(obj->reg); +} + +/*! \brief Deinit module into default state + * + * Call back in the usage of low power or sleep requirements + * + * \param[in] obj: pointer to I2C driver instance + * \return: void + */ +void I2cDrv_DeInit(I2cDrvType *obj) +{ + /* Disable module to make sure some register have been configurated successfully */ + I2cReg_SetModuleEnable(obj->reg, false); +} + +/*! \brief transmit data to other node + * + * This function request data to be sent + * + * \param[in] obj: pointer to I2C driver instance + * \param[in] pTxBuf: the pointer tx data + * \param[in] txBytesNum: how many bytes to be sent + * \return: bool + * true: request successful + * false: no enouth space for the current tx request + */ +bool I2cDrv_RequestWriteData(I2cDrvType *obj, const uint8_t *pTxBuf, uint8_t txBytesNum) +{ + bool tRtn = true; + + uint8_t i = 0; + + if((I2CDRV_TX_FIFO_DEPTH - I2cReg_GetTxFifoLevel(obj->reg)) >= txBytesNum) + { + for(i = 0; i < txBytesNum; i++) + { + I2cReg_SetDataAndCmd(obj->reg, pTxBuf[i], false); + } + } + else + { + tRtn = false; + } + + return tRtn; +} + +/*! \brief Receive data from other node + * + * This function request to received data + * + * \param[in] obj: pointer to I2C driver instance + * \param[in] rxBytesNum: how many bytes to be read out + * \return: void + */ +bool I2cDrv_RequestReadData(I2cDrvType *obj, uint8_t rxBytesNum) +{ + bool tRtn = true; + uint8_t i = 0; + + if((I2CDRV_TX_FIFO_DEPTH - I2cReg_GetTxFifoLevel(obj->reg)) >= rxBytesNum) + { + for(i = 0; i < rxBytesNum; i++) + { + I2cReg_SetDataAndCmd(obj->reg, 0u, true); + } + } + else + { + tRtn = false; + } + + return tRtn; +} + +/*! \brief Read received data from rx fifo + * + * This function read data from rx fifo + * + * \param[in] obj: pointer to I2C driver instance + * \param[in] pRxBuf : the space for read-out data + * \return: return how many bytes are received + */ +uint8_t I2cDrv_GetReceivedData(const I2cDrvType *obj, uint8_t *pRxBuf) +{ + uint8_t tRxBytesNum = 0, i = 0; + + tRxBytesNum = I2cReg_GetRxFifoLevel(obj->reg); + + if(tRxBytesNum > 0u) + { + for(i = 0; i < tRxBytesNum; i++) + { + pRxBuf[i] = I2cReg_GetData(obj->reg); + } + } + + return tRxBytesNum; +} + +/*! \brief Master request to abort current transfer + * + * This function request to abort the current transfer process + * + * \param[in] obj: pointer to I2C driver instance + * \return: void + */ +void I2cDrv_MasterAbortTransfer(I2cDrvType *obj) +{ + if(I2cReg_GetDmaTxIsEnabled(obj->reg) == true) + { + I2cReg_SetTxDmaEnable(obj->reg, false); + } + + /* TODO: Generate an interrupt event after abort operation? */ + I2cReg_SetInterruptMask(obj->reg, I2C_INTR_MASK_TX_ABRT_MASK, false); + + I2cReg_SetAbortReq(obj->reg); + + /* Wait tx abort status set to 1 */ + while(I2cReg_GetInterruptRawStatus(obj->reg, I2C_INTR_STAT_TX_ABRT_MASK) == false) + { + } + + /* Check the current abort request is from master request */ + if(I2cReg_GetTxAbortInfo(obj->reg, I2C_TX_ABRT_SOURCE_ABRT_USER_ABRT_MASK) == true) + { + } +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/i2c/i2c_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/i2c/i2c_drv.h new file mode 100644 index 0000000..53fb061 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/i2c/i2c_drv.h @@ -0,0 +1,352 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _I2C_DRV_H +#define _I2C_DRV_H + +/*! \brief Contains public interface to various functions related + * to the driver of I2C module + */ + +/****************************************************************************** + * the includes + *****************************************************************************/ + +#include +#include +#include "i2c_reg.h" + +/*! \addtogroup i2c_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * the defines + *****************************************************************************/ +#define I2CDRV_STANDARDSPEED_UPPER_FREQ_VALUE (100000ul) /* Hz */ +#define I2CDRV_FASTSPEED_UPPER_FREQ_VALUE (1000000ul) /* Hz */ + +#define I2CDRV_TX_FIFO_DEPTH (16u) +#define I2CDRV_RX_FIFO_DEPTH (16u) + +/****************************************************************************** + * the typedefs + *****************************************************************************/ +/*! \brief I2C node cosplayer */ +typedef enum +{ + I2CDRV_NODE_MODE_AS_SLAVE = 0u, + I2CDRV_NODE_MODE_AS_MASTER +} I2cDrv_NodeModeType; + +/*! \brief I2C address bit type */ +typedef enum +{ + I2CDRV_ADDR_MODE_7BIT = 0u, + I2CDRV_ADDR_MODE_10BIT +} I2cDrv_AddressModeType; + +/*! \brief I2C speed mode selection */ +typedef enum +{ + I2CDRV_SPEED_MODE_STANDARD_100KBIT = 1u, + I2CDRV_SPEED_MODE_FAST_400KBIT_1000KBIT, + I2CDRV_SPEED_MODE_HIGH /* Not support in the current IP */ +} I2cDrv_SpeedModeType; + +/*! \brief I2C APB data width type */ +typedef enum +{ + I2CDRV_APB_DATA_WIDTH_8BIT = 0u, + I2CDRV_APB_DATA_WIDTH_16BIT, + I2CDRV_APB_DATA_WIDTH_32BIT +} I2cDrv_ApbDataWidthType; + +/*! \brief I2C special command selection */ +typedef enum +{ + I2CDRV_SPECIAL_CMD_GENERAL_CALL = 0u, + I2CDRV_SPECIAL_CMD_START_BYTE +} I2cDrv_SpecialCmdType; + +/*! \brief I2C detect stop bit condition */ +typedef enum +{ + I2CDRV_SLAVE_DETECT_STOPBIT_CONDITION_IN_ANYTIME = 0u, + I2CDRV_SLAVE_DETECT_STOPBIT_CONDITION_IN_ADDR_MATCH +} I2cDrv_SlaveDetectStopBitConditionType; + +/*! \brief I2C tx empty control selection */ +typedef enum +{ + I2CDRV_TX_EMPTY_AT_TXFIFO_LESSTHAN_TXTL = 0u, + I2CDRV_TX_EMPTY_AT_LAST_DATA_TRANSFERED +} I2cDrv_TxEmptyCtrlType; + +/*! \brief Interrupt source */ +typedef enum +{ + I2CDRV_ISR_SRC_RX_UNDER = I2C_INTR_STAT_RX_UNDER_MASK, + I2CDRV_ISR_SRC_RX_OVER = I2C_INTR_STAT_RX_OVER_MASK, + I2CDRV_ISR_SRC_RX_FULL = I2C_INTR_STAT_RX_FULL_MASK, + I2CDRV_ISR_SRC_TX_OVER = I2C_INTR_STAT_TX_OVER_MASK, + I2CDRV_ISR_SRC_TX_EMPTY = I2C_INTR_STAT_TX_EMPTY_MASK, + I2CDRV_ISR_SRC_RD_REQ = I2C_INTR_STAT_RD_REQ_MASK, + I2CDRV_ISR_SRC_TX_ABRT = I2C_INTR_STAT_TX_ABRT_MASK, + I2CDRV_ISR_SRC_RX_DONE = I2C_INTR_STAT_RX_DONE_MASK, + I2CDRV_ISR_SRC_ACTIVITY = I2C_INTR_STAT_ACTIVITY_MASK, + I2CDRV_ISR_SRC_STOP_DET = I2C_INTR_STAT_STOP_DET_MASK, + I2CDRV_ISR_SRC_START_DET = I2C_INTR_STAT_START_DET_MASK, + I2CDRV_ISR_SRC_GEN_CALL = I2C_INTR_STAT_GEN_CALL_MASK, + I2CDRV_ISR_SRC_ALL = 0XFFF +} I2cDrv_IsrSrcType; + +/*! \brief I2C basic parameter information */ +typedef struct _I2cDrv_BasicParametersType_ +{ + uint32_t busClockFreq; + uint32_t sclFreq; + I2cDrv_NodeModeType nodeMode; + uint16_t ownAddress; + uint16_t targetAddress; + I2cDrv_AddressModeType addressMode; + bool restartBitEn; + I2cDrv_SpeedModeType speedMode; +} I2cDrv_BasicParametersType; + +/*! \brief I2C extend parameter information */ +typedef struct _I2cDrv_ExtendParametersType_ +{ + uint16_t spikeSuppressionTime_ns; + uint16_t rxHoldTime_ns; + uint16_t txHoldTime_ns; + uint16_t dataSetUpTime_ns; + uint8_t dmaTxDataLevel; + uint8_t dmaRxDataLevel; + I2cDrv_SpecialCmdType specialCmdType; + I2cDrv_SlaveDetectStopBitConditionType slaveDetectStopBitCondition; + I2cDrv_TxEmptyCtrlType txEmptyCtrl; +} I2cDrv_ExtendParametersType; + +/*! \brief I2C extend feature information */ +typedef struct _I2cDrv_ExtendFeaturesType_ +{ + bool dmaTxEn; + bool dmaRxEn; + bool ackForGeneralCallEn; + bool specialCmdEn; +} I2cDrv_ExtendFeaturesType; + +/*! \brief I2C initialize configuration information */ +typedef struct _I2cDrv_InitCfgType_ +{ + I2cDrv_BasicParametersType basicParameters; + I2cDrv_ExtendParametersType extendParameters; + I2cDrv_ExtendFeaturesType extendFeatures; +} I2cDrv_InitCfgType; + +/*! \brief I2C instance pointer */ +typedef struct _I2cDrvType_ +{ + I2cRegType *reg; +} I2cDrvType; + +/****************************************************************************** + * the globals + *****************************************************************************/ + +/****************************************************************************** + * the function prototypes + *****************************************************************************/ + +/*! \brief Get default configures the I2C module for configuration structure + * + * Note: This function gets default configures the I2C module for user configuration structure + * + * \param[in] pInitCfg: pointer to configuration structure + * \return: void + */ +extern void I2cDrv_GetDefaultConfig(I2cDrv_InitCfgType *pInitCfg); + +/*! \brief Set the module function with the configuration + * + * Note: This function initializes the run-time state structure to provide for module configuration + * + * \param[in] obj : pointer to I2C driver instance + * \param[in] pInitCfg : point to the I2C initialize configuration + * \return: void + */ +extern void I2cDrv_SetConfig(I2cDrvType *obj, const I2cDrv_InitCfgType *pInitCfg); + +/*! \brief Resets the I2C internal logic and registers to their default settings + * + * Note: This function initializes I2C driver by setting the register instance to it. + * + * \param[in] obj: pointer to I2C driver instance + * \param[in] pReg: pointer to I2C register instance + * \return: void + */ +extern void I2cDrv_Init(I2cDrvType *obj, I2cRegType *pReg); + +/*! \brief Deinit module into default state + * + * Note: Call back in the usage of low power or sleep requirements + * + * \param[in] obj: pointer to I2C driver instance + * \return: void + */ +extern void I2cDrv_DeInit(I2cDrvType *obj); + +/*! \brief Enable or Disable one or more than one interrupt source + * + * This function set the interrupt request action if condition matched + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] isrSrc :can used the more than one interrupt source once + * \param[in] isrEn :True(Enable) or false(Disable) + * \return: void + */ +extern void I2cDrv_SetInterruptReq(I2cDrvType *obj, uint32_t isrSrc, bool isrEn); + +/*! \brief Clear one interrupt flag + * + * This function clear the interrupt flag if condition matched + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] isrSrc :can use one interrupt source once + * \return: void + */ +extern void I2cDrv_ClrInterruptFlag(I2cDrvType *obj, uint32_t isrSrc); + +/*! \brief Get the current interrupt status + * + * This function get the current inyrttupy is enabled or disabled + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] interruptSource: Interrupt source + * \return: bool + * true: is enabled + * false: is disabled + */ +bool I2cDrv_GetInterruptIsEnabled(I2cDrvType *obj, I2cDrv_IsrSrcType interruptSource); + +/*! \brief Get I2C interrupt status + * + * this function get the special interrupt status + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] interruptSource: Interrupt source + * \return: bool + * 0h: inactive + * 1h: active + */ +bool I2cDrv_GetInterruptStatus(I2cDrvType *obj, I2cDrv_IsrSrcType interruptSource); + +/*! \brief Get I2C raw interrupt status + * + * this function get the interrupt raw status + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] isrSrc: Interrupt source + * \return: bool + * 0h: inactive + * 1h: active + */ +bool I2cDrv_GetInterruptRawStatus(I2cDrvType *obj, I2cDrv_IsrSrcType isrSrc); + +/*! \brief Contains the number of valid data entries in the receive FIFO. + * + * this function get the number of valid data entries in the receive FIFO. + * + * \param[in] obj :pointer to I2C driver instance + * \return: the number of valid data entries in the receive FIFO. + */ +uint8_t I2cDrv_GetRxFifoLevel(I2cDrvType *obj); + +/*! \brief Set RX FIFO threshold + * + * I2C RX FIFO threshold FIFO depth is 16 + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] rxFifoThreshold: RX FIFO threshold value + * \return: void + */ +void I2cDrv_SetRxFifoThreshold(I2cDrvType *obj, uint8_t rxFifoThreshold); + +/*! \brief Set TX FIFO threshold + * + * I2C TX FIFO threshold FIFO depth is 16 + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] txFifoThreshold: TX FIFO threshold value + * \return: void + */ +void I2cDrv_SetTxFifoThreshold(I2cDrvType *obj, uint8_t txFifoThreshold); + +/*! \brief transmit data to other node + * + * Note: This function request data to be sent + * + * \param[in] obj: pointer to I2C driver instance + * \param[in] pTxBuf: the pointer tx data + * \param[in] txBytesNum: how many bytes to be sent + * \return: bool + * true: request successful + * false: no enouth space for the current tx request + */ +extern bool I2cDrv_RequestWriteData(I2cDrvType *obj, const uint8_t *pTxBuf, uint8_t txBytesNum); + +/*! \brief Receive data from other node + * + * Note: This function request to received data + * + * \param[in] obj: pointer to I2C driver instance + * \param[in] pRxBuf: the read-out data to be filled in + * \param[in] rxBytesNum: how many bytes to be read out + * \return: void + */ +extern bool I2cDrv_RequestReadData(I2cDrvType *obj, uint8_t rxBytesNum); + +/*! \brief Read received data from rx fifo + * + * Note: This function read data from rx fifo + * + * \param[in] obj: pointer to I2C driver instance + * \param[in] pRxBuf : the space for read-out data + * \return: return how many bytes are received + */ +extern uint8_t I2cDrv_GetReceivedData(const I2cDrvType *obj, uint8_t *pRxBuf); + +/*! \brief Master request to abort current transfer + * + * Note: This function request to abort the current transfer process + * + * \param[in] obj: pointer to I2C driver instance + * \return: void + */ +extern void I2cDrv_MasterAbortTransfer(I2cDrvType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _I2C_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/i2sm/i2sm_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/i2sm/i2sm_drv.c new file mode 100644 index 0000000..4a05df1 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/i2sm/i2sm_drv.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "sim_reg.h" +#include "i2sm_drv.h" +#include "i2sm_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +void I2smDrv_Init(I2smDrvType *obj, struct _I2smRegType_ *reg1, struct _SimRegType_ *reg2) +{ + obj->regI2sm = reg1; + obj->regSim = reg2; +} + +void I2smDrv_GetDefaultConfig(I2smDrv_ConfigType *userConfig) +{ + userConfig->txFifoTriggerLevel = 3; + userConfig->wsCycle = I2SMDRV_CLOCK_CYCLES_32; + userConfig->sclkGateCycle = I2SMDRV_NO_CLOCK_GATE; + userConfig->dataResolution = I2SMDRV_RESOLUTION_32; + userConfig->txFifoEmptyIntMask = 1; + userConfig->txFifoOverrunIntMask = 1; +} + +void I2smDrv_Config(I2smDrvType *obj, const I2smDrv_ConfigType *userConfig) +{ + /* select I2S as master mode */ + SimReg_SetI2sMode(obj->regSim, 1); + /* enable I2S module */ + I2smReg_SetIerEn(obj->regI2sm, 1); + /* set FIFO threshold */ + I2smReg_SetTfcr0Tfcr0(obj->regI2sm, userConfig->txFifoTriggerLevel); + /* set ws cycle */ + I2smReg_SetCcrWss(obj->regI2sm, userConfig->wsCycle); + /* set clock gate cycle */ + I2smReg_SetCcrSclkg(obj->regI2sm, userConfig->sclkGateCycle); + /* set data resolution */ + I2smReg_SetTcr0TxWLen(obj->regI2sm, userConfig->dataResolution); + /* config interrupt mask for fifo empty */ + I2smReg_SetImr0TxFem(obj->regI2sm, userConfig->txFifoEmptyIntMask); + /* config interrupt mask for fifo overrun */ + I2smReg_SetImr0TxFom(obj->regI2sm, userConfig->txFifoOverrunIntMask); + /* enable tx block */ + I2smReg_SetIterTxEn(obj->regI2sm, 1); + /* enable tx channel0 */ + I2smReg_SetTer0TxChEn0(obj->regI2sm, 1); +} + +void I2smDrv_FillFifoByDma(I2smDrvType *obj, uint32_t *data, uint8_t len) +{ + for(uint8_t i = 0; i < len; i++) + { + I2smReg_SetTxDmaTxDma(obj->regI2sm, data[i]); + } +} + +void I2smDrv_FillFifoByBuffer(I2smDrvType *obj, uint32_t *data, uint8_t len) +{ + for(uint8_t i = 0; i < len; i += 2) + { + I2smReg_SetLthr0Lthr0(obj->regI2sm, data[i]); + I2smReg_SetRthr0Rthr0(obj->regI2sm, data[i + 1]); + } +} + +void I2smDrv_StartTransmit(I2smDrvType *obj) +{ + /* enable the clock */ + I2smReg_SetCerClkEn(obj->regI2sm, 1); +} + +void I2smDrv_StopTransmit(I2smDrvType *obj) +{ + /* disable the clock */ + I2smReg_SetCerClkEn(obj->regI2sm, 0); +} + +void I2smDrv_FlushTxFifo(I2smDrvType *obj) +{ + /* flush tx fifo 0 */ + I2smReg_SetTff0TxChfr0(obj->regI2sm, 1); +} + +bool I2smDrv_GetFifoOverrunFlag(I2smDrvType *obj) +{ + bool flag = 0; + flag = I2smReg_GetIsr0TxFO(obj->regI2sm); + return flag; +} + +bool I2smDrv_GetFifoLevelTrigFlag(I2smDrvType *obj) +{ + bool flag = 0; + flag = I2smReg_GetIsr0TxFE(obj->regI2sm); + return flag; +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/i2sm/i2sm_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/i2sm/i2sm_drv.h new file mode 100644 index 0000000..287036f --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/i2sm/i2sm_drv.h @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _I2SM_DRV_H_ +#define _I2SM_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of I2SM (I2S Master) + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup i2sm_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +#define TX_FIFO_DEPTH (16U) /*!< the tx fifo depth */ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +typedef enum +{ + I2SMDRV_CLOCK_CYCLES_16 = 0x0U, /*!< word select line stays 16 sclk cycles for left or right sample */ + I2SMDRV_CLOCK_CYCLES_24 = 0x1U, /*!< word select line stays 24 sclk cycles for left or right sample */ + I2SMDRV_CLOCK_CYCLES_32 = 0x2U /*!< word select line stays 32 sclk cycles for left or right sample */ +} I2smDrvWssType; + +typedef enum +{ + I2SMDRV_NO_CLOCK_GATE = 0x0U, /*!< clock gate is disabled */ + I2SMDRV_CLOCK_GATE_12 = 0x1U, /*!< clock gate is setting at 12 cycles */ + I2SMDRV_CLOCK_GATE_16 = 0x2U, /*!< clock gate is setting at 16 cycles */ + I2SMDRV_CLOCK_GATE_20 = 0x3U, /*!< clock gate is setting at 20 cycles */ + I2SMDRV_CLOCK_GATE_24 = 0x4U /*!< clock gate is setting at 24 cycles */ +} I2smDrvSclkGateType; + +typedef enum +{ + I2SMDRV_IGNORE_WORD_LEN = 0x0U, /*!< Ignore the word length */ + I2SMDRV_RESOLUTION_12 = 0x1U, /*!< data resolution is 12 bits */ + I2SMDRV_RESOLUTION_16 = 0x2U, /*!< data resolution is 16 bits */ + I2SMDRV_RESOLUTION_20 = 0x3U, /*!< data resolution is 20 bits */ + I2SMDRV_RESOLUTION_24 = 0x4U, /*!< data resolution is 24 bits */ + I2SMDRV_RESOLUTION_32 = 0x5U /*!< data resolution is 32 bits */ +} I2smDrvDataResolutionType; + +/*! \brief The definition of I2SM driver class + */ +typedef struct _I2smDrvType_ +{ + struct _I2smRegType_ *regI2sm; + struct _SimRegType_ *regSim; +} I2smDrvType; + +typedef struct _I2smDrv_ConfigType_ +{ + I2smDrvWssType wsCycle; /*!< number of clk cyles for ws line in left or right sample mode */ + I2smDrvSclkGateType sclkGateCycle; /*!< clock gate of the sclk */ + I2smDrvDataResolutionType dataResolution; /*!< data resolution of the transmitter */ + uint8_t txFifoTriggerLevel; /*!< the threshold level of the tx fifo trigger */ + bool txFifoEmptyIntMask; /*!< TXFE interrupt mask */ + bool txFifoOverrunIntMask; /*!< TXFO interrupt mask */ +} I2smDrv_ConfigType; +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the I2SM reg + * + * + * \param[in] obj : pointer to I2SM driver instance + * \param[in] reg1 : pointer to I2SM register instance + * \param[in] reg2 : pointer to SIM register instance + */ +extern void I2smDrv_Init(I2smDrvType *obj, struct _I2smRegType_ *reg1, struct _SimRegType_ *reg2); + +/*! \brief Get default configures the I2SM module for configuration structure + * + * + * \param[in] userConfig : pointer to user config sturcture + */ +extern void I2smDrv_GetDefaultConfig(I2smDrv_ConfigType *userConfig); + +/*! \brief config the I2SM module as userConfig + * + * + * \param[in] obj : pointer to I2SM driver instance + * \param[in] userConfig : pointer to user config sturcture + */ +extern void I2smDrv_Config(I2smDrvType *obj, const I2smDrv_ConfigType *userConfig); + +/*! \brief fill the tx FIFO via DMA + * + * + * \param[in] obj : pointer to I2SM driver instance + * \param[in] data : pointer to user data + * \param[in] len : the data length to transfer + */ +extern void I2smDrv_FillFifoByDma(I2smDrvType *obj, uint32_t *data, uint8_t len); + +/*! \brief fill the tx FIFO via buffer + * + * + * \param[in] obj : pointer to I2SM driver instance + * \param[in] data : pointer to user data + * \param[in] len : the data length to transfer + */ +extern void I2smDrv_FillFifoByBuffer(I2smDrvType *obj, uint32_t *data, uint8_t len); + +/*! \brief start transmit data + * + * + * \param[in] obj : pointer to I2SM driver instance + */ +extern void I2smDrv_StartTransmit(I2smDrvType *obj); + +/*! \brief stop transmit data + * + * + * \param[in] obj : pointer to I2SM driver instance + */ +extern void I2smDrv_StopTransmit(I2smDrvType *obj); + +/*! \brief flush the tx fifo + * + * + * \param[in] obj : pointer to I2SM driver instance + */ +extern void I2smDrv_FlushTxFifo(I2smDrvType *obj); + +/*! \brief get the status flag of fifo overrun + * + * + * \param[in] obj : pointer to I2SM driver instance + * \param[out] bool : flag status + * - false : not overrun + * - true : overrun + */ +extern bool I2smDrv_GetFifoOverrunFlag(I2smDrvType *obj); + +/*! \brief get the status flag of fifo level trig + * + * + * \param[in] obj : pointer to I2SM driver instance + * \param[out] bool : flag status + * - false : not reach the trig level + * - true : reach the trig level + */ +extern bool I2smDrv_GetFifoLevelTrigFlag(I2smDrvType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _I2SM_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/i2ss/i2ss_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/i2ss/i2ss_drv.c new file mode 100644 index 0000000..f5c8cfd --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/i2ss/i2ss_drv.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ +#include "sim_reg.h" +#include "i2ss_drv.h" +#include "i2ss_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +void I2ssDrv_Init(I2ssDrvType *obj, struct _I2ssRegType_ *reg1, struct _SimRegType_ *reg2) +{ + obj->regI2ss = reg1; + obj->regSim = reg2; +} + +void I2ssDrv_GetDefaultConfig(I2ssDrv_ConfigType *userConfig) +{ + userConfig->rxFifoTriggerLevel = 3; + userConfig->rxFifoEmptyIntMask = 1; + userConfig->rxFifoOverrunIntMask = 1; +} + +void I2ssDrv_Config(I2ssDrvType *obj, const I2ssDrv_ConfigType *userConfig) +{ + /* select I2S as master mode */ + SimReg_SetI2sMode(obj->regSim, 0); + /* enable I2S module */ + I2ssReg_SetIerEn(obj->regI2ss, 1); + /* set FIFO threshold */ + I2ssReg_SetRff0RxChfr0(obj->regI2ss, userConfig->rxFifoTriggerLevel); + /* config interrupt mask for fifo empty */ + I2ssReg_SetImr0RxDam(obj->regI2ss, userConfig->rxFifoEmptyIntMask); + /* config interrupt mask for fifo overrun */ + I2ssReg_SetImr0RxFom(obj->regI2ss, userConfig->rxFifoOverrunIntMask); + /* enable rx block */ + I2ssReg_SetIrerRxEn(obj->regI2ss, 1); + /* enable rx channel0 */ + I2ssReg_SetRer0Ch0(obj->regI2ss, 1); +} + +void I2ssDrv_ReadFifoByDma(I2ssDrvType *obj, uint32_t *data, uint8_t len) +{ + for(uint8_t i = 0; i < len; i++) + { + data[i] = I2ssReg_GetRxDmaRxDma(obj->regI2ss); + } +} + +void I2ssDrv_ReadFifoByBuffer(I2ssDrvType *obj, uint32_t *data, uint8_t len) +{ + for(uint8_t i = 0; i < len; i += 2) + { + data[i] = I2ssReg_GetLrbr0Lrbr0(obj->regI2ss); + data[i + 1] = I2ssReg_GetRrbr0Rrbr0(obj->regI2ss); + } +} + +void I2ssDrv_FlushRxFifo(I2ssDrvType *obj) +{ + /* flush rx fifo 0 */ + I2ssReg_SetRff0RxChfr0(obj->regI2ss, 1); +} + +bool I2ssDrv_GetFifoOverrunFlag(I2ssDrvType *obj) +{ + bool flag = 0; + flag = I2ssReg_GetIsr0RxFo(obj->regI2ss); + return flag; +} + +bool I2ssDrv_GetFifoLevelTrigFlag(I2ssDrvType *obj) +{ + bool flag = 0; + flag = I2ssReg_GetIsr0RxDa(obj->regI2ss); + return flag; +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/i2ss/i2ss_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/i2ss/i2ss_drv.h new file mode 100644 index 0000000..a1d179a --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/i2ss/i2ss_drv.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _I2SS_DRV_H_ +#define _I2SS_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of I2SS (I2S Slave) + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup i2ss_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +#define RX_FIFO_DEPTH (16U) /*!< the rx fifo depth */ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +typedef enum +{ + I2SSDRV_IGNORE_WORD_LEN = 0x0U, /*!< Ignore the word length */ + I2SSDRV_RESOLUTION_12 = 0x1U, /*!< data resolution is 12 bits */ + I2SSDRV_RESOLUTION_16 = 0x2U, /*!< data resolution is 16 bits */ + I2SSDRV_RESOLUTION_20 = 0x3U, /*!< data resolution is 20 bits */ + I2SSDRV_RESOLUTION_24 = 0x4U, /*!< data resolution is 24 bits */ + I2SSDRV_RESOLUTION_32 = 0x5U /*!< data resolution is 32 bits */ +} I2ssDrvDataResolutionType; + +/*! \brief The definition of I2SS driver class + */ +typedef struct _I2ssDrvType_ +{ + struct _I2ssRegType_ *regI2ss; + struct _SimRegType_ *regSim; +} I2ssDrvType; + +typedef struct _I2ssDrv_ConfigType_ +{ + I2ssDrvDataResolutionType dataResolution; /*!< data resolution of the receiver */ + uint8_t rxFifoTriggerLevel; /*!< the threshold level of the rx fifo trigger */ + bool rxFifoEmptyIntMask; /*!< RXFE interrupt mask */ + bool rxFifoOverrunIntMask; /*!< RXFO interrupt mask */ +} I2ssDrv_ConfigType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the I2SS reg + * + * + * \param[in] obj : pointer to I2SS driver instance + * \param[in] reg1 : pointer to I2SS register instance + * \param[in] reg2 : pointer to SIM register instance + */ +extern void I2ssDrv_Init(I2ssDrvType *obj, struct _I2ssRegType_ *reg1, struct _SimRegType_ *reg2); + +/*! \brief Get default configures the I2SS module for configuration structure + * + * + * \param[in] userConfig : pointer to user config sturcture + */ +extern void I2ssDrv_GetDefaultConfig(I2ssDrv_ConfigType *userConfig); + +/*! \brief config the I2SS module as userConfig + * + * + * \param[in] obj : pointer to I2SS driver instance + * \param[in] userConfig : pointer to user config sturcture + */ +extern void I2ssDrv_Config(I2ssDrvType *obj, const I2ssDrv_ConfigType *userConfig); + +/*! \brief read data from rx FIFO via DMA + * + * + * \param[in] obj : pointer to I2SS driver instance + * \param[in] data : pointer to user data + * \param[in] len : the data length to transfer + */ +extern void I2ssDrv_ReadFifoByDma(I2ssDrvType *obj, uint32_t *data, uint8_t len); + +/*! \brief read data from rx FIFO via buffer + * + * + * \param[in] obj : pointer to I2SS driver instance + * \param[in] data : pointer to user data + * \param[in] len : the data length to transfer + */ +extern void I2ssDrv_ReadFifoByBuffer(I2ssDrvType *obj, uint32_t *data, uint8_t len); + +/*! \brief flush the rx fifo + * + * + * \param[in] obj : pointer to I2SS driver instance + */ +extern void I2ssDrv_FlushRxFifo(I2ssDrvType *obj); + +/*! \brief get the status flag of fifo overrun + * + * + * \param[in] obj : pointer to I2SS driver instance + * \param[out] bool : flag status + * - false : not overrun + * - true : overrun + */ +extern bool I2ssDrv_GetFifoOverrunFlag(I2ssDrvType *obj); + +/*! \brief get the status flag of fifo level trig + * + * + * \param[in] obj : pointer to I2SS driver instance + * \param[out] bool : flag status + * - false : not reach the trig level + * - true : reach the trig level + */ +extern bool I2ssDrv_GetFifoLevelTrigFlag(I2ssDrvType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _I2SS_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/lpit/lpit_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/lpit/lpit_drv.c new file mode 100644 index 0000000..af11313 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/lpit/lpit_drv.c @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "lpit_drv.h" +#include "lpit_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* Max period in count of all operation mode except for dual 16 bit periodic counter mode */ +#define MAX_PERIOD_COUNT (0xFFFFFFFFU) + +/* Max period in count of dual 16 bit periodic counter mode */ +#define MAX_PERIOD_COUNT_IN_DUAL_16BIT_MODE (0x1FFFEU) + +/* Max count of 16 bit */ +#define MAX_PERIOD_COUNT_16_BIT (0xFFFFU) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void LpitDrv_Init(LpitDrvType *obj, struct _LpitRegType_ *reg) +{ + obj->reg = reg; +} + +void LpitDrv_GetDefaultConfig(LpitDrv_ConfigType *userConfig) +{ + userConfig->enableRunInDebug = false; + userConfig->enableRunInLowPower = false; +} + +void LpitDrv_Configure(LpitDrvType *obj, const LpitDrv_ConfigType *userConfig) +{ + /* Enables functional clock of LPIT module*/ + LpitReg_Enable(obj->reg); + /* Sets LPIT operation in Debug and LowPower mode*/ + LpitReg_SetDebugModeCmd(obj->reg, userConfig->enableRunInDebug ? 1 : 0); + LpitReg_SetLpModeCmd(obj->reg, userConfig->enableRunInLowPower ? 1 : 0); +} + +void LpitDrv_GetDefaultChannelConfig(LpitDrv_ChannelConfigType *userChannelConfig) +{ + userChannelConfig->timerMode = LPITDRV_PERIODIC_COUNTER; + userChannelConfig->period = 1000000U; + userChannelConfig->triggerSource = LPITDRV_TRIGGERSOURCE_EXTERNAL; + userChannelConfig->triggerSelect = 0U; + userChannelConfig->enableReloadOnTrigger = false; + userChannelConfig->enableStopOnInterrupt = false; + userChannelConfig->enableStartOnTrigger = false; + userChannelConfig->chainChannel = false; + userChannelConfig->isInterruptEnabled = true; +} + +bool LpitDrv_ConfigureChannel(LpitDrvType *obj, uint8_t channel, const LpitDrv_ChannelConfigType *userChannelConfig) +{ + /* Checks channel range */ + if(channel >= LPIT_TMR_COUNT) + { + return false; + } + + /* Setups the timer channel chaining */ + LpitReg_SetTimerChannelChainCmd(obj->reg, channel, (uint8_t)userChannelConfig->chainChannel); + /* Setups the timer channel operation mode */ + LpitReg_SetTimerChannelModeCmd(obj->reg, channel, (uint8_t)userChannelConfig->timerMode); + + /* Setups timer channel period in count unit */ + LpitReg_SetTimerPeriodByCount(obj->reg, channel, userChannelConfig->period); + + /* Setups the timer channel trigger source, trigger select, reload on trigger, + stop on timeout, start on trigger and channel chaining */ + LpitReg_SetTriggerSourceCmd(obj->reg, channel, userChannelConfig->triggerSource); + LpitReg_SetTriggerSelectCmd(obj->reg, channel, userChannelConfig->triggerSelect); + LpitReg_SetReloadOnTriggerCmd(obj->reg, channel, userChannelConfig->enableReloadOnTrigger ? 1 : 0); + LpitReg_SetStopOnInterruptCmd(obj->reg, channel, userChannelConfig->enableStopOnInterrupt ? 1 : 0); + LpitReg_SetStartOnTriggerCmd(obj->reg, channel, userChannelConfig->enableStartOnTrigger ? 1 : 0); + /* Setups interrupt generation for timer channel */ + if(userChannelConfig->isInterruptEnabled) + { + /* Enables interrupt generation */ + LpitReg_EnableInterruptTimerChannels(obj->reg, (uint32_t)1U << channel); + } + else + { + /* Disables interrupt generation */ + LpitReg_DisableInterruptTimerChannels(obj->reg, (uint32_t)1U << channel); + } + + return true; +} + +void LpitDrv_StartTimerChannels(LpitDrvType *obj, uint32_t mask) +{ + /* Checks the mask range */ + if(mask >= (1UL << LPIT_TMR_COUNT)) + { + return; + } + /* Start timer channels */ + LpitReg_StartTimerChannels(obj->reg, mask); +} + +void LpitDrv_StopTimerChannels(LpitDrvType *obj, uint32_t mask) +{ + /* Checks the mask range */ + if(mask >= (1UL << LPIT_TMR_COUNT)) + { + return; + } + /* Stop timer channels */ + LpitReg_StopTimerChannels(obj->reg, mask); +} + +void LpitDrv_SetTimerPeriodByCount(LpitDrvType *obj, uint8_t channel, uint32_t count) +{ + /* Checks the channel range */ + if(channel >= LPIT_TMR_COUNT) + { + return; + } + + LpitReg_SetTimerPeriodByCount(obj->reg, channel, count); +} + +void LpitDrv_SetTimerPeriodInDual16ModeByCount(LpitDrvType *obj, uint8_t channel, uint16_t periodHigh, uint16_t periodLow) +{ + /* Checks the channel range */ + if(channel >= LPIT_TMR_COUNT) + { + return; + } + + uint32_t period = ((uint32_t)periodHigh << 16U) | periodLow; + /* Sets the timer channel period in count unit */ + LpitReg_SetTimerPeriodByCount(obj->reg, channel, period); +} + +bool LpitDrv_GetTimerPeriodByCount(const LpitDrvType *obj, uint8_t channel, uint32_t *period) +{ + /* Checks the channel range */ + if(channel >= LPIT_TMR_COUNT) + { + return false; + } + + /* Gets current timer channel period by count.*/ + uint32_t currentPeriod = LpitReg_GetTimerPeriodByCount(obj->reg, channel); + /* Gets current timer channel operation mode */ + if(LpitReg_GetTimerChannelModeCmd(obj->reg, channel) == LPITDRV_DUAL_PERIODIC_COUNTER) + { + /* Calculates the period for dual 16 bit periodic counter mode */ + currentPeriod = (currentPeriod >> 16U) + (currentPeriod & MAX_PERIOD_COUNT_16_BIT); + } + + *period = currentPeriod; + return true; +} + +bool LpitDrv_GetCurrentTimerCount(const LpitDrvType *obj, uint8_t channel, uint32_t *time) +{ + /* Checks the channel range */ + if(channel >= LPIT_TMR_COUNT) + { + return false; + } + + /* Gets current timer channel counting value */ + uint32_t currentTime = LpitReg_GetCurrentTimerCount(obj->reg, channel); + /* Gets current timer channel operation mode */ + if(LpitReg_GetTimerChannelModeCmd(obj->reg, channel) == LPITDRV_DUAL_PERIODIC_COUNTER) + { + /* Calculates the current counting value for dual 16 bit periodic counter mode */ + currentTime = (currentTime >> 16U) + (currentTime & MAX_PERIOD_COUNT_16_BIT); + } + *time = currentTime; + return true; +} + +void LpitDrv_EnableTimerChannelInterrupt(LpitDrvType *obj, uint32_t mask) +{ + /* Checks the mask range */ + if(mask >= (1UL << LPIT_TMR_COUNT)) + { + return; + } + /* Enable interrupt of timer channels */ + LpitReg_EnableInterruptTimerChannels(obj->reg, mask); +} + +void LpitDrv_DisableTimerChannelInterrupt(LpitDrvType *obj, uint32_t mask) +{ + /* Checks the mask range */ + if(mask >= (1UL << LPIT_TMR_COUNT)) + { + return; + } + /* Enable interrupt of timer channels */ + LpitReg_DisableInterruptTimerChannels(obj->reg, mask); +} + +uint32_t LpitDrv_GetInterruptFlagTimerChannels(const LpitDrvType *obj, uint32_t mask) +{ + /* Checks the mask range */ + if(mask >= (1UL << LPIT_TMR_COUNT)) + { + return 0; + } + /* Gets the interrupt flag for timer channels */ + return LpitReg_GetInterruptFlag(obj->reg, mask); +} + +void LpitDrv_ClearInterruptFlagTimerChannels(LpitDrvType *obj, uint32_t mask) +{ + /* Checks the mask range */ + if(mask >= (1UL << LPIT_TMR_COUNT)) + { + return; + } + /* Clears the interrupt flag for timer channels */ + LpitReg_ClearInterruptFlag(obj->reg, mask); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/lpit/lpit_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/lpit/lpit_drv.h new file mode 100644 index 0000000..14eb324 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/lpit/lpit_drv.h @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _LPIT_DRV_H_ +#define _LPIT_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of LPIT (Low Power Interrupt Timer) + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Definition of mode options available for the LPIT timer + */ +typedef enum +{ + LPITDRV_PERIODIC_COUNTER = 0x00U, /*!< 32-bit Periodic Counter */ + LPITDRV_DUAL_PERIODIC_COUNTER = 0x01U, /*!< Dual 16-bit Periodic Counter */ + LPITDRV_TRIGGER_ACCUMULATOR = 0x02U, /*!< 32-bit Trigger Accumulator */ + LPITDRV_INPUT_CAPTURE = 0x03U /*!< 32-bit Trigger Input Capture */ +} LpitDrv_TimerModesType; + +/*! \brief Definition of trigger source options. + */ +typedef enum +{ + LPITDRV_TRIGGERSOURCE_EXTERNAL = 0x00U, /*!< Use external trigger */ + LPITDRV_TRIGGERSOURCE_INTERNAL = 0x01U /*!< Use internal trigger */ +} LpitDrv_TriggerSourceType; + +/*! \brief Definition of configuration of LPIT timer channel + */ +typedef struct _LpitDrv_ChannelConfigType_ +{ + LpitDrv_TimerModesType timerMode; /*!< Operation mode of timer channel */ + uint32_t period; /*!< Period of timer channel */ + LpitDrv_TriggerSourceType triggerSource; /*!< Selects between internal and external trigger sources */ + uint32_t triggerSelect; /*!< Selects one trigger from the internal trigger sources + this field makes sense if trigger source is internal */ + bool enableReloadOnTrigger; /*!< True: Timer channel will reload on selected trigger + False: Timer channel will not reload on selected trigger */ + bool enableStopOnInterrupt; /*!< True: Timer will stop after timeout + False: Timer channel does not stop after timeout */ + bool enableStartOnTrigger; /*!< True: Timer channel starts to decrement when rising edge + on selected trigger is detected. + False: Timer starts to decrement immediately based on + restart condition */ + bool chainChannel; /*!< Channel chaining enable */ + bool isInterruptEnabled; /*!< Timer channel interrupt generation enable */ +} LpitDrv_ChannelConfigType; + +/*! \brief Definition of configuration of LPIT driver + */ +typedef struct _LpitDrv_ConfigType_ +{ + bool enableRunInDebug; /*!< True: Timer channels continue to run in debug mode + False: Timer channels stop in debug mode */ + bool enableRunInLowPower; /*!< True: Timer channels continue to run in low power mode + False: Timer channels stop in low power mode */ +} LpitDrv_ConfigType; + +/* Forward declaration of LPIT register */ +struct _LpitRegType_; + +/*! \brief The definition of LPIT driver class + */ +typedef struct _LpitDrvType_ +{ + struct _LpitRegType_ *reg; +} LpitDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the LPIT driver module + * + * This function initializes LPIT driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] reg : pointer to LPIT register instance + */ +extern void LpitDrv_Init(LpitDrvType *obj, struct _LpitRegType_ *reg); + +/*! \brief Get default configures the LPIT module for configuration structure + * + * This function gets default configures the LPIT module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void LpitDrv_GetDefaultConfig(LpitDrv_ConfigType *userConfig); + +/*! \brief Configures the LPIT module from a user configuration structure + * + * This function resets LPIT module, enables the LPIT module, configures LPIT + * module operation in Debug and LowPower mode. The LPIT configuration structure shall + * be passed as arguments. + * This configuration structure affects all timer channels. + * This function should be called before calling any other LPIT driver function. + * + * This is an example demonstrating how to define a LPIT configuration structure: + \code + LpitDrv_ConfigType lpitConfig = + { + .enableRunInDebug = false, + .enableRunInLowPower = true + }; + \endcode + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void LpitDrv_Configure(LpitDrvType *obj, const LpitDrv_ConfigType *userConfig); + +/*! \brief Gets the default timer channel configuration + * + * This function gets the default timer channel configuration structure, with the following settings: + * - Timer mode: 32-bit Periodic Counter + * - Period: 1000000 + * - Trigger sources: External trigger + * - Trigger select: Trigger from channel 0 + * - Reload on trigger: Disable + * - Stop on interrupt : Disable + * - Start on trigger: Disable + * - Channel chaining: Disable + * - Interrupt generating: Enable + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userChannelConfig : pointer to channel configuration structure + */ +extern void LpitDrv_GetDefaultChannelConfig(LpitDrv_ChannelConfigType *userChannelConfig); + +/*! \brief Initializes the LPIT channel. + * + * This function initializes the LPIT timers by using a channel, this function + * configures timer channel chaining, timer channel mode, timer channel period, + * interrupt generation, trigger source, trigger select, reload on trigger, + * stop on interrupt and start on trigger. + * The timer channel number and its configuration structure shall be passed as arguments. + * Timer channels do not start counting by default after calling this function. + * + * The function 'StartTimerChannels' must be called to start the timer channel counting. + * In order to re-configures the period, call the 'SetTimerPeriodByCount'. + * + * This is an example demonstrating how to define a LPIT channel configuration structure: + \code + LpitDrv_ChannelConfigType lpitInitConfig = + { + .timerMode = LPITDRV_PERIODIC_COUNTER, + .period = 1000000U, + .triggerSource = LPITDRV_TRIGGERSOURCE_INTERNAL, + .triggerSelect = 1U, + .enableReloadOnTrigger = false, + .enableStopOnInterrupt = false, + .enableStartOnTrigger = false, + .chainChannel = false, + .isInterruptEnabled = true + }; + \endcode + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] channel : timer channel number + * \param[in] userChannelConfig : pointer to configuration structure + * \return The result of configuring channel + * - false : failed + * - true : success + */ +extern bool LpitDrv_ConfigureChannel(LpitDrvType *obj, uint8_t channel, const LpitDrv_ChannelConfigType *userChannelConfig); + +/*! \brief Starts the timer channel counting. + * + * This function allows starting timer channels simultaneously . + * After calling this function, timer channels are going operate depend on mode and + * control bits which controls timer channel start, reload and restart. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] mask : timer channels starting mask that decides which channels will be started + * For example: + * - with mask = 0x01U then channel 0 will be started + * - with mask = 0x02U then channel 1 will be started + * - with mask = 0x03U then channel 0 and channel 1 will be started + */ +extern void LpitDrv_StartTimerChannels(LpitDrvType *obj, uint32_t mask); + +/*! \brief Stops the timer channel counting. + * + * This function allows stop timer channels simultaneously from counting. + * Timer channels reload their periods respectively after the next time + * they call the LPIT_DRV_StartTimerChannels. Note that: In 32-bit Trigger Accumulator + * mode, the counter will load on the first trigger rising edge. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] mask : timer channels stopping mask that decides which channels will be stopped + * For example: + * - with mask = 0x01U then channel 0 will be stopped + * - with mask = 0x02U then channel 1 will be stopped + * - with mask = 0x03U then channel 0 and channel 1 will be stopped + */ +extern void LpitDrv_StopTimerChannels(LpitDrvType *obj, uint32_t mask); + +/*! \brief Sets the timer channel period in count unit. + * + * This function sets the timer channel period in count unit. + * The counter period of a running timer channel can be modified by first setting + * a new load value, the value will be loaded after the timer channel expires. + * To abort the current cycle and start a timer channel period with the new value, + * the timer channel must be disabled and enabled again. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] channel : timer channel number + * \param[in] count : timer channel period in count unit + */ +extern void LpitDrv_SetTimerPeriodByCount(LpitDrvType *obj, uint8_t channel, uint32_t count); + +/*! \brief Sets the timer channel period in count unit. + * + * This function sets the timer channel period in count unit when timer channel + * mode is dual 16 periodic counter mode. + * The counter period of a running timer channel can be modified by first setting + * a new load value, the value will be loaded after the timer channel expires. + * To abort the current cycle and start a timer channel period with the new value, + * the timer channel must be disabled and enabled again. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] channel : timer channel number + * \param[in] periodHigh : period of higher 16 bit in count unit + * \param[in] periodLow : period of lower 16 bit in count unit + */ +extern void LpitDrv_SetTimerPeriodInDual16ModeByCount(LpitDrvType *obj, uint8_t channel, uint16_t periodHigh, uint16_t periodLow); + +/*! \brief Gets the current timer channel period in count unit. + * + * This function returns current period of timer channel given as argument. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] channel : timer channel number + * \param[out] period : pointer to the timer channel period in count unit + * \return the result of getting period + * - false : failed + * - true : success + */ +extern bool LpitDrv_GetTimerPeriodByCount(const LpitDrvType *obj, uint8_t channel, uint32_t *period); + +/*! \brief Gets the current timer channel counting value in count. + * + * This function returns the real-time timer channel counting value, the value in + * a range from 0 to timer channel period. + * Need to make sure the running time does not exceed the timer channel period. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] channel : timer channel number + * \param[out] time : current timer channel counting value in count + * \return the result of getting counting value + * - false : failed + * - true : success + */ +extern bool LpitDrv_GetCurrentTimerCount(const LpitDrvType *obj, uint8_t channel, uint32_t *time); + +/*! \brief Enables the interrupt generation of timer channel. + * + * This function allows enabling interrupt generation of timer channel + * when timeout occurs or input trigger occurs. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] mask : the mask that decides which channels will be enabled interrupt. + * For example: + * - with mask = 0x01u then the interrupt of channel 0 will be enabled + * - with mask = 0x02u then the interrupt of channel 1 will be enabled + * - with mask = 0x03u then the interrupt of channel 0 and channel 1 will be enabled + */ +extern void LpitDrv_EnableTimerChannelInterrupt(LpitDrvType *obj, uint32_t mask); + +/*! \brief Disables the interrupt generation of timer channel. + * + * This function allows disabling interrupt generation of timer channel + * when timeout occurs or input trigger occurs. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] mask : the mask that decides which channels will be disable interrupt. + * For example: + * - with mask = 0x01u then the interrupt of channel 0 will be disable + * - with mask = 0x02u then the interrupt of channel 1 will be disable + * - with mask = 0x03u then the interrupt of channel 0 and channel 1 will be disable + */ +extern void LpitDrv_DisableTimerChannelInterrupt(LpitDrvType *obj, uint32_t mask); + +/*! \brief Gets the current interrupt flag of timer channels. + * + * This function gets the current interrupt flag of timer channels. + * In compare modes, the flag sets to 1 at the end of the timer period. + * In capture modes, the flag sets to 1 when the trigger asserts. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] mask : the interrupt flag getting mask that decides which channels will be got interrupt flag. + * For example: + * - with mask = 0x01u then the interrupt flag of channel 0 only will be got + * - with mask = 0x02u then the interrupt flag of channel 1 only will be got + * - with mask = 0x03u then the interrupt flags of channel 0 and channel 1 will be got + * \return current interrupt flag of timer channels + * \note return 0 if mask is invalid + */ +extern uint32_t LpitDrv_GetInterruptFlagTimerChannels(const LpitDrvType *obj, uint32_t mask); + +/*! \brief Clears the interrupt flag of timer channels. + * + * This function clears the interrupt flag of timer channels after + * their interrupt event occurred. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] mask : the interrupt flag clearing mask that decides which channels will be cleared interrupt flag + * For example: + * - with mask = 0x01u then the interrupt flag of channel 0 only will be cleared + * - with mask = 0x02u then the interrupt flag of channel 1 only will be cleared + * - with mask = 0x03u then the interrupt flags of channel 0 and channel 1 will be cleared + */ +extern void LpitDrv_ClearInterruptFlagTimerChannels(LpitDrvType *obj, uint32_t mask); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _LPIT_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/lptmr/lptmr_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/lptmr/lptmr_drv.c new file mode 100644 index 0000000..f9a1d46 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/lptmr/lptmr_drv.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "lptmr_drv.h" +#include "lptmr_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void LptmrDrv_Init(LptmrDrvType *obj, struct _LptmrRegType_ *reg) +{ + obj->reg = reg; +} + +void LptmrDrv_GetConfigure(LptmrDrvType *obj, LptmrDrv_ConfigType *userConfig) +{ + /* Get the work mode of LPTMR */ + userConfig->workMode = (LptmrDrv_WorkModeType)LptmrReg_GetWorkMode(obj->reg); + /* Get the Free Running state */ + userConfig->freeRun = LptmrReg_GetFreeRunning(obj->reg); + /* Get Pin Polarity for Pulse Counter Mode */ + userConfig->pinPolarity = (LptmrDrv_PinPolarityType)LptmrReg_GetPinPolarity(obj->reg); + /* Get the Pin selection for Pulse Counter Mode */ + userConfig->pinSelect = (LptmrDrv_PinSelectType)LptmrReg_GetPinSelect(obj->reg); + /* Get the Interrupt Enable state */ + userConfig->interruptEnable = LptmrReg_GetInterruptEnable(obj->reg); + /* Get the DMA Request Enable Flag state */ + userConfig->dmaRequest = LptmrReg_GetDmaRequest(obj->reg); + /* Get the Prescaler/Glitch Filter Bypass enable state */ + userConfig->bypassPrescaler = LptmrReg_GetBypass(obj->reg); + /* Get the Prescaler/Glitch Filter divider value */ + userConfig->prescaler = (LptmrDrv_PrescaleType)LptmrReg_GetPrescaler(obj->reg); + /* Get the Prescaler/Glitch Filter Bypass enable state */ + userConfig->compareValue = LptmrReg_GetCompareValue(obj->reg); +} + +void LptmrDrv_GetDefaultConfig(LptmrDrv_ConfigType *userConfig) +{ + /* General parameters */ + userConfig->dmaRequest = false; + userConfig->interruptEnable = false; + userConfig->freeRun = false; + userConfig->workMode = LPTMRDRV_WORKMODE_TIMER; + + /* Counter parameters */ + userConfig->prescaler = LPTMRDRV_PRESCALE_2; + userConfig->bypassPrescaler = false; + userConfig->compareValue = 0u; + + /* Pulse Counter specific parameters */ + userConfig->pinSelect = LPTMRDRV_PINSELECT_INPUT0; + userConfig->pinPolarity = LPTMRDRV_PINPOLARITY_RISING; +} + +void LptmrDrv_Configure(LptmrDrvType *obj, const LptmrDrv_ConfigType *userConfig) +{ + /* Disable LPTMR before configure */ + LptmrReg_SetEnable(obj->reg, false); + /* Set the work mode of LPTMR */ + LptmrReg_SetWorkMode(obj->reg, (uint8_t)userConfig->workMode); + /* Set the Free Running state */ + LptmrReg_SetFreeRunning(obj->reg, userConfig->freeRun); + /* Set Pin Polarity for Pulse Counter Mode */ + LptmrReg_SetPinPolarity(obj->reg, (uint8_t)userConfig->pinPolarity); + /* Set the Pin selection for Pulse Counter Mode */ + LptmrReg_SetPinSelect(obj->reg, (uint8_t)userConfig->pinSelect); + /* Set the Interrupt Enable state */ + LptmrReg_SetInterrupt(obj->reg, userConfig->interruptEnable); + /* Set the DMA Request Enable Flag state */ + LptmrReg_SetDmaRequest(obj->reg, userConfig->dmaRequest); + /* Set the Prescaler/Glitch Filter Bypass enable state */ + LptmrReg_SetBypass(obj->reg, userConfig->bypassPrescaler); + /* Set the Prescaler/Glitch Filter divider value */ + LptmrReg_SetPrescaler(obj->reg, (uint8_t)userConfig->prescaler); + /* Set the Prescaler/Glitch Filter Bypass enable state */ + LptmrReg_SetCompareValue(obj->reg, userConfig->compareValue); +} + +bool LptmrDrv_IsEnable(LptmrDrvType *obj) +{ + /* Get the Enable state */ + return (bool)(LptmrReg_GetEnable(obj->reg)); +} + +void LptmrDrv_Enable(LptmrDrvType *obj, bool enable) +{ + /* Set the Enable state */ + LptmrReg_SetEnable(obj->reg, enable); +} + +bool LptmrDrv_IsCompareEventAcvt(LptmrDrvType *obj) +{ + /* Get the Compare Flag state */ + return (bool)(LptmrReg_GetCompareFlag(obj->reg)); +} + +void LptmrDrv_ClearCompareFlag(LptmrDrvType *obj) +{ + /* Clear the Compare Flag */ + LptmrReg_ClearCompareFlag(obj->reg); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/lptmr/lptmr_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/lptmr/lptmr_drv.h new file mode 100644 index 0000000..d9680db --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/lptmr/lptmr_drv.h @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _LPTMR_DRV_H_ +#define _LPTMR_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of LPTMR (Low Power Timer) module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup lptmr_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Pulse Counter Input selection + */ +typedef enum +{ + LPTMRDRV_PINSELECT_INPUT0 = 0x00u, /*!< Pulse counter input 0 is selected */ + LPTMRDRV_PINSELECT_INPUT1 = 0x01u, /*!< Pulse counter input 1 is selected */ + LPTMRDRV_PINSELECT_INPUT2 = 0x02u, /*!< Pulse counter input 2 is selected */ +} LptmrDrv_PinSelectType; + +/*! \brief Pulse Counter input polarity + */ +typedef enum +{ + LPTMRDRV_PINPOLARITY_RISING = 0x00u, /*!< Count pulse on rising edge */ + LPTMRDRV_PINPOLARITY_FALLING = 0x01u, /*!< Count pulse on falling edge */ +} LptmrDrv_PinPolarityType; + +/*! \brief Work Mode + */ +typedef enum +{ + LPTMRDRV_WORKMODE_TIMER = 0u, /*!< Timer */ + LPTMRDRV_WORKMODE_PULSECOUNTER = 1u, /*!< Pulse counter */ +} LptmrDrv_WorkModeType; + +/*! \brief Prescaler Selection + */ +typedef enum +{ + LPTMRDRV_PRESCALE_2 = 0x00u, /*!< Timer mode: prescaler 2, Glitch filter mode: invalid */ + LPTMRDRV_PRESCALE_4_GLITCHFILTER_2 = 0x01u, /*!< Timer mode: prescaler 4, Glitch filter mode: 2 clocks */ + LPTMRDRV_PRESCALE_8_GLITCHFILTER_4 = 0x02u, /*!< Timer mode: prescaler 8, Glitch filter mode: 4 clocks */ + LPTMRDRV_PRESCALE_16_GLITCHFILTER_8 = 0x03u, /*!< Timer mode: prescaler 16, Glitch filter mode: 8 clocks */ + LPTMRDRV_PRESCALE_32_GLITCHFILTER_16 = 0x04u, /*!< Timer mode: prescaler 32, Glitch filter mode: 16 clocks */ + LPTMRDRV_PRESCALE_64_GLITCHFILTER_32 = 0x05u, /*!< Timer mode: prescaler 64, Glitch filter mode: 32 clocks */ + LPTMRDRV_PRESCALE_128_GLITCHFILTER_64 = 0x06u, /*!< Timer mode: prescaler 128, Glitch filter mode: 64 clocks */ + LPTMRDRV_PRESCALE_256_GLITCHFILTER_128 = 0x07u, /*!< Timer mode: prescaler 256, Glitch filter mode: 128 clocks */ + LPTMRDRV_PRESCALE_512_GLITCHFILTER_256 = 0x08u, /*!< Timer mode: prescaler 512, Glitch filter mode: 256 clocks */ + LPTMRDRV_PRESCALE_1024_GLITCHFILTER_512 = 0x09u, /*!< Timer mode: prescaler 1024, Glitch filter mode: 512 clocks */ + LPTMRDRV_PRESCALE_2048_GLITCHFILTER_1024 = 0x0Au, /*!< Timer mode: prescaler 2048, Glitch filter mode: 1024 clocks */ + LPTMRDRV_PRESCALE_4096_GLITCHFILTER_2048 = 0x0Bu, /*!< Timer mode: prescaler 4096, Glitch filter mode: 2048 clocks */ + LPTMRDRV_PRESCALE_8192_GLITCHFILTER_4096 = 0x0Cu, /*!< Timer mode: prescaler 8192, Glitch filter mode: 4096 clocks */ + LPTMRDRV_PRESCALE_16384_GLITCHFILTER_8192 = 0x0Du, /*!< Timer mode: prescaler 16384, Glitch filter mode: 8192 clocks */ + LPTMRDRV_PRESCALE_32768_GLITCHFILTER_16384 = 0x0Eu, /*!< Timer mode: prescaler 32768, Glitch filter mode: 16384 clocks */ + LPTMRDRV_PRESCALE_65536_GLITCHFILTER_32768 = 0x0Fu, /*!< Timer mode: prescaler 65536, Glitch filter mode: 32768 clocks */ +} LptmrDrv_PrescaleType; + +/*! \brief Definition of configuration of LPTMR driver + */ +typedef struct _LptmrDrv_ConfigType_ +{ + /* General parameters */ + bool dmaRequest; /*!< Enable/Disable DMA requests */ + bool interruptEnable; /*!< Enable/Disable Interrupt */ + bool freeRun; /*!< Enable/Disable Free Running Mode */ + LptmrDrv_WorkModeType workMode; /*!< Time/Pulse Counter Mode */ + + /* Counter parameters */ + LptmrDrv_PrescaleType prescaler; /*!< Prescaler Selection */ + bool bypassPrescaler; /*!< Enable/Disable prescaler bypass */ + uint16_t compareValue; /*!< Compare value */ + + /* Pulse Counter specific parameters */ + LptmrDrv_PinSelectType pinSelect; /*!< Pin selection for Pulse-Counter */ + LptmrDrv_PinPolarityType pinPolarity; /*!< Pin Polarity for Pulse-Counter */ +} LptmrDrv_ConfigType; + +/* Forward declaration of LPTMR register */ +struct _LptmrRegType_; + +/*! \brief The definition of LPTMR driver class + */ +typedef struct _LptmrDrvType_ +{ + struct _LptmrRegType_ *reg; +} LptmrDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the LPTMR driver module + * + * This function initializes LPTMR driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to LPTMR driver instance + * \param[in] reg : pointer to LPTMR register instance + */ +extern void LptmrDrv_Init(LptmrDrvType *obj, struct _LptmrRegType_ *reg); + +/*! \brief Get currunt configures of the LPTMR module for configuration structure + * + * This function gets currunt configures of the LPTMR module for user configuration structure + * + * \param[in] obj : pointer to LPTMR driver instance + * \param[out] userConfig : pointer to configuration structure + */ +extern void LptmrDrv_GetConfigure(LptmrDrvType *obj, LptmrDrv_ConfigType *userConfig); + +/*! \brief Get default configures the LPTMR module for configuration structure + * + * This function gets default configures the LPTMR module for user configuration structure + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void LptmrDrv_GetDefaultConfig(LptmrDrv_ConfigType *userConfig); + +/*! \brief Configures the LPTMR module from a user configuration structure + * + * This function Configures the LPTMR module from a user configuration structure + * + * \param[in] obj : pointer to LPTMR driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void LptmrDrv_Configure(LptmrDrvType *obj, const LptmrDrv_ConfigType *userConfig); + +/*! \brief Get the state of LPTMR enable + * + * This function gets the state of LPTMR enable + * + * \param[in] obj : pointer to LPTMR driver instance + * \return state of LPTMR enable + */ +extern bool LptmrDrv_IsEnable(LptmrDrvType *obj); + +/*! \brief Set the state of LPTMR enable + * + * This function sets the state of LPTMR enable + * + * \param[in] obj : pointer to lptmr LPTMR instance + * \param[in] state of LPTMR enable + */ +extern void LptmrDrv_Enable(LptmrDrvType *obj, bool enable); + +/*! \brief Get the flag of LPTMR compare flag + * + * This function gets the flag of LPTMR compare flag + * + * \param[in] obj : pointer to LPTMR driver instance + * \return the flag of LPTMR compare flag + */ +extern bool LptmrDrv_IsCompareEventAcvt(LptmrDrvType *obj); + +/*! \brief Clear the flag of LPTMR compare flag + * + * This function clears the flag of LPTMR compare flag + * + * \param[in] obj : pointer to LPTMR driver instance + */ +extern void LptmrDrv_ClearCompareFlag(LptmrDrvType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _LPTMR_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_ch.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_ch.c new file mode 100644 index 0000000..b04ec50 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_ch.c @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "mft_cap_ch.h" +#include "mft_cap_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void MftCapCh_Init(MftCapChType *obj, struct _MftCapDrvType_ *capDrv) +{ + obj->capDrv = capDrv; +} + +void MftCapCh_GetDefaultConfig(MftCapCh_ConfigType *userConfig) +{ + userConfig->hwChannelId = 0; /* Channel Id */ + userConfig->inputMode = MFTCAPCH_EDGE_DETECT; /* Input capture operation Mode */ + userConfig->edgeAlignement = MFTCAPCH_RISING_EDGE; /* Edge alignment Mode */ + userConfig->measurementType = MFTCAPCH_NO_MEASUREMENT; /* Signal measurement operation type */ + userConfig->filterValue = 0; /* Filter value */ + userConfig->filterEn = false; /* Filter disabled */ + userConfig->continuousModeEn = true; /* Continuous mode measurement */ + userConfig->callbacksParams = NULL; /* Callback parameters for channel events */ + userConfig->callbackFunc = NULL; /* Callback function for channels events */ +} + +void MftCapCh_Config(MftCapChType *obj, const MftCapCh_ConfigType *userConfig) +{ + /* Check Channel Id */ + if(userConfig->hwChannelId >= MFT_CHANNEL_NUM) + { + return; + } + + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->capDrv->base->reg, 1); + + /* Filter Mode, only availabe for channel 0, 1, 2, 3 */ + uint16_t filterValue = userConfig->filterEn ? userConfig->filterValue : 0; + switch(userConfig->hwChannelId) + { + case 0: + MftReg_SetFilterCh0FVal(obj->capDrv->base->reg, filterValue); + break; + case 1: + MftReg_SetFilterCh1FVal(obj->capDrv->base->reg, filterValue); + break; + case 2: + MftReg_SetFilterCh2FVal(obj->capDrv->base->reg, filterValue); + break; + case 3: + MftReg_SetFilterCh3FVal(obj->capDrv->base->reg, filterValue); + break; + default: + /* Nothing to do, not available for other channels */ + break; + } + + /* Input capture operation Mode, Edge alignment Mode, Signal measurement operation type */ + if(MFTCAPCH_EDGE_DETECT == userConfig->inputMode) + { + /* DECAPEN = 0 */ + MftDrv_SetDualEdgeCaptureCmd(obj->capDrv->base, userConfig->hwChannelId >> 1, false); + /* MSB:MSA = 0:0 */ + MftReg_SetCscMsb(obj->capDrv->base->reg, userConfig->hwChannelId, 0); + MftReg_SetCscMsa(obj->capDrv->base->reg, userConfig->hwChannelId, 0); + /* ELSnB:ELSnA = 0:0 */ + MftReg_SetCscElsb(obj->capDrv->base->reg, userConfig->hwChannelId, (userConfig->edgeAlignement >> 1) & 0x01U); + MftReg_SetCscElsa(obj->capDrv->base->reg, userConfig->hwChannelId, userConfig->edgeAlignement & 0x01U); + /* Enable interrupt request for the current channel */ + MftReg_SetCscChie(obj->capDrv->base->reg, userConfig->hwChannelId, 1); + } + else if(MFTCAPCH_SIGNAL_MEASUREMENT == userConfig->inputMode) + { + /* DECAPEN = 1 */ + MftDrv_SetDualEdgeCaptureCmd(obj->capDrv->base, userConfig->hwChannelId >> 1, true); + /* DECAP = 1 */ + MftDrv_SetDualChannelDecap(obj->capDrv->base, userConfig->hwChannelId >> 1, true); + /* If continuous mode is set */ + if(true == userConfig->continuousModeEn) + { + /* MSB:MSA = 1:1 */ + MftReg_SetCscMsb(obj->capDrv->base->reg, userConfig->hwChannelId, 1); + MftReg_SetCscMsa(obj->capDrv->base->reg, userConfig->hwChannelId, 1); + } + else + { + /* MSB:MSA = 1:0 */ + MftReg_SetCscMsb(obj->capDrv->base->reg, userConfig->hwChannelId, 1); + MftReg_SetCscMsa(obj->capDrv->base->reg, userConfig->hwChannelId, 0); + } + /* Check If want to measure a pulse width or period of the signal */ + if((MFTCAPCH_PERIOD_ON_MEASUREMENT == userConfig->measurementType) + || (MFTCAPCH_RISING_EDGE_PERIOD_MEASUREMENT == userConfig->measurementType)) + { + /* ELSnB:ELSnA = 0:1 (rising edge) */ + MftReg_SetCscElsb(obj->capDrv->base->reg, userConfig->hwChannelId, 0); + MftReg_SetCscElsa(obj->capDrv->base->reg, userConfig->hwChannelId, 1); + if(MFTCAPCH_PERIOD_ON_MEASUREMENT == userConfig->measurementType) + { + /* Measure time between rising and falling edge - positive duty */ + /* ELSnB:ELSnA = 1:0 (falling edge) for channel (n+1)*/ + MftReg_SetCscElsb(obj->capDrv->base->reg, userConfig->hwChannelId + 1, 1); + MftReg_SetCscElsa(obj->capDrv->base->reg, userConfig->hwChannelId + 1, 0); + } + else + { + /* If channel (n) is configured to capture falling edges (ELS(n)B:ELS(n)A = 0:1) + * then channel (n+1) also captures falling edges (ELS(n+1)B:ELS(n+1)A = 0:1) */ + MftReg_SetCscElsb(obj->capDrv->base->reg, userConfig->hwChannelId + 1, 0); + MftReg_SetCscElsa(obj->capDrv->base->reg, userConfig->hwChannelId + 1, 1); + } + } + else if((MFTCAPCH_PERIOD_OFF_MEASUREMENT == userConfig->measurementType) + || (MFTCAPCH_FALLING_EDGE_PERIOD_MEASUREMENT == userConfig->measurementType)) + { + /* ELSnB:ELSnA = 1:0 (falling edge) */ + MftReg_SetCscElsb(obj->capDrv->base->reg, userConfig->hwChannelId, 1); + MftReg_SetCscElsa(obj->capDrv->base->reg, userConfig->hwChannelId, 0); + if(MFTCAPCH_PERIOD_OFF_MEASUREMENT == userConfig->measurementType) + { + /* Measure time between falling and rising edge - negative duty */ + /* ELSnB:ELSnA = 0:1 (rising edge) for channel (n+1) */ + MftReg_SetCscElsb(obj->capDrv->base->reg, userConfig->hwChannelId + 1, 0); + MftReg_SetCscElsa(obj->capDrv->base->reg, userConfig->hwChannelId + 1, 1); + } + else + { + /* If channel (n) is configured to capture rising edges (ELS(n)B:ELS(n)A = 1:0) than + * channel (n+1) is setup to capture also raising edges (ELS(n+1)B:ELS(n+1)A = 1:0) */ + MftReg_SetCscElsb(obj->capDrv->base->reg, userConfig->hwChannelId + 1, 1); + MftReg_SetCscElsa(obj->capDrv->base->reg, userConfig->hwChannelId + 1, 0); + } + } + + /* Enable the interrupt request for the channel which will indicate that the measurement is done. */ + MftReg_SetCscChie(obj->capDrv->base->reg, userConfig->hwChannelId + 1, 1); + } + + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->capDrv->base->reg, 1); + + /* Remember the configuration */ + obj->config = *userConfig; +} + +void MftCapCh_Disarm(MftCapChType *obj) +{ + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->capDrv->base->reg, 1); + + /* Filter Mode, only availabe for channel 0, 1, 2, 3 */ + switch(obj->config.hwChannelId) + { + case 0: + MftReg_SetFilterCh0FVal(obj->capDrv->base->reg, 0); + break; + case 1: + MftReg_SetFilterCh1FVal(obj->capDrv->base->reg, 0); + break; + case 2: + MftReg_SetFilterCh2FVal(obj->capDrv->base->reg, 0); + break; + case 3: + MftReg_SetFilterCh3FVal(obj->capDrv->base->reg, 0); + break; + default: + /* Nothing to do, not available for other channels */ + break; + } + + /* Clear combine mode */ + MftReg_SetCombineCombine0(obj->capDrv->base->reg, 0); + MftReg_SetCombineCombine1(obj->capDrv->base->reg, 0); + MftReg_SetCombineCombine2(obj->capDrv->base->reg, 0); + MftReg_SetCombineCombine3(obj->capDrv->base->reg, 0); + MftDrv_SetDualEdgeCaptureCmd(obj->capDrv->base, obj->config.hwChannelId >> 1, false); + /* ELSnB:ELSnA = 0:0 (no edge) */ + MftReg_SetCscElsb(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + MftReg_SetCscElsa(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + /* Disable interrupt */ + MftReg_SetCscChie(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + /* Clear channel event flag */ + MftReg_SetCscChf(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + /* Disarm for channel (n+1) */ + /* ELSnB:ELSnA = 0:0 (no edge) */ + MftReg_SetCscElsb(obj->capDrv->base->reg, (obj->config.hwChannelId | 1U), 0); + MftReg_SetCscElsa(obj->capDrv->base->reg, (obj->config.hwChannelId | 1U), 0); + /* Disable interrupt */ + MftReg_SetCscChie(obj->capDrv->base->reg, (obj->config.hwChannelId | 1U), 0); + /* Clear channel event flag */ + MftReg_SetCscChf(obj->capDrv->base->reg, (obj->config.hwChannelId | 1U), 0); + + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->capDrv->base->reg, 1); +} + +bool MftCapCh_StartNewSignalMeasurement(MftCapChType *obj) +{ + bool retval = false; + /* Check if the channel is in single-shot mode */ + if(MftReg_GetCscMsa(obj->capDrv->base->reg, obj->config.hwChannelId) == 0 + && MftReg_GetCscMsb(obj->capDrv->base->reg, obj->config.hwChannelId) == 1) + { + if(MftDrv_GetDualEdgeCaptureCmd(obj->capDrv->base, obj->config.hwChannelId >> 1)) + { + /* Clear event flags for channel n and n + 1 */ + MftReg_SetCscChf(obj->capDrv->base->reg, obj->config.hwChannelId + 1, 0); + MftReg_SetCscChf(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + /* Set DECAP bit to start measurement */ + MftDrv_SetDualChannelDecap(obj->capDrv->base, obj->config.hwChannelId >> 1, true); + retval = true; + } + } + + return retval; +} + +void MftCapCh_SetChannelMode(MftCapChType *obj, MftCapCh_OpModeType inputMode, bool enableContinuousCapture) +{ + uint8_t level = 1U; + uint8_t nextChnlevel = 1U; + uint8_t channelPair = (uint8_t)(obj->config.hwChannelId >> 1U); + + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->capDrv->base->reg, 1); + + if(MFTCAPCH_DISABLE_OPERATION == inputMode) + { + /* Set the edge level to disable operation on the channel input */ + /* ELSnB:ELSnA = 0:0 (no edge) */ + MftReg_SetCscElsb(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + MftReg_SetCscElsa(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + } + else if((MFTCAPCH_TIMESTAMP_RISING_EDGE == inputMode) || (MFTCAPCH_TIMESTAMP_FALLING_EDGE == inputMode) || (MFTCAPCH_TIMESTAMP_BOTH_EDGES == inputMode)) + { + /* Disable the dual edge mode */ + MftDrv_SetDualEdgeCaptureCmd(obj->capDrv->base, channelPair, false); + /* Set input capture mode, MSB:MSA = 0:0 */ + MftReg_SetCscMsb(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + MftReg_SetCscMsa(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + /* Set the event which will generate the interrupt */ + MftReg_SetCscElsb(obj->capDrv->base->reg, obj->config.hwChannelId, (inputMode >> 1) & 0x01U); + MftReg_SetCscElsa(obj->capDrv->base->reg, obj->config.hwChannelId, inputMode & 0x01U); + /* Enable interrupt request for the current channel */ + MftReg_SetCscChie(obj->capDrv->base->reg, obj->config.hwChannelId, 1); + } + else + { + /* Check the channel is even number */ + if((obj->config.hwChannelId % 2U) != 0U) + { + return; + } + /* Enable the dual edge mode */ + MftDrv_SetDualEdgeCaptureCmd(obj->capDrv->base, channelPair, true); + /* Enable dual edge input capture */ + MftDrv_SetDualChannelDecap(obj->capDrv->base, channelPair, true); + /* If continuous mode is set*/ + if(true == enableContinuousCapture) + { + /* MSB:MSA = 1:1 */ + MftReg_SetCscMsb(obj->capDrv->base->reg, obj->config.hwChannelId, 1); + MftReg_SetCscMsa(obj->capDrv->base->reg, obj->config.hwChannelId, 1); + } + else + { + /* MSB:MSA = 1:0 */ + MftReg_SetCscMsb(obj->capDrv->base->reg, obj->config.hwChannelId, 1); + MftReg_SetCscMsa(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + } + + /* Check If want to measure a pulse width or period of the signal */ + if((MFTCAPCH_MEASURE_PULSE_HIGH == inputMode) || (MFTCAPCH_MEASURE_RISING_EDGE_PERIOD == inputMode)) + { + if(MFTCAPCH_MEASURE_PULSE_HIGH == inputMode) + { + /* Measure time between rising and falling edge - positive duty */ + nextChnlevel = 2U; + } + } + else + { + level = 2U; + if(MFTCAPCH_MEASURE_FALLING_EDGE_PERIOD == inputMode) + { + /* If channel (n) is configured to capture rising edges (ELS(n)B:ELS(n)A = 1:0) than + * channel (n+1) is setup to capture also raising edges (ELS(n+1)B:ELS(n+1)A = 1:0) */ + nextChnlevel = 2U; + } + } + /* Edge selection for channel (n) */ + MftReg_SetCscElsb(obj->capDrv->base->reg, obj->config.hwChannelId, (level >> 1) & 0x01U); + MftReg_SetCscElsa(obj->capDrv->base->reg, obj->config.hwChannelId, level & 0x01U); + /* Edge selection for channel (n+1) */ + MftReg_SetCscElsb(obj->capDrv->base->reg, obj->config.hwChannelId + 1, (nextChnlevel >> 1) & 0x01U); + MftReg_SetCscElsa(obj->capDrv->base->reg, obj->config.hwChannelId + 1, nextChnlevel & 0x01U); + + /* Disable interrupt request for the current channel */ + MftReg_SetCscChie(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + MftReg_SetCscChie(obj->capDrv->base->reg, obj->config.hwChannelId + 1, 1); + } + + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->capDrv->base->reg, 1); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_ch.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_ch.h new file mode 100644 index 0000000..7734bb1 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_ch.h @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MFT_CAP_CH_H_ +#define _MFT_CAP_CH_H_ + +/*! \brief Contains public interface to various functions related + * to the Capture channel of MFT + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup mft_cap_ch + * \ingroup mft_cap_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Selects mode operation in the input capture + */ +typedef enum +{ + MFTCAPCH_EDGE_DETECT = 0U, /*!< MFT edge detect */ + MFTCAPCH_SIGNAL_MEASUREMENT = 1U, /*!< MFT signal measurement */ + MFTCAPCH_NO_OPERATION = 2U /*!< MFT no operation */ +} MftCapCh_InputOpModeType; + +/*! \brief MFT input capture measurement type for dual edge input capture + */ +typedef enum +{ + MFTCAPCH_NO_MEASUREMENT = 0x00U, /*!< No measurement */ + MFTCAPCH_RISING_EDGE_PERIOD_MEASUREMENT = 0x01U, /*!< Period measurement between two consecutive rising edges */ + MFTCAPCH_FALLING_EDGE_PERIOD_MEASUREMENT = 0x02U, /*!< Period measurement between two consecutive falling edges */ + MFTCAPCH_PERIOD_ON_MEASUREMENT = 0x03U, /*!< The time measurement taken for the pulse to remain ON or HIGH state */ + MFTCAPCH_PERIOD_OFF_MEASUREMENT = 0x04U /*!< The time measurement taken for the pulse to remain OFF or LOW state */ +} MftCapCh_SignalMeasurementModeType; + +/*! \brief MFT input capture edge mode as rising edge or falling edge + */ +typedef enum +{ + MFTCAPCH_NO_PIN_CONTROL = 0x00U, /*!< No trigger */ + MFTCAPCH_RISING_EDGE = 0x01U, /*!< Rising edge trigger */ + MFTCAPCH_FALLING_EDGE = 0x02U, /*!< Falling edge trigger */ + MFTCAPCH_BOTH_EDGES = 0x03U /*!< Rising and falling edge trigger */ +} MftCapCh_EdgeAlignmentModeType; + +/*! \brief The measurement type for input capture mode + */ +typedef enum +{ + MFTCAPCH_DISABLE_OPERATION = 0x00U, /*!< Have no operation */ + MFTCAPCH_TIMESTAMP_RISING_EDGE = 0x01U, /*!< Rising edge trigger */ + MFTCAPCH_TIMESTAMP_FALLING_EDGE = 0x02U, /*!< Falling edge trigger */ + MFTCAPCH_TIMESTAMP_BOTH_EDGES = 0x03U, /*!< Rising and falling edge trigger */ + MFTCAPCH_MEASURE_RISING_EDGE_PERIOD = 0x04U, /*!< Period measurement between two consecutive rising edges */ + MFTCAPCH_MEASURE_FALLING_EDGE_PERIOD = 0x05U, /*!< Period measurement between two consecutive falling edges */ + MFTCAPCH_MEASURE_PULSE_HIGH = 0x06U, /*!< The time measurement taken for the pulse to remain ON or HIGH state */ + MFTCAPCH_MEASURE_PULSE_LOW = 0x07U /*!< The time measurement taken for the pulse to remain OFF or LOW state */ +} MftCapCh_OpModeType; + +/*! \brief MFT driver Input capture callback function prototype + */ +typedef void (*MftCapCh_CallbackType)(uint8_t event, void *params); + +/*! \brief MFT driver Input capture parameters for each channel + */ +typedef struct _MftCapCh_ConfigType_ +{ + uint8_t hwChannelId; /*!< Physical hardware channel ID*/ + MftCapCh_InputOpModeType inputMode; /*!< FlexTimer module mode of operation */ + MftCapCh_EdgeAlignmentModeType edgeAlignement; /*!< Edge alignment Mode for signal measurement*/ + MftCapCh_SignalMeasurementModeType measurementType; /*!< Measurement Mode for signal measurement*/ + uint16_t filterValue; /*!< Filter Value */ + bool filterEn; /*!< Input capture filter state */ + bool continuousModeEn; /*!< Continuous measurement state */ + void *callbacksParams; /*!< The parameters of callback functions for channels events */ + MftCapCh_CallbackType callbackFunc; /*!< The callback function for channels events */ +} MftCapCh_ConfigType; + +/* Forward declaration of MFT Capture driver */ +struct _MftCapDrvType_; + +/*! \brief The definition of MFT capture channel prototype + */ +typedef struct _MftCapChType_ +{ + struct _MftCapDrvType_ *capDrv; + MftCapCh_ConfigType config; +} MftCapChType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the MFT CAP channel + * + * This function initializes MFT CAP channel + * + * \param[in] obj : pointer to MFT CAP channel instance + * \param[in] base : pointer to MFT driver instance + */ +extern void MftCapCh_Init(MftCapChType *obj, struct _MftCapDrvType_ *capDrv); + +/*! \brief Get default configuration of the MFT capture channel + * + * This function gets default configures the MFT capture module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void MftCapCh_GetDefaultConfig(MftCapCh_ConfigType *userConfig); + +/*! \brief Configure the MFT capture channel + * + * This function configures the channel in the Input Capture mode for either getting + * time-stamps on edge detection or on signal measurement. When the edge specified in the capture Mode + * argument occurs on the channel and then the MFT counter is captured into the CnV register. + * The user have to read the CnV register separately to get this value. The filter + * function is disabled if the filterVal argument passed as 0. The filter feature + * is available only on channels 0,1,2,3. + * + * \param[in] obj : pointer to MFT CAP channel instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void MftCapCh_Config(MftCapChType *obj, const MftCapCh_ConfigType *userConfig); + +/*! \brief Disarm the MFT capture channel + * + * This function disables input capture mode and clears MFT timer configuration + * + * \param[in] obj : pointer to MFT CAP channel instance + */ +extern void MftCapCh_Disarm(MftCapChType *obj); + +/*! \brief Starts a new single-shot signal measurement of the given channel. + * + * This function starts the new single-shot signal measurement of the given channel. + * + * \param[in] obj : pointer to MFT CAP channel instance + * \return The result of the operation + * - true : succeed + * - false : failed + */ +extern bool MftCapCh_StartNewSignalMeasurement(MftCapChType *obj); + +/*! \brief Set mode operation for channel in the input capture mode + * + * This function will change the channel mode at run time or + * when stopping channel. The channel mode is selected in the MftCapCh_OpModeType + * enumeration type. + * + * \param[in] obj : pointer to MFT CAP channel instance + * \param[in] inputMode : The channel operation mode. + * \param[in] enableContinuousCapture : Enable/disable the continuous capture mode. + */ +extern void MftCapCh_SetChannelMode(MftCapChType *obj, MftCapCh_OpModeType inputMode, bool enableContinuousCapture); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _MFT_CAP_CH_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_drv.c new file mode 100644 index 0000000..77622e1 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_drv.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "mft_cap_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void MftCapDrv_Init(MftCapDrvType *obj, MftDrvType *base) +{ + obj->base = base; + + uint8_t i = 0; + for(i = 0; i < MFT_CHANNEL_NUM; ++i) + { + MftCapCh_Init(&obj->channel[i], obj); + } +} + +void MftCapDrv_GetDefaultConfig(MftCapDrv_ConfigType *userConfig) +{ + userConfig->maxCountValue = 65535; +} + +void MftCapDrv_Config(MftCapDrvType *obj, const MftCapDrv_ConfigType *userConfig) +{ + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->base->reg, 1); + + /* CNTIN = 0 */ + MftReg_SetCntInCntInit(obj->base->reg, 0U); + /* Set MOD */ + MftReg_SetModuloMod(obj->base->reg, userConfig->maxCountValue); + /* CPWMS = 0 */ + MftReg_SetScCPwms(obj->base->reg, 0); + + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->base->reg, 1); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_drv.h new file mode 100644 index 0000000..e059a22 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_drv.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MFT_CAP_DRV_H_ +#define _MFT_CAP_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the input Capture driver of MFT + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../mft_drv.h" +#include "mft_cap_ch.h" + +/*! \addtogroup mft_cap_drv + * \ingroup mft_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief MFT Input capture driver configuration + */ +typedef struct _MftCapDrv_ConfigType_ +{ + uint16_t maxCountValue; /*!< Maximum counter value. Minimum value is 0 for this mode */ +} MftCapDrv_ConfigType; + +/*! \brief The definition of MFT capture driver prototype + * \details Derived from MFT driver + */ +typedef struct _MftCapDrvType_ +{ + MftDrvType *base; /*!< base class of capture driver */ + MftCapChType channel[MFT_CHANNEL_NUM]; /*!< channels of the capture mode */ +} MftCapDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the MFT CAP module + * + * This function initializes MFT CAP driver by setting the MFT driver + * instance to it. + * + * \param[in] obj : pointer to MFT CAP channel instance + * \param[in] base : pointer to MFT driver instance + */ +extern void MftCapDrv_Init(MftCapDrvType *obj, MftDrvType *base); + +/*! \brief Get default configures the MFT capture module for configuration structure + * + * This function gets default configures the MFT capture module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void MftCapDrv_GetDefaultConfig(MftCapDrv_ConfigType *userConfig); + +/*! \brief Configure the MFT capture module + * + * This function configures the MFT capture module. + * + * \param[in] obj : pointer to MFT CAP channel instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void MftCapDrv_Config(MftCapDrvType *obj, const MftCapDrv_ConfigType *userConfig); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _MFT_CAP_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_drv.c new file mode 100644 index 0000000..317758e --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_drv.c @@ -0,0 +1,661 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "mft_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +/*! \brief Reset the MFT all registers + * + * This function resets MFT all registers. + * + * \param[in] obj : pointer to MFT driver instance + */ +void MftDrv_Reset(MftDrvType *obj) +{ + uint8_t channel = 0; + uint8_t pairIndex = 0; + + /* WPDIS is set when WPEN bit is read as a 1 and then 1 is written to WPDIS */ + obj->reg->FMS &= 0U; + /* This is the reset value for MODE register. WPDIS bit is set to disable write protection */ + obj->reg->MODE = 0x00000004U; + obj->reg->CNT = 0U; + obj->reg->SC &= 0U; + obj->reg->MODULO = 0U; + obj->reg->CNTIN = 0U; + obj->reg->STATUS &= 0U; + obj->reg->SYNC = 0U; + obj->reg->OUTINIT = 0U; + obj->reg->OUTMASK = 0U; + obj->reg->COMBINE = 0U; + obj->reg->DEADTIME = 0U; + obj->reg->EXTTRIG &= 0U; + obj->reg->POL = 0U; + obj->reg->FILTER = 0U; + obj->reg->FLTCTRL = 0U; + obj->reg->QDCTRL = 0U; + obj->reg->CONF = 0U; + obj->reg->FLTPOL = 0U; + obj->reg->SYNCONF = 0U; + obj->reg->INVCTRL = 0U; + obj->reg->SWOCTRL = 0U; + obj->reg->PWMLOAD = 0U; + obj->reg->HCR = 0U; + obj->reg->MOD_MIRROR = 0U; + obj->reg->SIM_OBE = 0U; + + for(channel = 0; channel < MFT_CHANNEL_NUM; ++channel) + { + obj->reg->CH[channel].CSC = 0; + obj->reg->CH[channel].CV = 0; + obj->reg->MIRROR[channel].CV = 0; + } + for(pairIndex = 0; pairIndex < MFT_DEADTIME_PAIR; ++pairIndex) + { + obj->reg->PAIR[pairIndex].DEADTIME = 0; + } +} + +void MftDrv_Init(MftDrvType *obj, struct _MftRegType_ *reg) +{ + obj->reg = reg; +} + +void MftDrv_GetDefaultConfig(MftDrv_ConfigType *userConfig) +{ + userConfig->clockSource = MFTDRV_CLOCK_SOURCE_SYSTEMCLK; + userConfig->countingMode = MFTDRV_UP_COUNTING; + userConfig->prescaler = MFTDRV_PRESCALE_DIV_BY_1; + userConfig->bdmMode = MFTDRV_BDM_MODE_11; +} + +void MftDrv_Config(MftDrvType *obj, const MftDrv_ConfigType *userConfig) +{ + /* Reset the MFT module */ + MftDrv_Reset(obj); + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->reg, 1); + /* Enable MFT */ + MftReg_SetModeMftEn(obj->reg, 1); + /* Set clock source */ + MftReg_SetScClks(obj->reg, userConfig->clockSource); + /* Set the clock prescale */ + MftReg_SetScPs(obj->reg, userConfig->prescaler); + /* Set BDM mode */ + MftReg_SetConfBdmMode(obj->reg, userConfig->bdmMode); + /* Set Counting mode */ + MftReg_SetScCPwms(obj->reg, userConfig->countingMode == MFTDRV_UP_COUNTING ? 0 : 1); + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->reg, 1); +} + +void MftDrv_MaskOutputChannels(MftDrvType *obj, uint32_t channelsMask, bool softWareTrigger) +{ + obj->reg->OUTMASK = channelsMask; + MftReg_SetSyncSwSync(obj->reg, softWareTrigger ? 1 : 0); +} + +void MftDrv_SetInitialCounterValue(MftDrvType *obj, uint16_t counterValue, bool softWareTrigger) +{ + MftReg_SetCntInCntInit(obj->reg, counterValue); + MftReg_SetSyncSwSync(obj->reg, softWareTrigger ? 1 : 0); +} + +uint16_t MftDrv_GetChnCounterValue(MftDrvType *obj, uint8_t channel) +{ + return MftReg_GetCvVal(obj->reg, channel); +} + +void MftDrv_SetHalfCycleReloadPoint(MftDrvType *obj, uint16_t reloadPoint, bool softWareTrigger) +{ + MftReg_SetHcrHCVal(obj->reg, reloadPoint); + MftReg_SetSyncSwSync(obj->reg, softWareTrigger ? 1 : 0); +} + +void MftDrv_SetSoftOutChnValue(MftDrvType *obj, uint8_t channelsValues, bool softWareTrigger) +{ + uint8_t channelsMask = channelsValues ^ (uint8_t)obj->reg->POL; + uint32_t mask = MFT_SWOCTRL_CH0OCV_MASK | MFT_SWOCTRL_CH1OCV_MASK | MFT_SWOCTRL_CH2OCV_MASK | MFT_SWOCTRL_CH3OCV_MASK | MFT_SWOCTRL_CH4OCV_MASK | MFT_SWOCTRL_CH5OCV_MASK | MFT_SWOCTRL_CH6OCV_MASK | MFT_SWOCTRL_CH7OCV_MASK; + obj->reg->SWOCTRL = ((obj->reg->SWOCTRL) & (~(mask))) | ((uint32_t)channelsMask << MFT_SWOCTRL_CH0OCV_SHIFT); + + MftReg_SetSyncSwSync(obj->reg, softWareTrigger ? 1 : 0); +} + +void MftDrv_SetSoftwareOutputChannelControl(MftDrvType *obj, uint8_t channelsMask, bool softWareTrigger) +{ + uint32_t mask = MFT_SWOCTRL_CH0OC_MASK | MFT_SWOCTRL_CH1OC_MASK | MFT_SWOCTRL_CH2OC_MASK | MFT_SWOCTRL_CH3OC_MASK | MFT_SWOCTRL_CH4OC_MASK | MFT_SWOCTRL_CH5OC_MASK | MFT_SWOCTRL_CH6OC_MASK | MFT_SWOCTRL_CH7OC_MASK; + obj->reg->SWOCTRL = ((obj->reg->SWOCTRL) & (~(mask))) | channelsMask; + + MftReg_SetSyncSwSync(obj->reg, softWareTrigger ? 1 : 0); +} + +void MftDrv_SetAllChnSoftwareOutputControl(MftDrvType *obj, uint8_t channelMask, uint8_t channelValueMask, bool softWareTrigger) +{ + uint16_t value = 0U; + + value = (uint16_t)(((uint16_t)channelValueMask ^ (uint16_t)obj->reg->POL) << (uint16_t)8U) | (uint16_t)channelMask; + obj->reg->SWOCTRL = value; + + MftReg_SetSyncSwSync(obj->reg, softWareTrigger ? 1 : 0); +} + +void MftDrv_SetInvertingControl(MftDrvType *obj, uint8_t channelsPairMask, bool softWareTrigger) +{ + obj->reg->INVCTRL = channelsPairMask; + MftReg_SetSyncSwSync(obj->reg, softWareTrigger ? 1 : 0); +} + +void MftDrv_SetModuloCounterValue(MftDrvType *obj, uint16_t counterValue, bool softWareTrigger) +{ + MftReg_SetModuloMod(obj->reg, counterValue); + MftReg_SetSyncSwSync(obj->reg, softWareTrigger ? 1 : 0); +} + +void MftDrv_SetOutputlevel(MftDrvType *obj, uint8_t channel, uint8_t level) +{ + MftReg_SetCscElsa(obj->reg, channel, (level & 0x01U)); + MftReg_SetCscElsb(obj->reg, channel, (level & 0x02U) >> 1U); +} + +void MftDrv_EnableInterrupts(MftDrvType *obj, uint32_t interruptMask) +{ + uint32_t chnlInts = (interruptMask & 0x000000FFU); + uint8_t channel = 0U; + + /* Enable the timer overflow interrupt */ + if((interruptMask & (uint32_t)MFTDRV_TIME_OVERFLOW_INT_ENABLE) != 0x0U) + { + MftReg_SetScToie(obj->reg, 1); + } + + /* Enable the fault interrupt */ + if((interruptMask & (uint32_t)MFTDRV_FAULT_INT_ENABLE) != 0x0U) + { + MftReg_SetModeFaultIE(obj->reg, 1); + } + + /* Enable the reload interrupt */ + if((interruptMask & (uint32_t)MFTDRV_RELOAD_INT_ENABLE) != 0x0U) + { + MftReg_SetScRie(obj->reg, 1); + } + + /* Enable the channel interrupts */ + while(chnlInts != 0U) + { + if((chnlInts & 0x1U) != 0x0U) + { + MftReg_SetCscChie(obj->reg, channel, 1); + } + channel++; + chnlInts = chnlInts >> 1U; + } +} + +void MftDrv_DisableInterrupts(MftDrvType *obj, uint32_t InterruptMask) +{ + uint32_t chnlInts = (InterruptMask & 0x000000FFU); + uint8_t channel = 0U; + + /* Disable the timer overflow interrupt */ + if((InterruptMask & (uint32_t)MFTDRV_TIME_OVERFLOW_INT_ENABLE) != 0x0U) + { + MftReg_SetScToie(obj->reg, 0); + } + + /* Disable the fault interrupt */ + if((InterruptMask & (uint32_t)MFTDRV_FAULT_INT_ENABLE) != 0x0U) + { + MftReg_SetModeFaultIE(obj->reg, 0); + } + + /* Disable the reload interrupt */ + if((InterruptMask & (uint32_t)MFTDRV_RELOAD_INT_ENABLE) != 0x0U) + { + MftReg_SetScRie(obj->reg, 0); + } + + /* Disable the channel interrupts */ + while(chnlInts != 0U) + { + if((chnlInts & 0x1U) != 0x0U) + { + MftReg_SetCscChie(obj->reg, channel, 0); + } + channel++; + chnlInts = chnlInts >> 1U; + } +} + +uint32_t MftDrv_GetEnabledInterrupts(MftDrvType *obj) +{ + uint32_t enabledInterrupts = 0U; + uint8_t channel = 0; + + /* Check if timer overflow interrupt is enabled */ + if(MftReg_GetScToie(obj->reg) == 1) + { + enabledInterrupts |= (uint32_t)MFTDRV_TIME_OVERFLOW_INT_ENABLE; + } + + /* Check if fault interrupt is enabled */ + if(MftReg_GetModeFaultIE(obj->reg) == 1) + { + enabledInterrupts |= (uint32_t)MFTDRV_FAULT_INT_ENABLE; + } + + /* Check if the reload interrupt is enabled */ + if(MftReg_GetScRie(obj->reg) == 1) + { + enabledInterrupts |= (uint32_t)MFTDRV_RELOAD_INT_ENABLE; + } + + /* Check if the channel interrupts are enabled */ + for(channel = 0U; channel < MFT_CHANNEL_NUM; channel++) + { + if(MftReg_GetCscChie(obj->reg, channel) == 1) + { + enabledInterrupts |= (1UL << (uint32_t)channel); + } + } + + return enabledInterrupts; +} + +uint32_t MftDrv_GetStatusFlags(MftDrvType *obj) +{ + uint8_t channel = 0U; + uint32_t statusFlags = 0U; + + /* Check the timer flag */ + if(MftReg_GetScTof(obj->reg) == 1) + { + statusFlags |= (uint32_t)MFTDRV_TIME_OVER_FLOW_FLAG; + } + + /* Check fault flag */ + if(MftReg_GetFmsFaultF(obj->reg) == 1) + { + statusFlags |= (uint32_t)MFTDRV_FAULT_FLAG; + } + + /* Check reload flag */ + if(MftReg_GetScRf(obj->reg) == 1) + { + statusFlags |= (uint32_t)MFTDRV_RELOAD_FLAG; + } + + /* Check channel trigger flag */ + if(MftReg_GetExtTrigTrigF(obj->reg) == 1) + { + statusFlags |= (uint32_t)MFTDRV_CHANNEL_TRIGGER_FLAG; + } + + /* Lower 8 bits contain the channel status flags */ + for(channel = 0U; channel < MFT_CHANNEL_NUM; channel++) + { + if(MftReg_GetCscChf(obj->reg, channel) == 1) + { + statusFlags |= (1UL << (uint32_t)channel); + } + } + + return statusFlags; +} + +void MftDrv_ClearStatusFlags(MftDrvType *obj, uint32_t flagMask) +{ + /* Clear the timer overflow flag by writing a 0 to the bit while it is set */ + if((flagMask & (uint32_t)MFTDRV_TIME_OVER_FLOW_FLAG) != 0x0U) + { + MftReg_SetScTof(obj->reg, 0); + } + + /* Clear fault flag by writing a 0 to the bit while it is set */ + if((flagMask & (uint32_t)MFTDRV_FAULT_FLAG) != 0x0U) + { + MftReg_SetFmsFaultF0(obj->reg, 0); + MftReg_SetFmsFaultF1(obj->reg, 0); + MftReg_SetFmsFaultF2(obj->reg, 0); + MftReg_SetFmsFaultF3(obj->reg, 0); + /* FAULTF is also cleared when FAULTF bit of each enabled fault input is cleared */ + MftReg_SetFmsFaultF(obj->reg, 0); + } + + /* Check reload flag by writing a 0 to the bit while it is set */ + if((flagMask & (uint32_t)MFTDRV_RELOAD_FLAG) != 0x0U) + { + MftReg_SetScRf(obj->reg, 0); + } + + /* Clear channel trigger flag */ + if((flagMask & (uint32_t)MFTDRV_CHANNEL_TRIGGER_FLAG) != 0x0U) + { + MftReg_SetExtTrigTrigF(obj->reg, 0); + } + + /* Clear the channel status flags by writing a 0 to the bit */ + if((flagMask & (uint32_t)MFTDRV_CHANNEL7_FLAG) != 0x0U) + { + MftReg_SetStatusCh7F(obj->reg, 0); + } + if((flagMask & (uint32_t)MFTDRV_CHANNEL6_FLAG) != 0x0U) + { + MftReg_SetStatusCh6F(obj->reg, 0); + } + if((flagMask & (uint32_t)MFTDRV_CHANNEL5_FLAG) != 0x0U) + { + MftReg_SetStatusCh5F(obj->reg, 0); + } + if((flagMask & (uint32_t)MFTDRV_CHANNEL4_FLAG) != 0x0U) + { + MftReg_SetStatusCh4F(obj->reg, 0); + } + if((flagMask & (uint32_t)MFTDRV_CHANNEL3_FLAG) != 0x0U) + { + MftReg_SetStatusCh3F(obj->reg, 0); + } + if((flagMask & (uint32_t)MFTDRV_CHANNEL2_FLAG) != 0x0U) + { + MftReg_SetStatusCh2F(obj->reg, 0); + } + if((flagMask & (uint32_t)MFTDRV_CHANNEL1_FLAG) != 0x0U) + { + MftReg_SetStatusCh1F(obj->reg, 0); + } + if((flagMask & (uint32_t)MFTDRV_CHANNEL0_FLAG) != 0x0U) + { + MftReg_SetStatusCh0F(obj->reg, 0); + } +} + +void MftDrv_CounterReset(MftDrvType *obj, bool softWareTrigger) +{ + /* Updates the counter with its initial value */ + MftReg_SetCntCount(obj->reg, 0U); + /* Set a software trigger or waiting a hardware trigger */ + MftReg_SetSyncSwSync(obj->reg, softWareTrigger ? 1 : 0); +} + +void MftDrv_SetDualEdgeCaptureCmd(MftDrvType *obj, uint8_t pairNum, bool enable) +{ + uint8_t enableValue = enable ? 1 : 0; + switch(pairNum) + { + case 0: + MftReg_SetCombineDecapEn0(obj->reg, enableValue); + break; + case 1: + MftReg_SetCombineDecapEn1(obj->reg, enableValue); + break; + case 2: + MftReg_SetCombineDecapEn2(obj->reg, enableValue); + break; + case 3: + MftReg_SetCombineDecapEn3(obj->reg, enableValue); + break; + default: + break; + } +} + +void MftDrv_SetDualChannelDecap(MftDrvType *obj, uint8_t pairNum, bool enable) +{ + uint8_t enableValue = enable ? 1 : 0; + switch(pairNum) + { + case 0: + MftReg_SetCombineDecap0(obj->reg, enableValue); + break; + case 1: + MftReg_SetCombineDecap1(obj->reg, enableValue); + break; + case 2: + MftReg_SetCombineDecap2(obj->reg, enableValue); + break; + case 3: + MftReg_SetCombineDecap3(obj->reg, enableValue); + break; + default: + break; + } +} + +bool MftDrv_GetDualEdgeCaptureCmd(MftDrvType *obj, uint8_t pairNum) +{ + bool retval = false; + switch(pairNum) + { + case 0: + retval = MftReg_GetCombineDecapEn0(obj->reg) == 1; + break; + case 1: + retval = MftReg_GetCombineDecapEn1(obj->reg) == 1; + break; + case 2: + retval = MftReg_GetCombineDecapEn2(obj->reg) == 1; + break; + case 3: + retval = MftReg_GetCombineDecapEn3(obj->reg) == 1; + break; + default: + break; + } + + return retval; +} + +void MftDrv_SetDualChannelComp(MftDrvType *obj, uint8_t pairNum, bool enable) +{ + uint8_t enableValue = enable ? 1 : 0; + switch(pairNum) + { + case 0: + MftReg_SetCombineComp0(obj->reg, enableValue); + break; + case 1: + MftReg_SetCombineComp1(obj->reg, enableValue); + break; + case 2: + MftReg_SetCombineComp2(obj->reg, enableValue); + break; + case 3: + MftReg_SetCombineComp3(obj->reg, enableValue); + break; + default: + break; + } +} + +void MftDrv_SetDualChannelCombine(MftDrvType *obj, uint8_t pairNum, bool enable) +{ + uint8_t enableValue = enable ? 1 : 0; + switch(pairNum) + { + case 0: + MftReg_SetCombineCombine0(obj->reg, enableValue); + break; + case 1: + MftReg_SetCombineCombine1(obj->reg, enableValue); + break; + case 2: + MftReg_SetCombineCombine2(obj->reg, enableValue); + break; + case 3: + MftReg_SetCombineCombine3(obj->reg, enableValue); + break; + default: + break; + } +} + +void MftDrv_SetDualChannelModifiedCombine(MftDrvType *obj, uint8_t pairNum, bool enable) +{ + uint8_t enableValue = enable ? 1 : 0; + switch(pairNum) + { + case 0: + MftReg_SetCombineMCombine0(obj->reg, enableValue); + break; + case 1: + MftReg_SetCombineMCombine1(obj->reg, enableValue); + break; + case 2: + MftReg_SetCombineMCombine2(obj->reg, enableValue); + break; + case 3: + MftReg_SetCombineMCombine3(obj->reg, enableValue); + break; + default: + break; + } +} + +void MftDrv_SetDualChannelFault(MftDrvType *obj, uint8_t pairNum, bool enable) +{ + uint8_t enableValue = enable ? 1 : 0; + switch(pairNum) + { + case 0: + MftReg_SetCombineFaultEn0(obj->reg, enableValue); + break; + case 1: + MftReg_SetCombineFaultEn1(obj->reg, enableValue); + break; + case 2: + MftReg_SetCombineFaultEn2(obj->reg, enableValue); + break; + case 3: + MftReg_SetCombineFaultEn3(obj->reg, enableValue); + break; + default: + break; + } +} + +void MftDrv_SetDualChannelPwmSync(MftDrvType *obj, uint8_t pairNum, bool enable) +{ + uint8_t enableValue = enable ? 1 : 0; + switch(pairNum) + { + case 0: + MftReg_SetCombineSyncEn0(obj->reg, enableValue); + break; + case 1: + MftReg_SetCombineSyncEn1(obj->reg, enableValue); + break; + case 2: + MftReg_SetCombineSyncEn2(obj->reg, enableValue); + break; + case 3: + MftReg_SetCombineSyncEn3(obj->reg, enableValue); + break; + default: + break; + } +} + +void MftDrv_EnablePwmChannelOutputs(MftDrvType *obj, uint8_t channel, bool enable) +{ + uint8_t enableValue = enable ? 1 : 0; + switch(channel) + { + case 0: + MftReg_SetScPwmEn0(obj->reg, enableValue); + break; + case 1: + MftReg_SetScPwmEn1(obj->reg, enableValue); + break; + case 2: + MftReg_SetScPwmEn2(obj->reg, enableValue); + break; + case 3: + MftReg_SetScPwmEn3(obj->reg, enableValue); + break; + case 4: + MftReg_SetScPwmEn4(obj->reg, enableValue); + break; + case 5: + MftReg_SetScPwmEn5(obj->reg, enableValue); + break; + case 6: + MftReg_SetScPwmEn6(obj->reg, enableValue); + break; + case 7: + MftReg_SetScPwmEn7(obj->reg, enableValue); + break; + default: + break; + } +} + +void MftDrv_SetChannelTriggerCmd(MftDrvType *obj, uint8_t channel, bool enable) +{ + uint8_t enableValue = enable ? 1 : 0; + switch(channel) + { + case 0: + MftReg_SetExtTrigCh0Trig(obj->reg, enableValue); + break; + case 1: + MftReg_SetExtTrigCh1Trig(obj->reg, enableValue); + break; + case 2: + MftReg_SetExtTrigCh2Trig(obj->reg, enableValue); + break; + case 3: + MftReg_SetExtTrigCh3Trig(obj->reg, enableValue); + break; + case 4: + MftReg_SetExtTrigCh4Trig(obj->reg, enableValue); + break; + case 5: + MftReg_SetExtTrigCh5Trig(obj->reg, enableValue); + break; + case 6: + MftReg_SetExtTrigCh6Trig(obj->reg, enableValue); + break; + case 7: + MftReg_SetExtTrigCh7Trig(obj->reg, enableValue); + break; + default: + break; + } +} + +void MftDrv_SoftWareTrigger(MftDrvType *obj) +{ + MftReg_SetSyncSwSync(obj->reg, 1); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_drv.h new file mode 100644 index 0000000..8ce58c2 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_drv.h @@ -0,0 +1,534 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MFT_DRV_H_ +#define _MFT_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of MFT (Multi Functional Timer) + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "mft_reg.h" + +/*! \addtogroup mft_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief MFT counting mode + */ +typedef enum +{ + MFTDRV_UP_COUNTING, /*!< up counting mode */ + MFTDRV_UP_DOWN_COUNTING, /*!< up-down counting mode */ +} MftDrv_CountingModeType; + +/*! \brief MFT clock source selection + */ +typedef enum +{ + MFTDRV_CLOCK_SOURCE_NONE = 0x00U, /*!< None use clock for MFT */ + MFTDRV_CLOCK_SOURCE_SYSTEMCLK = 0x01U, /*!< System clock */ + MFTDRV_CLOCK_SOURCE_FIXEDCLK = 0x02U, /*!< Fixed clock */ + MFTDRV_CLOCK_SOURCE_EXTERNALCLK = 0x03U /*!< External clock */ +} MftDrv_ClockSrcType; + +/*! \brief MFT pre-scaler factor selection for the clock source + */ +typedef enum +{ + MFTDRV_PRESCALE_DIV_BY_1 = 0x00U, /*!< Divide by 1 */ + MFTDRV_PRESCALE_DIV_BY_2 = 0x01U, /*!< Divide by 2 */ + MFTDRV_PRESCALE_DIV_BY_4 = 0x02U, /*!< Divide by 4 */ + MFTDRV_PRESCALE_DIV_BY_8 = 0x03U, /*!< Divide by 8 */ + MFTDRV_PRESCALE_DIV_BY_16 = 0x04U, /*!< Divide by 16 */ + MFTDRV_PRESCALE_DIV_BY_32 = 0x05U, /*!< Divide by 32 */ + MFTDRV_PRESCALE_DIV_BY_64 = 0x06U, /*!< Divide by 64 */ + MFTDRV_PRESCALE_DIV_BY_128 = 0x07U /*!< Divide by 128 */ +} MftDrv_PrescaleType; + +/*! \brief List of MFT interrupts + */ +typedef enum +{ + MFTDRV_CHANNEL0_INT_ENABLE = 0x00000001U, /*!< Channel 0 interrupt */ + MFTDRV_CHANNEL1_INT_ENABLE = 0x00000002U, /*!< Channel 1 interrupt */ + MFTDRV_CHANNEL2_INT_ENABLE = 0x00000004U, /*!< Channel 2 interrupt */ + MFTDRV_CHANNEL3_INT_ENABLE = 0x00000008U, /*!< Channel 3 interrupt */ + MFTDRV_CHANNEL4_INT_ENABLE = 0x00000010U, /*!< Channel 4 interrupt */ + MFTDRV_CHANNEL5_INT_ENABLE = 0x00000020U, /*!< Channel 5 interrupt */ + MFTDRV_CHANNEL6_INT_ENABLE = 0x00000040U, /*!< Channel 6 interrupt */ + MFTDRV_CHANNEL7_INT_ENABLE = 0x00000080U, /*!< Channel 7 interrupt */ + MFTDRV_FAULT_INT_ENABLE = 0x00000100U, /*!< Fault interrupt */ + MFTDRV_TIME_OVERFLOW_INT_ENABLE = 0x00000200U, /*!< Time overflow interrupt */ + MFTDRV_RELOAD_INT_ENABLE = 0x00000400U /*!< Reload interrupt */ +} MftDrv_InterruptOptionType; + +/*! \brief List of MFT flags + */ +typedef enum +{ + MFTDRV_CHANNEL0_FLAG = 0x00000001U, /*!< Channel 0 Flag */ + MFTDRV_CHANNEL1_FLAG = 0x00000002U, /*!< Channel 1 Flag */ + MFTDRV_CHANNEL2_FLAG = 0x00000004U, /*!< Channel 2 Flag */ + MFTDRV_CHANNEL3_FLAG = 0x00000008U, /*!< Channel 3 Flag */ + MFTDRV_CHANNEL4_FLAG = 0x00000010U, /*!< Channel 4 Flag */ + MFTDRV_CHANNEL5_FLAG = 0x00000020U, /*!< Channel 5 Flag */ + MFTDRV_CHANNEL6_FLAG = 0x00000040U, /*!< Channel 6 Flag */ + MFTDRV_CHANNEL7_FLAG = 0x00000080U, /*!< Channel 7 Flag */ + MFTDRV_FAULT_FLAG = 0x00000100U, /*!< Fault Flag */ + MFTDRV_TIME_OVER_FLOW_FLAG = 0x00000200U, /*!< Time overflow Flag */ + MFTDRV_RELOAD_FLAG = 0x00000400U, /*!< Reload Flag */ + MFTDRV_CHANNEL_TRIGGER_FLAG = 0x00000800U /*!< Channel trigger Flag */ +} MftDrv_StatusFlagType; + +/*! \brief List of MFT BDM Mode + */ +typedef enum +{ + MFTDRV_BDM_MODE_00 = 0x00U, /*!< MFT counter stopped */ + MFTDRV_BDM_MODE_01 = 0x01U, /*!< MFT counter stopped */ + MFTDRV_BDM_MODE_10 = 0x02U, /*!< MFT counter stopped */ + MFTDRV_BDM_MODE_11 = 0x03U /*!< MFT counter in functional mode*/ +} MftDrv_BdmModeType; + +/*! \brief MFT configuration structure + */ +typedef struct _MftDrv_ConfigType_ +{ + MftDrv_ClockSrcType clockSource; /*!< Clock source */ + MftDrv_CountingModeType countingMode; /*!< Counting mode */ + MftDrv_PrescaleType prescaler; /*!< Register pre-scaler options */ + MftDrv_BdmModeType bdmMode; /*!< Select MFT behavior in BDM mode */ +} MftDrv_ConfigType; + +/*! \brief The definition of MFT driver prototype + */ +typedef struct _MftDrvType_ +{ + struct _MftRegType_ *reg; /*!< MFT register */ +} MftDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the MFT reg and state + * + * This function initializes MFT driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] reg : pointer to MFT register instance + */ +extern void MftDrv_Init(MftDrvType *obj, struct _MftRegType_ *reg); + +/*! \brief Get default configures the MFT module for configuration structure + * + * This function gets default configures the MFT module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void MftDrv_GetDefaultConfig(MftDrv_ConfigType *userConfig); + +/*! \brief Configure the MFT driver + * + * This function resets MFT module, enables the MFT module, configures MFT + * module. The MFT configuration structure shall + * be passed as arguments. + * This function should be called before calling any other MFT driver function. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] userConfig : pointer to MFT config instance + */ +extern void MftDrv_Config(MftDrvType *obj, const MftDrv_ConfigType *userConfig); + +/*! \brief Mask the output of channels + * + * This function will mask the output of the channels and at match events will be ignored + * by the masked channels. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] channelsMask : channels mask + * \param[in] softWareTrigger : whether to enable softWare trigger + * - false : disable software trigger + * - true : enable software trigger + */ +extern void MftDrv_MaskOutputChannels(MftDrvType *obj, uint32_t channelsMask, bool softWareTrigger); + +/*! \brief Initializes the Mft module counter value + * + * This function configure the initial counter value. The counter will get this + * value after an overflow event. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] counterValue : counter Value + * \param[in] softWareTrigger : whether to enable softWare trigger + * - false : disable software trigger + * - true : enable software trigger + */ +extern void MftDrv_SetInitialCounterValue(MftDrvType *obj, uint16_t counterValue, bool softWareTrigger); + +/*! \brief Get the Mft module channel counter value + * + * This function get the counter value. Captured MFT counter value of the input modes or + * the match value for the output modes + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] channel : channel number + * \return Channel counter value + */ +extern uint16_t MftDrv_GetChnCounterValue(MftDrvType *obj, uint8_t channel); + +/*! \brief Configure the value of the counter which will generates an reload point + * + * This function configure the value of the counter which will + * generates an reload point. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] reloadPoint : reload Point + * \param[in] softWareTrigger : whether to enable softWare trigger + * - false : disable software trigger + * - true : enable software trigger + */ +extern void MftDrv_SetHalfCycleReloadPoint(MftDrvType *obj, uint16_t reloadPoint, bool softWareTrigger); + +/*! \brief Set soft out channel value + * + * This function will force the output value of a channel to a specific value. + * Before using this function it's mandatory to mask the match events using + * MftDrv_MaskOutputChannels and to enable software output control using + * MftDrv_SetSoftwareOutputChannelControl. + * + * \note When the PWM signal is configured with LOW/HIGH polarity on the channel (n). + * It should be set the safe state as LOW level state. However, We will have an issue + * with COMP bit is zero and CH(n)OCV is HIGH and CH(n+1)OCV is LOW. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] channelsValues : The values which will be software configured for channels. + * \param[in] softWareTrigger : whether to enable softWare trigger + * - false : disable software trigger + * - true : enable software trigger + */ +extern void MftDrv_SetSoftOutChnValue(MftDrvType *obj, uint8_t channelsValues, bool softWareTrigger); + +/*! \brief Set software output channel Control + * + * This function will configure which output channel can be software controlled. + * Software output control forces the following values on channels (n) and (n+1) when the + * COMP bit is zero and POL bit is zero. + * CH(n)OC|CH(n+1)OC|CH(n)OCV|CH(n+1)OCV|Channel (n) Output | Channel (n+1) Output + * 0 | 0 | X | X | is not modified by SWOC| is not modified by SWOC + * 1 | 1 | 0 | 0 | is forced to zero | is forced to zero + * 1 | 1 | 0 | 1 | is forced to zero | is forced to one + * 1 | 1 | 1 | 0 | is forced to one | is forced to zero + * 1 | 1 | 1 | 1 | is forced to one | is forced to one + * + * Software output control forces the following values on channels (n) and (n+1) when the + * COMP bit is one and POL bit is zero. + * CH(n)OC|CH(n+1)OC|CH(n)OCV|CH(n+1)OCV|Channel (n) Output | Channel (n+1) Output + * 0 | 0 | X | X | is not modified by SWOC| is not modified by SWOC + * 1 | 1 | 0 | 0 | is forced to zero | is forced to zero + * 1 | 1 | 0 | 1 | is forced to zero | is forced to one + * 1 | 1 | 1 | 0 | is forced to one | is forced to zero + * 1 | 1 | 1 | 1 | is forced to one | is forced to zero + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] channelsMask : The mask which will configure the channels which can be software controlled + * \param[in] softWareTrigger : whether to enable softWare trigger + * - false : disable software trigger + * - true : enable software trigger + */ +extern void MftDrv_SetSoftwareOutputChannelControl(MftDrvType *obj, uint8_t channelsMask, bool softWareTrigger); + +/*! \brief This function will control list of channels by software to force the output to specified value. + * + * Despite the odd channels are configured as HIGH/LOW, they will be inverted in the following + * configuration: COMP bit = 1 and CH(n)OCV and CH(n+1)OCV are HIGH. + * Please check software output control behavior chapter from reference manual. + * + * \note When the PWM signal is configured with LOW/HIGH polarity on the channel (n). + * It should be set the safe state as LOW level state. However, We will have an issue + * with COMP bit is zero and CH(n)OCV is HIGH and CH(n+1)OCV is LOW. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] channelsMask : The mask which will configure the channels which can be software controlled. + * \param[in] channelValueMask : The values which will be software configured for channels. + * \param[in] softWareTrigger : whether to enable softWare trigger + * - false : disable software trigger + * - true : enable software trigger + */ +extern void MftDrv_SetAllChnSoftwareOutputControl(MftDrvType *obj, uint8_t channelMask, uint8_t channelValueMask, bool softWareTrigger); + +/*! \brief Set inverting control + * + * This function will configure if the second channel of a pair will be inverted or not. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] channelsPairMask : The mask which will configure which channel pair will invert the second channel. + * \param[in] softWareTrigger : whether to enable softWare trigger + * - false : disable software trigger + * - true : enable software trigger + */ +extern void MftDrv_SetInvertingControl(MftDrvType *obj, uint8_t channelsPairMask, bool softWareTrigger); + +/*! \brief Set Modulo Counter Value + * + * This function configure the maximum counter value. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] counterValue : Maximum counter value + * \param[in] softWareTrigger : whether to enable softWare trigger + * - false : disable software trigger + * - true : enable software trigger + */ +extern void MftDrv_SetModuloCounterValue(MftDrvType *obj, uint16_t counterValue, bool softWareTrigger); + +/*! \brief Set Output level + * + * This function will set the channel edge or level on the selection + * of the channel mode. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] channel : channel number + * \param[in] level : the level or edge selection for channel mode. + */ +extern void MftDrv_SetOutputlevel(MftDrvType *obj, uint8_t channel, uint8_t level); + +/*! \brief Enable interrupts + * + * This function will enable the generation a list of interrupts. + * It includes the MFT overflow interrupts, the reload point interrupt, the fault + * interrupt and the channel (n) interrupt. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] interruptMask : interrupt Mask. This is the logical OR of members of the MftDrv_InterruptOptionType + */ +extern void MftDrv_EnableInterrupts(MftDrvType *obj, uint32_t interruptMask); + +/*! \brief Disable interrupts + * + * This function is used to disable some interrupts. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] interruptMask : interrupt Mask. This is the logical OR of members of the MftDrv_InterruptOptionType + */ +extern void MftDrv_DisableInterrupts(MftDrvType *obj, uint32_t interruptMask); + +/*! \brief Get enabled interrupts + * + * This function will get the enabled MFT interrupts. + * + * \param[in] obj : pointer to MFT driver instance + * \return The enabled interrupts. This is the logical OR of members of the MftDrv_InterruptOptionType + */ +extern uint32_t MftDrv_GetEnabledInterrupts(MftDrvType *obj); + +/*! \brief Get status flags + * + * This function will get the MFT status flags. + * + * \note Regarding the duty cycle is 100% at the channel output, the match interrupt + * has no event due to the C(n)V and C(n+1)V value are not between CNTIN value and MOD value. + * + * \param[in] obj : pointer to MFT driver instance + * \return The status flags. This is the logical OR of members of the MftDrv_StatusFlagType + */ +extern uint32_t MftDrv_GetStatusFlags(MftDrvType *obj); + +/*! \brief Clear status flags + * + * This function is used to clear the MFT status flags. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] flagMask : The status flags to clear. This is a logical OR of members of the MftDrv_StatusFlagType + */ +extern void MftDrv_ClearStatusFlags(MftDrvType *obj, uint32_t flagMask); + +/*! \brief Reset the counter + * + * This function will allow the MFT to restart the counter to + * its initial counting value in the register. + * + * \note The configuration is set in the MftDrv_SetSync() function to make + * sure that the MFT registers are updated by software trigger or hardware trigger. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] softwareTrigger : Selects the software trigger or hardware trigger to update COUNT register. + * - true: A software trigger is generate to update register + * - false: A software trigger is not implemented and need to update later or + * select a hardware trigger and waiting an external trigger for updating register. + */ +extern void MftDrv_CounterReset(MftDrvType *obj, bool softWareTrigger); + +/*! \brief Enables or disables the MFT dual edge capture mode. + * + * This function enables or disables the MFT dual edge capture mode. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] pairNum : The MFT peripheral channel pair number + * \param[in] enable : State of dual edge capture mode + * - true : To enable dual edge capture + * - false : To disable + */ +extern void MftDrv_SetDualEdgeCaptureCmd(MftDrvType *obj, uint8_t pairNum, bool enable); + +/*! \brief Enables or disables the MFT channel dual edge capture. + * + * This function enables or disables the MFT channel dual edge capture. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] pairNum : The MFT peripheral channel pair number + * \param[in] enable : State of dual edge capture mode + * - true : To enable dual edge capture + * - false : To disable + */ +extern void MftDrv_SetDualChannelDecap(MftDrvType *obj, uint8_t pairNum, bool enable); + +/*! \brief Enables or disables the MFT dual edge capture mode. + * + * This function enables or disables the MFT dual edge capture mode. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] pairNum : The MFT peripheral channel pair number + * \return Dual edge capture mode status + * - true : To enable dual edge capture + * - false: To disable + */ +extern bool MftDrv_GetDualEdgeCaptureCmd(MftDrvType *obj, uint8_t pairNum); + +/*! \brief Enables or disables the MFT complementary mode + * + * This function enables or disables the MFT complementary mode + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] pairNum : The MFT peripheral channel pair number + * \param[in] enable : State of complementary mode + * - true : To enable complementary + * - false : To disable + */ +extern void MftDrv_SetDualChannelComp(MftDrvType *obj, uint8_t pairNum, bool enable); + +/*! \brief Enables or disables the MFT combine mode + * + * This function enables or disables the MFT combine mode + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] pairNum : The MFT peripheral channel pair number + * \param[in] enable : State of combine mode + * - true : To enable combine + * - false : To disable + */ +extern void MftDrv_SetDualChannelCombine(MftDrvType *obj, uint8_t pairNum, bool enable); + +/*! \brief Enables or disables the MFT modified combine mode + * + * This function enables or disables the MFT modified combine mode + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] pairNum : The MFT peripheral channel pair number + * \param[in] enable : State of modified combine mode + * - true : To enable modified combine + * - false : To disable + */ +extern void MftDrv_SetDualChannelModifiedCombine(MftDrvType *obj, uint8_t pairNum, bool enable); + +/*! \brief Enables or disables the MFT dual channel fault + * + * This function enables or disables the MFT dual channel fault + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] pairNum : The MFT peripheral channel pair number + * \param[in] enable : State of dual channel fault + * - true : To enable dual channel fault + * - false : To disable + */ +extern void MftDrv_SetDualChannelFault(MftDrvType *obj, uint8_t pairNum, bool enable); + +/*! \brief Enables or disables the MFT dual channel PWM sync + * + * This function enables or disables the MFT dual channel PWM sync + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] pairNum : The MFT peripheral channel pair number + * \param[in] enable : State of dual channel PWM sync + * - true : To enable dual channel PWM sync + * - false : To disable + */ +extern void MftDrv_SetDualChannelPwmSync(MftDrvType *obj, uint8_t pairNum, bool enable); + +/*! \brief Enables or disables PWM channel Outputs + * + * This function enables or disables PWM channel Outputs + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] channel : The MFT peripheral channel number + * \param[in] enable : whether to enable PWM channel output + * - true : enable PWM channel output + * - false : disable PWM channel output + */ +extern void MftDrv_EnablePwmChannelOutputs(MftDrvType *obj, uint8_t channel, bool enable); + +/*! \brief Enables or disables the generation of the MFT peripheral timer channel trigger + * + * This function enables or disables the generation of the MFT peripheral timer channel trigger + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] channel : The MFT peripheral channel number + * \param[in] enable : State of trigger command + * - true : enable external trigger + * - false : disable external trigger + */ +extern void MftDrv_SetChannelTriggerCmd(MftDrvType *obj, uint8_t channel, bool enable); + +/*! \brief Sets the PWM Synchronization Software Trigger + * + * This function sets the PWM Synchronization Software Trigger + * + * \param[in] obj : pointer to MFT driver instance + */ +extern void MftDrv_SoftWareTrigger(MftDrvType *obj); + +/*! @}*/ + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _MFT_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_ch.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_ch.c new file mode 100644 index 0000000..e075780 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_ch.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "mft_oc_ch.h" +#include "mft_oc_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void MftOcCh_Init(MftOcChType *obj, struct _MftOcDrvType_ *ocDrv) +{ + obj->ocDrv = ocDrv; +} + +void MftOcCh_GetDefaultConfig(MftOcCh_ConfigType *userConfig) +{ + userConfig->hwChannelId = 0; /* Channel Id */ + userConfig->outputMode = MFTOCCH_TOGGLE_ON_MATCH; /* Output toggle on match */ + userConfig->enableExternalTrigger = false; /* Disable the generation of a trigger */ + userConfig->callbacksParams = NULL; /* Callback parameters for channel events */ + userConfig->callbackFunc = NULL; /* Callback function for channels events */ +} + +void MftOcCh_Config(MftOcChType *obj, const MftOcCh_ConfigType *userConfig) +{ + uint8_t hwChannel = 0U; + uint8_t chnlPairNum = 0U; + /* Check Channel Id */ + if(userConfig->hwChannelId >= MFT_CHANNEL_NUM) + { + return; + } + hwChannel = userConfig->hwChannelId; + + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->ocDrv->base->reg, 1); + + /* MSB:MSA = 0:1 set output compare mode*/ + MftReg_SetCscMsb(obj->ocDrv->base->reg, hwChannel, 0); + MftReg_SetCscMsa(obj->ocDrv->base->reg, hwChannel, 1); + + chnlPairNum = (uint8_t)(hwChannel >> 1U); + MftDrv_SetDualChannelComp(obj->ocDrv->base, chnlPairNum, false); + MftDrv_SetDualChannelCombine(obj->ocDrv->base, chnlPairNum, false); + MftDrv_SetDualEdgeCaptureCmd(obj->ocDrv->base, chnlPairNum, false); + /* Set Channel Output mode */ + MftDrv_SetOutputlevel(obj->ocDrv->base, hwChannel, userConfig->outputMode); + + /* Write initial count value for channel */ + MftReg_SetCvVal(obj->ocDrv->base->reg, hwChannel, userConfig->comparedValue); + /* Enable channel output */ + MftDrv_EnablePwmChannelOutputs(obj->ocDrv->base, hwChannel, true); + /* External trigger */ + MftDrv_SetChannelTriggerCmd(obj->ocDrv->base, hwChannel, userConfig->enableExternalTrigger); + /* Enable interrupt request for the current channel */ + MftReg_SetCscChie(obj->ocDrv->base->reg, userConfig->hwChannelId, 1); + + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->ocDrv->base->reg, 1); + + /* Remember the configuration */ + obj->config = *userConfig; +} + +void MftOcCh_Disarm(MftOcChType *obj) +{ + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->ocDrv->base->reg, 1); + + /* Clear combine mode */ + MftReg_SetCombineCombine0(obj->ocDrv->base->reg, 0); + MftReg_SetCombineCombine1(obj->ocDrv->base->reg, 0); + MftReg_SetCombineCombine2(obj->ocDrv->base->reg, 0); + MftReg_SetCombineCombine3(obj->ocDrv->base->reg, 0); + MftDrv_SetDualEdgeCaptureCmd(obj->ocDrv->base, obj->config.hwChannelId >> 1, false); + /* ELSnB:ELSnA = 0:0 (no edge) */ + MftReg_SetCscElsb(obj->ocDrv->base->reg, obj->config.hwChannelId, 0); + MftReg_SetCscElsa(obj->ocDrv->base->reg, obj->config.hwChannelId, 0); + /* Disable interrupt */ + MftReg_SetCscChie(obj->ocDrv->base->reg, obj->config.hwChannelId, 0); + /* Clear channel event flag */ + MftReg_SetCscChf(obj->ocDrv->base->reg, obj->config.hwChannelId, 0); + /* Disarm for channel (n+1) */ + /* ELSnB:ELSnA = 0:0 (no edge) */ + MftReg_SetCscElsb(obj->ocDrv->base->reg, (obj->config.hwChannelId | 1U), 0); + MftReg_SetCscElsa(obj->ocDrv->base->reg, (obj->config.hwChannelId | 1U), 0); + /* Disable interrupt */ + MftReg_SetCscChie(obj->ocDrv->base->reg, (obj->config.hwChannelId | 1U), 0); + /* Clear channel event flag */ + MftReg_SetCscChf(obj->ocDrv->base->reg, (obj->config.hwChannelId | 1U), 0); + + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->ocDrv->base->reg, 1); +} + +bool MftOcCh_UpdateOutputCompare(MftOcChType *obj, + uint16_t nextCompareMatchValue, + MftOcCh_OutputCompareUpdateType update, + bool softWareTrigger) +{ + bool retval = false; + uint16_t counterValue = MftReg_GetCntCount(obj->ocDrv->base->reg); + uint16_t compareValue = 0U; + uint16_t maxCounterValue = MftReg_GetModuloMod(obj->ocDrv->base->reg); + + if(update == MFTOCCH_RELATIVE_VALUE) + { + /* Configure channel compare register */ + if(nextCompareMatchValue > (maxCounterValue - counterValue)) + { + compareValue = (uint16_t)(nextCompareMatchValue - (maxCounterValue - counterValue)); + } + else + { + compareValue = (uint16_t)(counterValue + nextCompareMatchValue); + } + } + else + { + compareValue = nextCompareMatchValue; + } + /* Set CnV value and use software trigger for sync */ + MftReg_SetCvVal(obj->ocDrv->base->reg, obj->config.hwChannelId, compareValue); + MftReg_SetSyncSwSync(obj->ocDrv->base->reg, softWareTrigger); + return retval; +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_ch.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_ch.h new file mode 100644 index 0000000..22d6e81 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_ch.h @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MFT_OC_CH_H_ +#define _MFT_OC_CH_H_ + +/*! \brief Contains public interface to various functions related + * to the Output Compare channel of MFT + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup mft_oc_ch + * \ingroup mft_oc_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Selects mode operation int the output compare mode + */ +typedef enum +{ + MFTOCCH_DISABLE_OUTPUT = 0x00U, /*!< No action on output pin */ + MFTOCCH_TOGGLE_ON_MATCH = 0x01U, /*!< Toggle on match */ + MFTOCCH_CLEAR_ON_MATCH = 0x02U, /*!< Clear on match */ + MFTOCCH_SET_ON_MATCH = 0x03U /*!< Set on match */ +} MftOcCh_OutputCompareModeType; + +/*! \brief MFT output compare type of the next output compare value + */ +typedef enum +{ + MFTOCCH_RELATIVE_VALUE = 0x00U, /*!< Next compared value is relative to current value */ + MFTOCCH_ABSOLUTE_VALUE = 0x01U /*!< Next compared value is absolute */ +} MftOcCh_OutputCompareUpdateType; + +/*! \brief MFT driver output compare callback function prototype + */ +typedef void (*MftOcCh_CallbackType)(uint8_t event, void *params); + +/*! \brief MFT driver output compare parameters for each channel + */ +typedef struct _MftOcpCh_ConfigType_ +{ + uint8_t hwChannelId; /*!< Physical hardware channel ID*/ + MftOcCh_OutputCompareModeType outputMode; /*!< Channel output mode */ + uint16_t comparedValue; /*!< The compared value */ + bool enableExternalTrigger; /*!< true: enable the generation of a trigger is used for on-chip modules + * false: disable the generation of a trigger */ + void *callbacksParams; /*!< The parameters of callback functions for channels events */ + MftOcCh_CallbackType callbackFunc; /*!< The callback function for channels events */ +} MftOcCh_ConfigType; + +/* Forward declaration of MFT Output Compare driver */ +struct _MftOcDrvType_; + +/*! \brief The definition of MFT output compare channel prototype + */ +typedef struct _MftOcChType_ +{ + struct _MftOcDrvType_ *ocDrv; + MftOcCh_ConfigType config; +} MftOcChType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the MFT OC channel + * + * This function initializes MFT OC channel + * + * \param[in] obj : pointer to MFT OC channel instance + * \param[in] base : pointer to MFT driver instance + */ +extern void MftOcCh_Init(MftOcChType *obj, struct _MftOcDrvType_ *capDrv); + +/*! \brief Get default configuration of the MFT output compare channel + * + * This function gets default configures the MFT output compare module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void MftOcCh_GetDefaultConfig(MftOcCh_ConfigType *userConfig); + +/*! \brief Configure the MFT output compare channel + * + * This function configures the channel in the output compare mode for generate timed pulses. + * When the MFT counter matches the value of CnV, the channel output is changed based on what + * is specified in the output mode argument. + * + * \param[in] obj : pointer to MFT CAP channel instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void MftOcCh_Config(MftOcChType *obj, const MftOcCh_ConfigType *userConfig); + +/*! \brief Disarm the MFT Output Compare channel + * + * This function disables output compare mode and clears MFT timer configuration + * + * \param[in] obj : pointer to MFT OC channel instance + */ +extern void MftOcCh_Disarm(MftOcChType *obj); + +/*! \brief Sets the next compare match value based on the current counter value + * + * \param[in] obj : pointer to MFT OC channel instance + * \param[in] nextCompareMatchValue : Timer value in ticks until the next compare match event should appear + * \param[in] update : + * - MFTOCCH_RELATIVE_VALUE : nextComparemantchValue will be added to current counter value + * - MFTOCCH_ABSOLUTE_VALUE : nextComparemantchValue will be written in counter register as it is + * \param[in] softwareTrigger : This parameter will be true if software trigger sync is enabled and the user + * want to generate a software trigger (the value from buffer will be moved to register immediate or at next + * loading point depending on the sync configuration). Otherwise this parameter must be false and the next + * compared value will be stored in buffer untill a trigger signal will be received. + */ +extern bool MftOcCh_UpdateOutputCompare(MftOcChType *obj, + uint16_t nextCompareMatchValue, + MftOcCh_OutputCompareUpdateType update, + bool softwareTrigger); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _MFT_OC_CH_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_drv.c new file mode 100644 index 0000000..d767650 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_drv.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "mft_oc_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void MftOcDrv_Init(MftOcDrvType *obj, MftDrvType *base) +{ + obj->base = base; + + uint8_t i = 0; + for(i = 0; i < MFT_CHANNEL_NUM; ++i) + { + MftOcCh_Init(&obj->channel[i], obj); + } +} + +void MftOcDrv_GetDefaultConfig(MftOcDrv_ConfigType *userConfig) +{ + userConfig->maxCountValue = 65535; +} + +void MftOcDrv_Config(MftOcDrvType *obj, const MftOcDrv_ConfigType *userConfig) +{ + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->base->reg, 1); + + /* CNTIN = 0 */ + MftReg_SetCntInCntInit(obj->base->reg, 0U); + /* Set MOD */ + MftReg_SetModuloMod(obj->base->reg, userConfig->maxCountValue); + + /* Configure sync for OUTMASK register */ + MftReg_SetSynConfSwOM(obj->base->reg, 1); + /* Configure sync for INVCTRL register */ + MftReg_SetSynConfSwInvC(obj->base->reg, 1); + /* Configure sync for SWOCTRL register */ + MftReg_SetSynConfSwSoc(obj->base->reg, 1); + /* Configure sync for MOD, HCR, CNTIN, and CnV registers */ + MftReg_SetSynConfSwWrbuf(obj->base->reg, 1); + /* Configure synchronization method (waiting next loading point or now) */ + MftReg_SetSynConfSwRstCnt(obj->base->reg, 1); + /* Enhanced PWM sync is used */ + MftReg_SetSynConfSyncMode(obj->base->reg, 1); + /* Configure sync for CNTIN register updated with its buffer value at system_clock*/ + MftReg_SetSynConfCntInC(obj->base->reg, 0); + + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->base->reg, 1); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_drv.h new file mode 100644 index 0000000..ec420cf --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_drv.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MFT_OC_DRV_H_ +#define _MFT_OC_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the Output Compare driver of MFT + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../mft_drv.h" +#include "mft_oc_ch.h" + +/*! \addtogroup mft_oc_drv + * \ingroup mft_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +/*! \brief MFT Output compare driver configuration + */ +typedef struct _MftOcDrv_ConfigType_ +{ + uint16_t maxCountValue; /*!< Maximum counter value. Minimum value is 0 for this mode */ +} MftOcDrv_ConfigType; + +/*! \brief The definition of MFT output compare driver prototype + * \details Derived from MFT driver + */ +typedef struct _MftOcDrvType_ +{ + MftDrvType *base; /*!< base class of capture driver */ + MftOcChType channel[MFT_CHANNEL_NUM]; /*!< channels of the capture mode */ +} MftOcDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the MFT OC module + * + * This function initializes MFT OC driver by setting the MFT driver + * instance to it. + * + * \param[in] obj : pointer to MFT OC channel instance + * \param[in] base : pointer to MFT driver instance + */ +extern void MftOcDrv_Init(MftOcDrvType *obj, MftDrvType *base); + +/*! \brief Get default configures the MFT output compare module for configuration structure + * + * This function gets default configures the MFT output compare module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void MftOcDrv_GetDefaultConfig(MftOcDrv_ConfigType *userConfig); + +/*! \brief Configure the MFT output compare module + * + * This function configures the MFT output compare module. + * + * \param[in] obj : pointer to MFT OC channel instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void MftOcDrv_Config(MftOcDrvType *obj, const MftOcDrv_ConfigType *userConfig); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _MFT_OC_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_ch.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_ch.c new file mode 100644 index 0000000..edb0a11 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_ch.c @@ -0,0 +1,353 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "mft_pwm_ch.h" +#include "mft_pwm_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +/*! \brief Set the polarity of the channel + * + * This function sets the polarity of the channel + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] channel : The MFT peripheral channel number + * \param[in] polarity : the polarity of the channel + */ +static inline void MftPwmCh_SetPolarity(MftPwmChType *obj, uint8_t channel, MftPwmCh_PolarityType polarity) +{ + switch(channel) + { + case 0: + MftReg_SetPolPol0(obj->pwmDrv->base->reg, (uint8_t)polarity); + break; + case 1: + MftReg_SetPolPol1(obj->pwmDrv->base->reg, (uint8_t)polarity); + break; + case 2: + MftReg_SetPolPol2(obj->pwmDrv->base->reg, (uint8_t)polarity); + break; + case 3: + MftReg_SetPolPol3(obj->pwmDrv->base->reg, (uint8_t)polarity); + break; + case 4: + MftReg_SetPolPol4(obj->pwmDrv->base->reg, (uint8_t)polarity); + break; + case 5: + MftReg_SetPolPol5(obj->pwmDrv->base->reg, (uint8_t)polarity); + break; + case 6: + MftReg_SetPolPol6(obj->pwmDrv->base->reg, (uint8_t)polarity); + break; + case 7: + MftReg_SetPolPol7(obj->pwmDrv->base->reg, (uint8_t)polarity); + break; + default: + break; + } +} + +/*! \brief Enables or disables PWM channel pair deadtime insertion. + * + * This function enables or disables PWM channel pair deadtime insertion. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] pairNum : The MFT peripheral channel number + * \param[in] enable : whether to enable PWM channel pair deadtime insertion. + * - true : enable PWM channel pair deadtime insertion. + * - false : disable PWM channel pair deadtime insertion. + */ +static inline void MftPwmCh_SetDualChannelDeadtimeCmd(MftPwmChType *obj, uint8_t pairNum, bool enable) +{ + uint8_t enableValue = enable ? 1 : 0; + switch(pairNum) + { + case 0: + MftReg_SetCombineDtEn0(obj->pwmDrv->base->reg, enableValue); + break; + case 1: + MftReg_SetCombineDtEn1(obj->pwmDrv->base->reg, enableValue); + break; + case 2: + MftReg_SetCombineDtEn2(obj->pwmDrv->base->reg, enableValue); + break; + case 3: + MftReg_SetCombineDtEn3(obj->pwmDrv->base->reg, enableValue); + break; + default: + break; + } +} + +void MftPwmCh_Init(MftPwmChType *obj, struct _MftPwmDrvType_ *pwmDrv) +{ + obj->pwmDrv = pwmDrv; +} + +void MftPwmCh_GetDefaultConfig(MftPwmCh_ConfigType *userConfig) +{ + userConfig->hwChannelId = 0; + userConfig->pulseMode = MFTPWMCH_SET_ON_MATCH_UP; + userConfig->mainChannelPolarity = MFTPWMCH_ACTIVE_HIGH; + userConfig->enableExternalTrigger = false; + userConfig->enableFaultCtrl = false; + userConfig->enableSecondChannelOutput = false; + userConfig->enableComplementary = false; + userConfig->enableCombine = false; + userConfig->enableModifiedCombine = false; + userConfig->deadTime = false; + userConfig->secondChannelPolarity = MFTPWMCH_ACTIVE_HIGH; + userConfig->enableExternalTriggerOnNextChn = false; +} + +bool MftPwmCh_Config(MftPwmChType *obj, const MftPwmCh_ConfigType *userConfig) +{ + bool status = true; + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->pwmDrv->base->reg, 1); + + obj->config.hwChannelId = userConfig->hwChannelId; + /* MSB:MSA = 1:1 */ + MftReg_SetCscMsb(obj->pwmDrv->base->reg, obj->config.hwChannelId, 1); + MftReg_SetCscMsa(obj->pwmDrv->base->reg, obj->config.hwChannelId, 1); + + if(false == userConfig->enableSecondChannelOutput) + { + /* Independent channel */ + /* Set Polarity */ + MftPwmCh_SetPolarity(obj, userConfig->hwChannelId, userConfig->mainChannelPolarity); + /* Set pulse mode */ + if(MFTPWMCH_CLEAR_ON_MATCH_UP == userConfig->pulseMode) + { + /* ELSnB:ELSnA = 1:0 */ + MftReg_SetCscElsb(obj->pwmDrv->base->reg, userConfig->hwChannelId, 1); + MftReg_SetCscElsa(obj->pwmDrv->base->reg, userConfig->hwChannelId, 0); + } + else if(MFTPWMCH_SET_ON_MATCH_UP == userConfig->pulseMode) + { + /* ELSnB:ELSnA = 0:1 */ + MftReg_SetCscElsb(obj->pwmDrv->base->reg, userConfig->hwChannelId, 0); + MftReg_SetCscElsa(obj->pwmDrv->base->reg, userConfig->hwChannelId, 1); + } + uint8_t pairNum = userConfig->hwChannelId >> 1; + /* COMP = 0 */ + MftDrv_SetDualChannelComp(obj->pwmDrv->base, pairNum, false); + /* COMBINE = 0 */ + MftDrv_SetDualChannelCombine(obj->pwmDrv->base, pairNum, false); + /* MCOMBINE = 0 */ + MftDrv_SetDualChannelModifiedCombine(obj->pwmDrv->base, pairNum, false); + /* DECAP = 0 */ + MftDrv_SetDualChannelDecap(obj->pwmDrv->base, pairNum, false); + /* FAULTEN */ + MftDrv_SetDualChannelFault(obj->pwmDrv->base, pairNum, userConfig->enableFaultCtrl); + /* PWMSYNC */ + MftDrv_SetDualChannelPwmSync(obj->pwmDrv->base, pairNum, true); + /* External trigger */ + MftDrv_SetChannelTriggerCmd(obj->pwmDrv->base, userConfig->hwChannelId, userConfig->enableExternalTrigger); + /* Enable PWM output on channel (n) */ + MftDrv_EnablePwmChannelOutputs(obj->pwmDrv->base, userConfig->hwChannelId, true); + } + else + { + if(userConfig->hwChannelId % 2 != 0) + { + /* Must be even */ + return false; + } + /* MSB:MSA = 1:1 */ + MftReg_SetCscMsb(obj->pwmDrv->base->reg, userConfig->hwChannelId + 1, 1); + MftReg_SetCscMsa(obj->pwmDrv->base->reg, userConfig->hwChannelId + 1, 1); + + /* Dual channel modes */ + uint8_t pairNum = userConfig->hwChannelId >> 1; + /* DECAP = 0 */ + MftDrv_SetDualChannelDecap(obj->pwmDrv->base, pairNum, false); + /* PWMSYNC */ + MftDrv_SetDualChannelPwmSync(obj->pwmDrv->base, pairNum, true); + /* Set Polarity */ + MftPwmCh_SetPolarity(obj, userConfig->hwChannelId, userConfig->mainChannelPolarity); + MftPwmCh_SetPolarity(obj, userConfig->hwChannelId + 1, userConfig->secondChannelPolarity); + /* External trigger */ + MftDrv_SetChannelTriggerCmd(obj->pwmDrv->base, userConfig->hwChannelId, userConfig->enableExternalTrigger); + MftDrv_SetChannelTriggerCmd(obj->pwmDrv->base, userConfig->hwChannelId + 1, userConfig->enableExternalTriggerOnNextChn); + /* Enable PWM output on channel (n) and channel (n+1) */ + MftDrv_EnablePwmChannelOutputs(obj->pwmDrv->base, userConfig->hwChannelId, true); + MftDrv_EnablePwmChannelOutputs(obj->pwmDrv->base, userConfig->hwChannelId + 1, true); + /* FAULTEN */ + MftDrv_SetDualChannelFault(obj->pwmDrv->base, pairNum, userConfig->enableFaultCtrl); + if(true == userConfig->enableComplementary) + { + /* Complementary Mode, this configure has higher priority than combined/mcombined mode */ + /* COMP = 1 */ + MftDrv_SetDualChannelComp(obj->pwmDrv->base, pairNum, true); + + /* MCOMBINE = 0 */ + MftDrv_SetDualChannelModifiedCombine(obj->pwmDrv->base, pairNum, false); + /* Dead time */ + MftPwmCh_SetDualChannelDeadtimeCmd(obj, pairNum, userConfig->deadTime); + + if(MftReg_GetScCPwms(obj->pwmDrv->base->reg)) + { + /* COMBINE = 0 */ + MftDrv_SetDualChannelCombine(obj->pwmDrv->base, pairNum, false); + /* Set pulse mode */ + if(MFTPWMCH_CLEAR_ON_MATCH_UP == userConfig->pulseMode) + { + /* ELSnB:ELSnA = 1:0 */ + /* ELSnB:ELSnA of channel (n+1) not used */ + MftReg_SetCscElsb(obj->pwmDrv->base->reg, userConfig->hwChannelId, 1); + MftReg_SetCscElsa(obj->pwmDrv->base->reg, userConfig->hwChannelId, 0); + } + else if(MFTPWMCH_SET_ON_MATCH_UP == userConfig->pulseMode) + { + /* ELSnB:ELSnA = 0:1 */ + /* ELSnB:ELSnA of channel (n+1) not used */ + MftReg_SetCscElsb(obj->pwmDrv->base->reg, userConfig->hwChannelId, 0); + MftReg_SetCscElsa(obj->pwmDrv->base->reg, userConfig->hwChannelId, 1); + } + } + else + { + /* COMBINE = 1 */ + MftDrv_SetDualChannelCombine(obj->pwmDrv->base, pairNum, true); + + /* Set pulse mode */ + if(MFTPWMCH_SET_ON_MATCH_UP == userConfig->pulseMode) + { + /* ELSnB:ELSnA = 1:0 */ + /* ELSnB:ELSnA of channel (n+1) not used */ + MftReg_SetCscElsb(obj->pwmDrv->base->reg, userConfig->hwChannelId, 1); + MftReg_SetCscElsa(obj->pwmDrv->base->reg, userConfig->hwChannelId, 0); + } + else if(MFTPWMCH_CLEAR_ON_MATCH_UP == userConfig->pulseMode) + { + /* ELSnB:ELSnA = 0:1 */ + /* ELSnB:ELSnA of channel (n+1) not used */ + MftReg_SetCscElsb(obj->pwmDrv->base->reg, userConfig->hwChannelId, 0); + MftReg_SetCscElsa(obj->pwmDrv->base->reg, userConfig->hwChannelId, 1); + } + } + } + else if(false == userConfig->enableModifiedCombine + && true == userConfig->enableCombine) + { + if(MftReg_GetScCPwms(obj->pwmDrv->base->reg)) + { + /* CPWM does not support Combine mode*/ + status = false; + } + else + { + /* Combine Mode */ + /* COMP = 0 */ + MftDrv_SetDualChannelComp(obj->pwmDrv->base, pairNum, false); + /* COMBINE = 1 */ + MftDrv_SetDualChannelCombine(obj->pwmDrv->base, pairNum, true); + /* MCOMBINE = 0 */ + MftDrv_SetDualChannelModifiedCombine(obj->pwmDrv->base, pairNum, false); + /* Set pulse mode */ + if(MFTPWMCH_SET_ON_MATCH_UP == userConfig->pulseMode) + { + /* ELSnB:ELSnA = 1:0 */ + /* ELSnB:ELSnA of channel (n+1) not used */ + MftReg_SetCscElsb(obj->pwmDrv->base->reg, userConfig->hwChannelId, 1); + MftReg_SetCscElsa(obj->pwmDrv->base->reg, userConfig->hwChannelId, 0); + } + else if(MFTPWMCH_CLEAR_ON_MATCH_UP == userConfig->pulseMode) + { + /* ELSnB:ELSnA = 0:1 */ + /* ELSnB:ELSnA of channel (n+1) not used */ + MftReg_SetCscElsb(obj->pwmDrv->base->reg, userConfig->hwChannelId, 0); + MftReg_SetCscElsa(obj->pwmDrv->base->reg, userConfig->hwChannelId, 1); + } + } + } + else if(true == userConfig->enableModifiedCombine + && true == userConfig->enableCombine) + { + if(MftReg_GetScCPwms(obj->pwmDrv->base->reg)) + { + /* CPWM does not support Combine mode */ + status = false; + } + else + { + /* Modified combine Mode */ + /* COMP = 0 */ + MftDrv_SetDualChannelComp(obj->pwmDrv->base, pairNum, false); + /* COMBINE = 1 */ + MftDrv_SetDualChannelCombine(obj->pwmDrv->base, pairNum, true); + /* MCOMBINE = 1 */ + MftDrv_SetDualChannelModifiedCombine(obj->pwmDrv->base, pairNum, true); + /* Set pulse mode */ + if(MFTPWMCH_SET_ON_MATCH_UP == userConfig->pulseMode) + { + /* ELSnB:ELSnA = 1:0 */ + /* ELSnB:ELSnA of channel (n+1) not used */ + MftReg_SetCscElsb(obj->pwmDrv->base->reg, userConfig->hwChannelId, 1); + MftReg_SetCscElsa(obj->pwmDrv->base->reg, userConfig->hwChannelId, 0); + } + else if(MFTPWMCH_CLEAR_ON_MATCH_UP == userConfig->pulseMode) + { + /* ELSnB:ELSnA = 0:1 */ + /* ELSnB:ELSnA of channel (n+1) not used */ + MftReg_SetCscElsb(obj->pwmDrv->base->reg, userConfig->hwChannelId, 0); + MftReg_SetCscElsa(obj->pwmDrv->base->reg, userConfig->hwChannelId, 1); + } + } + } + } + + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->pwmDrv->base->reg, 1); + + obj->config = *userConfig; + + return status; +} + +void MftPwmCh_SetChannelValue(MftPwmChType *obj, uint16_t firstValue, uint16_t secondValue) +{ + MftReg_SetCvVal(obj->pwmDrv->base->reg, obj->config.hwChannelId, firstValue); + if(obj->config.enableSecondChannelOutput) + { + MftReg_SetCvVal(obj->pwmDrv->base->reg, obj->config.hwChannelId + 1, secondValue); + } +} + +void MftPwmCh_EnableOutput(MftPwmChType *obj, bool enable) +{ + MftDrv_EnablePwmChannelOutputs(obj->pwmDrv->base, obj->config.hwChannelId, enable); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_ch.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_ch.h new file mode 100644 index 0000000..872c614 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_ch.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MFT_PWM_CH_H_ +#define _MFT_PWM_CH_H_ + +/*! \brief Contains public interface to various functions related + * to the PWM output channel of MFT + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup mft_pwm_ch + * \ingroup mft_pwm_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The polarity of the channel output is configured in PWM signal + */ +typedef enum +{ + MFTPWMCH_ACTIVE_HIGH = 0x00U, /*!< The channel polarity is active HIGH */ + MFTPWMCH_ACTIVE_LOW = 0x01U /*!< The channel polarity is active LOW */ +} MftPwmCh_PolarityType; + +/*! \brief The pulse mode of PWM + */ +typedef enum +{ + MFTPWMCH_SET_ON_MATCH_UP, /*!< The channel set when counter matches CV in up-counting */ + MFTPWMCH_CLEAR_ON_MATCH_UP /*!< The channel clear when counter matches CV in up-counting */ +} MftPwmCh_PulseModeType; + +/*! \brief MFT driver combined PWM parameter + */ +typedef struct +{ + /* Independent channel configuration */ + uint8_t hwChannelId; /*!< Physical hardware channel ID for channel (n) */ + MftPwmCh_PulseModeType pulseMode; /*!< The mode of pulse */ + MftPwmCh_PolarityType mainChannelPolarity; /*!< Polarity of the PWM signal generated on MCU pin for channel n.*/ + bool enableExternalTrigger; /*!< The generation of the channel (n) trigger */ + bool enableFaultCtrl; /*!< Enable/disable fault control for this pair */ + /* Dual channels configuration */ + bool enableSecondChannelOutput; /*!< Select if channel (n+1) output is enabled/disabled for the complementary mode */ + bool enableComplementary; /*!< Enable the complementary mode for channels (n) and (n+1) */ + bool enableCombine; /*!< Enable the combine mode for channels (n) and (n+1) */ + bool enableModifiedCombine; /*!< Enable the modified combine mode for channels (n) and (n+1) */ + bool deadTime; /*!< Enable/disable dead time for channel */ + MftPwmCh_PolarityType secondChannelPolarity; /*!< Select channel (n+1) polarity relative to channel (n) in the complementary mode */ + bool enableExternalTriggerOnNextChn; /*!< The generation of the channel (n+1) trigger */ +} MftPwmCh_ConfigType; + +/* Forward declaration of MFT PWM driver */ +struct _MftPwmDrvType_; + +/*! \brief The definition of MFT PWM channel prototype + */ +typedef struct _MftPwmChType_ +{ + struct _MftPwmDrvType_ *pwmDrv; /*!< pointer to the PWM driver instance */ + MftPwmCh_ConfigType config; /*!< configuration of this channel */ +} MftPwmChType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the MFT PWM channel + * + * This function initializes MFT PWM channel. + * + * \param[in] obj : pointer to MFT PWM channel instance + * \param[in] base : pointer to MFT driver instance + */ +extern void MftPwmCh_Init(MftPwmChType *obj, struct _MftPwmDrvType_ *pwmDrv); + +/*! \brief Get default configures the MFT PWM module for configuration structure + * + * This function gets default configures the MFT PWM module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void MftPwmCh_GetDefaultConfig(MftPwmCh_ConfigType *userConfig); + +/*! \brief Configure the MFT PWM channel + * + * This function configures the channel in the PWM mode. The channel can + * be both independent mode or combined mode. + * + * \param[in] obj : pointer to MFT PWM channel instance + * \param[in] userConfig : pointer to configuration structure + * \return The result of the operation + * - true : success + * - false : failed + */ +extern bool MftPwmCh_Config(MftPwmChType *obj, const MftPwmCh_ConfigType *userConfig); + +/*! \brief Set the MFT PWM channel value + * + * This function set the MFT channel value. + * + * \note If the channel is independent, the second value has no effect. + * If the channel is in complementary mode, the second value also + * has no effect. + * + * \param[in] obj : pointer to MFT PWM channel instance + * \param[in] firstValue : the value of first channel + * \param[in] secondValue : the value of second channel + * if the first channel is independent, this value has no effect + */ +extern void MftPwmCh_SetChannelValue(MftPwmChType *obj, uint16_t firstValue, uint16_t secondValue); + +/*! \brief Enables or disables the channel output + * + * This function enables or disables the channel output + * + * \param[in] obj : pointer to MFT PWM channel instance + * \param[in] enable : whether to enable channel output + * - true : enable PWM output + * - false : disable PWM output + */ +extern void MftPwmCh_EnableOutput(MftPwmChType *obj, bool enable); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _MFT_PWM_CH_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_drv.c new file mode 100644 index 0000000..acf79b0 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_drv.c @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "mft_pwm_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +/*! \brief This function configures sync mechanism for some MFT registers + * + * This function configure the synchronization for PWM register (CnV, MOD, CINT, HCR, OUTMASK). + * If this function is used whit wrong parameters it's possible to generate wrong waveform. + * Registers synchronization need to be configured for PWM and output compare mode. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] param : pwm sync config + * \return The result of the operation + * - true : success + * - false : failed + */ +bool MftPwmDrv_SetSync(MftPwmDrvType *obj, const MftPwmDrv_SyncType *param) +{ + bool hardwareSync = param->hardwareSync0 || param->hardwareSync1 || param->hardwareSync2; + + /* Software and hardware triggers are not allowed in the same time */ + if((param->softwareSync && hardwareSync) || (true != (param->softwareSync || hardwareSync))) + { + return false; + } + + if(param->softwareSync) + { + /* Configure sync for OUTMASK register */ + MftReg_SetSynConfSwOM(obj->base->reg, 1); + /* Configure sync for INVCTRL register */ + MftReg_SetSynConfSwInvC(obj->base->reg, 1); + /* Configure sync for SWOCTRL register */ + MftReg_SetSynConfSwSoc(obj->base->reg, 1); + /* Configure sync for MOD, HCR, CNTIN, and CnV registers */ + MftReg_SetSynConfSwWrbuf(obj->base->reg, 1); + /* Configure synchronization method (waiting next loading point or now) */ + MftReg_SetSynConfSwRstCnt(obj->base->reg, param->syncPoint); + } + else + { + /* Configure sync for OUTMASK register */ + MftReg_SetSynConfHwOM(obj->base->reg, 1); + /* Configure sync for INVCTRL register */ + MftReg_SetSynConfHwInvC(obj->base->reg, 1); + /* Configure sync for SWOCTRL register */ + MftReg_SetSynConfHwSoc(obj->base->reg, 1); + /* Configure sync for MOD, HCR, CNTIN, and CnV registers */ + MftReg_SetSynConfHwWrbuf(obj->base->reg, 1); + /* Configure synchronization method (waiting next loading point or now) */ + MftReg_SetSynConfHwRstCnt(obj->base->reg, param->syncPoint); + } + + /* Enhanced PWM sync is used */ + MftReg_SetSynConfSyncMode(obj->base->reg, 1); + /* Configure trigger source for sync */ + MftReg_SetSyncTrig0(obj->base->reg, param->hardwareSync0 ? 1 : 0); + MftReg_SetSyncTrig1(obj->base->reg, param->hardwareSync1 ? 1 : 0); + MftReg_SetSyncTrig2(obj->base->reg, param->hardwareSync2 ? 1 : 0); + /* Configure loading points */ + MftReg_SetSyncCntMax(obj->base->reg, param->maxLoadingPoint); + MftReg_SetSyncCntMin(obj->base->reg, param->minLoadingPoint); + /* Configure sync for OUTMASK register */ + MftReg_SetSyncSynchOM(obj->base->reg, (bool)param->maskRegSync); + /* Configure sync for INVCTRL register */ + MftReg_SetSynConfInvC(obj->base->reg, param->inverterSync); + /* Configure sync for SWOCTRL register */ + MftReg_SetSynConfSwOC(obj->base->reg, param->outRegSync); + /* Configure sync for CNTIN register */ + MftReg_SetSynConfCntInC(obj->base->reg, param->initCounterSync); + /* Configure hardware trigger mode */ + MftReg_SetSynConfHwTrigMode(obj->base->reg, param->autoClearTrigger); + + return true; +} + +void MftPwmDrv_Init(MftPwmDrvType *obj, MftDrvType *base) +{ + obj->base = base; + + uint8_t i = 0; + for(i = 0; i < MFT_CHANNEL_NUM; ++i) + { + MftPwmCh_Init(&obj->channel[i], obj); + } +} + +void MftPwmDrv_GetDefaultConfig(MftPwmDrv_ConfigType *userConfig) +{ + userConfig->periodValue = 65536; + + userConfig->syncMethod.softwareSync = true; + userConfig->syncMethod.hardwareSync0 = false; + userConfig->syncMethod.hardwareSync1 = false; + userConfig->syncMethod.hardwareSync2 = false; + userConfig->syncMethod.maxLoadingPoint = false; + userConfig->syncMethod.minLoadingPoint = false; + userConfig->syncMethod.inverterSync = MFTPWMDRV_SYSTEM_CLOCK; + userConfig->syncMethod.outRegSync = MFTPWMDRV_SYSTEM_CLOCK; + userConfig->syncMethod.maskRegSync = MFTPWMDRV_SYSTEM_CLOCK; + userConfig->syncMethod.initCounterSync = MFTPWMDRV_SYSTEM_CLOCK; + userConfig->syncMethod.autoClearTrigger = true; + userConfig->syncMethod.syncPoint = MFTPWMDRV_WAIT_LOADING_POINTS; + + userConfig->faultConfig.enableTriStateOnFault = false; + userConfig->faultConfig.faultFilterValue = 0; + userConfig->faultConfig.faultMode = MFTPWMDRV_FAULT_CTRL_DISABLED; + uint8_t i = 0; + for(i = 0; i < MFT_FAULT_INPUT_NUM; ++i) + { + userConfig->faultConfig.faultInput[i].enabled = false; + userConfig->faultConfig.faultInput[i].filterEnabled = false; + userConfig->faultConfig.faultInput[i].inputPolarity = MFTPWMDRV_FAULT_ACTIVE_HIGH; + } + + userConfig->deadTimeCount = 0; + userConfig->deadTimePrescaler = MFTPWMDRV_DEADTIME_DIVID_BY_1; +} + +void MftPwmDrv_Config(MftPwmDrvType *obj, const MftPwmDrv_ConfigType *userConfig) +{ + /* Configure MFT PWM module */ + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->base->reg, 1); + + /* In PWM mode CNTIN is to be set 0*/ + MftReg_SetCntInCntInit(obj->base->reg, 0U); + /* Set period */ + MftReg_SetModuloMod(obj->base->reg, userConfig->periodValue); + /* Sync config */ + MftPwmDrv_SetSync(obj, &userConfig->syncMethod); + + /* Enable faults (if faults were configured) */ + if(userConfig->faultConfig.faultMode != MFTPWMDRV_FAULT_CTRL_DISABLED) + { + /* Configure PWM Output behavior */ + MftReg_SetFltCtrlFstate(obj->base->reg, userConfig->faultConfig.enableTriStateOnFault ? 1 : 0); + /* Configure fault filter value */ + MftReg_SetFltCtrlFFVal(obj->base->reg, userConfig->faultConfig.faultFilterValue); + uint8_t i = 0; + for(i = 0; i < MFT_FAULT_INPUT_NUM; ++i) + { + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(i) + { + case 0: + MftReg_SetFltCtrlFault0En(obj->base->reg, userConfig->faultConfig.faultInput[0].enabled ? 1 : 0); + MftReg_SetFltCtrlFFltr0En(obj->base->reg, userConfig->faultConfig.faultInput[0].filterEnabled ? 1 : 0); + MftReg_SetFltPolFlt0Pol(obj->base->reg, userConfig->faultConfig.faultInput[0].inputPolarity); + break; + case 1: + MftReg_SetFltCtrlFault1En(obj->base->reg, userConfig->faultConfig.faultInput[1].enabled ? 1 : 0); + MftReg_SetFltCtrlFFltr1En(obj->base->reg, userConfig->faultConfig.faultInput[1].filterEnabled ? 1 : 0); + MftReg_SetFltPolFlt1Pol(obj->base->reg, userConfig->faultConfig.faultInput[1].inputPolarity); + break; + case 2: + MftReg_SetFltCtrlFault2En(obj->base->reg, userConfig->faultConfig.faultInput[2].enabled ? 1 : 0); + MftReg_SetFltCtrlFFltr2En(obj->base->reg, userConfig->faultConfig.faultInput[2].filterEnabled ? 1 : 0); + MftReg_SetFltPolFlt2Pol(obj->base->reg, userConfig->faultConfig.faultInput[2].inputPolarity); + break; + case 3: + MftReg_SetFltCtrlFault3En(obj->base->reg, userConfig->faultConfig.faultInput[3].enabled ? 1 : 0); + MftReg_SetFltCtrlFFltr3En(obj->base->reg, userConfig->faultConfig.faultInput[3].filterEnabled ? 1 : 0); + MftReg_SetFltPolFlt3Pol(obj->base->reg, userConfig->faultConfig.faultInput[3].inputPolarity); + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + } + MftReg_SetModeFaultM(obj->base->reg, userConfig->faultConfig.faultMode); + } + + MftReg_SetDeadTimeDtPs(obj->base->reg, userConfig->deadTimePrescaler); + MftReg_SetDeadTimeDtVal(obj->base->reg, userConfig->deadTimeCount); + + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->base->reg, 1); +} + +void MftPwmDrv_SetInitOutputCmd(MftPwmDrvType *obj, bool enable) +{ + /* Set enable outputs to be set to Initial/default value */ + MftReg_SetModeInit(obj->base->reg, 1); +} + +void MftPwmDrv_SetPeriod(MftPwmDrvType *obj, uint16_t value) +{ + MftReg_SetModuloMod(obj->base->reg, value); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_drv.h new file mode 100644 index 0000000..8bf4801 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_drv.h @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MFT_PWM_DRV_H_ +#define _MFT_PWM_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the PWM driver of MFT + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../mft_drv.h" +#include "mft_pwm_ch.h" + +/*! \addtogroup mft_pwm_drv + * \ingroup mft_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief MFT fault control mode + */ +typedef enum +{ + MFTPWMDRV_FAULT_CTRL_DISABLED = 0x00U, /*!< Fault control is disabled for all channels */ + MFTPWMDRV_FAULT_CTRL_MAN_EVEN = 0x01U, /*!< Fault control is enabled for even channels + * only (channels 0, 2, 4, and 6), and the selected + * mode is the manual fault clearing */ + MFTPWMDRV_FAULT_CTRL_MAN_ALL = 0x02U, /*!< Fault control is enabled for all channels, + * and the selected mode is the manual fault clearing */ + MFTPWMDRV_FAULT_CTRL_AUTO_ALL = 0x03U /*!< Fault control is enabled for all channels, and + * the selected mode is the automatic fault clearing */ +} MftPwmDrv_FaultModeType; + +/*! \brief MFT PWM Fault channel polarity + */ +typedef enum +{ + MFTPWMDRV_FAULT_ACTIVE_HIGH = 0x00U, /*!< The fault occurs on the input (n) when it's HIGH, the input is LOW when no fault */ + MFTPWMDRV_FAULT_ACTIVE_LOW = 0x01U /*!< The fault occurs on the input (n) when it's LOW, the input is HIGH when no fault */ +} MftPwmDrv_FaultChannelPolarityType; + +/*! \brief MFT PWM Fault channel parameters + */ +typedef struct +{ + bool enabled; /*!< Fault channel state */ + bool filterEnabled; /*!< Fault channel filter state */ + MftPwmDrv_FaultChannelPolarityType inputPolarity; /*!< Fault channel input polarity */ +} MftPwmDrv_FaultChannelConfigType; + +/*! \brief FlexTimer driver PWM Fault parameter + */ +typedef struct +{ + bool enableTriStateOnFault; /*!< Output pin state on fault (safe state or tri-state) */ + uint8_t faultFilterValue; /*!< Fault filter value */ + MftPwmDrv_FaultModeType faultMode; /*!< Fault mode */ + MftPwmDrv_FaultChannelConfigType faultInput[MFT_FAULT_INPUT_NUM]; /*!< fault channels */ +} MftPwmDrv_FaultConfigType; + +/*! \brief MFT sync source + */ +typedef enum +{ + MFTPWMDRV_SYSTEM_CLOCK = 0U, /*!< Register is updated with its buffer value at all rising edges of system clock */ + MFTPWMDRV_PWM_SYNC = 1U /*!< Register is updated with its buffer value at the MFT synchronization */ +} MftPwmDrv_UpdateConfigType; + +/*! \brief MFT updated config + */ +typedef enum +{ + MFTPWMDRV_WAIT_LOADING_POINTS = 0U, /*!< MFT register is updated at first loading point */ + MFTPWMDRV_UPDATE_NOW = 1U /*!< MFT register is updated immediately */ +} MftPwmDrv_SyncModeConfigType; + +/*! \brief MFT pwm sync structure + */ +typedef struct _MftPwmDrv_SyncType_ +{ + bool softwareSync; /*!< True - enable software sync, False - disable software sync */ + bool hardwareSync0; /*!< True - enable hardware 0 sync, False - disable hardware 0 sync */ + bool hardwareSync1; /*!< True - enable hardware 1 sync, False - disable hardware 1 sync */ + bool hardwareSync2; /*!< True - enable hardware 2 sync, False - disable hardware 2 sync */ + bool maxLoadingPoint; /*!< True - enable maximum loading point, False - disable maximum loading point */ + bool minLoadingPoint; /*!< True - enable minimum loading point, False - disable minimum loading point */ + MftPwmDrv_UpdateConfigType inverterSync; /*!< Configures INVCTRL sync */ + MftPwmDrv_UpdateConfigType outRegSync; /*!< Configures SWOCTRL sync */ + MftPwmDrv_UpdateConfigType maskRegSync; /*!< Configures OUTMASK sync */ + MftPwmDrv_UpdateConfigType initCounterSync; /*!< Configures CNTIN sync */ + bool autoClearTrigger; /*!< Available only for hardware trigger */ + MftPwmDrv_SyncModeConfigType syncPoint; /*!< Configure synchronization method(waiting next loading point or immediate) */ +} MftPwmDrv_SyncType; + +/*! \brief MFT pre-scaler factor for the dead-time insertion + */ +typedef enum +{ + MFTPWMDRV_DEADTIME_DIVID_BY_1 = 0x01U, /*!< Divide by 1 */ + MFTPWMDRV_DEADTIME_DIVID_BY_4 = 0x02U, /*!< Divide by 4 */ + MFTPWMDRV_DEADTIME_DIVID_BY_16 = 0x03U /*!< Divide by 16 */ +} MftPwmDrv_DeadTimePrescalerType; + +/*! \brief MFT PWM driver parameters + */ +typedef struct _MftPwmDrv_ConfigType_ +{ + uint32_t periodValue; /*!< PWM period ticks */ + MftPwmDrv_SyncType syncMethod; /*!< Register sync options */ + MftPwmDrv_FaultConfigType faultConfig; /*!< Fault configuration */ + uint8_t deadTimeCount; /*!< Dead time value in [ticks], only available in complementary mode */ + MftPwmDrv_DeadTimePrescalerType deadTimePrescaler; /*!< Dead time pre-scaler value, only available in complementary mode */ +} MftPwmDrv_ConfigType; + +/*! \brief The definition of MFT PWM driver prototype + * \details Derived from MFT driver + */ +typedef struct _MftPwmDrvType_ +{ + MftDrvType *base; /*!< base class pointer */ + MftPwmChType channel[MFT_CHANNEL_NUM]; /*!< channels of the PWM mode */ +} MftPwmDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the MFT PWM channel instance + * + * This function initializes MFT PWM channel instance by setting the MFT driver + * instance to it. + * + * \param[in] obj : pointer to MFT PWM driver instance + * \param[in] base : pointer to MFT driver instance + */ +extern void MftPwmDrv_Init(MftPwmDrvType *obj, MftDrvType *base); + +/*! \brief Get default configuration of the MFT PWM module + * + * This function gets default configuration of the MFT PWM module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void MftPwmDrv_GetDefaultConfig(MftPwmDrv_ConfigType *userConfig); + +/*! \brief Configure the MFT PWM module + * + * This function configures the MFT PWM module. + * + * \param[in] obj : pointer to MFT PWM driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void MftPwmDrv_Config(MftPwmDrvType *obj, const MftPwmDrv_ConfigType *userConfig); + +/*! \brief Initializes the channels output. + * + * This function initializes the channels output. + * + * \note Normally it should be called after setup of channels + * + * \param[in] obj : pointer to MFT PWM driver instance + * \param[in] enable : Initialize the channels output + * - true : The channels output is initialized according to the state of OUTINIT reg + * - false: No effect + */ +extern void MftPwmDrv_SetInitOutputCmd(MftPwmDrvType *obj, bool enable); + +/*! \brief Configure the MFT PWM module + * + * This function configures the MFT PWM module. + * + * \param[in] obj : pointer to MFT PWM driver instance + * \param[in] value : the period value in ticks + */ +extern void MftPwmDrv_SetPeriod(MftPwmDrvType *obj, uint16_t value); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _MFT_PWM_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_qd/mft_qd_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_qd/mft_qd_drv.c new file mode 100644 index 0000000..e3f85ab --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_qd/mft_qd_drv.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "mft_qd_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void MftQdDrv_Init(MftQdDrvType *obj, MftDrvType *base) +{ + obj->base = base; + obj->isStarted = false; +} + +void MftQdDrv_GetDefaultConfig(MftQdDrv_ConfigType *userConfig) +{ + userConfig->mode = MFTQDDRV_PHASE_ENCODE; + userConfig->initialVal = 0U; + userConfig->maxVal = 65535U; + userConfig->phaseAConfig.phaseInputFilter = false; + userConfig->phaseAConfig.phaseFilterVal = 0U; + userConfig->phaseAConfig.phasePolarity = MFTQDDRV_PHASE_NORMAL; + userConfig->phaseBConfig.phaseInputFilter = false; + userConfig->phaseBConfig.phaseFilterVal = 0U; + userConfig->phaseBConfig.phasePolarity = MFTQDDRV_PHASE_NORMAL; +} + +void MftQdDrv_ConfigAndStart(MftQdDrvType *obj, const MftQdDrv_ConfigType *userConfig) +{ + if(false == obj->isStarted) + { + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->base->reg, 1); + + /* Disable Quadrature Decoder */ + MftReg_SetQDCtrlQuadEn(obj->base->reg, 0); + MftReg_SetScClks(obj->base->reg, 0); + /* Configure Quadrature Decoder */ + /* Set decoder mode Speed and direction or Phase A and Phase B encoding */ + MftReg_SetQDCtrlQuadMode(obj->base->reg, (uint8_t)userConfig->mode); + /* Set filter state for Phase A (enable/disable) */ + MftReg_SetQDCtrlPhaFltrEn(obj->base->reg, userConfig->phaseAConfig.phaseInputFilter ? 1 : 0); + /* Set Phase A filter value if phase filter is enabled */ + if(userConfig->phaseAConfig.phaseInputFilter) + { + MftReg_SetFilterCh0FVal(obj->base->reg, userConfig->phaseAConfig.phaseFilterVal); + } + + /* Set filter state for Phase B (enable/disable) */ + MftReg_SetQDCtrlPhbFltrEn(obj->base->reg, userConfig->phaseBConfig.phaseInputFilter ? 1 : 0); + /* Set Phase B filter value if phase filter is enabled */ + if(userConfig->phaseBConfig.phaseInputFilter) + { + MftReg_SetFilterCh1FVal(obj->base->reg, userConfig->phaseBConfig.phaseFilterVal); + } + + /* Set polarity for Phase A and Phase B */ + MftReg_SetQDCtrlPhaPol(obj->base->reg, (uint8_t)userConfig->phaseAConfig.phasePolarity); + MftReg_SetQDCtrlPhbPol(obj->base->reg, (uint8_t)userConfig->phaseBConfig.phasePolarity); + /* Configure counter (initial value and maximum value) */ + MftReg_SetCntInCntInit(obj->base->reg, userConfig->initialVal); + MftReg_SetModuloMod(obj->base->reg, userConfig->maxVal); + MftReg_SetCntCount(obj->base->reg, userConfig->initialVal); + /* Enable Quadrature Decoder */ + MftReg_SetQDCtrlQuadEn(obj->base->reg, 1); + + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->base->reg, 1); + + obj->isStarted = true; + } +} + +void MftQdDrv_QuadDecodeStop(MftQdDrvType *obj) +{ + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->base->reg, 1); + /* Disable Quadrature decoder */ + MftReg_SetQDCtrlQuadEn(obj->base->reg, 0); + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->base->reg, 1); + obj->isStarted = false; +} + +void MftQdDrv_GetState(MftQdDrvType *obj, MftQdDrv_StateType *state) +{ + state->counterDirection = MftReg_GetQDCtrlQuaDir(obj->base->reg) == 1; + state->overflowDirection = MftReg_GetQDCtrlTorDir(obj->base->reg) == 1; + state->overflowFlag = MftReg_GetScTof(obj->base->reg) == 1; + state->counter = MftReg_GetCntCount(obj->base->reg); +} \ No newline at end of file diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_qd/mft_qd_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_qd/mft_qd_drv.h new file mode 100644 index 0000000..d036006 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_qd/mft_qd_drv.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MFT_QD_DRV_H_ +#define _MFT_QD_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the quadrature decode mode driver of MFT + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../mft_drv.h" + +/*! \addtogroup mft_qd_drv + * \ingroup mft_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief MFT quadrature decode modes, phase encode or count and direction mode + */ +typedef enum +{ + MFTQDDRV_PHASE_ENCODE = 0x00U, /*!< Phase encoding mode */ + MFTQDDRV_COUNT_AND_DIR = 0x01U /*!< Counter and direction encoding mode */ +} MftQdDrv_ModeType; + +/*! \brief MFT quadrature phase polarities, normal or inverted polarity + */ +typedef enum +{ + MFTQDDRV_PHASE_NORMAL = 0x00U, /*!< Phase input signal is not inverted before identifying + * the rising and falling edges of this signal */ + MFTQDDRV_PHASE_INVERT = 0x01U /*!< Phase input signal is inverted before identifying + * the rising and falling edges of this signal */ +} MftQdDrv_PhasePolarityType; + +/*! \brief MFT quadrature decoder channel parameters + */ +typedef struct +{ + bool phaseInputFilter; /*!< false: disable phase filter, true: enable phase filter */ + uint8_t phaseFilterVal; /*!< Filter value (if input filter is enabled)*/ + MftQdDrv_PhasePolarityType phasePolarity; /*!< Phase polarity */ +} MftQdDrv_PhaseParamsType; + +/*! \brief MFT driver Input capture parameters for each channel + */ +typedef struct _MftQdDrv_ConfigType_ +{ + MftQdDrv_ModeType mode; /*!< Mode of quadrature decoder */ + uint16_t initialVal; /*!< Initial counter value*/ + uint16_t maxVal; /*!< Maximum counter value*/ + MftQdDrv_PhaseParamsType phaseAConfig; /*!< Configuration for the input phase a */ + MftQdDrv_PhaseParamsType phaseBConfig; /*!< Configuration for the input phase b */ +} MftQdDrv_ConfigType; + +/*! \brief MFT quadrature state(counter value and flags) + */ +typedef struct +{ + uint16_t counter; /*!< Counter value */ + bool overflowFlag; /*!< True if overflow occurred, False if overflow doesn't occurred */ + bool overflowDirection; /*!< False if overflow occurred at minimum value, True if overflow occurred at maximum value */ + bool counterDirection; /*!< False MFT counter is increasing, True MFT counter is decreasing */ +} MftQdDrv_StateType; + +/*! \brief The definition of MFT capture driver prototype + * \details Derived from MFT driver + */ +typedef struct _MftQdDrvType_ +{ + MftDrvType *base; /*!< base class is MFT driver */ + bool isStarted; /*!< Is quadrature decoder started */ +} MftQdDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the MFT quadrature decode mode + * + * This function initializes MFT quadrature decode driver by setting the MFT driver + * instance to it. + * + * \param[in] obj : pointer to MFT quadrature decode mode driver instance + * \param[in] base : pointer to MFT driver instance + */ +extern void MftQdDrv_Init(MftQdDrvType *obj, MftDrvType *base); + +/*! \brief Get default configures the MFT quadrature decode mode for configuration structure + * + * This function gets default configures the MFT quadrature decode mode for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void MftQdDrv_GetDefaultConfig(MftQdDrv_ConfigType *userConfig); + +/*! \brief Configures the quadrature mode and starts measurement + * + * This function configures the quadrature mode and starts measurement + * + * \param[in] obj : pointer to MFT quadrature decode mode driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void MftQdDrv_ConfigAndStart(MftQdDrvType *obj, const MftQdDrv_ConfigType *userConfig); + +/*! \brief De-activates the quadrature decode mode. + * + * This function de-activates the quadrature decode mode. + * + * \param[in] obj : pointer to MFT quadrature decode mode driver instance + */ +extern void MftQdDrv_QuadDecodeStop(MftQdDrvType *obj); + +/*! \brief Get the current quadrature decoder state + * + * This function get the current quadrature decoder state (counter value, overflow flag and + * overflow direction) + * + * \param[in] obj : pointer to MFT quadrature decode mode driver instance + * \param[out] state : pointer to the current state of quadrature decoder + */ +extern void MftQdDrv_GetState(MftQdDrvType *obj, MftQdDrv_StateType *state); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _MFT_QD_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mpu/mpu_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mpu/mpu_drv.c new file mode 100644 index 0000000..01a42e5 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mpu/mpu_drv.c @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "mpu_drv.h" +#include "mpu_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void MpuDrv_Init(MpuDrvType *obj, struct _MpuRegType_ *reg) +{ + obj->reg = reg; +} + +void MpuDrv_GetDefaultConfig(MpuDrv_ConfigType *userConfig) +{ + uint8_t regDescNum; + uint8_t masterNum; + uint8_t slvPortNum; + + /* mpu PID is used, default: false */ + userConfig->isEnableErrPid = false; + /* mpu main switch, default: enable */ + userConfig->ctrlInfo.mpuValid = true; + /* region description total num, default: 8 */ + userConfig->ctrlInfo.mpuTotalNumRegDesc = MPUDRV_NUMOFRGD_8; + + /* mpu control info */ + for(slvPortNum = 0; slvPortNum < MPUDRV_SLVPORTMAX; slvPortNum++) + { + /* slave port error status, default: false */ + userConfig->ctrlInfo.slvPortErrStatus[slvPortNum] = false; + + /* + * slave port default info + */ + + /* slave port access master number */ + userConfig->slvPortErrInfo->master = (MpuDrv_MasterType)0; + /* salve port error PID number,default: 0 */ + userConfig->slvPortErrInfo->pidNumber = 0; + /* salve port access mode, default: user mode */ + userConfig->slvPortErrInfo->attrbutes = MPUDRV_INSTRUCTION_ACCESS_IN_USER_MODE; + /* slave port access type, default: read mode */ + userConfig->slvPortErrInfo->accType = MPUDRV_ERRTYPE_READ; + /* salve port access error claw(EACD), default: 0 */ + userConfig->slvPortErrInfo->accCtrl = 0; + /* salve port error address, when master access fault,default: 0 */ + userConfig->slvPortErrInfo->addr = 0; + } + + /* region description default configure */ + for(regDescNum = 0; regDescNum < MPUDRV_CHMAX; regDescNum++) + { + /* region description channel 0 default all rights allow */ + if(regDescNum == 0) + { + /* RGD channel 0 tatus, mpu functions, default: enable */ + userConfig->regDescCfgInfo[regDescNum].chnEnable = true; + /* RGD channel 0 start address, default: 0 */ + userConfig->regDescCfgInfo[regDescNum].startAddr = 0; + /* RGD channel 0 end address, default: 0xFFFFFF1F */ + userConfig->regDescCfgInfo[regDescNum].endAddr = 0xFFFFFF1F; + /* RGD channel 0 PID mask number, default: 0 */ + userConfig->regDescCfgInfo[regDescNum].pidMask = 0; + /* RGD channel 0 PID number, default: 0 */ + userConfig->regDescCfgInfo[regDescNum].pidNumber = 0; + + for(masterNum = 0; masterNum < MPUDRV_MASTER_NUMMAX; masterNum++) + { + /* RGD master in privilege mode access right, default: same as user */ + userConfig->regDescCfgInfo[regDescNum].masterAccRight[masterNum].masterPrivilegeAccRight = MPUDRV_SUPERVISOR_SAME_AS_USER; + /* RGD master in user mode access right, default: RWX allow */ + userConfig->regDescCfgInfo[regDescNum].masterAccRight[masterNum].masterUserAccRight = MPUDRV_USER_RWX; + /* RGD master PID enable flag, default: false */ + userConfig->regDescCfgInfo[regDescNum].masterAccRight[masterNum].pidFlagEnable = false; + + /* + * Alternate Access Control channel 0 default all rights allow + */ + + /* AAC channel 0 onfig master in privilege mode access right, default: same as user */ + userConfig->aacCfgInfo[regDescNum].masterPrivilegeAccRight = MPUDRV_SUPERVISOR_SAME_AS_USER; + /* AAC channel 0 config master in user mode access right, default: RWX allow */ + userConfig->aacCfgInfo[regDescNum].masterUserAccRight = MPUDRV_USER_RWX; + /* AAC channel 0 config master PID enable flag, default: false */ + userConfig->aacCfgInfo[regDescNum].pidFlagEnable = false; + } + } + else + { + /* + * region description channel 1~8 default all rights forbidden + */ + + /* RGD channel 1~8 tatus, mpu functions, default: disable */ + userConfig->regDescCfgInfo[regDescNum].chnEnable = false; + /* RGD channel 1~8 start address, default: 0 */ + userConfig->regDescCfgInfo[regDescNum].startAddr = 0; + /* RGD channel 1~8 end address, default: 0x0 */ + userConfig->regDescCfgInfo[regDescNum].endAddr = 0x1F; + /* RGD channel 1~8 PID mask number, default: 0 */ + userConfig->regDescCfgInfo[regDescNum].pidMask = 0; + /* RGD channel 1~8 PID number, default: 0 */ + userConfig->regDescCfgInfo[regDescNum].pidNumber = 0; + + for(masterNum = 0; masterNum < MPUDRV_MASTER_NUMMAX; masterNum++) + { + /* RGD master in privilege mode access right, default: RWX allow */ + userConfig->regDescCfgInfo[regDescNum].masterAccRight[masterNum].masterPrivilegeAccRight = MPUDRV_SUPERVISOR_RWX; + /* RGD master in user mode access right, default: none */ + userConfig->regDescCfgInfo[regDescNum].masterAccRight[masterNum].masterUserAccRight = MPUDRV_USER_NONE; + /* RGD master PID enable flag, default: false */ + userConfig->regDescCfgInfo[regDescNum].masterAccRight[masterNum].pidFlagEnable = false; + + /* + * Alternate Access Control channel 1~8 default all rights forbidden + */ + + /* AAC channel 1~8 onfig master in privilege mode access right, default: RWX allow */ + userConfig->aacCfgInfo[regDescNum].masterPrivilegeAccRight = MPUDRV_SUPERVISOR_RWX; + /* AAC channel 1~8 config master in user mode access right, default: none */ + userConfig->aacCfgInfo[regDescNum].masterUserAccRight = MPUDRV_USER_NONE; + /* AAC channel 1~8 config master PID enable flag, default: false */ + userConfig->aacCfgInfo[regDescNum].pidFlagEnable = false; + } + } + } +} + +void MpuDrv_GetCtrlInfo(MpuDrvType *obj, MpuDrv_CtrlInfoType *ctrlInfo) +{ + uint8_t slvPortNum; + + for(slvPortNum = 0; slvPortNum < MPUDRV_SLVPORTMAX; slvPortNum++) + { + /* get slave port error info */ + ctrlInfo->slvPortErrStatus[slvPortNum] = MpuReg_GetSlvPortErrStatus(obj->reg, slvPortNum); + } + /* get total number of region description */ + ctrlInfo->mpuTotalNumRegDesc = (MpuDrv_RegDescTotalNumType)MpuReg_GetNumOfRegionDesc(obj->reg); + /* get MPU global enable status */ + ctrlInfo->mpuValid = MpuReg_GetMpuGlobalEnableStatus(obj->reg); +} + +__attribute__((always_inline)) static inline MpuDrv_MasterType MpuDrv_SlvPortEMNtoMaster(uint8_t emn) +{ + switch(emn) + { + case 0: + return MPUDRV_MASTER_CPU; + case 1: + return MPUDRV_MASTER_DEBUGGER; + case 2: + return MPUDRV_MASTER_DMA; + default: + return MPUDRV_MASTER_NUMMAX; + } +} + + +void MpuDrv_GetSlvPortErrInfo(MpuDrvType *obj, MpuDrv_SlvPortErrInfoType *slvPortErrInfo, bool isEnablePid) +{ + uint8_t slvPortNum; + + for(slvPortNum = 0; slvPortNum < MPUDRV_SLVPORTMAX; slvPortNum++) + { + /* get slave port error access detail info */ + slvPortErrInfo[slvPortNum].accCtrl = MpuReg_GetSlvPortEACD(obj->reg, slvPortNum); + /* get slave port error type R/W */ + slvPortErrInfo[slvPortNum].accType = (MpuDrv_AccType)MpuReg_GetSlvPortErrDetailERW(obj->reg, slvPortNum); + /* get slave port error type master number */ + slvPortErrInfo[slvPortNum].master = (MpuDrv_MasterType)MpuDrv_SlvPortEMNtoMaster(MpuReg_GetSlvPortErrDetailEMN(obj->reg, slvPortNum)); + /* get slave port error attribute */ + slvPortErrInfo[slvPortNum].attrbutes = (MpuDrv_AttrType)MpuReg_GetSlvPortErrDetailEAttr(obj->reg, slvPortNum); + /* get slave port error address */ + slvPortErrInfo[slvPortNum].addr = MpuReg_GetSlvPortErrAddr(obj->reg, slvPortNum); + + if(isEnablePid) + { + /* get slave port error PID */ + slvPortErrInfo[slvPortNum].pidNumber = MpuReg_GetSlvPortErrPID(obj->reg, slvPortNum); + } + } +} + +void MpuDrv_GetMasterAccRight(MpuDrvType *obj, + MpuDrv_MasterAccConfigType *masterAccRight, + MpuDrv_RegDescChnNumType regDescNum, + MpuDrv_MasterType masterNum) +{ + /* get master privilege mode access right */ + masterAccRight[masterNum].masterPrivilegeAccRight = (MpuDrv_MasterPrivilegeAccType)MpuReg_GetRegionDescPrivilegeAuthority(obj->reg, regDescNum, masterNum); + /* get master user mode access right */ + masterAccRight[masterNum].masterUserAccRight = (MpuDrv_MasterUserAccType)MpuReg_GetRegionDescUserAuthority(obj->reg, regDescNum, masterNum); + /* get master PID enable status (Only master0 & master1) */ + masterAccRight[masterNum].pidFlagEnable = MpuReg_GetRegionDescPIDFlagEnableStatus(obj->reg, regDescNum, masterNum); +} + +void MpuDrv_GetRegDescCfgInfo(MpuDrvType *obj, MpuDrv_RegDescType *regDesc, bool isEnablePid) +{ + uint8_t regDescNum; + uint8_t masterNum; + + for(regDescNum = 0; regDescNum < MPUDRV_CHMAX; regDescNum++) + { + /* get region description current channel start address */ + regDesc[regDescNum].startAddr = MpuReg_GetRegionDescStartAddr(obj->reg, regDescNum); + /* get region description current channel end address */ + regDesc[regDescNum].endAddr = MpuReg_GetRegionDescEndAddr(obj->reg, regDescNum); + + for(masterNum = 0; masterNum < MPUDRV_MASTER_NUMMAX; masterNum++) + { + /* get region description current channel master accsee right */ + MpuDrv_GetMasterAccRight(obj, ®Desc[regDescNum].masterAccRight[masterNum], (MpuDrv_RegDescChnNumType)regDescNum, (MpuDrv_MasterType)masterNum); + } + + if(isEnablePid) + { + /* get region description current channel PID */ + regDesc[regDescNum].pidNumber = MpuReg_GetPID(obj->reg, regDescNum); + /* get region description current channel PIDMask */ + regDesc[regDescNum].pidMask = MpuReg_GetPIDMask(obj->reg, regDescNum); + } + } +} + +void MpuDrv_GetAacCtrlInfo(MpuDrvType *obj, MpuDrv_MasterAccConfigType *aacRegDesc) +{ + uint8_t regDescNum; + uint8_t masterNum; + + for(regDescNum = 0; regDescNum < MPUDRV_CHMAX; regDescNum++) + { + for(masterNum = 0; masterNum < MPUDRV_MASTER_NUMMAX; masterNum++) + { + /* get AAC config master privilege mode access right */ + aacRegDesc[masterNum].masterPrivilegeAccRight = (MpuDrv_MasterPrivilegeAccType)MpuReg_GetRegionDescAACPrivilegeAuthority(obj->reg, regDescNum, masterNum); + /* get AAC config master user mode access right */ + aacRegDesc[masterNum].masterUserAccRight = (MpuDrv_MasterUserAccType)MpuReg_GetRegionDescAACUserAuthority(obj->reg, regDescNum, masterNum); + /* get AAC config master PID enable status (Only master0 & master1) */ + aacRegDesc[masterNum].pidFlagEnable = MpuReg_GetRegionDescAACPIDFlagEnableStatus(obj->reg, regDescNum, masterNum); + } + } +} + +void MpuDrv_GetConfigure(MpuDrvType *obj, MpuDrv_ConfigType *userConfig) +{ + /* get common part control info */ + MpuDrv_GetCtrlInfo(obj, &userConfig->ctrlInfo); + /* get slave port error info */ + MpuDrv_GetSlvPortErrInfo(obj, (MpuDrv_SlvPortErrInfoType *)&userConfig->slvPortErrInfo, userConfig->isEnableErrPid); + /* get region description config info */ + MpuDrv_GetRegDescCfgInfo(obj, (MpuDrv_RegDescType *)&userConfig->regDescCfgInfo, userConfig->isEnableErrPid); + /* get alternate access config info */ + MpuDrv_GetAacCtrlInfo(obj, (MpuDrv_MasterAccConfigType *)&userConfig->aacCfgInfo); +} + +static void MpuDrv_SetMasterAccRight(MpuDrvType *obj, + MpuDrv_MasterAccConfigType *masterAccRight, + MpuDrv_RegDescChnNumType regDescChnNum, + MpuDrv_MasterType masterNum) +{ + /* set master privilege mode access right */ + MpuReg_SetRegionDescPrivilegeAuthority(obj->reg, regDescChnNum, masterNum, masterAccRight[masterNum].masterPrivilegeAccRight); + /* set master user mode access right */ + MpuReg_SetRegionDescUserAuthority(obj->reg, regDescChnNum, masterNum, masterAccRight[masterNum].masterUserAccRight); + /* set master PID enable status (Only master0 & master1) */ + MpuReg_SetRegionDescPIDFlagEnable(obj->reg, regDescChnNum, masterNum, masterAccRight[masterNum].pidFlagEnable); +} + +void MpuDrv_EnableRegDescChn(MpuDrvType *obj, MpuDrv_RegDescChnNumType chnNum, bool enable) +{ + /* set region description channle enable */ + MpuReg_SetRegionDescValid(obj->reg, chnNum, enable); +} + +void MpuDrv_SetRegDescChnCfg(MpuDrvType *obj, + const MpuDrv_RegDescType *regDescCfg, + MpuDrv_RegDescChnNumType regDescChnNum, + bool pidEnable) +{ + uint8_t masterNum; + + /* set region description start address */ + MpuReg_SetRegionDescStartAddr(obj->reg, regDescCfg->startAddr, regDescChnNum); + /* set region description end address */ + MpuReg_SetRegionDescEndAddr(obj->reg, regDescCfg->endAddr, regDescChnNum); + + for(masterNum = 0; masterNum < MPUDRV_MASTER_NUMMAX; masterNum++) + { + /* set region description master access right */ + MpuDrv_SetMasterAccRight(obj, (MpuDrv_MasterAccConfigType *)®DescCfg->masterAccRight, (MpuDrv_RegDescChnNumType)regDescChnNum, (MpuDrv_MasterType)masterNum); + if(masterNum < MPUDRV_MASTER_DMA) + { + /* set region description pid enable */ + MpuReg_SetRegionDescPIDFlagEnable(obj->reg, regDescChnNum, masterNum, pidEnable); + } + } + + MpuDrv_EnableRegDescChn(obj, regDescChnNum, regDescCfg->chnEnable); +} + +void MpuDrv_SetAacCtrlInfo(MpuDrvType *obj, + MpuDrv_MasterAccConfigType *aacRegDesc, + MpuDrv_RegDescChnNumType regDescChnNum, + MpuDrv_MasterType masterNum) +{ + if(regDescChnNum >= MPUDRV_CHMAX || masterNum >= MPUDRV_MASTER_NUMMAX) + { + return; + } + + /* set AAC config master privilege mode access right */ + MpuReg_SetRegionDescAACPrivilegeAuthority(obj->reg, regDescChnNum, masterNum, aacRegDesc->masterPrivilegeAccRight); + /* set AAC config master user mode access right */ + MpuReg_SetRegionDescAACUserAuthority(obj->reg, regDescChnNum, masterNum, aacRegDesc->masterUserAccRight); + /* set AAC config master PID enable status (Only master0 & master1) */ + MpuReg_SetRegionDescAACPIDFlagEnable(obj->reg, regDescChnNum, masterNum, aacRegDesc->pidFlagEnable); +} + +bool MpuDrv_GetGlobalEnableStatus(MpuDrvType *obj) +{ + /* Get MPU Enable status */ + return MpuReg_GetMpuGlobalEnableStatus(obj->reg); +} + +void MpuDrv_SetGlobalEnable(MpuDrvType *obj, bool enable) +{ + /* Set MPU global Enable status */ + MpuReg_GlobalEnable(obj->reg, enable); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mpu/mpu_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mpu/mpu_drv.h new file mode 100644 index 0000000..10245f5 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/mpu/mpu_drv.h @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MPU_DRV_H_ +#define _MPU_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of MPU + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup mpu_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief MPU access error + */ +typedef enum +{ + MPUDRV_ERRTYPE_READ = 0U, /*!< MPU error type: read */ + MPUDRV_ERRTYPE_WRITE = 1U /*!< MPU error type: write */ +} MpuDrv_AccType; + +/*! \brief MPU access error attributes + */ +typedef enum +{ + MPUDRV_INSTRUCTION_ACCESS_IN_USER_MODE = 0U, /*!< Access instruction error in user mode */ + MPUDRV_DATA_ACCESS_IN_USER_MODE = 1U, /*!< Access data error in user mode */ + MPUDRV_INSTRUCTION_ACCESS_IN_SUPERVISOR_MODE = 2U, /*!< Access instruction error in supervisor mode */ + MPUDRV_DATA_ACCESS_IN_SUPERVISOR_MODE = 3U /*!< Access data error in supervisor mode */ +} MpuDrv_AttrType; + +/*! \brief MPU Region Description Number + */ +typedef enum +{ + MPUDRV_NUMOFRGD_8 = 0U, /*!< MPU Total Number of Region 8 Descriptions */ + MPUDRV_NUMOFRGD_12 = 1U, /*!< MPU Total Number of Region 12 Descriptions */ + MPUDRV_NUMOFRGD_16 = 2U, /*!< MPU Total Number of Region 16 Descriptions */ +} MpuDrv_RegDescTotalNumType; + +/*! \brief MPU access Master Type + * Implements : MpuDrv_MasterType + */ +typedef enum +{ + MPUDRV_MASTER_CPU = 0U, /*!< MPU Access Master Type CPU */ + MPUDRV_MASTER_DEBUGGER = 1U, /*!< MPU Access Master Type DEBUGGER */ + MPUDRV_MASTER_DMA = 2U, /*!< MPU Access Master Type DMA */ + MPUDRV_MASTER_NUMMAX = 3U /*!< Master Number value Max */ +} MpuDrv_MasterType; + +/*! \brief MPU slave port Type + */ +typedef enum +{ + MPUDRV_SLVPORT0 = 0U, /*!< MPU Slave Port Number0 */ + MPUDRV_SLVPORT1 = 1U, /*!< MPU Slave Port Number1 */ + MPUDRV_SLVPORTMAX = 2U /*!< MPU Slave Port NumberMax */ +} MpuDrv_SlvPortNumType; + +/*! \brief MPU Region Description Type + */ +typedef enum +{ + MPUDRV_CH0 = 0U, /*!< MPU RGD channel number 0 */ + MPUDRV_CH1 = 1U, /*!< MPU RGD channel number 1 */ + MPUDRV_CH2 = 2U, /*!< MPU RGD channel number 2 */ + MPUDRV_CH3 = 3U, /*!< MPU RGD channel number 3 */ + MPUDRV_CH4 = 4U, /*!< MPU RGD channel number 4 */ + MPUDRV_CH5 = 5U, /*!< MPU RGD channel number 5 */ + MPUDRV_CH6 = 6U, /*!< MPU RGD channel number 6 */ + MPUDRV_CH7 = 7U, /*!< MPU RGD channel number 7 */ + MPUDRV_CHMAX = 8U /*!< MPU RGD channel total num */ +} MpuDrv_RegDescChnNumType; + +/*! \brief MPU privilege access rights. + */ +typedef enum +{ + MPUDRV_SUPERVISOR_RWX = 0x0U, /*!< 0b00U : rwx, Allow Read, write, execute in supervisor mode */ + MPUDRV_SUPERVISOR_RX = 0x1U, /*!< 0b01U : r-x, Allow Read, execute in supervisor mode */ + MPUDRV_SUPERVISOR_RW = 0x2U, /*!< 0b10U : rw-, Allow Read, write in supervisor mode */ + MPUDRV_SUPERVISOR_SAME_AS_USER = 0x3U, /*!< 0b11U : xxx, Allow right the same as user mode */ +} MpuDrv_MasterPrivilegeAccType; + +/*! \brief MPU user access rights. + */ +typedef enum +{ + MPUDRV_USER_NONE = 0x00U, /*!< 0b000U : ---, No access allowed user modes */ + MPUDRV_USER_X = 0x01U, /*!< 0b001U : --x, Execute operation is allowed user modes */ + MPUDRV_USER_W = 0x02U, /*!< 0b010U : -w-, Write operation is allowed user modes */ + MPUDRV_USER_WX = 0x03U, /*!< 0b011U : -wx, Write and execute operations are allowed in user modes */ + MPUDRV_USER_R = 0x04U, /*!< 0b100U : r--, Read operation is allowed user modes */ + MPUDRV_USER_RX = 0x05U, /*!< 0b101U : r-x, Allow Read, execute in user mode */ + MPUDRV_USER_RW = 0x06U, /*!< 0b110U : rw-, Allow Read, write in user mode */ + MPUDRV_USER_RWX = 0x07U, /*!< 0b111U : rwx, Allow Read, write, execute in user mode */ +} MpuDrv_MasterUserAccType; + +/* Forward declaration of MPU register */ +struct _MpuRegType_; + +/*! \brief The definition of MPU driver class + */ +typedef struct _MpuDrvType_ +{ + struct _MpuRegType_ *reg; +} MpuDrvType; + +/*! \brief MPU control info + */ +typedef struct _MpuDrv_CtrlInfoType_ +{ + bool mpuValid; /*!< MPU main enable */ + MpuDrv_RegDescTotalNumType mpuTotalNumRegDesc; /*!< MPU channel num of region description */ + bool slvPortErrStatus[MPUDRV_SLVPORTMAX]; /*!< MPU slave portx error status */ +} MpuDrv_CtrlInfoType; + +/*! \brief MPU slave port detail error access info + */ +typedef struct _MpuDrv_SlvPortErrInfoType_ +{ + MpuDrv_MasterType master; /*!< Access error master */ + MpuDrv_AttrType attrbutes; /*!< Access error attributes */ + MpuDrv_AccType accType; /*!< Access error type */ + uint16_t accCtrl; /*!< Access error control(EACD) */ + uint32_t addr; /*!< Access error address */ + uint8_t pidNumber; /*!< Access error processor identification */ +} MpuDrv_SlvPortErrInfoType; + +/*! \brief MPU master access rights. + */ +typedef struct _MpuDrv_MasterAccConfigType_ +{ + MpuDrv_MasterPrivilegeAccType masterPrivilegeAccRight; /*!< Master Privilege Access right */ + MpuDrv_MasterUserAccType masterUserAccRight; /*!< Master User Access right */ + bool pidFlagEnable; /*!< Enables or disables process identifier */ +} MpuDrv_MasterAccConfigType; + +/*! \brief MPU Region Description rights + */ +typedef struct _MpuDrv_RegDescType_ +{ + uint32_t startAddr; /*!< Memory region start address */ + uint32_t endAddr; /*!< Memory region end address */ + MpuDrv_MasterAccConfigType masterAccRight[MPUDRV_MASTER_NUMMAX]; /*!< Access right for masters */ + uint8_t pidNumber; /*!< Process identifier */ + uint8_t pidMask; /*!< Process identifier mask. The setting bit will ignore the same bit in process identifier */ + bool chnEnable; /*!< current channel protect function enable */ +} MpuDrv_RegDescType; + +/*! \brief The definition of MPU driver class + */ +typedef struct _MpuDrv_ConfigType_ +{ + MpuDrv_CtrlInfoType ctrlInfo; /*!< MPU main ctrl info */ + MpuDrv_SlvPortErrInfoType slvPortErrInfo[MPUDRV_SLVPORTMAX]; /*!< MPU slave port error info */ + MpuDrv_RegDescType regDescCfgInfo[MPUDRV_CHMAX]; /*!< MPU region description config info */ + MpuDrv_MasterAccConfigType aacCfgInfo[MPUDRV_CHMAX]; /*!< MPU AAC register config info */ + bool isEnableErrPid; /*!< MPU Error PID is enable, user determine */ +} MpuDrv_ConfigType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the MPU driver module + * + * This function initializes MPU driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] reg : pointer to MPU register instance + */ +extern void MpuDrv_Init(MpuDrvType *obj, struct _MpuRegType_ *reg); + +/*! \brief Get MPU Default Config + * + * This function get MPU all default paramters + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] userConfig : pointer to user get all default + * + */ +extern void MpuDrv_GetDefaultConfig(MpuDrv_ConfigType *userConfig); + +/*! \brief Get MPU common Control Config + * + * This function get MPU common control paramters + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] ctrlInfo : pointer to common config paramter + * + */ +extern void MpuDrv_GetCtrlInfo(MpuDrvType *obj, MpuDrv_CtrlInfoType *ctrlInfo); + +/*! \brief Get MPU slave port Error info + * + * This function get MPU slave error info + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] slvPortErrInfo : slave port error info + * \param[in] isEnablePID : PID status + * + */ +extern void MpuDrv_GetSlvPortErrInfo(MpuDrvType *obj, MpuDrv_SlvPortErrInfoType *slvPortErrInfo, bool isEnablePid); + +/*! \brief Get MPU Master Config + * + * This function get MPU master config + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] masterAccRight : master access right + * \param[in] regDescNum : region description number + * \param[in] masterNum : master number + * + */ +extern void MpuDrv_GetMasterAccRight(MpuDrvType *obj, MpuDrv_MasterAccConfigType *masterAccRight, MpuDrv_RegDescChnNumType regDescNum, MpuDrv_MasterType masterNum); + +/*! \brief Get MPU Region Description config + * + * This function get MPU region description config parameters + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] regDesc : pointer to region description config parameter + * \param[in] isEnablePID : region description PID enable status + * + */ +extern void MpuDrv_GetRegDescCfgInfo(MpuDrvType *obj, MpuDrv_RegDescType *regDesc, bool isEnablePid); + +/*! \brief Get MPU Master Access Right + * + * This function get MPU master access right + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] aacRegDesc : pointer to mster access right paramter + * + */ +extern void MpuDrv_GetAacCtrlInfo(MpuDrvType *obj, MpuDrv_MasterAccConfigType *aacRegDesc); + +/*! \brief Get MPU Current all Config + * + * This function get MPU current all config paramters + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] userConfig : pointer to user get current all config + * + */ +extern void MpuDrv_GetConfigure(MpuDrvType *obj, MpuDrv_ConfigType *userConfig); + +/*! \brief Set Region Description channel Enable + * + * This function set mpu region description channle enable + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] chnNum : select config channel + * \param[in] enable : + * - true : enable + * - false : disable + * + */ +extern void MpuDrv_EnableRegDescChn(MpuDrvType *obj, MpuDrv_RegDescChnNumType chnNum, bool enable); + +/*! \brief Set Region Description channel Enable + * + * This function set mpu region description channle enable + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] regDescCfg : pointer to region description + * \param[in] regDescChnNum : region description number + * \param[in] pidEnable : + * - true : enable + * - false : disable + * + */ +extern void MpuDrv_SetRegDescChnCfg(MpuDrvType *obj,const MpuDrv_RegDescType *regDescCfg, MpuDrv_RegDescChnNumType regDescChnNum, bool pidEnable); + +/*! \brief Set Master Access Right + * + * This function set master access ram or flash right + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] aacRegDesc : pointer to master access right + * \param[in] regDescChnNum : region description number + * \param[in] masterNum : master number + * + */ +extern void MpuDrv_SetAacCtrlInfo(MpuDrvType *obj, MpuDrv_MasterAccConfigType *aacRegDesc, MpuDrv_RegDescChnNumType regDescChnNum, MpuDrv_MasterType masterNum); + +/*! \brief Get MPU enable status + * + * This function get MPU enable status enable + * + * \param[in] obj : pointer to MPU driver instance + * + */ +extern bool MpuDrv_GetGlobalEnableStatus(MpuDrvType *obj); + +/*! \brief Get MPU enable status + * + * This function get MPU enable status enable + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] enable : + * - true : enable + * - false : disable + * + */ +extern void MpuDrv_SetGlobalEnable(MpuDrvType *obj, bool enable); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _MPU_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/pdb/pdb_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/pdb/pdb_drv.c new file mode 100644 index 0000000..e6cdd5e --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/pdb/pdb_drv.c @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "pdb_drv.h" +#include "pdb_reg.h" +#include "sim_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define PDB_CF_MASK (1U) +#define PDBDRV_PRE_TRG_ENABLE (1U) +#define PDBDRV_PRE_BB_MODE_ENABLE (1U) +#define PDBDRV_PRE_DLY_MODE_ENABLE (1U) +#define PDBDRV_PO_ENABLE (1U) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void PdbDrv_Init(PdbDrvType *obj, struct _PdbRegType_ *pdbReg) +{ + obj->pdbReg = pdbReg; +} + +void PdbDrv_EnablePdb(PdbDrvType *obj) +{ + PdbReg_SetPdbenReg(obj->pdbReg, true); +} + +void PdbDrv_PdbDisable(PdbDrvType *obj) +{ + PdbReg_SetPdbenReg(obj->pdbReg, false); +} + +void PdbDrv_SwtrigCmd(PdbDrvType *obj) +{ + PdbReg_SwtrigReg(obj->pdbReg); +} + +void PdbDrv_ClrPdbif(PdbDrvType *obj) +{ + PdbReg_ClrPdbifReg(obj->pdbReg); +} + +void PdbDrv_LoadCmd(PdbDrvType *obj) +{ + PdbReg_StartLoadReg(obj->pdbReg); +} + +uint16_t PdbDrv_GetCnt(const PdbDrvType *obj) +{ + return (PdbReg_GetCntReg(obj->pdbReg)); +} + +uint8_t PdbDrv_GetChnCf(const PdbDrvType *obj, PdbDrv_ChType chn) +{ + uint8_t tmp; + tmp = PdbReg_GetChnCfReg(obj->pdbReg, (uint8_t)chn); + return (tmp); +} + +void PdbDrv_ClrChnCf(PdbDrvType *obj, PdbDrv_ChType chn) +{ + PdbReg_ClrChnCfReg(obj->pdbReg, (uint8_t)chn); +} + +uint8_t PdbDrv_GetChnErr(const PdbDrvType *obj, PdbDrv_ChType chn) +{ + uint8_t tmp; + tmp = PdbReg_GetChnErrReg(obj->pdbReg, (uint8_t)chn); + return (tmp); +} + +void PdbDrv_ClrChnErr(PdbDrvType *obj, PdbDrv_ChType chn) +{ + PdbReg_ClrChnErrReg(obj->pdbReg, (uint8_t)chn); +} + +void PdbDrv_SetChnBbMode(PdbDrvType *obj, PdbDrv_ChType chn, uint8_t value) +{ + PdbReg_SetChnBbReg(obj->pdbReg, value, (uint8_t)chn); +} + +uint8_t PdbDrv_GetChnBbMode(PdbDrvType *obj, PdbDrv_ChType chn) +{ + return (PdbReg_GetChnBbReg(obj->pdbReg, (uint8_t)chn)); +} + +void PdbDrv_SetChnTosMode(PdbDrvType *obj, PdbDrv_ChType chn, uint8_t value) +{ + PdbReg_SetChnTosReg(obj->pdbReg, value, (uint8_t)chn); +} + +uint8_t PdbDrv_GetChnTosMode(PdbDrvType *obj, PdbDrv_ChType chn) +{ + return (PdbReg_GetChnTosReg(obj->pdbReg, (uint8_t)chn)); +} + +void PdbDrv_ConfigPreTrg(PdbDrvType *obj, const PdbDrv_PreTrgType *userConfig) +{ + PdbDrv_ChType ch; + PdbDrv_PreChType preCh; + uint8_t tos; + uint8_t en; + uint8_t bb; + /* Pre-Trigger channel configuration */ + for(ch = PDBDRV_CHANNEL0; ch < PDBDRV_CH_NUMBER; ch++) + { + tos = 0; + en = 0; + bb = 0; + for(preCh = PDBDRV_PRE_CHANNEL0; preCh < PDBDRV_PRE_CH_NUMBER; preCh++) + { + switch(userConfig->mode[ch][preCh]) + { + case PDBDRV_PRETRG_DISABLE: + break; + case PDBDRV_PRETRG_BYPASSED_MODE: + en |= PDBDRV_PRE_TRG_ENABLE << preCh; + break; + case PDBDRV_PRETRG_DELAY_MODE: + en |= PDBDRV_PRE_TRG_ENABLE << preCh; + tos |= PDBDRV_PRE_DLY_MODE_ENABLE << preCh; + break; + case PDBDRV_PRETRG_BB_MODE: + en |= PDBDRV_PRE_TRG_ENABLE << preCh; + bb |= PDBDRV_PRE_BB_MODE_ENABLE << preCh; + break; + default: + /* Impossible case */ + break; + } + } + PdbReg_SetChnBbReg(obj->pdbReg, bb, ch); + PdbReg_SetChnTosReg(obj->pdbReg, tos, ch); + PdbReg_SetChnEnReg(obj->pdbReg, en, ch); + } +} + +void PdbDrv_GetPreTrgCfg(const PdbDrvType *obj, PdbDrv_PreTrgType *userConfig) +{ + PdbDrv_ChType ch; + PdbDrv_PreChType preCh; + uint8_t tos; + uint8_t en; + uint8_t bb; + /* Pre-Trigger channel configuration */ + for(ch = PDBDRV_CHANNEL0; ch < PDBDRV_CH_NUMBER; ch++) + { + tos = PdbReg_GetChnTosReg(obj->pdbReg, ch); + en = PdbReg_GetChnEnReg(obj->pdbReg, ch); + bb = PdbReg_GetChnBbReg(obj->pdbReg, ch); + for(preCh = PDBDRV_PRE_CHANNEL0; preCh < PDBDRV_PRE_CH_NUMBER; preCh++) + { + uint8_t preChEn = (en >> preCh) & PDBDRV_PRE_TRG_ENABLE; + uint8_t preChBb = (bb >> preCh) & PDBDRV_PRE_BB_MODE_ENABLE; + uint8_t preChDly = (tos >> preCh) & PDBDRV_PRE_DLY_MODE_ENABLE; + if(preChEn == 0) + { + userConfig->mode[ch][preCh] = PDBDRV_PRETRG_DISABLE; + } + else if(preChBb == 1) + { + userConfig->mode[ch][preCh] = PDBDRV_PRETRG_BB_MODE; + } + else if(preChDly == 1) + { + userConfig->mode[ch][preCh] = PDBDRV_PRETRG_DELAY_MODE; + } + else + { + userConfig->mode[ch][preCh] = PDBDRV_PRETRG_BYPASSED_MODE; + } + } + } +} + +void PdbDrv_GetDefaultConfig(PdbDrv_ConfigType *userConfig) +{ + userConfig->ldmode = PDBDRV_LDMOD_LOAD_VAL_IMMEDIATELY; + userConfig->pdbeie = false; + userConfig->dmaen = false; + userConfig->prescalerFactor = PDBDRV_PRESCALER_1MULT; + userConfig->trgInSel = PDBDRV_TRGSEL_TRGGER_SOFTWARE; + userConfig->pdbie = false; + userConfig->mult = PDBDRV_MULT_FACTOR_1; + userConfig->cMode = PDBDRV_CONT_CONTINUOUS; + + userConfig->dlyCfg.modCnt = 60000; + userConfig->dlyCfg.idlyCnt = 0; + + PdbDrv_ChType ch; + PdbDrv_PreChType preCh; + PdbDrv_PoChType poCh; + for(ch = PDBDRV_CHANNEL0; ch < PDBDRV_CH_NUMBER; ch++) + { + for(preCh = PDBDRV_PRE_CHANNEL0; preCh < PDBDRV_PRE_CH_NUMBER; preCh++) + { + userConfig->preTrgCfg.mode[ch][preCh] = PDBDRV_PRETRG_DISABLE; + userConfig->dlyCfg.dlyCnt[ch][preCh] = 0; + } + } + userConfig->preTrgCfg.mode[0][0] = PDBDRV_PRETRG_BYPASSED_MODE; + + for(poCh = PDBDRV_PO_CHANNEL0; poCh < PDBDRV_PO_CH_NUMBER; poCh++) + { + userConfig->poCfg.poen[poCh] = false; + userConfig->poCfg.dly1[poCh] = 0; + userConfig->poCfg.dly2[poCh] = 0; + } +} + +void PdbDrv_Configure(PdbDrvType *obj, const PdbDrv_ConfigType *userConfig) +{ + PdbDrv_ChType ch; + PdbDrv_PreChType preCh; + PdbDrv_PoChType poCh; + + /* Disable PDB */ + PdbDrv_PdbDisable(obj); + + /* Delay count configuration */ + PdbReg_SetModReg(obj->pdbReg, userConfig->dlyCfg.modCnt); + PdbReg_SetIdlyReg(obj->pdbReg, userConfig->dlyCfg.idlyCnt); + for(ch = PDBDRV_CHANNEL0; ch < PDBDRV_CH_NUMBER; ch++) + { + for(preCh = PDBDRV_PRE_CHANNEL0; preCh < PDBDRV_PRE_CH_NUMBER; preCh++) + { + PdbReg_SetChnDlyReg(obj->pdbReg, userConfig->dlyCfg.dlyCnt[ch][preCh], ch, preCh); + } + } + + /* Pre-trigger channel configuration */ + PdbDrv_ConfigPreTrg(obj, &userConfig->preTrgCfg); + + /* General configuration*/ + PdbReg_SetPdbeieReg(obj->pdbReg, (uint8_t)userConfig->pdbeie); + PdbReg_SetDmaenReg(obj->pdbReg, (uint8_t)userConfig->dmaen); + PdbReg_SetPrescalerReg(obj->pdbReg, userConfig->prescalerFactor); + PdbReg_SetTrgselReg(obj->pdbReg, (uint8_t)userConfig->trgInSel); + PdbReg_SetPdbieReg(obj->pdbReg, (uint8_t)userConfig->pdbie); + PdbReg_SetMultReg(obj->pdbReg, userConfig->mult); + PdbReg_SetContReg(obj->pdbReg, (uint8_t)userConfig->cMode); + + /* Pulse out configuration*/ + uint8_t poen = 0; + + for(poCh = PDBDRV_PO_CHANNEL0; poCh < PDBDRV_PO_CH_NUMBER; poCh++) + { + uint32_t tmp; + tmp = (userConfig->poCfg.dly1[poCh] << PDB_POnDLY_DLY1_SHIFT) | (userConfig->poCfg.dly2[poCh] << PDB_POnDLY_DLY2_SHIFT); + + /*! \note dly1 & dly2 need at the same time to write*/ + PdbReg_SetPonDlyReg(obj->pdbReg, tmp, poCh); + + if(userConfig->poCfg.poen[poCh]) + { + poen |= PDBDRV_PO_ENABLE << poCh; + } + } + PdbReg_SetPoenReg(obj->pdbReg, poen); + + /* Load delay count first*/ + PdbDrv_EnablePdb(obj); + PdbReg_SetLdmodReg(obj->pdbReg, (uint8_t)PDBDRV_LDMOD_LOAD_VAL_IMMEDIATELY); + PdbDrv_LoadCmd(obj); + PdbDrv_PdbDisable(obj); + + /* Load mode configuration */ + PdbReg_SetLdmodReg(obj->pdbReg, (uint8_t)userConfig->ldmode); + + /*! \note When enable PDB depend on user(use PdbDrv_EnablePdb for enable PDB)*/ +} + +void PdbDrv_GetConfig(const PdbDrvType *obj, PdbDrv_ConfigType *userConfig) +{ + PdbDrv_ChType ch; + PdbDrv_PreChType preCh; + PdbDrv_PoChType poCh; + + /* Get general configuration */ + userConfig->ldmode = (PdbDrv_LdmodType)(PdbReg_GetLdmodReg(obj->pdbReg)); + userConfig->pdbeie = PdbReg_GetPdbeieReg(obj->pdbReg); + userConfig->dmaen = PdbReg_GetDmaenReg(obj->pdbReg); + userConfig->prescalerFactor = (PdbDrv_PrescalerType)PdbReg_GetPrescalerReg(obj->pdbReg); + userConfig->trgInSel = (PdbDrv_TrgselType)PdbReg_GetTrgselReg(obj->pdbReg); + userConfig->pdbie = PdbReg_GetPdbieReg(obj->pdbReg); + userConfig->mult = (PdbDrv_MultFactorType)PdbReg_GetMultReg(obj->pdbReg); + userConfig->cMode = (PdbDrv_ContType)PdbReg_GetContReg(obj->pdbReg); + + /* Get pre-trigger channel configuration */ + PdbDrv_PreTrgType preTrgCfg; + PdbDrv_GetPreTrgCfg(obj, &preTrgCfg); + + /* Get delay count configuration */ + userConfig->dlyCfg.modCnt = PdbReg_GetModReg(obj->pdbReg); + userConfig->dlyCfg.idlyCnt = PdbReg_GetIdlyReg(obj->pdbReg); + for(ch = PDBDRV_CHANNEL0; ch < PDBDRV_CH_NUMBER; ch++) + { + for(preCh = PDBDRV_PRE_CHANNEL0; preCh < PDBDRV_PRE_CH_NUMBER; preCh++) + { + userConfig->dlyCfg.dlyCnt[ch][preCh] = PdbReg_GetChnDlyReg(obj->pdbReg, ch, preCh); + userConfig->preTrgCfg.mode[ch][preCh] = preTrgCfg.mode[ch][preCh]; + } + } + + /* Get pulse out configuration */ + uint8_t poen = PdbReg_GetPoenReg(obj->pdbReg); + for(poCh = PDBDRV_PO_CHANNEL0; poCh < PDBDRV_PO_CH_NUMBER; poCh++) + { + userConfig->poCfg.poen[poCh] = (poen >> poCh) & PDBDRV_PO_ENABLE; + userConfig->poCfg.dly1[poCh] = PdbReg_GetPonDly1Reg(obj->pdbReg, poCh); + userConfig->poCfg.dly2[poCh] = PdbReg_GetPonDly2Reg(obj->pdbReg, poCh); + } +} + +void PdbDrv_ConfigDly(PdbDrvType *obj, const PdbDrv_DlyCfgType *userConfig) +{ + PdbDrv_ChType ch; + PdbDrv_PreChType preCh; + + /* Delay count configuration */ + PdbReg_SetModReg(obj->pdbReg, userConfig->modCnt); + PdbReg_SetIdlyReg(obj->pdbReg, userConfig->idlyCnt); + for(ch = PDBDRV_CHANNEL0; ch < PDBDRV_CH_NUMBER; ch++) + { + for(preCh = PDBDRV_PRE_CHANNEL0; preCh < PDBDRV_PRE_CH_NUMBER; preCh++) + { + PdbReg_SetChnDlyReg(obj->pdbReg, userConfig->dlyCnt[ch][preCh], ch, preCh); + } + } + + /*! \note When effective delay count depend on user & load mode(use PdbDrv_LoadCmd for load)*/ +} + +void PdbDrv_GetConfigDly(const PdbDrvType *obj, PdbDrv_DlyCfgType *userConfig) +{ + PdbDrv_ChType ch; + PdbDrv_PreChType preCh; + + /* Get delay count configuration */ + userConfig->modCnt = PdbReg_GetModReg(obj->pdbReg); + userConfig->idlyCnt = PdbReg_GetIdlyReg(obj->pdbReg); + for(ch = PDBDRV_CHANNEL0; ch < PDBDRV_CH_NUMBER; ch++) + { + for(preCh = PDBDRV_PRE_CHANNEL0; preCh < PDBDRV_PRE_CH_NUMBER; preCh++) + { + userConfig->dlyCnt[ch][preCh] = PdbReg_GetChnDlyReg(obj->pdbReg, ch, preCh); + } + } + + /*! \note When effective delay count depend on user(use PdbDrv_LoadCmd for load)*/ +} + +void PdbDrv_ConfigPo(PdbDrvType *obj, const PdbDrv_PoCfgType *userConfig) +{ + PdbDrv_PoChType poCh; + + /* Pulse out configuration */ + + uint8_t poen = 0; + for(poCh = PDBDRV_PO_CHANNEL0; poCh < PDBDRV_PO_CH_NUMBER; poCh++) + { + uint32_t tmp; + tmp = (userConfig->dly1[poCh] << PDB_POnDLY_DLY1_SHIFT) | (userConfig->dly2[poCh] << PDB_POnDLY_DLY2_SHIFT); + PdbReg_SetPonDlyReg(obj->pdbReg, tmp, poCh); + if(userConfig->poen[poCh]) + { + poen |= PDBDRV_PO_ENABLE << poCh; + } + } + PdbReg_SetPoenReg(obj->pdbReg, poen); + + /*! \note When effective delay count depend on user & load mode(use PdbDrv_LoadCmd for load)*/ +} + +void PdbDrv_GetConfigPo(const PdbDrvType *obj, PdbDrv_PoCfgType *userConfig) +{ + PdbDrv_PoChType poCh; + + /* Pulse out configuration */ + uint8_t poen = 0; + poen = PdbReg_GetPoenReg(obj->pdbReg); + for(poCh = PDBDRV_PO_CHANNEL0; poCh < PDBDRV_PO_CH_NUMBER; poCh++) + { + userConfig->dly1[poCh] = PdbReg_GetPonDly1Reg(obj->pdbReg, poCh); + userConfig->dly2[poCh] = PdbReg_GetPonDly2Reg(obj->pdbReg, poCh); + uint8_t poChPoen = (poen >> poCh) & PDBDRV_PO_ENABLE; + if(poChPoen == 1U) + { + userConfig->poen[poCh] = true; + } + } +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/pdb/pdb_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/pdb/pdb_drv.h new file mode 100644 index 0000000..b87a9f4 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/pdb/pdb_drv.h @@ -0,0 +1,481 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PDB_DRV_H_ +#define _PDB_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of PDB module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup pdb_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + *******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief PDB type of LDMOD + */ +typedef enum +{ + /*!< The internal registers are loaded with the values from their buffers, immediately after 1 is written to LDOK. */ + PDBDRV_LDMOD_LOAD_VAL_IMMEDIATELY = 0U, + + /*!< The internal registers are loaded with the values from their buffers when the PDB counter (CNT) = MOD + 1 CNT delay elapsed, after 1 is written to LDOK. */ + PDBDRV_LDMOD_LOAD_VAL_AT_MODULO_COUNTER = 1U, + + /*!< The internal registers are loaded with the values from their buffers when a trigger input event is detected, after 1 is written to LDOK.*/ + PDBDRV_LDMOD_LOAD_VAL_AT_NEXT_TRIGGER = 2U, + + /*!< The internal registers are loaded with the values from their buffers when either the PDB counter (CNT) = MOD + 1 CNT delay elapsed, or a trigger + input event is detected, after 1 is written to LDOK.*/ + PDBDRV_LDMOD_LOAD_VAL_AT_MODULO_COUNTER_OR_NEXT_TRIGGER = 3U, +} PdbDrv_LdmodType; + +/*! \brief PDB type of trigger input source select + * Trigger-In 1 ~ Trigger-In 14 is reserved + */ +typedef enum +{ + PDBDRV_TRGSEL_TRGGER_IN_0 = 0U, /*!< Select Trigger channel 0*/ + PDBDRV_TRGSEL_TRGGER_IN_1 = 1U, /*!< Select Trigger channel 1*/ + PDBDRV_TRGSEL_TRGGER_IN_2 = 2U, /*!< Select Trigger channel 2*/ + PDBDRV_TRGSEL_TRGGER_IN_3 = 3U, /*!< Select Trigger channel 3*/ + PDBDRV_TRGSEL_TRGGER_IN_4 = 4U, /*!< Select Trigger channel 4*/ + PDBDRV_TRGSEL_TRGGER_IN_5 = 5U, /*!< Select Trigger channel 5*/ + PDBDRV_TRGSEL_TRGGER_IN_6 = 6U, /*!< Select Trigger channel 6*/ + PDBDRV_TRGSEL_TRGGER_IN_7 = 7U, /*!< Select Trigger channel 7*/ + PDBDRV_TRGSEL_TRGGER_IN_8 = 8U, /*!< Select Trigger channel 8*/ + PDBDRV_TRGSEL_TRGGER_IN_9 = 9U, /*!< Select Trigger channel 9*/ + PDBDRV_TRGSEL_TRGGER_IN_10 = 10U, /*!< Select Trigger channel 10*/ + PDBDRV_TRGSEL_TRGGER_IN_11 = 11U, /*!< Select Trigger channel 11*/ + PDBDRV_TRGSEL_TRGGER_IN_12 = 12U, /*!< Select Trigger channel 12*/ + PDBDRV_TRGSEL_TRGGER_IN_13 = 13U, /*!< Select Trigger channel 13*/ + PDBDRV_TRGSEL_TRGGER_IN_14 = 14U, /*!< Select Trigger channel 14*/ + PDBDRV_TRGSEL_TRGGER_SOFTWARE = 15U, /*!< Select Trigger form Software*/ +} PdbDrv_TrgselType; + +/*! \brief PDB type of Pre-Trigger channel selection. + */ +typedef enum +{ + PDBDRV_PRE_CHANNEL0 = 0U, /*!< Select Pre-Trigger channel 0*/ + PDBDRV_PRE_CHANNEL1 = 1U, /*!< Select Pre-Trigger channel 1*/ + PDBDRV_PRE_CHANNEL2 = 2U, /*!< Select Pre-Trigger channel 2*/ + PDBDRV_PRE_CHANNEL3 = 3U, /*!< Select Pre-Trigger channel 3*/ + PDBDRV_PRE_CHANNEL4 = 4U, /*!< Select Pre-Trigger channel 4*/ + PDBDRV_PRE_CHANNEL5 = 5U, /*!< Select Pre-Trigger channel 5*/ + PDBDRV_PRE_CHANNEL6 = 6U, /*!< Select Pre-Trigger channel 6*/ + PDBDRV_PRE_CHANNEL7 = 7U, /*!< Select Pre-Trigger channel 7*/ + PDBDRV_PRE_CH_NUMBER = 8U, /*!< Pre-Trigger channel number*/ +} PdbDrv_PreChType; + +/*! \brief PDB type of channel selection. + */ +typedef enum +{ + PDBDRV_CHANNEL0 = 0U, /*!< Select channel 0*/ + PDBDRV_CHANNEL1 = 1U, /*!< Select channel 1*/ + PDBDRV_CH_NUMBER = 2U, /*!< channel number*/ +} PdbDrv_ChType; + +/*! \brief PDB type of Pulse out channel selection. + */ +typedef enum +{ + PDBDRV_PO_CHANNEL0 = 0U, /*!< Select pulse out channel 0*/ + PDBDRV_PO_CH_NUMBER = 1U, /*!< Pulse out channel number*/ +} PdbDrv_PoChType; + +/*! \brief PDB type of CONT + */ +typedef enum +{ + PDBDRV_CONT_ONE_SHOT = 0U, /*!< PDB operation in One-Shot mode*/ + PDBDRV_CONT_CONTINUOUS = 1U, /*!< PDB operation in Continuous mode*/ +} PdbDrv_ContType; + +/*! \brief PDB type of PRESCALER + */ +typedef enum +{ + PDBDRV_PRESCALER_1MULT = 0U, /*!< Counting uses the peripheral clock divided by MULT (the multiplication factor). */ + PDBDRV_PRESCALER_2MULT = 1U, /*!< Counting uses the peripheral clock divided by 2 x MULT (the multiplication factor). */ + PDBDRV_PRESCALER_4MULT = 2U, /*!< Counting uses the peripheral clock divided by 4 x MULT (the multiplication factor). */ + PDBDRV_PRESCALER_8MULT = 3U, /*!< Counting uses the peripheral clock divided by 8 x MULT (the multiplication factor). */ + PDBDRV_PRESCALER_16MULT = 4U, /*!< Counting uses the peripheral clock divided by 16 x MULT (the multiplication factor). */ + PDBDRV_PRESCALER_32MULT = 5U, /*!< Counting uses the peripheral clock divided by 32 x MULT (the multiplication factor). */ + PDBDRV_PRESCALER_64MULT = 6U, /*!< Counting uses the peripheral clock divided by 64 x MULT (the multiplication factor). */ + PDBDRV_PRESCALER_128MULT = 7U, /*!< Counting uses the peripheral clock divided by 128 x MULT (the multiplication factor). */ +} PdbDrv_PrescalerType; + +/*! \brief PDB type of MULT + */ +typedef enum +{ + PDBDRV_MULT_FACTOR_1 = 0U, /*!< Multiplication factor is 1*/ + PDBDRV_MULT_FACTOR_10 = 1U, /*!< Multiplication factor is 10*/ + PDBDRV_MULT_FACTOR_20 = 2U, /*!< Multiplication factor is 20*/ + PDBDRV_MULT_FACTOR_40 = 3U, /*!< Multiplication factor is 40*/ +} PdbDrv_MultFactorType; + +/*! \brief PDB type of pre-trigger mode + */ +typedef enum +{ + PDBDRV_PRETRG_DISABLE = 0U, /*!< PDB Channel Pre-Trigger disable*/ + PDBDRV_PRETRG_BYPASSED_MODE = 1U, /*!< PDB Channel Pre-Trigger bypassed enable*/ + PDBDRV_PRETRG_DELAY_MODE = 2U, /*!< PDB Channel Pre-Trigger delay enable*/ + PDBDRV_PRETRG_BB_MODE = 3U, /*!< PDB Channel Pre-Trigger Back-to-Back operation enable*/ +} PdbDrv_PreTrgModeType; + +/*! \brief Definition of delay count configuration of PDB driver + */ +typedef struct _PdbDrv_DlyCfgType_ +{ + uint16_t modCnt; /*!port = port; + obj->gpio = gpio; +} + +void PinsDrv_SetPullSel(PinsDrvType *obj, uint32_t pin, PinsDrv_InternalPullModeType pullMode) +{ + if(PORT_PCR_COUNT <= pin) + { + return; + } + + /* Pull-down and pull-up cannot be enabled at the same time */ + switch(pullMode) + { + case PINSDRV_INTERNAL_NO_PULL: + PortReg_SetPcrPde(obj->port, pin, 0); /* disable pull-down */ + PortReg_SetPcrPue(obj->port, pin, 0); /* disable pull-up */ + break; + case PINSDRV_INTERNAL_PULL_DOWN: + PortReg_SetPcrPde(obj->port, pin, 1); /* enable pull-down */ + PortReg_SetPcrPue(obj->port, pin, 0); /* disable pull-up */ + break; + case PINSDRV_INTERNAL_PULL_UP: + PortReg_SetPcrPde(obj->port, pin, 0); /* disable pull-down */ + PortReg_SetPcrPue(obj->port, pin, 1); /* enable pull-up */ + break; + default: + break; + } +} + +void PinsDrv_SetPinPasFlt(PinsDrvType *obj, uint32_t pin, bool enable) +{ + if(PORT_PCR_COUNT <= pin) + { + return; + } + + PortReg_SetPcrPasFlt(obj->port, pin, enable); +} + +void PinsDrv_SetPinSr(PinsDrvType *obj, uint32_t pin, bool enable) +{ + if(PORT_PCR_COUNT <= pin) + { + return; + } + + PortReg_SetPcrSr(obj->port, pin, enable); +} + +void PinsDrv_SetPinDrvStr(PinsDrvType *obj, uint32_t pin, bool enable) +{ + if(PORT_PCR_COUNT <= pin) + { + return; + } + + PortReg_SetPcrDrvStr(obj->port, pin, enable); +} + +void PinsDrv_SetPinOde(PinsDrvType *obj, uint32_t pin, bool enable) +{ + if(PORT_PCR_COUNT <= pin) + { + return; + } + + PortReg_SetPcrOde(obj->port, pin, enable); +} +void PinsDrv_SetMuxModeSel(PinsDrvType *obj, uint32_t pin, PinsDrv_MuxType mux) +{ + /* analog feature */ + if(mux == PINSDRV_PIN_DISABLED) + { + PortReg_SetPcrMux(obj->port, pin, mux); + /* Analog pin, need enable analog feature */ + PortReg_SetPcrAen(obj->port, pin, 1); + } + else + { + /* Other functions, must disable analog feature */ + PortReg_SetPcrAen(obj->port, pin, 0); + PortReg_SetPcrMux(obj->port, pin, mux); + } +} + +void PinsDrv_SetPinLock(PinsDrvType *obj, uint32_t pin, bool enable) +{ + if(PORT_PCR_COUNT <= pin) + { + return; + } + + PortReg_SetPcrLock(obj->port, pin, enable); +} + +void PinsDrv_SetPinIntSel(PinsDrvType *obj, uint32_t pin, PinsDrv_InterruptConfigType intConfig) +{ + if(PORT_PCR_COUNT <= pin) + { + return; + } + + PortReg_SetPcrIrqCfg(obj->port, pin, intConfig); +} + +PinsDrv_InterruptConfigType PinsDrv_GetPinIntSel(const PinsDrvType *obj, uint32_t pin) +{ + PinsDrv_InterruptConfigType retval; + if(PORT_PCR_COUNT <= pin) + { + retval = PINSDRV_DMA_INT_RESERVED; + } + else + { + retval = (PinsDrv_InterruptConfigType)PortReg_GetPcrIrqCfg(obj->port, pin); + } + return retval; +} + +void PinsDrv_ClearPinIntFlagCmd(PinsDrvType *obj, uint32_t pin) +{ + if(PORT_PCR_COUNT <= pin) + { + return; + } + + PortReg_SetPcrIsf(obj->port, pin, 1); /* Write 1 to clear */ +} + +void PinsDrv_EnableDigitalFilter(PinsDrvType *obj, uint32_t pin) +{ + if(PORT_PCR_COUNT <= pin) + { + return; + } + + uint32_t tmp = PortReg_GetDferEn(obj->port); + tmp |= (uint32_t)1U << pin; + PortReg_SetDferEn(obj->port, tmp); +} + +void PinsDrv_DisableDigitalFilter(PinsDrvType *obj, uint32_t pin) +{ + if(PORT_PCR_COUNT <= pin) + { + return; + } + + uint32_t tmp = PortReg_GetDferEn(obj->port); + tmp &= ~((uint32_t)1U << pin); + PortReg_SetDferEn(obj->port, tmp); +} + +void PinsDrv_ConfigDigitalFilter(PinsDrvType *obj, const PinsDrv_FilterConfigType *config) +{ + PortReg_SetDfwrLen(obj->port, config->width); +} + +uint32_t PinsDrv_GetPortIntFlag(const PinsDrvType *obj) +{ + return PortReg_GetIsfrIsf(obj->port); +} + +void PinsDrv_ClearPortIntFlagCmd(PinsDrvType *obj) +{ + PortReg_SetIsfrIsf(obj->port, 0xffffffff); +} + +void PinsDrv_SetGlobalPinControl(PinsDrvType *obj, uint16_t pins, uint16_t value, PinsDrv_GlobalControlPinsType whichHalf) +{ + uint32_t mask = 0; + /* keep only available fields */ + mask |= PORT_PCR_PUE_MASK; + mask |= PORT_PCR_PDE_MASK; + mask |= PORT_PCR_PAS_FLT_MASK; + mask |= PORT_PCR_SR_MASK; + mask |= PORT_PCR_DRV_STR_MASK; + mask |= PORT_PCR_ODE_MASK; + mask |= PORT_PCR_MUX_MASK; + mask |= PORT_PCR_LOCK_MASK; + mask &= value; + + /* analog feature */ + if(((mask & PORT_PCR_MUX_MASK) >> PORT_PCR_MUX_SHIFT) == PINSDRV_PIN_DISABLED) + { + /* Analog pin, need enable analog feature */ + mask |= PORT_PCR_AEN_MASK; + } + + mask <<= 16; + mask += pins; + + switch(whichHalf) + { + case PINDRV_GLOBAL_CONTROL_LOWER_HALF_PINS: + PortReg_SetGpclr(obj->port, mask); + break; + case PINDRV_GLOBAL_CONTROL_UPPER_HALF_PINS: + PortReg_SetGpchr(obj->port, mask); + break; + default: + break; + } +} + +void PinsDrv_SetGlobalIntControl(PinsDrvType *obj, uint16_t pins, uint16_t value, PinsDrv_GlobalControlPinsType whichHalf) +{ + uint32_t mask = 0; + + mask = ((uint32_t)value << 16) + pins; + + switch(whichHalf) + { + case PINDRV_GLOBAL_CONTROL_LOWER_HALF_PINS: + PortReg_SetGiclrInt(obj->port, mask); + break; + case PINDRV_GLOBAL_CONTROL_UPPER_HALF_PINS: + PortReg_SetGichrInt(obj->port, mask); + break; + default: + break; + } +} + +uint32_t PinsDrv_GetPinsDirection(const PinsDrvType *obj) +{ + return GpioReg_GetPddrDir(obj->gpio); +} + +void PinsDrv_SetPinDirection(PinsDrvType *obj, uint32_t pin, uint8_t direction) +{ + uint32_t pinDirections = GpioReg_GetPddrDir(obj->gpio); + pinDirections &= (uint32_t)(~((uint32_t)1U << pin)); + pinDirections |= (uint32_t)((uint32_t)direction << pin); + GpioReg_SetPddrDir(obj->gpio, pinDirections); +} + +void PinsDrv_SetPortInputDisable(PinsDrvType *obj, uint32_t mask) +{ + GpioReg_SetPidrInDisable(obj->gpio, mask); +} + +uint32_t PinsDrv_GetPortInputDisable(const PinsDrvType *obj) +{ + return GpioReg_GetPidrInDisable(obj->gpio); +} + +void PinsDrv_WritePin(PinsDrvType *obj, uint32_t pin, uint8_t value) +{ + uint32_t pinDirections = GpioReg_GetPdorDatOut(obj->gpio); + pinDirections &= (uint32_t)(~((uint32_t)1U << pin)); + pinDirections |= (uint32_t)((uint32_t)value << pin); + GpioReg_SetPdorDatOut(obj->gpio, pinDirections); +} + +void PinsDrv_WritePins(PinsDrvType *obj, uint32_t mask) +{ + GpioReg_SetPdorDatOut(obj->gpio, mask); +} + +uint8_t PinsDrv_GetPinOutput(const PinsDrvType *obj, uint32_t pin) +{ + return (uint8_t)((GpioReg_GetPdorDatOut(obj->gpio) >> pin) & 0x01); +} + +uint32_t PinsDrv_GetPinsOutput(const PinsDrvType *obj) +{ + return GpioReg_GetPdorDatOut(obj->gpio); +} + +void PinsDrv_SetPin(PinsDrvType *obj, uint32_t pin) +{ + GpioReg_SetPsorDatSet(obj->gpio, (uint32_t)1U << pin); +} + +void PinsDrv_SetPins(PinsDrvType *obj, uint32_t mask) +{ + GpioReg_SetPsorDatSet(obj->gpio, mask); +} + +void PinsDrv_ClearPin(PinsDrvType *obj, uint32_t pin) +{ + GpioReg_SetPcorDatClr(obj->gpio, (uint32_t)1U << pin); +} + +void PinsDrv_ClearPins(PinsDrvType *obj, uint32_t mask) +{ + GpioReg_SetPcorDatClr(obj->gpio, mask); +} + +void PinsDrv_TogglePin(PinsDrvType *obj, uint32_t pin) +{ + GpioReg_SetPtorDatTog(obj->gpio, (uint32_t)1U << pin); +} + +void PinsDrv_TogglePins(PinsDrvType *obj, uint32_t mask) +{ + GpioReg_SetPtorDatTog(obj->gpio, mask); +} + +uint8_t PinsDrv_ReadPin(PinsDrvType *obj, uint32_t pin) +{ + uint8_t retval = 0; + uint32_t pinsData = GpioReg_GetPdirDatIn(obj->gpio) & ((uint32_t)1U << pin); + if(pinsData == 0) + { + retval = 0; + } + else + { + retval = 1; + } + + return retval; +} + +uint32_t PinsDrv_ReadPins(const PinsDrvType *obj) +{ + return GpioReg_GetPdirDatIn(obj->gpio); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/pins/pins_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/pins/pins_drv.h new file mode 100644 index 0000000..334a12a --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/pins/pins_drv.h @@ -0,0 +1,539 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PINS_DRV_H_ +#define _PINS_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of pins + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup pins_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Internal resistor pull feature selection + */ +typedef enum +{ + PINSDRV_INTERNAL_NO_PULL = 0x00U, /*!< Internal pull-down or pull-up resistor is not enabled */ + PINSDRV_INTERNAL_PULL_DOWN = 0x01U, /*!< Internal pull-down resistor is enabled */ + PINSDRV_INTERNAL_PULL_UP = 0x02U, /*!< Internal pull-up resistor is enabled */ +} PinsDrv_InternalPullModeType; + +/*! \brief Configures the Pin mux selection + */ +typedef enum +{ + PINSDRV_PIN_DISABLED = 0U, /*!< corresponding pin is disabled, but is used as an analog pin */ + PINSDRV_MUX_AS_GPIO = 1U, /*!< corresponding pin is configured as GPIO */ + PINSDRV_MUX_ALT2 = 2U, /*!< chip-specific */ + PINSDRV_MUX_ALT3 = 3U, /*!< chip-specific */ + PINSDRV_MUX_ALT4 = 4U, /*!< chip-specific */ + PINSDRV_MUX_ALT5 = 5U, /*!< chip-specific */ + PINSDRV_MUX_ALT6 = 6U, /*!< chip-specific */ + PINSDRV_MUX_ALT7 = 7U, /*!< chip-specific */ +} PinsDrv_MuxType; + +/*! \brief Configures the interrupt generation condition. + */ +typedef enum +{ + PINSDRV_DMA_INT_DISABLED = 0x0U, /*!< Interrupt/DMA request is disabled. */ + PINSDRV_DMA_RISING_EDGE = 0x1U, /*!< DMA request on rising edge. */ + PINSDRV_DMA_FALLING_EDGE = 0x2U, /*!< DMA request on falling edge. */ + PINSDRV_DMA_EITHER_EDGE = 0x3U, /*!< DMA request on either edge. */ + PINSDRV_INT_LOGIC_ZERO = 0x8U, /*!< Interrupt when logic 0. */ + PINSDRV_INT_RISING_EDGE = 0x9U, /*!< Interrupt on rising edge. */ + PINSDRV_INT_FALLING_EDGE = 0xAU, /*!< Interrupt on falling edge. */ + PINSDRV_INT_EITHER_EDGE = 0xBU, /*!< Interrupt on either edge. */ + PINSDRV_INT_LOGIC_ONE = 0xCU, /*!< Interrupt when logic 1. */ + PINSDRV_DMA_INT_RESERVED = 0xFU, /*!< reserved. */ +} PinsDrv_InterruptConfigType; + +/*! \brief The digital filter configuration + */ +typedef struct +{ + uint8_t width; /*!< The digital filter width value */ +} PinsDrv_FilterConfigType; + +/*! \brief The port global pin/interuppt control registers + */ +typedef enum +{ + PINDRV_GLOBAL_CONTROL_LOWER_HALF_PINS = 0U, /*!< the lower of pins is configured */ + PINDRV_GLOBAL_CONTROL_UPPER_HALF_PINS = 1U /*!< the upper of pins is configured */ +} PinsDrv_GlobalControlPinsType; + +/* Forward declaration of PORT register */ +struct _PortRegType_; +/* Forward declaration of PORT register */ +struct _GpioRegType_; + +/*! \brief The definition of pins driver class + */ +typedef struct _PinsDrvType_ +{ + struct _PortRegType_ *port; /*!< pointer to the port register */ + struct _GpioRegType_ *gpio; /*!< pointer to the gpio register */ +} PinsDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the pins driver module + * + * This function initializes pins driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] port : pointer to PORT register instance + * \param[in] gpio : pointer to GPIO register instance + * \param[in] func : the function of setting digital filter clock + */ +extern void PinsDrv_Init(PinsDrvType *obj, struct _PortRegType_ *port, struct _GpioRegType_ *gpio); + +/*! \brief Configures the internal resistor. + * + * This function configures the internal resistor. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + * \param[in] pullMode : the pull mode + */ +extern void PinsDrv_SetPullSel(PinsDrvType *obj, uint32_t pin, PinsDrv_InternalPullModeType pullMode); + +/*! \brief Configures the port pin passive filter. + * + * This function Configures the port pin passive filter. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + * \param[in] enable : passive filter enable/disable + * - 0 : corresponding pin is set to disable passive filter + * - 1 : corresponding pin is set to enable passive filter + */ +extern void PinsDrv_SetPinPasFlt(PinsDrvType *obj, uint32_t pin, bool enable); + +/*! \brief Configures the port pin slew rate. + * + * This function Configures the port pin slew rate. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + * \param[in] enable : fast/slow slew rate + * - 0 : corresponding pin is set to slow slew rate + * - 1 : corresponding pin is set to fast slew rate + */ +extern void PinsDrv_SetPinSr(PinsDrvType *obj, uint32_t pin, bool enable); + +/*! \brief Configures the port pin drive strength. + * + * This function Configures the port pin drive strength. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + * \param[in] enable : high/low drive strength + * - 0 : corresponding pin is set to low drive strength + * - 1 : corresponding pin is set to high drive strength + */ +extern void PinsDrv_SetPinDrvStr(PinsDrvType *obj, uint32_t pin, bool enable); + +/*! \brief Configures the port pin output mode. + * + * This function Configures the port pin output mode. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + * \param[in] enable : ode/push-pull output + * - 0 : corresponding pin is set to push-pull output + * - 1 : corresponding pin is set to ode output + */ +extern void PinsDrv_SetPinOde(PinsDrvType *obj, uint32_t pin, bool enable); + +/*! \brief Configures the pin muxing. + * + * This function configures the pin muxing. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + * \param[in] mux : Pin muxing slot selection + */ +extern void PinsDrv_SetMuxModeSel(PinsDrvType *obj, uint32_t pin, PinsDrv_MuxType mux); + +/*! \brief Configures the port pin register lock or unlock. + * + * This function Configures the port pin register lock or unlock. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + * \param[in] enable : lock register + * - 0 : Pin Control Register fields [15:0] are not locked + * - 1 : Pin Control Register fields [15:0] are locked and cannot be updated until the next system reset + */ +extern void PinsDrv_SetPinLock(PinsDrvType *obj, uint32_t pin, bool enable); + +/*! \brief Configures the port pin interrupt/DMA request. + * + * This function configures the port pin interrupt/DMA request. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + * \param[in] intConfig : Interrupt configuration + */ +extern void PinsDrv_SetPinIntSel(PinsDrvType *obj, uint32_t pin, PinsDrv_InterruptConfigType intConfig); + +/*! \brief Gets the current port pin interrupt/DMA request configuration. + * + * This function gets the current port pin interrupt/DMA request configuration. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + * \return Interrupt configuration + */ +extern PinsDrv_InterruptConfigType PinsDrv_GetPinIntSel(const PinsDrvType *obj, uint32_t pin); + +/*! \brief Clears the individual pin-interrupt status flag. + * + * This function clears the individual pin-interrupt status flag. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + */ +extern void PinsDrv_ClearPinIntFlagCmd(PinsDrvType *obj, uint32_t pin); + +/*! \brief Enables digital filter for digital pin muxing + * + * This function enables digital filter feature for digital pin muxing + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + */ +extern void PinsDrv_EnableDigitalFilter(PinsDrvType *obj, uint32_t pin); + +/*! \brief Disables digital filter for digital pin muxing + * + * This function disables digital filter feature for digital pin muxing + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + */ +extern void PinsDrv_DisableDigitalFilter(PinsDrvType *obj, uint32_t pin); + +/*! \brief Configures digital filter for port with given configuration + * + * This function configures digital filter for port with given configuration. + * + * User should configure the port filter clock first with the clock module. + * + * \note Updating the filter configuration must be done only after all filters are disabled. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] config : the digital filter configuration struct + */ +extern void PinsDrv_ConfigDigitalFilter(PinsDrvType *obj, const PinsDrv_FilterConfigType *config); + +/*! \brief Reads the entire port interrupt status flag + * + * This function reads the entire port interrupt status flag. + * + * \param[in] obj : pointer to pins driver instance + * \return All 32 pin interrupt status flags + */ +extern uint32_t PinsDrv_GetPortIntFlag(const PinsDrvType *obj); + +/*! \brief Clears the entire port interrupt status flag. + * + * This function clears the entire port interrupt status flag. + * + * \param[in] obj : pointer to pins driver instance + */ +extern void PinsDrv_ClearPortIntFlagCmd(PinsDrvType *obj); + +/*! \brief Quickly configures multiple pins with the same pin configuration. + * + * This function quickly configures multiple pins within the one port for the same peripheral + * function with the same pin configuration. Supports up to 16 pins with the lower or upper + * half of pin registers at the same port. + * + * \note The set global interrupt control function (PinsDrv_SetGlobalIntControl) cannot be + * configured if you ever used this function at the same port + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pins : Pin mask where each bit represents one pin. For each bit: + * - 0 : pins corresponding to bits with value of '1' is updated with the value input + * - 1 : pins corresponding to bits with value of '0' is not updated with the value input + * \param[in] value : the config value will be updated for the pins are set to '1' + * \param[in] whichHalf : the lower or upper half of pin registers at the same port + */ +extern void PinsDrv_SetGlobalPinControl(PinsDrvType *obj, uint16_t pins, uint16_t value, PinsDrv_GlobalControlPinsType whichHalf); + +/*! \brief Quickly configures multiple pins with the same interrupt configuration. + * + * This function quickly configures multiple pins within the one port for the same peripheral + * function with the same interrupt configuration. Supports up to 16 pins with the lower or + * upper half of pin registers at the same port. + * + * \note The set global pin control function (PinsDrv_SetGlobalPinControl) cannot be + * configured if you ever used this function at the same port + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pins : Pin mask where each bit represents one pin. For each bit: + * - 0 : pins corresponding to bits with value of '1' is updated with the value input + * - 1 : pins corresponding to bits with value of '0' is not updated with the value input + * \param[in] value : the config value will be updated for the pins are set to '1' + * \param[in] whichHalf : the lower or upper half of pin registers at the same port + */ +extern void PinsDrv_SetGlobalIntControl(PinsDrvType *obj, uint16_t pins, uint16_t value, PinsDrv_GlobalControlPinsType whichHalf); + +/*! \brief Get the pins directions configuration for a port + * + * This function returns the current pins directions for a port. Pins + * corresponding to bits with value of '1' are configured as output and + * pins corresponding to bits with value of '0' are configured as input. + * + * \param[in] obj : pointer to pins driver instance + * \return GPIO directions. Each bit represents one pin (LSB is pin 0, MSB is pin 31). + * For each bit: + * - 0 : corresponding pin is set to input + * - 1 : corresponding pin is set to output + */ +extern uint32_t PinsDrv_GetPinsDirection(const PinsDrvType *obj); + +/*! \brief Configure the direction for a certain pin from a port + * + * This function configures the direction for the given pin, with the + * given value('1' for pin to be configured as output and '0' for pin to + * be configured as input) + * + * \note With some platforms when you want to set a pin as output only and disable + * input completely, it is required to call PinsDrv_SetPortInputDisable if platform + * has this feature. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number for which to configure the direction + * \param[in] direction : pin direction + * - 0 : corresponding pin is set to input + * - 1 : corresponding pin is set to output + */ +extern void PinsDrv_SetPinDirection(PinsDrvType *obj, uint32_t pin, uint8_t direction); + +/*! \brief Set the pins input disable state for a port + * + * This function sets the pins input state for a port. + * Pins corresponding to bits with value of '1' will not be configured as input + * and pins corresponding to bits with value of '0' will be configured + * as input. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] mask : pin mask where each bit represents one pin (LSB is pin 0, MSB is pin 31). + * For each bit: + * - 0 : corresponding pin is set to input + * - 1 : corresponding pin is not set to input + */ +extern void PinsDrv_SetPortInputDisable(PinsDrvType *obj, uint32_t mask); + +/*! \brief Get the pins input disable state for a port + * + * This function returns the current pins input state for a port. Pins + * corresponding to bits with value of '1' are not configured as input and + * pins corresponding to bits with value of '0' are configured as input. + * + * \param[in] obj : pointer to pins driver instance + * \return GPIO input state. Each bit represents one pin (LSB is pin 0, MSB is pin 31). + * For each bit: + * - 0 : corresponding pin is set to input + * - 1 : corresponding pin is not set to input + */ +extern uint32_t PinsDrv_GetPortInputDisable(const PinsDrvType *obj); + +/*! \brief Write a pin of a port with a given value + * + * This function writes the given pin from a port, with the given value + * ('0' represents LOW, '1' represents HIGH). + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number to be written + * \param[in] value : pin value to be written + * - 0 : corresponding pin is set to LOW + * - 1 : corresponding pin is set to HIGH + */ +extern void PinsDrv_WritePin(PinsDrvType *obj, uint32_t pin, uint8_t value); + +/*! \brief Write all pins of a port + * + * This function writes all pins configured as output with the values given in + * the parameter pins. '0' represents LOW, '1' represents HIGH. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] mask : pin mask to be written + * - 0 : corresponding pin is set to LOW + * - 1 : corresponding pin is set to HIGH + */ +extern void PinsDrv_WritePins(PinsDrvType *obj, uint32_t mask); + +/*! \brief Get the current output from a pin + * + * This function returns the current output that is written to a pin. Only pin + * that are configured as output will have meaningful values. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number to be read + * \return GPIO pin output + * - 0 : corresponding pin is set to LOW + * - 1 : corresponding pin is set to HIGH + */ +extern uint8_t PinsDrv_GetPinOutput(const PinsDrvType *obj, uint32_t pin); + +/*! \brief Get the current output from a port + * + * This function returns the current output that is written to a port. Only pins + * that are configured as output will have meaningful values. + * + * \param[in] obj : pointer to pins driver instance + * \return GPIO outputs. Each bit represents one pin (LSB is pin 0, MSB is pin 31). + * For each bit: + * - 0 : corresponding pin is set to LOW + * - 1 : corresponding pin is set to HIGH + */ +extern uint32_t PinsDrv_GetPinsOutput(const PinsDrvType *obj); + +/*! \brief Write pin with 'Set' value + * + * This function configures output pin in parameter to have a value of 'set' (HIGH). + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : Pin that will be set. + */ +extern void PinsDrv_SetPin(PinsDrvType *obj, uint32_t pin); + +/*! \brief Write pins with 'Set' value + * + * This function configures output pins listed in parameter pins (bits that are + * '1') to have a value of 'set' (HIGH). Pins corresponding to '0' will be + * unaffected. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] mask : Pin mask of bits to be set. Each bit represents one pin (LSB is pin 0, MSB is pin 31). + * For each bit: + * - 0: corresponding pin is unaffected + * - 1: corresponding pin is set to HIGH + */ +extern void PinsDrv_SetPins(PinsDrvType *obj, uint32_t mask); + +/*! \brief Write pin to 'Clear' value + * + * This function configures output pin in parameter to have a 'cleared' value (LOW). + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : Pin that will be cleared. + */ +extern void PinsDrv_ClearPin(PinsDrvType *obj, uint32_t pin); + +/*! \brief Write pins to 'Clear' value + * + * This function configures output pins listed in parameter pins (bits that are + * '1') to have a 'cleared' value (LOW). Pins corresponding to '0' will be + * unaffected. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] mask : Pin mask of bits to be cleared. Each bit represents one pin (LSB is pin 0, MSB is pin 31). + * For each bit: + * - 0 : corresponding pin is unaffected + * - 1 : corresponding pin is cleared(set to LOW) + */ +extern void PinsDrv_ClearPins(PinsDrvType *obj, uint32_t mask); + +/*! \brief Toggle pin value + * + * This function toggles output pin in parameter. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : Pin that will be toggled. + */ +extern void PinsDrv_TogglePin(PinsDrvType *obj, uint32_t pin); + +/*! \brief Toggle pins value + * + * This function toggles output pins listed in parameter pins (bits that are + * '1'). Pins corresponding to '0' will be unaffected. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] mask : Pin mask of bits to be toggled. Each bit represents one pin (LSB is pin 0, MSB is pin 31). + * For each bit: + * - 0 : corresponding pin is unaffected + * - 1 : corresponding pin is toggled + */ +extern void PinsDrv_TogglePins(PinsDrvType *obj, uint32_t mask); + +/*! \brief Read a pin of a port + * + * This function returns the current input value of the given pin from a port. + * Only pins configured as input will have meaningful values. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number to read + * \return pin value + * - 0 : corresponding pin is read as LOW + * - 1 : corresponding pin is read as HIGH + */ +extern uint8_t PinsDrv_ReadPin(PinsDrvType *obj, uint32_t pin); + +/*! \brief Read input pins + * + * This function returns the current input values from a port. Only pins + * configured as input will have meaningful values. + * + * \param[in] obj : pointer to pins driver instance + * \return GPIO inputs. Each bit represents one pin (LSB is pin 0, MSB is pin 31). + * For each bit: + * - 0 : corresponding pin is read as LOW + * - 1 : corresponding pin is read as HIGH + */ +extern uint32_t PinsDrv_ReadPins(const PinsDrvType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _PINS_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/power/power_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/power/power_drv.c new file mode 100644 index 0000000..1a711d7 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/power/power_drv.c @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "../cpu/cpu_drv.h" +#include "power_drv.h" +#include "pmc_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void PowerDrv_Init(PowerDrvType *obj, struct _PmcRegType_ *pmcReg, struct _Scg2RegType_ *scg2Reg, struct _Scg1RegType_ *scg1Reg, struct _Scg0RegType_ *scg0Reg) +{ + obj->pmcReg = pmcReg; + obj->scg2Reg = scg2Reg; + obj->scg1Reg = scg1Reg; + obj->scg0Reg = scg0Reg; +} + +void PowerDrv_UnlockRegWriteAccess(PowerDrvType *obj) +{ + PmcReg_SetKey(obj->pmcReg, 0x20220509); +} + +void PowerDrv_LockRegWriteAccess(PowerDrvType *obj) +{ + PmcReg_SetKey(obj->pmcReg, 0); +} + +void PowerDrv_EnableLvwWarning(PowerDrvType *obj) +{ + PmcReg_SetDAIntfCtrlEnLvw(obj->pmcReg, true); +} + +void PowerDrv_DisableLvwWarning(PowerDrvType *obj) +{ + PmcReg_SetDAIntfCtrlEnLvw(obj->pmcReg, false); +} + +void PowerDrv_SetLvwLevel(PowerDrvType *obj, PowerDrvLvwLevelType level) +{ + PmcReg_SetDAIntfCtrlSelLvw(obj->pmcReg, level); +} + +void PowerDrv_EnableLvdDetect(PowerDrvType *obj) +{ + PmcReg_SetDAIntfCtrlEnLvd(obj->pmcReg, true); +} + +void PowerDrv_DisableLvdDetect(PowerDrvType *obj) +{ + PmcReg_SetDAIntfCtrlEnLvd(obj->pmcReg, false); +} + +void PowerDrv_EnableOtpWarning(PowerDrvType *obj) +{ + PmcReg_SetDAIntfCtrlOtpEn(obj->pmcReg, true); +} + +void PowerDrv_DisableOtpWarning(PowerDrvType *obj) +{ + PmcReg_SetDAIntfCtrlOtpEn(obj->pmcReg, false); +} + +void PowerDrv_EnableFldoDetect(PowerDrvType *obj) +{ + PmcReg_SetDAIntfCtrlEnFldoVDet(obj->pmcReg, true); +} + +void PowerDrv_DisableFldoDetect(PowerDrvType *obj) +{ + PmcReg_SetDAIntfCtrlEnFldoVDet(obj->pmcReg, false); +} + +void PowerDrv_ReleasePadKeep(PowerDrvType *obj) +{ + /* this bit is W1C, user should release it as early as possible */ + PowerDrv_UnlockRegWriteAccess(obj); + PmcReg_ClearStatusPadKeep(obj->pmcReg); + PowerDrv_LockRegWriteAccess(obj); +} + +uint8_t PowerDrv_GetStbAbortFlag(PowerDrvType *obj) +{ + uint8_t retval = 0; + retval = PmcReg_GetStatusStdbyAbortSts(obj->pmcReg); + return retval; +} + +void PowerDrv_ClrStbAbortFlag(PowerDrvType *obj) +{ + if(PmcReg_GetStatusStdbyAbortSts(obj->pmcReg)) + { + /* only clear when this bit is set, and this bit is W1C */ + PmcReg_ClearStatusStdbyAbortSts(obj->pmcReg); + } +} + +void PowerDrv_ClrAllWakupFlags(PowerDrvType *obj) +{ + /* clear all the wakeup flags */ + PowerDrv_UnlockRegWriteAccess(obj); + PmcReg_ClearWakupFlgCmpWakupEvtFlag(obj->pmcReg); + PmcReg_ClearWakupFlgLptmrWakupEvtFlg(obj->pmcReg); + PmcReg_ClearWakupFlgLpitWakupEvtFlg(obj->pmcReg); + PmcReg_ClearWakupFlgRtcWakupEvtFlg(obj->pmcReg); + PmcReg_ClearWakupFlgExtrstWakupEvtFlg(obj->pmcReg); + PmcReg_ClearWakupFlgPortEWakupEvtFlg(obj->pmcReg); + PmcReg_ClearWakupFlgPortDWakupEvtFlg(obj->pmcReg); + PmcReg_ClearWakupFlgPortCWakupEvtFlg(obj->pmcReg); + PmcReg_ClearWakupFlgPortBWakupEvtFlg(obj->pmcReg); + PmcReg_ClearWakupFlgPortAWakupEvtFlg(obj->pmcReg); + PowerDrv_LockRegWriteAccess(obj); +} + +void PowerDrv_ClrWakeupFlag(PowerDrvType *obj, PowerDrvWakeupFlagType flag) +{ + PowerDrv_UnlockRegWriteAccess(obj); + switch(flag) + { + case POWERDRV_PORTA_WU: + PmcReg_ClearWakupFlgPortAWakupEvtFlg(obj->pmcReg); + break; + case POWERDRV_PORTB_WU: + PmcReg_ClearWakupFlgPortBWakupEvtFlg(obj->pmcReg); + break; + case POWERDRV_PORTC_WU: + PmcReg_ClearWakupFlgPortCWakupEvtFlg(obj->pmcReg); + break; + case POWERDRV_PORTD_WU: + PmcReg_ClearWakupFlgPortDWakupEvtFlg(obj->pmcReg); + break; + case POWERDRV_PORTE_WU: + PmcReg_ClearWakupFlgPortEWakupEvtFlg(obj->pmcReg); + break; + case POWERDRV_RSTPIN_WU: + PmcReg_ClearWakupFlgExtrstWakupEvtFlg(obj->pmcReg); + break; + case POWERDRV_RTC_WU: + PmcReg_ClearWakupFlgRtcWakupEvtFlg(obj->pmcReg); + break; + case POWERDRV_LPIT_WU: + PmcReg_ClearWakupFlgLpitWakupEvtFlg(obj->pmcReg); + break; + case POWERDRV_LPTMR_WU: + PmcReg_ClearWakupFlgLptmrWakupEvtFlg(obj->pmcReg); + break; + case POWERDRV_CMP_WU: + PmcReg_ClearWakupFlgCmpWakupEvtFlag(obj->pmcReg); + break; + default: + break; + } + PowerDrv_LockRegWriteAccess(obj); +} + +PowerDrvWakeupFlagType PowerDrv_GetWakeupSource(PowerDrvType *obj) +{ + PowerDrvWakeupFlagType rtv = POWERDRV_NO_WU; + /* scan and return the wakeup flag which is set */ + for(uint8_t i = POWERDRV_PORTA_WU; i <= POWERDRV_CMP_WU; i++) + { + uint32_t temp = 1; + temp <<= i; + if(obj->pmcReg->WAKUP_FLG & temp) + { + rtv = (PowerDrvWakeupFlagType)i; + } + } + return rtv; +} + +void PowerDrv_StandbyModePreTask(PowerDrvType *obj) +{ + /* make sure these bits setting are correct before standby mode */ + PowerDrv_DisableOtpWarning(obj); + PowerDrv_DisableLvdDetect(obj); + PowerDrv_DisableLvwWarning(obj); + Scg0Reg_SetOscCtrlEnSosc(obj->scg0Reg, 0); + Scg0Reg_SetOscCtrlEnExtClk(obj->scg0Reg, 0); + Scg0Reg_SetPllCtrl0PllEn(obj->scg0Reg, 0); +} + +void PowerDrv_SetPowerMode(PowerDrvType *obj, PowerDrvPowerModeType mode) +{ + PowerDrv_UnlockRegWriteAccess(obj); + Scg0Reg_SetKey(obj->scg0Reg, 0x19962020); + /* target mode is stop mode */ + if(mode == POWERDRV_POWER_MODE_STOP) + { + /* enable stop mode */ + PmcReg_SetGlbCtrlStdbyEn(obj->pmcReg, 0); + PmcReg_SetGlbCtrlStopEn(obj->pmcReg, 1); + PmcReg_SetGlbCtrlCpuRetionEn(obj->pmcReg, 0); + Scg1Reg_SetCpuModeRet(obj->scg1Reg, 0); + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + } + /* target mode is standby mode */ + else + { + Scg2Reg_SetCsrSrcSys(obj->scg2Reg, 0); + PmcReg_SetGlbCtrlStopEn(obj->pmcReg, 0); + PmcReg_SetGlbCtrlStdbyEn(obj->pmcReg, 1); + PowerDrv_StandbyModePreTask(obj); + if(mode == POWERDRV_POWER_MODE_STANDBY_WITH_CPU_RETENTION) + { + PmcReg_SetGlbCtrlCpuRetionEn(obj->pmcReg, 1); + Scg1Reg_SetCpuModeRet(obj->scg1Reg, 1); + } + else + { + PmcReg_SetGlbCtrlCpuRetionEn(obj->pmcReg, 0); + Scg1Reg_SetCpuModeRet(obj->scg1Reg, 0); + } + PowerDrv_ClrAllWakupFlags(obj); + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + } + PowerDrv_LockRegWriteAccess(obj); + Scg0Reg_SetKey(obj->scg0Reg, 0); + __WFI(); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/power/power_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/power/power_drv.h new file mode 100644 index 0000000..c2cc86e --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/power/power_drv.h @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _POWER_DRV_H_ +#define _POWER_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of power related modules such as reset + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup power_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +typedef enum +{ + POWERDRV_LVW1 = 0x0U, /*!< LVW LEVEL1 */ + POWERDRV_LVW2 = 0x1U, /*!< LVW LEVEL2 */ + POWERDRV_LVW3 = 0x2U /*!< LVW LEVEL3 */ +} PowerDrvLvwLevelType; + +typedef enum +{ + POWERDRV_POWER_MODE_RUN = 0x0U, /*!< RUN MODE */ + POWERDRV_POWER_MODE_STOP = 0x1U, /*!< STOP MODE */ + POWERDRV_POWER_MODE_STANDBY_WITH_CPU_RETENTION = 0x2U, /*!< STANDBY MODE WITH CPU RETENTION */ + POWERDRV_POWER_MODE_STANDBY_WITHOUT_CPU_RETENTION + = 0x3U /*!< STANDBY MODE WITHOUT CPU RETENTION */ +} PowerDrvPowerModeType; + +typedef enum +{ + POWERDRV_PORTA_WU = 0x00U, /*!< WAKEUP BY PORTA */ + POWERDRV_PORTB_WU = 0x01U, /*!< WAKEUP BY PORTB */ + POWERDRV_PORTC_WU = 0x02U, /*!< WAKEUP BY PORTC */ + POWERDRV_PORTD_WU = 0x03U, /*!< WAKEUP BY PORTD */ + POWERDRV_PORTE_WU = 0x04U, /*!< WAKEUP BY PORTE */ + POWERDRV_RSTPIN_WU = 0x05U, /*!< WAKEUP BY RESET PIN */ + POWERDRV_RTC_WU = 0x06U, /*!< WAKEUP BY RTC */ + POWERDRV_LPIT_WU = 0x08U, /*!< WAKEUP BY LPIT */ + POWERDRV_LPTMR_WU = 0x09U, /*!< WAKEUP BY LPTMR */ + POWERDRV_CMP_WU = 0x0AU, /*!< WAKEUP BY CMP */ + POWERDRV_NO_WU = 0xFFU /*!< No WAKEUP FLAG */ +} PowerDrvWakeupFlagType; + +typedef struct _PowerDrvType_ +{ + struct _PmcRegType_ *pmcReg; + struct _Scg2RegType_ *scg2Reg; + struct _Scg1RegType_ *scg1Reg; + struct _Scg0RegType_ *scg0Reg; +} PowerDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ +/*! \brief Initializes the Power reg + * + * + * \param[in] obj : pointer to POWER driver instance + * \param[in] pmcReg : pointer to POWER register instance + * \param[in] scg2Reg : pointer to SCG2 register instance + * \param[in] scg1Reg : pointer to SCG1 register instance + * \param[in] scg0Reg : pointer to SCG0 register instance + */ +extern void PowerDrv_Init(PowerDrvType *obj, struct _PmcRegType_ *pmcReg, struct _Scg2RegType_ *scg2Reg, struct _Scg1RegType_ *scg1Reg, struct _Scg0RegType_ *scg0Reg); + +/*! \brief Unlock the PMC register write access + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_UnlockRegWriteAccess(PowerDrvType *obj); + +/*! \brief Lock the PMC register write access + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_LockRegWriteAccess(PowerDrvType *obj); + +/*! \brief Enable the LVW warning + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_EnableLvwWarning(PowerDrvType *obj); + +/*! \brief Disable the LVW warning + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_DisableLvwWarning(PowerDrvType *obj); + +/*! \brief set the lvw warning level + * + * + * \param[in] obj : pointer to POWER driver instance + * \param[in] level : the target lvw warning level + */ +extern void PowerDrv_SetLvwLevel(PowerDrvType *obj, PowerDrvLvwLevelType level); + +/*! \brief Enable the LVD detect + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_EnableLvdDetect(PowerDrvType *obj); + +/*! \brief Disable the LVD detect + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_DisableLvdDetect(PowerDrvType *obj); + +/*! \brief Enable the OTP warning + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_EnableOtpWarning(PowerDrvType *obj); + +/*! \brief Disable the OTP warning + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_DisableOtpWarning(PowerDrvType *obj); + +/*! \brief Enable the FLDO detect + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_EnableFldoDetect(PowerDrvType *obj); + +/*! \brief Disable the FLDO detect + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_DisableFldoDetect(PowerDrvType *obj); + +/*! \brief release the pad keep feature + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_ReleasePadKeep(PowerDrvType *obj); + +/*! \brief get the standby abort flag + * + * + * \param[in] obj : pointer to POWER driver instance + * \param[out] flag : flag + * - 0 : no abort happenned + * - 1 : abort happenned + */ +extern uint8_t PowerDrv_GetStbAbortFlag(PowerDrvType *obj); + +/*! \brief clear the standby abort flag + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_ClrStbAbortFlag(PowerDrvType *obj); + +/*! \brief clear all wakeup flags + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_ClrAllWakupFlags(PowerDrvType *obj); + +/*! \brief clear dedicated wakeup flag + * + * + * \param[in] obj : pointer to POWER driver instance + * \param[in] flag : the wakeup flag + */ +extern void PowerDrv_ClrWakeupFlag(PowerDrvType *obj, PowerDrvWakeupFlagType flag); + +/*! \brief get the wakeup flag + * + * + * \param[in] obj : pointer to POWER driver instance + * \param[out] PowerDrvWakeupFlagType : flag + */ +extern PowerDrvWakeupFlagType PowerDrv_GetWakeupSource(PowerDrvType *obj); + +/*! \brief set the power mode + * + * + * \param[in] obj : pointer to POWER driver instance + * \param[in] mode : the target mode + */ +extern void PowerDrv_SetPowerMode(PowerDrvType *obj, PowerDrvPowerModeType mode); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _POWER_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/pwmlite/pwmlite_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/pwmlite/pwmlite_drv.c new file mode 100644 index 0000000..81feb16 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/pwmlite/pwmlite_drv.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "pwmlite_drv.h" +#include "pwmlite_reg.h" +#include "sim_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +typedef void (*setPwmLiteMuxFunc)(SimRegType *obj, uint8_t value); + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +const setPwmLiteMuxFunc c_pwmLiteMuxFuncTable[PWMLITEDRV_MUX_PAD_PWM_NUM] = { + SimReg_SetPwmCtrl0PwmFunc0, + SimReg_SetPwmCtrl0PwmFunc1, + SimReg_SetPwmCtrl0PwmFunc2, + SimReg_SetPwmCtrl0PwmFunc3, + + SimReg_SetPwmCtrl1PwmFunc4, + SimReg_SetPwmCtrl1PwmFunc5, +}; + +const PwmLiteDrv_PwmMuxPadNumType c_pwmLiteMuxPadIndex[] = { + PWMLITEDRV_MUX_PAD_PWM0, + PWMLITEDRV_MUX_PAD_PWM1, + PWMLITEDRV_MUX_PAD_PWM2, + PWMLITEDRV_MUX_PAD_PWM3, + PWMLITEDRV_MUX_PAD_PWM4, + PWMLITEDRV_MUX_PAD_PWM5, +}; +#define PWMLITE_PWMMUXINDEX_MAX (sizeof(c_pwmLiteMuxPadIndex) / sizeof(PwmLiteDrv_PwmMuxPadNumType)) + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +void PwmLiteDrv_Init(PwmLiteDrvType *obj, struct _PwmLiteRegType_ *pwmLiteReg, struct _SimRegType_ *simReg) +{ + uint16_t i; + + obj->pwmLiteReg = pwmLiteReg; + obj->simReg = simReg; + /* disable the mux pwm output */ + for(i = 0; i < PWMLITE_PWMMUXINDEX_MAX; i++) + { + PwmLiteDrv_OutputMux(obj, PWMLITEDRV_MUX_PWM_CH_INVALID, c_pwmLiteMuxPadIndex[i]); + } +} + +void PwmLiteDrv_ModuleConfig(PwmLiteDrvType *obj, const PwmLiteDrv_ModuleConfigType *userConfig) +{ + /* disable the module first */ + PwmLiteDrv_DisableModule(obj); + /* Set the pwm period value */ + PwmLiteReg_SetPrdPeriod(obj->pwmLiteReg, userConfig->period); + /* Set the syne type of the module */ + PwmLiteReg_SetCtrlSyncMode(obj->pwmLiteReg, userConfig->syncType); +} + +void PwmLiteDrv_GetDefaultModuleConfig(PwmLiteDrv_ModuleConfigType *ModuleConfigType) +{ + ModuleConfigType->period = 0; + ModuleConfigType->syncType = PWMLITEDRV_SYNC_AT_RUNNING; +} + +void PwmLiteDrv_ConfigChannel(PwmLiteDrvType *obj, uint8_t channel, const PwmLiteDrv_ChannelConfigType *userConfig) +{ + if(channel >= PWMLITEDRV_PWM_CH_NUM) + { + return; + } + /* disable the module first */ + PwmLiteDrv_DisableModule(obj); + /* Set the pwm channels to target pad channel through SIM */ + PwmLiteDrv_OutputMux(obj, userConfig->pwmMuxType.channelNumber, userConfig->pwmMuxType.padNumber); + /* Set pwm threshold0/1 value */ + PwmLiteDrv_UpdatePwmThresholdAtRunning(obj, channel, userConfig->threshold0, userConfig->threshold1); + /* Set pwm threshold0 behavior */ + PwmLiteReg_SetChCtrl0(obj->pwmLiteReg, channel, userConfig->behavior0); + /* Set pwm threshold1 behavior */ + PwmLiteReg_SetChCtrl1(obj->pwmLiteReg, channel, userConfig->behavior1); +} + +void PwmLiteDrv_GetDefaultChannelConfig(PwmLiteDrv_ChannelConfigType *ChannelConfigType) +{ + ChannelConfigType->behavior0 = PWMLITEDRV_TOGGLE_AT_REACH; + ChannelConfigType->behavior1 = PWMLITEDRV_TOGGLE_AT_REACH; + ChannelConfigType->threshold0 = 0; + ChannelConfigType->threshold1 = 0; +} + +void PwmLiteDrv_EnableModule(PwmLiteDrvType *obj) +{ + PwmLiteReg_SetCtrlEn(obj->pwmLiteReg, 1); +} + +void PwmLiteDrv_DisableModule(PwmLiteDrvType *obj) +{ + PwmLiteReg_SetCtrlEn(obj->pwmLiteReg, 0); +} + +void PwmLiteDrv_Resume(PwmLiteDrvType *obj) +{ + PwmLiteReg_SetStopPause(obj->pwmLiteReg, 0); +} + +void PwmLiteDrv_Pause(PwmLiteDrvType *obj) +{ + PwmLiteReg_SetStopPause(obj->pwmLiteReg, 1); +} + +void PwmLiteDrv_UpdatePwmThresholdAtRunning(PwmLiteDrvType *obj, uint8_t channel, uint32_t threshold0, uint32_t threshold1) +{ + uint32_t prd = PwmLiteReg_GetPrdPeriod(obj->pwmLiteReg); + if(threshold1 == threshold0) /* DUTY: 0% */ + { + /* Set pwm threshold0 value */ + PwmLiteReg_SetChThr0(obj->pwmLiteReg, channel, (prd + 0x1u)); + /* Set pwm threshold1 value */ + PwmLiteReg_SetChThr1(obj->pwmLiteReg, channel, 0x0u); + } + else if(threshold1 - threshold0 == prd) /* DUTY: 100% */ + { + /* Set pwm threshold0 value */ + PwmLiteReg_SetChThr0(obj->pwmLiteReg, channel, 0x0u); + /* Set pwm threshold1 value */ + PwmLiteReg_SetChThr1(obj->pwmLiteReg, channel, (prd + 0x1u)); + } + else /* DUTY: 0~100% */ + { + /* Set pwm threshold0 value */ + PwmLiteReg_SetChThr0(obj->pwmLiteReg, channel, threshold0); + /* Set pwm threshold1 value */ + PwmLiteReg_SetChThr1(obj->pwmLiteReg, channel, threshold1); + } +} + +void PwmLiteDrv_UpdatePwmThresholdAtSync(PwmLiteDrvType *obj, uint8_t channel, uint32_t threshold0, uint32_t threshold1) +{ + uint32_t prd = PwmLiteReg_GetPrdPeriod(obj->pwmLiteReg); + if(threshold1 == threshold0) /* DUTY: 0% */ + { + /* Set pwm threshold0 value */ + PwmLiteReg_SetChThr0(obj->pwmLiteReg, channel, (prd + 0x1u)); + /* Set pwm threshold1 value */ + PwmLiteReg_SetChThr1(obj->pwmLiteReg, channel, 0x0u); + } + else if(threshold1 - threshold0 == prd) /* DUTY: 100% */ + { + /* Set pwm threshold0 value */ + PwmLiteReg_SetChThr0(obj->pwmLiteReg, channel, 0x0u); + /* Set pwm threshold1 value */ + PwmLiteReg_SetChThr1(obj->pwmLiteReg, channel, (prd + 0x1u)); + } + else /* DUTY: 0~100% */ + { + /* Set pwm threshold0 value */ + PwmLiteReg_SetChThr0(obj->pwmLiteReg, channel, threshold0); + /* Set pwm threshold1 value */ + PwmLiteReg_SetChThr1(obj->pwmLiteReg, channel, threshold1); + } + PwmLiteDrv_TrigSync(obj); + while(PwmLiteDrv_GetSyncResult(obj)) + { + ; + } +} + +void PwmLiteDrv_OutputMux(PwmLiteDrvType *obj, PwmLiteDrv_PwmMuxChannelType channel, PwmLiteDrv_PwmMuxPadNumType number) +{ + if(number >= PWMLITEDRV_MUX_PAD_PWM_NUM) + { + return; + } + /* select the correct path through target channel number */ + c_pwmLiteMuxFuncTable[number](obj->simReg, (uint8_t)channel); +} + +uint8_t PwmLiteDrv_GetSyncResult(PwmLiteDrvType *obj) +{ + uint8_t result = 0; + result = PwmLiteReg_GetSyncStatus(obj->pwmLiteReg); + return result; +} + +void PwmLiteDrv_TrigSync(PwmLiteDrvType *obj) +{ + PwmLiteReg_SetSyncStart(obj->pwmLiteReg, 1); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/pwmlite/pwmlite_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/pwmlite/pwmlite_drv.h new file mode 100644 index 0000000..22a11b5 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/pwmlite/pwmlite_drv.h @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PWMLITE_DRV_H_ +#define _PWMLITE_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of PWMLITE + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup pwmlite_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +typedef enum +{ + PWMLITEDRV_PWM_CH0 = 0x0U, /*!< Pwm0/1 channel0 */ + PWMLITEDRV_PWM_CH1 = 0x1U, /*!< Pwm0/1 channel1 */ + PWMLITEDRV_PWM_CH2 = 0x2U, /*!< Pwm0/1 channel2 */ + PWMLITEDRV_PWM_CH3 = 0x3U, /*!< Pwm0/1 channel3 */ + PWMLITEDRV_PWM_CH4 = 0x4U, /*!< Pwm0/1 channel4 */ + PWMLITEDRV_PWM_CH5 = 0x5U, /*!< Pwm0/1 channel5 */ + + PWMLITEDRV_PWM_CH_NUM, +} PwmLiteDrv_PwmChannelType; + +typedef enum +{ + PWMLITEDRV_MUX_PWM0_CH0 = 0x0U, /*!< Mux Pwm0 channel0 */ + PWMLITEDRV_MUX_PWM0_CH1 = 0x1U, /*!< Mux Pwm0 channel1 */ + PWMLITEDRV_MUX_PWM0_CH2 = 0x2U, /*!< Mux Pwm0 channel2 */ + PWMLITEDRV_MUX_PWM0_CH3 = 0x3U, /*!< Mux Pwm0 channel3 */ + PWMLITEDRV_MUX_PWM0_CH4 = 0x4U, /*!< Mux Pwm0 channel4 */ + PWMLITEDRV_MUX_PWM0_CH5 = 0x5U, /*!< Mux Pwm0 channel5 */ + PWMLITEDRV_MUX_PWM1_CH0 = 0x6U, /*!< Mux Pwm1 channel0 */ + PWMLITEDRV_MUX_PWM1_CH1 = 0x7U, /*!< Mux Pwm1 channel1 */ + PWMLITEDRV_MUX_PWM1_CH2 = 0x8U, /*!< Mux Pwm1 channel2 */ + PWMLITEDRV_MUX_PWM1_CH3 = 0x9U, /*!< Mux Pwm1 channel3 */ + PWMLITEDRV_MUX_PWM1_CH4 = 0xAU, /*!< Mux Pwm1 channel4 */ + PWMLITEDRV_MUX_PWM1_CH5 = 0xBU, /*!< Mux Pwm1 channel5 */ + + PWMLITEDRV_MUX_PWM_CH_INVALID, +} PwmLiteDrv_PwmMuxChannelType; + +typedef enum +{ + PWMLITEDRV_MUX_PAD_PWM0 = 0x0U, /*!< MUX PWM00 PAD */ + PWMLITEDRV_MUX_PAD_PWM1 = 0x1U, /*!< MUX PWM01 PAD */ + PWMLITEDRV_MUX_PAD_PWM2 = 0x2U, /*!< MUX PWM02 PAD */ + PWMLITEDRV_MUX_PAD_PWM3 = 0x3U, /*!< MUX PWM03 PAD */ + PWMLITEDRV_MUX_PAD_PWM4 = 0x4U, /*!< MUX PWM04 PAD */ + PWMLITEDRV_MUX_PAD_PWM5 = 0x5U, /*!< MUX PWM05 PAD */ + + PWMLITEDRV_MUX_PAD_PWM_NUM, +} PwmLiteDrv_PwmMuxPadNumType; + +typedef enum +{ + PWMLITEDRV_SYNC_AT_RUNNING = 0x0U, /*!< Sync at running */ + PWMLITEDRV_SYNC_AT_PERIOD = 0x1U /*!< Sync at period */ +} PwmLiteDrv_SyncType; + +typedef enum +{ + PWMLITEDRV_KEEP_AT_REACH = 0x0U, /*!< Output keep at reach match value */ + PWMLITEDRV_LOW_AT_REACH = 0x1U, /*!< Output set low at reach match value */ + PWMLITEDRV_HIGH_AT_REACH = 0x2U, /*!< Output set high at reach match value */ + PWMLITEDRV_TOGGLE_AT_REACH = 0x3U /*!< Output toggle at reach match value */ +} PwmLiteDrv_OutBehaviorType; + +/*! \brief The definition of PWMLITE driver class + */ +typedef struct _PwmLiteDrvType_ +{ + struct _PwmLiteRegType_ *pwmLiteReg; + struct _SimRegType_ *simReg; +} PwmLiteDrvType; + +typedef struct _PwmLiteDrv_PwmMuxConfigType_ +{ + PwmLiteDrv_PwmMuxChannelType channelNumber; /*!< The pwmlite channel number */ + PwmLiteDrv_PwmMuxPadNumType padNumber; /*!< The target pad number */ +} PwmLiteDrv_PwmMuxConfigType; + +typedef struct _PwmLiteDrv_ModuleConfigType_ +{ + uint32_t period; /*!< Pwm period value */ + PwmLiteDrv_SyncType syncType; /*!< Module sync type */ + +} PwmLiteDrv_ModuleConfigType; + +typedef struct _PwmLiteDrv_ChannelConfigType_ +{ + PwmLiteDrv_PwmMuxConfigType pwmMuxType; /*!< Pwm mux output type */ + + uint32_t threshold0; /*!< Threshold0 of the channel */ + uint32_t threshold1; /*!< Threshold1 of the channel */ + PwmLiteDrv_OutBehaviorType behavior0; /*!< Behavior0 on reach threshold0 */ + PwmLiteDrv_OutBehaviorType behavior1; /*!< Behavior1 on reach threshold1 */ +} PwmLiteDrv_ChannelConfigType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the PWMlite reg + * + * + * \param[in] obj : pointer to PWMLITE driver instance + * \param[in] pwmLiteReg : pointer to PWMLITE register instance + * \param[in] simReg : pointer to SIM register instance + */ +extern void PwmLiteDrv_Init(PwmLiteDrvType *obj, struct _PwmLiteRegType_ *pwmLiteReg, struct _SimRegType_ *simReg); + +/*! \brief Get default configures the PWMLITE module for configuration structure + * + * This function gets default configures the PWMLITE module for user configuration structure + * + * \param[in] obj : pointer to PWMLITE driver instance + * + */ +extern void PwmLiteDrv_GetDefaultModuleConfig(PwmLiteDrv_ModuleConfigType *ModuleConfigType); + +/*! \brief config the pwm module according to user config + * + * + * \param[in] obj : pointer to PWMLITE driver instance + * \param[in] userConfig : pointer to the user config structure + */ +extern void PwmLiteDrv_ModuleConfig(PwmLiteDrvType *obj, const PwmLiteDrv_ModuleConfigType *userConfig); + +/*! \brief Get default configures the PWMLITE module channel for configuration structure + * + * This function gets default configures the PWMLITE module channel for user configuration structure + * + * \param[in] obj : pointer to PWMLITE driver instance + * + */ +extern void PwmLiteDrv_GetDefaultChannelConfig(PwmLiteDrv_ChannelConfigType *userConfig); + +/*! \brief config the pwm channel according to user config + * + * + * \param[in] obj : pointer to PWMLITE driver instance + * \param[in] channel : the pwm channel number + * \param[in] userConfig : pointer to the user config structure + */ +extern void PwmLiteDrv_ConfigChannel(PwmLiteDrvType *obj, uint8_t channel, const PwmLiteDrv_ChannelConfigType *userConfig); + +/*! \brief update the Pwm duty value at running + * + * + * \param[in] obj : pointer to PWMLITE driver instance + * \param[in] channel : the pwm channel number + * \param[in] threshold0 : new threshold0 value + * \param[in] threshold1 : new threshold1 value + */ +extern void PwmLiteDrv_UpdatePwmThresholdAtRunning(PwmLiteDrvType *obj, uint8_t channel, uint32_t threshold0, uint32_t threshold1); + +/*! \brief update the Pwm duty value at sync time + * + * + * \param[in] obj : pointer to PWMLITE driver instance + * \param[in] channel : the pwm channel number + * \param[in] threshold0 : new threshold0 value + * \param[in] threshold1 : new threshold1 value + */ +extern void PwmLiteDrv_UpdatePwmThresholdAtSync(PwmLiteDrvType *obj, uint8_t channel, uint32_t threshold0, uint32_t threshold1); + +/*! \brief mux the pwm channels to target pad channel through SIM + * + * + * \param[in] channel : the pwm channel number + * \param[in] number : the target pad number + */ +extern void PwmLiteDrv_OutputMux(PwmLiteDrvType *obj, PwmLiteDrv_PwmMuxChannelType channel, PwmLiteDrv_PwmMuxPadNumType number); + +/*! \brief resume the pwm module output + * + * + * \param[in] obj : pointer to PWMLITE driver instance + */ +extern void PwmLiteDrv_Resume(PwmLiteDrvType *obj); + +/*! \brief pause the pwm module output + * + * + * \param[in] obj : pointer to PWMLITE driver instance + */ +extern void PwmLiteDrv_Pause(PwmLiteDrvType *obj); + +/*! \brief enable the pwm module + * + * + * \param[in] obj : pointer to PWMLITE driver instance + */ +extern void PwmLiteDrv_EnableModule(PwmLiteDrvType *obj); + +/*! \brief disable the pwm module + * + * + * \param[in] obj : pointer to PWMLITE driver instance + */ +extern void PwmLiteDrv_DisableModule(PwmLiteDrvType *obj); + +/*! \brief get the sync result + * + * + * \param[in] obj : pointer to PWMLITE driver instance + * \param[out] bool : result + * - 0 : update done + * - 1 : during update + */ +extern uint8_t PwmLiteDrv_GetSyncResult(PwmLiteDrvType *obj); + +/*! \brief trig the sync action + * + * + * \param[in] obj : pointer to PWMLITE driver instance + */ +extern void PwmLiteDrv_TrigSync(PwmLiteDrvType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _PWMLITE_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/reset/reset_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/reset/reset_drv.c new file mode 100644 index 0000000..9f158da --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/reset/reset_drv.c @@ -0,0 +1,457 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "reset_drv.h" +#include "rcm_reg.h" +#include "pcc0_reg.h" +#include "pcc1_reg.h" +#include "../cpu/cpu_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define RESET_RCM_UNLOCK (0x52434D4Bu) +#define RESET_PCC_UNLOCK (0x55534552u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void ResetDrv_Init(ResetDrvType *obj, struct _RcmRegType_ *rcmReg, struct _Pcc1RegType_ *pcc1Reg, struct _Pcc0RegType_ *pcc0Reg) +{ + obj->rcmReg = rcmReg; + obj->pcc1Reg = pcc1Reg; + obj->pcc0Reg = pcc0Reg; +} + +void ResetDrv_GetDefaultConfig(ResetDrv_ConfigType *userConfig) +{ + userConfig->enableExtFlt = false; + userConfig->extFltLen = 16; + userConfig->enableResetInterrupt = false; + userConfig->delay = RESETDRV_RESETDELAY_514LPOCYCLES; +} + +void ResetDrv_Configure(ResetDrvType *obj, const ResetDrv_ConfigType *userConfig) +{ + if((userConfig->extFltLen > 32) || (userConfig->extFltLen < 1)) + { + return; + } + if(userConfig->delay > RESETDRV_RESETDELAY_514LPOCYCLES) + { + return; + } + + RcmReg_SetKey(obj->rcmReg, RESET_RCM_UNLOCK); /* Unlock RCM */ + + RcmReg_SetExtRstFltEn(obj->rcmReg, userConfig->enableExtFlt); + RcmReg_SetExtRstFltLen(obj->rcmReg, (uint8_t)(userConfig->extFltLen - 1)); + RcmReg_SetRstCtrlGlobalIE(obj->rcmReg, userConfig->enableResetInterrupt); + RcmReg_SetRstCtrlRstDelay(obj->rcmReg, userConfig->delay); + + RcmReg_SetKey(obj->rcmReg, 0); /* Lock RCM again */ +} + +bool ResetDrv_IsResetCaused(const ResetDrvType *obj, ResetDrv_SourceType source) +{ + bool retval = false; + if(source >= RESETDRV_SOURCE_NUM) + { + return retval; + } + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:low] "still keep default though it's not reachable" */ + switch(source) + { + case RESETDRV_SOURCE_WDG: + retval = RcmReg_GetRstFlagWdg(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_SYS: + retval = RcmReg_GetRstFlagSys(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_LOCKUP: + retval = RcmReg_GetRstFlagLockup(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_PIN: + retval = RcmReg_GetRstFlagPin(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_MDMAP: + retval = RcmReg_GetRstFlagMdmap(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_PLL_LOSS: + retval = RcmReg_GetRstFlagPllLoss(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_CMUP: + retval = RcmReg_GetRstFlagCmuPll(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_CMUS: + retval = RcmReg_GetRstFlagCmuSosc(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_FHU: + retval = RcmReg_GetRstFlagFhu(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_STDBY_EXIT: + retval = RcmReg_GetRstFlagStdbyExit(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_FLS_INITIAL: + retval = RcmReg_GetRstFlagFlsInitial(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_LVR: + retval = RcmReg_GetRstFlagLvr(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_POR: + retval = RcmReg_GetRstFlagPor(obj->rcmReg) == 1; + break; + default: + /* Should not get here */ + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:low] "still keep default though it's not reachable" */ + return retval; +} + +bool ResetDrv_IsResetSticky(const ResetDrvType *obj, ResetDrv_SourceType source) +{ + bool retval = false; + if(source >= RESETDRV_SOURCE_NUM) + { + return retval; + } + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:low] "still keep default though it's not reachable" */ + switch(source) + { + case RESETDRV_SOURCE_WDG: + retval = RcmReg_GetRstSFlagWdg(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_SYS: + retval = RcmReg_GetRstSFlagSys(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_LOCKUP: + retval = RcmReg_GetRstSFlagLockup(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_PIN: + retval = RcmReg_GetRstSFlagPin(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_MDMAP: + retval = RcmReg_GetRstSFlagMdmap(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_PLL_LOSS: + retval = RcmReg_GetRstSFlagPllLoss(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_CMUP: + retval = RcmReg_GetRstSFlagCmuPll(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_CMUS: + retval = RcmReg_GetRstSFlagCmuSosc(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_FHU: + retval = RcmReg_GetRstSFlagFhu(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_STDBY_EXIT: + retval = RcmReg_GetRstSFlagStdbyExit(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_FLS_INITIAL: + retval = RcmReg_GetRstSFlagFlsInitial(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_LVR: + retval = RcmReg_GetRstSFlagLvr(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_POR: + retval = RcmReg_GetRstSFlagPor(obj->rcmReg) == 1; + break; + default: + /* Should not get here */ + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:low] "still keep default though it's not reachable" */ + return retval; +} + +void ResetDrv_ClrResetStickyFlag(ResetDrvType *obj, ResetDrv_SourceType source) +{ + if(source >= RESETDRV_SOURCE_NUM) + { + return; + } + RcmReg_SetKey(obj->rcmReg, RESET_RCM_UNLOCK); /* Unlock RCM */ + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:low] "still keep default though it's not reachable" */ + switch(source) + { + case RESETDRV_SOURCE_WDG: + RcmReg_SetRstSFlagWdg(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_SYS: + RcmReg_SetRstSFlagSys(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_LOCKUP: + RcmReg_SetRstSFlagLockup(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_PIN: + RcmReg_SetRstSFlagPin(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_MDMAP: + RcmReg_SetRstSFlagMdmap(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_PLL_LOSS: + RcmReg_SetRstSFlagPllLoss(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_CMUP: + RcmReg_SetRstSFlagCmuPll(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_CMUS: + RcmReg_SetRstSFlagCmuSosc(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_FHU: + RcmReg_SetRstSFlagFhu(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_STDBY_EXIT: + RcmReg_SetRstSFlagStdbyExit(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_FLS_INITIAL: + RcmReg_SetRstSFlagFlsInitial(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_LVR: + RcmReg_SetRstSFlagLvr(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_POR: + RcmReg_SetRstSFlagPor(obj->rcmReg, 1); + break; + default: + /* Should not get here */ + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:low] "still keep default though it's not reachable" */ + RcmReg_SetKey(obj->rcmReg, 0); /* Lock RCM again */ +} + +void ResetDrv_EnableResetInterrupt(ResetDrvType *obj, ResetDrv_ResetIntModuleType module, bool enable) +{ + RcmReg_SetKey(obj->rcmReg, RESET_RCM_UNLOCK); /* Unlock RCM */ + switch(module) + { + case RESETDRV_RESETINT_WDG: + RcmReg_SetRstCtrlWdgRstIE(obj->rcmReg, enable ? 1 : 0); + break; + case RESETDRV_RESETINT_SYS: + RcmReg_SetRstCtrlSysRstIE(obj->rcmReg, enable ? 1 : 0); + break; + case RESETDRV_RESETINT_PIN: + RcmReg_SetRstCtrlPinRstIE(obj->rcmReg, enable ? 1 : 0); + break; + case RESETDRV_RESETINT_MDMAP: + RcmReg_SetRstCtrlMdmapRstIE(obj->rcmReg, enable ? 1 : 0); + break; + case RESETDRV_RESETINT_PLL_LOSS: + RcmReg_SetRstCtrlPllLossIE(obj->rcmReg, enable ? 1 : 0); + break; + case RESETDRV_RESETINT_CMUP: + RcmReg_SetRstCtrlCmuPllIE(obj->rcmReg, enable ? 1 : 0); + break; + case RESETDRV_RESETINT_CMUS: + RcmReg_SetRstCtrlCmuSoscIE(obj->rcmReg, enable ? 1 : 0); + break; + default: + /* Should not get here */ + break; + } + RcmReg_SetKey(obj->rcmReg, 0); /* Lock RCM again */ +} + +void ResetDrv_EnableReset(ResetDrvType *obj, ResetDrv_ResetEnModuleType module, bool enable) +{ + RcmReg_SetKey(obj->rcmReg, RESET_RCM_UNLOCK); /* Unlock RCM */ + switch(module) + { + case RESETDRV_RESETEN_PLL_LOSS: + RcmReg_SetRstCtrlPllLossEn(obj->rcmReg, enable ? 1 : 0); + break; + case RESETDRV_RESETEN_LOCKUP: + RcmReg_SetRstCtrlLockupEn(obj->rcmReg, enable ? 1 : 0); + break; + default: + /* Should not get here */ + break; + } + RcmReg_SetKey(obj->rcmReg, 0); /* Lock RCM again */ +} + +void ResetDrv_SoftwareResetModule(ResetDrvType *obj, ResetDrv_SwResetModuleType module) +{ + Pcc0Reg_SetKey(obj->pcc0Reg, RESET_PCC_UNLOCK); /* Unlock PCC */ + switch(module) + { + case RESETDRV_SWRESET_CMP: + Pcc0Reg_SetCmpSwR(obj->pcc0Reg, 1); + Pcc0Reg_SetCmpSwR(obj->pcc0Reg, 0); + break; + case RESETDRV_SWRESET_PORTA: + Pcc0Reg_SetPortASwR(obj->pcc0Reg, 1); + Pcc0Reg_SetPortASwR(obj->pcc0Reg, 0); + break; + case RESETDRV_SWRESET_PORTB: + Pcc0Reg_SetPortBSwR(obj->pcc0Reg, 1); + Pcc0Reg_SetPortBSwR(obj->pcc0Reg, 0); + break; + case RESETDRV_SWRESET_PORTC: + Pcc0Reg_SetPortCSwR(obj->pcc0Reg, 1); + Pcc0Reg_SetPortCSwR(obj->pcc0Reg, 0); + break; + case RESETDRV_SWRESET_PORTD: + Pcc0Reg_SetPortDSwR(obj->pcc0Reg, 1); + Pcc0Reg_SetPortDSwR(obj->pcc0Reg, 0); + break; + case RESETDRV_SWRESET_PORTE: + Pcc0Reg_SetPortESwR(obj->pcc0Reg, 1); + Pcc0Reg_SetPortESwR(obj->pcc0Reg, 0); + break; + case RESETDRV_SWRESET_LPTMR: + Pcc0Reg_SetLptmrSwR(obj->pcc0Reg, 1); + Pcc0Reg_SetLptmrSwR(obj->pcc0Reg, 0); + break; + case RESETDRV_SWRESET_LPIT: + Pcc0Reg_SetLpitSwR(obj->pcc0Reg, 1); + Pcc0Reg_SetLpitSwR(obj->pcc0Reg, 0); + break; + case RESETDRV_SWRESET_WDG: + Pcc0Reg_SetWdgSwR(obj->pcc0Reg, 1); + Pcc0Reg_SetWdgSwR(obj->pcc0Reg, 0); + break; + case RESETDRV_SWRESET_DMA: + Pcc1Reg_SetDmaSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetDmaSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_MSCM: + Pcc1Reg_SetMscmSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetMscmSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_CRC: + Pcc1Reg_SetCrcSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetCrcSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_EIM: + Pcc1Reg_SetEimSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetEimSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_ERM: + Pcc1Reg_SetErmSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetErmSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_FHU: + Pcc1Reg_SetFhuSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetFhuSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_ADC: + Pcc1Reg_SetAdcSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetAdcSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_PDB: + Pcc1Reg_SetPdbSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetPdbSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_SPI0: + Pcc1Reg_SetSpi0SwR(obj->pcc1Reg, 1); + Pcc1Reg_SetSpi0SwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_SPI1: + Pcc1Reg_SetSpi1SwR(obj->pcc1Reg, 1); + Pcc1Reg_SetSpi1SwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_UART0: + Pcc1Reg_SetUart0SwR(obj->pcc1Reg, 1); + Pcc1Reg_SetUart0SwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_UART1: + Pcc1Reg_SetUart1SwR(obj->pcc1Reg, 1); + Pcc1Reg_SetUart1SwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_UART2: + Pcc1Reg_SetUart2SwR(obj->pcc1Reg, 1); + Pcc1Reg_SetUart2SwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_CAN: + Pcc1Reg_SetCanSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetCanSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_I2C: + Pcc1Reg_SetI2CSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetI2CSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_I2SM: + Pcc1Reg_SetI2SMSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetI2SMSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_I2SS: + Pcc1Reg_SetI2SSSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetI2SSSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_PWMLITE0: + Pcc1Reg_SetPwm0SwR(obj->pcc1Reg, 1); + Pcc1Reg_SetPwm0SwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_PWMLITE1: + Pcc1Reg_SetPwm1SwR(obj->pcc1Reg, 1); + Pcc1Reg_SetPwm1SwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_MFT0: + Pcc1Reg_SetMft0SwR(obj->pcc1Reg, 1); + Pcc1Reg_SetMft0SwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_MFT1: + Pcc1Reg_SetMft1SwR(obj->pcc1Reg, 1); + Pcc1Reg_SetMft1SwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_GPIO: + Pcc1Reg_SetGpioSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetGpioSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_CMUP: + Pcc1Reg_SetCmupSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetCmupSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_CMUS: + Pcc1Reg_SetCmusSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetCmusSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_FLS: + Pcc1Reg_SetFlsCtlSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetFlsCtlSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_MPU: + Pcc1Reg_SetMpuSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetMpuSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_SYS: + NVIC_SystemReset(); + break; + default: + /* Should not get here */ + break; + } + Pcc0Reg_SetKey(obj->pcc0Reg, 0); /* Lock Pcc0 again */ +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/reset/reset_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/reset/reset_drv.h new file mode 100644 index 0000000..6a67139 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/reset/reset_drv.h @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _RESET_DRV_H_ +#define _RESET_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of Reset + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup reset_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Definition of modules that can be software reset + */ +typedef enum +{ + RESETDRV_SWRESET_CMP = 0, + RESETDRV_SWRESET_PORTA, + RESETDRV_SWRESET_PORTB, + RESETDRV_SWRESET_PORTC, + RESETDRV_SWRESET_PORTD, + RESETDRV_SWRESET_PORTE, + RESETDRV_SWRESET_LPTMR, + RESETDRV_SWRESET_LPIT, + RESETDRV_SWRESET_WDG, + + RESETDRV_SWRESET_DMA, + RESETDRV_SWRESET_MSCM, + RESETDRV_SWRESET_CRC, + RESETDRV_SWRESET_EIM, + RESETDRV_SWRESET_ERM, + RESETDRV_SWRESET_FHU, + RESETDRV_SWRESET_ADC, + RESETDRV_SWRESET_PDB, + RESETDRV_SWRESET_SPI0, + RESETDRV_SWRESET_SPI1, + RESETDRV_SWRESET_UART0, + RESETDRV_SWRESET_UART1, + RESETDRV_SWRESET_UART2, + RESETDRV_SWRESET_CAN, + RESETDRV_SWRESET_I2C, + RESETDRV_SWRESET_I2SM, + RESETDRV_SWRESET_I2SS, + RESETDRV_SWRESET_PWMLITE0, + RESETDRV_SWRESET_PWMLITE1, + RESETDRV_SWRESET_MFT0, + RESETDRV_SWRESET_MFT1, + RESETDRV_SWRESET_GPIO, + RESETDRV_SWRESET_CMUP, + RESETDRV_SWRESET_CMUS, + RESETDRV_SWRESET_FLS, + RESETDRV_SWRESET_MPU, + RESETDRV_SWRESET_SYS +} ResetDrv_SwResetModuleType; + +/*! \brief Definition of delay between interrupt and reset + * \details The unit is LPO128k clock cycle + */ +typedef enum +{ + RESETDRV_RESETDELAY_10LPOCYCLES = 0, + RESETDRV_RESETDELAY_34LPOCYCLES = 1, + RESETDRV_RESETDELAY_130LPOCYCLES = 2, + RESETDRV_RESETDELAY_514LPOCYCLES = 3 +} ResetDrv_ResetDelayType; + +/*! \brief Definition of reset enable modules + */ +typedef enum +{ + RESETDRV_RESETEN_PLL_LOSS, + RESETDRV_RESETEN_LOCKUP, +} ResetDrv_ResetEnModuleType; + +/*! \brief Definition of reset interrupt modules + */ +typedef enum +{ + RESETDRV_RESETINT_WDG, + RESETDRV_RESETINT_SYS, + RESETDRV_RESETINT_PIN, + RESETDRV_RESETINT_MDMAP, + RESETDRV_RESETINT_PLL_LOSS, + RESETDRV_RESETINT_CMUP, + RESETDRV_RESETINT_CMUS, +} ResetDrv_ResetIntModuleType; + +/*! \brief Definition of reset source + */ +typedef enum +{ + RESETDRV_SOURCE_WDG = 0, + RESETDRV_SOURCE_SYS, + RESETDRV_SOURCE_LOCKUP, + RESETDRV_SOURCE_PIN, + RESETDRV_SOURCE_MDMAP, + RESETDRV_SOURCE_PLL_LOSS, + RESETDRV_SOURCE_CMUP, + RESETDRV_SOURCE_CMUS, + RESETDRV_SOURCE_FHU, + RESETDRV_SOURCE_STDBY_EXIT, + RESETDRV_SOURCE_FLS_INITIAL, + RESETDRV_SOURCE_LVR, + RESETDRV_SOURCE_POR, + + RESETDRV_SOURCE_NUM +} ResetDrv_SourceType; + +/*! \brief Definition of configuration of Reset driver + */ +typedef struct _ResetDrv_ConfigType_ +{ + bool enableExtFlt; /*!< whether to enable the external reset input digital filter */ + uint16_t extFltLen; /*!< external reset input digital filter length */ + bool enableResetInterrupt; /*!< whether to enable the global reset interrupt */ + ResetDrv_ResetDelayType delay; /*!< The delay between the interrupt and the reset */ +} ResetDrv_ConfigType; + +/* Forward declaration of related register */ +struct _RcmRegType_; +struct _Pcc1RegType_; +struct _Pcc0RegType_; + +/*! \brief The definition of RESET driver class + */ +typedef struct _ResetDrvType_ +{ + struct _RcmRegType_ *rcmReg; /*!< pointer to RCM register */ + struct _Pcc1RegType_ *pcc1Reg; /*!< pointer to PCC register */ + struct _Pcc0RegType_ *pcc0Reg; /*!< pointer to APC register */ +} ResetDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the Reset driver module + * + * This function initializes Reset driver by setting the register + * instances to it. + * + * \param[in] obj : pointer to Reset driver instance + * \param[in] rcmReg : pointer to RCM register instance + * \param[in] apcReg : pointer to APC register instance + */ +extern void ResetDrv_Init(ResetDrvType *obj, struct _RcmRegType_ *rcmReg, struct _Pcc1RegType_ *pcc1Reg, struct _Pcc0RegType_ *pcc0Reg); + +/*! \brief Get default configures the Reset module for configuration structure + * + * This function gets default configures the Reset module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void ResetDrv_GetDefaultConfig(ResetDrv_ConfigType *userConfig); + +/*! \brief Configures the Reset module from a user configuration structure + * + * This function configures the Reset module from a used configuration. + * + * \param[in] obj : pointer to Reset driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void ResetDrv_Configure(ResetDrvType *obj, const ResetDrv_ConfigType *userConfig); + +/*! \brief Get whether a specified source caused MCU's most recent reset + * + * This function gets whether a specified source caused MCU's most recent reset. + * Multiple source can be true if multiple reset events occur at the same time. + * + * \param[in] obj : pointer to Reset driver instance + * \param[in] source : the reset source + * \return whether the specified source caused MCU's most recent reset + * - true : the reset source occurred + * - false : the reset source not occurred + */ +extern bool ResetDrv_IsResetCaused(const ResetDrvType *obj, ResetDrv_SourceType source); + +/*! \brief Get whether a specified reset occurred since the last POR or LVD that have not been cleared by software + * + * This function gets whether a specified reset occurred since the last POR or LVD that have not been cleared by software + * + * \param[in] obj : pointer to Reset driver instance + * \param[in] source : the reset source + * \return whether the specified reset occurred since the last POR or LVD that have not been cleared by software + * - true : the reset source occurred + * - false : the reset source not occurred + */ +extern bool ResetDrv_IsResetSticky(const ResetDrvType *obj, ResetDrv_SourceType source); + +/*! \brief Clear Sticky reset flag since a reset has been caused + * + * This function clear Sticky reset flag since a reset has been caused + * + * \param[in] obj : pointer to Reset driver instance + * \param[in] source : the reset source + */ +extern void ResetDrv_ClrResetStickyFlag(ResetDrvType *obj, ResetDrv_SourceType source); + +/*! \brief Enable or disable the reset interrupt for a given module + * + * This function enable or disable the reset interrupt for a given module + * + * \param[in] obj : pointer to Reset driver instance + * \param[in] module : the module to configure + * \param[in] enable : whether to enable or disable the reset interrupt + * - true : enable the reset interrupt + * - falsa : disable the reset interrupt + */ +extern void ResetDrv_EnableResetInterrupt(ResetDrvType *obj, ResetDrv_ResetIntModuleType module, bool enable); + +/*! \brief Enable or disable the reset for a given module + * + * This function enable or disable the reset for a given module + * + * \param[in] obj : pointer to Reset driver instance + * \param[in] module : the module to configure + * \param[in] enable : whether to enable or disable the reset + * - true : enable the reset + * - falsa : disable the reset + */ +extern void ResetDrv_EnableReset(ResetDrvType *obj, ResetDrv_ResetEnModuleType module, bool enable); + +/*! \brief Trigger the software reset for a given module + * + * This function triggers the software reset for a given module + * + * \param[in] obj : pointer to Reset driver instance + * \param[in] module : the module to configure + */ +extern void ResetDrv_SoftwareResetModule(ResetDrvType *obj, ResetDrv_SwResetModuleType module); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _RESET_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/rtc/rtc_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/rtc/rtc_drv.c new file mode 100644 index 0000000..966d02b --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/rtc/rtc_drv.c @@ -0,0 +1,653 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "rtc_drv.h" +#include "rtc_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* Constants to transfer between TimeData and seconds*/ +#define SECONDS_IN_A_DAY (86400UL) +#define SECONDS_IN_A_HOUR (3600U) +#define SECONDS_IN_A_MIN (60U) +#define MINS_IN_A_HOUR (60U) +#define HOURS_IN_A_DAY (24U) +#define DAYS_IN_A_YEAR (365U) +#define DAYS_IN_A_LEAP_YEAR (366U) +#define YEAR_RANGE_START (1970U) +#define YEAR_RANGE_END (2099U) +#define MONTH_RANGE_START (1U) +#define MONTH_RANGE_END (12U) +#define DAY_RANGE_START (1U) +#define DAY_RANGE_END (31U) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief RTC register lock + */ +typedef enum +{ + RTCDRV_LOCK_REG_LOCK = 0x00U, /*!< RTC Lock Register lock */ + RTCDRV_STATUS_REG_LOCK = 0x01U, /*!< RTC Status Register lock */ + RTCDRV_CTRL_REG_LOCK = 0x02U, /*!< RTC Control Register lock */ +} RtcDrv_LockRegSelectType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/* Table of month length (in days) for the Un-leap-year*/ +const uint8_t c_unLeapYear[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U}; + +/* Table of month length (in days) for the Leap-year*/ +const uint8_t c_leapYear[] = {0U, 31U, 29U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U}; + +/* Number of days from begin of the non Leap-year*/ +const uint16_t c_monthDays[] = {0U, 0U, 31U, 59U, 90U, 120U, 151U, 181U, 212U, 243U, 273U, 304U, 334U}; + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the register lock status + * + * This function gets the register lock status + * + * \param[in] obj : pointer to RTC driver instance + * \param[in] lockRegSelect : the select of register lock + * \return the status of register lock + * - false : not locked + * - true : locked + */ +static inline bool RtcDrv_IsRegisterLocked(const RtcDrvType *obj, RtcDrv_LockRegSelectType lockRegSelect) +{ + bool result = false; + + switch(lockRegSelect) + { + case RTCDRV_LOCK_REG_LOCK: + result = ((RtcReg_GetLrLrl(obj->reg) == 0) ? true : false); + break; + case RTCDRV_STATUS_REG_LOCK: + result = ((RtcReg_GetLrSrl(obj->reg) == 0) ? true : false); + break; + case RTCDRV_CTRL_REG_LOCK: + result = ((RtcReg_GetLrCrl(obj->reg) == 0) ? true : false); + break; + default: + /* This statement should not be reached */ + break; + } + return result; +} + +/*! \brief Configure the RTC Clock out pin + * + * This function allows you to configure the RTC Clock out pin. + * + * \param[in] obj : pointer to RTC driver instance + * \param[in] config : the clock out configuration + * \return the result of the configure operation + * - false : failed + * - true : success + */ +static inline bool RtcDrv_ConfigureClockOut(RtcDrvType *obj, RtcDrv_ClkOutConfigType config) +{ + bool result = true; + + if(RtcDrv_IsRegisterLocked(obj, RTCDRV_CTRL_REG_LOCK) == true) + { + result = false; + } + else + { + switch(config) + { + case RTCDRV_CLKOUT_DISABLED: + RtcReg_SetCrCpe(obj->reg, 0); + break; + case RTCDRV_CLKOUT_SRC_TSIC: + RtcReg_SetCrCps(obj->reg, 0); + RtcReg_SetCrCpe(obj->reg, 1); + break; + case RTCDRV_CLKOUT_SRC_RTC: + RtcReg_SetCrCps(obj->reg, 1); + RtcReg_SetCrClkO(obj->reg, 0); + RtcReg_SetCrCpe(obj->reg, 1); + break; + default: + /* This statement should not be reached */ + break; + } + } + return result; +} + +/*! \brief Checks if the TCE can be written + * + * This function checks the following conditions to find if the + * Time Counter Enable bit is writable. + * - if Update Mode bitfield if 1 and: + * - Time is invalid or + * - Time Seconds Register has overflowed or + * - Time Counter is disabled, + * then the TCE bit can be set even if Status Register is locked. + * + * \param[in] obj : pointer to RTC driver instance + * \param[in] config : the clock out configuration + * \return the result of the configure operation + * - false : failed + * - true : success + */ +static inline bool RtcDrv_CanWriteTce(const RtcDrvType *obj) +{ + bool result = false; + + /* Check if the status register is locked */ + if(RtcDrv_IsRegisterLocked(obj, RTCDRV_STATUS_REG_LOCK) == false) + { + result = true; + } + /* Get the Update Mode bit */ + else if(RtcReg_GetCrUm(obj->reg) == 1) + { + bool tifFlagSet = RtcReg_GetSrTif(obj->reg) == 1; + bool tofFlagSet = RtcReg_GetSrTof(obj->reg) == 1; + bool tceFlagSet = RtcReg_GetSrTce(obj->reg) == 1; + + /* Check for the specified conditions */ + if((tifFlagSet == true) || (tofFlagSet == true) || (tceFlagSet == false)) + { + result = true; + } + } + else + { + result = false; + } + + /* Return the exit code */ + return result; +} + +void RtcDrv_Init(RtcDrvType *obj, struct _RtcRegType_ *const reg) +{ + obj->reg = reg; + + /* Initialize runtime structure */ + obj->runtimeConfig.isAlarmTimeNew = false; + obj->runtimeConfig.isAlarmConfigSet = false; + obj->runtimeConfig.isIntConfigSet = false; + obj->runtimeConfig.isSecondsIntConfigSet = false; +} + +void RtcDrv_GetDefaultConfig(RtcDrv_ConfigType *userConfig) +{ + userConfig->clockOutConfig = RTCDRV_CLKOUT_DISABLED; + userConfig->updateEnable = true; + userConfig->nonSupervisorAccessEnable = true; +} + +bool RtcDrv_Configure(RtcDrvType *obj, const RtcDrv_ConfigType *userConfig) +{ + bool retval = false; + + if(RtcDrv_IsRegisterLocked(obj, RTCDRV_CTRL_REG_LOCK) == false) + { /* not locked */ + RtcReg_SetCrSwr(obj->reg, 1); /* Write 1 to reset */ + while(RtcReg_GetSrTif(obj->reg) == 0) + { + ; + } + RtcReg_SetCrSwr(obj->reg, 0); + RtcDrv_ConfigureClockOut(obj, userConfig->clockOutConfig); + RtcReg_SetCrUm(obj->reg, userConfig->updateEnable ? 1 : 0); + RtcReg_SetCrSup(obj->reg, userConfig->nonSupervisorAccessEnable ? 1 : 0); + retval = true; + } + + return retval; +} + +bool RtcDrv_StartCounter(RtcDrvType *obj) +{ + /* Check if the TCE is writable and return corresponding result */ + if(RtcDrv_CanWriteTce(obj) == false) + { + return false; + } + /* if the counter is already enabled */ + if(RtcReg_GetSrTce(obj->reg) == 1) + { + return false; + } + RtcReg_SetSrCsd(obj->reg, 1); + /* if the counter is already CSD reg will set */ + while(RtcReg_GetSrCsd(obj->reg) == 0) + { + ; + } + RtcReg_SetSrTce(obj->reg, 1); + return true; +} + +bool RtcDrv_StopCounter(RtcDrvType *obj) +{ + /* Check if the TCE is writable and return corresponding result */ + if(RtcDrv_CanWriteTce(obj) == false) + { + return false; + } + /* if the counter is already enabled */ + if(RtcReg_GetSrTce(obj->reg) == 1) + { + RtcReg_SetSrTce(obj->reg, 0); + } + /* Read TCE bit to check if the counter is really disabled */ + return RtcReg_GetSrTce(obj->reg) == 0; +} + +bool RtcDrv_GetCurrentTimeDate(RtcDrvType *obj, RtcDrv_TimeDateType *currentTime) +{ + bool result = false; + uint32_t seconds; + uint32_t tempSeconds; + + /* Make two consecutive reads to ensure that the read was not + * done when the counter is incrementing. */ + tempSeconds = RtcReg_GetTsr(obj->reg); + seconds = RtcReg_GetTsr(obj->reg); + /* If the read was done when the counter was incrementing, + * try and read again. */ + if(tempSeconds != seconds) + { + tempSeconds = RtcReg_GetTsr(obj->reg); /* get the current time again */ + if(tempSeconds == seconds) + { + /* Convert the current time from seconds to time date structure */ + RtcDrv_ConvertSecondsToTimeDate(seconds, currentTime); + result = true; + } + } + else + { + /* Convert the current time from seconds to time date structure */ + RtcDrv_ConvertSecondsToTimeDate(seconds, currentTime); + result = true; + } + + return result; +} + +bool RtcDrv_SetTimeDate(RtcDrvType *obj, const RtcDrv_TimeDateType *time) +{ + /* Check if the TimeDate format is valid */ + if(RtcDrv_IsTimeDateCorrectFormat(time) == false) + { + return false; + } + /* Check if the TCE is writable and return corresponding result */ + if(RtcDrv_CanWriteTce(obj) == false) + { + return false; + } + /* Check if the counter is already started */ + if(RtcReg_GetSrTce(obj->reg) == 1) + { + return false; + } + + /* Convert the desired time to seconds */ + uint32_t seconds = 0; + RtcDrv_ConvertTimeDateToSeconds(time, &seconds); + RtcReg_SetTsr(obj->reg, seconds); + return true; +} + +bool RtcDrv_ConfigureRegisterLock(RtcDrvType *obj, const RtcDrv_RegLockConfigType *lockConfig) +{ + if(RtcReg_GetLrLrl(obj->reg) == 0) + { + return false; + } + + /* Configure Control register lock */ + if(lockConfig->controlRegisterLock) + { + RtcReg_SetLrCrl(obj->reg, 0); /* Write 0 to lock */ + } + /* Configure Status register lock */ + if(lockConfig->statusRegisterLock) + { + RtcReg_SetLrSrl(obj->reg, 0); /* Write 0 to lock */ + } + /* Configure Lock register lock */ + if(lockConfig->lockRegisterLock) + { + RtcReg_SetLrLrl(obj->reg, 0); /* Write 0 to lock */ + } + return true; +} + +void RtcDrv_GetRegisterLock(RtcDrvType *obj, RtcDrv_RegLockConfigType *lockConfig) +{ + /* For the Lock Register */ + lockConfig->lockRegisterLock = RtcDrv_IsRegisterLocked(obj, RTCDRV_LOCK_REG_LOCK); + /* For the Control Register */ + lockConfig->controlRegisterLock = RtcDrv_IsRegisterLocked(obj, RTCDRV_CTRL_REG_LOCK); + /* For the Status Register */ + lockConfig->statusRegisterLock = RtcDrv_IsRegisterLocked(obj, RTCDRV_STATUS_REG_LOCK); +} + +void RtcDrv_ConfigureOverFlowInt(RtcDrvType *obj, const RtcDrv_InterruptConfigType *intConfig) +{ + obj->runtimeConfig.intConfig = *intConfig; + obj->runtimeConfig.isIntConfigSet = true; + RtcReg_SetIerTioe(obj->reg, intConfig->overflowIntEnable ? 1 : 0); +} + +void RtcDrv_ConfigureSecondsInt(RtcDrvType *obj, const RtcDrv_SecondsIntConfigType *intConfig) +{ + obj->runtimeConfig.secondsIntConfig = *intConfig; + obj->runtimeConfig.isSecondsIntConfigSet = true; + + RtcReg_SetIerTsie(obj->reg, 0); + RtcReg_SetIerTsic(obj->reg, intConfig->secondIntConfig); + RtcReg_SetIerTsie(obj->reg, intConfig->secondIntEnable ? 1 : 0); +} + +bool RtcDrv_ConfigureAlarm(RtcDrvType *obj, const RtcDrv_AlarmConfigType *alarmConfig) +{ + bool result = false; + uint32_t alarmTime; + uint32_t currentTime; + + /* Check if the alarm time is in a correct format */ + if(RtcDrv_IsTimeDateCorrectFormat(&alarmConfig->alarmTime) == true) + { + /* Convert the time date to seconds */ + RtcDrv_ConvertTimeDateToSeconds(&alarmConfig->alarmTime, &alarmTime); + /* Get current time in seconds */ + currentTime = RtcReg_GetTsr(obj->reg); + /* Check if the alarm time is greater than current time */ + if(alarmTime > currentTime) + { + obj->runtimeConfig.alarmConfig = *alarmConfig; + obj->runtimeConfig.isAlarmConfigSet = true; + RtcReg_SetIerTaie(obj->reg, 0); + RtcReg_SetTar(obj->reg, alarmTime); + RtcReg_SetIerTaie(obj->reg, alarmConfig->alarmIntEnable); + } + } + + return result; +} + +void RtcDrv_GetAlarmConfig(const RtcDrvType *obj, RtcDrv_AlarmConfigType *alarmConfig) +{ + if(obj->runtimeConfig.isAlarmConfigSet) + { + *alarmConfig = obj->runtimeConfig.alarmConfig; + } +} + +bool RtcDrv_IsAlarmPending(const RtcDrvType *obj) +{ + return RtcReg_GetSrTaf(obj->reg) == 1; +} + +void RtcDrv_ConvertSecondsToTimeDate(uint32_t seconds, RtcDrv_TimeDateType *timeDate) +{ + uint8_t i; + bool yearLeap = false; + uint32_t numberOfDays = 0U; + uint32_t tempSeconds; + uint16_t daysInYear; + + /* Because the starting year(1970) is not leap, set the daysInYear + * variable with the number of the days in a normal year + */ + daysInYear = DAYS_IN_A_YEAR; + /* Set the year to the beginning of the range */ + timeDate->year = YEAR_RANGE_START; + /* Get the number of days */ + numberOfDays = seconds / SECONDS_IN_A_DAY; + /* Get the number of seconds remaining */ + tempSeconds = seconds % SECONDS_IN_A_DAY; + /* Get the current hour */ + timeDate->hour = (uint16_t)(tempSeconds / SECONDS_IN_A_HOUR); + /* Get the remaining seconds */ + tempSeconds = tempSeconds % SECONDS_IN_A_HOUR; + /* Get the minutes */ + timeDate->minutes = (uint16_t)(tempSeconds / SECONDS_IN_A_MIN); + /* Get seconds */ + timeDate->seconds = (uint8_t)(tempSeconds % SECONDS_IN_A_MIN); + /* Get the current year */ + while(numberOfDays >= daysInYear) + { + /* Increment year if the number of days is greater than the ones in one year */ + timeDate->year++; + /* Subtract the number of the days */ + numberOfDays -= daysInYear; + + /* Check if the year is leap or unleap */ + if(!RtcDrv_IsYearLeap(timeDate->year)) + { + daysInYear = DAYS_IN_A_YEAR; + } + else + { + daysInYear = DAYS_IN_A_LEAP_YEAR; + } + } + /* Add the current day */ + numberOfDays += 1U; + /* Check if the current year is leap */ + yearLeap = RtcDrv_IsYearLeap(timeDate->year); + /* Get the month */ + for(i = 1U; i <= 12U; i++) + { + uint32_t daysInCurrentMonth = ((yearLeap == true) ? (uint32_t)c_leapYear[i] : (uint32_t)c_unLeapYear[i]); + if(numberOfDays <= daysInCurrentMonth) + { + timeDate->month = (uint16_t)i; + break; + } + else + { + numberOfDays -= daysInCurrentMonth; + } + } + /* Set the current day */ + timeDate->day = (uint16_t)numberOfDays; +} + +void RtcDrv_ConvertTimeDateToSeconds(const RtcDrv_TimeDateType *timeDate, uint32_t *seconds) +{ + /* Declare local variables */ + uint16_t year; + + /* Convert years to seconds */ + (*seconds) = (uint32_t)(DAYS_IN_A_YEAR * (uint32_t)(SECONDS_IN_A_DAY)); + (*seconds) *= ((uint32_t)timeDate->year - YEAR_RANGE_START); + + /* Add the seconds from the leap years */ + for(year = YEAR_RANGE_START; year < timeDate->year; year++) + { + if(RtcDrv_IsYearLeap(year)) + { + (*seconds) += SECONDS_IN_A_DAY; + } + } + + /* If the current year is leap and 29th of February has passed, add + * another day to seconds passed. + */ + if(RtcDrv_IsYearLeap(year) && timeDate->month > 2U) + { + (*seconds) += SECONDS_IN_A_DAY; + } + + (*seconds) += c_monthDays[timeDate->month] * SECONDS_IN_A_DAY; + (*seconds) += (uint32_t)(((uint32_t)timeDate->day - 1U) * (uint32_t)SECONDS_IN_A_DAY); + (*seconds) += (uint32_t)((uint32_t)timeDate->hour * SECONDS_IN_A_HOUR) + (uint32_t)((uint32_t)timeDate->minutes * SECONDS_IN_A_MIN) + (uint32_t)((uint32_t)timeDate->seconds); +} + +bool RtcDrv_IsYearLeap(uint16_t year) +{ + bool isYearLeap = false; + + if((year % 4U) > 0U) + { + isYearLeap = false; + } + else if((year % 100U) > 0U) + { + isYearLeap = true; + } + else if((year % 400U) > 0U) + { + isYearLeap = false; + } + else + { + isYearLeap = true; + } + + return isYearLeap; +} + +bool RtcDrv_IsTimeDateCorrectFormat(const RtcDrv_TimeDateType *timeDate) +{ + /* Declare local variables */ + bool retval = true; + const uint8_t *pDays; + + /* Set the days-in-month table for the corresponding year */ + pDays = RtcDrv_IsYearLeap(timeDate->year) ? (c_leapYear) : (c_unLeapYear); + + /* Check if the time and date are in the correct ranges */ + if((timeDate->year < YEAR_RANGE_START) || (timeDate->year > YEAR_RANGE_END) + || (timeDate->month < 1U) || (timeDate->month > 12U) + || (timeDate->day < 1U) || (timeDate->day > 31U) + || (timeDate->hour >= HOURS_IN_A_DAY) + || (timeDate->minutes >= MINS_IN_A_HOUR) || (timeDate->seconds >= SECONDS_IN_A_MIN)) + { + retval = false; + } + /* Check if the day is a valid day from the corresponding month */ + else if(timeDate->day > pDays[timeDate->month]) + { + retval = false; + } + else + { + retval = true; + } + + return retval; +} + +bool RtcDrv_GetNextAlarmTime(RtcDrvType *obj, RtcDrv_TimeDateType *alarmTime) +{ + bool result = false; + uint32_t alarmInSec; + /* Check if is a new alarm and if true update alarm time date format from time seconds */ + if(obj->runtimeConfig.isAlarmTimeNew == true) + { + alarmInSec = RtcReg_GetTar(obj->reg); + RtcDrv_ConvertSecondsToTimeDate(alarmInSec, alarmTime); + result = true; + } + return result; +} + +void RtcDrv_IrqHandler(RtcDrvType *obj) +{ + uint32_t tempSeconds; + + /* Check if an alarm has occurred */ + if(RtcReg_GetSrTaf(obj->reg) == 1) + { + /* If the alarm interrupt configuration has been defined process the + * alarm IRQ + */ + if(obj->runtimeConfig.isAlarmConfigSet) + { + /* If recurrence is enabled modify the alarm register to the next + * alarm. + */ + if((obj->runtimeConfig.alarmConfig.numberOfRepeats > 0UL) || (obj->runtimeConfig.alarmConfig.repeatForever == true)) + { + /* Get current time */ + tempSeconds = RtcReg_GetTsr(obj->reg); + /* Current time is incremented with the repetition value */ + tempSeconds += obj->runtimeConfig.alarmConfig.repetitionInterval - 1; + /* Set new value to trigger the alarm */ + RtcReg_SetTar(obj->reg, tempSeconds); + + obj->runtimeConfig.isAlarmTimeNew = true; + /* If the alarm repeats forever, set number of repeats to 0 + * to avoid an accidental trigger of the core overflow flag + */ + obj->runtimeConfig.alarmConfig.numberOfRepeats = (obj->runtimeConfig.alarmConfig.repeatForever == false) ? (obj->runtimeConfig.alarmConfig.numberOfRepeats - 1UL) : 0UL; + } + else + { + /* If the alarm does not repeat, write 0 to TAR to clear the + * alarm flag. + */ + RtcReg_SetTar(obj->reg, 0); + obj->runtimeConfig.isAlarmTimeNew = false; + } + /* If the user has defined a callback, call it */ + if(obj->runtimeConfig.alarmConfig.alarmCallback != NULL) + { + obj->runtimeConfig.alarmConfig.alarmCallback(obj->runtimeConfig.alarmConfig.callbackParams); + } + } + } + + /* Check if an overflow has occurred */ + if(RtcReg_GetSrTof(obj->reg) == 1) + { + /* If the overflow interrupt configuration has been defined process the IRQ */ + if(obj->runtimeConfig.isIntConfigSet) + { + if(obj->runtimeConfig.intConfig.overflowCallback != NULL) + { + obj->runtimeConfig.intConfig.overflowCallback(obj->runtimeConfig.intConfig.callbackParams); + } + } + } +} + +void RtcDrv_SecondsIrqHandler(RtcDrvType *obj) +{ + if(obj->runtimeConfig.isSecondsIntConfigSet && obj->runtimeConfig.secondsIntConfig.secondsCallback != NULL) + { + obj->runtimeConfig.secondsIntConfig.secondsCallback(obj->runtimeConfig.secondsIntConfig.callbackParams); + } +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/rtc/rtc_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/rtc/rtc_drv.h new file mode 100644 index 0000000..df296f6 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/rtc/rtc_drv.h @@ -0,0 +1,403 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _RTC_DRV_H_ +#define _RTC_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of RTC (Real Time Clock) + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup rtc_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Definition of RTC CLKOUT Pin Configuration. + */ +typedef enum +{ + RTCDRV_CLKOUT_DISABLED = 0x00U, /*!< Clock out disabled */ + RTCDRV_CLKOUT_SRC_TSIC = 0x01U, /*!< The prescaler output clock (as configured by TSIC) is output on RTC_CLKOUT. */ + RTCDRV_CLKOUT_SRC_RTC = 0x02U, /*!< The RTC source clock is output on RTC_CLKOUT, provided it is output to other peripherals. */ +} RtcDrv_ClkOutConfigType; + +/*! \brief Definition of RTC Timer Seconds Interrupt Configuration. + */ +typedef enum +{ + RTCDRV_SECOND_INT_1HZ = 0x00U, /*!< Timer Seconds Interrupt Configuration 1 Hz */ + RTCDRV_SECOND_INT_2HZ = 0x01U, /*!< Timer Seconds Interrupt Configuration 2 Hz */ + RTCDRV_SECOND_INT_4HZ = 0x02U, /*!< Timer Seconds Interrupt Configuration 4 Hz */ + RTCDRV_SECOND_INT_8HZ = 0x03U, /*!< Timer Seconds Interrupt Configuration 8 Hz */ + RTCDRV_SECOND_INT_16HZ = 0x04U, /*!< Timer Seconds Interrupt Configuration 16 Hz */ + RTCDRV_SECOND_INT_32HZ = 0x05U, /*!< Timer Seconds Interrupt Configuration 32 Hz */ + RTCDRV_SECOND_INT_64HZ = 0x06U, /*!< Timer Seconds Interrupt Configuration 64 Hz */ + RTCDRV_SECOND_INT_128HZ = 0x07U /*!< Timer Seconds Interrupt Configuration 128 Hz */ +} RtcDrv_SecondIntConfigType; + +/*! \brief RTC Time TimeDate. + */ +typedef struct _RtcDrv_TimeDateType_ +{ + uint16_t year; /*!< Year. */ + uint16_t month; /*!< Month. */ + uint16_t day; /*!< Day. */ + uint16_t hour; /*!< Hour. */ + uint16_t minutes; /*!< Minutes. */ + uint8_t seconds; /*!< Seconds. */ +} RtcDrv_TimeDateType; + +/*! \brief RTC Register Lock configuration + */ +typedef struct _RtcDrv_RegLockConfigType_ +{ + bool lockRegisterLock; /*!< Lock state of the Lock Register */ + bool statusRegisterLock; /*!< Lock state of the Status Register */ + bool controlRegisterLock; /*!< Lock state of the Control Register */ +} RtcDrv_RegLockConfigType; + +/*! \brief RTC Interrupt configuration + */ +typedef struct _RtcDrv_InterruptConfigType_ +{ + bool overflowIntEnable; /*!< Enable Time Overflow Interrupt. */ + void (*overflowCallback)(void *callbackParams); /*!< OverFlow Interrupt callback. */ + void *callbackParams; /*!< OverFlow Interrupt callback parameters. */ +} RtcDrv_InterruptConfigType; + +/*! \brief RTC Seconds Interrupt configuration + */ +typedef struct _RtcDrv_SecondsIntConfigType_ +{ + RtcDrv_SecondIntConfigType secondIntConfig; /*!< Seconds Interrupt Configures The Frequency. */ + bool secondIntEnable; /*!< Seconds Interrupt Enable. */ + void (*secondsCallback)(void *callbackParams); /*!< Seconds Interrupt Callback. */ + void *callbackParams; /*!< Seconds Interrupt Callback Parameters. */ +} RtcDrv_SecondsIntConfigType; + +/*! \brief RTC Alarm Interrupt Configuration + */ +typedef struct _RtcDrv_AlarmConfigType_ +{ + RtcDrv_TimeDateType alarmTime; /*!< Alarm TimeData. */ + uint32_t repetitionInterval; /*!< Interval of repetition in sec */ + uint32_t numberOfRepeats; /*!< Number of alarm repeats */ + bool repeatForever; /*!< Repeat forever if set, discard number of repeats */ + bool alarmIntEnable; /*!< Enable alarm interrupt */ + void (*alarmCallback)(void *callbackParams); /*!< Pointer to the user callback method. */ + void *callbackParams; /*!< Pointer to the callback parameters. */ +} RtcDrv_AlarmConfigType; + +/*! \brief RTC Configuration + */ +typedef struct _RtcDrv_ConfigType_ +{ + RtcDrv_ClkOutConfigType clockOutConfig; /*!< RTC CLKOUT Pin Configuration. */ + bool updateEnable; /*!< RTC Update Mode configuration. */ + bool nonSupervisorAccessEnable; /*!< RTC Supervisor Access. */ +} RtcDrv_ConfigType; + +/*! \brief RTC runtime structure + */ +typedef struct _RtcDrv_RuntimeConfigType_ +{ + bool isAlarmTimeNew; /*!< Check if there is a new alarm */ + bool isAlarmConfigSet; /*!< If the alarm configure set */ + RtcDrv_AlarmConfigType alarmConfig; /*!< Alarm configuration */ + bool isIntConfigSet; /*!< If the interrupt configure set */ + RtcDrv_InterruptConfigType intConfig; /*!< Interrupt configuration */ + bool isSecondsIntConfigSet; /*!< If the seconds interrupt configure set */ + RtcDrv_SecondsIntConfigType secondsIntConfig; /*!< Time seconds interrupt configuration */ +} RtcDrv_RuntimeConfigType; + +/* Forward declaration of related register */ +struct _RtcRegType_; + +/*! \brief The definition of RTC driver class + */ +typedef struct _RtcDrvType_ +{ + struct _RtcRegType_ *reg; /*!< pointer to the RTC register*/ + RtcDrv_RuntimeConfigType runtimeConfig; /*!< runtime configuration */ +} RtcDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the RTC driver module + * + * This function initializes RTC driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to RTC driver instance + * \param[in] reg : pointer to RTC register instance + */ +extern void RtcDrv_Init(RtcDrvType *obj, struct _RtcRegType_ *reg); + +/*! \brief Get default configures the RTC module for configuration structure + * + * This function gets default configures the Rtc module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void RtcDrv_GetDefaultConfig(RtcDrv_ConfigType *userConfig); + +/*! \brief Configures the RTC module from a user configuration structure + * + * This function configures the RTC instance with the settings + * provided by the user via the userConfig parameter. The user must ensure + * that clock is enabled for the RTC instance used. + * In order to clear the CR Lock the user must perform a power-on reset. + * + * \param[in] obj : pointer to RTC driver instance + * \param[in] userConfig : pointer to configuration structure + * \return the result of the configure operation + * - false : configure failed + * - true : success + */ +extern bool RtcDrv_Configure(RtcDrvType *obj, const RtcDrv_ConfigType *userConfig); + +/*! \brief Start RTC instance counter. + * + * This function starts the RTC counter. + * Should use RtcDrv_Configure to configure the start time. + * + * \param[in] obj : pointer to RTC driver instance. + */ +extern bool RtcDrv_StartCounter(RtcDrvType *obj); + +/*! \brief Disable RTC instance counter. + * + * This function stops the RTC counter + * + * \param[in] obj : pointer to RTC driver instance. + */ +extern bool RtcDrv_StopCounter(RtcDrvType *obj); + +/*! \brief Get current TimeData from RTC instance. + * + * \param[in] obj : pointer to RTC driver instance. + * \param[out] currentTime : pointer to Rtc TimeDate structure. + * \return the result of the operation + * - false : the operation failed + * - true : success + */ +extern bool RtcDrv_GetCurrentTimeDate(RtcDrvType *obj, RtcDrv_TimeDateType *currentTime); + +/*! \brief Set timedate for RTC instance. + * + * The user must stop the counter + * before using this function. Otherwise it will return an error + * + * \param[in] obj : pointer to RTC driver instance. + * \param[in] time : pointer to Rtc Time TimeDate structure. + * \return the result of the operation + * - false : the operation failed, the time provided was invalid or the counter was not stopped + * - true : success + */ +extern bool RtcDrv_SetTimeDate(RtcDrvType *obj, const RtcDrv_TimeDateType *time); + +/*! \brief This method configures register lock for the corresponding RTC instance. + * + * Remember that all the registers are unlocked only by software reset or power on reset. + * (Except for CR that is unlocked only by POR). + * + * \param[in] obj : pointer to RTC driver instance. + * \param[in] lockConfig : pointer to Rtc Register Lock structure. + */ +extern bool RtcDrv_ConfigureRegisterLock(RtcDrvType *obj, const RtcDrv_RegLockConfigType *lockConfig); + +/*! \brief Get which registers are locked for RTC instance + * + * This function gets which registers are locked + * + * \param[in] obj : pointer to RTC driver instance. + * \param[out] lockConfig : pointer to Rtc Register Lock structure. + */ +extern void RtcDrv_GetRegisterLock(RtcDrvType *obj, RtcDrv_RegLockConfigType *lockConfig); + +/*! \brief Configure OverFlow Interrupt. + * + * This function configures the overflow interrupt + * + * \note Must disable the corresponding interrupt in the IRQ system + * before configure + * + * \param[in] obj : pointer to RTC driver instance. + * \param[in] intConfig : pointer to the structure which holds the configuration + */ +extern void RtcDrv_ConfigureOverFlowInt(RtcDrvType *obj, const RtcDrv_InterruptConfigType *intConfig); + +/*! \brief Configure Seconds Interrupt. + * + * This function configures the Seconds interrupt + * + * \note Must disable the corresponding interrupt in the IRQ system + * before configure + * + * \param[in] obj : pointer to RTC driver instance. + * \param[in] intConfig : pointer to the structure which holds the configuration + */ +extern void RtcDrv_ConfigureSecondsInt(RtcDrvType *obj, const RtcDrv_SecondsIntConfigType *intConfig); + +/*! \brief Configure alarm. + * + * This function configures the alarm with the configuration from the alarmConfig parameter + * + * \note Must disable the corresponding interrupt in the IRQ system + * before configure + * + * \param[in] obj : pointer to RTC driver instance. + * \param[in] alarmConfig : pointer to Rtc Alarm Interrupt Configuration. + * \return the result of the configure + * - false : the alarm time is invalid + * - true : configure success + */ +extern bool RtcDrv_ConfigureAlarm(RtcDrvType *obj, const RtcDrv_AlarmConfigType *alarmConfig); + +/*! \brief Get alarm configuration for RTC instance + * + * This function gets the current alarm configuration + * + * \param[in] obj : pointer to RTC driver instance. + * \param[out] alarmConfig : Pointer to the structure in which to store the alarm configuration + */ +extern void RtcDrv_GetAlarmConfig(const RtcDrvType *obj, RtcDrv_AlarmConfigType *alarmConfig); + +/*! \brief Get Time Alarm Flag. + * + * This function gets the time alarm flag + * + * \param[in] obj : pointer to RTC driver instance. + * \return if there is the alarm pending flag + * - false : no alarm pending + * - true : alarm is pending + */ +extern bool RtcDrv_IsAlarmPending(const RtcDrvType *obj); + +/*! \brief Convert Seconds To TimeDate. + * + * This function converts the seconds to TimeDate format. + * + * \note This function is a "static" function regardless of instances + * + * \param[in] seconds : seconds. + * \param[out] timeDate : pointer to Rtc TimeDate Structure. + */ +extern void RtcDrv_ConvertSecondsToTimeDate(uint32_t seconds, RtcDrv_TimeDateType *timeDate); + +/*! \brief Convert TimeDate To Seconds. + * + * This function converts the TimeDate format to seconds + * + * \note This function is a "static" function regardless of instances + * + * \param[in] timeDate : Rtc TimeDate Structure. + * \param[out] seconds : pointer to seconds. + */ +extern void RtcDrv_ConvertTimeDateToSeconds(const RtcDrv_TimeDateType *timeDate, uint32_t *seconds); + +/*! \brief Check year is leap + * + * This function checks whether it's a leap year + * + * \note This function is a "static" function regardless of instances + * + * \param[in] year : Year to check + * \return if the year is leap + * - false : not leap + * - true : the year is leap + */ +extern bool RtcDrv_IsYearLeap(uint16_t year); + +/*! \brief Check if the date time struct is configured properly + * + * This function checks if the TimeDate format is valid. + * + * \note This function is a "static" function regardless of instances + * + * \param[in] config: timeDate Structure + * \return if the time date is in the corrent format + * - false : not in the corrent format + * - true : the format is corrent + */ +extern bool RtcDrv_IsTimeDateCorrectFormat(const RtcDrv_TimeDateType *timeDate); + +/*! \brief Gets the next alarm time + * + * \param[in] obj : pointer to RTC driver instance. + * \param[in] config : pointer to Rtc Alarm Configuration Structure. + * \param[in] gettime : pointer to Rtc TimeDate Structure. + * \return the result of the operation + * - false : the get operation failed + * - true : success + */ +extern bool RtcDrv_GetNextAlarmTime(RtcDrvType *obj, RtcDrv_TimeDateType *alarmTime); + +/*! \brief IRQ Handler + * + * This method is the API's Interrupt handler for generic and alarm IRQ. + * It will handle the alarm repetition and calls the user callbacks if they + * are not NULL. + * Should be called in the IRQ handler of the IRQ system + * + * \param[in] obj : pointer to RTC driver instance. + */ +extern void RtcDrv_IrqHandler(RtcDrvType *obj); + +/*! \brief Seconds IRQ Handler + * + * This method is the API's Interrupt handler for RTC Second + * interrupt. This ISR will call the user callback if defined. + * Should be called in the IRQ handler of the IRQ system + * + * \param[in] obj : pointer to RTC driver instance. + */ +extern void RtcDrv_SecondsIrqHandler(RtcDrvType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _RTC_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/spi/spi_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/spi/spi_drv.c new file mode 100644 index 0000000..ccea836 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/spi/spi_drv.c @@ -0,0 +1,1966 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/****************************************************************************** + * the includes + *****************************************************************************/ + +#include "spi_drv.h" + +/****************************************************************************** + * the defines + *****************************************************************************/ + +/****************************************************************************** + * the typedefs + *****************************************************************************/ + +/****************************************************************************** + * the globals + *****************************************************************************/ + +/****************************************************************************** + * the static function declarations + *****************************************************************************/ +static void SpiDrv_GoldenSectionAlgorithm(SpiDrv_GoldenSectionInfoType *pGoldenSectionInfo); +static void SpiDrv_InitTxCommand(SpiRegType *obj, const SpiDrv_InitCfgType *pInitCfg); +static void SpiDrv_InitBasicParameters(SpiRegType *obj, const SpiDrv_BasicParametersType *pBasicParameters); +static void SpiDrv_InitExtendParameters(SpiRegType *obj, const SpiDrv_ExtendParametersType *pExtendParameters, const SpiDrv_ExtendFeaturesType *pExtendFeatures); +static SpiDrv_ShiftFirstBitType SpiDrv_GetDataShiftDirection(const SpiDrvType *obj); + +/****************************************************************************** + * the functions + *****************************************************************************/ + +/*! \brief the algorithm of golden section + * + * the algorithm of golden section + * + * \param[in] pGoldenSectionInfo : the golden section structure + * \return: void + */ +static void SpiDrv_GoldenSectionAlgorithm(SpiDrv_GoldenSectionInfoType *pGoldenSectionInfo) +{ + uint8_t tPrescalerIdx = 0; + uint8_t tMinIdx = 0; + uint32_t tDiffMin = 0; + uint32_t tFreq = 0; + uint16_t tDivIdx = 0; + bool tScanOver = false; + + SpiDrv_CalculateTblType tCalculateTbl[8] = {0}; + const uint32_t prescalerList[8] = {1, 2, 4, 8, 16, 32, 64, 128}; + const uint8_t prescalerNums = 8; + const uint32_t maxDivValue = 0xFF + 2; + + for(tPrescalerIdx = 0; tPrescalerIdx < prescalerNums; tPrescalerIdx++) + { + tCalculateTbl[tPrescalerIdx].diff = 0xFFFFFFFF; + tCalculateTbl[tPrescalerIdx].div = 0; + } + + for(tPrescalerIdx = 0; tPrescalerIdx < prescalerNums; tPrescalerIdx++) + { + for(tDivIdx = 2; tDivIdx <= maxDivValue; tDivIdx++) + { + tFreq = (pGoldenSectionInfo->freqInput / prescalerList[tPrescalerIdx]) / tDivIdx; + + if(tFreq == pGoldenSectionInfo->freqTargetOut) + { + tCalculateTbl[tPrescalerIdx].div = tDivIdx; + tCalculateTbl[tPrescalerIdx].prescalerIdx = tPrescalerIdx; + tCalculateTbl[tPrescalerIdx].diff = 0; + + tScanOver = true; + break; + } + else if(tFreq < pGoldenSectionInfo->freqTargetOut) + { + tCalculateTbl[tPrescalerIdx].div = tDivIdx; + tCalculateTbl[tPrescalerIdx].prescalerIdx = tPrescalerIdx; + tCalculateTbl[tPrescalerIdx].diff = pGoldenSectionInfo->freqTargetOut - tFreq; + break; + } + } + + if(tScanOver == true) + { + break; + } + } + + tMinIdx = 0; + tDiffMin = tCalculateTbl[tMinIdx].diff; + for(tPrescalerIdx = 1; tPrescalerIdx < prescalerNums; tPrescalerIdx++) + { + if(tCalculateTbl[tPrescalerIdx].diff < tDiffMin) + { + tDiffMin = tCalculateTbl[tPrescalerIdx].diff; + tMinIdx = tPrescalerIdx; + } + } + + if(tCalculateTbl[tMinIdx].div < 2) + { + tFreq = (pGoldenSectionInfo->freqInput / prescalerList[prescalerNums - 1]) / maxDivValue; + + pGoldenSectionInfo->bestOutPrescaler = prescalerNums - 1; + pGoldenSectionInfo->bestOutDiv = maxDivValue - 2; + pGoldenSectionInfo->bestOutFreq = tFreq; + } + else + { + pGoldenSectionInfo->bestOutPrescaler = tCalculateTbl[tMinIdx].prescalerIdx; + pGoldenSectionInfo->bestOutDiv = tCalculateTbl[tMinIdx].div - 2; + pGoldenSectionInfo->bestOutFreq = (uint32_t)(pGoldenSectionInfo->freqTargetOut - tCalculateTbl[tMinIdx].diff); + } +} + +/*! \brief Sets the Transmit Command Register (TCR) parameters + * + * this function initial the spi parameters about clock polarity and other parameters + * + * \param[in] obj : base reg address for the SPI instance + * \param[in] pInitCfg : Structure that contains the settings + * \return: void + */ +static void SpiDrv_InitTxCommand(SpiRegType *obj, const SpiDrv_InitCfgType *pInitCfg) +{ + uint32_t tTcr = 0; + uint8_t tPrescaler = 0; + uint32_t tDiv = 0; + + tTcr = SpiReg_GetTcr(obj); + + /* Normal transfer, used the default configuration, set it again if extend features used */ + SpiDrv_SetTxDataMask(&tTcr, false); + SpiDrv_SetRxDataMask(&tTcr, false); + + /* First Bit shift */ + SpiDrv_SetLowBitFirstTransfer(&tTcr, pInitCfg->basicParameters.dataShiftFirstBit); + + /* CPHA */ + SpiDrv_SetClockPhase(&tTcr, pInitCfg->basicParameters.clockPhase); + + /* CPOL */ + SpiDrv_SetClockPolarity(&tTcr, pInitCfg->basicParameters.clockPolarity); + + { + SpiDrv_GoldenSectionInfoType tGoldenSectionInfo; + + tGoldenSectionInfo.freqTargetOut = pInitCfg->basicParameters.baudRate; + tGoldenSectionInfo.freqInput = pInitCfg->basicParameters.busClockFreq; + + SpiDrv_GoldenSectionAlgorithm(&tGoldenSectionInfo); + + tPrescaler = (uint8_t)tGoldenSectionInfo.bestOutPrescaler; + tDiv = tGoldenSectionInfo.bestOutDiv; + /* SCK Div */ + SpiReg_SetSckDiv(obj, (uint8_t)tDiv); + } + + /* Prescaler */ + SpiDrv_SetPrescaler(&tTcr, tPrescaler); + + /* Frame Size */ + SpiDrv_SetFrameSize(&tTcr, (uint16_t)(pInitCfg->basicParameters.frameBitSize - 1u)); + + /* Byte-Swap, only in the frame size /32 != 0u case, can used the byte swap */ + if((pInitCfg->basicParameters.frameBitSize & SPIDRV_ONE_FRAME_BITS_MAX_NUM) != 0u) + { + SpiDrv_SetByteSwap(&tTcr, pInitCfg->extendFeatures.byteSwapEn); + } + else + { + SpiDrv_SetByteSwap(&tTcr, 0u); + } + + /* Select PCS */ + SpiDrv_SetPcsSelection(&tTcr, pInitCfg->basicParameters.pcsSelection); + + /* PIN Cfg */ + switch(pInitCfg->extendParameters.pinCfg) + { + case SPIDRV_PIN_CFG_SIN_IN_SOUT_OUT: + /* only support single-full duplex */ + SpiDrv_SetTransferWidth(&tTcr, 0); + + /* TX RX MASK */ + SpiDrv_SetRxDataMask(&tTcr, pInitCfg->extendFeatures.rxMaskEn); + SpiDrv_SetTxDataMask(&tTcr, pInitCfg->extendFeatures.txMaskEn); + break; + + case SPIDRV_PIN_CFG_HALF_DUPLEX_SIN: + /* For half-duplex parallel transfers, either Receive Data Mask (RXMSK) or Transmit Data Mask (TXMSK) must be set */ + SpiDrv_SetRxDataMask(&tTcr, 1); + SpiDrv_SetTxDataMask(&tTcr, 0); + + /* Duplex, single line or double line */ + if(pInitCfg->extendParameters.duplexType == SPIDRV_DUPLEX_HALF_DUPLEX_IN_SINGLE_LINE) + { + SpiDrv_SetTransferWidth(&tTcr, 0); + } + else if(pInitCfg->extendParameters.duplexType == SPIDRV_DUPLEX_HALF_DUPLEX_IN_DOUBLE_LINE) + { + SpiDrv_SetTransferWidth(&tTcr, 1); + } + break; + + case SPIDRV_PIN_CFG_HALF_DUPLEX_SOUT: + /* Duplex, single line or double line */ + if(pInitCfg->extendParameters.duplexType == SPIDRV_DUPLEX_HALF_DUPLEX_IN_SINGLE_LINE) + { + SpiDrv_SetTransferWidth(&tTcr, 0); + } + else if(pInitCfg->extendParameters.duplexType == SPIDRV_DUPLEX_HALF_DUPLEX_IN_DOUBLE_LINE) + { + SpiDrv_SetTransferWidth(&tTcr, 1); + } + + /* For half-duplex parallel transfers, either Receive Data Mask (RXMSK) or Transmit Data Mask (TXMSK) must be set */ + SpiDrv_SetRxDataMask(&tTcr, 1); + SpiDrv_SetTxDataMask(&tTcr, 0); + break; + + case SPIDRV_PIN_CFG_SIN_OUT_SOUT_IN: + /* only support single-full duplex */ + SpiDrv_SetTransferWidth(&tTcr, 0); + + /* TX RX MASK */ + SpiDrv_SetRxDataMask(&tTcr, pInitCfg->extendFeatures.rxMaskEn); + SpiDrv_SetTxDataMask(&tTcr, pInitCfg->extendFeatures.txMaskEn); + break; + + default: + /* only support single-full duplex */ + SpiDrv_SetTransferWidth(&tTcr, 0); + + /* TX RX MASK */ + SpiDrv_SetRxDataMask(&tTcr, pInitCfg->extendFeatures.rxMaskEn); + SpiDrv_SetTxDataMask(&tTcr, pInitCfg->extendFeatures.txMaskEn); + break; + } + + obj->TCR = tTcr; +} + +/*! \brief Init the spi module basic parameters and basic functions + * + * this function initializes the basic features with the parameters + * + * \param[in] obj : pointer to the instance + * \param[in] pBasicParameters : the conbination of basic parameters + * \return: void + */ +static void SpiDrv_InitBasicParameters(SpiRegType *obj, const SpiDrv_BasicParametersType *pBasicParameters) +{ + /* Configures the SPI in master or slave mode */ + SpiReg_SetNodeMode(obj, pBasicParameters->isMasterNode); + + /* Peripheral Chip Select Polarity */ + SpiReg_SetPcsPolarity(obj, (uint8_t)(((uint8_t)pBasicParameters->pcsPolarity) << ((uint8_t)pBasicParameters->pcsSelection))); +} + +/*! \brief Init the spi module extend parameters and extend functions + * + * this function initializes the extend features with the parameters + * + * \param[in] obj : pointer to the instance + * \param[in] pExtendParameters: the conbination of all extend parameters + * \param[in] pExtendFeatures: the conbination of the all extend features + * \return: void + */ +static void SpiDrv_InitExtendParameters(SpiRegType *obj, const SpiDrv_ExtendParametersType *pExtendParameters, const SpiDrv_ExtendFeaturesType *pExtendFeatures) +{ + /* DMA TX */ + SpiReg_SetTxDMA(obj, pExtendFeatures->dmaTxEn); + + /* DMA RX */ + SpiReg_SetRxDMA(obj, pExtendFeatures->dmaRxEn); + + /* NO-STALL */ + SpiReg_SetNoStallMode(obj, pExtendFeatures->noStallEn); + + /* CIRCULAR FIFO */ + SpiReg_SetCircularFIFO(obj, pExtendFeatures->circularFifoEn); + + /* Slave AUTO-PCS */ + if(SpiReg_GetNodeMasterState(obj) == false) + { + SpiReg_SetAutoCS(obj, pExtendFeatures->slaveAutoPcsEn); + } + + /* Stop or Debug to use module */ + SpiReg_EnableDozeMode(obj, pExtendFeatures->stopEn); + SpiReg_EnableDebugMode(obj, pExtendFeatures->dbgEn); + + /* Delay between transfers */ + SpiReg_SetDelayDBT(obj, pExtendParameters->delayBetweenTransfer); + + /* Delay from pcs to sck */ + SpiReg_SetDelayPcsToSck(obj, pExtendParameters->delayFromPcsToSck); + + /* Delay from sck to pcs */ + SpiReg_SetDelaySckToPcs(obj, pExtendParameters->delayFromSckToPcs); + + /* Master sck delay ticks */ + SpiReg_SetMstSckDelay(obj, pExtendParameters->masterSampleSckDelay); + + /* PIN Cfg */ + switch(pExtendParameters->pinCfg) + { + case SPIDRV_PIN_CFG_SIN_IN_SOUT_OUT: + SpiReg_SetOutCfg(obj, pExtendParameters->outCfg); + SpiReg_SetPinCfg(obj, 0); + break; + + case SPIDRV_PIN_CFG_HALF_DUPLEX_SIN: + SpiReg_SetPinCfg(obj, 1); + /* If performing half-duplex transfers, this bit must be set */ + SpiReg_SetOutCfg(obj, 1); + break; + + case SPIDRV_PIN_CFG_HALF_DUPLEX_SOUT: + SpiReg_SetPinCfg(obj, 2); + /* If performing half-duplex transfers, this bit must be set */ + SpiReg_SetOutCfg(obj, 1); + break; + + case SPIDRV_PIN_CFG_SIN_OUT_SOUT_IN: + SpiReg_SetOutCfg(obj, pExtendParameters->outCfg); + SpiReg_SetPinCfg(obj, 3); + break; + + default: + SpiReg_SetOutCfg(obj, pExtendParameters->outCfg); + SpiReg_SetPinCfg(obj, 0); + break; + } +} + +/*! \brief Get default configures the module for configuration structure + * + * This function gets default configures the module for user configuration structure + * + * \param[out] pInitCfg :pointer to configuration structure + * \return: void + */ +void SpiDrv_GetDefaultConfig(SpiDrv_InitCfgType *pInitCfg) +{ + /* If no user configuration, used the default configuration */ + pInitCfg->basicParameters.busClockFreq = 80000000ul; + pInitCfg->basicParameters.baudRate = 1000000ul; + pInitCfg->basicParameters.isMasterNode = true; + pInitCfg->basicParameters.clockPhase = SPIDRV_CLK_PHASE_DATA_SAMPLE_ON_LEADING_EDGE; + pInitCfg->basicParameters.clockPolarity = SPIDRV_CLK_POLARITY_IDLE_IN_LOW; + pInitCfg->basicParameters.pcsSelection = SPIDRV_PCS_SEL_PCS0; + pInitCfg->basicParameters.pcsPolarity = SPIDRV_PCS_POLARITY_ACTIVE_LOW; + pInitCfg->basicParameters.dataShiftFirstBit = SPIDRV_SHIFT_FIRST_BIT_LSB; + pInitCfg->basicParameters.frameBitSize = 8; + + pInitCfg->extendFeatures.dmaTxEn = false; + pInitCfg->extendFeatures.dmaRxEn = false; + pInitCfg->extendFeatures.noStallEn = false; + pInitCfg->extendFeatures.circularFifoEn = false; + pInitCfg->extendFeatures.byteSwapEn = false; + pInitCfg->extendFeatures.slaveAutoPcsEn = false; + pInitCfg->extendFeatures.dbgEn = false; + pInitCfg->extendFeatures.rxMaskEn = false; + pInitCfg->extendFeatures.txMaskEn = false; + pInitCfg->extendFeatures.stopEn = false; + + pInitCfg->extendParameters.duplexType = SPIDRV_DUPLEX_FULL_DUPLEX; + pInitCfg->extendParameters.delayBetweenTransfer = 10; /* N* fModule (Busclock / Prescaler) */ + pInitCfg->extendParameters.delayFromPcsToSck = 10; /* N* fModule (Busclock / Prescaler) */ + pInitCfg->extendParameters.delayFromSckToPcs = 10; /* N* fModule (Busclock / Prescaler) */ + pInitCfg->extendParameters.masterSampleSckDelay = 0; + pInitCfg->extendParameters.pinCfg = SPIDRV_PIN_CFG_SIN_IN_SOUT_OUT; + pInitCfg->extendParameters.outCfg = SPIDRV_OUTCFG_IN_OLD_VALUE; +} + +/*! \brief Set the spi module parameters include basic&extend features + * + * this function initializes the run-time state structure to provide for module configuration + * + * \param[in] obj : pointer to the instance + * \param[in] pInitCfg: the pointer to the user configuration + * \return: void + */ +void SpiDrv_SetConfig(SpiDrvType *obj, const SpiDrv_InitCfgType *pInitCfg) +{ + /* Disable the Module to make sure that some register be configured successfully */ + SpiReg_EnableModule(obj->reg, false); + + /* clear Tx&Rx FIFO */ + SpiReg_ResetTxFIFO(obj->reg); + SpiReg_ResetRxFIFO(obj->reg); + + /* set some duration after reset the module */ + __asm volatile("nop"); + __asm volatile("nop"); + __asm volatile("nop"); + + /* Set the basic parameters */ + SpiDrv_InitBasicParameters(obj->reg, &pInitCfg->basicParameters); + + /* Set the extend features if used */ + SpiDrv_InitExtendParameters(obj->reg, &pInitCfg->extendParameters, &pInitCfg->extendFeatures); + + /* Enable the module */ + SpiReg_EnableModule(obj->reg, true); + + /* Configure the tx parameters */ + SpiDrv_InitTxCommand(obj->reg, pInitCfg); +} + +/*! \brief Resets the SPI internal logic and registers to their default settings + * + * this function instance an object and reset module + * + * \param[in/out] this : pointer to the instance + * \param[in] pReg : the phycial module base address pointer + * \return: void + */ +void SpiDrv_Init(SpiDrvType *obj, SpiRegType *pReg) +{ + obj->reg = pReg; + + /* Reset tx&rx fifo first after reset or reinit or power-on */ + SpiReg_ResetTxFIFO(obj->reg); + SpiReg_ResetRxFIFO(obj->reg); + + /* Reset the module */ + SpiReg_ResetModule(obj->reg, true); + + /* set some duration after reset the module */ + __asm volatile("nop"); + __asm volatile("nop"); + __asm volatile("nop"); + /* Notice: the reset bit should be clear by software, 7/5/2022 Changed by CVAchip */ + obj->reg->CR = 0; +} + +/*! \brief Set the module to special condition + * + * call back in the usage of Low power or sleep requirements + * + * \param[in] obj : pointer to the instance + * \return: void + */ +void SpiDrv_DeInit(SpiDrvType *obj) +{ + /* clear Tx&Rx FIFO */ + SpiReg_ResetTxFIFO(obj->reg); + SpiReg_ResetRxFIFO(obj->reg); + __asm volatile("nop"); + __asm volatile("nop"); + __asm volatile("nop"); + + SpiReg_ResetModule(obj->reg, true); + /* set some duration after reset the module */ + __asm volatile("nop"); + __asm volatile("nop"); + __asm volatile("nop"); + /* Notice: the reset bit should be clear by software, 7/5/2022 Changed by CVAchip */ + SpiReg_ResetModule(obj->reg, false); + + /* Disable the Module */ + SpiReg_EnableModule(obj->reg, false); +} + +/*! \brief Get the data shift direction of transfer + * + * this function get the current configuration about data shift method + * + * \param[in] obj : pointer to the instance + * \return: return the data shift direction + */ +static SpiDrv_ShiftFirstBitType SpiDrv_GetDataShiftDirection(const SpiDrvType *obj) +{ + SpiDrv_ShiftFirstBitType tRtn = SPIDRV_SHIFT_FIRST_BIT_MSB; + + if(SpiReg_GetTransferDataBitLsbState(obj->reg) == true) + { + tRtn = SPIDRV_SHIFT_FIRST_BIT_LSB; + } + + return tRtn; +} + +/*! \brief Get the status of the SpiDrv_StatusType of event + * + * this function read out the special status what want to be read + * + * \param[in] obj : pointer to the instance + * \param[in] status: which status to be read out + * \return: bool + * true: The status is exist + * false: The status is not exist + */ +bool SpiDrv_GetStatus(const SpiDrvType *obj, SpiDrv_StatusType status) +{ + bool tRtn = false; + + uint32_t tRegValue = 0; + + switch(status) + { + case SPIDRV_STATUS_TX_DATA: + tRegValue = SpiReg_GetTxDataFlag(obj->reg); + break; + + case SPIDRV_STATUS_RX_DATA: + tRegValue = SpiReg_GetRxDataFlag(obj->reg); + break; + + case SPIDRV_STATUS_RX_WORD_DONE: + tRegValue = SpiReg_GetRxWordDoneFlag(obj->reg); + break; + + case SPIDRV_STATUS_FRAME_DONE: + tRegValue = SpiReg_GetFrameDoneFlag(obj->reg); + break; + + case SPIDRV_STATUS_XFR_DONE: + tRegValue = SpiReg_GetMasterTransferDoneFlag(obj->reg); + break; + + case SPIDRV_STATUS_TX_UF: + tRegValue = SpiReg_GetTxUnderFlowFlag(obj->reg); + break; + + case SPIDRV_STATUS_RX_OF: + tRegValue = SpiReg_GetRxOverFlowFlag(obj->reg); + break; + + case SPIDRV_STATUS_BUSY: + tRegValue = SpiReg_GetBusyFlag(obj->reg); + break; + + default: + break; + } + + if(tRegValue != 0ul) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief Clear the status + * + * this function clear the special status falg + * + * \param[in] obj : pointer to the instance + * \param[in] status : combination of any SpiDrv_StatusType event + * example: Status = (SPIDRV_STATUS_RX_WORD_DONE | SPIDRV_STATUS_FRAME_DONE) + * \return: void + */ +void SpiDrv_ClearStatus(SpiDrvType *obj, uint32_t status) +{ + /* RX_WORD_DONE */ + if((status & SPIDRV_STATUS_RX_WORD_DONE) != 0ul) + { + SpiReg_ClearRxWordDoneFlag(obj->reg); + } + + /* FRAME_DONE */ + if((status & SPIDRV_STATUS_FRAME_DONE) != 0ul) + { + SpiReg_ClearFrameDoneFlag(obj->reg); + } + + /* MST_TRANSFER_DONE */ + if((status & SPIDRV_STATUS_XFR_DONE) != 0ul) + { + SpiReg_ClearMasterTransferDoneFlag(obj->reg); + } + + /* TX_UF */ + if((status & SPIDRV_STATUS_TX_UF) != 0ul) + { + SpiReg_ClearTxUnderFlowFlag(obj->reg); + } + + /* RX_OF */ + if((status & SPIDRV_STATUS_RX_OF) != 0ul) + { + SpiReg_ClearRxOverFlowFlag(obj->reg); + } +} + +/*! \brief Master Sync tx data, sent and received data from other node + * + * _____ DATA DATA DATA DATA __________ + * PCS |_____________________| + * + * \param[in] obj : pointer to the instance + * \param[in] frameSizeBitType: the data width to describe the pTxBuffer + * \param[in] txFrameNums: the nums data to be sent + * \param[in] pTxBuffer: the transmit data buffer pointer + * \param[in] pRxBuffer: the pointer for the read-out datas + * \return: bool + * false: the current tx fifo is full, no enough space for this transmit + * true: no error + */ +bool SpiDrv_MasterSyncTransfer(SpiDrvType *obj, SpiDrv_FrameSizeBitType frameSizeBitType, uint16_t txFrameNums, const void *pTxBuffer, void *pRxBuffer) +{ + bool tRtn = true; + uint8_t tTxFreeNums = 0; + + tTxFreeNums = SPIDRV_TX_FIFO_SIZE - SpiReg_GetTxFifoCounter(obj->reg); + + if(tTxFreeNums >= txFrameNums) + { + uint32_t tTcr = 0, tTimeout = 0; + uint16_t x = 0; + + tTcr = SpiReg_GetTcr(obj->reg); + SpiDrv_SetContinuousCmd(&tTcr, false); + SpiDrv_SetContinuousTransfer(&tTcr, true); + SpiDrv_SetTxDataMask(&tTcr, false); + SpiDrv_SetRxDataMask(&tTcr, false); + SpiDrv_SetFrameSize(&tTcr, (uint16_t)((uint16_t)frameSizeBitType * 8u - 1u)); + SpiReg_SetTcr(obj->reg, tTcr); + + for(x = 0; x < txFrameNums; x++) + { + while(SpiReg_GetTxDataFlag(obj->reg) == false) + { + /* Wait tx fifo avaliable */ + tTimeout++; + if(tTimeout > 1000ul) + { + tRtn = false; + break; + } + } + + /* Transmit data */ + if(frameSizeBitType == SPIDRV_FRAME_SIZE_BIT_TYPE_BYTE) + { + obj->reg->TDR = ((uint8_t *)pTxBuffer)[x]; + } + else if(frameSizeBitType == SPIDRV_FRAME_SIZE_BIT_TYPE_HALF_WORD) + { + obj->reg->TDR = ((uint16_t *)pTxBuffer)[x]; + } + else + { + obj->reg->TDR = ((uint32_t *)pTxBuffer)[x]; + } + + tTimeout = 0; + + while((SpiReg_GetRxFifoEmptyState(obj->reg) == true)) + { + tTimeout++; + if(tTimeout > 1000ul) + { + tRtn = false; + break; + } + } + + if(frameSizeBitType == SPIDRV_FRAME_SIZE_BIT_TYPE_BYTE) + { + ((uint8_t *)pRxBuffer)[x] = (obj->reg->RDR & 0xFF); + } + else if(frameSizeBitType == SPIDRV_FRAME_SIZE_BIT_TYPE_HALF_WORD) + { + ((uint16_t *)pRxBuffer)[x] = (obj->reg->RDR & 0xFFFF); + } + else + { + ((uint32_t *)pRxBuffer)[x] = obj->reg->RDR; + } + } + + SpiDrv_SetContinuousCmd(&tTcr, false); + SpiDrv_SetContinuousTransfer(&tTcr, false); + SpiReg_SetTcr(obj->reg, tTcr); + } + else + { + /* Transfer by byte, but not enough space to fill tx datas in bytes */ + tRtn = false; + } + + return tRtn; +} + +/*! \brief Send one short frame each frame bits numbers is equal to or less than 32bits, every time hard set pcs signal again + * the DBT feature is valid + * _____ DATA (DBT) _________ DATA(DBT) __________ + * PCS |_____________| |_____________| + * + * \param[in] obj : pointer to the instance + * \param[in] txData:data to be sent + * \param[in] frameSizeBitType:the frame bit width(8bit/16bit/32bit) to describe the pTxBuffer data width type + * \return: bool + * true: no err + * false: no enough space for the current tx requirement + */ +bool SpiDrv_AsyncSingleFrameTransfer(SpiDrvType *obj, uint32_t txData, SpiDrv_FrameSizeBitType frameSizeBitType) +{ + bool tRtn = true; + uint8_t tTxFreeNums = 0; + + tTxFreeNums = SPIDRV_TX_FIFO_SIZE - SpiReg_GetTxFifoCounter(obj->reg) - 1u; + + if(tTxFreeNums > 0) + { + uint32_t tTcr = 0; + + tTcr = SpiReg_GetTcr(obj->reg); + SpiDrv_SetContinuousCmd(&tTcr, false); + SpiDrv_SetContinuousTransfer(&tTcr, false); + SpiDrv_SetFrameSize(&tTcr, (uint16_t)((uint16_t)frameSizeBitType * 8u - 1u)); + SpiReg_SetTcr(obj->reg, tTcr); + + if(frameSizeBitType == SPIDRV_FRAME_SIZE_BIT_TYPE_BYTE) + { + /* Transmit data */ + obj->reg->TDR = (txData & 0xFF); + } + else if(frameSizeBitType == SPIDRV_FRAME_SIZE_BIT_TYPE_HALF_WORD) + { + /* Transmit data */ + obj->reg->TDR = (txData & 0xFFFF); + } + else + { + /* Transmit data */ + obj->reg->TDR = txData; + } + } + else + { + /* Transfer by byte, but not enough space to fill tx datas in bytes */ + tRtn = false; + } + + return tRtn; +} + +/*! \brief Send more than 32bits frame one time, the DBT feature is invalid + * + * _____ DATA DATA DATA DATA __________ + * PCS |_____________________| + * + * \param[in] obj : pointer to the instance + * \param[in] txFrameNums: the nums data to be sent + * \param[in] pTxBuffer: th pointer of which data to be sent + * \param[in] frameSizeBitType:the frame bit width(8bit/16bit/32bit) to describe the pTxBuffer data width type + * \param[in] littleEndDian: transfer byte turn + * \return: bool + * true: no err + * false: no enough space for the current tx requirement + */ +bool SpiDrv_AsyncLongFrameTransfer(SpiDrvType *obj, uint16_t txFrameNums, const void *pTxBuffer, SpiDrv_FrameSizeBitType frameSizeBitType, bool littleEndDian) +{ + bool tRtn = true; + uint8_t tTxFreeNums = 0; + uint16_t tTxBytesNums = txFrameNums * (uint16_t)frameSizeBitType; + + tTxFreeNums = SPIDRV_TX_FIFO_SIZE - SpiReg_GetTxFifoCounter(obj->reg); + + if(tTxFreeNums >= ((tTxBytesNums + 3) / 4u)) + { + uint32_t tTcr = 0; + + tTcr = SpiReg_GetTcr(obj->reg); + SpiDrv_SetContinuousCmd(&tTcr, false); + SpiDrv_SetContinuousTransfer(&tTcr, false); + SpiDrv_SetFrameSize(&tTcr, (uint16_t)(tTxBytesNums * 8u - 1u)); + SpiReg_SetTcr(obj->reg, tTcr); + + tRtn = SpiDrv_AsyncBitDataWriteIntoHwTxBuffer(obj, (uint16_t)(tTxBytesNums * 8u), pTxBuffer, littleEndDian); + } + else + { + /* Transfer by byte, but not enough space to fill tx datas in bytes */ + tRtn = false; + } + + return tRtn; +} + +/*! \brief continue Send constinues frame,each frame bits numbers is equal to or less than 32bits + * the DBT feature is valid + * _____ DATA(xbits) (DBT) DATA(xBits)__________ + * PCS |_______________________________| + * + * \param[in] obj : pointer to the instance + * \param[in] txFrameNums: the nums data to be sent + * \param[in] pTxBuffer: th pointer of which data to be sent + * \param[in] frameSizeBitType:the frame bit width(8bit/16bit/32bit) to describe the pTxBuffer data width type + * \return: bool + * true: no err + * false: no enough space for the current tx requirement + */ +bool SpiDrv_AsyncContinueFrameTransfer(SpiDrvType *obj, uint16_t txFrameNums, const void *pTxBuffer, SpiDrv_FrameSizeBitType frameSizeBitType) +{ + bool tRtn = true; + uint8_t tTxFreeNums = 0; + + tTxFreeNums = SPIDRV_TX_FIFO_SIZE - SpiReg_GetTxFifoCounter(obj->reg); + + if(tTxFreeNums >= txFrameNums) + { + uint32_t tTcr = 0; + uint16_t i = 0; + + tTcr = SpiReg_GetTcr(obj->reg); + SpiDrv_SetContinuousCmd(&tTcr, false); + SpiDrv_SetContinuousTransfer(&tTcr, true); + SpiDrv_SetFrameSize(&tTcr, (uint16_t)((uint16_t)frameSizeBitType * 8u - 1u)); + SpiReg_SetTcr(obj->reg, tTcr); + + if(frameSizeBitType == SPIDRV_FRAME_SIZE_BIT_TYPE_BYTE) + { + for(i = 0; i < txFrameNums; i++) + { + /* Transmit data */ + obj->reg->TDR = ((uint8_t *)pTxBuffer)[i]; + } + } + else if(frameSizeBitType == SPIDRV_FRAME_SIZE_BIT_TYPE_HALF_WORD) + { + for(i = 0; i < txFrameNums; i++) + { + /* Transmit data */ + obj->reg->TDR = ((uint16_t *)pTxBuffer)[i]; + } + } + else + { + for(i = 0; i < txFrameNums; i++) + { + /* Transmit data */ + obj->reg->TDR = ((uint32_t *)pTxBuffer)[i]; + } + } + + SpiDrv_SetContinuousTransfer(&tTcr, false); + SpiReg_SetTcr(obj->reg, tTcr); + } + else + { + /* Transfer by byte, but not enough space to fill tx datas in bytes */ + tRtn = false; + } + + return tRtn; +} + +/*! \brief Set the link route function in the slave node with byte transfer + * + * this function is used for slave node to link transfer from master to other node with bytes + * + * \param[in] obj : pointer to the instance + * \param[in] txBytesCnt: the data bytes to be sent + * \param[in] pTxByteBuffer: pointer to the tx data byte buffer + * the tx data will fill or not by special requirement + * \return: void + */ +void SpiDrv_SlaveAsyncLinkTransferBytes(SpiDrvType *obj, uint16_t txBytesCnt, const uint8_t *pTxByteBuffer) +{ + uint8_t tTxFreeNums = 0; + + tTxFreeNums = SPIDRV_TX_FIFO_SIZE - SpiReg_GetTxFifoCounter(obj->reg); + + if(tTxFreeNums > ((txBytesCnt + 3u) / 4u)) + { + uint32_t tTcr = 0; + uint32_t i = 0; + uint8_t tMultFrameNums = 0, tRestNums = 0; + + if(txBytesCnt > 0) + { + uint8_t tBufferIdx = 0; + + tTcr = SpiReg_GetTcr(obj->reg); + SpiDrv_SetContinuousCmd(&tTcr, false); + SpiDrv_SetContinuousTransfer(&tTcr, true); + SpiDrv_SetTxDataMask(&tTcr, false); + SpiDrv_SetRxDataMask(&tTcr, false); + SpiDrv_SetFrameSize(&tTcr, 7u); + SpiReg_SetTcr(obj->reg, tTcr); + + tMultFrameNums = (uint8_t)(txBytesCnt / 4u); + tRestNums = (txBytesCnt & 0x03); + + if(tMultFrameNums > 0) + { + for(i = 0; i < tMultFrameNums; i++) + { + /* Transmit data */ + obj->reg->TDR = *((uint32_t *)&pTxByteBuffer[tBufferIdx]); + tBufferIdx += 4; + } + } + + if(tRestNums > 0) + { + uint8_t x = 0; + SpiDrv_DataAlignedType tTxDataAligned; + + tTxDataAligned.wordData = 0; + + /* The rest bytes filled action */ + if(SpiDrv_GetDataShiftDirection(obj) == SPIDRV_SHIFT_FIRST_BIT_LSB) + { + for(x = 0; x < tRestNums; x++) + { + tTxDataAligned.byteData[tRestNums - 1 - x] = pTxByteBuffer[tBufferIdx]; + tBufferIdx++; + } + } + else + { + for(x = 0; x < tRestNums; x++) + { + tTxDataAligned.byteData[x] = pTxByteBuffer[tBufferIdx]; + tBufferIdx++; + } + } + + /* Transmit data */ + obj->reg->TDR = tTxDataAligned.wordData; + } + } + } +} + +/*! \brief Set the link route function in the slave node with halfword transfer + * + * this function is used for slave node to link transfer from master to other node with halfwords + * + * \param[in] obj : pointer to the instance + * \param[in] txHalfWordsCnt: the data halfwords to be sent + * \param[in] pTxHalfWordBuffer: pointer to the tx data halfword buffer + * the tx data will fill or not by special requirement + * \return: void + */ +void SpiDrv_SlaveAsyncLinkTransferHalfWords(SpiDrvType *obj, uint16_t txHalfWordsCnt, const uint16_t *pTxHalfWordBuffer) +{ + uint8_t tTxFreeNums = 0; + + tTxFreeNums = SPIDRV_TX_FIFO_SIZE - SpiReg_GetTxFifoCounter(obj->reg); + + if(tTxFreeNums > ((txHalfWordsCnt + 1u) / 2u)) + { + uint32_t tTcr = 0, i = 0; + uint16_t tMultFrameNums = 0, tRestNums = 0; + + if(txHalfWordsCnt > 0) + { + uint8_t tBufferIdx = 0; + + tTcr = SpiReg_GetTcr(obj->reg); + SpiDrv_SetContinuousCmd(&tTcr, false); + SpiDrv_SetContinuousTransfer(&tTcr, true); + SpiDrv_SetTxDataMask(&tTcr, false); + SpiDrv_SetRxDataMask(&tTcr, false); + SpiDrv_SetFrameSize(&tTcr, 15u); + SpiReg_SetTcr(obj->reg, tTcr); + + tMultFrameNums = txHalfWordsCnt; + tRestNums = (txHalfWordsCnt & 0x01); + + for(i = 0; i < tMultFrameNums; i++) + { + /* Transmit data */ + obj->reg->TDR = *((uint32_t *)&pTxHalfWordBuffer[tBufferIdx]); + tBufferIdx += 2; + } + + if(tRestNums > 0) + { + uint8_t x = 0; + SpiDrv_DataAlignedType tTxDataAligned; + + tTxDataAligned.wordData = 0; + + /* The rest bytes filled action */ + if(SpiDrv_GetDataShiftDirection(obj) == SPIDRV_SHIFT_FIRST_BIT_LSB) + { + for(x = 0; x < tRestNums; x++) + { + tTxDataAligned.halfWordData[tRestNums - 1 - x] = pTxHalfWordBuffer[tBufferIdx]; + tBufferIdx++; + } + } + else + { + for(x = 0; x < tRestNums; x++) + { + tTxDataAligned.halfWordData[x] = pTxHalfWordBuffer[tBufferIdx]; + tBufferIdx++; + } + } + + /* Transmit data */ + obj->reg->TDR = tTxDataAligned.wordData; + } + } + } +} + +/*! \brief Set the link route function in the slave node with word transfer + * + * this function is used for slave node to link transfer from master to other node with words + * + * \param[in] obj : base address for the SPI instance + * \param[in] txWodsCnt: the data words to be sent + * \param[in] pTxWordBuffer: pointer to the tx data word buffer + * the tx data will fill or not by special requirement + * \return: void + */ +void SpiDrv_SlaveAsyncLinkTransferWords(SpiDrvType *obj, uint16_t txWodsCnt, const uint32_t *pTxWordBuffer) +{ + uint8_t tTxFreeNums = 0; + + tTxFreeNums = SPIDRV_TX_FIFO_SIZE - SpiReg_GetTxFifoCounter(obj->reg); + + if(tTxFreeNums > txWodsCnt) + { + uint32_t tTcr = 0, i = 0; + + if(txWodsCnt > 0) + { + tTcr = SpiReg_GetTcr(obj->reg); + SpiDrv_SetContinuousCmd(&tTcr, false); + SpiDrv_SetContinuousTransfer(&tTcr, true); + SpiDrv_SetTxDataMask(&tTcr, false); + SpiDrv_SetRxDataMask(&tTcr, false); + SpiDrv_SetFrameSize(&tTcr, 31u); + SpiReg_SetTcr(obj->reg, tTcr); + + for(i = 0; i < txWodsCnt; i++) + { + /* Transmit data */ + obj->reg->TDR = pTxWordBuffer[i]; + } + } + } +} + +/*! \brief Update Transmit Command Register configuration structure + * + * Any writes to the TCR will cause the entire TCR contents to be pushed to the TX FIFO. + * Therefore any updates to the TCR should include updates to all of the register + * bit fields to form a 32-bit write to the TCR. + * + * \param[in] obj : pointer to the instance + * \param[in] pTcrInfo : Transmit Command Register configuration structure + * \return void + */ +void SpiDrv_SetTcrCmdConfig(SpiDrvType *obj, const SpiDrv_TcrInfoType *pTcrInfo) +{ + uint32_t tTcr = 0; + + tTcr = SpiReg_GetTcr(obj->reg); + + /* TX RX MASK */ + SpiDrv_SetTxDataMask(&tTcr, pTcrInfo->txMask); + SpiDrv_SetRxDataMask(&tTcr, pTcrInfo->rxMask); + + /* Byte-Swap, only in the frame size /32 != 0u case, can used the byte swap */ + SpiDrv_SetByteSwap(&tTcr, pTcrInfo->byteSwap); + + /* First Bit shift */ + SpiDrv_SetLowBitFirstTransfer(&tTcr, pTcrInfo->dataShiftFirstBit); + + /* CPHA */ + SpiDrv_SetClockPhase(&tTcr, pTcrInfo->clockPhase); + + /* CPOL */ + SpiDrv_SetClockPolarity(&tTcr, pTcrInfo->clockPolarity); + + /* Select PCS */ + SpiDrv_SetPcsSelection(&tTcr, pTcrInfo->pcsSelection); + + /* Continuous transfer */ + SpiDrv_SetContinuousTransfer(&tTcr, pTcrInfo->continuousTransfer); + + /* Continuous command */ + SpiDrv_SetContinuousCmd(&tTcr, pTcrInfo->continuousCmd); + + /* Frame Size */ + SpiDrv_SetFrameSize(&tTcr, pTcrInfo->frameBitSize); + + /* Transfer width */ + SpiDrv_SetTransferWidth(&tTcr, pTcrInfo->transferWidth); + + /* Update the tcr register */ + SpiReg_SetTcr(obj->reg, tTcr); +} + +/*! \brief Get Transmit Command Register configuration structure + * + * This function get the current tcr register value + * + * \param[in] obj : pointer to the instance + * \return: Transmit Command Register configuration structure + */ +SpiDrv_TcrInfoType SpiDrv_GetTcrCmdConfig(const SpiDrvType *obj) +{ + SpiDrv_TcrInfoType tTcrInfo; + uint32_t tTcr = 0; + + tTcr = SpiReg_GetTcr(obj->reg); + + if((tTcr & SPI_TCR_CPHA_MASK) != 0u) + { + tTcrInfo.clockPhase = SPIDRV_CLK_PHASE_DATA_SAMPLE_ON_TRAILING_EDGE; + } + else + { + tTcrInfo.clockPhase = SPIDRV_CLK_PHASE_DATA_SAMPLE_ON_LEADING_EDGE; + } + + if((tTcr & SPI_TCR_CPOL_MASK) != 0u) + { + tTcrInfo.clockPolarity = SPIDRV_CLK_POLARITY_IDLE_IN_HIGH; + } + else + { + tTcrInfo.clockPolarity = SPIDRV_CLK_POLARITY_IDLE_IN_LOW; + } + + if((((tTcr & SPI_TCR_PCS_SEL_MASK) >> SPI_TCR_PCS_SEL_SHIFT) & 0xFF) == 0u) + { + tTcrInfo.pcsSelection = SPIDRV_PCS_SEL_PCS0; + } + else if((((tTcr & SPI_TCR_PCS_SEL_MASK) >> SPI_TCR_PCS_SEL_SHIFT) & 0xFF) == 1u) + { + tTcrInfo.pcsSelection = SPIDRV_PCS_SEL_PCS1; + } + else if((((tTcr & SPI_TCR_PCS_SEL_MASK) >> SPI_TCR_PCS_SEL_SHIFT) & 0xFF) == 2u) + { + tTcrInfo.pcsSelection = SPIDRV_PCS_SEL_PCS2; + } + else if((((tTcr & SPI_TCR_PCS_SEL_MASK) >> SPI_TCR_PCS_SEL_SHIFT) & 0xFF) == 3u) + { + tTcrInfo.pcsSelection = SPIDRV_PCS_SEL_PCS3; + } + + if((tTcr & SPI_TCR_LSB_FIRST_MASK) != 0u) + { + tTcrInfo.dataShiftFirstBit = SPIDRV_SHIFT_FIRST_BIT_LSB; + } + else + { + tTcrInfo.dataShiftFirstBit = SPIDRV_SHIFT_FIRST_BIT_MSB; + } + + tTcrInfo.frameBitSize = (((tTcr & SPI_TCR_FRAME_SIZE_MASK) >> SPI_TCR_FRAME_SIZE_SHIFT) & 0xFFF); + tTcrInfo.transferWidth = (((tTcr & SPI_TCR_TRANSFER_WIDTH_MASK) >> SPI_TCR_TRANSFER_WIDTH_SHIFT) & 0x03u); + tTcrInfo.prescaler = (((tTcr & SPI_TCR_PRESCALER_MASK) >> SPI_TCR_PRESCALER_SHIFT) & 0xFF); + + if((tTcr & SPI_TCR_RX_MASK_MASK) != 0u) + { + tTcrInfo.rxMask = true; + } + else + { + tTcrInfo.rxMask = false; + } + + if((tTcr & SPI_TCR_TX_MASK_MASK) != 0u) + { + tTcrInfo.txMask = true; + } + else + { + tTcrInfo.txMask = false; + } + + if((tTcr & SPI_TCR_BYTE_SWAP_MASK) != 0u) + { + tTcrInfo.byteSwap = true; + } + else + { + tTcrInfo.byteSwap = false; + } + + tTcrInfo.continuousTransfer = (((tTcr & SPI_TCR_CONTINUE_TRANSFER_MASK) >> SPI_TCR_CONTINUE_TRANSFER_SHIFT) & 0x01); + tTcrInfo.continuousCmd = (((tTcr & SPI_TCR_CONTINUE_CMD_MASK) >> SPI_TCR_CONTINUE_CMD_SHIFT) & 0x01); + + return tTcrInfo; +} + +/*! \brief Set Slave rx fifo water mark + * + * the max water mark is must less than the supported depth + * + * \param[in] obj : pointer to the instance + * \param[in] txFrameNums: the tx frame to be sent + * \param[in] frameSizeBitType: frame bit width(8bit/16bit/32bit) + * \return: bool + * false: the current water is more than the actual max supported depth + * true: no error + */ +bool SpiDrv_SlaveSetRxWaterMark(SpiDrvType *obj, uint16_t txFrameNums, SpiDrv_FrameSizeBitType frameSizeBitType) +{ + bool tRtn = false; + uint8_t tMultFrameNums = 0, tRestNums = 0; + uint16_t tTxBytesNum = 0; + + if(frameSizeBitType == SPIDRV_FRAME_SIZE_BIT_TYPE_BYTE) + { + tTxBytesNum = txFrameNums; + } + else if(frameSizeBitType == SPIDRV_FRAME_SIZE_BIT_TYPE_HALF_WORD) + { + tTxBytesNum = txFrameNums * 2; + } + else + { + tTxBytesNum = txFrameNums * 4; + } + + tMultFrameNums = (uint8_t)(tTxBytesNum / 4u); + tRestNums = (tTxBytesNum & 0x03); + + if(tMultFrameNums < (SpiReg_GetRxFifoDepth(obj->reg) - SpiReg_GetRxFifoCounter(obj->reg))) + { + if(tRestNums > 0) + { + SpiReg_SetRxFifoWaterMark(obj->reg, tMultFrameNums); + } + else + { + if(tMultFrameNums > 0) + { + SpiReg_SetRxFifoWaterMark(obj->reg, (uint8_t)(tMultFrameNums - 1u)); + } + else + { + SpiReg_SetRxFifoWaterMark(obj->reg, 0u); + } + } + + tRtn = true; + } + + return tRtn; +} + +/*! \brief Async bit data write to hardware tx data buffer + * + * this function just only fill datas to tx fifo, but not read out datas from rx fifo + * + * \param[in] obj : pointer to the instance + * \param[in] txBitNums: the tx data bits numbers to be write + * \param[in] pTxBuffer: write data buffer, notice: aligned with 32bits + * \param[in] littleEndDian: write bit flow turn + * \return: bool + * false: error + * true: no error + */ +bool SpiDrv_AsyncBitDataWriteIntoHwTxBuffer(SpiDrvType *obj, uint16_t txBitNums, const void *pTxBuffer, bool littleEndDian) +{ + bool tRtn = true; + uint16_t tRestBitNums = 0, i = 0; + uint8_t tBufferIdx = 0; + uint32_t timeOutCnt = 0; + SpiDrv_DataAlignedType tDataAligned; + + tRestBitNums = txBitNums; + do + { + if(SpiReg_GetTxFifoCounter(obj->reg) <= (SPIDRV_TX_FIFO_SIZE - 1u)) + { + tDataAligned.wordData = 0; + + if(tRestBitNums >= (SPIDRV_FRAME_SIZE_WORD + 1u)) + { + if(littleEndDian == false) + { + for(i = 0u; i < 4; i++) + { + tDataAligned.byteData[i] = ((uint8_t *)pTxBuffer)[tBufferIdx + 3 - i]; + } + } + else + { + for(i = 0; i < 4u; i++) + { + tDataAligned.byteData[i] = ((uint8_t *)pTxBuffer)[tBufferIdx + i]; + } + } + + obj->reg->TDR = tDataAligned.wordData; + tRestBitNums -= 32u; + tBufferIdx += 4u; + } + else if(tRestBitNums >= (SPIDRV_FRAME_SIZE_HALF_WORD + 1u)) + { + if(tRestBitNums > 24u) + { + if(littleEndDian == false) + { + for(i = 0u; i < 4; i++) + { + tDataAligned.byteData[i] = ((uint8_t *)pTxBuffer)[tBufferIdx + 3 - i]; + } + } + else + { + for(i = 0; i < 4u; i++) + { + tDataAligned.byteData[i] = ((uint8_t *)pTxBuffer)[tBufferIdx + i]; + } + } + + tBufferIdx += 4u; + } + else if(tRestBitNums > 16u) + { + if(littleEndDian == false) + { + for(i = 0u; i < 3; i++) + { + tDataAligned.byteData[i] = ((uint8_t *)pTxBuffer)[tBufferIdx + 2 - i]; + } + } + else + { + for(i = 0; i < 3u; i++) + { + tDataAligned.byteData[i] = ((uint8_t *)pTxBuffer)[tBufferIdx + i]; + } + } + + tBufferIdx += 3u; + } + else + { + if(littleEndDian == false) + { + for(i = 0u; i < 2; i++) + { + tDataAligned.byteData[i] = ((uint8_t *)pTxBuffer)[tBufferIdx + 1 - i]; + } + } + else + { + for(i = 0; i < 2u; i++) + { + tDataAligned.byteData[i] = ((uint8_t *)pTxBuffer)[tBufferIdx + i]; + } + } + + tBufferIdx += 2u; + } + + tRestBitNums = 0u; + obj->reg->TDR = tDataAligned.wordData; + } + else if(tRestBitNums >= (SPIDRV_FRAME_SIZE_BYTE + 1u)) + { + if(tRestBitNums > 8u) + { + if(littleEndDian == false) + { + for(i = 0u; i < 2u; i++) + { + tDataAligned.byteData[i] = ((uint8_t *)pTxBuffer)[tBufferIdx + 1 - i]; + } + } + else + { + for(i = 0; i < 2u; i++) + { + tDataAligned.byteData[i] = ((uint8_t *)pTxBuffer)[tBufferIdx + i]; + } + } + + tBufferIdx += 2u; + } + else + { + tDataAligned.byteData[0] = (((uint8_t *)pTxBuffer)[tBufferIdx]); + } + + obj->reg->TDR = tDataAligned.wordData; + tRestBitNums = 0u; + tBufferIdx += 1u; + } + else + { + obj->reg->TDR = (((uint8_t *)pTxBuffer)[tBufferIdx]); + tRestBitNums = 0; + tBufferIdx++; + } + + timeOutCnt = 0; + } + else + { + timeOutCnt++; + } + + } while((tRestBitNums > 0u) && (timeOutCnt < SPIDRV_TX_TIMEOUT_CNT)); + + if(timeOutCnt >= SPIDRV_TX_TIMEOUT_CNT) + { + tRtn = false; + } + + return tRtn; +} + +/*! \brief Async tx data with any length of bits + * + * this function just only fill datas to tx fifo, but not read out datas from rx fifo, the bits num should be multile by 2! + * + * \param[in] obj : pointer to the instance + * \param[in] txBitNums: the nums bits of data to be sent + * \param[in] pBuffer: th pointer of which data to be sent;if in half duplex mode, and the txmask is true, no care about this parameter, + * notice: aligned with 32bits + * \param[in] txMask: tx mask bit + * \param[in] rxMask: rx mask bit + * \param[in] littleEndDian: transfer data flow + * \return: bool + * true: no error + * false: error + */ +bool SpiDrv_AsyncBitsTransfer(SpiDrvType *obj, uint16_t txBitNums, const void *pBuffer, bool txMask, bool rxMask, bool littleEndDian) +{ + bool tRtn = true; + SpiDrv_TcrInfoType tcrInfo; + + tcrInfo = SpiDrv_GetTcrCmdConfig(obj); + tcrInfo.frameBitSize = txBitNums - 1u; + tcrInfo.txMask = txMask; + tcrInfo.rxMask = rxMask; + + SpiDrv_SetTcrCmdConfig(obj, &tcrInfo); + + if(tcrInfo.txMask == false) + { + tRtn = SpiDrv_AsyncBitDataWriteIntoHwTxBuffer(obj, txBitNums, pBuffer, littleEndDian); + } + + return tRtn; +} + +/*! \brief Async bits Received + * + * this function read the datas from rx fifo, and return the bytes nums have been readout. + * Notice: Returns the number of words currently stored in the receive FIFO, may be just one byte in rx fifo, but still return four bytes + * so the total read out bytes number must be more than the actual useful numbers + * + * \param[in] obj : pointer to the instance + * \param[in] pBuffer: th pointer of which data to be stored, Notice: the address must be aligned with word!!!! + * \param[in] littleEndDian: transfer data flow + * \return: the bytes in the rx fifo + */ +uint8_t SpiDrv_AsyncReceive(SpiDrvType *obj, void *pBuffer, bool littleEndDian) +{ + uint8_t retBytesNum = 0; + + if(SpiReg_GetRxFifoEmptyState(obj->reg) == false) + { + uint8_t tRxFifoCnt = 0, tWriteByteIdx = 0; + uint16_t i = 0, y = 0; + SpiDrv_DataAlignedType tDataAligned; + uint32_t frameBitSize = 0; + + /* Read out the number of words currently stored in the receive FIFO. */ + tRxFifoCnt = SpiReg_GetRxFifoCounter(obj->reg); + frameBitSize = SpiReg_GetFrameSize(obj->reg); + + /* the rx fifo counter is aligned with word , so may by just read out less than 4bytes, also return 4bytes! */ + if(frameBitSize > SPIDRV_FRAME_SIZE_HALF_WORD) + { + retBytesNum = tRxFifoCnt << 2; + + for(i = 0; i < tRxFifoCnt; i++) + { + tDataAligned.wordData = obj->reg->RDR; + + if(littleEndDian == true) + { + for(y = 0; y < 4u; y++) + { + ((uint8_t *)pBuffer)[tWriteByteIdx++] = tDataAligned.byteData[y]; + } + } + else + { + for(y = 0; y < 4u; y++) + { + ((uint8_t *)pBuffer)[tWriteByteIdx++] = tDataAligned.byteData[3 - y]; + } + } + } + } + else if(frameBitSize > SPIDRV_FRAME_SIZE_BYTE) + { + retBytesNum = tRxFifoCnt << 1; + + for(i = 0; i < tRxFifoCnt; i++) + { + tDataAligned.wordData = obj->reg->RDR; + + if(littleEndDian == true) + { + for(y = 0; y < 2u; y++) + { + ((uint8_t *)pBuffer)[tWriteByteIdx++] = tDataAligned.byteData[y]; + } + } + else + { + for(y = 0; y < 2u; y++) + { + ((uint8_t *)pBuffer)[tWriteByteIdx++] = tDataAligned.byteData[1 - y]; + } + } + } + } + else + { + retBytesNum = tRxFifoCnt; + + for(i = 0; i < tRxFifoCnt; i++) + { + ((uint8_t *)pBuffer)[tWriteByteIdx++] = obj->reg->RDR; + } + } + } + + return retBytesNum; +} + +/*! \brief Set SPI interrupt config + * + * \param[in] obj : pointer to the instance + * \param[in] isrSrc: interrupt source + * \param[in] enabled: config status + * \return: void + */ +void SpiDrv_SetIsrConfig(SpiDrvType *obj, SpiDrv_IsrSrcType isrSrc, bool enabled) +{ + switch(isrSrc) + { + case SPIDRV_ISR_SRC_TX_DATA: + SpiReg_SetTxDataIsr(obj->reg, enabled); + break; + + case SPIDRV_ISR_SRC_RX_DATA: + SpiReg_SetRxDataIsr(obj->reg, enabled); + break; + + case SPIDRV_ISR_SRC_RX_WORD_DONE: + SpiReg_SetRxWordDoneIsr(obj->reg, enabled); + break; + + case SPIDRV_ISR_SRC_FRAME_DONE: + SpiReg_SetFrameDoneIsr(obj->reg, enabled); + break; + + case SPIDRV_ISR_SRC_MASTER_XFR_DONE: + SpiReg_SetTxTransferDoneIsr(obj->reg, enabled); + break; + + case SPIDRV_ISR_SRC_TX_UF: + SpiReg_SetTxUnderflowIsr(obj->reg, enabled); + break; + + case SPIDRV_ISR_SRC_RX_OF: + SpiReg_SetRxOverflowIsr(obj->reg, enabled); + break; + + default: + break; + } +} + +/*! \brief Get SPI interrupt config + * + * \param[in] obj : pointer to the instance + * \param[in] isrSrc: interrupt source + * \return: config status + */ +bool SpiDrv_GetIsrConfig(SpiDrvType *obj, SpiDrv_IsrSrcType isrSrc) +{ + bool isrCfg = false; + + switch(isrSrc) + { + case SPIDRV_ISR_SRC_TX_DATA: + isrCfg = SpiReg_GetIntReqEnableState(obj->reg, SPI_IER_TX_DATA_IE_MASK); + break; + + case SPIDRV_ISR_SRC_RX_DATA: + isrCfg = SpiReg_GetIntReqEnableState(obj->reg, SPI_IER_RX_DATA_IE_MASK); + break; + + case SPIDRV_ISR_SRC_RX_WORD_DONE: + isrCfg = SpiReg_GetIntReqEnableState(obj->reg, SPI_IER_RX_WORD_DONE_IE_MASK); + break; + + case SPIDRV_ISR_SRC_FRAME_DONE: + isrCfg = SpiReg_GetIntReqEnableState(obj->reg, SPI_IER_FRAME_DONE_IE_MASK); + break; + + case SPIDRV_ISR_SRC_MASTER_XFR_DONE: + isrCfg = SpiReg_GetIntReqEnableState(obj->reg, SPI_IER_MST_TRANSFER_DONE_IE_MASK); + break; + + case SPIDRV_ISR_SRC_TX_UF: + isrCfg = SpiReg_GetIntReqEnableState(obj->reg, SPI_IER_TX_UF_IE_MASK); + break; + + case SPIDRV_ISR_SRC_RX_OF: + isrCfg = SpiReg_GetIntReqEnableState(obj->reg, SPI_IER_RX_OF_IE_MASK); + break; + + default: + break; + } + + return isrCfg; +} + +/*! \brief Set rx fifo water mask + * + * \param[in] obj : pointer to the instance + * \param[in] waterMask: fifo water mask + * \return: void + */ +void SpiDrv_SetRxFifoWaterMask(SpiDrvType *obj, uint8_t waterMask) +{ + SpiReg_SetRxFifoWaterMark(obj->reg, waterMask); +} + +/*! \brief Set tx fifo water mask + * + * \param[in] obj : pointer to the instance + * \param[in] waterMask: fifo water mask + * \return: void + */ +void SpiDrv_SetTxFifoWaterMask(SpiDrvType *obj, uint8_t waterMask) +{ + SpiReg_SetTxFifoWaterMark(obj->reg, waterMask); +} + +/*! \brief Set Clock Polarity + * + * The Clock Polarity field is only updated when PCS negated. + * + * \param[in] pTcr : TCR variable instance + * \param[in] clockPolarity : + * 0b : The inactive state value of SCK is low + * 1b : The inactive state value of SCK is high + * \return: void + */ +void SpiDrv_SetClockPolarity(uint32_t *pTcr, uint8_t clockPolarity) +{ + uint32_t tmp = *pTcr; + + tmp &= ~SPI_TCR_CPOL_MASK; + tmp |= (((uint32_t)(((uint32_t)(clockPolarity)) << SPI_TCR_CPOL_SHIFT)) & SPI_TCR_CPOL_MASK); + *pTcr = tmp; +} + +/*! \brief Set Clock Phase + * + * The Clock Phase field is only updated when PCS negated. + * + * \param[in] pTcr : TCR variable instance + * \param[in] clockPhase : + * 0b : Data is captured on the leading edge of SCK and changed on the following edge of SCK + * 1b : Data is changed on the leading edge of SCK and captured on the following edge of SCK + * \return: void + */ +void SpiDrv_SetClockPhase(uint32_t *pTcr, uint8_t clockPhase) +{ + uint32_t tmp = *pTcr; + + tmp &= ~SPI_TCR_CPHA_MASK; + tmp |= (((uint32_t)(((uint32_t)(clockPhase)) << SPI_TCR_CPHA_SHIFT)) & SPI_TCR_CPHA_MASK); + *pTcr = tmp; +} + +/*! \brief Set Prescaler Value + * + * For all SPI bus transfers, the Prescaler value applied to the clock configuration register. The Prescaler Value field is only updated when PCS negated. + * + * \param[in] pTcr : TCR variable instance + * \param[in] prescaler : + * 000b : Divide by 1 + * 001b : Divide by 2 + * 010b : Divide by 4 + * 011b : Divide by 8 + * 100b : Divide by 16 + * 101b : Divide by 32 + * 110b : Divide by 64 + * 111b : Divide by 128 + * \return: void + */ +void SpiDrv_SetPrescaler(uint32_t *pTcr, uint8_t prescaler) +{ + uint32_t tmp = *pTcr; + + tmp &= ~SPI_TCR_PRESCALER_MASK; + tmp |= (((uint32_t)(((uint32_t)(prescaler)) << SPI_TCR_PRESCALER_SHIFT)) & SPI_TCR_PRESCALER_MASK); + *pTcr = tmp; +} + +/*! \brief Select Peripheral Chip + * + * Configures the peripheral chip select used for the transfer. The Peripheral Chip Select field is only updated when PCS negated. + * + * \param[in] pTcr : TCR variable instance + * \param[in] pcsSelection : + * 00b : Transfer using SPI_PCS[0] + * 01b : Transfer using SPI_PCS[1] + * 10b : Transfer using SPI_PCS[2] + * 11b : Transfer using SPI_PCS[3] + * \return: void + */ +void SpiDrv_SetPcsSelection(uint32_t *pTcr, uint8_t pcsSelection) +{ + uint32_t tmp = *pTcr; + + tmp &= ~SPI_TCR_PCS_SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(pcsSelection)) << SPI_TCR_PCS_SEL_SHIFT)) & SPI_TCR_PCS_SEL_MASK); + *pTcr = tmp; +} + +/*! \brief Set data transfer direction + * + * + * + * \param[in] pTcr : TCR variable instance + * \param[in] lsbFirst : + * 0b:Data is transferred MSB first + * 1b:Data is transferred LSB first + * \return: void + */ +void SpiDrv_SetLowBitFirstTransfer(uint32_t *pTcr, uint8_t lsbFirst) +{ + uint32_t tmp = *pTcr; + + tmp &= ~SPI_TCR_LSB_FIRST_MASK; + tmp |= (((uint32_t)(((uint32_t)(lsbFirst)) << SPI_TCR_LSB_FIRST_SHIFT)) & SPI_TCR_LSB_FIRST_MASK); + *pTcr = tmp; +} + +/*! \brief Set Byte Swap + * + * Byte swap will swap the contents of [31:24] with [7:0] and [23:16] with [15:8] for each transmit data word read from + * the FIFO and for each received data word stored to the FIFO + * + * \param[in] pTcr : TCR variable instance + * \param[in] enable : + * 0b:Byte swap is disabled + * 1b:Byte swap is enabled + * \return: void + */ +void SpiDrv_SetByteSwap(uint32_t *pTcr, bool enable) +{ + uint32_t tRegValue = *pTcr; + + if(enable == true) + { + *pTcr = ((1ul << SPI_TCR_BYTE_SWAP_SHIFT) | ((~SPI_TCR_BYTE_SWAP_MASK) & tRegValue)); + } + else + { + *pTcr = ((0ul << SPI_TCR_BYTE_SWAP_SHIFT) | ((~SPI_TCR_BYTE_SWAP_MASK) & tRegValue)); + } +} + +/*! \brief Set Continuous Transfer + * + * In master mode, continuous transfer will keep the PCS asserted at the end of the frame size, + * until a command word is received that starts a new frame. + * In slave mode, when continuous transfer is enabled, the SPI will only transmit the first FRAMESZ bits; + * after which the SPI will transmit received data (assuming a 32-bit shift register) until the next PCS negation. + * + * \param[in] pTcr : TCR variable instance + * \param[in] enable : + * 0b:Continuous transfer is disabled + * 1b:Continuous transfer is enabled + * \return: void + */ +void SpiDrv_SetContinuousTransfer(uint32_t *pTcr, bool enable) +{ + uint32_t tRegValue = *pTcr; + + if(enable == true) + { + *pTcr = ((1ul << SPI_TCR_CONTINUE_TRANSFER_SHIFT) | ((~SPI_TCR_CONTINUE_TRANSFER_MASK) & tRegValue)); + } + else + { + *pTcr = ((0ul << SPI_TCR_CONTINUE_TRANSFER_SHIFT) | ((~SPI_TCR_CONTINUE_TRANSFER_MASK) & tRegValue)); + } +} + +/*! \brief Set Continuing Command + * + * In master mode, the Continuing Command bit allows the command word to be changed within a transfer. + * 1. in continuous transfer + * - the initial command word must enable continuous transfer (CONT=1), + * - the continuing command must set this bit (CONTC=1), + * - the continuing command word must be loaded on a frame size boundary. + * 2. in non-continuous transfer + * - the continuing command must set this bit (CONTC=1), + * - the continuing command word must be loaded on a frame size boundary. + * + * \param[in] pTcr : TCR variable instance + * \param[in] cmd : + * 0b:Command word for start of new transfer + * 1b:Command word for continuing transfer + * \return: void + */ +void SpiDrv_SetContinuousCmd(uint32_t *pTcr, uint8_t cmd) +{ + uint32_t tmp = *pTcr; + + tmp &= ~SPI_TCR_CONTINUE_CMD_MASK; + tmp |= (((uint32_t)(((uint32_t)(cmd)) << SPI_TCR_CONTINUE_CMD_SHIFT)) & SPI_TCR_CONTINUE_CMD_MASK); + *pTcr = tmp; +} + +/*! \brief Set Receive Data Mask + * + * When set, receive data is masked (receive data is not stored in receive FIFO). + * + * \param[in] pTcr : TCR variable instance + * \param[in] enableMask : + * 0b:Normal transfer + * 1b:Receive data is masked + * \return: void + */ +void SpiDrv_SetRxDataMask(uint32_t *pTcr, bool enableMask) +{ + uint32_t tRegValue = *pTcr; + + if(enableMask == true) + { + *pTcr = ((1ul << SPI_TCR_RX_MASK_SHIFT) | ((~SPI_TCR_RX_MASK_MASK) & tRegValue)); + } + else + { + *pTcr = ((0ul << SPI_TCR_RX_MASK_SHIFT) | ((~SPI_TCR_RX_MASK_MASK) & tRegValue)); + } +} + +/*! \brief Set Transmit Data Mask + * + * When set, transmit data is masked (no data is loaded from transmit FIFO and output pin is tristated). + * In master mode, the Transmit Data Mask bit will initiate a new transfer + * which cannot be aborted by another command word; TXMSK bit will be cleared by hardware at the end of the transfer. + * + * \param[in] pTcr : TCR variable instance + * \param[in] enableMask : + * 0b:Normal transfer + * 1b:Mask transmit data + * \return: void + */ +void SpiDrv_SetTxDataMask(uint32_t *pTcr, bool enableMask) +{ + uint32_t tRegValue = *pTcr; + + if(enableMask == true) + { + *pTcr = ((1ul << SPI_TCR_TX_MASK_SHIFT) | ((~SPI_TCR_TX_MASK_MASK) & tRegValue)); + } + else + { + *pTcr = ((0ul << SPI_TCR_TX_MASK_SHIFT) | ((~SPI_TCR_TX_MASK_MASK) & tRegValue)); + } +} + +/*! \brief Set Transfer data Width + * + * Configures between serial (1-bit) or parallel transfers. For half-duplex parallel transfers, either Receive Data Mask (RXMSK) or Transmit Data Mask (TXMSK) must be set. + * + * \param[in] pTcr : TCR variable instance + * \param[in] transferWidth : + * 00b:1 bit transfer + * 01b:2 bit transfer + * 10b:Reserved + * 11b:Reserved + * \return: void + */ +void SpiDrv_SetTransferWidth(uint32_t *pTcr, uint8_t transferWidth) +{ + uint32_t tmp = *pTcr; + + tmp &= ~SPI_TCR_TRANSFER_WIDTH_MASK; + tmp |= (((uint32_t)(((uint32_t)(transferWidth)) << SPI_TCR_TRANSFER_WIDTH_SHIFT)) & SPI_TCR_TRANSFER_WIDTH_MASK); + *pTcr = tmp; +} + +/*! \brief Set Frame Size + * + * The minimum frame size is 8 bits, The minimum word size is 2 bits; a frame size of 33 bits (or similar) is not supported. + * If the frame size is larger than 32 bits, then the frame is divided into multiple words of 32-bits; + * each word is loaded from the transmit FIFO and stored in the receive FIFO separately. + * If the size of the frame is not divisible by 32, then the last load of the transmit FIFO and store of the receive FIFO will contain the remainder bits. + * For example, a 72-bit transfer will consist of 3 words: the 1st and 2nd words are 32 bits, and the 3rd word is 8 bits. + * + * \param[in] pTcr : TCR variable instance + * \param[in] frameSize :Configures the frame size in number of bits equal to (FRAMESZ + 1) + * \return: void + */ +void SpiDrv_SetFrameSize(uint32_t *pTcr, uint16_t frameSize) +{ + uint32_t tmp = *pTcr; + + tmp &= ~SPI_TCR_FRAME_SIZE_MASK; + tmp |= (((uint32_t)(((uint32_t)(frameSize)) << SPI_TCR_FRAME_SIZE_SHIFT)) & SPI_TCR_FRAME_SIZE_MASK); + *pTcr = tmp; +} + +/*! \brief Transmit Command config + * + * this function config the clock polarity, clock phase prescaler value and transfer mode .... + * + * \param[in] obj: pointer to the instance + * \param[in] tcr: Transmit Command + * \return: void + */ +void SpiDrv_SetTcr(SpiDrvType *obj, uint32_t tcr) +{ + SpiReg_SetTcr(obj->reg, tcr); +} + +/*! \brief Get Transmit Command config + * + * this function config get the clock polarity, clock phase prescaler value and transfer mode .... + * + * \param[in] obj: pointer to the instance + * \return: Transmit Command + */ +uint32_t SpiDrv_GetTcr(const SpiDrvType *obj) +{ + return SpiReg_GetTcr(obj->reg); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/spi/spi_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/spi/spi_drv.h new file mode 100644 index 0000000..18a9eb4 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/spi/spi_drv.h @@ -0,0 +1,764 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _SPI_DRV_H_ +#define _SPI_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of SPI module + */ + +/****************************************************************************** + * the includes + *****************************************************************************/ + +#include +#include +#include "spi_reg.h" + +/*! \addtogroup spi_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * the defines + *****************************************************************************/ + +#define SPIDRV_ONE_FRAME_BITS_MAX_NUM (32u) +#define SPIDRV_TX_FIFO_SIZE (16u) +#define SPIDRV_RX_FIFO_IN_WORD_SIZE (16u) +#define SPIDRV_TX_TIMEOUT_CNT (1000u) + +/****************************************************************************** + * the typedefs + *****************************************************************************/ + +/*! \brief SPI Peripheral Chip Select (PCS) configuration (which PCS to configure).*/ +typedef enum +{ + SPIDRV_PCS_SEL_PCS0 = 0u, + SPIDRV_PCS_SEL_PCS1, + SPIDRV_PCS_SEL_PCS2, + SPIDRV_PCS_SEL_PCS3, + + SPIDRV_PCS_SEL_NUM +} SpiDrv_PcsSelType; + +/*! \brief SPI Signal (PCS and Host Request) Polarity configuration.*/ +typedef enum +{ + SPIDRV_PCS_POLARITY_ACTIVE_LOW = 0u, + SPIDRV_PCS_POLARITY_ACTIVE_HIGH, + + SPIDRV_PCS_POLARITY_NUM +} SpiDrv_PcsPolarityType; + +/*! \brief SPI clock phase configuration.*/ +typedef enum +{ + SPIDRV_CLK_PHASE_DATA_SAMPLE_ON_LEADING_EDGE = 0u, + SPIDRV_CLK_PHASE_DATA_SAMPLE_ON_TRAILING_EDGE, + + SPIDRV_CLK_PHASE_NUM +} SpiDrv_ClockPhaseType; + +/*! \brief SPI Clock Signal (SCK) Polarity configuration. */ +typedef enum +{ + SPIDRV_CLK_POLARITY_IDLE_IN_LOW = 0u, + SPIDRV_CLK_POLARITY_IDLE_IN_HIGH, + + SPIDRV_CLK_POLARITY_NUM +} SpiDrv_ClockPolarityType; + +/*! \brief SPI Duplex mode selection */ +typedef enum +{ + SPIDRV_DUPLEX_HALF_DUPLEX_IN_SINGLE_LINE = 0u, + SPIDRV_DUPLEX_HALF_DUPLEX_IN_DOUBLE_LINE, + SPIDRV_DUPLEX_FULL_DUPLEX, + SPIDRV_DUPLEX_NUM +} SpiDrv_DuplexType; + +/*! \brief SPI data shift direction */ +typedef enum +{ + SPIDRV_SHIFT_FIRST_BIT_MSB = 0u, + SPIDRV_SHIFT_FIRST_BIT_LSB, + + SPIDRV_SHIFT_FIRST_BIT_NUM +} SpiDrv_ShiftFirstBitType; + +/*! \brief SPI communication duplex pin configuration */ +typedef enum +{ + SPIDRV_PIN_CFG_SIN_IN_SOUT_OUT = 0u, + SPIDRV_PIN_CFG_HALF_DUPLEX_SIN, + SPIDRV_PIN_CFG_HALF_DUPLEX_SOUT, + SPIDRV_PIN_CFG_SIN_OUT_SOUT_IN, + + SPIDRV_PIN_CFG_NUM +} SpiDrv_PinCfgType; + +/*! \brief SPI pin out level after transmit */ +typedef enum +{ + SPIDRV_OUTCFG_IN_OLD_VALUE = 0u, + SPIDRV_OUTCFG_IN_TRISTATE, + + SPIDRV_OUTCFG_NUM +} SpiDrv_OutCfgType; + +/*! \brief SPI Frame size bit width */ +typedef enum +{ + SPIDRV_FRAME_SIZE_BYTE = 7u, + SPIDRV_FRAME_SIZE_HALF_WORD = 15u, + SPIDRV_FRAME_SIZE_WORD = 31u +} SpiDrv_FrameSizeType; + +/*! \brief SPI Frame size type */ +typedef enum +{ + SPIDRV_FRAME_SIZE_BIT_TYPE_BYTE = 1u, + SPIDRV_FRAME_SIZE_BIT_TYPE_HALF_WORD = 2u, + SPIDRV_FRAME_SIZE_BIT_TYPE_WORD = 4u +} SpiDrv_FrameSizeBitType; + +/*! \brief SPI Frame type selection */ +typedef enum +{ + SPIDRV_FRAME_TRANSFER_SHORT_FRAME = 0u, + SPIDRV_FRAME_TRANSFER_LONG_FRAME, + SPIDRV_FRAME_TRANSFER_MULTI_FRAME +} SpiDrv_FrameTransferType; + +/*! \brief Interrupt source */ +typedef enum +{ + SPIDRV_ISR_SRC_TX_DATA = 0x01ul, + SPIDRV_ISR_SRC_RX_DATA = 0x02ul, + SPIDRV_ISR_SRC_RX_WORD_DONE = 0x100ul, + SPIDRV_ISR_SRC_FRAME_DONE = 0x200ul, + SPIDRV_ISR_SRC_MASTER_XFR_DONE = 0x400ul, + SPIDRV_ISR_SRC_TX_UF = 0x800ul, + SPIDRV_ISR_SRC_RX_OF = 0x1000ul, + + SPIDRV_ISR_SRC_ALL = 0xFFFFFFFF +} SpiDrv_IsrSrcType; + +/*! \brief Status flag */ +typedef enum +{ + SPIDRV_STATUS_TX_DATA = 0x01ul, + SPIDRV_STATUS_RX_DATA = 0x02ul, + SPIDRV_STATUS_RX_WORD_DONE = 0x100ul, + SPIDRV_STATUS_FRAME_DONE = 0x200ul, + SPIDRV_STATUS_XFR_DONE = 0x400ul, + SPIDRV_STATUS_TX_UF = 0x800ul, + SPIDRV_STATUS_RX_OF = 0x1000ul, + SPIDRV_STATUS_BUSY = 0x1000000ul, + SPIDRV_STATUS_ALL = 0x1FFFFFFul +} SpiDrv_StatusType; + +/*! \brief golden section information diff table */ +typedef struct _SpiDrv_CalculateTblType_ +{ + uint32_t diff; + uint16_t div; + uint8_t prescalerIdx; +} SpiDrv_CalculateTblType; + +/*! \brief golden section information */ +typedef struct +{ + uint32_t freqInput; + uint32_t freqTargetOut; + uint32_t bestOutPrescaler; + uint32_t bestOutDiv; + uint32_t bestOutFreq; +} SpiDrv_GoldenSectionInfoType; + +/*! \brief data aligned union */ +typedef union _SpiDrv_DataAlignedType_ +{ + uint8_t byteData[4]; + uint16_t halfWordData[2]; + uint32_t wordData; +} SpiDrv_DataAlignedType; + +/*! \brief TCR information */ +typedef struct _SpiDrv_TcrInfoType_ +{ + SpiDrv_ClockPhaseType clockPhase; + SpiDrv_ClockPolarityType clockPolarity; + SpiDrv_PcsSelType pcsSelection; + SpiDrv_ShiftFirstBitType dataShiftFirstBit; + uint16_t frameBitSize; + uint8_t transferWidth; + uint8_t prescaler; + bool txMask; + bool rxMask; + bool byteSwap; + bool continuousTransfer; + bool continuousCmd; +} SpiDrv_TcrInfoType; + +/*! \brief SPI basic parameter information */ +typedef struct _SpiDrv_BasicParametersType_ +{ + uint32_t busClockFreq; + uint32_t baudRate; + bool isMasterNode; + SpiDrv_ClockPhaseType clockPhase; + SpiDrv_ClockPolarityType clockPolarity; + SpiDrv_PcsSelType pcsSelection; + SpiDrv_PcsPolarityType pcsPolarity; + SpiDrv_ShiftFirstBitType dataShiftFirstBit; + uint16_t frameBitSize; +} SpiDrv_BasicParametersType; + +/*! \brief SPI extend parameter inoformation */ +typedef struct _SpiDrv_ExtendParametersType_ +{ + SpiDrv_DuplexType duplexType; + uint8_t delayBetweenTransfer; + uint8_t delayFromPcsToSck; + uint8_t delayFromSckToPcs; + uint8_t masterSampleSckDelay; + SpiDrv_PinCfgType pinCfg; + SpiDrv_OutCfgType outCfg; +} SpiDrv_ExtendParametersType; + +/*! \brief SPI extend feature information */ +typedef struct _SpiDrv_ExtendFeaturesType_ +{ + bool dmaTxEn; + bool dmaRxEn; + bool noStallEn; + bool circularFifoEn; + bool byteSwapEn; + bool slaveAutoPcsEn; + bool dbgEn; + bool stopEn; + bool rxMaskEn; + bool txMaskEn; +} SpiDrv_ExtendFeaturesType; + +/*! \brief SPI Isr access information */ +typedef struct _SpiDrv_IsrAccessType_ +{ + uint8_t txWatermark; + uint8_t rxWatermark; + bool rxdataIsrEnable; + bool txdataIsrEnable; + bool rxWordDoneIsrEnable; + bool frameDoneIsrEnable; + bool masterTransferDoneIsrEnable; + bool rxOfIsrEnable; + bool txUfIsrEnable; +} SpiDrv_IsrAccessType; + +/*! \brief SPI initialize configuration information */ +typedef struct _SpiDrv_InitCfgType_ +{ + SpiDrv_BasicParametersType basicParameters; + SpiDrv_ExtendParametersType extendParameters; + SpiDrv_ExtendFeaturesType extendFeatures; +} SpiDrv_InitCfgType; + +/*! \brief SPI instance pointer */ +typedef struct _SpiDrvType_ +{ + SpiRegType *reg; +} SpiDrvType; + +/****************************************************************************** + * the globals + *****************************************************************************/ + +/****************************************************************************** + * the function prototypes + *****************************************************************************/ + +/*! \brief Set Clock Polarity + * + * The Clock Polarity field is only updated when PCS negated. + * + * \param[in] pTcr : TCR variable instance + * \param[in] clockPolarity : + * 0b : The inactive state value of SCK is low + * 1b : The inactive state value of SCK is high + * \return: void + */ +extern void SpiDrv_SetClockPolarity(uint32_t *pTcr, uint8_t clockPolarity); + +/*! \brief Set Clock Phase + * + * The Clock Phase field is only updated when PCS negated. + * + * \param[in] pTcr : TCR variable instance + * \param[in] clockPhase : + * 0b : Data is captured on the leading edge of SCK and changed on the following edge of SCK + * 1b : Data is changed on the leading edge of SCK and captured on the following edge of SCK + * \return: void + */ +extern void SpiDrv_SetClockPhase(uint32_t *pTcr, uint8_t clockPhase); + +/*! \brief Set Prescaler Value + * + * For all SPI bus transfers, the Prescaler value applied to the clock configuration register. The Prescaler Value field is only updated when PCS negated. + * + * \param[in] pTcr : TCR variable instance + * \param[in] prescaler : + * 000b : Divide by 1 + * 001b : Divide by 2 + * 010b : Divide by 4 + * 011b : Divide by 8 + * 100b : Divide by 16 + * 101b : Divide by 32 + * 110b : Divide by 64 + * 111b : Divide by 128 + * \return: void + */ +extern void SpiDrv_SetPrescaler(uint32_t *pTcr, uint8_t prescaler); + +/*! \brief Select Peripheral Chip + * + * Configures the peripheral chip select used for the transfer. The Peripheral Chip Select field is only updated when PCS negated. + * + * \param[in] pTcr : TCR variable instance + * \param[in] pcsSelection : + * 00b : Transfer using SPI_PCS[0] + * 01b : Transfer using SPI_PCS[1] + * 10b : Transfer using SPI_PCS[2] + * 11b : Transfer using SPI_PCS[3] + * \return: void + */ +extern void SpiDrv_SetPcsSelection(uint32_t *pTcr, uint8_t pcsSelection); + +/*! \brief Set data transfer direction + * + * + * + * \param[in] pTcr : TCR variable instance + * \param[in] lsbFirst : + * 0b:Data is transferred MSB first + * 1b:Data is transferred LSB first + * \return: void + */ +extern void SpiDrv_SetLowBitFirstTransfer(uint32_t *pTcr, uint8_t lsbFirst); + +/*! \brief Set Byte Swap + * + * Byte swap will swap the contents of [31:24] with [7:0] and [23:16] with [15:8] for each transmit data word read from + * the FIFO and for each received data word stored to the FIFO + * + * \param[in] pTcr : TCR variable instance + * \param[in] enable : + * 0b:Byte swap is disabled + * 1b:Byte swap is enabled + * \return: void + */ +extern void SpiDrv_SetByteSwap(uint32_t *pTcr, bool enable); + +/*! \brief Set Continuous Transfer + * + * In master mode, continuous transfer will keep the PCS asserted at the end of the frame size, + * until a command word is received that starts a new frame. + * In slave mode, when continuous transfer is enabled, the SPI will only transmit the first FRAMESZ bits; + * after which the SPI will transmit received data (assuming a 32-bit shift register) until the next PCS negation. + * + * \param[in] pTcr : TCR variable instance + * \param[in] enable : + * 0b:Continuous transfer is disabled + * 1b:Continuous transfer is enabled + * \return: void + */ +extern void SpiDrv_SetContinuousTransfer(uint32_t *pTcr, bool enable); + +/*! \brief Set Continuing Command + * + * In master mode, the Continuing Command bit allows the command word to be changed within a transfer. + * 1. in continuous transfer + * - the initial command word must enable continuous transfer (CONT=1), + * - the continuing command must set this bit (CONTC=1), + * - the continuing command word must be loaded on a frame size boundary. + * 2. in non-continuous transfer + * - the continuing command must set this bit (CONTC=1), + * - the continuing command word must be loaded on a frame size boundary. + * + * \param[in] pTcr : TCR variable instance + * \param[in] cmd : + * 0b:Command word for start of new transfer + * 1b:Command word for continuing transfer + * \return: void + */ +extern void SpiDrv_SetContinuousCmd(uint32_t *pTcr, uint8_t cmd); + +/*! \brief Set Receive Data Mask + * + * When set, receive data is masked (receive data is not stored in receive FIFO). + * + * \param[in] pTcr : TCR variable instance + * \param[in] enableMask : + * 0b:Normal transfer + * 1b:Receive data is masked + * \return: void + */ +extern void SpiDrv_SetRxDataMask(uint32_t *pTcr, bool enableMask); + +/*! \brief Set Transmit Data Mask + * + * When set, transmit data is masked (no data is loaded from transmit FIFO and output pin is tristated). + * In master mode, the Transmit Data Mask bit will initiate a new transfer + * which cannot be aborted by another command word; TXMSK bit will be cleared by hardware at the end of the transfer. + * + * \param[in] pTcr : TCR variable instance + * \param[in] enableMask : + * 0b:Normal transfer + * 1b:Mask transmit data + * \return: void + */ +extern void SpiDrv_SetTxDataMask(uint32_t *pTcr, bool enableMask); + +/*! \brief Set Transfer data Width + * + * Configures between serial (1-bit) or parallel transfers. For half-duplex parallel transfers, either Receive Data Mask (RXMSK) or Transmit Data Mask (TXMSK) must be set. + * + * \param[in] pTcr : TCR variable instance + * \param[in] transferWidth : + * 00b:1 bit transfer + * 01b:2 bit transfer + * 10b:Reserved + * 11b:Reserved + * \return: void + */ +extern void SpiDrv_SetTransferWidth(uint32_t *pTcr, uint8_t transferWidth); + +/*! \brief Set Frame Size + * + * The minimum frame size is 8 bits, The minimum word size is 2 bits; a frame size of 33 bits (or similar) is not supported. + * If the frame size is larger than 32 bits, then the frame is divided into multiple words of 32-bits; + * each word is loaded from the transmit FIFO and stored in the receive FIFO separately. + * If the size of the frame is not divisible by 32, then the last load of the transmit FIFO and store of the receive FIFO will contain the remainder bits. + * For example, a 72-bit transfer will consist of 3 words: the 1st and 2nd words are 32 bits, and the 3rd word is 8 bits. + * + * \param[in] pTcr : TCR variable instance + * \param[in] frameSize :Configures the frame size in number of bits equal to (FRAMESZ + 1) + * \return: void + */ +extern void SpiDrv_SetFrameSize(uint32_t *pTcr, uint16_t frameSize); + +/*! \brief Transmit Command config + * + * this function config the clock polarity, clock phase prescaler value and transfer mode .... + * + * \param[in] obj: pointer to the instance + * \param[in] tcr: Transmit Command + * \return: void + */ +extern void SpiDrv_SetTcr(SpiDrvType *obj, uint32_t tcr); + +/*! \brief Get Transmit Command config + * + * this function config get the clock polarity, clock phase prescaler value and transfer mode .... + * + * \param[in] obj: pointer to the instance + * \return: Transmit Command + */ +extern uint32_t SpiDrv_GetTcr(const SpiDrvType *obj); + +/*! \brief Get default configures the module for configuration structure + * + * This function gets default configures the module for user configuration structure + * + * \param[out] pInitCfg :pointer to configuration structure + * \return: void + */ +extern void SpiDrv_GetDefaultConfig(SpiDrv_InitCfgType *pInitCfg); + +/*! \brief Set the spi module parameters include basic&extend features + * + * this function initializes the run-time state structure to provide for module configuration + * + * \param[in] obj : pointer to the instance + * \param[in] - const SpiDrv_InitCfgType * const pInitCfg: the pointer to the user configuration + * \return: void + */ +extern void SpiDrv_SetConfig(SpiDrvType *obj, const SpiDrv_InitCfgType *pInitCfg); + +/*! \brief Resets the SPI internal logic and registers to their default settings + * + * this function instance an object and reset module + * + * \param[in/out] : pointer to the instance + * \param[in] pReg : the phycial module base address pointer + * \return: void + */ +extern void SpiDrv_Init(SpiDrvType *obj, SpiRegType *pReg); + +/*! \brief Set the module to special condition + * + * call back in the usage of Low power or sleep requirements + * + * \param[in] obj : pointer to the instance + * \return: void + */ +extern void SpiDrv_DeInit(SpiDrvType *obj); + +/*! \brief Get the status of the SpiDrv_StatusType of event + * + * this function read out the special status what want to be read + * + * \param[in] obj : pointer to the instance + * \param[in] status : which status to be read out + * \return: bool + * true: The status is exist + * false: The status is not exist + */ +extern bool SpiDrv_GetStatus(const SpiDrvType *obj, SpiDrv_StatusType status); + +/*! \brief Clear the status + * + * this function clear the special status falg + * + * \param[in] obj : pointer to the instance + * \param[in] status : combination of any SpiDrv_StatusType event + * example: status = (SPIDRV_STATUS_RX_WORD_DONE | SPIDRV_STATUS_FRAME_DONE) + * \return: void + */ +extern void SpiDrv_ClearStatus(SpiDrvType *obj, uint32_t status); + +/*! \brief Set the link route function in the slave node with byte transfer + * + * this function is used for slave node to link transfer from master to other node with bytes + * + * \param[in] obj : pointer to the instance + * \param[in] txBytesCnt: the data bytes to be sent + * \param[in] pTxByteBuffer: pointer to the tx data byte buffer + * the tx data will fill or not by special requirement + * \return: void + */ +extern void SpiDrv_SlaveAsyncLinkTransferBytes(SpiDrvType *obj, uint16_t txBytesCnt, const uint8_t *pTxByteBuffer); + +/*! \brief Set the link route function in the slave node with halfword transfer + * + * this function is used for slave node to link transfer from master to other node with halfwords + * + * \param[in] obj : pointer to the instance + * \param[in] txHalfWordsCnt: the data halfwords to be sent + * \param[in] pTxHalfWordBuffer: pointer to the tx data halfword buffer + * the tx data will fill or not by special requirement + * \return: void + */ +extern void SpiDrv_SlaveAsyncLinkTransferHalfWords(SpiDrvType *obj, uint16_t txHalfWordsCnt, const uint16_t *pTxHalfWordBuffer); + +/*! \brief Set the link route function in the slave node with word transfer + * + * this function is used for slave node to link transfer from master to other node with words + * + * \param[in] obj : pointer to the instance + * \param[in] txWodsCnt: the data words to be sent + * \param[in] pTxWordBuffer: pointer to the tx data word buffer + * the tx data will fill or not by special requirement + * \return: void + */ +extern void SpiDrv_SlaveAsyncLinkTransferWords(SpiDrvType *obj, uint16_t txWodsCnt, const uint32_t *pTxWordBuffer); + +/*! \brief Set Transmit Command Register configuration + * + * Any writes to the TCR will cause the entire TCR contents to be pushed to the TX FIFO. + * Therefore any updates to the TCR should include updates to all of the register + * bit fields to form a 32-bit write to the TCR. + * + * \param[in] obj : pointer to the instance + * \param[in] pTcrInfo : Transmit Command Register configuration structure + * \return void + */ +extern void SpiDrv_SetTcrCmdConfig(SpiDrvType *obj, const SpiDrv_TcrInfoType *pTcrInfo); + +/*! \brief Get Transmit Command Register configuration structure + * + * This function get the current tcr register value + * + * \param[in] obj : pointer to the instance + * \return: Transmit Command Register configuration structure + */ +extern SpiDrv_TcrInfoType SpiDrv_GetTcrCmdConfig(const SpiDrvType *obj); + +/*! \brief Send one short frame each frame bits numbers is equal to or less than 32bits, every time hard set pcs signal again + * the DBT feature is valid + * _____ DATA (DBT) _________ DATA(DBT) __________ + * PCS |_____________| |_____________| + * + * \param[in] obj : pointer to the instance + * \param[in] txData:data to be sent + * \param[in] frameSizeBitType:the frame bit width(8bit/16bit/32bit) to describe the pTxBuffer data width type + * \return: bool + * true: no err + * false: no enough space for the current tx requirement + */ +extern bool SpiDrv_AsyncSingleFrameTransfer(SpiDrvType *obj, uint32_t txData, SpiDrv_FrameSizeBitType frameSizeBitType); + +/*! \brief Send more than 32bits frame one time, the DBT feature is invalid + * + * _____ DATA DATA DATA DATA __________ + * PCS |_____________________| + * + * \param[in] obj : pointer to the instance + * \param[in] txFrameNums: the nums data to be sent + * \param[in] pTxBuffer: th pointer of which data to be sent + * \param[in] frameSizeBitType:the frame bit width(8bit/16bit/32bit) to describe the pTxBuffer data width type + * \param[in] littleEndDian: transfer byte turn + * \return: bool + * true: no err + * false: no enough space for the current tx requirement + */ +extern bool SpiDrv_AsyncLongFrameTransfer(SpiDrvType *obj, uint16_t txFrameNums, const void *pTxBuffer, SpiDrv_FrameSizeBitType frameSizeBitType, bool littleEndDian); + +/*! \brief continue Send constinues frame,each frame bits numbers is equal to or less than 32bits + * the DBT feature is valid + * _____ DATA(xbits) (DBT) DATA(xBits)__________ + * PCS |_______________________________| + * + * \param[in] obj : pointer to the instance + * \param[in] txFrameNums: the nums data to be sent + * \param[in] pTxBuffer: th pointer of which data to be sent + * \param[in] frameSizeBitType:the frame bit width(8bit/16bit/32bit) to describe the pTxBuffer data width type + * \return: bool + * true: no err + * false: no enough space for the current tx requirement + */ +extern bool SpiDrv_AsyncContinueFrameTransfer(SpiDrvType *obj, uint16_t txFrameNums, const void *pTxBuffer, SpiDrv_FrameSizeBitType frameSizeBitType); + +/*! \brief Async bit data write to hardware tx data buffer + * + * this function just only fill datas to tx fifo, but not read out datas from rx fifo + * + * \param[in] obj : pointer to the instance + * \param[in] txBitNums: the tx data bits numbers to be write + * \param[in] pTxBuffer: write data buffer , notice: aligned with 32bits + * \param[in] littleEndDian: write bit flow turn + * \return: bool + * false: error + * true: no error + */ +extern bool SpiDrv_AsyncBitDataWriteIntoHwTxBuffer(SpiDrvType *obj, uint16_t txBitNums, const void *pTxBuffer, bool littleEndDian); + +/*! \brief Master Async tx data with any length of bits + * + * this function just only fill datas to tx fifo, but not read out datas from rx fifo, the bits num should be multile by 2! + * + * \param[in] obj : pointer to the instance + * \param[in] txBitNums: the nums bits of data to be sent + * \param[in] pBuffer: th pointer of which data to be sent;if in half duplex mode, and the txmask is true, no care about this parameter, + * notice: aligned with 32bits + * \param[in] txMask: tx mask bit + * \param[in] rxMask: rx mask bit + * \param[in] littleEndDian: transfer data flow + * \return: bool + * true: no error + * false: error + */ +extern bool SpiDrv_AsyncBitsTransfer(SpiDrvType *obj, uint16_t txBitNums, const void *pBuffer, bool txMask, bool rxMask, bool littleEndDian); + +/*! \brief Async bits Received + * + * this function read the datas from rx fifo, and return the bytes nums have been readout. + * Notice: Returns the number of words currently stored in the receive FIFO, may be just one byte in rx fifo, but still return four bytes + * so the total read out bytes number must be more than the actual useful numbers + * + * \param[in] obj : pointer to the instance + * \param[in] pBuffer: th pointer of which data to be stored, Notice: the address must be aligned with word!!!! + * \param[in] littleEndDian: transfer data flow + * \return: the bytes in the rx fifo + */ +extern uint8_t SpiDrv_AsyncReceive(SpiDrvType *obj, void *pBuffer, bool littleEndDian); + +/*! \brief Master Sync tx data, sent and received data from other node + * + * _____ DATA DATA DATA DATA __________ + * PCS |_____________________| + * + * \param[in] obj : pointer to the instance + * \param[in] frameSizeBitType: the data width to describe the pTxBuffer + * \param[in] txFrameNums: the nums data to be sent + * \param[in] pTxBuffer: the transmit data buffer pointer + * \param[in] pRxBuffer: the pointer for the read-out datas + * \return: bool + * false: the current tx fifo is full, no enough space for this transmit + * true: no error + */ +extern bool SpiDrv_MasterSyncTransfer(SpiDrvType *obj, SpiDrv_FrameSizeBitType frameSizeBitType, uint16_t txFrameNums, const void *pTxBuffer, void *pRxBuffer); + +/*! \brief Set Slave rx fifo water mark + * + * the max water mark is must less than the supported depth + * + * \param[in] obj : pointer to the instance + * \param[in] txFrameNums: the tx frame to be sent + * \param[in] frameSizeBitType: frame bit width(8bit/16bit/32bit) + * \return: bool + * false: the current water is more than the actual max supported depth + * true: no error + */ +extern bool SpiDrv_SlaveSetRxWaterMark(SpiDrvType *obj, uint16_t txFrameNums, SpiDrv_FrameSizeBitType frameSizeBitType); + +/*! \brief Set rx fifo water mask + * + * \param[in] obj : pointer to the instance + * \param[in] waterMask: fifo water mask + * \return: void + */ +extern void SpiDrv_SetRxFifoWaterMask(SpiDrvType *obj, uint8_t waterMask); + +/*! \brief Set tx fifo water mask + * + * \param[in] obj : pointer to the instance + * \param[in] waterMask: fifo water mask + * \return: void + */ +extern void SpiDrv_SetTxFifoWaterMask(SpiDrvType *obj, uint8_t waterMask); + +/*! \brief Set SPI interrupt config + * + * \param[in] obj : pointer to the instance + * \param[in] isrSrc: interrupt source + * \param[in] enabled: config status + * \return: void + */ +extern void SpiDrv_SetIsrConfig(SpiDrvType *obj, SpiDrv_IsrSrcType isrSrc, bool enabled); + +/*! \brief Get SPI interrupt config + * + * \param[in] obj : pointer to the instance + * \param[in] isrSrc: interrupt source + * \return: config status + */ +extern bool SpiDrv_GetIsrConfig(SpiDrvType *obj, SpiDrv_IsrSrcType isrSrc); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _SPI_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/trgmux/trgmux_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/trgmux/trgmux_drv.c new file mode 100644 index 0000000..9e2969c --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/trgmux/trgmux_drv.c @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "trgmux_drv.h" +#include "trgmux_reg.h" +#include "sim_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* Number of target modules for TRGMUX IP */ +#define TRGMUXDRV_MODULE_NUM (sizeof(TrgMuxRegType) / sizeof(uint32_t)) +/* Number of output ports in one target module */ +#define TRGMUXDRV_TARGET_NUM (4) +/* Sim software trigger delay */ +#define TRGMUXDRV_DELAY(x) \ + do \ + { \ + for(volatile int cnt = 0; cnt < x; cnt++) \ + { \ + ; \ + } \ + } while(0) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/* Definition of function prototype of getting module's lock state */ +typedef uint8_t (*TrgMuxReg_GetModuleLockFunc)(const TrgMuxRegType *obj); +/* Definition of function prototype of locking module selection */ +typedef void (*TrgMuxReg_SetModuleLockFunc)(TrgMuxRegType *obj, uint8_t value); +/* Definition of function prototype of getting module selection */ +typedef uint8_t (*TrgMuxReg_GetModuleSelFunc)(const TrgMuxRegType *obj); +/* Definition of function prototype of setting module selection */ +typedef void (*TrgMuxReg_SetModuleSelFunc)(TrgMuxRegType *obj, uint8_t value); + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/* Definition of the table of getting module's lock state functions */ +static const TrgMuxReg_GetModuleLockFunc c_getModuleLockFuncTable[TRGMUXDRV_MODULE_NUM] = { + TrgMuxReg_GetDmaMux0Lk, + TrgMuxReg_GetExtOut0Lk, + NULL, + TrgMuxReg_GetAdcLk, + NULL, + TrgMuxReg_GetCmpLk, + TrgMuxReg_GetMft0Lk, + TrgMuxReg_GetMft1Lk, + NULL, + NULL, + TrgMuxReg_GetPdbLk, + NULL, + TrgMuxReg_GetLpitLk, + TrgMuxReg_GetLptmrLk}; + +/* Definition of the table of setting module's lock state functions */ +static const TrgMuxReg_SetModuleLockFunc c_setModuleLockFuncTable[TRGMUXDRV_MODULE_NUM] = { + TrgMuxReg_SetDmaMux0Lk, + TrgMuxReg_SetExtOut0Lk, + NULL, + TrgMuxReg_SetAdcLk, + NULL, + TrgMuxReg_SetCmpLk, + TrgMuxReg_SetMft0Lk, + TrgMuxReg_SetMft1Lk, + NULL, + NULL, + TrgMuxReg_SetPdbLk, + NULL, + TrgMuxReg_SetLpitLk, + TrgMuxReg_SetLptmrLk}; + +/* Definition of the table of getting module's selection functions */ +static const TrgMuxReg_GetModuleSelFunc c_getModuleSelFuncTable[TRGMUXDRV_MODULE_NUM][TRGMUXDRV_TARGET_NUM] = { + {TrgMuxReg_GetDmaMux0Sel0, TrgMuxReg_GetDmaMux0Sel1, TrgMuxReg_GetDmaMux0Sel2, TrgMuxReg_GetDmaMux0Sel3}, + {TrgMuxReg_GetExtOut0Sel0, TrgMuxReg_GetExtOut0Sel1, TrgMuxReg_GetExtOut0Sel2, TrgMuxReg_GetExtOut0Sel3}, + {NULL, NULL, NULL, NULL }, + {TrgMuxReg_GetAdcSel0, TrgMuxReg_GetAdcSel1, TrgMuxReg_GetAdcSel2, TrgMuxReg_GetAdcSel3 }, + {NULL, NULL, NULL, NULL }, + {TrgMuxReg_GetCmpSel0, NULL, NULL, NULL }, + {TrgMuxReg_GetMft0Sel0, TrgMuxReg_GetMft0Sel1, TrgMuxReg_GetMft0Sel2, TrgMuxReg_GetMft0Sel3 }, + {TrgMuxReg_GetMft1Sel0, TrgMuxReg_GetMft1Sel1, TrgMuxReg_GetMft1Sel2, TrgMuxReg_GetMft1Sel3 }, + {NULL, NULL, NULL, NULL }, + {NULL, NULL, NULL, NULL }, + {TrgMuxReg_GetPdbSel0, NULL, NULL, NULL }, + {NULL, NULL, NULL, NULL }, + {TrgMuxReg_GetLpitSel0, TrgMuxReg_GetLpitSel1, TrgMuxReg_GetLpitSel2, TrgMuxReg_GetLpitSel3 }, + {TrgMuxReg_GetLptmrSel0, NULL, NULL, NULL }, +}; + +/* Definition of the table of setting module's selection functions */ +static const TrgMuxReg_SetModuleSelFunc c_setModuleSelFuncTable[TRGMUXDRV_MODULE_NUM][TRGMUXDRV_TARGET_NUM] = { + {TrgMuxReg_SetDmaMux0Sel0, TrgMuxReg_SetDmaMux0Sel1, TrgMuxReg_SetDmaMux0Sel2, TrgMuxReg_SetDmaMux0Sel3}, + {TrgMuxReg_SetExtOut0Sel0, TrgMuxReg_SetExtOut0Sel1, TrgMuxReg_SetExtOut0Sel2, TrgMuxReg_SetExtOut0Sel3}, + {NULL, NULL, NULL, NULL }, + {TrgMuxReg_SetAdcSel0, TrgMuxReg_SetAdcSel1, TrgMuxReg_SetAdcSel2, TrgMuxReg_SetAdcSel3 }, + {NULL, NULL, NULL, NULL }, + {TrgMuxReg_SetCmpSel0, NULL, NULL, NULL }, + {TrgMuxReg_SetMft0Sel0, TrgMuxReg_SetMft0Sel1, TrgMuxReg_SetMft0Sel2, TrgMuxReg_SetMft0Sel3 }, + {TrgMuxReg_SetMft1Sel0, TrgMuxReg_SetMft1Sel1, TrgMuxReg_SetMft1Sel2, TrgMuxReg_SetMft1Sel3 }, + {NULL, NULL, NULL, NULL }, + {NULL, NULL, NULL, NULL }, + {TrgMuxReg_SetPdbSel0, NULL, NULL, NULL }, + {NULL, NULL, NULL, NULL }, + {TrgMuxReg_SetLpitSel0, TrgMuxReg_SetLpitSel1, TrgMuxReg_SetLpitSel2, TrgMuxReg_SetLpitSel3 }, + {TrgMuxReg_SetLptmrSel0, NULL, NULL, NULL }, +}; + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void TrgMuxDrv_Init(TrgMuxDrvType *obj, struct _TrgMuxRegType_ *trgMuxReg, struct _SimRegType_ *simReg) +{ + obj->trgMuxReg = trgMuxReg; + obj->simReg = simReg; +} + +void TrgMuxDrv_Configure(TrgMuxDrvType *obj, const TrgMuxDrv_ConfigType *userConfig) +{ + uint16_t index; + + if((obj == NULL) + || (userConfig == NULL) + || (userConfig->numOfInOutMappings == 0)) + { + return; + } + + for(index = 0; index < userConfig->numOfInOutMappings; index++) + { + TrgMuxDrv_SetTrigSourceForTargetModule(obj, + userConfig->inOutMapping[index].triggerSource, + userConfig->inOutMapping[index].targetModule); + } + for(index = 0; index < userConfig->numOfInOutMappings; index++) + { + if(userConfig->inOutMapping[index].lockTargetModuleReg) + { + TrgMuxDrv_SetLockForTargetModule(obj, userConfig->inOutMapping[index].targetModule); + } + } +} + +bool TrgMuxDrv_SetTrigSourceForTargetModule(TrgMuxDrvType *obj, TrgMuxDrv_TrigSourceType triggerSource, TrgMuxDrv_TargetModuleType targetModule) +{ + bool retval; + + if(TrgMuxDrv_GetLockForTargetModule(obj, targetModule) == true) + { + retval = false; + } + else + { + /* Configure link between trigger source and target module. */ + uint8_t moduleIndex = (uint8_t)((uint32_t)targetModule / 4); + uint8_t sourceIndex = (uint8_t)((uint32_t)targetModule % 4); + if(c_setModuleSelFuncTable[moduleIndex][sourceIndex] != NULL) + { + c_setModuleSelFuncTable[moduleIndex][sourceIndex](obj->trgMuxReg, triggerSource); + retval = true; + } + else + { + retval = false; + } + } + + return retval; +} + +TrgMuxDrv_TrigSourceType TrgMuxDrv_GetTrigSourceForTargetModule(const TrgMuxDrvType *obj, TrgMuxDrv_TargetModuleType targetModule) +{ + TrgMuxDrv_TrigSourceType retval = TRGMUXDRV_TRIGSOURCE_SIG0; + uint8_t moduleIndex = (uint8_t)((uint32_t)targetModule / 4); + uint8_t sourceIndex = (uint8_t)((uint32_t)targetModule % 4); + if(c_getModuleSelFuncTable[moduleIndex][sourceIndex] != NULL) + { + retval = (TrgMuxDrv_TrigSourceType)c_getModuleSelFuncTable[moduleIndex][sourceIndex](obj->trgMuxReg); + } + + return retval; +} + +void TrgMuxDrv_SetLockForTargetModule(TrgMuxDrvType *obj, TrgMuxDrv_TargetModuleType targetModule) +{ + uint8_t moduleIndex = (uint8_t)((uint32_t)targetModule / 4); + if(c_setModuleLockFuncTable[moduleIndex] != NULL) + { + c_setModuleLockFuncTable[moduleIndex](obj->trgMuxReg, 1); + } +} + +bool TrgMuxDrv_GetLockForTargetModule(const TrgMuxDrvType *obj, TrgMuxDrv_TargetModuleType targetModule) +{ + bool retval = true; + uint8_t moduleIndex = (uint8_t)((uint32_t)targetModule / 4); + if(c_getModuleLockFuncTable[moduleIndex] != NULL) + { + retval = (c_getModuleLockFuncTable[moduleIndex](obj->trgMuxReg) == 1); + } + + return retval; +} + +void TrgMuxDrv_GenSWTrigger(TrgMuxDrvType *obj, uint32_t delay) +{ + /* The trigger is generated only when writing from 0 to 1*/ + SimReg_SetSwTrg(obj->simReg, 0); + TRGMUXDRV_DELAY(delay); + SimReg_SetSwTrg(obj->simReg, 1); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/trgmux/trgmux_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/trgmux/trgmux_drv.h new file mode 100644 index 0000000..d736e7b --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/trgmux/trgmux_drv.h @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _TRGMUX_DRV_H_ +#define _TRGMUX_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of TRGMUX (Trigger MUX) + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup trgmux_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of TRGMUX trigger source + */ +typedef enum +{ + TRGMUXDRV_TRIGSOURCE_SIG0 = 0U, + TRGMUXDRV_TRIGSOURCE_SIG1 = 1U, + TRGMUXDRV_TRIGSOURCE_TRGMUX_IN0 = 2U, + TRGMUXDRV_TRIGSOURCE_TRGMUX_IN1 = 3U, + TRGMUXDRV_TRIGSOURCE_TRGMUX_IN2 = 4U, + TRGMUXDRV_TRIGSOURCE_TRGMUX_IN3 = 5U, + TRGMUXDRV_TRIGSOURCE_TRGMUX_IN4 = 6U, + TRGMUXDRV_TRIGSOURCE_TRGMUX_IN5 = 7U, + + TRGMUXDRV_TRIGSOURCE_TRGMUX_IN7 = 9U, + TRGMUXDRV_TRIGSOURCE_TRGMUX_IN8 = 10U, + TRGMUXDRV_TRIGSOURCE_TRGMUX_IN9 = 11U, + + TRGMUXDRV_TRIGSOURCE_CMP0_OUT = 14U, + + TRGMUXDRV_TRIGSOURCE_LPIT_CH0 = 16U, + TRGMUXDRV_TRIGSOURCE_LPIT_CH1 = 17U, + TRGMUXDRV_TRIGSOURCE_LPIT_CH2 = 18U, + TRGMUXDRV_TRIGSOURCE_LPIT_CH3 = 19U, + + TRGMUXDRV_TRIGSOURCE_LPTMR0 = 21U, + TRGMUXDRV_TRIGSOURCE_MFT0_INIT_TRIG = 22U, + TRGMUXDRV_TRIGSOURCE_MFT0_EXT_TRIG = 23U, + TRGMUXDRV_TRIGSOURCE_MFT1_INIT_TRIG = 24U, + TRGMUXDRV_TRIGSOURCE_MFT1_EXT_TRIG = 25U, + + TRGMUXDRV_TRIGSOURCE_ADC0_SC1A_COCO = 30U, + TRGMUXDRV_TRIGSOURCE_ADC0_SC1B_COCO = 31U, + + TRGMUXDRV_TRIGSOURCE_PDB0_CH0_TRIG = 34U, + TRGMUXDRV_TRIGSOURCE_PDB0_PULSE_OUT = 35U, + + TRGMUXDRV_TRIGSOURCE_RTC_ALARM = 38U, + TRGMUXDRV_TRIGSOURCE_RTC_SECOND = 39U, + TRGMUXDRV_TRIGSOURCE_SPI0_FRAME = 40U, + TRGMUXDRV_TRIGSOURCE_SPI0_WORD = 41U, + TRGMUXDRV_TRIGSOURCE_SPI1_FRAME = 42U, + TRGMUXDRV_TRIGSOURCE_SPI1_WORD = 43U, + + TRGMUXDRV_TRIGSOURCE_SIM_SW_TRIG = 48U, + +} TrgMuxDrv_TrigSourceType; + +/*! \brief The definition of TRGMUX trigger module + */ +typedef enum +{ + TRGMUXDRV_TARGETMODULE_DMA_CH0 = 0U, + TRGMUXDRV_TARGETMODULE_DMA_CH1 = 1U, + TRGMUXDRV_TARGETMODULE_DMA_CH2 = 2U, + TRGMUXDRV_TARGETMODULE_DMA_CH3 = 3U, + TRGMUXDRV_TARGETMODULE_TRGMUX_OUT0 = 4U, + TRGMUXDRV_TARGETMODULE_TRGMUX_OUT1 = 5U, + TRGMUXDRV_TARGETMODULE_TRGMUX_OUT2 = 6U, + TRGMUXDRV_TARGETMODULE_TRGMUX_OUT3 = 7U, + + TRGMUXDRV_TARGETMODULE_ADC0_ADHWT_TLA0 = 12U, + TRGMUXDRV_TARGETMODULE_ADC0_ADHWT_TLA1 = 13U, + TRGMUXDRV_TARGETMODULE_ADC0_ADHWT_TLA2 = 14U, + TRGMUXDRV_TARGETMODULE_ADC0_ADHWT_TLA3 = 15U, + + TRGMUXDRV_TARGETMODULE_CMP0_SAMPLE = 20U, + TRGMUXDRV_TARGETMODULE_MFT0_HWTRIG0 = 24U, + TRGMUXDRV_TARGETMODULE_MFT0_FAULT0 = 25U, + TRGMUXDRV_TARGETMODULE_MFT0_FAULT1 = 26U, + TRGMUXDRV_TARGETMODULE_MFT0_FAULT2 = 27U, + TRGMUXDRV_TARGETMODULE_MFT1_HWTRIG0 = 28U, + TRGMUXDRV_TARGETMODULE_MFT1_FAULT0 = 29U, + TRGMUXDRV_TARGETMODULE_MFT1_FAULT1 = 30U, + TRGMUXDRV_TARGETMODULE_MFT1_FAULT2 = 31U, + + TRGMUXDRV_TARGETMODULE_PDB0_TRG_IN = 40U, + + TRGMUXDRV_TARGETMODULE_LPIT_TRG_CH0 = 48U, + TRGMUXDRV_TARGETMODULE_LPIT_TRG_CH1 = 49U, + TRGMUXDRV_TARGETMODULE_LPIT_TRG_CH2 = 50U, + TRGMUXDRV_TARGETMODULE_LPIT_TRG_CH3 = 51U, + TRGMUXDRV_TARGETMODULE_LPTMR_ALT0 = 52U, +} TrgMuxDrv_TargetModuleType; + +/*! \brief Definition of In Out Mapping of TRGMUX driver + */ +typedef struct _TrgMuxDrv_InOutMappingType_ +{ + TrgMuxDrv_TrigSourceType triggerSource; /*!< selects one of the TRGMUX trigger sources */ + TrgMuxDrv_TargetModuleType targetModule; /*!< selects one of the TRGMUX target modules */ + bool lockTargetModuleReg; /*!< if true, the LOCK bit of the target module register will be + set by TrgMuxDrv_Configure(), after the current mapping is configured */ + +} TrgMuxDrv_InOutMappingType; + +/*! \brief Definition of configuration of TRGMUX driver + */ +typedef struct _TrgMuxDrv_ConfigType_ +{ + uint16_t numOfInOutMappings; /*!< number of in-out mappings defined in TRGMUX configuration */ + const TrgMuxDrv_InOutMappingType *inOutMapping; /*!< pointer to array of in-out mapping structures */ +} TrgMuxDrv_ConfigType; + +/* Forward declaration of TRGMUX register */ +struct _TrgMuxRegType_; +/* Forward declaration of TRGMUX register */ +struct _SimRegType_; + +/*! \brief The definition of TRGMUX driver class + */ +typedef struct _TrgMuxDrvType_ +{ + struct _TrgMuxRegType_ *trgMuxReg; + struct _SimRegType_ *simReg; +} TrgMuxDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +/*! \brief Initializes the TRGMUX driver module + * + * This function initializes TRGMUX driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to TRGMUX driver instance + * \param[in] reg : pointer to TRGMUX register instance + */ +extern void TrgMuxDrv_Init(TrgMuxDrvType *obj, struct _TrgMuxRegType_ *trgMuxReg, struct _SimRegType_ *simReg); + +/*! \brief Configures the TRGMUX module from the user configuration structure + * + * This function configures the TRGMUX module from the user configuration structure + * + * \param[in] obj : pointer to TRGMUX driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void TrgMuxDrv_Configure(TrgMuxDrvType *obj, const TrgMuxDrv_ConfigType *userConfig); + +/*! \brief Configure a source trigger for a selected target module. + * + * This function configures a TRGMUX link between a source trigger and a target module, + * if the requested target module is not locked. + * + * \param[in] obj : pointer to TRGMUX driver instance + * \param[in] triggerSource : One of the values in the TrgMuxDrv_TrigSourceType enumeration + * \param[in] targetModule : One of the values in the TrgMuxDrv_TargetModuleType enumeration + * \return the result of setting source for target module + * - true : succeed + * - false : failed because targetModule is locked + */ +extern bool TrgMuxDrv_SetTrigSourceForTargetModule(TrgMuxDrvType *obj, TrgMuxDrv_TrigSourceType triggerSource, TrgMuxDrv_TargetModuleType targetModule); + +/*! \brief Get the source trigger configured for a target module. + * + * This function returns the TRGMUX source trigger linked to a selected target module. + * + * \note If the target module is invalid (not in the enum), this function will return source 0 + * which has no meaning. + * + * \param[in] obj : pointer to TRGMUX driver instance + * \param[in] triggerSource : One of the values in the TrgMuxDrv_TrigSourceType enumeration + * \param[in] targetModule : One of the values in the TrgMuxDrv_TargetModuleType enumeration + */ +extern TrgMuxDrv_TrigSourceType TrgMuxDrv_GetTrigSourceForTargetModule(const TrgMuxDrvType *obj, TrgMuxDrv_TargetModuleType targetModule); + +/*! \brief Locks the TRGMUX register of a target module. + * + * This function sets the LK bit of the TRGMUX register corresponding to + * the selected target module. Please note that some TRGMUX registers can contain up to 4 + * SEL bitfields, meaning that these registers can be used to configure up to 4 target + * modules independently. Because the LK bit is only one per register, the configuration + * of all target modules referred from that register will be locked. + * + * \param[in] obj : pointer to TRGMUX driver instance + * \param[in] targetModule : One of the values in the TrgMuxDrv_TargetModuleType enumeration + */ +extern void TrgMuxDrv_SetLockForTargetModule(TrgMuxDrvType *obj, TrgMuxDrv_TargetModuleType targetModule); + +/*! \brief Get the Lock bit status of the TRGMUX register of a target module. + * + * This function gets the value of the LK bit from the TRGMUX register corresponding to + * the selected target module. + * + * \param[in] obj : pointer to TRGMUX driver instance + * \param[in] targetModule : One of the values in the TrgMuxDrv_TargetModuleType enumeration + * \return the result of lock + * - true : if the selected targetModule register is locked + * - false : if the selected targetModule register is not locked + */ +extern bool TrgMuxDrv_GetLockForTargetModule(const TrgMuxDrvType *obj, TrgMuxDrv_TargetModuleType targetModule); + +/*! \brief Generate software triggers + * + * This function uses a SIM register in order to generate a software triggers to the target + * peripherals selected in TRGMUX + * + * \param[in] obj : pointer to TRGMUX driver instance + * \param[in] delay : set delay time for trigger pulse width + */ +extern void TrgMuxDrv_GenSWTrigger(TrgMuxDrvType *obj, uint32_t delay); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _TRGMUX_DRV_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/uart/uart_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/uart/uart_drv.c new file mode 100644 index 0000000..0402154 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/uart/uart_drv.c @@ -0,0 +1,805 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/****************************************************************************** + * the includes + *****************************************************************************/ + +#include "uart_drv.h" + +/****************************************************************************** + * the defines + *****************************************************************************/ + +/****************************************************************************** + * the globals + ******************************************************************************/ + +/****************************************************************************** + * the Static Function Declarations + ******************************************************************************/ +static void UartDrv_InitBasicParameters(UartDrvType *obj, const UartDrv_BasicParametersType *pBasicParameters); +static void UartDrv_InitExtendParameters(UartDrvType *obj, const UartDrv_ExtendParametersType *pExtendParameters, const UartDrv_ExtendFeaturesType *pExtendFeatures); + +/****************************************************************************** + * the functions + *****************************************************************************/ + +/*! \brief Config the basic parameter of the usart basic feature + * + * This function initializes the basic features with the parameters + * + * \param[in] obj: pointer to UART driver instance + * \param[in] pBasicParameters : the combination of basic parameters + * \return: void + */ +static void UartDrv_InitBasicParameters(UartDrvType *obj, const UartDrv_BasicParametersType *pBasicParameters) +{ + /* Parity configuration setting */ + if(pBasicParameters->paritySelection < UARTDRV_PARITY_SELECT_UNUSED) + { + UartReg_SelectParity(obj->reg, pBasicParameters->paritySelection); + UartReg_SetParityControlEnable(obj->reg, true); + } + else + { + UartReg_SetParityControlEnable(obj->reg, false); + } + + /* Data length set */ + UartReg_SetWordLength(obj->reg, pBasicParameters->dataBitsNum); + + /* STOP Bit num */ + UartReg_SetStopBitNums(obj->reg, pBasicParameters->stopBitsNum); + + /* Data shift direction */ + UartReg_SetFirstBitShift(obj->reg, pBasicParameters->dataShiftDirection); + + /* Sampliing setting */ + UartReg_SetOverSamplingMode(obj->reg, pBasicParameters->overSamplingMode); + + /* note: When the one sample bit method is selected the noise detection flag (NF) is disabled */ + UartReg_SetSampleBitMethod(obj->reg, pBasicParameters->oneSampleBitMethod); + + if(pBasicParameters->baudRate != UARTDRV_BRAUD_RATE_INVALID) + { + /* TODO: How to get the system clock frequency? if 6/24/2022 Changed by %USERNAME% */ + uint32_t tDiv = 0; + + if(pBasicParameters->overSamplingMode == UARTDRV_OVERSAMPLING_MODE_BY_8) + { + /* + -BRR[2:0] = UARTDIV[3:0] shifted 1 bit to the right + -BRR[3] must be kept cleared + -BRR[15:4] = UARTDIV[15:4] + */ + tDiv = pBasicParameters->busClockFreq / (pBasicParameters->baudRate >> 1ul); + tDiv = ((tDiv & UARTDRV_BRR_LOW_4BITS_MASK) >> 1u) | (tDiv & (~UARTDRV_BRR_LOW_4BITS_MASK)); + } + else + { + /* overSamplingMode == 16, BRR = UARTDIV */ + tDiv = pBasicParameters->busClockFreq / pBasicParameters->baudRate; + } + + UartReg_SetBaudRate(obj->reg, (uint16_t)(tDiv & 0xFFFF)); + + /* Disable Auto detect baud rate feature */ + UartReg_EnableAutoBaudrateFeature(obj->reg, false); + } + + /* Transceiver enable */ + switch(pBasicParameters->dataTransferDirect) + { + case UARTDRV_DATA_TRANSFER_TX_RX_EN: + UartReg_SetReceiverEnable(obj->reg, true); + UartReg_SetTransmitterEnable(obj->reg, true); + break; + + case UARTDRV_DATA_TRANSFER_TX_ONLY: + UartReg_SetReceiverEnable(obj->reg, false); + UartReg_SetTransmitterEnable(obj->reg, true); + break; + + case UARTDRV_DATA_TRANSFER_RX_ONLY: + UartReg_SetReceiverEnable(obj->reg, true); + UartReg_SetTransmitterEnable(obj->reg, false); + break; + + case UARTDRV_DATA_TRANSFER_TX_RX_DIS: + UartReg_SetReceiverEnable(obj->reg, false); + UartReg_SetTransmitterEnable(obj->reg, false); + break; + + default: + UartReg_SetReceiverEnable(obj->reg, false); + UartReg_SetTransmitterEnable(obj->reg, false); + break; + } +} + +/*! \brief Set the extend parameter of the extend feature + * + * This function initializes the extend features with the parameters + * + * \param[in] obj: pointer to UART driver instance + * \param[in] pExtendParameters: the combination of extend parameters + * \param[in] pExtendFeatures: the combination of extendFeatures + * \return: void + */ +static void UartDrv_InitExtendParameters(UartDrvType *obj, const UartDrv_ExtendParametersType *pExtendParameters, const UartDrv_ExtendFeaturesType *pExtendFeatures) +{ + /* Loops mode */ + UartReg_SetLoopsMode(obj->reg, pExtendFeatures->loopEn); + + switch(pExtendFeatures->cosplayer) + { + case UARTDRV_COSPLAY_LIN: + UartReg_EnableCts(obj->reg, false); + UartReg_EnableRts(obj->reg, false); + UartReg_SetDriverEnableMode(obj->reg, false); + UartReg_SetTxLinSyncBreakWidth(obj->reg, pExtendParameters->breakFieldSyncBreakTxBitsNum); + UartReg_SetLinDelimitorWidth(obj->reg, pExtendParameters->breakFieldDelimiterTxBitsNum); + UartReg_SetLinSyncBreakDetectLen(obj->reg, pExtendParameters->syncBreakRxBitsNum); + UartReg_EnableLineBreakDetectFeature(obj->reg, true); + break; + + case UARTDRV_COSPLAY_RS232: + UartReg_EnableLineBreakDetectFeature(obj->reg, false); + UartReg_SetDriverEnableMode(obj->reg, false); + /* CTS Hardware flow control enable */ + UartReg_EnableCts(obj->reg, true); + UartReg_EnableRts(obj->reg, true); + break; + + case UARTDRV_COSPLAY_RS485: + UartReg_EnableLineBreakDetectFeature(obj->reg, false); + UartReg_SetDEDT(obj->reg, pExtendParameters->driverEnDeassertionTime); + UartReg_SetDEAT(obj->reg, pExtendParameters->driverEnAssertionTime); + UartReg_SetDriverPolarity(obj->reg, pExtendParameters->driverEnablePolarityActiveInLow); + UartReg_SetDriverEnableMode(obj->reg, true); + break; + + case UARTDRV_COSPLAY_UART: + default: + UartReg_EnableCts(obj->reg, false); + UartReg_EnableRts(obj->reg, false); + UartReg_SetDriverEnableMode(obj->reg, false); + UartReg_EnableLineBreakDetectFeature(obj->reg, false); + break; + } + + /* Inversion in Rx&Tx Pin & Data */ + UartReg_EnableRxInverteFeature(obj->reg, pExtendFeatures->rxInvertEn); + UartReg_EnableTxInverteFeature(obj->reg, pExtendFeatures->txInvertEn); + UartReg_EnableDataInverteFeature(obj->reg, pExtendFeatures->dataInvertEn); + + if(pExtendFeatures->autoBaudRateDetectionEn == true) + { + /* Enable Auto detect baud rate feature */ + UartReg_EnableAutoBaudrateFeature(obj->reg, true); + UartReg_SetAutoBaudrateMode(obj->reg, pExtendParameters->autoBaudRateMode); + } + else + { + UartReg_EnableAutoBaudrateFeature(obj->reg, false); + } + + if(pExtendParameters->rxTimeoutBitsCnt > 0u) + { + /* This bit-field gives the Receiver timeout value in terms of number of bit duration */ + UartReg_SetRxTimeout(obj->reg, pExtendParameters->rxTimeoutBitsCnt); + UartReg_EnableRxTimeoutFeature(obj->reg, true); + } + else + { + UartReg_EnableRxTimeoutFeature(obj->reg, false); + } + + if(pExtendFeatures->wakeUpEn == true) + { + if(pExtendParameters->wakeSrc == UARTDRV_WAKE_SOURCE_ADDRESS_MARK) + { + UartReg_SetNodeAddress(obj->reg, pExtendParameters->addrMarkDetectValue); + UartReg_SetAutoBaudrateMode(obj->reg, pExtendParameters->addrDetectMode); + } + else + { + UartReg_SetIdleConfig(obj->reg, pExtendParameters->idleCharNums); + } + + UartReg_SetMuteMode(obj->reg, true); + UartReg_SetWakeupMethod(obj->reg, pExtendParameters->wakeSrc); + } + else + { + UartReg_SetMuteMode(obj->reg, false); + UartReg_SetIdleConfig(obj->reg, pExtendParameters->idleCharNums); + } + + if(pExtendFeatures->dmaEn == true) + { + switch(pExtendParameters->dmaSelection) + { + case UARTDRV_DMA_SELECTION_TX_RX_DIS: + UartReg_EnableRxDMA(obj->reg, false); + UartReg_EnableTxDMA(obj->reg, false); + break; + + case UARTDRV_DMA_SELECTION_TX_EN_RX_DIS: + UartReg_EnableRxDMA(obj->reg, false); + UartReg_EnableTxDMA(obj->reg, true); + break; + + case UARTDRV_DMA_SELECTION_TX_DIS_RX_EN: + UartReg_EnableRxDMA(obj->reg, true); + UartReg_EnableTxDMA(obj->reg, false); + break; + + case UARTDRV_DMA_SELECTION_TX_EN_RX_EN: + UartReg_EnableRxDMA(obj->reg, true); + UartReg_EnableTxDMA(obj->reg, true); + break; + + default: + UartReg_EnableRxDMA(obj->reg, false); + UartReg_EnableTxDMA(obj->reg, false); + break; + } + } + else + { + UartReg_EnableRxDMA(obj->reg, false); + UartReg_EnableTxDMA(obj->reg, false); + } +} + +/*! \brief Transmit one data + * + * This function write one data to tx fifo + * + * \param[in] obj :pointer to UART driver instance + * \param[in] txDatabuf : the copy of data to be sent + * \return: void + */ +void UartDrv_TxData(UartDrvType *obj, uint16_t txData) +{ + UartReg_TxData(obj->reg, txData); +} + +/*! \brief Read out from the rx buffer to the specific address and indicated how + * + * This function read out received datas from rx fifo + * + * \param[in] obj : pointer to UART driver instance + * \return: read-out value , if PE or FE or NF, return UARTDRV_READ_DATA_INVALID + */ +uint16_t UartDrv_RxData(const UartDrvType *obj) +{ + uint16_t tRtn = UARTDRV_READ_DATA_INVALID; + + uint32_t tRegValue = obj->reg->RDR; + + if((tRegValue & UART_RDR_ERR_MASK) == 0u) + { + tRtn = (((tRegValue & UART_RDR_RDR_MASK) >> UART_RDR_RDR_SHIFT) & 0x1FF); + } + + return tRtn; +} + +/*! \brief Read out the current status flag + * + * This function Get the expected status + * + * \param[in] obj : pointer to UART driver instance + * \param[in] status: which status want to get + * \return : bool + * FALSE: + * TRUE: some event happend + */ +bool UartDrv_GetStatus(const UartDrvType *obj, UartDrv_StatusType status) +{ + bool tRtn = false; + + uint32_t tRegValue = 0; + + if(status <= UARTDRV_STATUS_RWU) + { + /* FIFO */ + if((status == UARTDRV_STATUS_RXUF) || (status == UARTDRV_STATUS_TXOF)) + { + if(status == UARTDRV_STATUS_RXUF) + { + tRtn = UartReg_GetRxUnderflowFlag(obj->reg); + } + else + { + tRtn = UartReg_GetTxOverflowFlag(obj->reg); + } + } + else + { + /* ISR */ + tRegValue = obj->reg->ISR; + + if((tRegValue & status) != 0u) + { + tRtn = true; + } + } + } + else if(status <= UARTDRV_STATUS_RX_EMPTY) + { + tRegValue = obj->reg->FIFO; + + if(status == UARTDRV_STATUS_RX_EMPTY) + { + if((tRegValue & UART_FIFO_RXEMPT_MASK) != 0u) + { + tRtn = true; + } + } + else + { + if((tRegValue & UART_FIFO_TXEMPT_MASK) != 0u) + { + tRtn = true; + } + } + } + else + { + /* Nothing to do */ + } + + return tRtn; +} + +/*! \brief Clear the expected status + * + * This function clear the special status , can be combination with more than one status + * + * \param[in] obj : pointer to UART driver instance + * \param[in] status: can used the combination of the UartDrv_IsrStatusIdxType to clear more than one bit interrupt flag; + * for example: if want to clear PE&FE: (UARTDRV_STATUS_RXUF | UART_STATUS_PE) + * \return: void + */ +void UartDrv_ClearStatus(UartDrvType *obj, uint32_t status) +{ + /* FIFO */ + if(((status & UARTDRV_STATUS_RXUF) != 0ul) || ((status & UARTDRV_STATUS_TXOF) != 0ul)) + { + if((status & UARTDRV_STATUS_TXOF) != 0ul) + { + UartReg_ClearTxOverflowFlag(obj->reg); + } + else + { + UartReg_ClearRxUnderflowFlag(obj->reg); + } + } + else if((status & UARTDRV_STATUS_ABRE) != 0ul) + { + UartReg_ReqAutoBaudRate(obj->reg); + } + else if((status & UARTDRV_STATUS_LBDT_FAIL) != 0ul) + { + UartReg_ClearLinBreakDetectedResultFlag(obj->reg); + } + else + { + /* ISR */ + obj->reg->ICR = (uint32_t)status; + } +} + +/*! \brief Enable or Disable one or more than one interrupt source + * + * This function set the interrupt request action if condition matched + * + * \param[in] obj :pointer to UART driver instance + * \param[in] isrSrc :can used the more than one interrupt source once + * \param[in] isrEn :True(Enable) or false(Disable) + * \return: void + */ +void UartDrv_SetInterruptReq(UartDrvType *obj, uint32_t isrSrc, bool isrEn) +{ + /* Tx interrupt configuration */ + /* Transmit overflow */ + if((isrSrc & UARTDRV_ISR_SRC_TX_OVERFLOW) != 0u) + { + UartReg_SetTxOverflowIsr(obj->reg, isrEn); + } + + /* Transmit data register empty */ + if((isrSrc & UARTDRV_ISR_SRC_TX_EMPTY) != 0u) + { + UartReg_SetTxBufferEmptyIsr(obj->reg, isrEn); + } + /* Transmission Complete */ + if((isrSrc & UARTDRV_ISR_SRC_TX_COMPLETE) != 0u) + { + UartReg_SetTxCompletedIsr(obj->reg, isrEn); + } + /* Send break done flag */ + if((isrSrc & UARTDRV_ISR_SRC_TX_SYNC_BREAK) != 0u) + { + UartReg_SetBreakTxCompletedIsr(obj->reg, isrEn); + } + + /* Rx interrupt configuration */ + /* Receive under flow */ + if((isrSrc & UARTDRV_ISR_SRC_RX_UNDERFLOW) != 0u) + { + UartReg_SetRxUnderflowIsr(obj->reg, isrEn); + } + + /* Receive Data Register Full */ + if((isrSrc & UARTDRV_ISR_SRC_RX_FULL) != 0u) + { + UartReg_SetRxBufferFullIsr(obj->reg, isrEn); + } + + /* Receiver timeout */ + if((isrSrc & UARTDRV_ISR_SRC_RX_TIMEOUT) != 0u) + { + UartReg_SetRxTimeoutIsr(obj->reg, isrEn); + } + + /* LIN Break Detect Done */ + if((isrSrc & UARTDRV_ISR_SRC_RX_SYNC_BREAK) != 0u) + { + UartReg_SetLinBreakDetectedIsr(obj->reg, isrEn); + } + + /* Idle line detected */ + if((isrSrc & UARTDRV_ISR_SRC_RX_IDLE) != 0u) + { + UartReg_SetIdleIsr(obj->reg, isrEn); + } + + /* CTS */ + if((isrSrc & UARTDRV_ISR_SRC_RX_CTS) != 0u) + { + UartReg_SetCtsIsr(obj->reg, isrEn); + } + + /* Err interrupt configuration */ + /* Parity error */ + if((isrSrc & UARTDRV_ISR_SRC_ERR_PARITY) != 0u) + { + UartReg_SetParityErrIsr(obj->reg, isrEn); + } + + /* One of the frame err or noise err or over run err */ + if(((isrSrc & UARTDRV_ISR_SRC_ERR_FRAME) != 0u) || ((isrSrc & UARTDRV_ISR_SRC_ERR_NOISE) != 0u) || ((isrSrc & UARTDRV_ISR_SRC_ERR_OVER_RUN) != 0u)) + { + UartReg_SetErrIsr(obj->reg, isrEn); + } +} + +/*! \brief Get one interrupt source is enable or disable + * + * This function gets one interrupt source is enable or disable + * + * \param[in] obj :pointer to UART driver instance + * \param[in] isrType :one interrupt source type + * \return: True(Enable) or false(Disable) + */ +bool UartDrv_IsInterruptEnabled(UartDrvType *obj, UartDrv_IsrSrcType isrType) +{ + bool bRet = false; + + switch(isrType) + { + case UARTDRV_ISR_SRC_TX_OVERFLOW: + bRet = UartReg_GetTxOverflowIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_TX_EMPTY: + bRet = UartReg_GetTxBufferEmptyIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_TX_COMPLETE: + bRet = UartReg_GetTxCompletedIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_TX_SYNC_BREAK: + bRet = UartReg_GetBreakTxCompletedIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_RX_UNDERFLOW: + bRet = UartReg_GetRxUnderflowIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_RX_FULL: + bRet = UartReg_GetRxBufferFullIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_RX_TIMEOUT: + bRet = UartReg_GetRxTimeoutIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_RX_SYNC_BREAK: + bRet = UartReg_GetLinBreakDetectedIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_RX_IDLE: + bRet = UartReg_GetIdleIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_RX_CTS: + bRet = UartReg_GetCtsIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_ERR_PARITY: + bRet = UartReg_GetParityErrIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_ERR_FRAME: + case UARTDRV_ISR_SRC_ERR_NOISE: + case UARTDRV_ISR_SRC_ERR_OVER_RUN: + bRet = UartReg_GetErrIsrIsEnabled(obj->reg); + break; + default: + break; + } + + return bRet; +} + +/*! \brief Get default configures the UART module for configuration structure + * + * This function gets default configures the UART module for user configuration structure + * + * \param[out] userConfig : pointer to configuration structure + * \return: void + */ +void UartDrv_GetDefaultConfig(UartDrv_InitCfgType *pInitCfg) +{ + pInitCfg->basicParameters.baudRate = 19200; + pInitCfg->basicParameters.dataBitsNum = UARTDRV_DATA_BITS_NUM_8; + pInitCfg->basicParameters.stopBitsNum = UARTDRV_STOP_BITS_NUM_1; + pInitCfg->basicParameters.dataShiftDirection = UARTDRV_DATA_SHIFT_DIRECTION_LSB; + pInitCfg->basicParameters.paritySelection = UARTDRV_PARITY_SELECT_UNUSED; + pInitCfg->basicParameters.oneSampleBitMethod = UARTDRV_ONE_SAMPLE_BIT_METHOD_IN_3BITS; + pInitCfg->basicParameters.overSamplingMode = UARTDRV_OVERSAMPLING_MODE_BY_16; + pInitCfg->basicParameters.dataTransferDirect = UARTDRV_DATA_TRANSFER_TX_RX_EN; + + pInitCfg->extendParameters.addrDetectMode = UARTDRV_ADDR_DETECTION_MODE_ALL_BITS; + pInitCfg->extendParameters.addrMarkDetectValue = 0x55; + pInitCfg->extendParameters.idleCharNums = UARTDRV_IDLE_CHAR_NUM_4; + pInitCfg->extendParameters.wakeSrc = UARTDRV_WAKE_SOURCE_IDLE_LINE; + pInitCfg->extendParameters.rxTimeoutBitsCnt = 0x00FF; + + pInitCfg->extendParameters.breakFieldSyncBreakTxBitsNum = UARTDRV_BREAK_FIELD_SYNC_BREAK_TX_BITS_NUM_13; + pInitCfg->extendParameters.breakFieldDelimiterTxBitsNum = UARTDRV_BREAK_FIELD_DELIMITER_TX_BITS_NUM_1; + pInitCfg->extendParameters.syncBreakRxBitsNum = UARTDRV_LIN_SYNC_BREAK_RX_BITS_NUM_11; + + pInitCfg->extendParameters.autoBaudRateMode = UARTDRV_AUTO_BAUDRATE_MODE_0; + + pInitCfg->extendParameters.dmaSelection = UARTDRV_DMA_SELECTION_TX_RX_DIS; + + pInitCfg->extendParameters.driverEnAssertionTime = 4; + pInitCfg->extendParameters.driverEnDeassertionTime = 2; + pInitCfg->extendParameters.driverEnablePolarityActiveInLow = true; + + pInitCfg->extendFeatures.wakeUpEn = false; + pInitCfg->extendFeatures.dmaEn = false; + pInitCfg->extendFeatures.autoBaudRateDetectionEn = false; + pInitCfg->extendFeatures.rxInvertEn = false; + pInitCfg->extendFeatures.txInvertEn = false; + pInitCfg->extendFeatures.dataInvertEn = false; + pInitCfg->extendFeatures.loopEn = false; + pInitCfg->extendFeatures.cosplayer = UARTDRV_COSPLAY_UART; +} + +/*! \brief Set the config for the uart module + * + * This function initializes the run-time state structure to provide for module configuration + * + * \param[in] obj :pointer to UART driver instance + * \param[in] pInitCfg :the pointer to the user configuration + * \return: void + */ +void UartDrv_SetConfig(UartDrvType *obj, const UartDrv_InitCfgType *pInitCfg) +{ + /* Disable Uart Module to make sure that some register be configured successfully */ + UartReg_EnableModule(obj->reg, false); + + /* Clear tx&rx fifo */ + UartReg_FlushTxFifo(obj->reg); + + UartReg_FlushRxFifo(obj->reg); + + UartDrv_InitBasicParameters(obj, &pInitCfg->basicParameters); + + UartDrv_InitExtendParameters(obj, &pInitCfg->extendParameters, &pInitCfg->extendFeatures); + + /* Enable Uart module */ + UartReg_EnableModule(obj->reg, true); + + /* Clear all Interrupt status or flag, avoid to enter interrupt routines only in Module is enabled */ + UartDrv_ClearStatus(obj, UARTDRV_STATUS_ISR_ALL); +} + +/*! \brief Enable or disable the uart module + * + * This function enables or disables the uart module + * + * \param[in] obj :pointer to UART driver instance + * \param[in] isEnable: + * 0: UART disabled + * 1: UART enabled + * \return: void + */ +void UartDrv_EnableModule(UartDrvType *obj, bool isEnable) +{ + /* Enable or disable Uart module */ + UartReg_EnableModule(obj->reg, isEnable); +} + +/*! \brief Get received data number in Rx FIFO + * + * This function gets received data number in Rx FIFO + * + * \param[in] obj : pointer to UART driver instance + * \return : data counter in Rx FIFO + */ +uint8_t UartDrv_GetRxCounter(const UartDrvType *obj) +{ + return UartReg_GetRxCounter(obj->reg); +} + +/*! \brief Get wait to transmit data number in Tx FIFO + * + * This function gets wait to transmit data number in Tx FIFO + * + * \param[in] obj : pointer to UART driver instance + * \return : data counter in Tx FIFO + */ +uint8_t UartDrv_GetTxCounter(const UartDrvType *obj) +{ + return UartReg_GetTxCounter(obj->reg); +} + +/*! \brief clear all data of Tx FIFO + * + * This function clears all data of Tx FIFO + * + * \param[in] obj : pointer to UART driver instance + */ +void UartDrv_ClearTxFifo(const UartDrvType *obj) +{ + /* Clear tx fifo */ + UartReg_FlushTxFifo(obj->reg); +} + +/*! \brief clear all data of Rx FIFO + * + * This function clears all data of Rx FIFO + * + * \param[in] obj : pointer to UART driver instance + */ +void UartDrv_ClearRxFifo(const UartDrvType *obj) +{ + /* Clear rx fifo */ + UartReg_FlushRxFifo(obj->reg); +} + +/*! \brief Set the threshold value of Rx FIFO + * + * This function sets the threshold value of Rx FIFO + * + * \param[in] obj : pointer to the instance + * \param[in] txWater : threshold value (range 0 to 3) + * \return : void + */ +void UartDrv_SetRxWater(const UartDrvType *obj, uint8_t rxWater) +{ + if(true == UartReg_GetEnable(obj->reg)) + { + UartReg_EnableModule(obj->reg, false); + UartReg_SetRxWater(obj->reg, rxWater); + UartReg_EnableModule(obj->reg, true); + } + else + { + UartReg_SetRxWater(obj->reg, rxWater); + } +} + +/*! \brief Set the threshold value of Tx FIFO + * + * This function sets the threshold value of Tx FIFO + * + * \param[in] obj : pointer to the instance + * \param[in] txWater : threshold value (range 0 to 3) + * \return : void + */ +void UartDrv_SetTxWater(const UartDrvType *obj, uint8_t txWater) +{ + if(true == UartReg_GetEnable(obj->reg)) + { + UartReg_EnableModule(obj->reg, false); + UartReg_SetTxWater(obj->reg, txWater); + UartReg_EnableModule(obj->reg, true); + } + else + { + UartReg_SetTxWater(obj->reg, txWater); + } +} + +/*! \brief Send lin sync break field + * + * This function sends lin sync break field + * + * \param[in] obj : pointer to UART driver instance + * \return : void + */ +void UartDrv_SendLinBreakField(const UartDrvType *obj) +{ + UartReg_ReqTxBreak(obj->reg); +} + +/*! \brief Enable or disable the Line break detect + * + * This function enables or disables the Line break detect + * + * \param[in] obj :pointer to UART driver instance + * \param[in] isEnable: + * 0: Line break detect disable + * 1: Line break detect enable + * \return: void + */ +void UartDrv_EnableLineBreakDetect(const UartDrvType *obj, bool isEnable) +{ + UartReg_EnableLineBreakDetectFeature(obj->reg, isEnable); +} + +/*! \brief Initializes the UART driver module + * + * This function initializes UART driver by setting the register instance to it. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] reg : pointer to UART register instance + * \return: void + */ +void UartDrv_Init(UartDrvType *obj, UartRegType *pReg) +{ + obj->reg = pReg; + + /* Clear tx&rx fifo */ + UartReg_FlushTxFifo(obj->reg); + + UartReg_FlushRxFifo(obj->reg); + + obj->reg->CR1 = 0; +} + +/*! \brief DeInit the uart module to default + * + * This function call back in the usage of low power or sleep requirements + * + * \param[in] obj : pointer to UART driver instance + * \return: void + */ +void UartDrv_DeInit(UartDrvType *obj) +{ + /* Clear all Interrupt status or flag, avoid to enter interrupt routines only in Module is enabled */ + UartDrv_ClearStatus(obj, UARTDRV_STATUS_ISR_ALL); + + /* Disable all Interrupt enable bit */ + UartDrv_SetInterruptReq(obj, UARTDRV_ISR_SRC_ALL, false); + + /* Clear tx&rx fifo */ + UartReg_FlushTxFifo(obj->reg); + UartReg_FlushRxFifo(obj->reg); + + /* Disable module */ + UartReg_EnableModule(obj->reg, false); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/uart/uart_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/uart/uart_drv.h new file mode 100644 index 0000000..54d9b2f --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/uart/uart_drv.h @@ -0,0 +1,496 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UARTDRV_DRV_H_ +#define _UARTDRV_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of UART module + */ + +/****************************************************************************** + * the includes + *****************************************************************************/ + +#include +#include +#include "uart_reg.h" + +/*! \addtogroup uart_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * the defines + *****************************************************************************/ + +#define UARTDRV_BRR_LOW_4BITS_MASK (0x0000000Fu) +#define UARTDRV_READ_DATA_INVALID (0xFFFFul) +#define UARTDRV_BRAUD_RATE_INVALID (0xFFFFFFFF) + +/****************************************************************************** + * the typedefs + *****************************************************************************/ + +/*! \brief Word length */ +typedef enum +{ + UARTDRV_DATA_BITS_NUM_8 = 0x00u, /*!< 1 Start bit, 8 data bits, n stop bits */ + UARTDRV_DATA_BITS_NUM_9 /*!< 1 Start bit, 9 data bits, n stop bits */ +} UartDrv_DataBitsNumType; + +/*! \brief stop bits setting */ +typedef enum +{ + UARTDRV_STOP_BITS_NUM_1 = 0x00u, /*!< 1 stop bit */ + UARTDRV_STOP_BITS_NUM_2 /*!< 2 stop bits */ +} UartDrv_StopBitsNumType; + +/*! \brief transfer data bit sequeue */ +typedef enum +{ + UARTDRV_DATA_SHIFT_DIRECTION_LSB = 0x00u, /*!< data is transmitted/received with data bit 0 first, following the start bit. */ + UARTDRV_DATA_SHIFT_DIRECTION_MSB /*!< data is transmitted/received with the MSB (bit 7/8/9) first, following the start bit. */ +} UartDrv_DataShiftDirectionType; + +/*! \brief parity selection */ +typedef enum +{ + UARTDRV_PARITY_SELECT_EVEN = 0x00u, /*!< Even parity */ + UARTDRV_PARITY_SELECT_ODD, /*!< Odd parity */ + UARTDRV_PARITY_SELECT_UNUSED /*!< Parity check feature is not used */ +} UartDrv_ParitySelectionType; + +/*! \brief Transfer mode usage */ +typedef enum +{ + UARTDRV_DATA_TRANSFER_TX_RX_DIS = 0x00u, /*!< Transfer is not in tx&rx */ + UARTDRV_DATA_TRANSFER_TX_ONLY, /*!< Transfer is in tx */ + UARTDRV_DATA_TRANSFER_RX_ONLY, /*!< Transfer is in rx*/ + UARTDRV_DATA_TRANSFER_TX_RX_EN /*!< Transfer is in rx&tx */ +} UartDrv_DataTransferDirectType; + +/*! \brief Idle character nums */ +typedef enum +{ + UARTDRV_IDLE_CHAR_NUM_1 = 0x00u, /*!< 1 idle character */ + UARTDRV_IDLE_CHAR_NUM_2, /*!< 2 idle character */ + UARTDRV_IDLE_CHAR_NUM_4, /*!< 4 idle character */ + UARTDRV_IDLE_CHAR_NUM_8, /*!< 8 idle character */ + UARTDRV_IDLE_CHAR_NUM_16, /*!< 16 idle character */ + UARTDRV_IDLE_CHAR_NUM_32, /*!< 32 idle character */ + UARTDRV_IDLE_CHAR_NUM_64, /*!< 64 idle character */ + UARTDRV_IDLE_CHAR_NUM_128 /*!< 128 idle character */ +} UartDrv_IdleCharNumsType; + +/*! \brief wakeup source selection */ +typedef enum +{ + UARTDRV_WAKE_SOURCE_IDLE_LINE = 0x00u, /*!< Idle line */ + UARTDRV_WAKE_SOURCE_ADDRESS_MARK /*!< Address mark */ +} UartDrv_WakeSourceType; + +/*! \brief Oversampling mode */ +typedef enum +{ + UARTDRV_ONE_SAMPLE_BIT_METHOD_IN_3BITS = 0u, /*!< Three sample bit method */ + UARTDRV_ONE_SAMPLE_BIT_METHOD_IN_1BITS /*!< One sample bit method */ +} UartDrv_OneSampleBitMethod; + +/*! \brief oversampling mode */ +typedef enum +{ + UARTDRV_OVERSAMPLING_MODE_BY_16 = 0x00u, /*!< Oversampling by 16 */ + UARTDRV_OVERSAMPLING_MODE_BY_8 /*!< Oversampling by 8 */ +} UartDrv_OverSamplingModeType; + +/*! \brief Dma selection */ +typedef enum +{ + UARTDRV_DMA_SELECTION_TX_RX_DIS = 0x00u, /*!< DMA mode is disabled for tx&rx */ + UARTDRV_DMA_SELECTION_TX_EN_RX_DIS, /*!< DMA mode is enabled for tx */ + UARTDRV_DMA_SELECTION_TX_DIS_RX_EN, /*!< DMA mode is enabled for rx */ + UARTDRV_DMA_SELECTION_TX_EN_RX_EN /*!< DMA mode is enabled for tx&rx */ +} UartDrv_DmaSelectionType; + +/*! \brief Auto baudrate detect mode */ +typedef enum +{ + UARTDRV_AUTO_BAUDRATE_MODE_0 = 0x00u, /*!< Measurement of the start bit is used to detect the baud rate */ + UARTDRV_AUTO_BAUDRATE_MODE_1, /*!< Falling edge to falling edge measurement */ + UARTDRV_AUTO_BAUDRATE_MODE_2, /*!< 0x7F frame detection */ + UARTDRV_AUTO_BAUDRATE_MODE_3, /*!< 0x55 frame detection */ +} UartDrv_AutoBaudRateModeType; + +/*! \brief 7-bit Address Detection/4-bit Address Detection */ +typedef enum +{ + UARTDRV_ADDR_DETECTION_MODE_LOW_4BITS = 0x00u, /*!< 4-bit address detection */ + UARTDRV_ADDR_DETECTION_MODE_ALL_BITS /*!< 7-bit address detection (in 8-bit data mode) */ +} UartDrv_AddrDetectionModeType; + +/*! \brief Send the bits of the sync break signal(Low level) */ +typedef enum +{ + UARTDRV_BREAK_FIELD_SYNC_BREAK_TX_BITS_NUM_13 = 0x00u, /*!< - 13 bits */ + UARTDRV_BREAK_FIELD_SYNC_BREAK_TX_BITS_NUM_14, /*!< - 14 bits */ + UARTDRV_BREAK_FIELD_SYNC_BREAK_TX_BITS_NUM_15 /*!< - 15 bits */ +} UartDrv_BreakFieldSyncBreakTxBitsNumType; + +/*! \brief Send the bits of the delimiter (High level) */ +typedef enum +{ + UARTDRV_BREAK_FIELD_DELIMITER_TX_BITS_NUM_1 = 0x00u, /*!<- 1 bits */ + UARTDRV_BREAK_FIELD_DELIMITER_TX_BITS_NUM_2 /*!< - 2 bits */ +} UartDrv_BreakFieldDelimiterTxBitsNumType; + +/*! \brief LIN synch break detect length: */ +typedef enum +{ + UARTDRV_LIN_SYNC_BREAK_RX_BITS_NUM_11 = 0x00u, /*!< - 11 bits */ + UARTDRV_LIN_SYNC_BREAK_RX_BITS_NUM_12, /*!< - 12 bits */ + UARTDRV_LIN_SYNC_BREAK_RX_BITS_NUM_13 /*!< - 13 bits */ +} UartDrv_LinSyncBreakRxBitsNumType; + +typedef enum +{ + UARTDRV_COSPLAY_UART = 0x00u, + UARTDRV_COSPLAY_LIN, + UARTDRV_COSPLAY_RS232, + UARTDRV_COSPLAY_RS485 +} UartDrv_Cosplay; + +/*! \brief Interrupt source */ +typedef enum +{ + UARTDRV_ISR_SRC_TX_OVERFLOW = 0x01ul, + UARTDRV_ISR_SRC_TX_EMPTY = 0x02ul, + UARTDRV_ISR_SRC_TX_COMPLETE = 0x04ul, + UARTDRV_ISR_SRC_TX_SYNC_BREAK = 0x08ul, + + UARTDRV_ISR_SRC_RX_UNDERFLOW = 0x10ul, + UARTDRV_ISR_SRC_RX_FULL = 0x20ul, + UARTDRV_ISR_SRC_RX_TIMEOUT = 0x40ul, + UARTDRV_ISR_SRC_RX_SYNC_BREAK = 0x80ul, + UARTDRV_ISR_SRC_RX_IDLE = 0x100ul, + UARTDRV_ISR_SRC_RX_CTS = 0x200ul, + + UARTDRV_ISR_SRC_ERR_PARITY = 0x400ul, + UARTDRV_ISR_SRC_ERR_FRAME = 0x800ul, + UARTDRV_ISR_SRC_ERR_NOISE = 0x1000ul, + UARTDRV_ISR_SRC_ERR_OVER_RUN = 0x2000ul, + UARTDRV_ISR_SRC_ERR_ALL = 0x4000ul, + + UARTDRV_ISR_SRC_ALL = 0xFFFFFFFF +} UartDrv_IsrSrcType; + +/*! \brief Status flag */ +typedef enum +{ + UARTDRV_STATUS_PE = 0x01ul, + UARTDRV_STATUS_FE = 0x02ul, + UARTDRV_STATUS_NF = 0x04ul, + UARTDRV_STATUS_ORE = 0x08ul, + UARTDRV_STATUS_IDLE = 0x10ul, + UARTDRV_STATUS_RDRF = 0x20ul, + UARTDRV_STATUS_TC = 0x40ul, + UARTDRV_STATUS_TDRE = 0x80ul, + UARTDRV_STATUS_LBDT_DONE = 0x100ul, + UARTDRV_STATUS_CTSIF = 0x200ul, + UARTDRV_STATUS_CTS = 0x400ul, + UARTDRV_STATUS_RTOF = 0x800ul, + UARTDRV_STATUS_RXUF = 0x1000ul, + UARTDRV_STATUS_TXOF = 0x2000ul, + UARTDRV_STATUS_ABRE = 0x4000ul, + UARTDRV_STATUS_ABRF = 0x8000ul, + UARTDRV_STATUS_BUSY = 0x10000ul, + UARTDRV_STATUS_LBDT_FAIL = 0x20000ul, + UARTDRV_STATUS_SBRKD = 0x40000ul, + UARTDRV_STATUS_ISR_ALL = 0xFFFFCFFF, + UARTDRV_STATUS_RWU = 0x80000ul, + UARTDRV_STATUS_TX_EMPTY = 0x100000ul, + UARTDRV_STATUS_RX_EMPTY = 0x200000ul +} UartDrv_StatusType; + +/*! \brief Basic parameters for the basic features */ +typedef struct _UartDrv_BasicParametersType_ +{ + uint32_t busClockFreq; + uint32_t baudRate; + UartDrv_DataBitsNumType dataBitsNum; + UartDrv_StopBitsNumType stopBitsNum; + UartDrv_DataShiftDirectionType dataShiftDirection; + UartDrv_ParitySelectionType paritySelection; + UartDrv_OneSampleBitMethod oneSampleBitMethod; + UartDrv_OverSamplingModeType overSamplingMode; + UartDrv_DataTransferDirectType dataTransferDirect; +} UartDrv_BasicParametersType; + +/*! \brief advanced parameters for the advance features if used */ +typedef struct _UartDrv_ExtendParametersType_ +{ + UartDrv_AutoBaudRateModeType autoBaudRateMode; + UartDrv_DmaSelectionType dmaSelection; + UartDrv_AddrDetectionModeType addrDetectMode; + UartDrv_WakeSourceType wakeSrc; + UartDrv_BreakFieldSyncBreakTxBitsNumType breakFieldSyncBreakTxBitsNum; + UartDrv_BreakFieldDelimiterTxBitsNumType breakFieldDelimiterTxBitsNum; + UartDrv_LinSyncBreakRxBitsNumType syncBreakRxBitsNum; + UartDrv_IdleCharNumsType idleCharNums; + uint32_t rxTimeoutBitsCnt; + uint8_t addrMarkDetectValue; + uint8_t driverEnDeassertionTime; + uint8_t driverEnAssertionTime; + bool driverEnablePolarityActiveInLow; +} UartDrv_ExtendParametersType; + +/*! \brief advance features if wanted to be used */ +typedef struct _UartDrv_ExtendFeaturesType_ +{ + bool dmaEn; + bool autoBaudRateDetectionEn; + bool rxInvertEn; + bool txInvertEn; + bool dataInvertEn; + bool loopEn; + bool wakeUpEn; + UartDrv_Cosplay cosplayer; +} UartDrv_ExtendFeaturesType; + +/*! \brief the initial configuration if used to be set */ +typedef struct _UartDrv_InitCfgType_ +{ + UartDrv_BasicParametersType basicParameters; + UartDrv_ExtendParametersType extendParameters; + UartDrv_ExtendFeaturesType extendFeatures; +} UartDrv_InitCfgType; + +/*! \brief uart instance pointer */ +typedef struct _UartDrvType_ +{ + UartRegType *reg; +} UartDrvType; + +/****************************************************************************** + * the globals + ******************************************************************************/ + +/****************************************************************************** + * the function prototypes + ******************************************************************************/ + +/*! \brief Get default configures the UART module for configuration structure + * + * This function gets default configures the UART module for user configuration structure + * + * \param[out] userConfig : pointer to configuration structure + * \return: void + */ +extern void UartDrv_GetDefaultConfig(UartDrv_InitCfgType *pInitCfg); + +/*! \brief Set the config for the uart module + * + * this function initializes the run-time state structure to provide for module configuration + * + * \param[in] obj : pointer to UART driver instance + * \param[in] pInitCfg :the pointer to the user configuration + * \return: void + */ +extern void UartDrv_SetConfig(UartDrvType *obj, const UartDrv_InitCfgType *pInitCfg); + +/*! \brief Enable or disable the uart module + * + * This function enables or disables the uart module + * + * \param[in] obj :pointer to UART driver instance + * \param[in] isEnable: + * 0: UART disabled + * 1: UART enabled + * \return: void + */ +extern void UartDrv_EnableModule(UartDrvType *obj, bool isEnable); + +/*! \brief Get received data number in Rx FIFO + * + * This function gets received data number in Rx FIFO + * + * \param[in] obj : pointer to UART driver instance + * \return : data counter in Rx FIFO + */ +extern uint8_t UartDrv_GetRxCounter(const UartDrvType *obj); + +/*! \brief Get wait to transmit data number in Tx FIFO + * + * This function gets wait to transmit data number in Tx FIFO + * + * \param[in] obj : pointer to UART driver instance + * \return : data counter in Tx FIFO + */ +extern uint8_t UartDrv_GetTxCounter(const UartDrvType *obj); + +/*! \brief clear all data of Tx FIFO + * + * This function clears all data of Tx FIFO + * + * \param[in] obj : pointer to UART driver instance + */ +extern void UartDrv_ClearTxFifo(const UartDrvType *obj); + +/*! \brief clear all data of Rx FIFO + * + * This function clears all data of Rx FIFO + * + * \param[in] obj : pointer to UART driver instance + */ +extern void UartDrv_ClearRxFifo(const UartDrvType *obj); + +/*! \brief Set the threshold value of Rx FIFO + * + * This function sets the threshold value of Rx FIFO + * + * \param[in] obj : pointer to the instance + * \param[in] txWater : threshold value (range 0 to 3) + * \return : void + */ +extern void UartDrv_SetRxWater(const UartDrvType *obj, uint8_t rxWater); + +/*! \brief Set the threshold value of Tx FIFO + * + * This function sets the threshold value of Tx FIFO + * + * \param[in] obj : pointer to the instance + * \param[in] txWater : threshold value (range 0 to 3) + * \return : void + */ +extern void UartDrv_SetTxWater(const UartDrvType *obj, uint8_t txWater); + +/*! \brief Send lin sync break field + * + * This function sends lin sync break field + * + * \param[in] obj : pointer to UART driver instance + * \return : void + */ +extern void UartDrv_SendLinBreakField(const UartDrvType *obj); + +/*! \brief Enable or disable the Line break detect + * + * This function enables or disables the Line break detect + * + * \param[in] obj :pointer to UART driver instance + * \param[in] isEnable: + * 0: Line break detect disable + * 1: Line break detect enable + * \return: void + */ +extern void UartDrv_EnableLineBreakDetect(const UartDrvType *obj, bool isEnable); + +/*! \brief Initializes the UART driver module + * + * This function initializes UART driver by setting the register instance to it. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] reg : pointer to UART register instance + * \return: void + */ +extern void UartDrv_Init(UartDrvType *obj, UartRegType *pReg); + +/*! \brief DeInit the uart module to default + * + * Call back in the usage of low power or sleep requirements + * + * \param[in] obj :pointer to UART driver instance + * \return: void + */ +extern void UartDrv_DeInit(UartDrvType *obj); + +/*! \brief Read out from the rx buffer to the specific address and indicated how + * + * this function read out received datas from rx fifo + * + * \param[in] obj : pointer to UART driver instance + * \return: uint16_t : + * read-out value , if PE or FE or NF, return UARTDRV_READ_DATA_INVALID + */ +extern uint16_t UartDrv_RxData(const UartDrvType *obj); + +/*! \brief Transmit one data + * + * This function write one data to tx fifo + * + * \param[in] obj :pointer to UART driver instance + * \param[in] txDatabuf : the copy of data to be sent + * \return: void + */ +extern void UartDrv_TxData(UartDrvType *obj, uint16_t txDatabuf); + +/*! \brief Read out the current status flag + * + * This function get the expected status + * + * \param[in] obj : pointer to UART driver instance + * \param[in] status : which status want to get + * \return None + * - FALSE: + * - TRUE: some event happend + */ +extern bool UartDrv_GetStatus(const UartDrvType *obj, UartDrv_StatusType status); + +/*! \brief Clear the expected status + * + * This function clear the special status , can be conbination with more than one status + * + * \param[in] obj : pointer to UART driver instance + * \param[in] status : can used the combination of the UartDrv_IsrStatusIdxType + * to clear more than one bit interrupt flag; + * for example: if want to clear PE&FE: (UARTDRV_STATUS_RXUF | UARTDRV_STATUS_STATUS_PE) + * \return: void + */ +extern void UartDrv_ClearStatus(UartDrvType *obj, uint32_t status); + +/*! \brief Enable or Disable one or more than one interrupt source + * + * This function set the interrupt request action if condition matched + * + * \param[in] obj :pointer to UART driver instance + * \param[in] isrSrc : can used the more than one interrupt source once + * \param[in] isrEn : True(Enable) or false(Disable) + * \return: void + */ +extern void UartDrv_SetInterruptReq(UartDrvType *obj, uint32_t isrSrc, bool isrEn); + +/*! \brief Get one interrupt source is enable or disable + * + * This function gets one interrupt source is enable or disable + * + * \param[in] obj :pointer to UART driver instance + * \param[in] isrType :one interrupt source type + * \return: True(Enable) or false(Disable) + */ +extern bool UartDrv_IsInterruptEnabled(UartDrvType *obj, UartDrv_IsrSrcType isrType); + + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/wdg/wdg_drv.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/wdg/wdg_drv.c new file mode 100644 index 0000000..af686ee --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/wdg/wdg_drv.c @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "wdg_drv.h" +#include "wdg_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define WDGDRV_REFRESH_VALUE (0xB480A602U) /* refresh wdg counter value */ +#define WDGDRV_UNLOCK_VALUE (0xD928C520U) /* unlock wdg reg */ +#define WDGDRV_TO_RESET_VALUE (0xFFFFU) /* the wdg TOVAL configuration default value */ +#define WDGDRV_WIN_RESET_VALUE (0x0U) /* the wdg WIN configuration default value */ +#define WDGDRV_CLEAR_INT_FLAG_VALUE (0x1U) /* W1C, the wdg clear interrupt flag value */ + +/* Unlock WDG register */ +#define WDGDRV_UNLOCK(x) ((x)->CNT = WDGDRV_UNLOCK_VALUE) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void WdgDrv_Init(WdgDrvType *obj, struct _WdgRegType_ *reg) +{ + obj->reg = reg; +} + +void WdgDrv_Configure(WdgDrvType *obj, const WdgDrv_ConfigureType *userConfig) +{ + uint8_t enable = WdgReg_IsEnabled(obj->reg); + uint8_t update = WdgReg_IsEnabledUpdate(obj->reg); + uint8_t csd = WdgReg_IsDoneConfigSync(obj->reg); + + if((enable == 0x0u) && (update == 0x01u) && (csd == 0x01u)) + { + /* Clear the bits used for configuration */ + WdgRegType preReg = {0}; + preReg.CS &= ~(WDG_CS_CLK_MASK + | WDG_CS_WIN_MASK + | WDG_CS_PRES_MASK + | WDG_CS_INTR_MASK + | WDG_CS_UPDATE_MASK + | WDG_CS_TST_MASK + | WDG_CS_DEBUG_MASK + | WDG_CS_STOP_MASK); + /* pre-configuration: Construct CS register new value */ + WdgReg_SetClockSource(&preReg, (uint8_t)userConfig->clkSource); + WdgReg_EnableWinMode(&preReg, userConfig->winEnable); + WdgReg_EnablePrescaler(&preReg, userConfig->prescalerEnable); + WdgReg_EnableInterrupt(&preReg, userConfig->intEnable); + WdgReg_EnableUpdate(&preReg, userConfig->updateEnable); + WdgReg_EnableDebugMode(&preReg, userConfig->debugModeEnable); + WdgReg_EnableStopMode(&preReg, userConfig->stopModeEnable); + WdgReg_ClearInterruptFlag(&preReg, userConfig->flag); + WdgReg_Enable(&preReg, userConfig->enable); + WdgReg_SetTestMode(&preReg, (uint8_t)userConfig->testMode); + /* configuration: Construct register new value */ + WDGDRV_UNLOCK(obj->reg); + obj->reg->CS = preReg.CS; + obj->reg->TOVAL = userConfig->timeoutValue; + while(!WdgReg_IsSuccessConfig(obj->reg)) + { + /* Wait until the reconfiguration successful */ + } + while(!WdgReg_IsDoneConfigSync(obj->reg)) + { + /* Wait until the synchronization of new configuration done */ + } + if(userConfig->winEnable) + { + WdgReg_SetCntVal(obj->reg, WDGDRV_REFRESH_VALUE); + WDGDRV_UNLOCK(obj->reg); + obj->reg->WIN = userConfig->windowValue; + while(!WdgReg_IsDoneConfigSync(obj->reg)) + { + /* Wait until the synchronization of new configuration done */ + } + } + } +} + +void WdgDrv_GetDefaultConfig(WdgDrv_ConfigureType *userConfig) +{ + userConfig->clkSource = WDGDRV_CLK_SRC_LPO128K; + userConfig->winEnable = 0x0u; + userConfig->flag = WDGDRV_CLEAR_INT_FLAG_VALUE; + userConfig->prescalerEnable = 0x0u; + userConfig->enable = 0x0u; + userConfig->intEnable = 0x0u; + userConfig->updateEnable = 0x1u; + userConfig->debugModeEnable = 0x0u; + userConfig->stopModeEnable = 0x0u; + userConfig->timeoutValue = WDGDRV_TO_RESET_VALUE; + userConfig->windowValue = WDGDRV_WIN_RESET_VALUE; + userConfig->testMode = WDGDRV_TEST_MODE_DISABLED; +} + +void WdgDrv_GetCurrentConfig(const WdgDrvType *obj, WdgDrv_ConfigureType *userConfig) +{ + userConfig->clkSource = (WdgDrv_ClkSrcType)WdgReg_GetClockSource(obj->reg); + userConfig->winEnable = WdgReg_IsEnabledWinMode(obj->reg); + userConfig->flag = WdgReg_GetInterruptFlag(obj->reg); + userConfig->prescalerEnable = WdgReg_IsEnabledPrescaler(obj->reg); + userConfig->enable = WdgReg_IsEnabled(obj->reg); + userConfig->intEnable = WdgReg_IsEnabledInterrupt(obj->reg); + userConfig->updateEnable = WdgReg_IsEnabledUpdate(obj->reg); + userConfig->debugModeEnable = WdgReg_IsEnabledDebugMode(obj->reg); + userConfig->stopModeEnable = WdgReg_IsEnabledStopMode(obj->reg); + userConfig->timeoutValue = WdgReg_GetToval(obj->reg); + userConfig->windowValue = WdgReg_GetWinVal(obj->reg); + userConfig->testMode = (WdgDrv_TestModeType)WdgReg_GetTestModeStatus(obj->reg); +} + +void WdgDrv_Enable(WdgDrvType *obj) +{ + uint8_t update = WdgReg_IsEnabledUpdate(obj->reg); + /* If allowed reconfigures WDG */ + if(update == 0x01u) + { + uint32_t csTmp = obj->reg->CS; + csTmp &= ~(WDG_CS_EN_MASK); + csTmp |= (((uint32_t)(((uint32_t)(true)) << WDG_CS_EN_SHIFT)) & WDG_CS_EN_MASK); + WDGDRV_UNLOCK(obj->reg); + obj->reg->CS = csTmp; + while(WdgReg_IsUnlocked(obj->reg)) + { + /* Wait until the unlock window closes */ + } + } +} + +void WdgDrv_Disable(WdgDrvType *obj) +{ + uint8_t update = WdgReg_IsEnabledUpdate(obj->reg); + /* If allowed reconfigures WDG */ + if(update == 0x01u) + { + WDGDRV_UNLOCK(obj->reg); + obj->reg->CS &= ~((uint32_t)WDG_CS_EN_MASK); + /* reset timeout value for the WDG */ + obj->reg->TOVAL = WDGDRV_TO_RESET_VALUE; + while(WdgReg_IsUnlocked(obj->reg)) + { + /* Wait until the unlock window closes */ + } + while(!WdgReg_IsDoneConfigSync(obj->reg)) + { + /* Wait until the synchronization of new configuration done */ + } + } +} + +void WdgDrv_SetInt(WdgDrvType *obj, bool enable) +{ + uint8_t update = WdgReg_IsEnabledUpdate(obj->reg); + /* If allowed reconfigures WDG */ + if(update == 0x01u) + { + uint32_t csTmp = obj->reg->CS; + csTmp &= ~(WDG_CS_INTR_MASK); + csTmp |= (((uint32_t)(((uint32_t)(enable)) << WDG_CS_INTR_SHIFT)) & WDG_CS_INTR_MASK); + WDGDRV_UNLOCK(obj->reg); + obj->reg->CS = csTmp; + while(WdgReg_IsUnlocked(obj->reg)) + { + /* Wait until the unlock window closes */ + } + } +} + +void WdgDrv_ClearIntFlag(WdgDrvType *obj) +{ + /* Clear interrupt flag of the WDG, W1C*/ + WDGDRV_UNLOCK(obj->reg); + WdgReg_ClearInterruptFlag(obj->reg, WDGDRV_CLEAR_INT_FLAG_VALUE); +} + +void WdgDrv_Refresh(WdgDrvType *obj) +{ + WdgReg_SetCntVal(obj->reg, WDGDRV_REFRESH_VALUE); +} + +uint32_t WdgDrv_GetCnt(const WdgDrvType *obj) +{ + return WdgReg_GetCntVal(obj->reg); +} + +void WdgDrv_SetWindow(WdgDrvType *obj, uint32_t winVal, bool enable) +{ + uint8_t update = WdgReg_IsEnabledUpdate(obj->reg); + /* If allowed reconfigures WDG */ + if(update == 0x01u) + { + uint32_t csTmp = obj->reg->CS; + csTmp &= ~(WDG_CS_WIN_MASK); + csTmp |= (((uint32_t)(((uint32_t)(enable)) << WDG_CS_WIN_SHIFT)) & WDG_CS_WIN_MASK); + WDGDRV_UNLOCK(obj->reg); + obj->reg->CS = csTmp; + /* Set window value for the WDG */ + obj->reg->WIN = winVal; + while(WdgReg_IsUnlocked(obj->reg)) + { + /* Wait until the unlock window closes */ + } + } +} + +void WdgDrv_SetStopMode(WdgDrvType *obj, bool enable) +{ + uint8_t update = WdgReg_IsEnabledUpdate(obj->reg); + /* If allowed reconfigures WDG */ + if(update == 0x01u) + { + uint32_t csTmp = obj->reg->CS; + csTmp &= ~(WDG_CS_STOP_MASK); + csTmp |= (((uint32_t)(((uint32_t)(enable)) << WDG_CS_STOP_SHIFT)) & WDG_CS_STOP_MASK); + WDGDRV_UNLOCK(obj->reg); + /* Set stop mode */ + obj->reg->CS = csTmp; + while(WdgReg_IsUnlocked(obj->reg)) + { + /* Wait until the unlock window closes */ + } + } +} + +void WdgDrv_SetTimeout(WdgDrvType *obj, uint32_t toval) +{ + uint8_t update = WdgReg_IsEnabledUpdate(obj->reg); + /* If allowed reconfigures WDG */ + if(update == 0x01u) + { + WDGDRV_UNLOCK(obj->reg); + /* Set timeout value for the WDG */ + WdgReg_SetToval(obj->reg, toval); + while(WdgReg_IsUnlocked(obj->reg)) + { + /* Wait until the unlock window closes */ + } + } +} + +void WdgDrv_SetTestMode(WdgDrvType *obj, WdgDrv_TestModeType type) +{ + uint8_t update = WdgReg_IsEnabledUpdate(obj->reg); + /* If allowed reconfigures WDG */ + if(update == 0x01u) + { + uint32_t csTmp = obj->reg->CS; + csTmp &= ~(WDG_CS_TST_MASK | WDG_CS_EN_MASK); + csTmp |= (((uint32_t)(((uint32_t)(type)) << WDG_CS_TST_SHIFT)) & WDG_CS_TST_MASK); + csTmp |= (((uint32_t)(((uint32_t)(1)) << WDG_CS_EN_SHIFT)) & WDG_CS_EN_MASK); + WDGDRV_UNLOCK(obj->reg); + /* Set test mode */ + obj->reg->CS = csTmp; + while(WdgReg_IsUnlocked(obj->reg)) + { + /* Wait until the unlock window closes */ + } + } +} + +WdgDrv_TestModeType WdgDrv_GetTestMode(const WdgDrvType *obj) +{ + /* Get test mode configuration type */ + uint8_t testModeType = WdgReg_GetTestModeStatus(obj->reg); + /* Gets test mode */ + return ((WdgDrv_TestModeType)testModeType); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/wdg/wdg_drv.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/wdg/wdg_drv.h new file mode 100644 index 0000000..c11409f --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/drivers/wdg/wdg_drv.h @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _WDG_DRV_H_ +#define _WDG_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of WDG module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ +#include +#include + +/*! \addtogroup wdg_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Definition of mode options available for the clock source type + */ +typedef enum +{ + WDGDRV_CLK_SRC_BUS = 0x00U, /*!< Bus clock */ + WDGDRV_CLK_SRC_LPO128K = 0x01U, /*!< LPO128 clock */ + WDGDRV_CLK_SRC_SOSC = 0x02U, /*!< SOSC clock */ + WDGDRV_CLK_SRC_SIRC = 0x03U, /*!< SIRC clock */ + WDGDRV_CLK_SRC_LPO32K = 0x04U, /*!< LPO32 clock */ + WDGDRV_CLK_SRC_LPO1K = 0x05U, /*!< LPO1 clock */ +} WdgDrv_ClkSrcType; + +/*! \brief Definition of mode options available for the TEST mode + */ +typedef enum +{ + WDGDRV_TEST_MODE_DISABLED = 0x00U, /*!< Test mode disabled */ + WDGDRV_TEST_MODE_USER = 0x01U, /*!< User mode enabled. (Test mode disabled.) */ + WDGDRV_TEST_MODE_LOW = 0x02U, /*!< Test mode enabled, only the low byte is used. */ + WDGDRV_TEST_MODE_HIGH = 0x03U /*!< Test mode enabled, only the high byte is used. */ +} WdgDrv_TestModeType; + +/*! \brief Definition of configuration of WDG driver + */ +typedef struct _WdgDrv_ConfigureType_ +{ + WdgDrv_ClkSrcType clkSource; /*!< RW, The clock source of the WDOG */ + uint8_t winEnable; /*!< RW, If true, window mode is enabled */ + uint8_t flag; /*!< W1C, If true, clear wdg interrupt flag */ + uint8_t prescalerEnable; /*!< RW, If true, a fixed 256 prescaling of the counter reference clock is enabled */ + uint8_t enable; /*!< RW, If true, the WDOG are enabled */ + uint8_t intEnable; /*!< RW, If true, an interrupt request is generated before reset */ + uint8_t updateEnable; /*!< RW, If true, further updates of the WDOG are enabled */ + WdgDrv_TestModeType testMode; /*!< RW, Test mode */ + uint8_t debugModeEnable; /*!< RW, Debug mode */ + uint8_t stopModeEnable; /*!< RW, Stop mode */ + uint32_t windowValue; /*!< RW, The window value */ + uint32_t timeoutValue; /*!< RW, The timeout value */ + +} WdgDrv_ConfigureType; + +/*! \brief Forward declaration of WDG register + */ +struct _WdgRegType_; + +/*! \brief The definition of WDG driver class + */ +typedef struct _WdgDrvType_ +{ + struct _WdgRegType_ *reg; /*!< pointer to WDG register */ +} WdgDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the WDG driver module + * + * This function initializes WDG driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to WDG driver instance + * \param[in] reg : pointer to WDG register instance + */ +extern void WdgDrv_Init(WdgDrvType *obj, struct _WdgRegType_ *reg); + +/*! \brief Get default configures the WDG module for configuration structure + * + * This function gets default configures the WDG module for user configuration structure + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void WdgDrv_GetDefaultConfig(WdgDrv_ConfigureType *userConfig); + +/*! \brief Configures the WDG module from a user configuration structure + * + * This function configures the WDG module from a user configuration structure + * + * \param[in] obj : pointer to WDG driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void WdgDrv_Configure(WdgDrvType *obj, const WdgDrv_ConfigureType *userConfig); + +/*! \brief Get current configures the WDG module for configuration structure + * + * This function gets current configures the WDG module for user configuration structure + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void WdgDrv_GetCurrentConfig(const WdgDrvType *obj, WdgDrv_ConfigureType *userConfig); + +/*! \brief Enable the WDG module currently + * + * This function enable the WDG module currently + * + * \param[in] obj : pointer to WDG driver instance + */ +extern void WdgDrv_Enable(WdgDrvType *obj); + +/*! \brief Disable the WDG module currently + * + * This function Disable the WDG module currently + * + * \param[in] obj : pointer to WDG driver instance + */ +extern void WdgDrv_Disable(WdgDrvType *obj); + +/*! + * \brief Enables/Disables the WDG Interrupt. + * + * This function enables/disables the WDG Interrupt. + * + * \param[in] obj : pointer to WDG driver instance + * \param[in] enable : enable/disable WDG Interrupt. + */ +extern void WdgDrv_SetInt(WdgDrvType *obj, bool enable); + +/*! + * \brief Clear the WDG Interrupt flag. + * + * This function Clear the WDG Interrupt flag. + * + * \param[in] obj : pointer to WDG driver instance + */ +extern void WdgDrv_ClearIntFlag(WdgDrvType *obj); + +/*! + * \brief refresh the WDG counter value. + * + * This function refresh the WDG counter. + * + * \param[in] obj : pointer to WDG driver instance + */ +extern void WdgDrv_Refresh(WdgDrvType *obj); + +/*! + * \brief Enables/Disables the WDG window mode. + * + * This function enables/Disables the WDG window mode. + * + * \param[in] obj : pointer to WDG driver instance + * \param[in] winVal : pointer to window value. + * \param[in] enable : enable/disable WDG Interrupt. + */ +extern void WdgDrv_SetWindow(WdgDrvType *obj, uint32_t winVal, bool enable); + +/*! + * \brief Enables/Disables the WDG stop mode. + * + * This function enables/disables the WDG stop mode. + * + * \param[in] obj : pointer to WDG driver instance + * \param[in] enable : enable/disable WDG stop mode. + */ +extern void WdgDrv_SetStopMode(WdgDrvType *obj, bool enable); + +/*! + * \brief set timeout value. + * + * This function set timeout value. + * + * \param[in] obj : pointer to WDG driver instance + * \param[in] toval : set timeout value. + */ +extern void WdgDrv_SetTimeout(WdgDrvType *obj, uint32_t toval); + +/*! + * \brief Sets the WDG test mode. + * + * This function sets the WDG test mode. + * + * \param[in] obj : pointer to WDG driver instance + * \param[in] type set WDG test mode. + * - 000b: watchdog test mode disable + * - 001b: watchdog user mode enable. (watchdog test mode disabled) + * - 010b: watchdog test mode enabled, only the low byte is used. + * - 011b: watchdog test mode enabled, only the high byte is used. + */ +extern void WdgDrv_SetTestMode(WdgDrvType *obj, WdgDrv_TestModeType type); + +/*! + * \brief Get type of the WDG test mode. + * + * This function get type of the WDG test mode. + * + * \param[in] obj : pointer to WDG driver instance + * \param[out] func : test mode type. + */ +extern WdgDrv_TestModeType WdgDrv_GetTestMode(const WdgDrvType *obj); + +/*! + * \brief Get value of the WDG counter. + * + * This function get value of the WDG counter. + * + * \param[in] obj : pointer to WDG driver instance + * \param[out] func : CNT value. + */ +extern uint32_t WdgDrv_GetCnt(const WdgDrvType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/linker/CVM0114_flash.icf b/cva_asw_m0118/SDK/platform/devices/CVM011x/linker/CVM0114_flash.icf new file mode 100644 index 0000000..21ea4db --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/linker/CVM0114_flash.icf @@ -0,0 +1,117 @@ +/* +** ################################################################### +** Processor: CVM0116 +** Compiler: IAR ANSI C/C++ Compiler for ARM +** +** Abstract: +** Linker file for the IAR ANSI C/C++ Compiler for ARM +** +** Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD +** All rights reserved. +** +** Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use +** exclusively with CVA's microcontroller products. This file can be freely +** distributed within development tools that are supporting such microcontroller +** products. +** +** THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED +** OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. +** CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, +** OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +** +** http: www.cvachip.com +** +** ################################################################### +*/ + +/* If symbol __flash_vector_table__=1 is defined at link time + * the interrupt vector will not be copied to RAM. + * Warning: Using the interrupt vector from FLASH will not allow + * INT_SYS_InstallHandler because the section is Read Only. + */ +define symbol __ram_vector_table_size__ = isdefinedsymbol(__flash_vector_table__) ? 0 : 0x000000C0; +define symbol __ram_vector_table_offset__ = isdefinedsymbol(__flash_vector_table__) ? 0 : 0x00000000; + +/* Flash */ +define symbol m_interrupts_start = 0x00000000; +define symbol m_interrupts_end = 0x000000C0; + +define symbol m_flash_config_start = 0x00000400; +define symbol m_flash_config_end = 0x0000041F; + +define symbol m_text_start = 0x00000420; +define symbol m_text_end = 0x00010000; + +/* SRAM */ +define symbol m_interrupts_ram_start = 0x20000000; +define symbol m_interrupts_ram_end = 0x200003FF; + +define symbol m_data_start = 0x20000400; +define symbol m_data_end = 0x200023FF; + +define symbol m_data_2_start = 0x20002400; +define symbol m_data_2_end = 0x200043FF; + +/* Sizes */ +if (isdefinedsymbol(__stack_size__)) { + define symbol __size_cstack__ = __stack_size__; +} else { + define symbol __size_cstack__ = 0x00000200; +} + +if (isdefinedsymbol(__heap_size__)) { + define symbol __size_heap__ = __heap_size__; +} else { + define symbol __size_heap__ = 0x00000200; +} + +define exported symbol __VECTOR_TABLE = m_interrupts_start; +define exported symbol __VECTOR_RAM = isdefinedsymbol(__flash_vector_table__) ? m_interrupts_start : m_interrupts_ram_start; +define exported symbol __RAM_VECTOR_TABLE_SIZE = __ram_vector_table_size__; + +define exported symbol __RAM_START = m_interrupts_ram_start; +define exported symbol __RAM_END = m_data_2_end; + +define memory mem with size = 4G; +define region m_flash_config_region = mem:[from m_flash_config_start to m_flash_config_end]; +define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end] + | mem:[from m_text_start to m_text_end]; +define region DATA_region = mem:[from m_data_start to m_data_end]; +define region DATA_region_2 = mem:[from m_data_2_start to m_data_2_end-__size_cstack__]; +define region CSTACK_region = mem:[from m_data_2_end-__size_cstack__+1 to m_data_2_end]; +define region m_interrupts_ram_region = mem:[from m_interrupts_ram_start to m_interrupts_ram_end]; + + +define block CSTACK with alignment = 8, size = __size_cstack__ { }; +define block HEAP with alignment = 8, size = __size_heap__ { }; +define block RW { readwrite }; +define block ZI { zi }; + +/* Custom Section Block that can be used to place data at absolute address. */ +/* Use __attribute__((section (".customSection"))) to place data here. */ +define block customSectionBlock { section .customSection }; + +define block __CODE_ROM { section .textrw_init }; +define block __CODE_RAM { section .textrw }; + +initialize manually { section .textrw }; +initialize manually { section .bss }; +initialize manually { section .customSection }; +initialize manually { section .data }; +initialize manually { section __DLIB_PERTHREAD }; +do not initialize { section .noinit, section .bss, section .data, section __DLIB_PERTHREAD, section .customSection }; + +place at address mem: m_interrupts_start { readonly section .intvec }; +place in m_flash_config_region { section FlashConfig }; +place in TEXT_region { readonly }; +place in TEXT_region { block __CODE_ROM }; +place in DATA_region { block RW }; +place in DATA_region { block __CODE_RAM }; +place in DATA_region_2 { first block customSectionBlock }; +place in DATA_region_2 { block ZI }; +place in DATA_region_2 { last block HEAP }; +place in CSTACK_region { block CSTACK }; +place in m_interrupts_ram_region { section m_interrupts_ram }; + + diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/linker/CVM0114_ram.icf b/cva_asw_m0118/SDK/platform/devices/CVM011x/linker/CVM0114_ram.icf new file mode 100644 index 0000000..cde01d6 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/linker/CVM0114_ram.icf @@ -0,0 +1,93 @@ +/* +** ################################################################### +** Processor: CVM0116 +** Compiler: IAR ANSI C/C++ Compiler for ARM +** +** Abstract: +** Linker file for the IAR ANSI C/C++ Compiler for ARM +** +** Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD +** All rights reserved. +** +** Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use +** exclusively with CVA's microcontroller products. This file can be freely +** distributed within development tools that are supporting such microcontroller +** products. +** +** THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED +** OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. +** CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, +** OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +** +** http: www.cvachip.com +** +** ################################################################### +*/ + +/* SRAM_U */ +define symbol m_interrupts_start = 0x20000000; +define symbol m_interrupts_end = 0x200000BF; + +define symbol m_text_start = 0x200000C0; +define symbol m_text_end = 0x200020BF; + +define symbol m_custom_start = 0x200020C0; +define symbol m_custom_end = 0x200024BF; + +define symbol m_data_start = 0x200024C0; +define symbol m_data_end = 0x200043FF; + +/* Sizes */ +if (isdefinedsymbol(__stack_size__)) { + define symbol __size_cstack__ = __stack_size__; +} else { + define symbol __size_cstack__ = 0x00000200; +} + +if (isdefinedsymbol(__heap_size__)) { + define symbol __size_heap__ = __heap_size__; +} else { + define symbol __size_heap__ = 0x00000200; +} + +define exported symbol __VECTOR_TABLE = m_interrupts_start; +define exported symbol __VECTOR_RAM = m_interrupts_start; +define exported symbol __RAM_VECTOR_TABLE_SIZE = 0x0; + +define exported symbol __RAM_START = m_interrupts_start; +define exported symbol __RAM_END = m_data_end; + +define memory mem with size = 4G; +define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end] + | mem:[from m_text_start to m_text_end]; +define region DATA_region = mem:[from m_data_start to m_data_end-__size_cstack__]; +define region CSTACK_region = mem:[from m_data_end-__size_cstack__+1 to m_data_end]; + + +define block CSTACK with alignment = 8, size = __size_cstack__ { }; +define block HEAP with alignment = 8, size = __size_heap__ { }; +define block RW { readwrite }; +define block ZI { zi }; + +/* Custom Section Block that can be used to place data at absolute address. */ +/* Use __attribute__((section (".customSection"))) to place data here. */ +define block customSectionBlock { section .customSection }; +define block __CODE_RAM { section .textrw }; +define block __CODE_ROM { section .textrw_init }; + +initialize manually { section .bss }; +initialize manually { section .customSection }; +initialize manually { section .textrw }; +initialize manually { section __DLIB_PERTHREAD }; +do not initialize { section .noinit, section .bss, section __DLIB_PERTHREAD, section .customSection }; + +place at address mem: m_interrupts_start { readonly section .intvec }; +place in TEXT_region { readonly }; +place in TEXT_region { block __CODE_ROM }; +place in DATA_region { first block customSectionBlock }; +place in DATA_region { block RW }; +place in DATA_region { block __CODE_RAM }; +place in DATA_region { block ZI }; +place in DATA_region { last block HEAP }; +place in CSTACK_region { block CSTACK }; \ No newline at end of file diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/linker/CVM0116_flash.icf b/cva_asw_m0118/SDK/platform/devices/CVM011x/linker/CVM0116_flash.icf new file mode 100644 index 0000000..b9e1358 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/linker/CVM0116_flash.icf @@ -0,0 +1,117 @@ +/* +** ################################################################### +** Processor: CVM0116 +** Compiler: IAR ANSI C/C++ Compiler for ARM +** +** Abstract: +** Linker file for the IAR ANSI C/C++ Compiler for ARM +** +** Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD +** All rights reserved. +** +** Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use +** exclusively with CVA's microcontroller products. This file can be freely +** distributed within development tools that are supporting such microcontroller +** products. +** +** THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED +** OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. +** CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, +** OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +** +** http: www.cvachip.com +** +** ################################################################### +*/ + +/* If symbol __flash_vector_table__=1 is defined at link time + * the interrupt vector will not be copied to RAM. + * Warning: Using the interrupt vector from FLASH will not allow + * INT_SYS_InstallHandler because the section is Read Only. + */ +define symbol __ram_vector_table_size__ = isdefinedsymbol(__flash_vector_table__) ? 0 : 0x000000C0; +define symbol __ram_vector_table_offset__ = isdefinedsymbol(__flash_vector_table__) ? 0 : 0x00000000; + +/* Flash */ +define symbol m_interrupts_start = 0x00000000; +define symbol m_interrupts_end = 0x000000BF; + +define symbol m_flash_config_start = 0x00000400; +define symbol m_flash_config_end = 0x0000041F; + +define symbol m_text_start = 0x00000420; +define symbol m_text_end = 0x0001FFFF; + +/* SRAM */ +define symbol m_interrupts_ram_start = 0x20000000; +define symbol m_interrupts_ram_end = 0x200003FF; + +define symbol m_data_start = 0x20000400; +define symbol m_data_end = 0x200023FF; + +define symbol m_data_2_start = 0x20002400; +define symbol m_data_2_end = 0x200043FF; + +/* Sizes */ +if (isdefinedsymbol(__stack_size__)) { + define symbol __size_cstack__ = __stack_size__; +} else { + define symbol __size_cstack__ = 0x00000200; +} + +if (isdefinedsymbol(__heap_size__)) { + define symbol __size_heap__ = __heap_size__; +} else { + define symbol __size_heap__ = 0x00000200; +} + +define exported symbol __VECTOR_TABLE = m_interrupts_start; +define exported symbol __VECTOR_RAM = isdefinedsymbol(__flash_vector_table__) ? m_interrupts_start : m_interrupts_ram_start; +define exported symbol __RAM_VECTOR_TABLE_SIZE = __ram_vector_table_size__; + +define exported symbol __RAM_START = m_interrupts_ram_start; +define exported symbol __RAM_END = m_data_2_end; + +define memory mem with size = 4G; +define region m_flash_config_region = mem:[from m_flash_config_start to m_flash_config_end]; +define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end] + | mem:[from m_text_start to m_text_end]; +define region DATA_region = mem:[from m_data_start to m_data_end]; +define region DATA_region_2 = mem:[from m_data_2_start to m_data_2_end-__size_cstack__]; +define region CSTACK_region = mem:[from m_data_2_end-__size_cstack__+1 to m_data_2_end]; +define region m_interrupts_ram_region = mem:[from m_interrupts_ram_start to m_interrupts_ram_end]; + + +define block CSTACK with alignment = 8, size = __size_cstack__ { }; +define block HEAP with alignment = 8, size = __size_heap__ { }; +define block RW { readwrite }; +define block ZI { zi }; + +/* Custom Section Block that can be used to place data at absolute address. */ +/* Use __attribute__((section (".customSection"))) to place data here. */ +define block customSectionBlock { section .customSection }; + +define block __CODE_ROM { section .textrw_init }; +define block __CODE_RAM { section .textrw }; + +initialize manually { section .textrw }; +initialize manually { section .bss }; +initialize manually { section .customSection }; +initialize manually { section .data }; +initialize manually { section __DLIB_PERTHREAD }; +do not initialize { section .noinit, section .bss, section .data, section __DLIB_PERTHREAD, section .customSection }; + +place at address mem: m_interrupts_start { readonly section .intvec }; +place in m_flash_config_region { section FlashConfig }; +place in TEXT_region { readonly }; +place in TEXT_region { block __CODE_ROM }; +place in DATA_region { block RW }; +place in DATA_region { block __CODE_RAM }; +place in DATA_region_2 { first block customSectionBlock }; +place in DATA_region_2 { block ZI }; +place in DATA_region_2 { last block HEAP }; +place in CSTACK_region { block CSTACK }; +place in m_interrupts_ram_region { section m_interrupts_ram }; + + diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/linker/CVM0116_ram.icf b/cva_asw_m0118/SDK/platform/devices/CVM011x/linker/CVM0116_ram.icf new file mode 100644 index 0000000..cde01d6 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/linker/CVM0116_ram.icf @@ -0,0 +1,93 @@ +/* +** ################################################################### +** Processor: CVM0116 +** Compiler: IAR ANSI C/C++ Compiler for ARM +** +** Abstract: +** Linker file for the IAR ANSI C/C++ Compiler for ARM +** +** Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD +** All rights reserved. +** +** Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use +** exclusively with CVA's microcontroller products. This file can be freely +** distributed within development tools that are supporting such microcontroller +** products. +** +** THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED +** OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. +** CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, +** OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +** +** http: www.cvachip.com +** +** ################################################################### +*/ + +/* SRAM_U */ +define symbol m_interrupts_start = 0x20000000; +define symbol m_interrupts_end = 0x200000BF; + +define symbol m_text_start = 0x200000C0; +define symbol m_text_end = 0x200020BF; + +define symbol m_custom_start = 0x200020C0; +define symbol m_custom_end = 0x200024BF; + +define symbol m_data_start = 0x200024C0; +define symbol m_data_end = 0x200043FF; + +/* Sizes */ +if (isdefinedsymbol(__stack_size__)) { + define symbol __size_cstack__ = __stack_size__; +} else { + define symbol __size_cstack__ = 0x00000200; +} + +if (isdefinedsymbol(__heap_size__)) { + define symbol __size_heap__ = __heap_size__; +} else { + define symbol __size_heap__ = 0x00000200; +} + +define exported symbol __VECTOR_TABLE = m_interrupts_start; +define exported symbol __VECTOR_RAM = m_interrupts_start; +define exported symbol __RAM_VECTOR_TABLE_SIZE = 0x0; + +define exported symbol __RAM_START = m_interrupts_start; +define exported symbol __RAM_END = m_data_end; + +define memory mem with size = 4G; +define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end] + | mem:[from m_text_start to m_text_end]; +define region DATA_region = mem:[from m_data_start to m_data_end-__size_cstack__]; +define region CSTACK_region = mem:[from m_data_end-__size_cstack__+1 to m_data_end]; + + +define block CSTACK with alignment = 8, size = __size_cstack__ { }; +define block HEAP with alignment = 8, size = __size_heap__ { }; +define block RW { readwrite }; +define block ZI { zi }; + +/* Custom Section Block that can be used to place data at absolute address. */ +/* Use __attribute__((section (".customSection"))) to place data here. */ +define block customSectionBlock { section .customSection }; +define block __CODE_RAM { section .textrw }; +define block __CODE_ROM { section .textrw_init }; + +initialize manually { section .bss }; +initialize manually { section .customSection }; +initialize manually { section .textrw }; +initialize manually { section __DLIB_PERTHREAD }; +do not initialize { section .noinit, section .bss, section __DLIB_PERTHREAD, section .customSection }; + +place at address mem: m_interrupts_start { readonly section .intvec }; +place in TEXT_region { readonly }; +place in TEXT_region { block __CODE_ROM }; +place in DATA_region { first block customSectionBlock }; +place in DATA_region { block RW }; +place in DATA_region { block __CODE_RAM }; +place in DATA_region { block ZI }; +place in DATA_region { last block HEAP }; +place in CSTACK_region { block CSTACK }; \ No newline at end of file diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/linker/CVM0118_flash.icf b/cva_asw_m0118/SDK/platform/devices/CVM011x/linker/CVM0118_flash.icf new file mode 100644 index 0000000..72d6c70 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/linker/CVM0118_flash.icf @@ -0,0 +1,117 @@ +/* +** ################################################################### +** Processor: CVM0118 +** Compiler: IAR ANSI C/C++ Compiler for ARM +** +** Abstract: +** Linker file for the IAR ANSI C/C++ Compiler for ARM +** +** Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD +** All rights reserved. +** +** Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use +** exclusively with CVA's microcontroller products. This file can be freely +** distributed within development tools that are supporting such microcontroller +** products. +** +** THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED +** OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. +** CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, +** OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +** +** http: www.cvachip.com +** +** ################################################################### +*/ + +/* If symbol __flash_vector_table__=1 is defined at link time + * the interrupt vector will not be copied to RAM. + * Warning: Using the interrupt vector from FLASH will not allow + * INT_SYS_InstallHandler because the section is Read Only. + */ +define symbol __ram_vector_table_size__ = isdefinedsymbol(__flash_vector_table__) ? 0 : 0x000000C0; +define symbol __ram_vector_table_offset__ = isdefinedsymbol(__flash_vector_table__) ? 0 : 0x00000000; + +/* Flash */ +define symbol m_interrupts_start = 0x00000000; +define symbol m_interrupts_end = 0x000000C0; + +define symbol m_flash_config_start = 0x00000400; +define symbol m_flash_config_end = 0x0000041F; + +define symbol m_text_start = 0x00000420; +define symbol m_text_end = 0x00037FFF; + +/* SRAM */ +define symbol m_interrupts_ram_start = 0x20000000; +define symbol m_interrupts_ram_end = 0x200003FF; + +define symbol m_data_start = 0x20000400; +define symbol m_data_end = 0x200033FF; + +define symbol m_data_2_start = 0x20003400; +define symbol m_data_2_end = 0x200063FF; + +/* Sizes */ +if (isdefinedsymbol(__stack_size__)) { + define symbol __size_cstack__ = __stack_size__; +} else { + define symbol __size_cstack__ = 0x00000200; +} + +if (isdefinedsymbol(__heap_size__)) { + define symbol __size_heap__ = __heap_size__; +} else { + define symbol __size_heap__ = 0x00000200; +} + +define exported symbol __VECTOR_TABLE = m_interrupts_start; +define exported symbol __VECTOR_RAM = isdefinedsymbol(__flash_vector_table__) ? m_interrupts_start : m_interrupts_ram_start; +define exported symbol __RAM_VECTOR_TABLE_SIZE = __ram_vector_table_size__; + +define exported symbol __RAM_START = m_interrupts_ram_start; +define exported symbol __RAM_END = m_data_2_end; + +define memory mem with size = 4G; +define region m_flash_config_region = mem:[from m_flash_config_start to m_flash_config_end]; +define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end] + | mem:[from m_text_start to m_text_end]; +define region DATA_region = mem:[from m_data_start to m_data_end]; +define region DATA_region_2 = mem:[from m_data_2_start to m_data_2_end-__size_cstack__]; +define region CSTACK_region = mem:[from m_data_2_end-__size_cstack__+1 to m_data_2_end]; +define region m_interrupts_ram_region = mem:[from m_interrupts_ram_start to m_interrupts_ram_end]; + + +define block CSTACK with alignment = 8, size = __size_cstack__ { }; +define block HEAP with alignment = 8, size = __size_heap__ { }; +define block RW { readwrite }; +define block ZI { zi }; + +/* Custom Section Block that can be used to place data at absolute address. */ +/* Use __attribute__((section (".customSection"))) to place data here. */ +define block customSectionBlock { section .customSection }; + +define block __CODE_ROM { section .textrw_init }; +define block __CODE_RAM { section .textrw }; + +initialize manually { section .textrw }; +initialize manually { section .bss }; +initialize manually { section .customSection }; +initialize manually { section .data }; +initialize manually { section __DLIB_PERTHREAD }; +do not initialize { section .noinit, section .bss, section .data, section __DLIB_PERTHREAD, section .customSection }; + +place at address mem: m_interrupts_start { readonly section .intvec }; +place in m_flash_config_region { section FlashConfig }; +place in TEXT_region { readonly }; +place in TEXT_region { block __CODE_ROM }; +place in DATA_region { block RW }; +place in DATA_region { block __CODE_RAM }; +place in DATA_region_2 { first block customSectionBlock }; +place in DATA_region_2 { block ZI }; +place in DATA_region_2 { last block HEAP }; +place in CSTACK_region { block CSTACK }; +place in m_interrupts_ram_region { section m_interrupts_ram }; + + diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/linker/CVM0118_ram.icf b/cva_asw_m0118/SDK/platform/devices/CVM011x/linker/CVM0118_ram.icf new file mode 100644 index 0000000..7f5a3af --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/linker/CVM0118_ram.icf @@ -0,0 +1,93 @@ +/* +** ################################################################### +** Processor: CVM0118 +** Compiler: IAR ANSI C/C++ Compiler for ARM +** +** Abstract: +** Linker file for the IAR ANSI C/C++ Compiler for ARM +** +** Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD +** All rights reserved. +** +** Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use +** exclusively with CVA's microcontroller products. This file can be freely +** distributed within development tools that are supporting such microcontroller +** products. +** +** THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED +** OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. +** CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, +** OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +** +** http: www.cvachip.com +** +** ################################################################### +*/ + +/* SRAM_U */ +define symbol m_interrupts_start = 0x20000000; +define symbol m_interrupts_end = 0x200000BF; + +define symbol m_text_start = 0x200000C0; +define symbol m_text_end = 0x200030BF; + +define symbol m_custom_start = 0x200030C0; +define symbol m_custom_end = 0x200034BF; + +define symbol m_data_start = 0x200034C0; +define symbol m_data_end = 0x200063FF; + +/* Sizes */ +if (isdefinedsymbol(__stack_size__)) { + define symbol __size_cstack__ = __stack_size__; +} else { + define symbol __size_cstack__ = 0x00000200; +} + +if (isdefinedsymbol(__heap_size__)) { + define symbol __size_heap__ = __heap_size__; +} else { + define symbol __size_heap__ = 0x00000200; +} + +define exported symbol __VECTOR_TABLE = m_interrupts_start; +define exported symbol __VECTOR_RAM = m_interrupts_start; +define exported symbol __RAM_VECTOR_TABLE_SIZE = 0x0; + +define exported symbol __RAM_START = m_interrupts_start; +define exported symbol __RAM_END = m_data_end; + +define memory mem with size = 4G; +define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end] + | mem:[from m_text_start to m_text_end]; +define region DATA_region = mem:[from m_data_start to m_data_end-__size_cstack__]; +define region CSTACK_region = mem:[from m_data_end-__size_cstack__+1 to m_data_end]; + + +define block CSTACK with alignment = 8, size = __size_cstack__ { }; +define block HEAP with alignment = 8, size = __size_heap__ { }; +define block RW { readwrite }; +define block ZI { zi }; + +/* Custom Section Block that can be used to place data at absolute address. */ +/* Use __attribute__((section (".customSection"))) to place data here. */ +define block customSectionBlock { section .customSection }; +define block __CODE_RAM { section .textrw }; +define block __CODE_ROM { section .textrw_init }; + +initialize manually { section .bss }; +initialize manually { section .customSection }; +initialize manually { section .textrw }; +initialize manually { section __DLIB_PERTHREAD }; +do not initialize { section .noinit, section .bss, section __DLIB_PERTHREAD, section .customSection }; + +place at address mem: m_interrupts_start { readonly section .intvec }; +place in TEXT_region { readonly }; +place in TEXT_region { block __CODE_ROM }; +place in DATA_region { first block customSectionBlock }; +place in DATA_region { block RW }; +place in DATA_region { block __CODE_RAM }; +place in DATA_region { block ZI }; +place in DATA_region { last block HEAP }; +place in CSTACK_region { block CSTACK }; \ No newline at end of file diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/mcu.c b/cva_asw_m0118/SDK/platform/devices/CVM011x/mcu.c new file mode 100644 index 0000000..077f3cc --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/mcu.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "mcu.h" +#include "drivers/cpu/startup/system_M011x.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void Mcu_Init(McuType *obj) +{ + /* Initialize ADC driver */ + AdcDrv_Init(&obj->adcDrv, ADC, SIM); + + /* Initialize clock driver */ + ClockDrv_InitParamsType clockInitParams; + clockInitParams.sircFreq = CPU_INT_SLOW_CLK_HZ; + clockInitParams.xtalClkFreq = CPU_XTAL_CLK_HZ; + clockInitParams.rtcClkInFreq = 0; + clockInitParams.tclkFreq[0] = 0; + clockInitParams.tclkFreq[1] = 0; + clockInitParams.tclkFreq[2] = 0; + ClockDrv_Init(&obj->clockDrv, RCM, PCC0, SCG0, SCG1, PCC1, SCG2, &clockInitParams); + + /* Initialize CMP driver */ + CmpDrv_Init(&obj->cmpDrv, CMP); + + /* Initialize CMU PLL driver */ + CmuDrv_Init(&obj->cmuPllDrv, CMU_PLL); + + /* Initialize CMU SOSC driver */ + CmuDrv_Init(&obj->cmuSoscDrv, CMU_SOSC); + + /* Initialize crc driver */ + CrcDrv_Init(&obj->crcDrv, CRC); + + /* Initialize rtc driver */ + EDmaDrv_Init(&obj->edmaDrv, DMA, DMAMUX); + + /* Initialize eim driver */ + EimDrv_Init(&obj->eimDrv, EIM); + + /* Initialize erm driver */ + ErmDrv_Init(&obj->ermDrv, ERM); + + /* Initialize fhu driver */ + FhuDrv_Init(&obj->fhuDrv, FHU); + + /* Initialize Flash driver */ + FlashDrv_Init(&obj->flashDrv, FTFC, SCG0); + + /* Initialize flexCAN driver */ + FlexCanDrv_InitHwParType initHwPar; + initHwPar.canRamNum = 2; + FlexCanDrv_Init(&obj->flexCanDrv, CAN, PCC1, PCC0, SCG0, SCG2, SIM, &initHwPar); + + /* Initialize IIC driver */ + I2cDrv_Init(&obj->i2cDrv0, I2C); + + /* Initialize I2SM driver */ + I2smDrv_Init(&obj->i2smDrv, I2SM, SIM); + + /* Initialize I2SS driver */ + I2ssDrv_Init(&obj->i2ssDrv, I2SS, SIM); + + /* Initialize LPIT driver */ + LpitDrv_Init(&obj->lpitDrv, LPIT); + + /* Initialize LPTMR driver */ + LptmrDrv_Init(&obj->lptmrDrv, LPTMR); + + /* Initialize MFT drivers */ + MftDrv_Init(&obj->mftDrv0, MFT0); + MftDrv_Init(&obj->mftDrv1, MFT1); + + /* Initialize mpu driver */ + MpuDrv_Init(&obj->mpuDrv, MPU); + + /* Initialize PDB driver */ + PdbDrv_Init(&obj->pdbDrv, PDB); + + /* Initialize PINS driver */ + PinsDrv_Init(&obj->pta, PORTA, GPIOA); + PinsDrv_Init(&obj->ptb, PORTB, GPIOB); + PinsDrv_Init(&obj->ptc, PORTC, GPIOC); + PinsDrv_Init(&obj->ptd, PORTD, GPIOD); + PinsDrv_Init(&obj->pte, PORTE, GPIOE); + + /* Initialize POWER driver */ + PowerDrv_Init(&obj->powerDrv, PMC, SCG2, SCG1, SCG0); + + /* Initialize PWMLITE driver */ + PwmLiteDrv_Init(&obj->pwmLiteDrv0, PWMLITE0, SIM); + PwmLiteDrv_Init(&obj->pwmLiteDrv1, PWMLITE1, SIM); + + /* Initialize reset driver */ + ResetDrv_Init(&obj->resetDrv, RCM, PCC1, PCC0); + + /* Initialize rtc driver */ + RtcDrv_Init(&obj->rtcDrv, RTC); + + /* Initialize SPI0&SPI1 driver */ + SpiDrv_Init(&obj->spiDrv0, SPI0); + SpiDrv_Init(&obj->spiDrv1, SPI1); + + /* Initialize TRGMUX driver */ + TrgMuxDrv_Init(&obj->trgMuxDrv, TRGMUX, SIM); + + /* Initialize UART0&UART1&UART2 driver */ + UartDrv_Init(&obj->uartDrv0, UART0); +#if FEATURE_UART_INSTANCE_NUM == 3 + UartDrv_Init(&obj->uartDrv1, UART1); +#endif + UartDrv_Init(&obj->uartDrv2, UART2); + + /* Initialize watchdog driver */ + WdgDrv_Init(&obj->wdgDrv, WDG); +} diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/mcu.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/mcu.h new file mode 100644 index 0000000..afabe00 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/mcu.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MCU_H_ +#define _MCU_H_ + +/*! \brief Contains public interface to various functions related + * to the MCAL (MCU Abstract Layer) module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "CVM011x_features.h" +#include "drivers/adc/adc_drv.h" +#include "drivers/clock/clock_drv.h" +#include "drivers/cmp/cmp_drv.h" +#include "drivers/cmu/cmu_drv.h" +#include "drivers/cpu/cpu_drv.h" +#include "drivers/crc/crc_drv.h" +#include "drivers/edma/edma_drv.h" +#include "drivers/eim/eim_drv.h" +#include "drivers/erm/erm_drv.h" +#include "drivers/fhu/fhu_drv.h" +#include "drivers/flash/flash_drv.h" +#include "drivers/flexcan/flexcan_drv.h" +#include "drivers/i2c/i2c_drv.h" +#include "drivers/i2sm/i2sm_drv.h" +#include "drivers/i2ss/i2ss_drv.h" +#include "drivers/lpit/lpit_drv.h" +#include "drivers/lptmr/lptmr_drv.h" +#include "drivers/mft/mft_drv.h" +#include "drivers/mpu/mpu_drv.h" +#include "drivers/pdb/pdb_drv.h" +#include "drivers/pins/pins_drv.h" +#include "drivers/power/power_drv.h" +#include "drivers/pwmlite/pwmlite_drv.h" +#include "drivers/reset/reset_drv.h" +#include "drivers/rtc/rtc_drv.h" +#include "drivers/spi/spi_drv.h" +#include "drivers/trgmux/trgmux_drv.h" +#include "drivers/uart/uart_drv.h" +#include "drivers/wdg/wdg_drv.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Definition of MCU prototype + */ +typedef struct _McuType_ +{ + AdcDrvType adcDrv; + ClockDrvType clockDrv; + CmpDrvType cmpDrv; + CmuDrvType cmuPllDrv; + CmuDrvType cmuSoscDrv; + CrcDrvType crcDrv; + EDmaDrvType edmaDrv; + EimDrvType eimDrv; + ErmDrvType ermDrv; + FhuDrvType fhuDrv; + FlashDrvType flashDrv; + FlexCanDrvType flexCanDrv; + I2cDrvType i2cDrv0; + I2smDrvType i2smDrv; + I2ssDrvType i2ssDrv; + LpitDrvType lpitDrv; + LptmrDrvType lptmrDrv; + MftDrvType mftDrv0; + MftDrvType mftDrv1; + MpuDrvType mpuDrv; + PdbDrvType pdbDrv; + PinsDrvType pta; + PinsDrvType ptb; + PinsDrvType ptc; + PinsDrvType ptd; + PinsDrvType pte; + PowerDrvType powerDrv; + PwmLiteDrvType pwmLiteDrv0; + PwmLiteDrvType pwmLiteDrv1; + ResetDrvType resetDrv; + RtcDrvType rtcDrv; + SpiDrvType spiDrv0; + SpiDrvType spiDrv1; + TrgMuxDrvType trgMuxDrv; + UartDrvType uartDrv0; +#if FEATURE_UART_INSTANCE_NUM == 3 + UartDrvType uartDrv1; +#endif + UartDrvType uartDrv2; + WdgDrvType wdgDrv; +} McuType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the MCU + * + * This function initializes MCU by setting up all the peripheral drivers + * + * \param[in] obj : pointer to MCU instance + */ +extern void Mcu_Init(McuType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _MCU_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/adc_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/adc_reg.h new file mode 100644 index 0000000..0477888 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/adc_reg.h @@ -0,0 +1,1284 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _ADC_REG_H_ +#define _ADC_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the ADC Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define ADC_REG_LOCK_KEY (0x0U) +#define ADC_REG_UNLOCK_KEY (0xA5D2C3C3U) + +/* Number of channels register for every ADC instance */ +#define ADC_REG_CH_COUNT (16U) + +/* CFG1 Bit Fields */ +#define ADC_CFG1_WITHOUT_W1C_MASK (0xFFFFFEFFu) +#define ADC_CFG1_CLRLTRG_MASK (0x100u) +#define ADC_CFG1_CLRLTRG_SHIFT (8u) +#define ADC_CFG1_CLRLTRG_WIDTH (1u) +#define ADC_CFG1_MODE_MASK (0x03u) +#define ADC_CFG1_MODE_SHIFT (0u) +#define ADC_CFG1_MODE_WIDTH (2u) + +/* CFG2 Bit Fields */ +#define ADC_CFG2_LEN_PWR_ON_MASK (0x3F0000u) +#define ADC_CFG2_LEN_PWR_ON_SHIFT (16u) +#define ADC_CFG2_LEN_PWR_ON_WIDTH (6u) +#define ADC_CFG2_LEN_SMPL_1ST_MASK (0xFF00u) +#define ADC_CFG2_LEN_SMPL_1ST_SHIFT (8u) +#define ADC_CFG2_LEN_SMPL_1ST_WIDTH (8u) +#define ADC_CFG2_LEN_SMPL_MASK (0xFFu) +#define ADC_CFG2_LEN_SMPL_SHIFT (0u) +#define ADC_CFG2_LEN_SMPL_WIDTH (8u) + +/* CV1 Bit Fields */ +#define ADC_CV1_CV_MASK (0xFFFFu) +#define ADC_CV1_CV_SHIFT (0u) +#define ADC_CV1_CV_WIDTH (16u) +#define ADC_CV2_CV_MASK (0xFFFFu) +#define ADC_CV2_CV_SHIFT (0u) +#define ADC_CV2_CV_WIDTH (16u) + +/* SC2 Bit Fields */ +#define ADC_SC2_WITHOUT_W1C_MASK (0xFFFFFFu) +#define ADC_SC2_TRGSTERR_MASK (0xF000000u) +#define ADC_SC2_TRGSTERR_SHIFT (24u) +#define ADC_SC2_TRGSTERR_WIDTH (4u) +#define ADC_SC2_TRGSTLAT_MASK (0xF0000u) +#define ADC_SC2_TRGSTLAT_SHIFT (16u) +#define ADC_SC2_TRGSTLAT_WIDTH (4u) +#define ADC_SC2_TRGPRNUM_MASK (0x6000u) +#define ADC_SC2_TRGPRNUM_SHIFT (13u) +#define ADC_SC2_TRGPRNUM_WIDTH (2u) +#define ADC_SC2_ADACT_MASK (0x80u) +#define ADC_SC2_ADACT_SHIFT (7u) +#define ADC_SC2_ADACT_WIDTH (1u) +#define ADC_SC2_ADTRG_MASK (0x40u) +#define ADC_SC2_ADTRG_SHIFT (6u) +#define ADC_SC2_ADTRG_WIDTH (1u) +#define ADC_SC2_ACFE_MASK (0x20u) +#define ADC_SC2_ACFE_SHIFT (5u) +#define ADC_SC2_ACFE_WIDTH (1u) +#define ADC_SC2_ACFGT_MASK (0x10u) +#define ADC_SC2_ACFGT_SHIFT (4u) +#define ADC_SC2_ACFGT_WIDTH (1u) +#define ADC_SC2_ACREN_MASK (0x08u) +#define ADC_SC2_ACREN_SHIFT (3u) +#define ADC_SC2_ACREN_WIDTH (1u) +#define ADC_SC2_DMAEN_MASK (0x04u) +#define ADC_SC2_DMAEN_SHIFT (2u) +#define ADC_SC2_DMAEN_WIDTH (1u) + +/* SC3 Bit Fields */ +#define ADC_SC3_ADC_PD_MASK (0x10000u) +#define ADC_SC3_ADC_PD_SHIFT (16u) +#define ADC_SC3_ADC_PD_WIDTH (1u) +#define ADC_SC3_STSEL_MASK (0x3000u) +#define ADC_SC3_STSEL_SHIFT (12u) +#define ADC_SC3_STSEL_WIDTH (2u) +#define ADC_SC3_STVCM_EN_MASK (0x800u) +#define ADC_SC3_STVCM_EN_SHIFT (11u) +#define ADC_SC3_STVCM_EN_WIDTH (1u) +#define ADC_SC3_CAL_GE_MASK (0x20u) +#define ADC_SC3_CAL_GE_SHIFT (5u) +#define ADC_SC3_CAL_GE_WIDTH (1u) +#define ADC_SC3_CAL_OFS_MASK (0x10u) +#define ADC_SC3_CAL_OFS_SHIFT (4u) +#define ADC_SC3_CAL_OFS_WIDTH (1u) +#define ADC_SC3_ADCO_MASK (0x08u) +#define ADC_SC3_ADCO_SHIFT (3u) +#define ADC_SC3_ADCO_WIDTH (1u) +#define ADC_SC3_AVGE_MASK (0x04u) +#define ADC_SC3_AVGE_SHIFT (2u) +#define ADC_SC3_AVGE_WIDTH (1u) +#define ADC_SC3_AVGS_MASK (0x03u) +#define ADC_SC3_AVGS_SHIFT (0u) +#define ADC_SC3_AVGS_WIDTH (2u) + +/* OFS Bit Fields */ +#define ADC_OFS_SUB_OFS_MASK (0x10000u) +#define ADC_OFS_SUB_OFS_SHIFT (16u) +#define ADC_OFS_SUB_OFS_WIDTH (1u) +#define ADC_OFS_VAL_OFS_MASK (0x7FFu) +#define ADC_OFS_VAL_OFS_SHIFT (0u) +#define ADC_OFS_VAL_OFS_WIDTH (11u) + +/* GE Bit Fields */ +#define ADC_GE_VAL_GE_MASK (0xFFFu) +#define ADC_GE_VAL_GE_SHIFT (0u) +#define ADC_GE_VAL_GE_WIDTH (12u) + +/* USRK Bit Fields */ +#define ADC_USRK_USER_KEY_MASK (0xFFFFFFFFu) +#define ADC_USRK_USER_KEY_SHIFT (0u) +#define ADC_USRK_USER_KEY_WIDTH (32u) + +/* SC Bit Fields */ +#define ADC_SC_COCO_MASK (0x80u) +#define ADC_SC_COCO_SHIFT (7u) +#define ADC_SC_COCO_WIDTH (1u) +#define ADC_SC_AIEN_MASK (0x40u) +#define ADC_SC_AIEN_SHIFT (6u) +#define ADC_SC_AIEN_WIDTH (1u) +#define ADC_SC_ADCH_MASK (0xFu) +#define ADC_SC_ADCH_SHIFT (0u) +#define ADC_SC_ADCH_WIDTH (4u) + +/* R Bit Fields */ +#define ADC_R_DATA_MASK (0x3FFFu) +#define ADC_R_DATA_SHIFT (0u) +#define ADC_R_DATA_WIDTH (14u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of ADC registers + */ +typedef struct _AdcRegType_ +{ + volatile uint32_t CFG1; /*!< Configs Register 1, Offset: 0000H */ + volatile uint32_t CFG2; /*!< Configs Register 2, Offset: 0004H */ + volatile uint32_t CV1; /*!< Compare Value 1, Offset: 0008H */ + volatile uint32_t CV2; /*!< Compare Value 2, Offset: 000CH */ + volatile uint32_t SC2; /*!< Status and Control Register 2, Offset: 0010H */ + volatile uint32_t SC3; /*!< Status and Control Register 3, Offset: 0014H */ + volatile uint32_t OFS; /*!< Offset Register, Offset: 0018H */ + volatile uint32_t GE; /*!< Error Gain Register, Offset: 001CH */ + volatile uint32_t USRK; /*!< User Key Register, Offset: 0020H */ + uint32_t RESERVED0[55]; /*!< reserverd block, Offset: 0024H */ + volatile uint32_t SC[ADC_REG_CH_COUNT]; /*!< Status and Control Register, Offset: 0100H */ + uint32_t RESERVED1[16]; /*!< reserverd block, Offset: 0160H */ + const volatile uint32_t R[ADC_REG_CH_COUNT]; /*!< Conversion Result Register, Offset: 0180H */ +} AdcRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Sets the Clear Latch Trigger in Trigger Handler Block + * + * This function sets the Clear Latch Trigger in Trigger Handler Block. + * Writing a 1 to this field clears all the latched triggers inside the trigger + * handler except the one under processing. Writing 0 has no effect. This is a + * write-only-one bit that self-clears immediately + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Clear Latch Trigger in Trigger Handler Block + */ +__attribute__((always_inline)) static inline void AdcReg_ClrTrg(AdcRegType *obj) +{ + uint32_t tmp = obj->CFG1; + + tmp &= ~ADC_CFG1_CLRLTRG_MASK; + tmp |= (((uint32_t)(((uint32_t)(1u)) << ADC_CFG1_CLRLTRG_SHIFT)) & ADC_CFG1_CLRLTRG_MASK); + obj->CFG1 = tmp; +} + +/*! \brief Gets the Conversion Mode Selection + * + * This function gets the current Conversion Mode Selection. + * Selects the ADC resolution. + * + * \param[in] obj : pointer to ADC register instance + * \return Conversion Mode Selection + * - 00b : 8-bit conversion. + * - x1b : 12-bit conversion. + * - 10b : 10-bit conversion. + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetCfg1Mode(const AdcRegType *obj) +{ + return ((obj->CFG1 & ADC_CFG1_MODE_MASK) >> ADC_CFG1_MODE_SHIFT); +} + +/*! \brief Sets the Conversion Mode Selection + * + * This function sets the Conversion Mode Selection. + * Selects the ADC resolution. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Conversion Mode Selection + * - 00b : 8-bit conversion. + * - x1b : 12-bit conversion. + * - 10b : 10-bit conversion. + */ +__attribute__((always_inline)) static inline void AdcReg_SetCfg1Mode(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CFG1; + tmp &= ADC_CFG1_WITHOUT_W1C_MASK; + tmp &= ~ADC_CFG1_MODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_CFG1_MODE_SHIFT)) & ADC_CFG1_MODE_MASK); + obj->CFG1 = tmp; +} + +/*! \brief Gets the POWER On Sample Delay Config + * + * This function gets the current POWER On Sample Delay Config. + * After ADC power on, this register configs delay time before sampling is + * started. The delay time is (LEN_PWR_ON+1)*clk_adc + * + * \param[in] obj : pointer to ADC register instance + * \return POWER On Sample Delay Config + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetCfg2LenPwrOn(const AdcRegType *obj) +{ + return ((obj->CFG2 & ADC_CFG2_LEN_PWR_ON_MASK) >> ADC_CFG2_LEN_PWR_ON_SHIFT); +} + +/*! \brief Sets the POWER On Sample Delay Config + * + * This function sets the POWER On Sample Delay Config. + * After ADC power on, this register configs delay time before sampling is + * started. The delay time is (LEN_PWR_ON+1)*clk_adc + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of POWER On Sample Delay Config + */ +__attribute__((always_inline)) static inline void AdcReg_SetCfg2LenPwrOn(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CFG2; + + tmp &= ~ADC_CFG2_LEN_PWR_ON_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_CFG2_LEN_PWR_ON_SHIFT)) & ADC_CFG2_LEN_PWR_ON_MASK); + obj->CFG2 = tmp; +} + +/*! \brief Gets the First Sample Delay Config + * + * This function gets the current First Sample Delay Config. + * After ADC power on or channel changes, the first sampling time needs to be + * LEN_SMPL added by LEN_SMPL_1ST, so the actual sample time is + * (LEN_SMPL_1ST+LEN_SMPL+1)*clk_adc + * + * \param[in] obj : pointer to ADC register instance + * \return First Sample Delay Config + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetCfg2LenSmpl1st(const AdcRegType *obj) +{ + return ((obj->CFG2 & ADC_CFG2_LEN_SMPL_1ST_MASK) >> ADC_CFG2_LEN_SMPL_1ST_SHIFT); +} + +/*! \brief Sets the First Sample Delay Config + * + * This function sets the First Sample Delay Config. + * After ADC power on or channel changes, the first sampling time needs to be + * LEN_SMPL added by LEN_SMPL_1ST, so the actual sample time is + * (LEN_SMPL_1ST+LEN_SMPL+1)*clk_adc + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of First Sample Delay Config + */ +__attribute__((always_inline)) static inline void AdcReg_SetCfg2LenSmpl1st(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CFG2; + + tmp &= ~ADC_CFG2_LEN_SMPL_1ST_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_CFG2_LEN_SMPL_1ST_SHIFT)) & ADC_CFG2_LEN_SMPL_1ST_MASK); + obj->CFG2 = tmp; +} + +/*! \brief Gets the ADC Sampling Time + * + * This function gets the current ADC Sampling Time. + * Configs ADC Sampling time, the actual time is (LEN_SMPL+1)*clk_adc + * + * \param[in] obj : pointer to ADC register instance + * \return ADC Sampling Time + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetCfg2LenSmpl(const AdcRegType *obj) +{ + return ((obj->CFG2 & ADC_CFG2_LEN_SMPL_MASK) >> ADC_CFG2_LEN_SMPL_SHIFT); +} + +/*! \brief Sets the ADC Sampling Time + * + * This function sets the ADC Sampling Time. + * Configs ADC Sampling time, the actual time is (LEN_SMPL+1)*clk_adc + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of ADC Sampling Time + */ +__attribute__((always_inline)) static inline void AdcReg_SetCfg2LenSmpl(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CFG2; + + tmp &= ~ADC_CFG2_LEN_SMPL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_CFG2_LEN_SMPL_SHIFT)) & ADC_CFG2_LEN_SMPL_MASK); + obj->CFG2 = tmp; +} + +/*! \brief Gets the compare value 1 + * + * This function gets the current compare value 1. + * + * \param[in] obj : pointer to ADC register instance + * \return compare value 1 + */ +__attribute__((always_inline)) static inline uint16_t AdcReg_GetCv1Cv(const AdcRegType *obj) +{ + return ((obj->CV1 & ADC_CV1_CV_MASK) >> ADC_CV1_CV_SHIFT); +} + +/*! \brief Sets the compare value 1 + * + * This function sets the compare value 1. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of compare value 1 + */ +__attribute__((always_inline)) static inline void AdcReg_SetCv1Cv(AdcRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->CV1; + + tmp &= ~ADC_CV1_CV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_CV1_CV_SHIFT)) & ADC_CV1_CV_MASK); + obj->CV1 = tmp; +} + +/*! \brief Gets the compare value 2 + * + * This function gets the current compare value 2. + * + * \param[in] obj : pointer to ADC register instance + * \return compare value 2 + */ +__attribute__((always_inline)) static inline uint16_t AdcReg_GetCv2Cv(const AdcRegType *obj) +{ + return ((obj->CV2 & ADC_CV2_CV_MASK) >> ADC_CV2_CV_SHIFT); +} + +/*! \brief Sets the compare value 2 + * + * This function sets the compare value 2. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of compare value 2 + */ +__attribute__((always_inline)) static inline void AdcReg_SetCv2Cv(AdcRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->CV2; + + tmp &= ~ADC_CV2_CV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_CV2_CV_SHIFT)) & ADC_CV2_CV_MASK); + obj->CV2 = tmp; +} + +/*! \brief Gets the Error in Multiplexed Trigger Request + * + * This function gets the current Error in Multiplexed Trigger Request. + * Each of these error signals indicate that a multiplexed hardware trigger + * request from a source has been missed, in which case the request has already + * been latched or is being serviced. Each bit in this field can be cleared by + * writing a 1 to it, and each bit corresponds to an individual trigger request: + * - Bit 24 corresponds to trigger request 0 + * - Bit 25 corresponds to trigger request 1 + * - Bit 26 corresponds to trigger request 2 + * - Bit 27 corresponds to trigger request 3 + * The read value of each bit in this field is interpreted individually + * + * \param[in] obj : pointer to ADC register instance + * \return Error in Multiplexed Trigger Request + * - 0b : No error has occurred + * - 1b : An error has occurred + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2TrgStErr(const AdcRegType *obj) +{ + return ((obj->SC2 & ADC_SC2_TRGSTERR_MASK) >> ADC_SC2_TRGSTERR_SHIFT); +} + +/*! \brief Sets the Error in Multiplexed Trigger Request + * + * This function sets the Error in Multiplexed Trigger Request. + * Each of these error signals indicate that a multiplexed hardware trigger + * request from a source has been missed, in which case the request has already + * been latched or is being serviced. Each bit in this field can be cleared by + * writing a 1 to it, and each bit corresponds to an individual trigger request: + * - Bit 24 corresponds to trigger request 0 + * - Bit 25 corresponds to trigger request 1 + * - Bit 26 corresponds to trigger request 2 + * - Bit 27 corresponds to trigger request 3 + * The read value of each bit in this field is interpreted individually + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Error in Multiplexed Trigger Request + * - 0b : No error has occurred + * - 1b : An error has occurred + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc2TrgStErr(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC2; + + tmp &= ~ADC_SC2_TRGSTERR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC2_TRGSTERR_SHIFT)) & ADC_SC2_TRGSTERR_MASK); + obj->SC2 = tmp; +} + +/*! \brief Gets the Trigger Status + * + * This function gets the current Trigger Status. + * Each of these status bits indicate that a multiplexed hardware trigger + * request from a source has been latched. Each bit in this field corresponds to + * an individual trigger request: + * - Bit 16 corresponds to trigger request 0 + * - Bit 17 corresponds to trigger request 1 + * - Bit 18 corresponds to trigger request 2 + * - Bit 19 corresponds to trigger request 3 + * The read value of each bit in this field is interpreted individually + * + * \param[in] obj : pointer to ADC register instance + * \return Trigger Status + * - 0b : No trigger request has been latched + * - 1b : A trigger request has been latched + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2TrgStLat(const AdcRegType *obj) +{ + return ((obj->SC2 & ADC_SC2_TRGSTLAT_MASK) >> ADC_SC2_TRGSTLAT_SHIFT); +} + +/*! \brief Gets the Trigger Process Number + * + * This function gets the current Trigger Process Number. + * Indicates the trigger number that is being serviced. + * This has to be qualified with the 1-bit value for the corresponding trigger + * latch status. + * - TRGPRNUM=00 is valid only if TRGSTLAT[16]=1 + * - TRGPRNUM=01 is valid only if TRGSTLAT[17]=1 + * - TRGPRNUM=10 is valid only if TRGSTLAT[18]=1 + * - TRGPRNUM=11 is valid only if TRGSTLAT[19]=1 + * + * \note Occasionally there may be a mismatch between the TRGPRNUM and the ideal + * trigger to be selected as per TRGSTLAT by Round Robin algorithm. This happens + * because of different operating clocks of the TRGSTLAT and the hardware logic. + * The TRGSTLAT is updated first with arrival of triggers, and then it is + * synchronized into the hardware clock. So, the hardware uses a delayed version + * of TRGSTLAT. Any trigger that arrives during the synchronization time is not + * presented to hardware immediately, but shows in TRGSTLAT + * + * \param[in] obj : pointer to ADC register instance + * \return Trigger Process Number + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2TrgPrNum(const AdcRegType *obj) +{ + return ((obj->SC2 & ADC_SC2_TRGPRNUM_MASK) >> ADC_SC2_TRGPRNUM_SHIFT); +} + +/*! \brief Gets the Conversion Active + * + * This function gets the current Conversion Active. + * Indicates that a conversion or hardware averaging is in progress. + * ADACT is set when a conversion is initiated and cleared when a conversion is + * completed or aborted. + * + * \param[in] obj : pointer to ADC register instance + * \return Conversion Active + * - 0b : Conversion not in progress. + * - 1b : Conversion in progress. + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2AdAct(const AdcRegType *obj) +{ + return ((obj->SC2 & ADC_SC2_ADACT_MASK) >> ADC_SC2_ADACT_SHIFT); +} + +/*! \brief Gets the Conversion Trigger state + * + * This function gets the current Conversion Trigger state. + * + * \param[in] obj : pointer to ADC register instance + * \return Conversion Trigger Select + * - 0b : trigger disable. + * - 1b : trigger enable. + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2AdTrg(const AdcRegType *obj) +{ + return ((obj->SC2 & ADC_SC2_ADTRG_MASK) >> ADC_SC2_ADTRG_SHIFT); +} + +/*! \brief Sets the Conversion Trigger state + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Conversion Trigger state select + * - 0b : trigger disable. + * - 1b : trigger enable. + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc2AdTrg(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC2; + + tmp &= ADC_SC2_WITHOUT_W1C_MASK; + tmp &= ~ADC_SC2_ADTRG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC2_ADTRG_SHIFT)) & ADC_SC2_ADTRG_MASK); + obj->SC2 = tmp; +} + +/*! \brief Gets the Compare Function Enable + * + * This function gets the current Compare Function Enable. + * Enables the compare function. + * + * \param[in] obj : pointer to ADC register instance + * \return Compare Function Enable + * - 0b : Compare function disabled. + * - 1b : Compare function enabled. + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2Acfe(const AdcRegType *obj) +{ + return ((obj->SC2 & ADC_SC2_ACFE_MASK) >> ADC_SC2_ACFE_SHIFT); +} + +/*! \brief Sets the Compare Function Enable + * + * This function sets the Compare Function Enable. + * Enables the compare function. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Compare Function Enable + * - 0b : Compare function disabled. + * - 1b : Compare function enabled. + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc2Acfe(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC2; + + tmp &= ADC_SC2_WITHOUT_W1C_MASK; + tmp &= ~ADC_SC2_ACFE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC2_ACFE_SHIFT)) & ADC_SC2_ACFE_MASK); + obj->SC2 = tmp; +} + +/*! \brief Gets the Compare Function Greater Than Enable + * + * This function gets the current Compare Function Greater Than Enable. + * Configures the compare function to check the conversion result relative to + * CV1 and CV2 based upon the value of ACREN. ACFE must be set for ACFGT to have + * any effect. + * + * \param[in] obj : pointer to ADC register instance + * \return Compare Function Greater Than Enable + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2AcFgt(const AdcRegType *obj) +{ + return ((obj->SC2 & ADC_SC2_ACFGT_MASK) >> ADC_SC2_ACFGT_SHIFT); +} + +/*! \brief Sets the Compare Function Greater Than Enable + * + * This function sets the Compare Function Greater Than Enable. + * Configures the compare function to check the conversion result relative to + * CV1 and CV2 based upon the value of ACREN. ACFE must be set for ACFGT to have + * any effect. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Compare Function Greater Than Enable + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc2AcFgt(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC2; + + tmp &= ADC_SC2_WITHOUT_W1C_MASK; + tmp &= ~ADC_SC2_ACFGT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC2_ACFGT_SHIFT)) & ADC_SC2_ACFGT_MASK); + obj->SC2 = tmp; +} + +/*! \brief Gets the Compare Function Range Enable + * + * This function gets the current Compare Function Range Enable. + * Configures the compare function to check if the conversion result of the + * input being monitored is either between or outside the range formed by CV1 + * and CV2 determined by the value of ACFGT. ACFE must be set for ACFGT to have + * any effect. + * + * \param[in] obj : pointer to ADC register instance + * \return Compare Function Range Enable + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2AcREn(const AdcRegType *obj) +{ + return ((obj->SC2 & ADC_SC2_ACREN_MASK) >> ADC_SC2_ACREN_SHIFT); +} + +/*! \brief Sets the Compare Function Range Enable + * + * This function sets the Compare Function Range Enable. + * Configures the compare function to check if the conversion result of the + * input being monitored is either between or outside the range formed by CV1 + * and CV2 determined by the value of ACFGT. ACFE must be set for ACFGT to have + * any effect. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Compare Function Range Enable + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc2AcREn(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC2; + + tmp &= ADC_SC2_WITHOUT_W1C_MASK; + tmp &= ~ADC_SC2_ACREN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC2_ACREN_SHIFT)) & ADC_SC2_ACREN_MASK); + obj->SC2 = tmp; +} + +/*! \brief Gets the DMA Enable + * + * This function gets the current DMA Enable. + * + * \param[in] obj : pointer to ADC register instance + * \return DMA Enable + * - 0b : DMA is disabled. + * - 1b : DMA is enabled and will assert the ADC DMA request during an + * ADC conversion complete event, which is indicated when any SCn[COCO] flag is + * asserted. + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2DmaEn(const AdcRegType *obj) +{ + return ((obj->SC2 & ADC_SC2_DMAEN_MASK) >> ADC_SC2_DMAEN_SHIFT); +} + +/*! \brief Sets the DMA Enable + * + * This function sets the DMA Enable. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of DMA Enable + * - 0b : DMA is disabled. + * - 1b : DMA is enabled and will assert the ADC DMA request + * during an ADC conversion complete event, which is indicated when any + * SCn[COCO] flag is asserted. + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc2DmaEn(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC2; + + tmp &= ADC_SC2_WITHOUT_W1C_MASK; + tmp &= ~ADC_SC2_DMAEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC2_DMAEN_SHIFT)) & ADC_SC2_DMAEN_MASK); + obj->SC2 = tmp; +} + +/*! \brief Gets the ADC Power Down + * + * This function gets the current ADC Power Down. + * + * \note It is recommended that powers on ADC first, and then configs other + * registers. + * + * \param[in] obj : pointer to ADC register instance + * \return ADC Power Down + * - 0b : power on + * - 1b : power down + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3AdcPD(const AdcRegType *obj) +{ + return ((obj->SC3 & ADC_SC3_ADC_PD_MASK) >> ADC_SC3_ADC_PD_SHIFT); +} + +/*! \brief Sets the ADC Power Down + * + * This function sets the ADC Power Down. + * + * \note It is recommended that powers on ADC first, and then configs other + * registers. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of ADC Power Down + * - 0b : power on + * - 1b : power down + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc3AdcPD(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC3; + + tmp &= ~ADC_SC3_ADC_PD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_ADC_PD_SHIFT)) & ADC_SC3_ADC_PD_MASK); + obj->SC3 = tmp; +} + +/*! \brief Gets the ADC Self-test Channel Select + * + * This function gets the current ADC Self-test Channel Select. + * + * \param[in] obj : pointer to ADC register instance + * \return ADC Self-test Channel Select + * - 00b : AVSS + * - 01b : 1/8*VREF + * - 10b : 1/2*VREF + * - 11b : 7/8*VREF + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3StSel(const AdcRegType *obj) +{ + return ((obj->SC3 & ADC_SC3_STSEL_MASK) >> ADC_SC3_STSEL_SHIFT); +} + +/*! \brief Sets the ADC Self-test Channel Select + * + * This function sets the ADC Self-test Channel Select. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of ADC Self-test Channel Select + * - 00b : AVSS + * - 01b : 1/8*VREF + * - 10b : 1/2*VREF + * - 11b : 7/8*VREF + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc3StSel(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC3; + + tmp &= ~ADC_SC3_STSEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_STSEL_SHIFT)) & ADC_SC3_STSEL_MASK); + obj->USRK = ADC_REG_UNLOCK_KEY; + obj->SC3 = tmp; + obj->USRK = ADC_REG_LOCK_KEY; +} + +/*! \brief Gets the ADC Self-test Common Mode Level Enable + * + * This function gets the current ADC Self-test Common Mode Level Enable. + * This configs the common mode level enable, which is used in calibration and + * self-test + * + * \param[in] obj : pointer to ADC register instance + * \return ADC Self-test Common Mode Level Enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3StVcmEn(const AdcRegType *obj) +{ + return ((obj->SC3 & ADC_SC3_STVCM_EN_MASK) >> ADC_SC3_STVCM_EN_SHIFT); +} + +/*! \brief Sets the ADC Self-test Common Mode Level Enable + * + * This function sets the ADC Self-test Common Mode Level Enable. + * This configs the common mode level enable, which is used in calibration and + * self-test + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of ADC Self-test Common Mode Level Enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc3StVcmEn(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC3; + + tmp &= ~ADC_SC3_STVCM_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_STVCM_EN_SHIFT)) & ADC_SC3_STVCM_EN_MASK); + obj->USRK = ADC_REG_UNLOCK_KEY; + obj->SC3 = tmp; + obj->USRK = ADC_REG_LOCK_KEY; +} + +/*! \brief Gets the Gain Error Calibration Start + * + * This function gets the current Gain Error Calibration Start. + * Write 1 to this bit to start gain error calibration. This bit is cleared by + * hardware when calibration finishes. + * + * \param[in] obj : pointer to ADC register instance + * \return Gain Error Calibration Start + * - 0b : gain error calibration is no ongoing + * - 1b : gain error calibration is in progress + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3CalGE(const AdcRegType *obj) +{ + return ((obj->SC3 & ADC_SC3_CAL_GE_MASK) >> ADC_SC3_CAL_GE_SHIFT); +} + +/*! \brief Sets the Gain Error Calibration Start + * + * This function sets the Gain Error Calibration Start. + * Write 1 to this bit to start gain error calibration. This bit is cleared by + * hardware when calibration finishes. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Gain Error Calibration Start + * - 0b : gain error calibration is no ongoing + * - 1b : gain error calibration is in progress + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc3CalGE(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC3; + + tmp &= ~ADC_SC3_CAL_GE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_CAL_GE_SHIFT)) & ADC_SC3_CAL_GE_MASK); + obj->SC3 = tmp; +} + +/*! \brief Gets the Offset Calibration Start + * + * This function gets the current Offset Calibration Start. + * Write 1 to this bit to start offset calibration. This bit is cleared by + * hardware when calibration finishes. + * + * \param[in] obj : pointer to ADC register instance + * \return Offset Calibration Start + * - 0b : offset calibration is no ongoing + * - 1b : offset calibration is in progress + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3CalOfs(const AdcRegType *obj) +{ + return ((obj->SC3 & ADC_SC3_CAL_OFS_MASK) >> ADC_SC3_CAL_OFS_SHIFT); +} + +/*! \brief Sets the Offset Calibration Start + * + * This function sets the Offset Calibration Start. + * Write 1 to this bit to start offset calibration. This bit is cleared by + * hardware when calibration finishes. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Offset Calibration Start + * - 0b : offset calibration is no ongoing + * - 1b : offset calibration is in progress + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc3CalOfs(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC3; + + tmp &= ~ADC_SC3_CAL_OFS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_CAL_OFS_SHIFT)) & ADC_SC3_CAL_OFS_MASK); + obj->SC3 = tmp; +} + +/*! \brief Gets the Continuous Conversion Enable + * + * This function gets the current Continuous Conversion Enable. + * Enables continuous conversions. + * + * \param[in] obj : pointer to ADC register instance + * \return Continuous Conversion Enable + * - 0b : One conversion will be performed (or one set of conversions, + * if AVGE is set) after a conversion is initiated. + * - 1b : Continuous conversions will be performed (or continuous sets + * of conversions, if AVGE is set) after a conversion is initiated. + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3Adco(const AdcRegType *obj) +{ + return ((obj->SC3 & ADC_SC3_ADCO_MASK) >> ADC_SC3_ADCO_SHIFT); +} + +/*! \brief Sets the Continuous Conversion Enable + * + * This function sets the Continuous Conversion Enable. + * Enables continuous conversions. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Continuous Conversion Enable + * - 0b : One conversion will be performed (or one set of + * conversions, if AVGE is set) after a conversion is initiated. + * - 1b : Continuous conversions will be performed (or + * continuous sets of conversions, if AVGE is set) after a conversion is + * initiated. + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc3Adco(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC3; + + tmp &= ~ADC_SC3_ADCO_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_ADCO_SHIFT)) & ADC_SC3_ADCO_MASK); + obj->SC3 = tmp; +} + +/*! \brief Gets the Hardware Average Enable + * + * This function gets the current Hardware Average Enable. + * Enables the hardware average function of the ADC. + * + * \param[in] obj : pointer to ADC register instance + * \return Hardware Average Enable + * - 0b : Hardware average function disabled. + * - 1b : Hardware average function enabled. + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3AvgE(const AdcRegType *obj) +{ + return ((obj->SC3 & ADC_SC3_AVGE_MASK) >> ADC_SC3_AVGE_SHIFT); +} + +/*! \brief Sets the Hardware Average Enable + * + * This function sets the Hardware Average Enable. + * Enables the hardware average function of the ADC. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Hardware Average Enable + * - 0b : Hardware average function disabled. + * - 1b : Hardware average function enabled. + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc3AvgE(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC3; + + tmp &= ~ADC_SC3_AVGE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_AVGE_SHIFT)) & ADC_SC3_AVGE_MASK); + obj->SC3 = tmp; +} + +/*! \brief Gets the Hardware Average Select + * + * This function gets the current Hardware Average Select. + * Determines how many ADC conversions will be averaged to create the ADC + * average result. + * + * \param[in] obj : pointer to ADC register instance + * \return Hardware Average Select + * - 00b : 4 samples averaged. + * - 01b : 8 samples averaged. + * - 10b : 16 samples averaged. + * - 11b : 32 samples averaged. + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3AvgS(const AdcRegType *obj) +{ + return ((obj->SC3 & ADC_SC3_AVGS_MASK) >> ADC_SC3_AVGS_SHIFT); +} + +/*! \brief Sets the Hardware Average Select + * + * This function sets the Hardware Average Select. + * Determines how many ADC conversions will be averaged to create the ADC + * average result. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Hardware Average Select + * - 00b : 4 samples averaged. + * - 01b : 8 samples averaged. + * - 10b : 16 samples averaged. + * - 11b : 32 samples averaged. + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc3AvgS(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC3; + + tmp &= ~ADC_SC3_AVGS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_AVGS_SHIFT)) & ADC_SC3_AVGS_MASK); + obj->SC3 = tmp; +} + +/*! \brief Gets the ADC Offset Addition Subtraction Flag + * + * This function gets the current ADC Offset Addition Subtraction Flag. + * This bit configs how offset is used in calibration. It can be set by hardware + * or software. + * + * \param[in] obj : pointer to ADC register instance + * \return ADC Offset Addition Subtraction Flag + * - 0b : ADC output will be added by VAL_OFS(ceiling to 4095) + * - 1b : ADC output will be subtracted by VAL_OFS(flooring to 4095) + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetOfsSubOfs(const AdcRegType *obj) +{ + return ((obj->OFS & ADC_OFS_SUB_OFS_MASK) >> ADC_OFS_SUB_OFS_SHIFT); +} + +/*! \brief Sets the ADC Offset Addition Subtraction Flag + * + * This function sets the ADC Offset Addition Subtraction Flag. + * This bit configs how offset is used in calibration. It can be set by hardware + * or software. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of ADC Offset Addition Subtraction Flag + * - 0b : ADC output will be added by VAL_OFS(ceiling to + * 4095) + * - 1b : ADC output will be subtracted by VAL_OFS(flooring + * to 4095) + */ +__attribute__((always_inline)) static inline void AdcReg_SetOfsSubOfs(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OFS; + + tmp &= ~ADC_OFS_SUB_OFS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_OFS_SUB_OFS_SHIFT)) & ADC_OFS_SUB_OFS_MASK); + obj->OFS = tmp; +} + +/*! \brief Gets the ADC Offset Value + * + * This function gets the current ADC Offset Value. + * Used in calibration to caculate the final result. It can be set by hardware + * or software + * + * \param[in] obj : pointer to ADC register instance + * \return ADC Offset Value + */ +__attribute__((always_inline)) static inline uint16_t AdcReg_GetOfsValOfs(const AdcRegType *obj) +{ + return ((obj->OFS & ADC_OFS_VAL_OFS_MASK) >> ADC_OFS_VAL_OFS_SHIFT); +} + +/*! \brief Sets the ADC Offset Value + * + * This function sets the ADC Offset Value. + * Used in calibration to caculate the final result. It can be set by hardware + * or software + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of ADC Offset Value + */ +__attribute__((always_inline)) static inline void AdcReg_SetOfsValOfs(AdcRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->OFS; + + tmp &= ~ADC_OFS_VAL_OFS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_OFS_VAL_OFS_SHIFT)) & ADC_OFS_VAL_OFS_MASK); + obj->OFS = tmp; +} + +/*! \brief Gets the ADC Gain Error Value + * + * This function gets the current ADC Gain Error Value. + * Used in gain error adjusting. It can be set by hardware or software. + * ADC output * 3072/VAL_GE is the gain erro + * + * \param[in] obj : pointer to ADC register instance + * \return ADC Gain Error Value + */ +__attribute__((always_inline)) static inline uint16_t AdcReg_GetGeValGE(const AdcRegType *obj) +{ + return ((obj->GE & ADC_GE_VAL_GE_MASK) >> ADC_GE_VAL_GE_SHIFT); +} + +/*! \brief Sets the ADC Gain Error Value + * + * This function sets the ADC Gain Error Value. + * Used in gain error adjusting. It can be set by hardware or software. + * ADC output * 3072/VAL_GE is the gain erro + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of ADC Gain Error Value + */ +__attribute__((always_inline)) static inline void AdcReg_SetGeValGE(AdcRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->GE; + + tmp &= ~ADC_GE_VAL_GE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_GE_VAL_GE_SHIFT)) & ADC_GE_VAL_GE_MASK); + obj->GE = tmp; +} + +/*! \brief Gets the Conversion Complete Flag + * + * This function gets the current Conversion Complete Flag. + * This is a read-only field that is set each time a conversion is completed + when one or more of the following is true: + * - The compare function is disabled SC2[ACFE]=0 and the hardware average + function is disabled SC3[AVGE]=0 + * If the compare result is true, then COCO is set upon completion of a + conversion if one or more of the following is true: + * - The compare function is enabled SC2[ACFE]=1 + * COCO is set upon completion of the selected number of conversions (determined + by AVGS) if one or more of the following is true: + * - The hardware average function is enabled SC3[AVGE]=1 + * COCO is cleared when one of the following is true: + - The respective SCn register is written + - The respective Rn register is read + * + * \param[in] obj : pointer to ADC register instance + * \param[in] channel : the channel number + * \return Conversion Complete Flag + * - 0b : Conversion is not completed. + * - 1b : Conversion is completed. + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetScCoCo(const AdcRegType *obj, uint8_t channel) +{ + return ((obj->SC[channel] & ADC_SC_COCO_MASK) >> ADC_SC_COCO_SHIFT); +} + +/*! \brief Gets the Interrupt Enable + * + * This function gets the current Interrupt Enable. + * Enables conversion complete interrupts. When COCO becomes set while the + * respective AIEN is high, an interrupt is asserted. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] channel : the channel number + * \return Interrupt Enable + * - 0b : Conversion complete interrupt is disabled. + * - 1b : Conversion complete interrupt is enabled. + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetScAIEn(const AdcRegType *obj, uint8_t channel) +{ + return ((obj->SC[channel] & ADC_SC_AIEN_MASK) >> ADC_SC_AIEN_SHIFT); +} + +/*! \brief Sets the Interrupt Enable + * + * This function sets the Interrupt Enable. + * Enables conversion complete interrupts. When COCO becomes set while the + * respective AIEN is high, an interrupt is asserted. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] channel : the channel number + * \param[in] value : the value of Interrupt Enable + * - 0b : Conversion complete interrupt is disabled. + * - 1b : Conversion complete interrupt is enabled. + */ +__attribute__((always_inline)) static inline void AdcReg_SetScAIEn(AdcRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->SC[channel]; + + tmp &= ~ADC_SC_AIEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC_AIEN_SHIFT)) & ADC_SC_AIEN_MASK); + obj->SC[channel] = tmp; +} + +/*! \brief Gets the Input channel select + * + * This function gets the current Input channel select. + * Selects one of the input channels. + * The successive approximation converter subsystem is turned off when the + * channel bits are all set (i.e.ADCH set to all 1s). This feature allows + * explicit disabling of the ADC and isolation of the input channel from all + * sources. Terminating continuous conversions this way prevents an additional + * single conversion from being performed. It is not necessary to set ADCH to + * all 1s to place the ADC in a low:power state when continuous conversions are + * not enabled because the module automatically enters a low:power state when a + * conversion completes. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] channel : the channel number + * \return Input channel select + * - 0x0 : External channel 0 is selected as ADC input + * - 0x1 : External channel 1 is selected as ADC input + * - 0x2 : External channel 2 is selected as ADC input + * - 0x3 : External channel 3 is selected as ADC input + * - 0x4 : External channel 4 is selected as ADC input + * - 0x5 : External channel 5 is selected as ADC input + * - 0x6 : External channel 6 is selected as ADC input + * - 0x7 : External channel 7 is selected as ADC input + * - 0x8 : External channel 8 is selected as ADC input + * - 0x9 : External channel 9 is selected as ADC input + * - 0xA : External channel 10 is selected as ADC input + * - 0xB : External channel 11 is selected as ADC input + * - 0xC : External channel 12 is selected as ADC input + * - 0xD : External channel 13 is selected as ADC input + * - 0xE : External channel 14 is selected as ADC input + * - 0xF : External channel 15 is selected as ADC input + * - 0x10 : VBUF_TSEN_LPVBG + * - 0x11 : VBUF_TSEN_LPVBG + * - 0x12 : VBG + * - 0x13 : monitor ldo output + * - 0x14 : monitor supply voltage(0.5*supply_voltage) + * - 0x15 : AVSS + * - 0x16 : AVSS + * - 0x17 : Self Test Voltage + * - 0x18 ~ 0x1E : Reserved + * - 0x1F : Module is disabled + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetScAdCh(const AdcRegType *obj, uint8_t channel) +{ + return ((obj->SC[channel] & ADC_SC_ADCH_MASK) >> ADC_SC_ADCH_SHIFT); +} + +/*! \brief Sets the Input channel select + * + * This function sets the Input channel select. + * Selects one of the input channels. + * The successive approximation converter subsystem is turned off when the + * channel bits are all set (i.e.ADCH set to all 1s). This feature allows + * explicit disabling of the ADC and isolation of the input channel from all + * sources. Terminating continuous conversions this way prevents an additional + * single conversion from being performed. It is not necessary to set ADCH to + * all 1s to place the ADC in a low:power state when continuous conversions are + * not enabled because the module automatically enters a low:power state when a + * conversion completes. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] channel : the channel number + * \param[in] value : the value of Input channel select + * - 0x0 : External channel 0 is selected as ADC input + * - 0x1 : External channel 1 is selected as ADC input + * - 0x2 : External channel 2 is selected as ADC input + * - 0x3 : External channel 3 is selected as ADC input + * - 0x4 : External channel 4 is selected as ADC input + * - 0x5 : External channel 5 is selected as ADC input + * - 0x6 : External channel 6 is selected as ADC input + * - 0x7 : External channel 7 is selected as ADC input + * - 0x8 : External channel 8 is selected as ADC input + * - 0x9 : External channel 9 is selected as ADC input + * - 0xA : External channel 10 is selected as ADC input + * - 0xB : External channel 11 is selected as ADC input + * - 0xC : External channel 12 is selected as ADC input + * - 0xD : External channel 13 is selected as ADC input + * - 0xE : External channel 14 is selected as ADC input + * - 0xF : External channel 15 is selected as ADC input + * - 0x10 : VBUF_TSEN_LPVBG + * - 0x11 : VBUF_TSEN_LPVBG + * - 0x12 : VBG + * - 0x13 : monitor ldo output + * - 0x14 : monitor supply voltage(0.5*supply_voltage) + * - 0x15 : AVSS + * - 0x16 : AVSS + * - 0x17 : Self Test Voltage + * - 0x18 ~ 0x1E : Reserved + * - 0x1F : Module is disabled + */ +__attribute__((always_inline)) static inline void AdcReg_SetScAdCh(AdcRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->SC[channel]; + + tmp &= ~ADC_SC_ADCH_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC_ADCH_SHIFT)) & ADC_SC_ADCH_MASK); + obj->SC[channel] = tmp; +} + +/*! \brief Gets the ADC data result + * + * This function gets the current ADC data result. + * \param[in] obj : pointer to ADC register instance + * \param[in] channel : the channel number + * \return ADC data result + */ +__attribute__((always_inline)) static inline uint16_t AdcReg_GetRData(const AdcRegType *obj, uint8_t channel) +{ + return ((obj->R[channel] & ADC_R_DATA_MASK) >> ADC_R_DATA_SHIFT); +} + +/*! \brief Abort ADC chn + * This function for software trigger ADC. + * \param[in] obj : pointer to ADC register instance + * \param[in] chn : expect abort channel number + */ +__attribute__((always_inline)) static inline void AdcReg_AbortChn(AdcRegType *obj, uint8_t chn) +{ + uint32_t tmp = obj->SC[chn]; + obj->SC[chn] = tmp; +} +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _ADC_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/axbs_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/axbs_reg.h new file mode 100644 index 0000000..5632b6b --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/axbs_reg.h @@ -0,0 +1,528 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _AXBS_REG_H_ +#define _AXBS_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the AXBS Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define AXBS_MASTER_NUM (8) + +/* CSR Bit Fields */ +#define AXBS_CSR_MERR7_MASK (0x80000000u) +#define AXBS_CSR_MERR7_SHIFT (31u) +#define AXBS_CSR_MERR7_WIDTH (1u) +#define AXBS_CSR_MERR6_MASK (0x40000000u) +#define AXBS_CSR_MERR6_SHIFT (30u) +#define AXBS_CSR_MERR6_WIDTH (1u) +#define AXBS_CSR_MERR5_MASK (0x20000000u) +#define AXBS_CSR_MERR5_SHIFT (29u) +#define AXBS_CSR_MERR5_WIDTH (1u) +#define AXBS_CSR_MERR4_MASK (0x10000000u) +#define AXBS_CSR_MERR4_SHIFT (28u) +#define AXBS_CSR_MERR4_WIDTH (1u) +#define AXBS_CSR_MERR3_MASK (0x8000000u) +#define AXBS_CSR_MERR3_SHIFT (27u) +#define AXBS_CSR_MERR3_WIDTH (1u) +#define AXBS_CSR_MERR2_MASK (0x4000000u) +#define AXBS_CSR_MERR2_SHIFT (26u) +#define AXBS_CSR_MERR2_WIDTH (1u) +#define AXBS_CSR_MERR1_MASK (0x2000000u) +#define AXBS_CSR_MERR1_SHIFT (25u) +#define AXBS_CSR_MERR1_WIDTH (1u) +#define AXBS_CSR_MERR0_MASK (0x1000000u) +#define AXBS_CSR_MERR0_SHIFT (24u) +#define AXBS_CSR_MERR0_WIDTH (1u) +#define AXBS_CSR_AHB_REG_VLD_MASK (0x01u) +#define AXBS_CSR_AHB_REG_VLD_SHIFT (0u) +#define AXBS_CSR_AHB_REG_VLD_WIDTH (1u) + +/* EAR Bit Fields */ +#define AXBS_EAR_EADDR_MASK (0xFFFFFFFFu) +#define AXBS_EAR_EADDR_SHIFT (0u) +#define AXBS_EAR_EADDR_WIDTH (32u) + +/* EDR Bit Fields */ +#define AXBS_EDR_EMN_MASK (0xF000u) +#define AXBS_EDR_EMN_SHIFT (12u) +#define AXBS_EDR_EMN_WIDTH (4u) +#define AXBS_EDR_EATTR_MASK (0xF0u) +#define AXBS_EDR_EATTR_SHIFT (4u) +#define AXBS_EDR_EATTR_WIDTH (4u) +#define AXBS_EDR_ERW_MASK (0x01u) +#define AXBS_EDR_ERW_SHIFT (0u) +#define AXBS_EDR_ERW_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of AHB registers + */ +typedef struct _AxbsRegType_ +{ + volatile uint32_t CSR; /*!< AXBS control/error status register, offset: 0x0 */ + uint32_t RESERVED0[3]; /*!< Reserverd block, 0004H */ + struct + { + const volatile uint32_t EAR; /*!< Master n Error Address Register */ + const volatile uint32_t EDR; /*!< Master n Error Detail Register */ + } ERR[AXBS_MASTER_NUM]; +} AxbsRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the AXBS master 0 Error + * + * This function gets the current AXBS master 0 Error. + * Indicates a captured error in AXBS master0 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \return AXBS master 0 Error + * - 0b : No error has occurred for AXBS master 0 interface. + * - 1b : An error has occurred for AXBS master 0 interface. + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetCsrMErr0(const AxbsRegType *obj) +{ + return ((obj->CSR & AXBS_CSR_MERR0_MASK) >> AXBS_CSR_MERR0_SHIFT); +} + +/*! \brief Sets the AXBS master 0 Error + * + * This function sets the AXBS master 0 Error. + * Indicates a captured error in AXBS master0 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] value : whether to clear the flag + * - 0b : No effect + * - 1b : Clear the error flag + */ +__attribute__((always_inline)) static inline void AxbsReg_SetCsrMErr0(AxbsRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = obj->CSR & AXBS_CSR_AHB_REG_VLD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << AXBS_CSR_MERR0_SHIFT)) & AXBS_CSR_MERR0_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the AXBS master 1 Error + * + * This function gets the current AXBS master 1 Error. + * Indicates a captured error in AXBS master1 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \return AXBS master 1 Error + * - 0b : No error has occurred for AXBS master 1 interface. + * - 1b : An error has occurred for AXBS master 1 interface. + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetCsrMErr1(const AxbsRegType *obj) +{ + return ((obj->CSR & AXBS_CSR_MERR1_MASK) >> AXBS_CSR_MERR1_SHIFT); +} + +/*! \brief Sets the AXBS master 1 Error + * + * This function sets the AXBS master 1 Error. + * Indicates a captured error in AXBS master1 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] value : whether to clear the flag + * - 0b : No effect + * - 1b : Clear the error flag + */ +__attribute__((always_inline)) static inline void AxbsReg_SetCsrMErr1(AxbsRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = obj->CSR & AXBS_CSR_AHB_REG_VLD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << AXBS_CSR_MERR1_SHIFT)) & AXBS_CSR_MERR1_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the AXBS master 2 Error + * + * This function gets the current AXBS master 2 Error. + * Indicates a captured error in AXBS master2 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \return AXBS master 2 Error + * - 0b : No error has occurred for AXBS master 2 interface. + * - 1b : An error has occurred for AXBS master 2 interface. + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetCsrMErr2(const AxbsRegType *obj) +{ + return ((obj->CSR & AXBS_CSR_MERR2_MASK) >> AXBS_CSR_MERR2_SHIFT); +} + +/*! \brief Sets the AXBS master 2 Error + * + * This function sets the AXBS master 2 Error. + * Indicates a captured error in AXBS master2 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] value : whether to clear the flag + * - 0b : No effect + * - 1b : Clear the error flag + */ +__attribute__((always_inline)) static inline void AxbsReg_SetCsrMErr2(AxbsRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = obj->CSR & AXBS_CSR_AHB_REG_VLD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << AXBS_CSR_MERR2_SHIFT)) & AXBS_CSR_MERR2_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the AXBS master 3 Error + * + * This function gets the current AXBS master 3 Error. + * Indicates a captured error in AXBS master3 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \return AXBS master 3 Error + * - 0b : No error has occurred for AXBS master 3 interface. + * - 1b : An error has occurred for AXBS master 3 interface. + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetCsrMErr3(const AxbsRegType *obj) +{ + return ((obj->CSR & AXBS_CSR_MERR3_MASK) >> AXBS_CSR_MERR3_SHIFT); +} + +/*! \brief Sets the AXBS master 3 Error + * + * This function sets the AXBS master 3 Error. + * Indicates a captured error in AXBS master3 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] value : whether to clear the flag + * - 0b : No effect + * - 1b : Clear the error flag + */ +__attribute__((always_inline)) static inline void AxbsReg_SetCsrMErr3(AxbsRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = obj->CSR & AXBS_CSR_AHB_REG_VLD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << AXBS_CSR_MERR3_SHIFT)) & AXBS_CSR_MERR3_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the AXBS master 4 Error + * + * This function gets the current AXBS master 4 Error. + * Indicates a captured error in AXBS master4 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \return AXBS master 4 Error + * - 0b : No error has occurred for AXBS master 4 interface. + * - 1b : An error has occurred for AXBS master 4 interface. + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetCsrMErr4(const AxbsRegType *obj) +{ + return ((obj->CSR & AXBS_CSR_MERR4_MASK) >> AXBS_CSR_MERR4_SHIFT); +} + +/*! \brief Sets the AXBS master 4 Error + * + * This function sets the AXBS master 4 Error. + * Indicates a captured error in AXBS master4 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] value : whether to clear the flag + * - 0b : No effect + * - 1b : Clear the error flag + */ +__attribute__((always_inline)) static inline void AxbsReg_SetCsrMErr4(AxbsRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = obj->CSR & AXBS_CSR_AHB_REG_VLD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << AXBS_CSR_MERR4_SHIFT)) & AXBS_CSR_MERR4_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the AXBS master 5 Error + * + * This function gets the current AXBS master 5 Error. + * Indicates a captured error in AXBS master5 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \return AXBS master 5 Error + * - 0b : No error has occurred for AXBS master 5 interface. + * - 1b : An error has occurred for AXBS master 5 interface. + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetCsrMErr5(const AxbsRegType *obj) +{ + return ((obj->CSR & AXBS_CSR_MERR5_MASK) >> AXBS_CSR_MERR5_SHIFT); +} + +/*! \brief Sets the AXBS master 5 Error + * + * This function sets the AXBS master 5 Error. + * Indicates a captured error in AXBS master5 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] value : whether to clear the flag + * - 0b : No effect + * - 1b : Clear the error flag + */ +__attribute__((always_inline)) static inline void AxbsReg_SetCsrMErr5(AxbsRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = obj->CSR & AXBS_CSR_AHB_REG_VLD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << AXBS_CSR_MERR5_SHIFT)) & AXBS_CSR_MERR5_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the AXBS master 6 Error + * + * This function gets the current AXBS master 6 Error. + * Indicates a captured error in AXBS master6 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \return AXBS master 6 Error + * - 0b : No error has occurred for AXBS master 6 interface. + * - 1b : An error has occurred for AXBS master 6 interface. + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetCsrMErr6(const AxbsRegType *obj) +{ + return ((obj->CSR & AXBS_CSR_MERR6_MASK) >> AXBS_CSR_MERR6_SHIFT); +} + +/*! \brief Sets the AXBS master 6 Error + * + * This function sets the AXBS master 6 Error. + * Indicates a captured error in AXBS master6 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] value : whether to clear the flag + * - 0b : No effect + * - 1b : Clear the error flag + */ +__attribute__((always_inline)) static inline void AxbsReg_SetCsrMErr6(AxbsRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = obj->CSR & AXBS_CSR_AHB_REG_VLD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << AXBS_CSR_MERR6_SHIFT)) & AXBS_CSR_MERR6_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the AXBS master 7 Error + * + * This function gets the current AXBS master 7 Error. + * Indicates a captured error in AXBS master7 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \return AXBS master 7 Error + * - 0b : No error has occurred for AXBS master 7 interface. + * - 1b : An error has occurred for AXBS master 7 interface. + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetCsrMErr7(const AxbsRegType *obj) +{ + return ((obj->CSR & AXBS_CSR_MERR7_MASK) >> AXBS_CSR_MERR7_SHIFT); +} + +/*! \brief Sets the AXBS master 7 Error + * + * This function sets the AXBS master 7 Error. + * Indicates a captured error in AXBS master7 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] value : whether to clear the flag + * - 0b : No effect + * - 1b : Clear the error flag + */ +__attribute__((always_inline)) static inline void AxbsReg_SetCsrMErr7(AxbsRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = obj->CSR & AXBS_CSR_AHB_REG_VLD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << AXBS_CSR_MERR7_SHIFT)) & AXBS_CSR_MERR7_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the AXBS status regsiter module enable flag + * + * This function gets the current AXBS status regsiter module enable flag + * + * \param[in] obj : pointer to AXBS register instance + * \return the current AXBS status regsiter module enable flag + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetCsrRegVld(const AxbsRegType *obj) +{ + return ((obj->CSR & AXBS_CSR_AHB_REG_VLD_MASK) >> AXBS_CSR_AHB_REG_VLD_SHIFT); +} + +/*! \brief Sets the AXBS status regsiter module enable flag + * + * This function sets the AXBS status regsiter module enable flag. + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] value : the value of AXBS status regsiter module enable flag + */ +__attribute__((always_inline)) static inline void AxbsReg_SetCsrRegVld(AxbsRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CSR; + + tmp &= ~AXBS_CSR_AHB_REG_VLD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << AXBS_CSR_AHB_REG_VLD_SHIFT)) & AXBS_CSR_AHB_REG_VLD_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the Error Address + * + * This function gets the current Error Address. + * Indicates the reference address from master 0 that generated the access erro + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] master : the master index + * \return Error Address + */ +__attribute__((always_inline)) static inline uint32_t AxbsReg_GetEarEAddr(const AxbsRegType *obj, uint8_t master) +{ + return ((obj->ERR[master].EAR & AXBS_EAR_EADDR_MASK) >> AXBS_EAR_EADDR_SHIFT); +} + +/*! \brief Gets the Error Master Number + * + * This function gets the current Error Master Number. + * Indicates the bus master that generated the access error + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] master : the master index + * \return Error Master Number + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetEdrEmn(const AxbsRegType *obj, uint8_t master) +{ + return ((obj->ERR[master].EDR & AXBS_EDR_EMN_MASK) >> AXBS_EDR_EMN_SHIFT); +} + +/*! \brief Gets the Error Attributes + * + * This function gets the current Error Attributes. + * Indicates hprot[3:0] of error access + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] master : the master index + * \return Error Attributes + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetEdrEAttr(const AxbsRegType *obj, uint8_t master) +{ + return ((obj->ERR[master].EDR & AXBS_EDR_EATTR_MASK) >> AXBS_EDR_EATTR_SHIFT); +} + +/*! \brief Gets the Error Read/Write + * + * This function gets the current Error Read/Write. + * Indicates the access type of the faulting reference. + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] master : the master index + * \return Error Read/Write + * - 0b : Read + * - 1b : Write + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetEdrErw(const AxbsRegType *obj, uint8_t master) +{ + return ((obj->ERR[master].EDR & AXBS_EDR_ERW_MASK) >> AXBS_EDR_ERW_SHIFT); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _AXBS_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/cmp_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/cmp_reg.h new file mode 100644 index 0000000..e9109da --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/cmp_reg.h @@ -0,0 +1,2304 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CMP_REG_H_ +#define _CMP_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the CMP Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* CMP Register Lock Key for unlock or lock */ +#define UNLOCK_KEY (0x5f5f0101u) +#define LOCK_KEY (0x00000000u) + +/* C0 Bit Fields */ +#define CMP_C0_WITHOUT_W1C_MASK (0xF9FFFFFFu) +#define CMP_C0_HYSTCTR_MASK (0x3u) +#define CMP_C0_HYSTCTR_SHIFT (0u) +#define CMP_C0_HYSTCTR_WIDTH (2u) +#define CMP_C0_OFFSET_MASK (0x4u) +#define CMP_C0_OFFSET_SHIFT (2u) +#define CMP_C0_OFFSET_WIDTH (1u) +#define CMP_C0_FILTER_CNT_MASK (0x70u) +#define CMP_C0_FILTER_CNT_SHIFT (4u) +#define CMP_C0_FILTER_CNT_WIDTH (3u) +#define CMP_C0_EN_MASK (0x100u) +#define CMP_C0_EN_SHIFT (8u) +#define CMP_C0_EN_WIDTH (1u) +#define CMP_C0_OPE_MASK (0x200u) +#define CMP_C0_OPE_SHIFT (9u) +#define CMP_C0_OPE_WIDTH (1u) +#define CMP_C0_COS_MASK (0x400u) +#define CMP_C0_COS_SHIFT (10u) +#define CMP_C0_COS_WIDTH (1u) +#define CMP_C0_INVT_MASK (0x800u) +#define CMP_C0_INVT_SHIFT (11u) +#define CMP_C0_INVT_WIDTH (1u) +#define CMP_C0_PMODE_MASK (0x1000u) +#define CMP_C0_PMODE_SHIFT (12u) +#define CMP_C0_PMODE_WIDTH (1u) +#define CMP_C0_WE_MASK (0x4000u) +#define CMP_C0_WE_SHIFT (14u) +#define CMP_C0_WE_WIDTH (1u) +#define CMP_C0_SE_MASK (0x8000u) +#define CMP_C0_SE_SHIFT (15u) +#define CMP_C0_SE_WIDTH (1u) +#define CMP_C0_FPR_MASK (0xFF0000u) +#define CMP_C0_FPR_SHIFT (16u) +#define CMP_C0_FPR_WIDTH (8u) +#define CMP_C0_COUT_MASK (0x1000000u) +#define CMP_C0_COUT_SHIFT (24u) +#define CMP_C0_COUT_WIDTH (1u) +#define CMP_C0_CFF_MASK (0x2000000u) +#define CMP_C0_CFF_SHIFT (25u) +#define CMP_C0_CFF_WIDTH (1u) +#define CMP_C0_CFR_MASK (0x4000000u) +#define CMP_C0_CFR_SHIFT (26u) +#define CMP_C0_CFR_WIDTH (1u) +#define CMP_C0_IEF_MASK (0x8000000u) +#define CMP_C0_IEF_SHIFT (27u) +#define CMP_C0_IEF_WIDTH (1u) +#define CMP_C0_IER_MASK (0x10000000u) +#define CMP_C0_IER_SHIFT (28u) +#define CMP_C0_IER_WIDTH (1u) +#define CMP_C0_LPFSEL_MASK (0x60000000u) +#define CMP_C0_LPFSEL_SHIFT (29u) +#define CMP_C0_LPFSEL_WIDTH (2u) +#define CMP_C0_DMAEN_MASK (0x80000000u) +#define CMP_C0_DMAEN_SHIFT (31u) +#define CMP_C0_DMAEN_WIDTH (1u) + +/* C1 Bit Fields */ +#define CMP_C1_VOSEL_MASK (0xFFu) +#define CMP_C1_VOSEL_SHIFT (0u) +#define CMP_C1_VOSEL_WIDTH (8u) +#define CMP_C1_MSEL_MASK (0x700u) +#define CMP_C1_MSEL_SHIFT (8u) +#define CMP_C1_MSEL_WIDTH (3u) +#define CMP_C1_PSEL_MASK (0x3800u) +#define CMP_C1_PSEL_SHIFT (11u) +#define CMP_C1_PSEL_WIDTH (3u) +#define CMP_C1_VRSEL_MASK (0x4000u) +#define CMP_C1_VRSEL_SHIFT (14u) +#define CMP_C1_VRSEL_WIDTH (1u) +#define CMP_C1_DACEN_MASK (0x8000u) +#define CMP_C1_DACEN_SHIFT (15u) +#define CMP_C1_DACEN_WIDTH (1u) +#define CMP_C1_CHN0_MASK (0x10000u) +#define CMP_C1_CHN0_SHIFT (16u) +#define CMP_C1_CHN0_WIDTH (1u) +#define CMP_C1_CHN1_MASK (0x20000u) +#define CMP_C1_CHN1_SHIFT (17u) +#define CMP_C1_CHN1_WIDTH (1u) +#define CMP_C1_CHN2_MASK (0x40000u) +#define CMP_C1_CHN2_SHIFT (18u) +#define CMP_C1_CHN2_WIDTH (1u) +#define CMP_C1_CHN3_MASK (0x80000u) +#define CMP_C1_CHN3_SHIFT (19u) +#define CMP_C1_CHN3_WIDTH (1u) +#define CMP_C1_CHN4_MASK (0x100000u) +#define CMP_C1_CHN4_SHIFT (20u) +#define CMP_C1_CHN4_WIDTH (1u) +#define CMP_C1_CHN5_MASK (0x200000u) +#define CMP_C1_CHN5_SHIFT (21u) +#define CMP_C1_CHN5_WIDTH (1u) +#define CMP_C1_CHN6_MASK (0x400000u) +#define CMP_C1_CHN6_SHIFT (22u) +#define CMP_C1_CHN6_WIDTH (1u) +#define CMP_C1_CHN7_MASK (0x800000u) +#define CMP_C1_CHN7_SHIFT (23u) +#define CMP_C1_CHN7_WIDTH (1u) +#define CMP_C1_INNSEL_MASK (0x3000000u) +#define CMP_C1_INNSEL_SHIFT (24u) +#define CMP_C1_INNSEL_WIDTH (2u) +#define CMP_C1_INPSEL_MASK (0x18000000u) +#define CMP_C1_INPSEL_SHIFT (27u) +#define CMP_C1_INPSEL_WIDTH (2u) + +/* C2 Bit Fields */ +#define CMP_C2_WITHOUT_W1C_MASK (0xFF00FFFFu) +#define CMP_C2_ACO0_MASK (0x1u) +#define CMP_C2_ACO0_SHIFT (0u) +#define CMP_C2_ACO0_WIDTH (1u) +#define CMP_C2_ACO1_MASK (0x2u) +#define CMP_C2_ACO1_SHIFT (1u) +#define CMP_C2_ACO1_WIDTH (1u) +#define CMP_C2_ACO2_MASK (0x4u) +#define CMP_C2_ACO2_SHIFT (2u) +#define CMP_C2_ACO2_WIDTH (1u) +#define CMP_C2_ACO3_MASK (0x8u) +#define CMP_C2_ACO3_SHIFT (3u) +#define CMP_C2_ACO3_WIDTH (1u) +#define CMP_C2_ACO4_MASK (0x10u) +#define CMP_C2_ACO4_SHIFT (4u) +#define CMP_C2_ACO4_WIDTH (1u) +#define CMP_C2_ACO5_MASK (0x20u) +#define CMP_C2_ACO5_SHIFT (5u) +#define CMP_C2_ACO5_WIDTH (1u) +#define CMP_C2_ACO6_MASK (0x40u) +#define CMP_C2_ACO6_SHIFT (6u) +#define CMP_C2_ACO6_WIDTH (1u) +#define CMP_C2_ACO7_MASK (0x80u) +#define CMP_C2_ACO7_SHIFT (7u) +#define CMP_C2_ACO7_WIDTH (1u) +#define CMP_C2_INITMOD_MASK (0x3F00u) +#define CMP_C2_INITMOD_SHIFT (8u) +#define CMP_C2_INITMOD_WIDTH (6u) +#define CMP_C2_NSAM_MASK (0xC000u) +#define CMP_C2_NSAM_SHIFT (14u) +#define CMP_C2_NSAM_WIDTH (2u) +#define CMP_C2_CHnF_MASK (0xFF0000u) +#define CMP_C2_CH0F_MASK (0x10000u) +#define CMP_C2_CH0F_SHIFT (16u) +#define CMP_C2_CH0F_WIDTH (1u) +#define CMP_C2_CH1F_MASK (0x20000u) +#define CMP_C2_CH1F_SHIFT (17u) +#define CMP_C2_CH1F_WIDTH (1u) +#define CMP_C2_CH2F_MASK (0x40000u) +#define CMP_C2_CH2F_SHIFT (18u) +#define CMP_C2_CH2F_WIDTH (1u) +#define CMP_C2_CH3F_MASK (0x80000u) +#define CMP_C2_CH3F_SHIFT (19u) +#define CMP_C2_CH3F_WIDTH (1u) +#define CMP_C2_CH4F_MASK (0x100000u) +#define CMP_C2_CH4F_SHIFT (20u) +#define CMP_C2_CH4F_WIDTH (1u) +#define CMP_C2_CH5F_MASK (0x200000u) +#define CMP_C2_CH5F_SHIFT (21u) +#define CMP_C2_CH5F_WIDTH (1u) +#define CMP_C2_CH6F_MASK (0x400000u) +#define CMP_C2_CH6F_SHIFT (22u) +#define CMP_C2_CH6F_WIDTH (1u) +#define CMP_C2_CH7F_MASK (0x800000u) +#define CMP_C2_CH7F_SHIFT (23u) +#define CMP_C2_CH7F_WIDTH (1u) +#define CMP_C2_FXMXCH_MASK (0xE000000u) +#define CMP_C2_FXMXCH_SHIFT (25u) +#define CMP_C2_FXMXCH_WIDTH (3u) +#define CMP_C2_FXMP_MASK (0x20000000u) +#define CMP_C2_FXMP_SHIFT (29u) +#define CMP_C2_FXMP_WIDTH (1u) +#define CMP_C2_RRIE_MASK (0x40000000u) +#define CMP_C2_RRIE_SHIFT (30u) +#define CMP_C2_RRIE_WIDTH (1u) +#define CMP_C2_RRE_MASK (0x80000000u) +#define CMP_C2_RRE_SHIFT (31u) +#define CMP_C2_RRE_WIDTH (1u) + +/* C4 Bit Fields */ +#define CMP_C4_LOCK_KEY_MASK (0xFFFFFFFFu) +#define CMP_C4_LOCK_KEY_SHIFT (0u) +#define CMP_C4_LOCK_KEY_WIDTH (32u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of CMP registers + */ +typedef struct _CmpRegType_ +{ + volatile uint32_t C0; /*!< CMP control register 0, offset: 0x0 */ + volatile uint32_t C1; /*!< CMP control register 1, offset: 0x4 */ + volatile uint32_t C2; /*!< CMP control register 2, offset: 0x8 */ + const volatile uint32_t C3; /*!< CMP control register 3, offset: 0xC */ + volatile uint32_t C4; /*!< CMP control register 4, offset: 0x10 */ +} CmpRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Get the current CMP LOCK_KEY register configuration + * + * This function gets the current CMP LOCK_KEY register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP LOCK_KEY register configuration. + */ +__attribute__((always_inline)) static inline uint32_t CmpReg_GetLockKeyReg(const CmpRegType *obj) +{ + return ((obj->C4 & CMP_C4_LOCK_KEY_MASK) >> CMP_C4_LOCK_KEY_SHIFT); +} + +/*! \brief Set CMP LOCK_KEY configuration for lock + * + * This function writes new configuration to CMP LOCK_KEY register for lock + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_LockReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C4; + tmp &= ~(CMP_C4_LOCK_KEY_MASK); + tmp |= (((uint32_t)(((uint32_t)(LOCK_KEY)) << CMP_C4_LOCK_KEY_SHIFT)) & CMP_C4_LOCK_KEY_MASK); + obj->C4 = tmp; +} + +/*! \brief Set CMP LOCK_KEY configuration for unlock + * + * This function writes new configuration to CMP LOCK_KEY register for unlock + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_UnlockReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C4; + tmp &= ~(CMP_C4_LOCK_KEY_MASK); + tmp |= (((uint32_t)(((uint32_t)(UNLOCK_KEY)) << CMP_C4_LOCK_KEY_SHIFT)) & CMP_C4_LOCK_KEY_MASK); + obj->C4 = tmp; +} + +/*! \brief Get the current CMP HYSTCTR register configuration + * + * This function gets the current CMP HYSTCTR register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP HYSTCTR register configuration. + * - 00b: The hard block output has level 0 hysteresis internally. + * - 01b: The hard block output has level 1 hysteresis internally. + * - 10b: The hard block output has level 2 hysteresis internally. + * - 11b: The hard block output has level 3 hysteresis internally. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetHystctrReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_HYSTCTR_MASK) >> CMP_C0_HYSTCTR_SHIFT); +} + +/*! \brief Set CMP HYSTCTR configuration + * + * This function writes new configuration to CMP HYSTCTR register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write protect by CMP_C4_LOCK_KEY + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP HYSTCTR register configuration + * - 00b: The hard block output has level 0 hysteresis internally. + * - 01b: The hard block output has level 1 hysteresis internally. + * - 10b: The hard block output has level 2 hysteresis internally. + * - 11b: The hard block output has level 3 hysteresis internally. + */ +__attribute__((always_inline)) static inline void CmpReg_SetHystctrReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_HYSTCTR_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_HYSTCTR_SHIFT)) & CMP_C0_HYSTCTR_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP OFFSET register configuration + * + * This function gets the current CMP OFFSET register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP OFFSET register configuration. + * - 0b: The comparator hard block output has level 0 offset internally. + * - 1b: The comparator hard block output has level 1 offset internally. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetOffsetReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_OFFSET_MASK) >> CMP_C0_OFFSET_SHIFT); +} + +/*! \brief Set CMP OFFSET configuration + * + * This function writes new configuration to CMP OFFSET register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write protect by CMP_C4_LOCK_KEY + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP OFFSET register configuration + * - 0b: The comparator hard block output has level 0 offset internally. + * - 1b: The comparator hard block output has level 1 offset internally. + */ +__attribute__((always_inline)) static inline void CmpReg_SetOffsetReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_OFFSET_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_OFFSET_SHIFT)) & CMP_C0_OFFSET_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP FILTER_CNT register configuration + * + * This function gets the current CMP FILTER_CNT register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP FILTER_CNT register configuration. + * - 000b: Filter is disabled. If SE = 1, then COUT is a logic zero (this is not a legal state, and is not recommended). If SE = 0, COUT = COUTA. + * - 001b: 1 consecutive sample must agree (comparator output is simply sampled). + * - 010b: 2 consecutive samples must agree. + * - 011b: 3 consecutive samples must agree. + * - 100b: 4 consecutive samples must agree. + * - 101b: 5 consecutive samples must agree. + * - 110b: 6 consecutive samples must agree. + * - 111b: 7 consecutive samples must agree. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetFilterCntReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_FILTER_CNT_MASK) >> CMP_C0_FILTER_CNT_SHIFT); +} + +/*! \brief Set CMP FILTER_CNT configuration + * + * This function writes new configuration to CMP FILTER_CNT register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP FILTER_CNT register configuration + * - 000b: Filter is disabled. If SE = 1, then COUT is a logic zero (this is not a legal state, and is not recommended). If SE = 0, COUT = COUTA. + * - 001b: 1 consecutive sample must agree (comparator output is simply sampled). + * - 010b: 2 consecutive samples must agree. + * - 011b: 3 consecutive samples must agree. + * - 100b: 4 consecutive samples must agree. + * - 101b: 5 consecutive samples must agree. + * - 110b: 6 consecutive samples must agree. + * - 111b: 7 consecutive samples must agree. + */ +__attribute__((always_inline)) static inline void CmpReg_SetFilterCntReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_FILTER_CNT_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_FILTER_CNT_SHIFT)) & CMP_C0_FILTER_CNT_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP EN register configuration + * + * This function gets the current CMP EN register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP EN register configuration. + * - 0b: Analog Comparator is disabled. + * - 1b: Analog Comparator is enabled. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetEnReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_EN_MASK) >> CMP_C0_EN_SHIFT); +} + +/*! \brief Set CMP EN configuration + * + * This function writes new configuration to CMP EN register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write protect by CMP_C4_LOCK_KEY + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP EN register configuration + * - 0b: Analog Comparator is disabled. + * - 1b: Analog Comparator is enabled. + */ +__attribute__((always_inline)) static inline void CmpReg_SetEnReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_EN_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_EN_SHIFT)) & CMP_C0_EN_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP OPE register configuration + * + * This function gets the current CMP OPE register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP OPE register configuration. + * - 0b: The comparator output (after window/filter settings dependent on software configuration) is not available to a packaged pin. + * - 1b: If the software has configured the comparator to own a packaged pin, the comparator is available in a packaged pin. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetOpeReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_OPE_MASK) >> CMP_C0_OPE_SHIFT); +} + +/*! \brief Set CMP OPE configuration + * + * This function writes new configuration to CMP OPE register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP OPE register configuration + * - 0b: The comparator output (after window/filter settings dependent on software configuration) is not available to a packaged pin. + * - 1b: If the software has configured the comparator to own a packaged pin, the comparator is available in a packaged pin. + */ +__attribute__((always_inline)) static inline void CmpReg_SetOpeReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_OPE_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_OPE_SHIFT)) & CMP_C0_OPE_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP COS register configuration + * + * This function gets the current CMP COS register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP COS register configuration. + * - 0b: Set CMPO to equal COUT (filtered comparator output). + * - 1b: Set CMPO to equal COUTA (unfiltered comparator output). + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCosReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_COS_MASK) >> CMP_C0_COS_SHIFT); +} + +/*! \brief Set CMP COS configuration + * + * This function writes new configuration to CMP COS register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP COS register configuration + * - 0b: Set CMPO to equal COUT (filtered comparator output). + * - 1b: Set CMPO to equal COUTA (unfiltered comparator output). + */ +__attribute__((always_inline)) static inline void CmpReg_SetCosReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_COS_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_COS_SHIFT)) & CMP_C0_COS_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP INVT register configuration + * + * This function gets the current CMP INVT register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP INVT register configuration. + * - 0b: Does not invert the comparator output. + * - 1b: Inverts the comparator output. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetInvtReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_INVT_MASK) >> CMP_C0_INVT_SHIFT); +} + +/*! \brief Set CMP INVT configuration + * + * This function writes new configuration to CMP INVT register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP INVT register configuration + * - 0b: Does not invert the comparator output. + * - 1b: Inverts the comparator output. + */ +__attribute__((always_inline)) static inline void CmpReg_SetInvtReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_INVT_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_INVT_SHIFT)) & CMP_C0_INVT_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP PMODE register configuration + * + * This function gets the current CMP PMODE register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP PMODE register configuration. + * - 0b: Low Speed (LS) comparison mode is selected. + * - 1b: High Speed (HS) comparison mode is selected, in VLPx mode, or Stop mode switched to Low Speed (LS) mode. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetPmodeReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_PMODE_MASK) >> CMP_C0_PMODE_SHIFT); +} + +/*! \brief Set CMP PMODE configuration + * + * This function writes new configuration to CMP PMODE register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write protect by CMP_C4_LOCK_KEY + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP PMODE register configuration + * - 0b: Low Speed (LS) comparison mode is selected. + * - 1b: High Speed (HS) comparison mode is selected, in VLPx mode, or Stop mode switched to Low Speed (LS) mode. + */ +__attribute__((always_inline)) static inline void CmpReg_SetPmodeReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_PMODE_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_PMODE_SHIFT)) & CMP_C0_PMODE_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP WE register configuration + * + * This function gets the current CMP WE register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP WE register configuration. + * - 0b: Windowing mode is not selected. + * - 1b: Windowing mode is selected. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetWeReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_WE_MASK) >> CMP_C0_WE_SHIFT); +} + +/*! \brief Set CMP WE configuration + * + * This function writes new configuration to CMP WE register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP WE register configuration + * - 0b: Windowing mode is not selected. + * - 1b: Windowing mode is selected. + */ +__attribute__((always_inline)) static inline void CmpReg_SetWeReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_WE_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_WE_SHIFT)) & CMP_C0_WE_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP SE register configuration + * + * This function gets the current CMP SE register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP SE register configuration. + * - 0b: Sampling mode is not selected. + * - 1b: Sampling mode is selected. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetSeReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_SE_MASK) >> CMP_C0_SE_SHIFT); +} + +/*! \brief Set CMP SE configuration + * + * This function writes new configuration to CMP SE register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP SE register configuration + * - 0b: Sampling mode is not selected. + * - 1b: Sampling mode is selected. + */ +__attribute__((always_inline)) static inline void CmpReg_SetSeReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_SE_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_SE_SHIFT)) & CMP_C0_SE_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP FPR register configuration + * + * This function gets the current CMP FPR register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP FPR register configuration. + * Specifies the sampling period, in bus clock cycles, of the comparator output filter, when C0[SE] = 0. + * -0b: disables the filter. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetFprReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_FPR_MASK) >> CMP_C0_FPR_SHIFT); +} + +/*! \brief Set CMP FPR configuration + * + * This function writes new configuration to CMP FPR register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP FPR register configuration + * Specifies the sampling period, in bus clock cycles, of the comparator output filter, when C0[SE] = 0. + * -0b: disables the filter. + */ +__attribute__((always_inline)) static inline void CmpReg_SetFprReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_FPR_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_FPR_SHIFT)) & CMP_C0_FPR_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP COUT register + * + * This function gets the current CMP COUT register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register read only + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP COUT register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCoutReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_COUT_MASK) >> CMP_C0_COUT_SHIFT); +} + +/*! \brief Get the current CMP CFF register + * + * This function gets the current CMP CFF register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CFF register configuration. + * - 0b: A falling edge has not been detected on COUT. + * - 1b: A falling edge on COUT has occurred. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCffReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_CFF_MASK) >> CMP_C0_CFF_SHIFT); +} + +/*! \brief Clear CMP CFF register + * + * This function clear CMP CFF register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write 1 to Clear + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_ClearCffReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_CFF_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(1u)) << CMP_C0_CFF_SHIFT)) & CMP_C0_CFF_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP CFR register + * + * This function gets the current CMP CFR register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CFR register configuration. + * - 0b: A rising edge has not been detected on COUT. + * - 1b: A rising edge on COUT has occurred. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCfrReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_CFR_MASK) >> CMP_C0_CFR_SHIFT); +} + +/*! \brief Clear CMP CFR register + * + * This function clear CMP CFR register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write 1 to Clear + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_ClearCfrReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_CFR_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(1u)) << CMP_C0_CFR_SHIFT)) & CMP_C0_CFR_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP IEF register configuration + * + * This function gets the current CMP IEF register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP IEF register configuration. + * - 0b: Interrupt is disabled. + * - 1b: Interrupt is enabled. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetIefReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_IEF_MASK) >> CMP_C0_IEF_SHIFT); +} + +/*! \brief Set CMP IEF configuration + * + * This function writes new configuration to CMP IEF register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP IEF register configuration + * - 0b: Interrupt is disabled. + * - 1b: Interrupt is enabled. + */ +__attribute__((always_inline)) static inline void CmpReg_SetIefReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_IEF_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_IEF_SHIFT)) & CMP_C0_IEF_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP IER register configuration + * + * This function gets the current CMP IER register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP IER register configuration. + * - 0b: Interrupt is disabled. + * - 1b: Interrupt is enabled. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetIerReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_IER_MASK) >> CMP_C0_IER_SHIFT); +} + +/*! \brief Set CMP IER configuration + * + * This function writes new configuration to CMP IER register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP IER register configuration + * - 0b: Interrupt is disabled. + * - 1b: Interrupt is enabled. + */ +__attribute__((always_inline)) static inline void CmpReg_SetIerReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_IER_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_IER_SHIFT)) & CMP_C0_IER_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP LPFSEL register configuration + * + * This function gets the current CMP LPFSEL register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP LPFSEL register configuration. + * - 00b: 23MHz + * - 01b: 16MHz + * - 10b: 13MHz + * - 11b: 10MHz + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetLpfselReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_LPFSEL_MASK) >> CMP_C0_LPFSEL_SHIFT); +} + +/*! \brief Set CMP LPFSEL configuration + * + * This function writes new configuration to CMP LPFSEL register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write protect by CMP_C4_LOCK_KEY + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP LPFSEL register configuration + * - 00b: 23MHz + * - 01b: 16MHz + * - 10b: 13MHz + * - 11b: 10MHz + */ +__attribute__((always_inline)) static inline void CmpReg_SetLpfselReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_LPFSEL_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_LPFSEL_SHIFT)) & CMP_C0_LPFSEL_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP DMAEN register configuration + * + * This function gets the current CMP DMAEN register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP DMAEN register configuration. + * - 0b: DMA is disabled. + * - 1b: DMA is enabled. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetDmaenReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_DMAEN_MASK) >> CMP_C0_DMAEN_SHIFT); +} + +/*! \brief Set CMP DMAEN configuration + * + * This function writes new configuration to CMP DMAEN register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP DMAEN register configuration + * - 0b: DMA is disabled. + * - 1b: DMA is enabled. + */ +__attribute__((always_inline)) static inline void CmpReg_SetDmaenReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_DMAEN_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_DMAEN_SHIFT)) & CMP_C0_DMAEN_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP VOSEL register configuration + * + * This function gets the current CMP VOSEL register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP VOSEL register configuration. + * DAC Output Voltage = (Vin/256) × (VOSEL[7:0] + 1). + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetVoselReg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_VOSEL_MASK) >> CMP_C1_VOSEL_SHIFT); +} + +/*! \brief Set CMP VOSEL configuration + * + * This function writes new configuration to CMP LPFSEL register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write protect by CMP_C4_LOCK_KEY + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP VOSEL register configuration + * DAC Output Voltage = (Vin/256) × (VOSEL[7:0] + 1). + */ +__attribute__((always_inline)) static inline void CmpReg_SetVoselReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_VOSEL_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_VOSEL_SHIFT)) & CMP_C1_VOSEL_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP MSEL register configuration + * + * This function gets the current CMP MSEL register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP MSEL register configuration. + * - 000b: IN0 + * - 001b: IN1 + * - 010b: IN2 + * - 011b: IN3 + * - 100b: IN4 + * - 101b: IN5 + * - 110b: IN6 + * - 111b: IN7 + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetMselReg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_MSEL_MASK) >> CMP_C1_MSEL_SHIFT); +} + +/*! \brief Set CMP MSEL configuration + * + * This function writes new configuration to CMP MSEL register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP MSEL register configuration + * - 000b: IN0 + * - 001b: IN1 + * - 010b: IN2 + * - 011b: IN3 + * - 100b: IN4 + * - 101b: IN5 + * - 110b: IN6 + * - 111b: IN7 + */ +__attribute__((always_inline)) static inline void CmpReg_SetMselReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_MSEL_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_MSEL_SHIFT)) & CMP_C1_MSEL_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP PSEL register configuration + * + * This function gets the current CMP PSEL register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP PSEL register configuration. + * - 000b: IN0 + * - 001b: IN1 + * - 010b: IN2 + * - 011b: IN3 + * - 100b: IN4 + * - 101b: IN5 + * - 110b: IN6 + * - 111b: IN7 + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetPselReg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_PSEL_MASK) >> CMP_C1_PSEL_SHIFT); +} + +/*! \brief Set CMP PSEL configuration + * + * This function writes new configuration to CMP PSEL register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP PSEL register configuration + * - 000b: IN0 + * - 001b: IN1 + * - 010b: IN2 + * - 011b: IN3 + * - 100b: IN4 + * - 101b: IN5 + * - 110b: IN6 + * - 111b: IN7 + */ +__attribute__((always_inline)) static inline void CmpReg_SetPselReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_PSEL_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_PSEL_SHIFT)) & CMP_C1_PSEL_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP VRSEL register configuration + * + * This function gets the current CMP VRSEL register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP VRSEL register configuration. + * - 0b: Vin1 is selected as resistor ladder network supply reference Vin. + * - 1b: Vin2 is selected as resistor ladder network supply reference Vin. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetVrselReg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_VRSEL_MASK) >> CMP_C1_VRSEL_SHIFT); +} + +/*! \brief Set CMP VRSEL configuration + * + * This function writes new configuration to CMP VRSEL register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write protect by CMP_C4_LOCK_KEY + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP VRSEL register configuration + * - 0b: Vin1 is selected as resistor ladder network supply reference Vin. + * - 1b: Vin2 is selected as resistor ladder network supply reference Vin. + */ +__attribute__((always_inline)) static inline void CmpReg_SetVrselReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_VRSEL_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_VRSEL_SHIFT)) & CMP_C1_VRSEL_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP DACEN register configuration + * + * This function gets the current CMP DACEN register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP DACEN register configuration. + * - 0b: DAC is disabled. + * - 1b: DAC is enabled. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetDacenReg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_DACEN_MASK) >> CMP_C1_DACEN_SHIFT); +} + +/*! \brief Set CMP DACEN configuration + * + * This function writes new configuration to CMP DACEN register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write protect by CMP_C4_LOCK_KEY + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP DACEN register configuration + * - 0b: DAC is disabled. + * - 1b: DAC is enabled. + */ +__attribute__((always_inline)) static inline void CmpReg_SetDacenReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_DACEN_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_DACEN_SHIFT)) & CMP_C1_DACEN_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP CHN0 register configuration + * + * This function gets the current CMP CHN0 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Channel 0 of the input enable for the round-robin checker. + * If CHN0 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CHN0 register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetChn0Reg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_CHN0_MASK) >> CMP_C1_CHN0_SHIFT); +} + +/*! \brief Set CMP CHN0 configuration + * + * This function writes new configuration to CMP CHN0 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 0 of the input enable for the round-robin checker. + * If CHN0 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP CHN0 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetChn0Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_CHN0_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_CHN0_SHIFT)) & CMP_C1_CHN0_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP CHN1 register configuration + * + * This function gets the current CMP CHN1 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 1 of the input enable for the round-robin checker. + * If CHN1 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CHN1 register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetChn1Reg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_CHN1_MASK) >> CMP_C1_CHN1_SHIFT); +} + +/*! \brief Set CMP CHN1 configuration + * + * This function writes new configuration to CMP CHN1 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 1 of the input enable for the round-robin checker. + * If CHN1 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP CHN1 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetChn1Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_CHN1_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_CHN1_SHIFT)) & CMP_C1_CHN1_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP CHN2 register configuration + * + * This function gets the current CMP CHN2 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 2 of the input enable for the round-robin checker. + * If CHN2 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CHN2 register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetChn2Reg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_CHN2_MASK) >> CMP_C1_CHN2_SHIFT); +} + +/*! \brief Set CMP CHN2 configuration + * + * This function writes new configuration to CMP CHN2 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 2 of the input enable for the round-robin checker. + * If CHN2 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP CHN2 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetChn2Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_CHN2_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_CHN2_SHIFT)) & CMP_C1_CHN2_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP CHN3 register configuration + * + * This function gets the current CMP CHN3 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 3 of the input enable for the round-robin checker. + * If CHN3 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CHN3 register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetChn3Reg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_CHN3_MASK) >> CMP_C1_CHN3_SHIFT); +} + +/*! \brief Set CMP CHN3 configuration + * + * This function writes new configuration to CMP CHN3 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 3 of the input enable for the round-robin checker. + * If CHN3 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP CHN3 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetChn3Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_CHN3_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_CHN3_SHIFT)) & CMP_C1_CHN3_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP CHN4 register configuration + * + * This function gets the current CMP CHN4 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 4 of the input enable for the round-robin checker. + * If CHN4 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CHN4 register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetChn4Reg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_CHN4_MASK) >> CMP_C1_CHN4_SHIFT); +} + +/*! \brief Set CMP CHN4 configuration + * + * This function writes new configuration to CMP CHN4 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 4 of the input enable for the round-robin checker. + * If CHN4 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP CHN4 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetChn4Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_CHN4_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_CHN4_SHIFT)) & CMP_C1_CHN4_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP CHN5 register configuration + * + * This function gets the current CMP CHN5 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 5 of the input enable for the round-robin checker. + * If CHN5 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CHN5 register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetChn5Reg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_CHN5_MASK) >> CMP_C1_CHN5_SHIFT); +} + +/*! \brief Set CMP CHN5 configuration + * + * This function writes new configuration to CMP CHN5 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 5 of the input enable for the round-robin checker. + * If CHN5 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP CHN5 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetChn5Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_CHN5_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_CHN5_SHIFT)) & CMP_C1_CHN5_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP CHN6 register configuration + * + * This function gets the current CMP CHN6 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 6 of the input enable for the round-robin checker. + * If CHN6 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CHN6 register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetChn6Reg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_CHN6_MASK) >> CMP_C1_CHN6_SHIFT); +} + +/*! \brief Set CMP CHN6 configuration + * + * This function writes new configuration to CMP CHN6 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 6 of the input enable for the round-robin checker. + * If CHN6 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP CHN6 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetChn6Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_CHN6_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_CHN6_SHIFT)) & CMP_C1_CHN6_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP CHN7 register configuration + * + * This function gets the current CMP CHN7 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 7 of the input enable for the round-robin checker. + * If CHN7 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CHN7 register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetChn7Reg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_CHN7_MASK) >> CMP_C1_CHN7_SHIFT); +} + +/*! \brief Set CMP CHN7 configuration + * + * This function writes new configuration to CMP CHN7 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 7 of the input enable for the round-robin checker. + * If CHN7 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP CHN7 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetChn7Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_CHN7_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_CHN7_SHIFT)) & CMP_C1_CHN7_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP INNSEL register configuration + * + * This function gets the current CMP INNSEL register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP INNSEL register configuration. + * - 00b: IN0, from the 8-bit DAC output + * - 01b: IN1, from the analog 8-1 mux + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetInnselReg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_INNSEL_MASK) >> CMP_C1_INNSEL_SHIFT); +} + +/*! \brief Set CMP INNSEL configuration + * + * This function writes new configuration to CMP INNSEL register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write protect by CMP_C4_LOCK_KEY + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP INNSEL register configuration + * - 00b: IN0, from the 8-bit DAC output + * - 01b: IN1, from the analog 8-1 mux + */ +__attribute__((always_inline)) static inline void CmpReg_SetInnselReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_INNSEL_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_INNSEL_SHIFT)) & CMP_C1_INNSEL_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP INPSEL register configuration + * + * This function gets the current CMP INPSEL register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP INPSEL register configuration. + * - 00b: IN0, from the 8-bit DAC output + * - 01b: IN1, from the analog 8-1 mux + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetInpselReg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_INPSEL_MASK) >> CMP_C1_INPSEL_SHIFT); +} + +/*! \brief Set CMP INPSEL configuration + * + * This function writes new configuration to CMP INPSEL register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write protect by CMP_C4_LOCK_KEY + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP INPSEL register configuration + * - 00b: IN0, from the 8-bit DAC output + * - 01b: IN1, from the analog 8-1 mux + */ +__attribute__((always_inline)) static inline void CmpReg_SetInpselReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_INPSEL_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_INPSEL_SHIFT)) & CMP_C1_INPSEL_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP ACO0 register configuration + * + * This function gets the current CMP ACO0 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP ACO0 register configuration. + * This field stores the latest comparison result of the input channel 0 with the fixed mux port. + * Reading this bit returns the latest comparison result. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetAco0Reg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_ACO0_MASK) >> CMP_C2_ACO0_SHIFT); +} + +/*! \brief Set CMP ACO0 configuration + * + * This function writes new configuration to CMP ACO0 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * Writing this field defines the pre-set state of channel 0. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP ACO0 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetAco0Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_ACO0_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_ACO0_SHIFT)) & CMP_C2_ACO0_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP ACO1 register configuration + * + * This function gets the current CMP ACO1 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP ACO1 register configuration. + * This field stores the latest comparison result of the input channel 1 with the fixed mux port. + * Reading this bit returns the latest comparison result. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetAco1Reg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_ACO1_MASK) >> CMP_C2_ACO1_SHIFT); +} + +/*! \brief Set CMP ACO1 configuration + * + * This function writes new configuration to CMP ACO1 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * Writing this field defines the pre-set state of channel 1. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP ACO1 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetAco1Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_ACO1_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_ACO1_SHIFT)) & CMP_C2_ACO1_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP ACO2 register configuration + * + * This function gets the current CMP ACO2 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP ACO2 register configuration. + * This field stores the latest comparison result of the input channel 2 with the fixed mux port. + * Reading this bit returns the latest comparison result. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetAco2Reg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_ACO2_MASK) >> CMP_C2_ACO2_SHIFT); +} + +/*! \brief Set CMP ACO2 configuration + * + * This function writes new configuration to CMP ACO2 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * Writing this field defines the pre-set state of channel 2. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP ACO2 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetAco2Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_ACO2_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_ACO2_SHIFT)) & CMP_C2_ACO2_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP ACO3 register configuration + * + * This function gets the current CMP ACO3 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP ACO3 register configuration. + * This field stores the latest comparison result of the input channel 3 with the fixed mux port. + * Reading this bit returns the latest comparison result. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetAco3Reg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_ACO3_MASK) >> CMP_C2_ACO3_SHIFT); +} + +/*! \brief Set CMP ACO3 configuration + * + * This function writes new configuration to CMP ACO3 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * Writing this field defines the pre-set state of channel 3. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP ACO3 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetAco3Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_ACO3_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_ACO3_SHIFT)) & CMP_C2_ACO3_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP ACO4 register configuration + * + * This function gets the current CMP ACO4 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP ACO4 register configuration. + * This field stores the latest comparison result of the input channel 4 with the fixed mux port. + * Reading this bit returns the latest comparison result. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetAco4Reg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_ACO4_MASK) >> CMP_C2_ACO4_SHIFT); +} + +/*! \brief Set CMP ACO4 configuration + * + * This function writes new configuration to CMP ACO4 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * Writing this field defines the pre-set state of channel 4. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP ACO4 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetAco4Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_ACO4_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_ACO4_SHIFT)) & CMP_C2_ACO4_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP ACO5 register configuration + * + * This function gets the current CMP ACO5 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP ACO5 register configuration. + * This field stores the latest comparison result of the input channel 5 with the fixed mux port. + * Reading this bit returns the latest comparison result. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetAco5Reg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_ACO5_MASK) >> CMP_C2_ACO5_SHIFT); +} + +/*! \brief Set CMP ACO5 configuration + * + * This function writes new configuration to CMP ACO5 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * Writing this field defines the pre-set state of channel 5. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP ACO5 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetAco5Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_ACO5_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_ACO5_SHIFT)) & CMP_C2_ACO5_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP ACO6 register configuration + * + * This function gets the current CMP ACO6 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP ACO6 register configuration. + * This field stores the latest comparison result of the input channel 6 with the fixed mux port. + * Reading this bit returns the latest comparison result. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetAco6Reg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_ACO6_MASK) >> CMP_C2_ACO6_SHIFT); +} + +/*! \brief Set CMP ACO6 configuration + * + * This function writes new configuration to CMP ACO6 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * Writing this field defines the pre-set state of channel 6. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP ACO6 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetAco6Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_ACO6_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_ACO6_SHIFT)) & CMP_C2_ACO6_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP ACO7 register configuration + * + * This function gets the current CMP ACO7 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP ACO7 register configuration. + * This field stores the latest comparison result of the input channel 7 with the fixed mux port. + * Reading this bit returns the latest comparison result. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetAco7Reg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_ACO7_MASK) >> CMP_C2_ACO7_SHIFT); +} + +/*! \brief Set CMP ACO7 configuration + * + * This function writes new configuration to CMP ACO7 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * Writing this field defines the pre-set state of channel 7. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP ACO7 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetAco7Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_ACO7_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_ACO7_SHIFT)) & CMP_C2_ACO7_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP INITMOD register configuration + * + * This function gets the current CMP INITMOD register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP INITMOD register configuration. + * These values specify the round robin clock cycles used to determine the comparator and DAC initialization delays. + * - 000000b: The modulus is set to 64 (same with 111111). + * other values Initialization delay is set to INITMOD × round robin clock period + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetInitmodReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_INITMOD_MASK) >> CMP_C2_INITMOD_SHIFT); +} + +/*! \brief Set CMP INITMOD configuration + * + * This function writes new configuration to CMP INITMOD register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP INITMOD register configuration + * These values specify the round robin clock cycles used to determine the comparator and DAC initialization delays. + * - 000000b: The modulus is set to 64 (same with 111111). + * other values Initialization delay is set to INITMOD × round robin clock period + */ +__attribute__((always_inline)) static inline void CmpReg_SetInitmodReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_INITMOD_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_INITMOD_SHIFT)) & CMP_C2_INITMOD_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP NSAM register configuration + * + * This function gets the current CMP NSAM register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP NSAM register configuration. + * - 00b: The comparison result is sampled as soon as the active channel is scanned in one round-robin clock. + * - 01b: The sampling takes place 1 round-robin clock cycle after the next cycle of the round-robin clock. + * - 10b: The sampling takes place 2 round-robin clock cycles after the next cycle of the round-robin clock. + * - 11b: The sampling takes place 3 round-robin clock cycles after the next cycle of the round-robin clock. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetNsamReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_NSAM_MASK) >> CMP_C2_NSAM_SHIFT); +} + +/*! \brief Set CMP NSAM configuration + * + * This function writes new configuration to CMP NSAM register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP NSAM register configuration + * - 00b: The comparison result is sampled as soon as the active channel is scanned in one round-robin clock. + * - 01b: The sampling takes place 1 round-robin clock cycle after the next cycle of the round-robin clock. + * - 10b: The sampling takes place 2 round-robin clock cycles after the next cycle of the round-robin clock. + * - 11b: The sampling takes place 3 round-robin clock cycles after the next cycle of the round-robin clock. + */ +__attribute__((always_inline)) static inline void CmpReg_SetNsamReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_NSAM_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_NSAM_SHIFT)) & CMP_C2_NSAM_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP CH0F register + * + * This function gets the current CMP CH0F register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CH0F register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCh0fReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_CH0F_MASK) >> CMP_C2_CH0F_SHIFT); +} + +/*! \brief Clear CMP CH0F register + * + * This function clear CMP CH0F register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write 1 to Clear + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_ClearCh0fReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_CHnF_MASK); + tmp |= (((uint32_t)(((uint32_t)(1u)) << CMP_C2_CH0F_SHIFT)) & CMP_C2_CH0F_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP CH1F register + * + * This function gets the current CMP CH1F register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CH1F register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCh1fReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_CH1F_MASK) >> CMP_C2_CH1F_SHIFT); +} + +/*! \brief Clear CMP CH1F register + * + * This function clear CMP CH1F register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write 1 to Clear + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_ClearCh1fReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_CHnF_MASK); + tmp |= (((uint32_t)(((uint32_t)(1u)) << CMP_C2_CH1F_SHIFT)) & CMP_C2_CH1F_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP CH2F register + * + * This function gets the current CMP CH2F register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CH2F register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCh2fReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_CH2F_MASK) >> CMP_C2_CH2F_SHIFT); +} + +/*! \brief Clear CMP CH2F register + * + * This function clear CMP CH2F register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write 1 to Clear + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_ClearCh2fReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_CHnF_MASK); + tmp |= (((uint32_t)(((uint32_t)(1u)) << CMP_C2_CH2F_SHIFT)) & CMP_C2_CH2F_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP CH3F register + * + * This function gets the current CMP CH3F register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CH3F register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCh3fReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_CH3F_MASK) >> CMP_C2_CH3F_SHIFT); +} + +/*! \brief Clear CMP CH3F register + * + * This function clear CMP CH3F register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write 1 to Clear + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_ClearCh3fReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_CHnF_MASK); + tmp |= (((uint32_t)(((uint32_t)(1u)) << CMP_C2_CH3F_SHIFT)) & CMP_C2_CH3F_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP CH4F register + * + * This function gets the current CMP CH4F register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CH4F register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCh4fReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_CH4F_MASK) >> CMP_C2_CH4F_SHIFT); +} + +/*! \brief Clear CMP CH4F register + * + * This function clear CMP CH4F register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write 1 to Clear + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_ClearCh4fReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_CHnF_MASK); + tmp |= (((uint32_t)(((uint32_t)(1u)) << CMP_C2_CH4F_SHIFT)) & CMP_C2_CH4F_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP CH5F register + * + * This function gets the current CMP CH5F register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CH5F register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCh5fReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_CH5F_MASK) >> CMP_C2_CH5F_SHIFT); +} + +/*! \brief Clear CMP CH5F register + * + * This function clear CMP CH5F register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write 1 to Clear + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_ClearCh5fReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_CHnF_MASK); + tmp |= (((uint32_t)(((uint32_t)(1u)) << CMP_C2_CH5F_SHIFT)) & CMP_C2_CH5F_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP CH6F register + * + * This function gets the current CMP CH6F register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CH6F register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCh6fReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_CH6F_MASK) >> CMP_C2_CH6F_SHIFT); +} + +/*! \brief Clear CMP CH6F register + * + * This function clear CMP CH6F register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write 1 to Clear + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_ClearCh6fReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_CHnF_MASK); + tmp |= (((uint32_t)(((uint32_t)(1u)) << CMP_C2_CH6F_SHIFT)) & CMP_C2_CH6F_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP CH7F register + * + * This function gets the current CMP CH6F register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CH7F register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCh7fReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_CH7F_MASK) >> CMP_C2_CH7F_SHIFT); +} + +/*! \brief Clear CMP CH7F register + * + * This function clear CMP CH7F register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write 1 to Clear + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_ClearCh7fReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_CHnF_MASK); + tmp |= (((uint32_t)(((uint32_t)(1u)) << CMP_C2_CH7F_SHIFT)) & CMP_C2_CH7F_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP FXMXCH register + * + * This function gets the current CMP FXMXCH register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP FXMXCH register configuration. + * - 000b: Channel 0 is selected as the fixed reference input for the fixed mux port. + * - 001b: Channel 1 is selected as the fixed reference input for the fixed mux port. + * - 010b: Channel 2 is selected as the fixed reference input for the fixed mux port. + * - 011b: Channel 3 is selected as the fixed reference input for the fixed mux port. + * - 100b: Channel 4 is selected as the fixed reference input for the fixed mux port. + * - 101b: Channel 5 is selected as the fixed reference input for the fixed mux port. + * - 110b: Channel 6 is selected as the fixed reference input for the fixed mux port. + * - 111b: Channel 7 is selected as the fixed reference input for the fixed mux port. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetFxmxchReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_FXMXCH_MASK) >> CMP_C2_FXMXCH_SHIFT); +} + +/*! \brief Set CMP FXMXCH configuration + * + * This function writes new configuration to CMP FXMXCH register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP FXMXCH register configuration + * - 000b: Channel 0 is selected as the fixed reference input for the fixed mux port. + * - 001b: Channel 1 is selected as the fixed reference input for the fixed mux port. + * - 010b: Channel 2 is selected as the fixed reference input for the fixed mux port. + * - 011b: Channel 3 is selected as the fixed reference input for the fixed mux port. + * - 100b: Channel 4 is selected as the fixed reference input for the fixed mux port. + * - 101b: Channel 5 is selected as the fixed reference input for the fixed mux port. + * - 110b: Channel 6 is selected as the fixed reference input for the fixed mux port. + * - 111b: Channel 7 is selected as the fixed reference input for the fixed mux port. + */ +__attribute__((always_inline)) static inline void CmpReg_SetFxmxchReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_FXMXCH_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_FXMXCH_SHIFT)) & CMP_C2_FXMXCH_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP FXMP register + * + * This function gets the current CMP FXMP register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP FXMP register configuration. + * 0b: The Plus port is fixed. Only the inputs to the Minus port are swept in each round. + * 1b: The Minus port is fixed. Only the inputs to the Plus port are swept in each round. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetFxmpReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_FXMP_MASK) >> CMP_C2_FXMP_SHIFT); +} + +/*! \brief Set CMP FXMP configuration + * + * This function writes new configuration to CMP FXMP register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP FXMP register configuration + * 0b: The Plus port is fixed. Only the inputs to the Minus port are swept in each round. + * 1b: The Minus port is fixed. Only the inputs to the Plus port are swept in each round. + */ +__attribute__((always_inline)) static inline void CmpReg_SetFxmpReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_FXMP_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_FXMP_SHIFT)) & CMP_C2_FXMP_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP RRIE register + * + * This function gets the current CMP RRIE register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP RRIE register configuration. + * - 0b: The round-robin interrupt is disabled. + * - 1b: The round-robin interrupt is enabled when a comparison result changes from the last sample. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetRrieReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_RRIE_MASK) >> CMP_C2_RRIE_SHIFT); +} + +/*! \brief Set CMP RRIE configuration + * + * This function writes new configuration to CMP RRIE register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP RRIE register configuration + * - 0b: The round-robin interrupt is disabled. + * - 1b: The round-robin interrupt is enabled when a comparison result changes from the last sample. + */ +__attribute__((always_inline)) static inline void CmpReg_SetRrieReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_RRIE_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_RRIE_SHIFT)) & CMP_C2_RRIE_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP RRE register + * + * This function gets the current CMP RRE register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP RRE register configuration. + * - 0b: Round-robin operation is disabled. + * - 1b: Round-robin operation is enabled. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetRreReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_RRE_MASK) >> CMP_C2_RRE_SHIFT); +} + +/*! \brief Set CMP RRE configuration + * + * This function writes new configuration to CMP RRE register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP RRE register configuration + * - 0b: Round-robin operation is disabled. + * - 1b: Round-robin operation is enabled. + */ +__attribute__((always_inline)) static inline void CmpReg_SetRreReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_RRE_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_RRE_SHIFT)) & CMP_C2_RRE_MASK); + obj->C2 = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _CMP_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/cmu_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/cmu_reg.h new file mode 100644 index 0000000..6567b31 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/cmu_reg.h @@ -0,0 +1,413 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CMU_REG_H_ +#define _CMU_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the CMU Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* GCR Bit Fields */ +#define CMU_GCR_EN_MASK (0x01u) +#define CMU_GCR_EN_SHIFT (0u) +#define CMU_GCR_EN_WIDTH (1u) + +/* RCCR Bit Fields */ +#define CMU_RCCR_REF_CNT_MASK (0xFFFFu) +#define CMU_RCCR_REF_CNT_SHIFT (0u) +#define CMU_RCCR_REF_CNT_WIDTH (16u) + +/* HTCR Bit Fields */ +#define CMU_HTCR_HFREF_MASK (0xFFFFFFu) +#define CMU_HTCR_HFREF_SHIFT (0u) +#define CMU_HTCR_HFREF_WIDTH (24u) + +/* LTCR Bit Fields */ +#define CMU_LTCR_LFREF_MASK (0xFFFFFFu) +#define CMU_LTCR_LFREF_SHIFT (0u) +#define CMU_LTCR_LFREF_WIDTH (24u) + +/* SR Bit Fields */ +#define CMU_SR_RS_MASK (0x10u) +#define CMU_SR_RS_SHIFT (4u) +#define CMU_SR_RS_WIDTH (1u) +#define CMU_SR_FHH_MASK (0x02u) +#define CMU_SR_FHH_SHIFT (1u) +#define CMU_SR_FHH_WIDTH (1u) +#define CMU_SR_FLL_MASK (0x01u) +#define CMU_SR_FLL_SHIFT (0u) +#define CMU_SR_FLL_WIDTH (1u) + +/* IER Bit Fields */ +#define CMU_IER_FHHIE_MASK (0x0Cu) +#define CMU_IER_FHHIE_SHIFT (2u) +#define CMU_IER_FHHIE_WIDTH (2u) +#define CMU_IER_FLLIE_MASK (0x03u) +#define CMU_IER_FLLIE_SHIFT (0u) +#define CMU_IER_FLLIE_WIDTH (2u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of CMU registers + */ +typedef struct _CmuRegType_ +{ + volatile uint32_t GCR; /*!< CMU global config register, offset: 0x0 */ + volatile uint32_t RCCR; /*!< CMU reference counter value config register, offset: 0x4 */ + volatile uint32_t HTCR; /*!< CMU high threshold value config register, offset: 0x8 */ + volatile uint32_t LTCR; /*!< CMU low threshold value config register, offset: 0xC */ + volatile uint32_t SR; /*!< CMU status register, offset: 0x10 */ + volatile uint32_t IER; /*!< CMU interrupt enable register, offset: 0x14 */ +} CmuRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the CMU enable + * + * This function gets the CMU enable + * + * \param[in] obj : pointer to CMU register instance + * \return CMU enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t CmuReg_GetEnable(const CmuRegType *obj) +{ + return ((obj->GCR & CMU_GCR_EN_MASK) >> CMU_GCR_EN_SHIFT); +} + +/*! \brief Sets the CMU enable + * + * This function sets the CMU enable + * + * \param[in] obj : pointer to CMU register instance + * \param[in] value : the value of CMU enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void CmuReg_SetEnable(CmuRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->GCR; + + tmp &= ~CMU_GCR_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMU_GCR_EN_SHIFT)) & CMU_GCR_EN_MASK); + obj->GCR = tmp; +} + +/*! \brief Gets the reference counter value + * + * This function gets the reference counter value + * + * \param[in] obj : pointer to CMU register instance + * \return reference counter value + * - 0000h : 0 + * - 0001h : 1 + * - 0002h : 2 + * . + * . + * . + * - FFFFh : 65535 + */ +__attribute__((always_inline)) static inline uint32_t CmuReg_GetRefCnt(const CmuRegType *obj) +{ + return ((obj->RCCR & CMU_RCCR_REF_CNT_MASK) >> CMU_RCCR_REF_CNT_SHIFT); +} + +/*! \brief Sets the reference counter value + * + * This function sets the reference counter value + * + * \param[in] obj : pointer to CMU register instance + * \param[in] value : reference counter value + * - 0000h : 0 + * - 0001h : 1 + * - 0002h : 2 + * . + * . + * . + * - FFFFh : 65535 + */ +__attribute__((always_inline)) static inline void CmuReg_SetRefCnt(CmuRegType *obj, uint32_t value) +{ + uint32_t tmp = obj->RCCR; + + tmp &= ~CMU_RCCR_REF_CNT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMU_RCCR_REF_CNT_SHIFT)) & CMU_RCCR_REF_CNT_MASK); + obj->RCCR = tmp; +} + +/*! \brief Gets the high threshold value + * + * This function gets the high threshold value + * + * \param[in] obj : pointer to CMU register instance + * \return high threshold value + * - 000000h : 0 + * - 000001h : 1 + * - 000002h : 2 + * . + * . + * . + * - FFFFFFh : 16,777,215 + */ +__attribute__((always_inline)) static inline uint32_t CmuReg_GetFreqHighRefValue(const CmuRegType *obj) +{ + return ((obj->HTCR & CMU_HTCR_HFREF_MASK) >> CMU_HTCR_HFREF_SHIFT); +} + +/*! \brief Sets the high threshold value + * + * This function sets the high threshold value + * + * \param[in] obj : pointer to CMU register instance + * \param[in] value : high threshold value + * - 000000h : 0 + * - 000001h : 1 + * - 000002h : 2 + * . + * . + * . + * - FFFFFFh : 16,777,215 + */ +__attribute__((always_inline)) static inline void CmuReg_SetFreqHighRefValue(CmuRegType *obj, uint32_t value) +{ + uint32_t tmp = obj->HTCR; + + tmp &= ~CMU_HTCR_HFREF_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMU_HTCR_HFREF_SHIFT)) & CMU_HTCR_HFREF_MASK); + obj->HTCR = tmp; +} + +/*! \brief Gets the low threshold value + * + * This function gets the low threshold value + * + * \param[in] obj : pointer to CMU register instance + * \return low threshold value + * - 000000h : 0 + * - 000001h : 1 + * - 000002h : 2 + * . + * . + * . + * - FFFFFFh : 16,777,215 + */ +__attribute__((always_inline)) static inline uint32_t CmuReg_GetFreqLowRefValue(const CmuRegType *obj) +{ + return ((obj->LTCR & CMU_LTCR_LFREF_MASK) >> CMU_LTCR_LFREF_SHIFT); +} + +/*! \brief Sets the low threshold value + * + * This function sets the low threshold value + * + * \param[in] obj : pointer to CMU register instance + * \param[in] value : low threshold value + * - 000000h : 0 + * - 000001h : 1 + * - 000002h : 2 + * . + * . + * . + * - FFFFFFh : 16,777,215 + */ +__attribute__((always_inline)) static inline void CmuReg_SetFreqLowRefValue(CmuRegType *obj, uint32_t value) +{ + uint32_t tmp = obj->LTCR; + + tmp &= ~CMU_LTCR_LFREF_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMU_LTCR_LFREF_SHIFT)) & CMU_LTCR_LFREF_MASK); + obj->LTCR = tmp; +} + +/*! \brief Gets the CMU run status + * + * Indicates the CMU run status + * + * \param[in] obj : pointer to CMU register instance + * \return CMU run status + * - 0b : false + * - 1b : true + */ +__attribute__((always_inline)) static inline uint8_t CmuReg_GetRunStatus(const CmuRegType *obj) +{ + return ((obj->SR & CMU_SR_RS_MASK) >> CMU_SR_RS_SHIFT); +} + +/*! \brief Gets the frequency higher event flag + * + * FHH is set when the CMU is enabled and the frequency detected is higher than high threshold value + * + * \param[in] obj : pointer to CMU register instance + * \return frequency higher event flag + * - 0b : false + * - 1b : true + */ +__attribute__((always_inline)) static inline uint8_t CmuReg_GetFreqHighEventFlag(const CmuRegType *obj) +{ + return ((obj->SR & CMU_SR_FHH_MASK) >> CMU_SR_FHH_SHIFT); +} + +/*! \brief Clear the frequency higher event flag + * + * FHH is cleared when a logic 1 is written to it. + * + * \param[in] obj : pointer to CMU register instance + * \return none + * + */ +__attribute__((always_inline)) static inline void CmuReg_ClearFreqHighEventFlag(CmuRegType *obj) +{ + uint32_t tmp = obj->SR; + tmp &= ~(CMU_SR_FHH_MASK | CMU_SR_FLL_MASK); + tmp |= (CMU_SR_FHH_MASK); + obj->SR = tmp; + /* Read back to avoid problem */ + (void)obj->SR; +} + +/*! \brief Gets the frequency lower event flag + * + * FLL is set when the CMU is enabled and the frequency detected is lower than low threshold value + * + * \param[in] obj : pointer to CMU register instance + * \return frequency Lower event flag + * - 0b : false + * - 1b : true + */ +__attribute__((always_inline)) static inline uint8_t CmuReg_GetFreqLowEventFlag(const CmuRegType *obj) +{ + return ((obj->SR & CMU_SR_FLL_MASK) >> CMU_SR_FLL_SHIFT); +} + +/*! \brief Clear the frequency lower event flag + * + * FHH is cleared when a logic 1 is written to it. + * + * \param[in] obj : pointer to CMU register instance + * \return none + * + */ +__attribute__((always_inline)) static inline void CmuReg_ClearFreqLowEventFlag(CmuRegType *obj) +{ + uint32_t tmp = obj->SR; + tmp &= ~(CMU_SR_FHH_MASK | CMU_SR_FLL_MASK); + tmp |= (CMU_SR_FLL_MASK); + obj->SR = tmp; + /* Read back to avoid problem */ + (void)obj->SR; +} + +/*! \brief Gets the frequency high event state + * + * This function gets the frequency high event state + * + * \param[in] obj : pointer to CMU register instance + * \return frequency higher interrupt enable + * - 00b : interrupt and reset disable + * - 01b : interrupt enable, reset disable + * - 10b : interrupt disable, reset enable + * - 11b : interrupt disable, reset enable + */ +__attribute__((always_inline)) static inline uint8_t CmuReg_GetFreqHighEventState(const CmuRegType *obj) +{ + return ((obj->IER & CMU_IER_FHHIE_MASK) >> CMU_IER_FHHIE_SHIFT); +} + +/*! \brief Sets the frequency high event state + * + * This function sets the frequency high event state + * + * \param[in] obj : pointer to CMU register instance + * \param[in] value : the value of the frequency high event state + * - 00b : interrupt and reset disable + * - 01b : interrupt enable, reset disable + * - 10b : interrupt disable, reset enable + * - 11b : interrupt disable, reset enable + */ +__attribute__((always_inline)) static inline void CmuReg_SetFreqHighEventState(CmuRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IER; + + tmp &= ~CMU_IER_FHHIE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMU_IER_FHHIE_SHIFT)) & CMU_IER_FHHIE_MASK); + obj->IER = tmp; +} + +/*! \brief Gets the frequency low event state + * + * This function gets the frequency low event state + * + * \param[in] obj : pointer to CMU register instance + * \return frequency lower interrupt enable + * - 00b : interrupt and reset disable + * - 01b : interrupt enable, reset disable + * - 10b : interrupt disable, reset enable + * - 11b : interrupt disable, reset enable + */ +__attribute__((always_inline)) static inline uint8_t CmuReg_GetFreqLowEventState(const CmuRegType *obj) +{ + return ((obj->IER & CMU_IER_FLLIE_MASK) >> CMU_IER_FLLIE_SHIFT); +} + +/*! \brief Sets the frequency low event state + * + * This function sets the frequency low event state + * + * \param[in] obj : pointer to CMU register instance + * \param[in] value : the value of the frequency low event state + * - 00b : interrupt and reset disable + * - 01b : interrupt enable, reset disable + * - 10b : interrupt disable, reset enable + * - 11b : interrupt disable, reset enable + */ +__attribute__((always_inline)) static inline void CmuReg_SetFreqLowEventState(CmuRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IER; + + tmp &= ~CMU_IER_FLLIE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMU_IER_FLLIE_SHIFT)) & CMU_IER_FLLIE_MASK); + obj->IER = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _CMU_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/crc_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/crc_reg.h new file mode 100644 index 0000000..dcb304a --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/crc_reg.h @@ -0,0 +1,416 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CRC_REG_H_ +#define _CRC_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the CRC Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* DR Bit Fields */ +#define CRC_DR_DR_MASK (0xFFFFFFFFu) +#define CRC_DR_DR_SHIFT (0u) +#define CRC_DR_DR_WIDTH (32u) + +/* IDR Bit Fields */ +#define CRC_IDR_COUNTER_MASK (0xFu) +#define CRC_IDR_COUNTER_SHIFT (0u) +#define CRC_IDR_COUNTER_WIDTH (4u) + +/* CR Bit Fields */ +#define CRC_CR_RESET_MASK (0x1u) +#define CRC_CR_RESET_SHIFT (0u) +#define CRC_CR_RESET_WIDTH (1u) +#define CRC_CR_REVIN_MASK (0x60u) +#define CRC_CR_REVIN_SHIFT (5u) +#define CRC_CR_REVIN_WIDTH (2u) +#define CRC_CR_REVOUT_MASK (0x300u) +#define CRC_CR_REVOUT_SHIFT (8u) +#define CRC_CR_REVOUT_WIDTH (2u) +#define CRC_CR_FXOR_MASK (0x800u) +#define CRC_CR_FXOR_SHIFT (11u) +#define CRC_CR_FXOR_WIDTH (1u) +#define CRC_CR_TCRC_MASK (0x1000u) +#define CRC_CR_TCRC_SHIFT (12u) +#define CRC_CR_TCRC_WIDTH (1u) + +/* INIT Bit Fields */ +#define CRC_INIT_INIT_MASK (0xFFFFFFFFu) +#define CRC_INIT_INIT_SHIFT (0u) +#define CRC_INIT_INIT_WIDTH (32u) + +/* POL Bit Fields */ +#define CRC_POL_POL_MASK (0xFFFFFFFFu) +#define CRC_POL_POL_SHIFT (0u) +#define CRC_POL_POL_WIDTH (32u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of CRC registers + */ +typedef struct _CrcRegType_ +{ + union + { + volatile uint32_t DATA_32; /*!< CRC data storage register, offset: 0x0 */ + struct + { + volatile uint16_t L; /*!< CRC_DR_L, offset: 0x0 */ + volatile uint16_t H; /*!< CRC_DR_L, offset: 0x2 */ + } DATA_16; + struct + { + volatile uint8_t LL; /*!< CRC_DR_LL, offset: 0x0 */ + volatile uint8_t LU; /*!< CRC_DR_LU, offset: 0x1 */ + volatile uint8_t HL; /*!< CRC_DR_HL, offset: 0x2 */ + volatile uint8_t HU; /*!< CRC_DR_HU, offset: 0x3 */ + } DATA_8; + } DR; + volatile uint32_t IDR; /*!< CRC data length register, offset: 0x4 */ + volatile uint32_t CR; /*!< CRC control register, offset: 0x8 */ + uint32_t RESERVED; /*!< Reserved register, offset: 0xC */ + volatile uint32_t INIT; /*!< Initial seed value register, offset: 0x10 */ + volatile uint32_t POL; /*!< Initial value of polynormal register, offset: 0x14 */ +} CrcRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Get the current CRC data register + * + * This function gets the current CRC calculation result. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * If CR.RESET happen, it holds the crc_init value + * + * \param[in] obj : pointer to CRC register instance + * \return the current CRC calculation result + */ +__attribute__((always_inline)) static inline uint32_t CrcReg_GetDataReg(const CrcRegType *obj) +{ + return obj->DR.DATA_32; +} + +/*! \brief Set the 32 bits of CRC data register + * + * This function writes new 32 bits data to CRC calculator + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CRC register instance + * \param[in] value : current CRC calculation data + */ +__attribute__((always_inline)) static inline void CrcReg_SetDataReg(CrcRegType *obj, uint32_t value) +{ + obj->DR.DATA_32 = value; +} + +/*! \brief Set the 16 bits of CRC data register + * + * This function writes new 16 bits data to CRC calculator + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CRC register instance + * \param[in] value : current CRC calculation data + */ +__attribute__((always_inline)) static inline void CrcReg_SetData16Reg(CrcRegType *obj, uint16_t value) +{ + obj->DR.DATA_16.L = value; +} + +/*! \brief Set the 8 bits of CRC data register + * + * This function writes new 8 bits data to CRC calculator + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CRC register instance + * \param[in] value : current CRC calculation data + */ +__attribute__((always_inline)) static inline void CrcReg_SetData8Reg(CrcRegType *obj, uint8_t value) +{ + obj->DR.DATA_8.LL = value; +} + +/*! \brief Get the remain number of data in FIFO + * + * Total depth is 8, the register shows the remain number of data in fifo + * Counter reset to 0 if CR.RESET happened + * This register is read-only + * + * \param[in] obj : pointer to CRC register instance + * \return the remain number of data in fifo + */ +__attribute__((always_inline)) static inline uint32_t CrcReg_GetDataNumInFifo(const CrcRegType *obj) +{ + return ((obj->IDR & CRC_IDR_COUNTER_MASK) >> CRC_IDR_COUNTER_SHIFT); +} + +/*! \brief Get the reset bit in CR register + * + * This bit is automatically cleared by hardware. + * Read as 1 , assert to 1 after reading + * + * \param[in] obj : pointer to CRC register instance + * \return the reset bit value + */ +__attribute__((always_inline)) static inline uint8_t CrcReg_GetCrReset(const CrcRegType *obj) +{ + return ((obj->CR & CRC_CR_RESET_MASK) >> CRC_CR_RESET_SHIFT); +} + +/*! \brief Set the reset bit in CR register + * + * This bit is set to reset CRC calculation unit and set data register to the value stored in CRC_INIT + * + * \param[in] obj : pointer to CRC register instance + */ +__attribute__((always_inline)) static inline void CrcReg_SetCrReset(CrcRegType *obj) +{ + uint32_t crTmp = obj->CR; + + crTmp &= ~(CRC_CR_RESET_MASK); + crTmp |= (((uint32_t)(((uint32_t)(1u)) << CRC_CR_RESET_SHIFT)) & CRC_CR_RESET_MASK); + obj->CR = crTmp; +} + +/*! \brief Get the reversal of bit order of the input data + * + * These bits control the reversal of the bit order of the input data + * This register is not affected by CRC resets generated by the reset bit in the CRC_CR register + * + * \param[in] obj : pointer to CRC register instance + * \return the value of reversal of bit order + * - 0 : No transposition. + * - 1 : Bits in bytes are transposed; bytes are not transposed. + * - 2 : Both bits in bytes and bytes are transposed + * - 3 : Only bytes are transposed; no bits in a byte are transposed + */ +__attribute__((always_inline)) static inline uint8_t CrcReg_GetCrReverseIn(const CrcRegType *obj) +{ + return ((obj->CR & CRC_CR_REVIN_MASK) >> CRC_CR_REVIN_SHIFT); +} + +/*! \brief Set the reversal of bit order of the input data + * + * These bits control the reversal of the bit order of the input data + * This register is not affected by CRC resets generated by the reset bit in the CRC_CR register + * + * \param[in] obj : pointer to CRC register instance + * \param[in] value : the value of reversal of bit order + * - 0 : No transposition. + * - 1 : Bits in bytes are transposed; bytes are not transposed. + * - 2 : Both bits in bytes and bytes are transposed + * - 3 : Only bytes are transposed; no bits in a byte are transposed + */ +__attribute__((always_inline)) static inline void CrcReg_SetCrReverseIn(CrcRegType *obj, uint8_t value) +{ + uint32_t crTmp = obj->CR; + + crTmp &= ~(CRC_CR_REVIN_MASK); + crTmp |= (((uint32_t)(((uint32_t)(value)) << CRC_CR_REVIN_SHIFT)) & CRC_CR_REVIN_MASK); + obj->CR = crTmp; +} + +/*! \brief Get the reversal of bit order of the output data + * + * These bits control the reversal of the bit order of the output data + * This register is not affected by CRC resets generated by the reset bit in the CRC_CR register + * + * \param[in] obj : pointer to CRC register instance + * \return the value of reversal of bit order + * - 0 : No transposition. + * - 1 : Bits in bytes are transposed; bytes are not transposed. + * - 2 : Both bits in bytes and bytes are transposed + * - 3 : Only bytes are transposed; no bits in a byte are transposed + */ +__attribute__((always_inline)) static inline uint8_t CrcReg_GetCrReverseOut(const CrcRegType *obj) +{ + return ((obj->CR & CRC_CR_REVOUT_MASK) >> CRC_CR_REVOUT_SHIFT); +} + +/*! \brief Set the reversal of bit order of the output data + * + * These bits control the reversal of the bit order of the output data + * This register is not affected by CRC resets generated by the reset bit in the CRC_CR register + * + * \param[in] obj : pointer to CRC register instance + * \param[in] value : the value of reversal of bit order + * - 0 : No transposition. + * - 1 : Bits in bytes are transposed; bytes are not transposed. + * - 2 : Both bits in bytes and bytes are transposed + * - 3 : Only bytes are transposed; no bits in a byte are transposed + */ +__attribute__((always_inline)) static inline void CrcReg_SetCrReverseOut(CrcRegType *obj, uint8_t value) +{ + uint32_t crTmp = obj->CR; + + crTmp &= ~(CRC_CR_REVOUT_MASK); + crTmp |= (((uint32_t)(((uint32_t)(value)) << CRC_CR_REVOUT_SHIFT)) & CRC_CR_REVOUT_MASK); + obj->CR = crTmp; +} + +/*! \brief Get complement read of CRC data register + * + * Some CRC protocols require the final checksum to be XORed with 0xFFFFFFFF or 0xFFFF. + * Asserting this bit enables on the fly complementing of read data. + * This register is not affected by CRC resets generated by the reset bit in the CRC_CR register. + * + * \param[in] obj : pointer to CRC register instance + * \return the value of complement read + * - 0 : No XOR on reading. + * - 1 : Invert or complement the read value of the CRC Data register. + */ +__attribute__((always_inline)) static inline uint8_t CrcReg_GetCrFXor(const CrcRegType *obj) +{ + return ((obj->CR & CRC_CR_FXOR_MASK) >> CRC_CR_FXOR_SHIFT); +} + +/*! \brief Set complement read of CRC data register + * + * Some CRC protocols require the final checksum to be XORed with 0xFFFFFFFF or 0xFFFF. + * Asserting this bit enables on the fly complementing of read data. + * This register is not affected by CRC resets generated by the reset bit in the CRC_CR register. + * + * \param[in] obj : pointer to CRC register instance + * \param[in] value : the value of complement read + * - 0 : No XOR on reading. + * - 1 : Invert or complement the read value of the CRC Data register. + */ +__attribute__((always_inline)) static inline void CrcReg_SetCrFXor(CrcRegType *obj, uint8_t value) +{ + uint32_t crTmp = obj->CR; + + crTmp &= ~(CRC_CR_FXOR_MASK); + crTmp |= (((uint32_t)(((uint32_t)(value)) << CRC_CR_FXOR_SHIFT)) & CRC_CR_FXOR_MASK); + obj->CR = crTmp; +} + +/*! \brief Get the width of CRC protocol (poly) + * + * This function gets the width of CRC protocol (poly). + * This register is not affected by CRC resets generated by the reset bit in the CRC_CR register. + * + * \param[in] obj : pointer to CRC register instance + * \return the value of reversal of bit order + * - 0 : 16-bit CRC protocol. + * - 1 : 32-bit CRC protocol. + */ +__attribute__((always_inline)) static inline uint8_t CrcReg_GetCrProtocolWidth(const CrcRegType *obj) +{ + return ((obj->CR & CRC_CR_TCRC_MASK) >> CRC_CR_TCRC_SHIFT); +} + +/*! \brief Set the width of CRC protocol (poly) + * + * This function sets the width of CRC protocol (poly). + * This register is not affected by CRC resets generated by the reset bit in the CRC_CR register. + * + * \param[in] obj : pointer to CRC register instance + * \param[in] value : the value of reversal of bit order + * - 0 : 16-bit CRC protocol. + * - 1 : 32-bit CRC protocol. + */ +__attribute__((always_inline)) static inline void CrcReg_SetCrProtocolWidth(CrcRegType *obj, uint8_t value) +{ + uint32_t crTmp = obj->CR; + + crTmp &= ~(CRC_CR_TCRC_MASK); + crTmp |= (((uint32_t)(((uint32_t)(value)) << CRC_CR_TCRC_SHIFT)) & CRC_CR_TCRC_MASK); + obj->CR = crTmp; +} + +/*! \brief Get the initial seed register value + * + * This function gets the initial seed register value. + * + * \param[in] obj : pointer to CRC register instance + * \return the initial seed register value + */ +__attribute__((always_inline)) static inline uint32_t CrcReg_GetInitReg(const CrcRegType *obj) +{ + return obj->INIT; +} + +/*! \brief Set the initial seed register + * + * This function sets the initial seed register. + * Write this reg also can reset CRC calculation unit. + * + * \param[in] obj : pointer to CRC register instance + * \param[in] value : initial seed + */ +__attribute__((always_inline)) static inline void CrcReg_SetInitReg(CrcRegType *obj, uint32_t value) +{ + obj->INIT = value; +} + +/*! \brief Get the initial value of polynomial + * + * This function gets the initial value of polynomial. + * This register is not affected by CRC resets generated + * by the reset bit in the CRC_CR register. + * + * \param[in] obj : pointer to CRC register instance + * \return the initial value of polynomial + */ +__attribute__((always_inline)) static inline uint32_t CrcReg_GetPolyReg(const CrcRegType *obj) +{ + return obj->POL; +} + +/*! \brief Set initial value of polynomial + * + * This function sets initial value of polynomial. + * This register is not affected by CRC resets generated + * by the reset bit in the CRC_CR register. + * + * \param[in] obj : pointer to CRC register instance + * \param[in] value : the initial value of polynomial + */ +__attribute__((always_inline)) static inline void CrcReg_SetPolyReg(CrcRegType *obj, uint32_t value) +{ + obj->POL = value; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _CRC_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/dmamux_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/dmamux_reg.h new file mode 100644 index 0000000..cc9bdfc --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/dmamux_reg.h @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _DMAMUX_REG_H_ +#define _DMAMUX_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the DMAMUX (Direct Memory Access Multiplexer) Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* DMAMUX peripheral is available in silicon. */ +#define DMAMUX_AVAILABLE +/* Number of DMA channels. */ +#define DMAMUX_CHANNELS (4U) +/* Has the periodic trigger capability */ +#define DMAMUX_HAS_TRIG (1) +/** DMAMUX - Size of Registers Arrays */ +#define DMAMUX_CHCFG_COUNT (4u) + +/* CR Bit Fields */ +#define DMAMUX_CHCFG_SOURCE_MASK (0x3Fu) +#define DMAMUX_CHCFG_SOURCE_SHIFT (0u) +#define DMAMUX_CHCFG_SOURCE_WIDTH (6u) +#define DMAMUX_CHCFG_TRIG_MASK (0x40u) +#define DMAMUX_CHCFG_TRIG_SHIFT (6u) +#define DMAMUX_CHCFG_TRIG_WIDTH (1u) +#define DMAMUX_CHCFG_ENBL_MASK (0x80u) +#define DMAMUX_CHCFG_ENBL_SHIFT (7u) +#define DMAMUX_CHCFG_ENBL_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of DMAMUX registers + */ +typedef struct _DmamuxRegType_ +{ + volatile uint8_t CHCFG[DMAMUX_CHCFG_COUNT]; /*!< Channel Configuration register, array offset: 0x0, array step: 0x1 */ +} DmamuxRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ +/*! \brief Configures the DMA request for the DMAMUX channel. + * + * Selects which DMA source is routed to a DMA channel. + * + * \param[in] obj : pointer to DMAMUX register instance. + * \param[in] channel : DMAMUX channel number. + * \param[in] source : DMA request source. + */ +__attribute__((always_inline)) static inline void DmamuxReg_SetChannelSource(DmamuxRegType *obj, uint8_t channel, uint8_t source) +{ + uint8_t regValTemp; + regValTemp = obj->CHCFG[channel]; + regValTemp &= (uint8_t) ~(DMAMUX_CHCFG_SOURCE_MASK); + regValTemp |= (uint8_t)(((uint8_t)(((uint8_t)(source)) << DMAMUX_CHCFG_SOURCE_SHIFT)) & DMAMUX_CHCFG_SOURCE_MASK); + obj->CHCFG[channel] = regValTemp; +} + +/*! \brief Configure DMA Channel Trigger bit in DMAMUX. + * + * Enables/Disables DMA Channel Trigger bit in DMAMUX. + * + * \param[in] obj : pointer to DMAMUX register instance. + * \param[in] channel : DMAMUX channel number. + * \param[in] enable: Enables (true) or Disables (false) command. + */ +__attribute__((always_inline)) static inline void DmamuxReg_SetChannelTrigger(DmamuxRegType *obj, uint8_t channel, bool enable) +{ + if(enable) + { + obj->CHCFG[channel] |= DMAMUX_CHCFG_TRIG_MASK; + } + else + { + obj->CHCFG[channel] &= ~DMAMUX_CHCFG_TRIG_MASK; + } +} + +/*! \brief Enables/Disables the DMAMUX channel. + * + * Enables the hardware request. If enabled, the hardware request is sent to + * the corresponding DMA channel. + * + * \param[in] obj : pointer to DMAMUX register instance. + * \param[in] channel DMAMUX channel number. + * \param[in] enable: Enables (true) or Disables (false) DMAMUX channel. + */ +__attribute__((always_inline)) static inline void DmamuxReg_SetChannelCmd(DmamuxRegType *obj, uint8_t channel, bool enable) +{ + if(enable) + { + obj->CHCFG[channel] |= DMAMUX_CHCFG_ENBL_MASK; + } + else + { + obj->CHCFG[channel] &= ~DMAMUX_CHCFG_ENBL_MASK; + } +} + +/*! \brief Initializes the DMAMUX module to the reset state. + * + * Initializes the DMAMUX module to the reset state. + * + * \param[in] obj : pointer to DMAMUX register instance. + */ +__attribute__((always_inline)) static inline void DmamuxReg_Init(DmamuxRegType *obj) +{ + uint8_t i; + + for(i = 0; i < DMAMUX_CHANNELS; i++) + { + obj->CHCFG[i] = 0; + } +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _DMAMUX_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/edma_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/edma_reg.h new file mode 100644 index 0000000..79a651d --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/edma_reg.h @@ -0,0 +1,2109 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _EDMA_REG_H_ +#define _EDMA_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the EDMA (Enhance Direct Memory Access) Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* Number of EDMA channels. */ +#define EDMA_CHANNELS (4U) +/* brief Number of EDMA interrupt lines. */ +#define EDMA_CHANNELS_INTERRUPT_LINES (4U) +/* brief EDMA supports the following particular transfer size: */ +#define EDMA_TRANSFER_SIZE_16B +#define EDMA_TRANSFER_SIZE_32B + +/*! \brief Structure for the EDMA hardware request + * + * Defines the structure for the EDMA hardware request collections. The user can configure the + * hardware request into EDMAMUX to trigger the EDMA transfer accordingly. The index + * of the hardware request varies according to the to SoC. + */ + +typedef enum +{ + EDMA_REQ_TRIGGER_0 = 0U, + EDMA_REQ_TRIGGER_1 = 1U, + + EDMA_REQ_DISABLED = 2U, + + EDMA_REQ_UART0_RX = 3U, + EDMA_REQ_UART0_TX = 4U, + EDMA_REQ_UART1_RX = 5U, + EDMA_REQ_UART1_TX = 6U, + EDMA_REQ_UART2_RX = 7U, + EDMA_REQ_UART2_TX = 8U, + + EDMA_REQ_I2S_SLV = 11U, + EDMA_REQ_I2S_MST = 12U, + + EDMA_REQ_SPI0_RX = 13U, + EDMA_REQ_SPI0_TX = 14U, + EDMA_REQ_SPI1_RX = 15U, + EDMA_REQ_SPI1_TX = 16U, + + EDMA_REQ_MFT0_CHANNEL_0 = 21U, + EDMA_REQ_MFT0_CHANNEL_1 = 22U, + EDMA_REQ_MFT0_CHANNEL_2 = 23U, + EDMA_REQ_MFT0_CHANNEL_3 = 24U, + EDMA_REQ_MFT0_CHANNEL_4 = 25U, + EDMA_REQ_MFT0_CHANNEL_5 = 26U, + EDMA_REQ_MFT0_CHANNEL_6 = 27U, + EDMA_REQ_MFT0_CHANNEL_7 = 28U, + + EDMA_REQ_MFT1_CHANNEL_0 = 29U, + EDMA_REQ_MFT1_CHANNEL_1 = 30U, + EDMA_REQ_MFT1_CHANNEL_2 = 31U, + EDMA_REQ_MFT1_CHANNEL_3 = 32U, + EDMA_REQ_MFT1_CHANNEL_4 = 33U, + EDMA_REQ_MFT1_CHANNEL_5 = 34U, + EDMA_REQ_MFT1_CHANNEL_6 = 35U, + EDMA_REQ_MFT1_CHANNEL_7 = 36U, + + EDMA_REQ_I2C0_RX = 45U, + EDMA_REQ_I2C0_TX = 46U, + + EDMA_REQ_PDB = 47U, + + EDMA_REQ_CMP = 49U, + + EDMA_REQ_PORTA = 50U, + EDMA_REQ_PORTB = 51U, + EDMA_REQ_PORTC = 52U, + EDMA_REQ_PORTD = 53U, + EDMA_REQ_PORTE = 54U, + + EDMA_REQ_CAN = 55U, + + EDMA_REQ_LPTMR0 = 59U, + + EDMA_REQ_ADC0 = 60U, +} EDma_RequestSourceType; + +/* CR Bit Fields */ +#define EDMA_CR_EDBG_MASK (0x2u) +#define EDMA_CR_EDBG_SHIFT (1u) +#define EDMA_CR_EDBG_WIDTH (1u) +#define EDMA_CR_ERCA_MASK (0x4u) +#define EDMA_CR_ERCA_SHIFT (2u) +#define EDMA_CR_ERCA_WIDTH (1u) +#define EDMA_CR_HOE_MASK (0x10u) +#define EDMA_CR_HOE_SHIFT (4u) +#define EDMA_CR_HOE_WIDTH (1u) +#define EDMA_CR_HALT_MASK (0x20u) +#define EDMA_CR_HALT_SHIFT (5u) +#define EDMA_CR_HALT_WIDTH (1u) +#define EDMA_CR_CLM_MASK (0x40u) +#define EDMA_CR_CLM_SHIFT (6u) +#define EDMA_CR_CLM_WIDTH (1u) +#define EDMA_CR_EMLM_MASK (0x80u) +#define EDMA_CR_EMLM_SHIFT (7u) +#define EDMA_CR_EMLM_WIDTH (1u) +#define EDMA_CR_ECX_MASK (0x10000u) +#define EDMA_CR_ECX_SHIFT (16u) +#define EDMA_CR_ECX_WIDTH (1u) +#define EDMA_CR_CX_MASK (0x20000u) +#define EDMA_CR_CX_SHIFT (17u) +#define EDMA_CR_CX_WIDTH (1u) +#define EDMA_CR_ACTIVE_MASK (0x80000000u) +#define EDMA_CR_ACTIVE_SHIFT (31u) +#define EDMA_CR_ACTIVE_WIDTH (1u) + +/* ES Bit Fields */ +#define EDMA_ES_DBE_MASK (0x1u) +#define EDMA_ES_DBE_SHIFT (0u) +#define EDMA_ES_DBE_WIDTH (1u) +#define EDMA_ES_SBE_MASK (0x2u) +#define EDMA_ES_SBE_SHIFT (1u) +#define EDMA_ES_SBE_WIDTH (1u) +#define EDMA_ES_SGE_MASK (0x4u) +#define EDMA_ES_SGE_SHIFT (2u) +#define EDMA_ES_SGE_WIDTH (1u) +#define EDMA_ES_NCE_MASK (0x8u) +#define EDMA_ES_NCE_SHIFT (3u) +#define EDMA_ES_NCE_WIDTH (1u) +#define EDMA_ES_DOE_MASK (0x10u) +#define EDMA_ES_DOE_SHIFT (4u) +#define EDMA_ES_DOE_WIDTH (1u) +#define EDMA_ES_DAE_MASK (0x20u) +#define EDMA_ES_DAE_SHIFT (5u) +#define EDMA_ES_DAE_WIDTH (1u) +#define EDMA_ES_SOE_MASK (0x40u) +#define EDMA_ES_SOE_SHIFT (6u) +#define EDMA_ES_SOE_WIDTH (1u) +#define EDMA_ES_SAE_MASK (0x80u) +#define EDMA_ES_SAE_SHIFT (7u) +#define EDMA_ES_SAE_WIDTH (1u) +#define EDMA_ES_ERRCHN_MASK (0xF00u) +#define EDMA_ES_ERRCHN_SHIFT (8u) +#define EDMA_ES_ERRCHN_WIDTH (4u) +#define EDMA_ES_CPE_MASK (0x4000u) +#define EDMA_ES_CPE_SHIFT (14u) +#define EDMA_ES_CPE_WIDTH (1u) +#define EDMA_ES_ECX_MASK (0x10000u) +#define EDMA_ES_ECX_SHIFT (16u) +#define EDMA_ES_ECX_WIDTH (1u) +#define EDMA_ES_VLD_MASK (0x80000000u) +#define EDMA_ES_VLD_SHIFT (31u) +#define EDMA_ES_VLD_WIDTH (1u) + +/* ERQ Bit Fields */ +#define EDMA_ERQ_ERQ0_MASK (0x1u) +#define EDMA_ERQ_ERQ0_SHIFT (0u) +#define EDMA_ERQ_ERQ0_WIDTH (1u) +#define EDMA_ERQ_ERQ1_MASK (0x2u) +#define EDMA_ERQ_ERQ1_SHIFT (1u) +#define EDMA_ERQ_ERQ1_WIDTH (1u) +#define EDMA_ERQ_ERQ2_MASK (0x4u) +#define EDMA_ERQ_ERQ2_SHIFT (2u) +#define EDMA_ERQ_ERQ2_WIDTH (1u) +#define EDMA_ERQ_ERQ3_MASK (0x8u) +#define EDMA_ERQ_ERQ3_SHIFT (3u) +#define EDMA_ERQ_ERQ3_WIDTH (1u) + +/* EEI Bit Fields */ +#define EDMA_EEI_EEI0_MASK (0x1u) +#define EDMA_EEI_EEI0_SHIFT (0u) +#define EDMA_EEI_EEI0_WIDTH (1u) +#define EDMA_EEI_EEI1_MASK (0x2u) +#define EDMA_EEI_EEI1_SHIFT (1u) +#define EDMA_EEI_EEI1_WIDTH (1u) +#define EDMA_EEI_EEI2_MASK (0x4u) +#define EDMA_EEI_EEI2_SHIFT (2u) +#define EDMA_EEI_EEI2_WIDTH (1u) +#define EDMA_EEI_EEI3_MASK (0x8u) +#define EDMA_EEI_EEI3_SHIFT (3u) +#define EDMA_EEI_EEI3_WIDTH (1u) + +/* CEEI Bit Fields */ +#define EDMA_CEEI_CEEI_MASK (0xFu) +#define EDMA_CEEI_CEEI_SHIFT (0u) +#define EDMA_CEEI_CEEI_WIDTH (4u) +#define EDMA_CEEI_CAEE_MASK (0x40u) +#define EDMA_CEEI_CAEE_SHIFT (6u) +#define EDMA_CEEI_CAEE_WIDTH (1u) +#define EDMA_CEEI_NOP_MASK (0x80u) +#define EDMA_CEEI_NOP_SHIFT (7u) +#define EDMA_CEEI_NOP_WIDTH (1u) + +/* SEEI Bit Fields */ +#define EDMA_SEEI_SEEI_MASK (0xFu) +#define EDMA_SEEI_SEEI_SHIFT (0u) +#define EDMA_SEEI_SEEI_WIDTH (4u) +#define EDMA_SEEI_SAEE_MASK (0x40u) +#define EDMA_SEEI_SAEE_SHIFT (6u) +#define EDMA_SEEI_SAEE_WIDTH (1u) +#define EDMA_SEEI_NOP_MASK (0x80u) +#define EDMA_SEEI_NOP_SHIFT (7u) +#define EDMA_SEEI_NOP_WIDTH (1u) + +/* CERQ Bit Fields */ +#define EDMA_CERQ_CERQ_MASK (0xFu) +#define EDMA_CERQ_CERQ_SHIFT (0u) +#define EDMA_CERQ_CERQ_WIDTH (4u) +#define EDMA_CERQ_CAER_MASK (0x40u) +#define EDMA_CERQ_CAER_SHIFT (6u) +#define EDMA_CERQ_CAER_WIDTH (1u) +#define EDMA_CERQ_NOP_MASK (0x80u) +#define EDMA_CERQ_NOP_SHIFT (7u) +#define EDMA_CERQ_NOP_WIDTH (1u) + +/* SERQ Bit Fields */ +#define EDMA_SERQ_SERQ_MASK (0xFu) +#define EDMA_SERQ_SERQ_SHIFT (0u) +#define EDMA_SERQ_SERQ_WIDTH (4u) +#define EDMA_SERQ_SAER_MASK (0x40u) +#define EDMA_SERQ_SAER_SHIFT (6u) +#define EDMA_SERQ_SAER_WIDTH (1u) +#define EDMA_SERQ_NOP_MASK (0x80u) +#define EDMA_SERQ_NOP_SHIFT (7u) +#define EDMA_SERQ_NOP_WIDTH (1u) + +/* CDNE Bit Fields */ +#define EDMA_CDNE_CDNE_MASK (0xFu) +#define EDMA_CDNE_CDNE_SHIFT (0u) +#define EDMA_CDNE_CDNE_WIDTH (4u) +#define EDMA_CDNE_CADN_MASK (0x40u) +#define EDMA_CDNE_CADN_SHIFT (6u) +#define EDMA_CDNE_CADN_WIDTH (1u) +#define EDMA_CDNE_NOP_MASK (0x80u) +#define EDMA_CDNE_NOP_SHIFT (7u) +#define EDMA_CDNE_NOP_WIDTH (1u) + +/* SSRT Bit Fields */ +#define EDMA_SSRT_SSRT_MASK (0xFu) +#define EDMA_SSRT_SSRT_SHIFT (0u) +#define EDMA_SSRT_SSRT_WIDTH (4u) +#define EDMA_SSRT_SAST_MASK (0x40u) +#define EDMA_SSRT_SAST_SHIFT (6u) +#define EDMA_SSRT_SAST_WIDTH (1u) +#define EDMA_SSRT_NOP_MASK (0x80u) +#define EDMA_SSRT_NOP_SHIFT (7u) +#define EDMA_SSRT_NOP_WIDTH (1u) + +/* CERR Bit Fields */ +#define EDMA_CERR_CERR_MASK (0xFu) +#define EDMA_CERR_CERR_SHIFT (0u) +#define EDMA_CERR_CERR_WIDTH (4u) +#define EDMA_CERR_CAEI_MASK (0x40u) +#define EDMA_CERR_CAEI_SHIFT (6u) +#define EDMA_CERR_CAEI_WIDTH (1u) +#define EDMA_CERR_NOP_MASK (0x80u) +#define EDMA_CERR_NOP_SHIFT (7u) +#define EDMA_CERR_NOP_WIDTH (1u) + +/* CINT Bit Fields */ +#define EDMA_CINT_CINT_MASK (0xFu) +#define EDMA_CINT_CINT_SHIFT (0u) +#define EDMA_CINT_CINT_WIDTH (4u) +#define EDMA_CINT_CAIR_MASK (0x40u) +#define EDMA_CINT_CAIR_SHIFT (6u) +#define EDMA_CINT_CAIR_WIDTH (1u) +#define EDMA_CINT_NOP_MASK (0x80u) +#define EDMA_CINT_NOP_SHIFT (7u) +#define EDMA_CINT_NOP_WIDTH (1u) + +/* INT Bit Fields */ +#define EDMA_INT_INT0_MASK (0x1u) +#define EDMA_INT_INT0_SHIFT (0u) +#define EDMA_INT_INT0_WIDTH (1u) +#define EDMA_INT_INT1_MASK (0x2u) +#define EDMA_INT_INT1_SHIFT (1u) +#define EDMA_INT_INT1_WIDTH (1u) +#define EDMA_INT_INT2_MASK (0x4u) +#define EDMA_INT_INT2_SHIFT (2u) +#define EDMA_INT_INT2_WIDTH (1u) +#define EDMA_INT_INT3_MASK (0x8u) +#define EDMA_INT_INT3_SHIFT (3u) +#define EDMA_INT_INT3_WIDTH (1u) + +/* ERR Bit Fields */ +#define EDMA_ERR_ERRN_MASK (0x1u) +#define EDMA_ERR_ERR0_MASK (0x1u) +#define EDMA_ERR_ERR0_SHIFT (0u) +#define EDMA_ERR_ERR0_WIDTH (1u) +#define EDMA_ERR_ERR1_MASK (0x2u) +#define EDMA_ERR_ERR1_SHIFT (1u) +#define EDMA_ERR_ERR1_WIDTH (1u) +#define EDMA_ERR_ERR2_MASK (0x4u) +#define EDMA_ERR_ERR2_SHIFT (2u) +#define EDMA_ERR_ERR2_WIDTH (1u) +#define EDMA_ERR_ERR3_MASK (0x8u) +#define EDMA_ERR_ERR3_SHIFT (3u) +#define EDMA_ERR_ERR3_WIDTH (1u) + +/* HRS Bit Fields */ +#define EDMA_HRS_HRS0_MASK (0x1u) +#define EDMA_HRS_HRS0_SHIFT (0u) +#define EDMA_HRS_HRS0_WIDTH (1u) +#define EDMA_HRS_HRS1_MASK (0x2u) +#define EDMA_HRS_HRS1_SHIFT (1u) +#define EDMA_HRS_HRS1_WIDTH (1u) +#define EDMA_HRS_HRS2_MASK (0x4u) +#define EDMA_HRS_HRS2_SHIFT (2u) +#define EDMA_HRS_HRS2_WIDTH (1u) +#define EDMA_HRS_HRS3_MASK (0x8u) +#define EDMA_HRS_HRS3_SHIFT (3u) +#define EDMA_HRS_HRS3_WIDTH (1u) + +/* DCHPRI Bit Fields */ +#define EDMA_DCHPRI_CHPRI_MASK (0xFu) +#define EDMA_DCHPRI_CHPRI_SHIFT (0u) +#define EDMA_DCHPRI_CHPRI_WIDTH (4u) +#define EDMA_DCHPRI_DPA_MASK (0x40u) +#define EDMA_DCHPRI_DPA_SHIFT (6u) +#define EDMA_DCHPRI_DPA_WIDTH (1u) +#define EDMA_DCHPRI_ECP_MASK (0x80u) +#define EDMA_DCHPRI_ECP_SHIFT (7u) +#define EDMA_DCHPRI_ECP_WIDTH (1u) + +/* TCD_SADDR Bit Fields */ +#define EDMA_TCD_SADDR_SADDR_MASK (0xFFFFFFFFu) +#define EDMA_TCD_SADDR_SADDR_SHIFT (0u) +#define EDMA_TCD_SADDR_SADDR_WIDTH (32u) + +/* TCD_SOFF Bit Fields */ +#define EDMA_TCD_SOFF_SOFF_MASK (0xFFFFu) +#define EDMA_TCD_SOFF_SOFF_SHIFT (0u) +#define EDMA_TCD_SOFF_SOFF_WIDTH (16u) + +/* TCD_ATTR Bit Fields */ +#define EDMA_TCD_ATTR_SDSIZE_MASK (0x7u) +#define EDMA_TCD_ATTR_SDSIZE_SHIFT (0u) +#define EDMA_TCD_ATTR_SDSIZE_WIDTH (3u) +#define EDMA_TCD_ATTR_SDSIZE(x) (((uint16_t)(((uint16_t)(x)) << EDMA_TCD_ATTR_SDSIZE_SHIFT)) & EDMA_TCD_ATTR_SDSIZE_MASK) +#define EDMA_TCD_ATTR_DMOD_MASK (0xF8u) +#define EDMA_TCD_ATTR_DMOD_SHIFT (3u) +#define EDMA_TCD_ATTR_DMOD_WIDTH (5u) +#define EDMA_TCD_ATTR_DMOD(x) (((uint16_t)(((uint16_t)(x)) << EDMA_TCD_ATTR_DMOD_SHIFT)) & EDMA_TCD_ATTR_DMOD_MASK) +#define EDMA_TCD_ATTR_SMOD_MASK (0xF800u) +#define EDMA_TCD_ATTR_SMOD_SHIFT (11u) +#define EDMA_TCD_ATTR_SMOD_WIDTH (5u) +#define EDMA_TCD_ATTR_SMOD(x) (((uint16_t)(((uint16_t)(x)) << EDMA_TCD_ATTR_SMOD_SHIFT)) & EDMA_TCD_ATTR_SMOD_MASK) + +/* TCD_NBYTES_MLOFFNO Bit Fields */ +#define EDMA_TCD_NBYTES_MLOFFNO_NBYTES_MASK (0x3FFFFFFFu) +#define EDMA_TCD_NBYTES_MLOFFNO_NBYTES_SHIFT (0u) +#define EDMA_TCD_NBYTES_MLOFFNO_NBYTES_WIDTH (30u) +#define EDMA_TCD_NBYTES_MLOFFNO_DMLOE_MASK (0x40000000u) +#define EDMA_TCD_NBYTES_MLOFFNO_DMLOE_SHIFT (30u) +#define EDMA_TCD_NBYTES_MLOFFNO_DMLOE_WIDTH (1u) +#define EDMA_TCD_NBYTES_MLOFFNO_SMLOE_MASK (0x80000000u) +#define EDMA_TCD_NBYTES_MLOFFNO_SMLOE_SHIFT (31u) +#define EDMA_TCD_NBYTES_MLOFFNO_SMLOE_WIDTH (1u) + +/* TCD_NBYTES_MLOFFYES Bit Fields */ +#define EDMA_TCD_NBYTES_MLOFFYES_NBYTES_MASK (0x3FFu) +#define EDMA_TCD_NBYTES_MLOFFYES_NBYTES_SHIFT (0u) +#define EDMA_TCD_NBYTES_MLOFFYES_NBYTES_WIDTH (10u) +#define EDMA_TCD_NBYTES_MLOFFYES_MLOFF_MASK (0x3FFFFC00u) +#define EDMA_TCD_NBYTES_MLOFFYES_MLOFF_SHIFT (10u) +#define EDMA_TCD_NBYTES_MLOFFYES_MLOFF_WIDTH (20u) +#define EDMA_TCD_NBYTES_MLOFFYES_DMLOE_MASK (0x40000000u) +#define EDMA_TCD_NBYTES_MLOFFYES_DMLOE_SHIFT (30u) +#define EDMA_TCD_NBYTES_MLOFFYES_DMLOE_WIDTH (1u) +#define EDMA_TCD_NBYTES_MLOFFYES_SMLOE_MASK (0x80000000u) +#define EDMA_TCD_NBYTES_MLOFFYES_SMLOE_SHIFT (31u) +#define EDMA_TCD_NBYTES_MLOFFYES_SMLOE_WIDTH (1u) + +/* TCD_SLAST Bit Fields */ +#define EDMA_TCD_SLAST_SLAST_MASK (0xFFFFFFFFu) +#define EDMA_TCD_SLAST_SLAST_SHIFT (0u) +#define EDMA_TCD_SLAST_SLAST_WIDTH (32u) + +/* TCD_DADDR Bit Fields */ +#define EDMA_TCD_DADDR_DADDR_MASK (0xFFFFFFFFu) +#define EDMA_TCD_DADDR_DADDR_SHIFT (0u) +#define EDMA_TCD_DADDR_DADDR_WIDTH (32u) + +/* TCD_DOFF Bit Fields */ +#define EDMA_TCD_DOFF_DOFF_MASK (0xFFFFu) +#define EDMA_TCD_DOFF_DOFF_SHIFT (0u) +#define EDMA_TCD_DOFF_DOFF_WIDTH (16u) + +/* TCD_CITER_ELINKNO Bit Fields */ +#define EDMA_TCD_CITER_ELINKNO_CITER_MASK (0x7FFFu) +#define EDMA_TCD_CITER_ELINKNO_CITER_SHIFT (0u) +#define EDMA_TCD_CITER_ELINKNO_CITER_WIDTH (15u) +#define EDMA_TCD_CITER_ELINKNO_ELINK_MASK (0x8000u) +#define EDMA_TCD_CITER_ELINKNO_ELINK_SHIFT (15u) +#define EDMA_TCD_CITER_ELINKNO_ELINK_WIDTH (1u) + +/* TCD_CITER_ELINKYES Bit Fields */ +#define EDMA_TCD_CITER_ELINKYES_CITER_MASK (0x1FFu) +#define EDMA_TCD_CITER_ELINKYES_CITER_SHIFT (0u) +#define EDMA_TCD_CITER_ELINKYES_CITER_WIDTH (9u) +#define EDMA_TCD_CITER_ELINKYES_LINKCH_MASK (0x1E00u) +#define EDMA_TCD_CITER_ELINKYES_LINKCH_SHIFT (9u) +#define EDMA_TCD_CITER_ELINKYES_LINKCH_WIDTH (4u) +#define EDMA_TCD_CITER_ELINKYES_ELINK_MASK (0x8000u) +#define EDMA_TCD_CITER_ELINKYES_ELINK_SHIFT (15u) +#define EDMA_TCD_CITER_ELINKYES_ELINK_WIDTH (1u) + +/* TCD_DLASTSGA Bit Fields */ +#define EDMA_TCD_DLASTSGA_DLASTSGA_MASK (0xFFFFFFFFu) +#define EDMA_TCD_DLASTSGA_DLASTSGA_SHIFT (0u) +#define EDMA_TCD_DLASTSGA_DLASTSGA_WIDTH (32u) + +/* TCD_CSR Bit Fields */ +#define EDMA_TCD_CSR_START_MASK (0x1u) +#define EDMA_TCD_CSR_START_SHIFT (0u) +#define EDMA_TCD_CSR_START_WIDTH (1u) +#define EDMA_TCD_CSR_INTMAJOR_MASK (0x2u) +#define EDMA_TCD_CSR_INTMAJOR_SHIFT (1u) +#define EDMA_TCD_CSR_INTMAJOR_WIDTH (1u) +#define EDMA_TCD_CSR_INTHALF_MASK (0x4u) +#define EDMA_TCD_CSR_INTHALF_SHIFT (2u) +#define EDMA_TCD_CSR_INTHALF_WIDTH (1u) +#define EDMA_TCD_CSR_DREQ_MASK (0x8u) +#define EDMA_TCD_CSR_DREQ_SHIFT (3u) +#define EDMA_TCD_CSR_DREQ_WIDTH (1u) +#define EDMA_TCD_CSR_ESG_MASK (0x10u) +#define EDMA_TCD_CSR_ESG_SHIFT (4u) +#define EDMA_TCD_CSR_ESG_WIDTH (1u) +#define EDMA_TCD_CSR_MAJORELINK_MASK (0x20u) +#define EDMA_TCD_CSR_MAJORELINK_SHIFT (5u) +#define EDMA_TCD_CSR_MAJORELINK_WIDTH (1u) +#define EDMA_TCD_CSR_ACTIVE_MASK (0x40u) +#define EDMA_TCD_CSR_ACTIVE_SHIFT (6u) +#define EDMA_TCD_CSR_ACTIVE_WIDTH (1u) +#define EDMA_TCD_CSR_DONE_MASK (0x80u) +#define EDMA_TCD_CSR_DONE_SHIFT (7u) +#define EDMA_TCD_CSR_DONE_WIDTH (1u) +#define EDMA_TCD_CSR_MAJORLINKCH_MASK (0xF00u) +#define EDMA_TCD_CSR_MAJORLINKCH_SHIFT (8u) +#define EDMA_TCD_CSR_MAJORLINKCH_WIDTH (4u) +#define EDMA_TCD_CSR_HARD_CLR_DONE_MASK (0x1000u) +#define EDMA_TCD_CSR_HARD_CLR_DONE_SHIFT (12u) +#define EDMA_TCD_CSR_HARD_CLR_DONE_WIDTH (1u) + +/* TCD_BITER_ELINKNO Bit Fields */ +#define EDMA_TCD_BITER_ELINKNO_BITER_MASK (0x7FFFu) +#define EDMA_TCD_BITER_ELINKNO_BITER_SHIFT (0u) +#define EDMA_TCD_BITER_ELINKNO_BITER_WIDTH (15u) +#define EDMA_TCD_BITER_ELINKNO_ELINK_MASK (0x8000u) +#define EDMA_TCD_BITER_ELINKNO_ELINK_SHIFT (15u) +#define EDMA_TCD_BITER_ELINKNO_ELINK_WIDTH (1u) + +/* TCD_BITER_ELINKYES Bit Fields */ +#define EDMA_TCD_BITER_ELINKYES_BITER_MASK (0x1FFu) +#define EDMA_TCD_BITER_ELINKYES_BITER_SHIFT (0u) +#define EDMA_TCD_BITER_ELINKYES_BITER_WIDTH (9u) +#define EDMA_TCD_BITER_ELINKYES_LINKCH_MASK (0x1E00u) +#define EDMA_TCD_BITER_ELINKYES_LINKCH_SHIFT (9u) +#define EDMA_TCD_BITER_ELINKYES_LINKCH_WIDTH (4u) +#define EDMA_TCD_BITER_ELINKYES_ELINK_MASK (0x8000u) +#define EDMA_TCD_BITER_ELINKYES_ELINK_SHIFT (15u) +#define EDMA_TCD_BITER_ELINKYES_ELINK_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +/*! \brief EDMA - Size of Registers Arrays + */ +#define EDMA_DCHPRI_COUNT (4u) +#define EDMA_TCD_COUNT (4u) + +/*! \brief The definition of EDMA registers + */ +typedef struct _EDmaRegType_ +{ + volatile uint32_t CR; /*!< EDMA control register, offset: 0x0 */ + volatile uint32_t ES; /*!< EDMA status register, offset: 0x4 */ + uint32_t RESERVED0; /*!< Reserved register, offset: 0x8 */ + volatile uint32_t ERQ; /*!< EDMA enable request register, offset: 0xC */ + uint32_t RESERVED1; /*!< Reserved register, offset: 0x10 */ + volatile uint32_t EEI; /*!< EDMA enable error interrupt register, offset: 0x14 */ + volatile uint8_t CEEI; /*!< EDMA clear enable error interrupt register, offset: 0x18 */ + volatile uint8_t SEEI; /*!< EDMA clear enable error interrupt register, offset: 0x19 */ + volatile uint8_t CERQ; /*!< EDMA clear enable error interrupt register, offset: 0x1A */ + volatile uint8_t SERQ; /*!< EDMA clear enable error interrupt register, offset: 0x1B */ + volatile uint8_t CDNE; /*!< EDMA clear enable error interrupt register, offset: 0x1C */ + volatile uint8_t SSRT; /*!< EDMA clear enable error interrupt register, offset: 0x1D */ + volatile uint8_t CERR; /*!< EDMA clear enable error interrupt register, offset: 0x1E */ + volatile uint8_t CINT; /*!< EDMA clear enable error interrupt register, offset: 0x1F */ + uint32_t RESERVED2; /*!< Reserved register, offset: 0x20 */ + volatile uint32_t INT; /*!< EDMA interrupt request register, offset: 0x24 */ + uint32_t RESERVED3; /*!< Reserved register, offset: 0x28 */ + volatile uint32_t ERR; /*!< EDMA error register, offset: 0x2C */ + uint32_t RESERVED4; /*!< Reserved register, offset: 0x30 */ + volatile uint32_t HRS; /*!< EDMA hardware request status register, offset: 0x34 */ + uint32_t RESERVED5[50]; /*!< Reserved register, offset: 0x38 */ + volatile uint8_t DCHPRI_N[EDMA_DCHPRI_COUNT]; /*!< EDMA channel N arbitration priority register, offset: 0x100 */ + uint32_t RESERVED6[959]; /*!< Reserved register, offset: 0x110 */ + struct + { + volatile uint32_t SADDR; /*!< EDMA tcd source address register, offset: 0x1000 */ + volatile uint16_t SOFF; /*!< EDMA tcd signed source address offset register, offset: 0x1004 */ + volatile uint16_t ATTR; /*!< EDMA tcd transfer attributes register, offset: 0x1006 */ + volatile uint32_t NBYTES; /*!< EDMA tcd minor byte count register, offset: 0x1008 */ + volatile uint32_t SLAST; /*!< EDMA tcd last source address adjustment register, offset: 0x100C */ + volatile uint32_t DADDR; /*!< EDMA tcd destination address register, offset: 0x1010 */ + volatile uint16_t DOFF; /*!< EDMA tcd destination address signed offset register, offset: 0x1014 */ + volatile uint16_t CITER; /*!< EDMA tcd current minor loop link major loop link register, offset: 0x1016 */ + volatile uint32_t DLASTSGA; /*!< EDMA last destination address adjustment/scatter gather address register, offset: 0x1018 */ + volatile uint16_t CSR; /*!< EDMA tcd control and status register, offset 0x101C */ + volatile uint16_t BITER; /*!< EDMA tcd current begining minor loop link, major loop count register, offset: 0x101E */ + } TCD[EDMA_TCD_COUNT]; +} EDmaRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ +/*! \brief Get Debug mode + * + * \param[in] obj : pointer to eDMA register instance + * \return debug mode + * -0b: when in debug mode, the DMA continues to operate + * -1b: when in debug mode, the DMA stalls the start of a new channel. + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetDebugMode(const EDmaRegType *obj) +{ + return ((obj->CR & EDMA_CR_EDBG_MASK) >> EDMA_CR_EDBG_SHIFT); +} + +/*! \brief Set When in debug mode, the DMA stalls the start of a new channel. + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableDebugStall(EDmaRegType *obj) +{ + obj->CR |= EDMA_CR_EDBG_MASK; +} + +/*! \brief Set When in debug mode, the DMA continues to operate + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableDebugStall(EDmaRegType *obj) +{ + obj->CR &= ~EDMA_CR_EDBG_MASK; +} + +/*! \brief Get the channel arbitration mode + * + * \param[in] obj base pointer to eDMA register instance + * \return arbitration mode + * - 0b: Fixed priority arbitration is used for channel selection + * - 1b: Round-Robin arbitration is used for channel selection + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetChannelArbitrationMode(const EDmaRegType *obj) +{ + return ((obj->CR & EDMA_CR_ERCA_MASK) >> EDMA_CR_ERCA_SHIFT); +} + +/*! \brief Sets the channel arbitration algorithm. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] mode : Round-Robin(1) way or fixed(0) priority way. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetChannelArbitrationMode(EDmaRegType *obj, uint8_t mode) +{ + uint32_t tempVal; + tempVal = obj->CR; + tempVal &= ~EDMA_CR_ERCA_MASK; + tempVal |= (mode << EDMA_CR_ERCA_SHIFT) & EDMA_CR_ERCA_MASK; + obj->CR = tempVal; +} + +/*! \brief Get Halt on error + * + * \param[in] obj : pointer to eDMA register instance + * \return halt on error mode + * - 0: Normal operation + * - 1: Any error causes the HALT bit to set.Subsequently,all service requests are ignored until the HALT bit is cleared. + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetHaltOnError(const EDmaRegType *obj) +{ + return ((obj->CR & EDMA_CR_HOE_MASK) >> EDMA_CR_HOE_SHIFT); +} + +/*! \brief Halts or does not halt the eDMA module when an error occurs. + * + * An error causes the HALT bit to be set. Subsequently, all service requests are ignored until the + * HALT bit is cleared. + * + * \param[in] base pointer to eDMA register instance + * \param[in] enable Halts (true) or not halt (false) eDMA module when an error occurs. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetHaltOnErrorCmd(EDmaRegType *obj, uint8_t enable) +{ + if(enable) + { + obj->CR |= EDMA_CR_HOE_MASK; + } + else + { + obj->CR &= ~EDMA_CR_HOE_MASK; + } +} + +/*! \brief Get Halt eDMA operations + * + * \param[in] obj : pointer to eDMA register instance + * \return Halt eDMA operations + * - 0b: normal operation + * - 1b: stall the start of any new channels.Executing channels are allowed to complete. + * Channel execution resumes when this bit is cleared + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetHalt(EDmaRegType *obj) +{ + return ((obj->CR & EDMA_CR_HALT_MASK) >> EDMA_CR_HALT_SHIFT); +} + +/*! \brief Halts or does not halt the eDMA module . + * + * Execution channels are not allowed to complete, dma stop transfer at the end fo read-write sequence + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] enable : Halts (true) or not halt (false) eDMA module. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetHaltCmd(EDmaRegType *obj, uint8_t enable) +{ + if(enable) + { + obj->CR |= EDMA_CR_HALT_MASK; + } + else + { + obj->CR &= ~EDMA_CR_HALT_MASK; + } +} + +/*! \brief Get continuous link mode + * + * \param[in] obj : pointer to eDMA register instance + * \return continuous link mode + * - 0b: a minor loop channel link made to itself goes through channel arbitration before being activated again + * - 1b: a minor loop channel link made to itself does not go through channel arbitration before being activated again. + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetClm(const EDmaRegType *obj) +{ + return ((obj->CR & EDMA_CR_CLM_MASK) >> EDMA_CR_CLM_SHIFT); +} + +/*! \brief Enable continuous link mode + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableClm(EDmaRegType *obj) +{ + obj->CR |= EDMA_CR_CLM_MASK; +} + +/*! \brief Disable continuous link mode + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableClm(EDmaRegType *obj) +{ + obj->CR &= ~EDMA_CR_CLM_MASK; +} + +/*! \brief Get Minor Loop Mapping + * + * \param[in] obj pointer to eDMA register instance + * \return minor loop mapping mode + * - 0b: disable. + * - 1b: enabled + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetMinorLoopMapping(const EDmaRegType *obj) +{ + return ((obj->CR & EDMA_CR_EMLM_MASK) >> EDMA_CR_EMLM_SHIFT); +} + +/*! \brief Enables/Disables the minor loop mapping. + * + * This function enables/disables the minor loop mapping feature. + * If enabled, the NBYTES is redefined to include the individual enable fields and the NBYTES field. The + * individual enable fields allow the minor loop offset to be applied to the source address, the + * destination address, or both. The NBYTES field is reduced when either offset is enabled. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] enable : Enables (true) or Disable (false) minor loop mapping. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetMinorLoopMappingCmd(EDmaRegType *obj, uint8_t enable) +{ + if(enable) + { + obj->CR |= EDMA_CR_EMLM_MASK; + } + else + { + obj->CR &= ~EDMA_CR_EMLM_MASK; + } +} + +/*! \brief Get Error cancel transfer mode + * + * \param[in] obj : pointer to eDMA register instance + * \return error cancel transfer mode + * - 0b: normal operation + * - 1b: cancel the remaining data transfer same as CX bit. Moreover, ECX treats the cancel as an error condition, + * thus updating the Error Status register (DMAx_ES) and generating an optional error interrupt. + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetEcx(const EDmaRegType *obj) +{ + return ((obj->CR & EDMA_CR_ECX_MASK) >> EDMA_CR_ECX_SHIFT); +} + +/*! \brief Cancels the remaining data transfer and treats it as an error condition. + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableEcx(EDmaRegType *obj) +{ + obj->CR |= EDMA_CR_ECX_MASK; +} + +/*! \brief Disable error cancel transfer + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableEcx(EDmaRegType *obj) +{ + obj->CR &= ~EDMA_CR_ECX_MASK; +} + +/*! \brief Get Cancel transfer mode + * + * \param[in] obj : pointer to eDMA register instance + * \return cancel transfer mode + * - 0b: normal operation + * - 1b: cancel the remaining data transfer. Stop the executing channel and force the minor loop to finish. + * The cancel takes effect after the last write of the current read/write sequence. The CX bit clears itself + * after the cancel has been honored. This cancel retires the channel normally as if the minor loop was completed. no error + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetCx(const EDmaRegType *obj) +{ + return ((obj->CR & EDMA_CR_CX_MASK) >> EDMA_CR_CX_SHIFT); +} + +/*! \brief Cancels the remaining data transfer. + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableCx(EDmaRegType *obj) +{ + obj->CR |= EDMA_CR_CX_MASK; +} + +/*! \brief Disable cancel transfer + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableCx(EDmaRegType *obj) +{ + obj->CR &= ~EDMA_CR_CX_MASK; +} + +/*! \brief EDMA active status + * + * \param[in] obj : pointer to eDMA register instance + * \return dma active status + * - 0b: eDMA is idle + * - 1b: eDMA is excuting a channel + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetActiveStatus(const EDmaRegType *obj) +{ + return ((obj->CR & EDMA_CR_ACTIVE_MASK) >> EDMA_CR_ACTIVE_SHIFT); +} + +/*! \brief Get destination bus error status + * + * \param[in] obj : pointer to eDMA register instance + * \return destination bus error status + * - 0b: No destination bus error + * - 1b: The last recorded error was a bus error on a destination write + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetDbeStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_DBE_MASK) >> EDMA_ES_DBE_SHIFT); +} + +/*! \brief Get source bus error status + * + * \param[in] obj : pointer to eDMA register instance + * \return source bus error status + * - 0b: No source bus error + * - 1b: The last recorded error was a bus error on a source read + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetSbeStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_SBE_MASK) >> EDMA_ES_SBE_SHIFT); +} + +/*! \brief Get Scatter/Gather configuration error + * + * \param[in] obj : pointer to eDMA register instance + * \return Scatter/Gather configuration error status + * - 0b: No scatter/gather configuration error + * - 1b: The last recorded error was a configuration error detected in the TCDn_DLASTSGA field. + * TCDn_DLASTSGA is not on a 32 bits boundary. + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetSgeStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_SGE_MASK) >> EDMA_ES_SGE_SHIFT); +} + +/*! \brief Get NBYTES/CITER configuration Error + * + * \param[in] obj : pointer to eDMA register instance + * \return NBYTES/CITER configuration error status + * - 0b: No NBYTES/CITER configuration error + * - 1b: The last recorded error was a configuration error detected in the TCDn_NBYTES or TCDn_CITER fields. + * TCDn_NBYTES is not a multiple of TCDn_ATTR[SSIZE] and TCDn_ATTR[DSIZE], orTCDn_CITER[CITER] is equal to zero, + * orTCDn_CITER[ELINK] is not equal to TCDn_BITER[ELINK] + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetNceStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_NCE_MASK) >> EDMA_ES_NCE_SHIFT); +} + +/*! \brief Get destination offset error + * + * \param[in] obj : pointer to eDMA register instance + * \return destination offset error status + * - 0b: No destination offset configuration error + * - 1b: The last recorded error was a configuration error detected in the TCDn_DOFF field. + * TCDn_DOFF is inconsistent with TCDn_ATTR[SIZE]. + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetDoeStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_DOE_MASK) >> EDMA_ES_DOE_SHIFT); +} + +/*! \brief Get destination address error + * + * \param[in] obj : pointer to eDMA register instance + * \return destination address error status + * - 0b: No destination address configuration error + * - 1b: The last recorded error was a configuration error detected in the TCDn_DADDR field. + * TCDn_DADDR is inconsistent with TCDn_ATTR[SIZE] + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetDaeStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_DAE_MASK) >> EDMA_ES_DAE_SHIFT); +} + +/*! \brief Get source offset error + * + * \param[in] obj : pointer to eDMA register instance + * \return source offset error status + * - 0b: No source offset configuration error + * - 1b: The last recorded error was a configuration error detected in the TCDn_SOFF field. + * TCDn_SOFF is inconsistent with TCDn_ATTR[SIZE]. + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetSoeStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_SOE_MASK) >> EDMA_ES_SOE_SHIFT); +} + +/*! \brief Get source address Error + * + * \param[in] obj : pointer to eDMA register instance + * \return source address error status + * - 0b: No source address configuration error. + * - 1b: The last recorded error was a configuration error detected in the TCDn_SADDR field. + * TCDn_SADDR is inconsistent with TCDn_ATTR[SIZE]. + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetSaeStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_SAE_MASK) >> EDMA_ES_SAE_SHIFT); +} + +/*! \brief Get error channel number or canceled channel number + * + * \param[in] obj : pointer to eDMA register instance + * \return The channel number of the last recorded error, excluding CPE errors, or last recorded error canceled transfer + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetErrChn(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_ERRCHN_MASK) >> EDMA_ES_ERRCHN_SHIFT); +} + +/*! \brief Get channel priority error + * + * \param[in] obj : pointer to eDMA register instance + * \return channel priority error status + * - 0b: No channel priority error + * - 1b: The last recorded error was a configuration error in the channel priorities . Channel priorities are not unique. + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetCpeStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_CPE_MASK) >> EDMA_ES_CPE_SHIFT); +} + +/*! \brief Get transfer Canceled status + * + * \param[in] obj : pointer to eDMA register instance + * \return transfer canceled status + * - 0b: No canceled transfers + * - 1b: The last recorded entry was a canceled transfer by the error cancel transfer input + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetEcxStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_ECX_MASK) >> EDMA_ES_ECX_SHIFT); +} + +/*! \brief Get logical OR of all error status bits + * + * \param[in] obj : pointer to eDMA register instance + * \return logical OR of all error status bits + * - 0b: No ERR bits are set. + * - 1b: At least one ERR bit is set indicating a valid error exists that has not been cleared + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetVldStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_VLD_MASK) >> EDMA_ES_VLD_SHIFT); +} + +/*! \brief Clear enable error interrupt register + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_ClearEnableErrorInterrupt(EDmaRegType *obj, uint8_t value) +{ + uint32_t ceeiTmp = 0; + ceeiTmp |= (((uint32_t)(((uint32_t)(value)) << EDMA_CEEI_CEEI_SHIFT)) & EDMA_CEEI_CEEI_MASK); + obj->CEEI = ceeiTmp; +} + +/*! \brief Clear all bits in EEI + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableCaee(EDmaRegType *obj) +{ + uint32_t ceeiTmp = 0; + ceeiTmp |= EDMA_CEEI_CAEE_MASK; + obj->CEEI = ceeiTmp; +} + +/*! \brief : Clear only the EEI bit specified in the CEEI field + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableCaee(EDmaRegType *obj) +{ + uint32_t ceeiTmp = 0; + ceeiTmp &= ~EDMA_CEEI_CAEE_MASK; + obj->CEEI = ceeiTmp; +} + +/*! \brief Set enable error interrupt register + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetEnableErrorInterrupt(EDmaRegType *obj, uint8_t channel) +{ + uint8_t seeiTmp = 0; + seeiTmp |= (((uint8_t)(((uint8_t)(channel)) << EDMA_SEEI_SEEI_SHIFT)) & EDMA_SEEI_SEEI_MASK); + obj->SEEI = seeiTmp; +} + +/*! \brief Sets all bits in EEI + * + * \param[in] obj :pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableSaee(EDmaRegType *obj) +{ + uint8_t seeiTmp = 0; + seeiTmp |= EDMA_SEEI_SAEE_MASK; + obj->SEEI = seeiTmp; +} + +/*! \brief Set only the EEI bit specified in the SEEI field. + * + * \param[in] obj :pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableSaee(EDmaRegType *obj) +{ + uint8_t seeiTmp = 0; + seeiTmp &= ~EDMA_SEEI_SAEE_MASK; + obj->SEEI = seeiTmp; +} + +/*! \brief Clear enable request register + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_ClearEnableRequest(EDmaRegType *obj, uint8_t channel) +{ + uint8_t cerqTmp = 0; + cerqTmp |= (((uint8_t)(((uint8_t)(channel)) << EDMA_CERQ_CERQ_SHIFT)) & EDMA_CERQ_CERQ_MASK); + obj->CERQ = cerqTmp; +} + +/*! \brief Clear only the ERQ bit specified in the CERQ field + * + * \param[in] obj :pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableCaer(EDmaRegType *obj) +{ + uint8_t cerqTmp = 0; + cerqTmp |= EDMA_CERQ_CAER_MASK; + obj->CERQ = cerqTmp; +} + +/*! \brief Clear all bits in ERQ + * + * \param[in] obj :pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableCaer(EDmaRegType *obj) +{ + uint8_t cerqTmp = 0; + cerqTmp &= ~EDMA_CERQ_CAER_MASK; + obj->CERQ = cerqTmp; +} + +/*! \brief Set enable request register + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetEnableRequest(EDmaRegType *obj, uint8_t channel) +{ + uint32_t serqTmp = 0; + serqTmp |= (((uint8_t)(((uint8_t)(channel)) << EDMA_SERQ_SERQ_SHIFT)) & EDMA_SERQ_SERQ_MASK); + obj->SERQ = serqTmp; +} + +/*! \brief Set all bits in ERQ + * + * \param[in] obj :pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableSaer(EDmaRegType *obj) +{ + uint8_t serqTmp = 0; + serqTmp |= EDMA_SERQ_SAER_MASK; + obj->SERQ = serqTmp; +} + +/*! \brief Set only the ERQ bit specified in the SERQ field + * + * \param[in] obj :pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableSaer(EDmaRegType *obj) +{ + uint8_t serqTmp = 0; + serqTmp &= ~EDMA_SERQ_SAER_MASK; + obj->SERQ = serqTmp; +} + +/*! \brief Clears the done status for a channel or all channels. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_ClearDoneStatusFlag(EDmaRegType *obj, uint8_t channel) +{ + uint8_t cdenTmp = 0; + cdenTmp |= (((uint8_t)(((uint8_t)(channel)) << EDMA_CDNE_CDNE_SHIFT)) & EDMA_CDNE_CDNE_MASK); + obj->CDNE = cdenTmp; +} + +/*! \brief Clears all bits in TCDn_CSR[DONE] + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableCadn(EDmaRegType *obj) +{ + uint8_t cdenTmp = 0; + cdenTmp |= EDMA_CDNE_CDNE_MASK; + obj->CDNE = cdenTmp; +} + +/*! \brief Clears only the TCDn_CSR[DONE] bit specified in the CDNE field + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableCadn(EDmaRegType *obj) +{ + uint8_t cdenTmp = 0; + cdenTmp &= ~EDMA_CDNE_CDNE_MASK; + obj->CDNE = cdenTmp; +} + +/*! \brief Set set START bit register + * + * \param[in] obj pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetChannelStartFlag(EDmaRegType *obj, uint8_t channel) +{ + uint8_t ssrtTmp = 0; + ssrtTmp |= (((uint8_t)(((uint8_t)(channel)) << EDMA_SSRT_SSRT_SHIFT)) & EDMA_SSRT_SSRT_MASK); + obj->SSRT = ssrtTmp; +} + +/*! \brief Set all bits in TCDn_CSR[START] + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableSast(EDmaRegType *obj) +{ + uint8_t ssrtTmp = 0; + ssrtTmp |= EDMA_SSRT_SAST_MASK; + obj->SSRT = ssrtTmp; +} +/*! \brief Set only the TCDn_CSR[START] bit specified in the SSRT field + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableSast(EDmaRegType *obj) +{ + uint8_t ssrtTmp = 0; + ssrtTmp &= ~EDMA_SSRT_SAST_MASK; + obj->SSRT = ssrtTmp; +} + +/*! \brief Clears the error status for the eDMA channel or channels. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_ClearErrorIntStatusFlag(EDmaRegType *obj, uint8_t channel) +{ + uint8_t cerrTmp = 0; + cerrTmp |= (((uint8_t)(((uint8_t)(channel)) << EDMA_CERR_CERR_SHIFT)) & EDMA_CERR_CERR_MASK); + obj->CERR = cerrTmp; + /* Read back to avoid problem */ + (void)obj->CERR; +} + +/*! \brief Clear all bits in ERR + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableCaei(EDmaRegType *obj) +{ + uint8_t cerrTmp = 0; + cerrTmp |= EDMA_CERR_CAEI_MASK; + obj->CERR = cerrTmp; +} + +/*! \brief Clear only the ERR bit specified in the CERR field + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableCaei(EDmaRegType *obj) +{ + uint8_t cerrTmp = 0; + cerrTmp &= ~EDMA_CERR_CAEI_MASK; + obj->CERR = cerrTmp; +} + +/*! \brief Gets interrupt status + * + * \param[in] obj : pointer to eDMA register instance + * \return 32 bit variable indicating interrupt channels. + */ +__attribute__((always_inline)) static inline uint32_t EDmaReg_GetChnInterruptFlag(const EDmaRegType *obj) +{ + return obj->INT; +} + +/*! \brief Clear interrupt register + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_ClearIntStatusFlag(EDmaRegType *obj, uint8_t channel) +{ + uint8_t cintTmp = 0; + cintTmp |= (((uint8_t)(((uint8_t)(channel)) << EDMA_CINT_CINT_SHIFT)) & EDMA_CINT_CINT_MASK); + obj->CINT = cintTmp; + /* Read back to avoid problem */ + (void)obj->CINT; +} + +/*! \brief Clear all bits in interrupt + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableCair(EDmaRegType *obj) +{ + uint8_t cintTmp = 0; + cintTmp |= EDMA_CINT_CAIR_MASK; + obj->CINT = cintTmp; +} + +/*! \brief Clear only the interrupt bit specified in the CINT field + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableCair(EDmaRegType *obj) +{ + uint8_t cintTmp = 0; + cintTmp &= ~EDMA_CINT_CAIR_MASK; + obj->CINT = cintTmp; +} + +/*! \brief Gets error status + * + * \param[in] obj : pointer to eDMA register instance + * \return 32 bit variable indicating error channels. If error happens on eDMA channel n, the bit n + * of this variable is '1'. If not, the bit n of this variable is '0'. + */ +__attribute__((always_inline)) static inline uint32_t EDmaReg_GetErrorStatusFlag(const EDmaRegType *obj) +{ + return obj->ERR; +} + +/*! \brief Gets channel error status + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \return bool variable indicating error channels. + */ +__attribute__((always_inline)) static inline bool EDmaReg_GetChannelErrorStatusFlag(EDmaRegType *obj, const uint8_t channel) +{ + uint32_t errTmp = 0; + errTmp = obj->ERR; + return 1UL == ((errTmp >> channel) & EDMA_ERR_ERRN_MASK); +} + +/*! \brief Sets the eDMA channel priority. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : Priority of the DMA channel. Different channels should have different priority + * setting inside a group. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetChannelPriority(EDmaRegType *obj, const uint8_t channel, uint8_t value) +{ + uint32_t dchpriTmp = obj->DCHPRI_N[channel]; + + dchpriTmp &= ~(EDMA_DCHPRI_CHPRI_MASK); + dchpriTmp |= (((uint32_t)(((uint32_t)(value)) << EDMA_DCHPRI_CHPRI_SHIFT)) & EDMA_DCHPRI_CHPRI_MASK); + obj->DCHPRI_N[channel] = dchpriTmp; +} + +/*! \brief Channel n can suspend a lower priority channel. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_EnablePreemptAbility(EDmaRegType *obj, const uint8_t channel) +{ + obj->DCHPRI_N[channel] &= ~EDMA_DCHPRI_DPA_MASK; +} + +/*! \brief Channel n cannot suspend any channel, regardless of channel + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_DisablePreemptAbility(EDmaRegType *obj, const uint8_t channel) +{ + obj->DCHPRI_N[channel] |= EDMA_DCHPRI_DPA_MASK; +} + +/*! \brief Channel n can be temporarilly suspended by the service request of a higher priority channel. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableChannelPreemption(EDmaRegType *obj, const uint8_t channel) +{ + obj->DCHPRI_N[channel] |= EDMA_DCHPRI_ECP_MASK; +} + +/*! \brief Channel n cannot be suspended by a higher priority channel's service request. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableChannelPreemption(EDmaRegType *obj, const uint8_t channel) +{ + obj->DCHPRI_N[channel] &= ~EDMA_DCHPRI_ECP_MASK; +} + +/*! \brief Configures the source address for the hardware TCD. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : The pointer to the source memory address. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdSrcAddr(EDmaRegType *obj, const uint8_t channel, uint32_t value) +{ + obj->TCD[channel].SADDR = value; +} + +/*! \brief Configures the source address signed offset for the hardware TCD. + * + * Sign-extended offset applied to the current source address to form the next-state value as each + * source read is complete. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : signed-offset for source address. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdSrcOffset(EDmaRegType *obj, uint8_t channel, int16_t value) +{ + obj->TCD[channel].SOFF = (int16_t)value; +} + +/*! \brief Sets the source/destination transfer size. + * + * Configures the source/destination data read transfer size (1/2/4/16/32 bytes). + * + * \param[in] obj : base pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] size : Source transfer size. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdSrcDesTransferSize(EDmaRegType *obj, uint8_t channel, uint8_t value) +{ + uint16_t attrTemp; + attrTemp = obj->TCD[channel].ATTR; + attrTemp &= (uint16_t)(~(EDMA_TCD_ATTR_SDSIZE_MASK)); + attrTemp |= (((uint16_t)(((uint16_t)(value)) << EDMA_TCD_ATTR_SDSIZE_SHIFT)) & EDMA_TCD_ATTR_SDSIZE_MASK); + obj->TCD[channel].ATTR = attrTemp; +} + +/*! \brief Set the destination address modulo. + * + * 00000b: destination address modulo feature is disabled + * 00001~11111b: This value defnies a specific address range specified to be the value after SADDR + SOFF + * calculation is performed on the original register value. Setting this field provides the ability to implement + * a circular data queue easily. For data queues requiring power-of-2 size bytes, the queue should start + * at a 0-modulo-size address and the SMOD field should be set to the appropriate value for the queue, freezing + * the desired number of upper address bits. The value programmed into this field specifieds the number of lower + * bits alllowed to change. For a cicular queue application, the SOFF is typically set to the transfer size to + * implement post-increment addressing with the SMOD funciton constraining the addresses to a 0-modulo-size range. + * + * \param[in] obj : base pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : address modulo. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdDmod(EDmaRegType *obj, uint8_t channel, uint8_t value) +{ + uint16_t attrTemp; + attrTemp = obj->TCD[channel].ATTR; + attrTemp &= (uint16_t)(~(EDMA_TCD_ATTR_DMOD_MASK)); + attrTemp |= (((uint16_t)(((uint16_t)(value)) << EDMA_TCD_ATTR_DMOD_SHIFT)) & EDMA_TCD_ATTR_DMOD_MASK); + obj->TCD[channel].ATTR = attrTemp; +} + +/*! \brief Set the source address modulo. + * + * 00000b: Source address modulo feature is disabled + * 00001~11111b: This value defnies a specific address range specified to be the value after SADDR + SOFF + * calculation is performed on the original register value. Setting thsi field provides the ability to implement + * a circular data queue easily. For data queues requiring power-of-2 size bytes, the queue should start + * at a 0-modulo-size address and the SMOD field should be set to the appropriate value for the queue, freezing + * the desired number of upper address bits. The value programmed into this field specifieds the number of lower + * bits alllowed to change. For a cicular queue application, the SOFF is typically set to the transfer size to + * implement post-increment addressing with the SMOD funciton constraining the addresses to a 0-modulo-size range. + * + * \param[in] obj : base pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : Source transfer size. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdSmod(EDmaRegType *obj, uint8_t channel, uint8_t value) +{ + uint16_t attrTemp; + attrTemp = obj->TCD[channel].ATTR; + attrTemp &= (uint16_t)(~(EDMA_TCD_ATTR_SMOD_MASK)); + attrTemp |= (((uint16_t)(((uint16_t)(value)) << EDMA_TCD_ATTR_SMOD_SHIFT)) & EDMA_TCD_ATTR_SMOD_MASK); + obj->TCD[channel].ATTR = attrTemp; +} + +/*! \brief Configures the nbytes for the eDMA channel. + * + * + * Note here that user need firstly configure the minor loop mapping feature and then call this + * function. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : Number of bytes to be transferred in each service request of the channel + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdNbytes(EDmaRegType *obj, uint8_t channel, uint32_t value) +{ + if(((obj->CR & EDMA_CR_EMLM_MASK) >> EDMA_CR_EMLM_SHIFT) != 0UL) + { + bool mlOffNo = false; + if(((obj->TCD[channel].NBYTES & EDMA_TCD_NBYTES_MLOFFNO_SMLOE_MASK) >> EDMA_TCD_NBYTES_MLOFFNO_SMLOE_SHIFT) == 0UL) + { + if(((obj->TCD[channel].NBYTES & EDMA_TCD_NBYTES_MLOFFNO_DMLOE_MASK) >> EDMA_TCD_NBYTES_MLOFFNO_DMLOE_SHIFT) == 0UL) + { + obj->TCD[channel].NBYTES = (value & EDMA_TCD_NBYTES_MLOFFNO_NBYTES_MASK); + mlOffNo = true; + } + } + if(!mlOffNo) + { + uint32_t regValTemp; + regValTemp = obj->TCD[channel].NBYTES; + regValTemp &= ~(EDMA_TCD_NBYTES_MLOFFYES_NBYTES_MASK); + regValTemp + |= (((uint16_t)(((uint16_t)(value)) << EDMA_TCD_NBYTES_MLOFFYES_NBYTES_SHIFT)) & EDMA_TCD_NBYTES_MLOFFYES_NBYTES_MASK); + obj->TCD[channel].NBYTES = regValTemp; + } + } + else + { + obj->TCD[channel].NBYTES = value; + } +} + +/*! \brief Enables/disables the source minor loop offset feature for the TCD. + * + * Configures whether the minor loop offset is applied to the source address + * upon minor loop completion. + * NOTE: EMLM bit needs to be enabled prior to calling this function, otherwise + * it has no effect. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] enable : Enables (true) or disables (false) source minor loop offset. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdSrcMinorLoopOffsetCmd(EDmaRegType *obj, uint8_t channel, bool enable) +{ + if(((obj->CR >> EDMA_CR_EMLM_SHIFT) & 1U) != 0U) + { + if(enable) + { + obj->TCD[channel].NBYTES |= EDMA_TCD_NBYTES_MLOFFYES_SMLOE_MASK; + } + else + { + obj->TCD[channel].NBYTES &= ~EDMA_TCD_NBYTES_MLOFFYES_SMLOE_MASK; + } + } +} + +/*! \brief Enables/disables the destination minor loop offset feature for the TCD. + * + * Configures whether the minor loop offset is applied to the destination address + * upon minor loop completion. + * NOTE: EMLM bit needs to be enabled prior to calling this function, otherwise + * it has no effect. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] enable : Enables (true) or disables (false) destination minor loop offset. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdDestMinorLoopOffsetCmd(EDmaRegType *obj, uint8_t channel, bool enable) +{ + if(((obj->CR >> EDMA_CR_EMLM_SHIFT) & 1U) != 0U) + { + if(enable) + { + obj->TCD[channel].NBYTES |= EDMA_TCD_NBYTES_MLOFFYES_DMLOE_MASK; + } + else + { + obj->TCD[channel].NBYTES &= ~EDMA_TCD_NBYTES_MLOFFYES_DMLOE_MASK; + } + } +} + +/*! \brief Configures the minor loop offset for the TCD. + * + * Configures the offset value. If neither source nor destination offset is enabled, + * offset is not configured. + * NOTE: EMLM bit needs to be enabled prior to calling this function, otherwise + * it has no effect. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] offset : Minor loop offset + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdMinorLoopOffset(EDmaRegType *obj, uint8_t channel, int32_t offset) +{ + if(((obj->CR & EDMA_CR_EMLM_MASK) >> EDMA_CR_EMLM_SHIFT) != 0UL) + { + bool mlOffNo = false; + if(((obj->TCD[channel].NBYTES & EDMA_TCD_NBYTES_MLOFFNO_SMLOE_MASK) >> EDMA_TCD_NBYTES_MLOFFNO_SMLOE_SHIFT) != 0UL) + { + mlOffNo = true; + } + if(((obj->TCD[channel].NBYTES & EDMA_TCD_NBYTES_MLOFFNO_DMLOE_MASK) >> EDMA_TCD_NBYTES_MLOFFNO_DMLOE_SHIFT) != 0UL) + { + mlOffNo = true; + } + if(mlOffNo) + { + uint32_t regValTemp; + regValTemp = obj->TCD[channel].NBYTES; + regValTemp &= ~(EDMA_TCD_NBYTES_MLOFFYES_MLOFF_MASK); + regValTemp + |= (((uint32_t)(((uint32_t)(offset)) << EDMA_TCD_NBYTES_MLOFFYES_MLOFF_SHIFT)) & EDMA_TCD_NBYTES_MLOFFYES_MLOFF_MASK); + obj->TCD[channel].NBYTES = regValTemp; + } + } +} + +/*! \brief Configures the last source address adjustment for the TCD. + * + * Adjustment value added to the source address at the completion of the major iteration count. This + * value can be applied to restore the source address to the initial value, or adjust the address to + * reference the next data structure. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : adjustment value + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdSrcLastAdjust(EDmaRegType *obj, uint8_t channel, int32_t value) +{ + obj->TCD[channel].SLAST = (uint32_t)value; +} + +/*! \brief Configures the destination address for the TCD. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : The pointer to the destination address. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdDestAddr(EDmaRegType *obj, uint8_t channel, uint32_t value) +{ + obj->TCD[channel].DADDR = value; +} + +/*! \brief Configures the destination address signed offset for the TCD. + * + * Sign-extended offset applied to the current source address to form the next-state value as each + * destination write is complete. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : signed-offset + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdDestOffset(EDmaRegType *obj, uint8_t channel, int16_t value) +{ + obj->TCD[channel].DOFF = (uint16_t)value; +} + +/*! \brief Enable/Disables channel-to-channel linking on minor-loop complete. + * + * As the channel completes the minor loop,this flag enables linking to another channel, defined by the + * LINKC field. THe link target channel initiates a channel service request via an internal mechanism + * that sets the TCDn_CSR[START]bit of the specified channel. + * If channel linking is disabled, the CITER value is extended to 15 bits in place of a link channel number. + * If the major loop is exhausted, this link mechanism is suppressed in favor of the MAJORELINK channel linking. + * + NOTE: this bit must be equal to the BITER[ELINK] bit;oterwise, a configuration error is reported. + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] enable : Enables (true) or disables (false) signed-offset + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdCiterMinorLinkCmd(EDmaRegType *obj, uint8_t channel, uint8_t enable) +{ + if(enable) + { + obj->TCD[channel].CITER |= EDMA_TCD_CITER_ELINKYES_ELINK_MASK; + } + else + { + obj->TCD[channel].CITER &= ~EDMA_TCD_CITER_ELINKYES_ELINK_MASK; + } +} + +/*! \brief Configures the minor loop link channel number. + * + * If channel-to-channel linking is enabled(ELINK = 1),then after the minor loop is exhausted. + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : channel number for minor link + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdCiterMinorLinkChannel(EDmaRegType *obj, uint8_t channel, uint8_t value) +{ + uint16_t citerElinkTemp; + citerElinkTemp = obj->TCD[channel].CITER; + citerElinkTemp &= (uint16_t) ~(EDMA_TCD_CITER_ELINKYES_LINKCH_MASK); + citerElinkTemp |= (((uint16_t)(((uint16_t)(value)) << EDMA_TCD_CITER_ELINKYES_LINKCH_SHIFT)) & EDMA_TCD_CITER_ELINKYES_LINKCH_MASK); + obj->TCD[channel].CITER = citerElinkTemp; +} + +/*! \brief Configures the major loop count for the channel. + * + * It is decremented each time the minor loop is completed and updated in the transfer control descriptor + * memory. After the major iteration count is exhausted, the channel performs a number of operations, for + * example,final source and destination address calculations, optionally generating an interrupt to signal + * channel completion before reloading the CITER field from the Beginning iteration Count(BITER)field. + * + * NOTE: When the CITER field is initially loaded by software, it must be set to the same value as that + * contained in the BITER field. if the channel is configured to execute a single service request. the + * initial values of BITER and CITER should be 0x0001. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : channel number for minor link + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdMajorCount(EDmaRegType *obj, uint8_t channel, uint16_t count) +{ + uint16_t regValTemp = 0; + if((obj->TCD[channel].BITER & EDMA_TCD_BITER_ELINKNO_ELINK_MASK) == EDMA_TCD_BITER_ELINKNO_ELINK_MASK) + { + regValTemp = obj->TCD[channel].BITER; + regValTemp &= (uint16_t) ~(EDMA_TCD_BITER_ELINKYES_BITER_MASK); + regValTemp |= (((uint16_t)(((uint16_t)(count)) << EDMA_TCD_BITER_ELINKYES_BITER_SHIFT)) & EDMA_TCD_BITER_ELINKYES_BITER_MASK); + obj->TCD[channel].BITER = regValTemp; + + regValTemp = obj->TCD[channel].CITER; + regValTemp &= (uint16_t) ~(EDMA_TCD_CITER_ELINKYES_CITER_MASK); + regValTemp |= (((uint16_t)(((uint16_t)(count)) << EDMA_TCD_CITER_ELINKYES_CITER_SHIFT)) & EDMA_TCD_CITER_ELINKYES_CITER_MASK); + obj->TCD[channel].CITER = regValTemp; + } + else + { + regValTemp = obj->TCD[channel].BITER; + regValTemp &= (uint16_t) ~(EDMA_TCD_BITER_ELINKNO_BITER_MASK); + regValTemp |= (((uint16_t)(((uint16_t)(count)) << EDMA_TCD_BITER_ELINKNO_BITER_SHIFT)) & EDMA_TCD_BITER_ELINKNO_BITER_MASK); + obj->TCD[channel].BITER = regValTemp; + + regValTemp = obj->TCD[channel].CITER; + regValTemp &= (uint16_t) ~(EDMA_TCD_CITER_ELINKNO_CITER_MASK); + regValTemp |= (((uint16_t)(((uint16_t)(count)) << EDMA_TCD_CITER_ELINKNO_CITER_SHIFT)) & EDMA_TCD_CITER_ELINKNO_CITER_MASK); + obj->TCD[channel].CITER = regValTemp; + } +} + +/*! \brief Returns the current major iteration count. + * + * Gets the current major iteration count according to minor loop channel link settings. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \return current : iteration count + */ +__attribute__((always_inline)) static inline uint32_t EDmaReg_GetTcdCurrentMajorCount(const EDmaRegType *obj, uint8_t channel) +{ + uint16_t result = 0U; + if((obj->TCD[channel].BITER & EDMA_TCD_BITER_ELINKNO_ELINK_MASK) == EDMA_TCD_BITER_ELINKNO_ELINK_MASK) + { + result = (uint16_t)((obj->TCD[channel].CITER & EDMA_TCD_CITER_ELINKYES_CITER_MASK) >> EDMA_TCD_CITER_ELINKYES_CITER_SHIFT); + } + else + { + result = (uint16_t)((obj->TCD[channel].CITER & EDMA_TCD_CITER_ELINKNO_CITER_MASK) >> EDMA_TCD_CITER_ELINKNO_CITER_SHIFT); + } + return (uint32_t)result; +} + +/*! \brief Configures the last source address adjustment. + * + * This function adds an adjustment value added to the source address at the completion of the major + * iteration count. This value can be applied to restore the source address to the initial value, or + * adjust the address to reference the next data structure. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : adjustment value + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdDestLastAdjust(EDmaRegType *obj, uint8_t channel, uint32_t value) +{ + obj->TCD[channel].DLASTSGA = (uint32_t)value; +} + +/*! \brief Configures the memory address of the next TCD, in Scatter/Gather mode. + * + * This address points to the beginning of a 0-modulo-32-byte region containing the next transfer control + * descriptor to be loaded into this channel. This channel reload is performed as the major iteration + * count completes. The scatter/gather address must be 0-modulo-32-byte, oterwise a configuration error + * is reported. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : next tcd address + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdScatterGatherLink(EDmaRegType *obj, uint8_t channel, uint32_t value) +{ + obj->TCD[channel].DLASTSGA = value; +} + +/*! \brief Channel Start + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] enable : Enable (true) /Disable (false) interrupt after TCD done. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdStartCmd(EDmaRegType *obj, uint8_t channel, uint8_t enable) +{ + if(enable) + { + obj->TCD[channel].CSR |= EDMA_TCD_CSR_START_MASK; + } + else + { + obj->TCD[channel].CSR &= ~EDMA_TCD_CSR_START_MASK; + } +} + +/*! \brief Enables/Disables the interrupt after the major loop completes for the TCD. + * + * If enabled, the channel generates an interrupt request by setting the appropriate bit in the + * interrupt register when the current major iteration count reaches zero. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] enable : Enable (true) /Disable (false) interrupt after TCD done. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdMajorCompleteIntCmd(EDmaRegType *obj, uint8_t channel, uint8_t enable) +{ + if(enable) + { + obj->TCD[channel].CSR |= EDMA_TCD_CSR_INTMAJOR_MASK; + } + else + { + obj->TCD[channel].CSR &= ~EDMA_TCD_CSR_INTMAJOR_MASK; + } +} + +/*! \brief Enables/Disables the half complete interrupt for the TCD. + * + * If set, the channel generates an interrupt request by setting the appropriate bit in the + * interrupt register when the current major iteration count reaches the halfway point. Specifically, + * the comparison performed by the eDMA engine is (CITER == (BITER >> 1)). This half-way point + * interrupt request is provided to support the double-buffered schemes or other types of data movement + * where the processor needs an early indication of the transfer's process. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] enable : Enable (true) /Disable (false) half complete interrupt. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdMajorHalfCompleteIntCmd(EDmaRegType *obj, uint8_t channel, uint8_t enable) +{ + if(enable) + { + obj->TCD[channel].CSR |= EDMA_TCD_CSR_INTHALF_MASK; + } + else + { + obj->TCD[channel].CSR &= ~EDMA_TCD_CSR_INTHALF_MASK; + } +} + +/*! \brief Disables/Enables the DMA request after the major loop completes for the TCD. + * + * If disabled, the eDMA hardware automatically clears the corresponding DMA request when the + * current major iteration count reaches zero. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] enable : Disable (true)/Enable (false) DMA request after TCD complete. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdDisableDmaRequestAfterTcdDoneCmd(EDmaRegType *obj, uint8_t channel, uint8_t disable) +{ + if(disable) + { + obj->TCD[channel].CSR |= EDMA_TCD_CSR_DREQ_MASK; + } + else + { + obj->TCD[channel].CSR &= ~EDMA_TCD_CSR_DREQ_MASK; + } +} + +/*! \brief Enables/Disables the scatter/gather feature for the TCD. + * + * \param[in] obj : base pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] enable : Enables (true) /Disables (false) scatter/gather feature. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdScatterGatherCmd(EDmaRegType *obj, uint8_t channel, uint8_t enable) +{ + if(enable) + { + obj->TCD[channel].CSR |= EDMA_TCD_CSR_ESG_MASK; + } + else + { + obj->TCD[channel].CSR &= ~EDMA_TCD_CSR_ESG_MASK; + } +} + +/*! \brief Configures the major channel link the TCD. + * + * If the major link is enabled, after the major loop counter is exhausted, the eDMA engine initiates a + * channel service request at the channel defined by these six bits by setting that channel start + * bits. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] enable : Enables (true) or Disables (false) channel major link. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdChannelMajorLinkCmd(EDmaRegType *obj, uint8_t channel, uint8_t enable) +{ + if(enable) + { + obj->TCD[channel].CSR |= EDMA_TCD_CSR_MAJORELINK_MASK; + } + else + { + obj->TCD[channel].CSR &= ~EDMA_TCD_CSR_MAJORELINK_MASK; + } +} + +/*! \brief This flag signals the channel is currently in execution + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetTcdChannelActiveStatus(EDmaRegType *obj, uint8_t channel) +{ + return ((obj->TCD[channel].CSR & EDMA_TCD_CSR_ACTIVE_MASK) >> EDMA_TCD_CSR_ACTIVE_SHIFT); +} + +/*! \brief This flag signals the eDMA has completed the major loop. + * + * The eDMA engine sets it as the CITER count reaches zero.The software clears it, orthe hardware when the + * channel is activated. This bit must be cleared to write the MAJORELINK or ESG bits. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetTcdChannelDoneStatus(EDmaRegType *obj, uint8_t channel) +{ + return ((obj->TCD[channel].CSR & EDMA_TCD_CSR_DONE_MASK) >> EDMA_TCD_CSR_DONE_SHIFT); +} + +/*! \brief Configures the major channel link the TCD. + * + * If the major link is enabled, after the major loop counter is exhausted, the eDMA engine initiates a + * channel service request at the channel defined by these field by setting that channel's TCDn_CSR[MAJORELINK] + * bit. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] majorLinkChannel : channel number for major link + * \param[in] enable : Enables (true) or Disables (false) channel major link. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdMajorLinkChannel(EDmaRegType *obj, uint8_t channel, uint8_t value) +{ + uint16_t csrTemp; + csrTemp = obj->TCD[channel].CSR; + csrTemp &= (uint16_t) ~(EDMA_TCD_CSR_MAJORLINKCH_MASK); + csrTemp |= (((uint16_t)(((uint16_t)(value)) << EDMA_TCD_CSR_MAJORLINKCH_SHIFT)) & EDMA_TCD_CSR_MAJORLINKCH_MASK); + ; + obj->TCD[channel].CSR = csrTemp; +} + +/*! \brief Get Hardware clear Done automatically + * + * \param[in] obj: pointer to eDMA register instance + * \param[in] channel: eDMA channel number. + * \param[in] enable: Enables (true) or Disables (false) would clear Done automatically. + * 0:hardware would not clear Done automatically + * 1:hardware would clear Done automatically + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdHardClrDoneCmd(EDmaRegType *obj, uint8_t channel, uint8_t enable) +{ + if(enable) + { + obj->TCD[channel].CSR |= EDMA_TCD_CSR_HARD_CLR_DONE_MASK; + } + else + { + obj->TCD[channel].CSR &= ~EDMA_TCD_CSR_HARD_CLR_DONE_MASK; + } +} + +/*! \brief Get Hardware clear Done automatically + * + * \param[in] obj: pointer to eDMA register instance + * \param[in] channel: eDMA channel number. + * \return 0:hardware would not clear Done automatically + * 1:hardware would clear Done automatically + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_getTcdHardClrDone(EDmaRegType *obj, uint8_t channel) +{ + return ((obj->TCD[channel].CSR & EDMA_TCD_CSR_HARD_CLR_DONE_MASK) >> EDMA_TCD_CSR_HARD_CLR_DONE_SHIFT); +} + +/*! \brief Sets the channel minor link for the TCD. + * + * \param[in] obj: pointer to eDMA register instance + * \param[in] channel: eDMA channel number. + * \param[in] enable: Channel to be linked on minor loop complete. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdBiterMinorLinkChannel(EDmaRegType *obj, uint8_t channel, uint8_t value) +{ + uint16_t biterElinkTemp; + biterElinkTemp = obj->TCD[channel].BITER; + biterElinkTemp &= (uint16_t) ~(EDMA_TCD_BITER_ELINKYES_LINKCH_MASK); + biterElinkTemp |= (((uint16_t)(((uint16_t)(value)) << EDMA_TCD_BITER_ELINKYES_LINKCH_SHIFT)) & EDMA_TCD_BITER_ELINKYES_LINKCH_MASK); + obj->TCD[channel].BITER = biterElinkTemp; +} + +/*! \brief Configures the minor channel link the TCD. + * + * If the major link is enabled, after the major loop counter is exhausted, the eDMA engine initiates a + * channel service request at the channel defined by these six bits by setting that channel start + * bits. + * + * \param[in] obj: pointer to eDMA register instance + * \param[in] channel: eDMA channel number. + * \param[in] enable: Enables (true) or Disables (false) channel major link. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdBiterMinorLinkCmd(EDmaRegType *obj, uint8_t channel, uint8_t enable) +{ + if(enable) + { + obj->TCD[channel].BITER |= EDMA_TCD_BITER_ELINKYES_ELINK_MASK; + } + else + { + obj->TCD[channel].BITER &= ~EDMA_TCD_BITER_ELINKYES_ELINK_MASK; + } +} + +/*! \brief Cancels the remaining data transfer. + * + * This function stops the executing channel and forces the minor loop + * to finish. The cancellation takes effect after the last write of the + * current read/write sequence. The CX clears itself after the cancel has + * been honored. This cancel retires the channel normally as if the minor + * loop had completed. + * + * \param[in] obj: pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_CancelTransfer(EDmaRegType *obj) +{ + EDmaReg_EnableCx(obj); + while(EDmaReg_GetCx(obj) != 0UL) + { + } +} + +/*! \brief Cancels the remaining data transfer and treats it as an error condition. + * + * This function stops the executing channel and forces the minor loop + * to finish. The cancellation takes effect after the last write of the + * current read/write sequence. The CX clears itself after the cancel has + * been honoured. This cancel retires the channel normally as if the minor + * loop had completed. Additional thing is to treat this operation as an error + * condition. + * + * \param[in] obj: pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_CancelTransferWithError(EDmaRegType *obj) +{ + EDmaReg_EnableEcx(obj); + while(EDmaReg_GetEcx(obj) != 0UL) + { + } +} + +/*! \brief Enables/Disables the error interrupt for channels. + * + * \param[in] obj: base pointer to eDMA register instance + * \param[in] channel: Channel indicator. + * \param[in] enable : Enable(true) or Disable (false) error interrupt. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetErrorIntCmd(EDmaRegType *obj, uint8_t channel, bool enable) +{ + if(enable) + { + EDmaReg_SetEnableErrorInterrupt(obj, channel); + } + else + { + EDmaReg_ClearEnableErrorInterrupt(obj, channel); + } +} + +/*! \brief Enables/Disables the DMA request for the channel or all channels. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] enable : Enable(true) or Disable (false) eDMA request. + * \param[in] channel : Channel indicator. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetDmaRequestCmd(EDmaRegType *obj, uint8_t channel, bool enable) +{ + if(enable) + { + EDmaReg_SetEnableRequest(obj, channel); + } + else + { + EDmaReg_ClearEnableRequest(obj, channel); + } +} + +/*! \brief Clears all registers to 0 for the hardware TCD. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_ClearTcdReg(EDmaRegType *obj, uint8_t channel) +{ + obj->TCD[channel].NBYTES = 0U; + obj->TCD[channel].SADDR = 0U; + obj->TCD[channel].SOFF = 0; + obj->TCD[channel].ATTR = 0U; + obj->TCD[channel].SLAST = 0; + obj->TCD[channel].DADDR = 0U; + obj->TCD[channel].DOFF = 0; + obj->TCD[channel].CITER = 1U; + obj->TCD[channel].DLASTSGA = 0; + obj->TCD[channel].CSR = 0U; + obj->TCD[channel].BITER = 1U; +} + +/*! \brief Configures the transfer attribute for the eDMA channel. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] srcModulo : enumeration type for an allowed source modulo. The value defines a specific address range + * specified as the value after the SADDR + SOFF calculation is performed on the original register + * value. Setting this field provides the ability to implement a circular data. For data queues + * requiring power-of-2 size bytes, the queue should start at a 0-modulo-size address and the SMOD + * field should be set to the appropriate value for the queue, freezing the desired number of upper + * address bits. The value programmed into this field specifies the number of the lower address bits + * allowed to change. For a circular queue application, the SOFF is typically set to the transfer + * size to implement post-increment addressing with SMOD function restricting the addresses to a + * 0-modulo-size range. + * \param[in] destModulo : Enum type for an allowed destination modulo. + * \param[in] transferSize : Enum type for source/destination transfer size. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdAttribute(EDmaRegType *obj, uint8_t channel, uint8_t srcModulo, uint8_t destModulo, uint8_t transferSize) +{ + EDmaReg_SetTcdDmod(obj, channel, destModulo); + EDmaReg_SetTcdSmod(obj, channel, srcModulo); + EDmaReg_SetTcdSrcDesTransferSize(obj, channel, transferSize); +} + +/*! \brief Configures the major channel link the TCD. + * + * If the major link is enabled, after the major loop counter is exhausted, the eDMA engine initiates a + * channel service request at the channel defined by these six bits by setting that channel start + * bits. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] majorLinkChannel : channel number for major link + * \param[in] enable : Enables (true) or Disables (false) channel major link. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdChannelMajorLink(EDmaRegType *obj, uint8_t channel, uint32_t majorLinkChannel, bool enable) +{ + EDmaReg_SetTcdChannelMajorLinkCmd(obj, channel, enable); + EDmaReg_SetTcdMajorLinkChannel(obj, channel, majorLinkChannel); +} + +/*! \brief Sets the channel minor link for the TCD. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] linkChannel : Channel to be linked on minor loop complete. + * \param[in] enable : Enable (true)/Disable (false) channel minor link. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdChannelMinorLink(EDmaRegType *obj, uint8_t channel, uint32_t linkChannel, bool enable) +{ + EDmaReg_SetTcdBiterMinorLinkCmd(obj, channel, enable); + EDmaReg_SetTcdCiterMinorLinkCmd(obj, channel, enable); + if(enable) + { + EDmaReg_SetTcdBiterMinorLinkChannel(obj, channel, linkChannel); + EDmaReg_SetTcdCiterMinorLinkChannel(obj, channel, linkChannel); + } +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _DMA_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/eim_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/eim_reg.h new file mode 100644 index 0000000..a7c9bbb --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/eim_reg.h @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _EIM_REG_H_ +#define _EIM_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the EIM Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* CR Bit Fields */ +#define EIM_CR_GEIEN_MASK (0x01u) +#define EIM_CR_GEIEN_SHIFT (0u) +#define EIM_CR_GEIEN_WIDTH (1u) + +/* CHEN Bit Fields */ +#define EIM_CH_EN_CH0_MASK (0x01u) +#define EIM_CH_EN_CH0_SHIFT (0u) +#define EIM_CH_EN_CH0_WIDTH (1u) + +/* CH0_DATAH Bit Fields */ +#define EIM_CH0_DATAH_DATAH_MASK (0xFF000000u) +#define EIM_CH0_DATAH_DATAH_SHIFT (24u) +#define EIM_CH0_DATAH_DATAH_WIDTH (8u) + +/* CH0_DATAL Bit Fields */ +#define EIM_CH0_DATAL_DATAL_MASK (0xFFFFFFFFu) +#define EIM_CH0_DATAL_DATAL_SHIFT (0u) +#define EIM_CH0_DATAL_DATAL_WIDTH (32u) + +/* CH0_DATAM Bit Fields */ +#define EIM_CH0_DATAM_DATAM_MASK (0xFFFFFFFFu) +#define EIM_CH0_DATAM_DATAM_SHIFT (0u) +#define EIM_CH0_DATAM_DATAM_WIDTH (32u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of EIM registers + */ +typedef struct _EimRegType_ +{ + volatile uint32_t CR; /*!< Control, Error in Control Register, offset: 0x0 */ + volatile uint32_t CH_EN; /*!< Control, Error in channel enable Register, offset: 0x4 */ + uint32_t RESERVED0[62]; /*!< Reserverd block, offset: 0x8 */ + volatile uint32_t CH0_DATAH; /*!< CH0 data bits[71:64] error injection enable, offset: 0x100 */ + volatile uint32_t CH0_DATAL; /*!< CH0 data bits[31:0] error injection enable, offset: 0x0x104 */ + volatile uint32_t CH0_DATAM; /*!< CH0 data bits[63:32] error injection enable, offset: 0x0x108 */ +} EimRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the Global Error Injection Enable + * + * This function gets the current Global Error Injection Enable. + * This bit globally enables or disables the error injection function of the EIM. + * This field is initialized by hardware reset. + * + * \param[in] obj : pointer to EIM register instance + * \return Global Error Injection Enable + * - 0b : Disabled + * - 1b : Enabled + */ +__attribute__((always_inline)) static inline uint8_t EimReg_GetCrGeiEn(const EimRegType *obj) +{ + return ((obj->CR & EIM_CR_GEIEN_MASK) >> EIM_CR_GEIEN_SHIFT); +} + +/*! \brief Sets the Global Error Injection Enable + * + * This function sets the Global Error Injection Enable. + * This bit globally enables or disables the error injection function of the EIM. + * This field is initialized by hardware reset. + * + * \param[in] obj : pointer to EIM register instance + * \param[in] value : the value of Global Error Injection Enable + * - 0b : Disabled + * - 1b : Enabled + */ +__attribute__((always_inline)) static inline void EimReg_SetCrGeiEn(EimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR; + + tmp &= ~EIM_CR_GEIEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << EIM_CR_GEIEN_SHIFT)) & EIM_CR_GEIEN_MASK); + obj->CR = tmp; +} + +/*! \brief Gets the Error Injection Channel 0 Enable + * + * This function gets the current Error Injection Channel 0 Enable. + * This field enables the corresponding error injection channel. + * The Global Error Injection Enable (EIMCR[GEIEN]) field must also be asserted to enable error injection. + * After error injection is enabled, all subsequent read accesses incur one or more bit inversions as defined + * in the corresponding EIM_CHn_* registers. + * Error injection remains in effect until the error injection channel is manually disabled via software. + * + * \param[in] obj : pointer to EIM register instance + * \return Error Injection Channel 0 Enable + * - 0b : Error injection is disabled on Error Injection Channel 0 + * - 1b : Error injection is enabled on Error Injection Channel 0 + */ +__attribute__((always_inline)) static inline uint8_t EimReg_GetChEnCh0(const EimRegType *obj) +{ + return ((obj->CH_EN & EIM_CH_EN_CH0_MASK) >> EIM_CH_EN_CH0_SHIFT); +} + +/*! \brief Sets the Error Injection Channel 0 Enable + * + * This function sets the Error Injection Channel 0 Enable. + * This field enables the corresponding error injection channel. + * The Global Error Injection Enable (EIMCR[GEIEN]) field must also be asserted to enable error injection. + * After error injection is enabled, all subsequent read accesses incur one or more bit inversions + * as defined in the corresponding EIM_CHn_* registers. + * Error injection remains in effect until the error injection channel is manually disabled via software. + * + * \param[in] obj : pointer to EIM register instance + * \param[in] value : the value of Error Injection Channel 0 Enable + * - 0b : Error injection is disabled on Error Injection Channel 0 + * - 1b : Error injection is enabled on Error Injection Channel 0 + */ +__attribute__((always_inline)) static inline void EimReg_SetChEnCh0(EimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CH_EN; + + tmp &= ~EIM_CH_EN_CH0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << EIM_CH_EN_CH0_SHIFT)) & EIM_CH_EN_CH0_MASK); + obj->CH_EN = tmp; +} + +/*! \brief Gets the Data Inversion Enable [71:64] + * + * This function gets the current Data Inversion Enable [71:64]. + * This field defines a bit-mapped mask that specifies whether the corresponding bit of the read data bus + * from the target RAM should be inverted or remain unmodified. + * Writes to unimplemented bits are ignored. + * + * \param[in] obj : pointer to EIM register instance + * \return Data Inversion Enable [71:64] + * - 0b : The corresponding bit of the checkbit bus remains unmodified. + * - 1b : The corresponding bit of the checkbit bus is inverted. + */ +__attribute__((always_inline)) static inline uint8_t EimReg_GetCh0DataH(const EimRegType *obj) +{ + return ((obj->CH0_DATAH & EIM_CH0_DATAH_DATAH_MASK) >> EIM_CH0_DATAH_DATAH_SHIFT); +} + +/*! \brief Sets the Data Inversion Enable [71:64] + * + * This function sets the Data Inversion Enable [71:64]. + * This field defines a bit-mapped mask that specifies whether the corresponding bit of the read data bus + * from the target RAM should be inverted or remain unmodified. + * Writes to unimplemented bits are ignored. + * + * \param[in] obj : pointer to EIM register instance + * \param[in] value : the value of Data Inversion Enable [71:64] + * - 0b : The corresponding bit of the checkbit bus remains unmodified. + * - 1b : The corresponding bit of the checkbit bus is inverted. + */ +__attribute__((always_inline)) static inline void EimReg_SetCh0DataH(EimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CH0_DATAH; + + tmp &= ~EIM_CH0_DATAH_DATAH_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << EIM_CH0_DATAH_DATAH_SHIFT)) & EIM_CH0_DATAH_DATAH_MASK); + obj->CH0_DATAH = tmp; +} + +/*! \brief Gets the Data Inversion Enable [31:0] + * + * This function gets the current Data Inversion Enable [31:0]. + * This field defines a bit-mapped mask that specifies whether the corresponding bit of the read data bus + * from the target RAM should be inverted or remain unmodified. + * Writes to unimplemented bits are ignored. + * + * \param[in] obj : pointer to EIM register instance + * \return Data Inversion Enable [31:0] + * - 0b : The corresponding bit of the checkbit bus remains unmodified. + * - 1b : The corresponding bit of the checkbit bus is inverted. + */ +__attribute__((always_inline)) static inline uint32_t EimReg_GetCh0DataL(const EimRegType *obj) +{ + return ((obj->CH0_DATAL & EIM_CH0_DATAL_DATAL_MASK) >> EIM_CH0_DATAL_DATAL_SHIFT); +} + +/*! \brief Sets the Data Inversion Enable [31:0] + * + * This function sets the Data Inversion Enable [31:0]. + * This field defines a bit-mapped mask that specifies whether the corresponding bit of the read data bus + * from the target RAM should be inverted or remain unmodified. + * Writes to unimplemented bits are ignored. + * + * \param[in] obj : pointer to EIM register instance + * \param[in] value : the value of Data Inversion Enable [31:0] + * - 0b : The corresponding bit of the checkbit bus remains unmodified. + * - 1b : The corresponding bit of the checkbit bus is inverted. + */ +__attribute__((always_inline)) static inline void EimReg_SetCh0DataL(EimRegType *obj, uint32_t value) +{ + uint32_t tmp = obj->CH0_DATAL; + + tmp &= ~EIM_CH0_DATAL_DATAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << EIM_CH0_DATAL_DATAL_SHIFT)) & EIM_CH0_DATAL_DATAL_MASK); + obj->CH0_DATAL = tmp; +} + +/*! \brief Gets the Data Inversion Enable [63:32] + * + * This function gets the current Data Inversion Enable [63:32]. + * This field defines a bit-mapped mask that specifies whether the corresponding bit of the read data bus + * from the target RAM should be inverted or remain unmodified. + * Writes to unimplemented bits are ignored. + * + * \param[in] obj : pointer to EIM register instance + * \return Data Inversion Enable [63:32] + * - 0b : The corresponding bit of the checkbit bus remains unmodified. + * - 1b : The corresponding bit of the checkbit bus is inverted. + */ +__attribute__((always_inline)) static inline uint32_t EimReg_GetCh0DataM(const EimRegType *obj) +{ + return ((obj->CH0_DATAM & EIM_CH0_DATAM_DATAM_MASK) >> EIM_CH0_DATAM_DATAM_SHIFT); +} + +/*! \brief Sets the Data Inversion Enable [63:32] + * + * This function sets the Data Inversion Enable [63:32]. + * This field defines a bit-mapped mask that specifies whether the corresponding bit of the read data bus + * from the target RAM should be inverted or remain unmodified. + * Writes to unimplemented bits are ignored. + * + * \param[in] obj : pointer to EIM register instance + * \param[in] value : the value of Data Inversion Enable [63:32] + * - 0b : The corresponding bit of the checkbit bus remains unmodified. + * - 1b : The corresponding bit of the checkbit bus is inverted. + */ +__attribute__((always_inline)) static inline void EimReg_SetCh0DataM(EimRegType *obj, uint32_t value) +{ + uint32_t tmp = obj->CH0_DATAM; + + tmp &= ~EIM_CH0_DATAM_DATAM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << EIM_CH0_DATAM_DATAM_SHIFT)) & EIM_CH0_DATAM_DATAM_MASK); + obj->CH0_DATAM = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _EIM_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/erm_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/erm_reg.h new file mode 100644 index 0000000..dea99b8 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/erm_reg.h @@ -0,0 +1,520 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _ERM_REG_H_ +#define _ERM_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the ERM Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* CR0 Bit Fields */ +#define ERM_CR0_ENCIE1_MASK (0x08u) +#define ERM_CR0_ENCIE1_SHIFT (3u) +#define ERM_CR0_ENCIE1_WIDTH (1u) +#define ERM_CR0_ESCIE1_MASK (0x04u) +#define ERM_CR0_ESCIE1_SHIFT (2u) +#define ERM_CR0_ESCIE1_WIDTH (1u) +#define ERM_CR0_ENCIE0_MASK (0x02u) +#define ERM_CR0_ENCIE0_SHIFT (1u) +#define ERM_CR0_ENCIE0_WIDTH (1u) +#define ERM_CR0_ESCIE0_MASK (0x01u) +#define ERM_CR0_ESCIE0_SHIFT (0u) +#define ERM_CR0_ESCIE0_WIDTH (1u) + +/* SR Bit Fields */ +#define ERM_SR_NCE1_MASK (0x08u) +#define ERM_SR_NCE1_SHIFT (3u) +#define ERM_SR_NCE1_WIDTH (1u) +#define ERM_SR_SBC1_MASK (0x04u) +#define ERM_SR_SBC1_SHIFT (2u) +#define ERM_SR_SBC1_WIDTH (1u) +#define ERM_SR_NCE0_MASK (0x02u) +#define ERM_SR_NCE0_SHIFT (1u) +#define ERM_SR_NCE0_WIDTH (1u) +#define ERM_SR_SBC0_MASK (0x01u) +#define ERM_SR_SBC0_SHIFT (0u) +#define ERM_SR_SBC0_WIDTH (1u) + +/* CH0_ST0 Bit Fields */ +#define ERM_CH0_ST0_ADR0_MASK (0xFFFFFFFFu) +#define ERM_CH0_ST0_ADR0_SHIFT (0u) +#define ERM_CH0_ST0_ADR0_WIDTH (32u) + +/* CH0_ST1 Bit Fields */ +#define ERM_CH0_ST1_SYN0_MASK (0xFF000000u) +#define ERM_CH0_ST1_SYN0_SHIFT (24u) +#define ERM_CH0_ST1_SYN0_WIDTH (8u) + +/* CH0_ST2 Bit Fields */ +#define ERM_CH0_ST2_CORR_CNT0_MASK (0xFFu) +#define ERM_CH0_ST2_CORR_CNT0_SHIFT (0u) +#define ERM_CH0_ST2_CORR_CNT0_WIDTH (8u) + +/* CH1_ST0 Bit Fields */ +#define ERM_CH1_ST0_ADR1_MASK (0xFFFFFFFFu) +#define ERM_CH1_ST0_ADR1_SHIFT (0u) +#define ERM_CH1_ST0_ADR1_WIDTH (32u) + +/* CH1_ST1 Bit Fields */ +#define ERM_CH1_ST1_SYN1_MASK (0xFF000000u) +#define ERM_CH1_ST1_SYN1_SHIFT (24u) +#define ERM_CH1_ST1_SYN1_WIDTH (8u) + +/* CH1_ST2 Bit Fields */ +#define ERM_CH1_ST2_CORR_CNT1_MASK (0xFFu) +#define ERM_CH1_ST2_CORR_CNT1_SHIFT (0u) +#define ERM_CH1_ST2_CORR_CNT1_WIDTH (8u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of ERM registers + */ +typedef struct _ErmRegType_ +{ + volatile uint32_t CR0; /*!< Error report channel enable control register, offset: 0x0 */ + uint32_t RESERVED0[3]; /*!< Reserverd block, offset: 0x4 */ + volatile uint32_t SR; /*!< Error report channel status register, offset: 0x10 */ + uint32_t RESERVED1[59]; /*!< Reserverd block, offset: 0x14 */ + volatile uint32_t CH0_ST0; /*!< channel0's error address, offset: 0x100 */ + volatile uint32_t CH0_ST1; /*!< channel0's syndrome, offset: 0x104 */ + volatile uint32_t CH0_ST2; /*!< channel0's Correctable Error Count, offset: 0x108 */ + uint32_t RESERVED2[1]; /*!< Reserverd block, offset: 0x10C */ + volatile uint32_t CH1_ST0; /*!< channel1's error address, offset: 0x110 */ + volatile uint32_t CH1_ST1; /*!< channel1's syndrome, offset: 0x114 */ + volatile uint32_t CH1_ST2; /*!< channel1's Correctable Error Count, offset: 0x118 */ +} ErmRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the Enable Memory 1 Non-Correctable Notification + * + * This function gets the current Enable Memory 1 Non-Correctable Notification. + * + * \param[in] obj : pointer to ERM register instance + * \return Enable Memory 1 Non-Correctable Notification + * - 0b : Notification of Memory 1 non-correctable error events is disabled. + * - 1b : Notification of Memory 1 non-correctable error events is enabled. + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetCr0Encie1(const ErmRegType *obj) +{ + return ((obj->CR0 & ERM_CR0_ENCIE1_MASK) >> ERM_CR0_ENCIE1_SHIFT); +} + +/*! \brief Sets the Enable Memory 1 Non-Correctable Notification + * + * This function sets the Enable Memory 1 Non-Correctable Notification. + * + * \param[in] obj : pointer to ERM register instance + * \param[in] value : the value of Enable Memory 1 Non-Correctable Notification + * - 0b : Notification of Memory 1 non-correctable error events is disabled. + * - 1b : Notification of Memory 1 non-correctable error events is enabled. + */ +__attribute__((always_inline)) static inline void ErmReg_SetCr0Encie1(ErmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR0; + + tmp &= ~ERM_CR0_ENCIE1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ERM_CR0_ENCIE1_SHIFT)) & ERM_CR0_ENCIE1_MASK); + obj->CR0 = tmp; +} + +/*! \brief Gets the Enable Memory 1 Single Correction Notification + * + * This function gets the current Enable Memory 1 Single Correction Notification. + * + * \param[in] obj : pointer to ERM register instance + * \return Enable Memory 1 Single Correction Notification + * - 0b : notification of Memory 1 single-bit correction events is disabled. + * - 1b : notification of Memory 1 single-bit correction events is enabled. + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetCr0Escie1(const ErmRegType *obj) +{ + return ((obj->CR0 & ERM_CR0_ESCIE1_MASK) >> ERM_CR0_ESCIE1_SHIFT); +} + +/*! \brief Sets the Enable Memory 1 Single Correction Notification + * + * This function sets the Enable Memory 1 Single Correction Notification. + * + * \param[in] obj : pointer to ERM register instance + * \param[in] value : the value of Enable Memory 1 Single Correction Notification + * - 0b : notification of Memory 1 single-bit correction events is disabled. + * - 1b : notification of Memory 1 single-bit correction events is enabled. + */ +__attribute__((always_inline)) static inline void ErmReg_SetCr0Escie1(ErmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR0; + + tmp &= ~ERM_CR0_ESCIE1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ERM_CR0_ESCIE1_SHIFT)) & ERM_CR0_ESCIE1_MASK); + obj->CR0 = tmp; +} + +/*! \brief Gets the Enable Memory 0 Non-Correctable Notification to FHU + * + * This function gets the current Enable Memory 0 Non-Correctable Notification to FHU. + * This field is initialized by hardware reset. + * + * \param[in] obj : pointer to ERM register instance + * \return Enable Memory 0 Non-Correctable Notification to FHU + * - 0b : Notification of Memory 0 non-correctable error events is disabled. + * - 1b : Notification of Memory 0 non-correctable error events is enabled. + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetCr0Encie0(const ErmRegType *obj) +{ + return ((obj->CR0 & ERM_CR0_ENCIE0_MASK) >> ERM_CR0_ENCIE0_SHIFT); +} + +/*! \brief Sets the Enable Memory 0 Non-Correctable Notification to FHU + * + * This function sets the Enable Memory 0 Non-Correctable Notification to FHU. + * This field is initialized by hardware reset. + * + * \param[in] obj : pointer to ERM register instance + * \param[in] value : the value of Enable Memory 0 Non-Correctable Notification to FHU + * - 0b : Notification of Memory 0 non-correctable error events is disabled. + * - 1b : Notification of Memory 0 non-correctable error events is enabled. + */ +__attribute__((always_inline)) static inline void ErmReg_SetCr0Encie0(ErmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR0; + + tmp &= ~ERM_CR0_ENCIE0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ERM_CR0_ENCIE0_SHIFT)) & ERM_CR0_ENCIE0_MASK); + obj->CR0 = tmp; +} + +/*! \brief Gets the Enable Memory 0 Single Correction Notification to FHU + * + * This function gets the current Enable Memory 0 Single Correction Notification to FHU. + * This field is initialized by hardware reset. + * + * \param[in] obj : pointer to ERM register instance + * \return Enable Memory 0 Single Correction Notification to FHU + * - 0b : notification of Memory 0 single-bit correction events is disabled. + * - 1b : notification of Memory 0 single-bit correction events is enabled. + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetCr0Escie0(const ErmRegType *obj) +{ + return ((obj->CR0 & ERM_CR0_ESCIE0_MASK) >> ERM_CR0_ESCIE0_SHIFT); +} + +/*! \brief Sets the Enable Memory 0 Single Correction Notification to FHU + * + * This function sets the Enable Memory 0 Single Correction Notification to FHU. + * This field is initialized by hardware reset. + * + * \param[in] obj : pointer to ERM register instance + * \param[in] value : the value of Enable Memory 0 Single Correction Notification to FHU + * - 0b : notification of Memory 0 single-bit correction events is disabled. + * - 1b : notification of Memory 0 single-bit correction events is enabled. + */ +__attribute__((always_inline)) static inline void ErmReg_SetCr0Escie0(ErmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR0; + + tmp &= ~ERM_CR0_ESCIE0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ERM_CR0_ESCIE0_SHIFT)) & ERM_CR0_ESCIE0_MASK); + obj->CR0 = tmp; +} + +/*! \brief Gets the Memory 1 Non-Correctable Error Event + * + * This function gets the current Memory 1 Non-Correctable Error Event. + * + * \param[in] obj : pointer to ERM register instance + * \return Memory 1 Non-Correctable Error Event + * - 0b : No non-correctable error event on Memory 1 detected. + * - 1b : Non-correctable error event on Memory 1 detected. + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetSrNce1(const ErmRegType *obj) +{ + return ((obj->SR & ERM_SR_NCE1_MASK) >> ERM_SR_NCE1_SHIFT); +} + +/*! \brief Sets the Memory 1 Non-Correctable Error Event + * + * This function sets the Memory 1 Non-Correctable Error Event. + * + * \param[in] obj : pointer to ERM register instance + * \param[in] value : the value of Memory 1 Non-Correctable Error Event + * - 0b : No non-correctable error event on Memory 1 detected. + * - 1b : Non-correctable error event on Memory 1 detected. + */ +__attribute__((always_inline)) static inline void ErmReg_SetSrNce1(ErmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << ERM_SR_NCE1_SHIFT)) & ERM_SR_NCE1_MASK); + obj->SR = tmp; +} + +/*! \brief Gets the Memory 1 Single-Bit Correction Event + * + * This function gets the current Memory 1 Single-Bit Correction Event. + * + * \param[in] obj : pointer to ERM register instance + * \return Memory 1 Single-Bit Correction Event + * - 0b : No single-bit correction event on Memory 1 detected. + * - 1b : Single-bit correction event on Memory 1 detected. + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetSrSbc1(const ErmRegType *obj) +{ + return ((obj->SR & ERM_SR_SBC1_MASK) >> ERM_SR_SBC1_SHIFT); +} + +/*! \brief Sets the Memory 1 Single-Bit Correction Event + * + * This function sets the Memory 1 Single-Bit Correction Event. + * + * \param[in] obj : pointer to ERM register instance + * \param[in] value : the value of Memory 1 Single-Bit Correction Event + * - 0b : No single-bit correction event on Memory 1 detected. + * - 1b : Single-bit correction event on Memory 1 detected. + */ +__attribute__((always_inline)) static inline void ErmReg_SetSrSbc1(ErmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << ERM_SR_SBC1_SHIFT)) & ERM_SR_SBC1_MASK); + obj->SR = tmp; +} + +/*! \brief Gets the Memory 0 Non-Correctable Error Event + * + * This function gets the current Memory 0 Non-Correctable Error Event. + * Write 1 to clear this field. This write also clears the corresponding interrupt notification, + * if CR0[ENCIE0] is enabled. + * + * \param[in] obj : pointer to ERM register instance + * \return Memory 0 Non-Correctable Error Event + * - 0b : No non-correctable error event on Memory 0 detected. + * - 1b : Non-correctable error event on Memory 0 detected. + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetSrNce0(const ErmRegType *obj) +{ + return ((obj->SR & ERM_SR_NCE0_MASK) >> ERM_SR_NCE0_SHIFT); +} + +/*! \brief Sets the Memory 0 Non-Correctable Error Event + * + * This function sets the Memory 0 Non-Correctable Error Event. + * Write 1 to clear this field. This write also clears the corresponding interrupt notification, + * if CR0[ENCIE0] is enabled. + * + * \param[in] obj : pointer to ERM register instance + * \param[in] value : the value of Memory 0 Non-Correctable Error Event + * - 0b : No non-correctable error event on Memory 0 detected. + * - 1b : Non-correctable error event on Memory 0 detected. + */ +__attribute__((always_inline)) static inline void ErmReg_SetSrNce0(ErmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << ERM_SR_NCE0_SHIFT)) & ERM_SR_NCE0_MASK); + obj->SR = tmp; +} + +/*! \brief Gets the Memory 0 Single-Bit Correction Event + * + * This function gets the current Memory 0 Single-Bit Correction Event. + * Write 1 to clear this field. This write also clears the corresponding interrupt notification, + * if CR0[ESCIE0] is enabled. + * + * \param[in] obj : pointer to ERM register instance + * \return Memory 0 Single-Bit Correction Event + * - 0b : No single-bit correction event on Memory 0 detected. + * - 1b : Single-bit correction event on Memory 0 detected. + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetSrSbc0(const ErmRegType *obj) +{ + return ((obj->SR & ERM_SR_SBC0_MASK) >> ERM_SR_SBC0_SHIFT); +} + +/*! \brief Sets the Memory 0 Single-Bit Correction Event + * + * This function sets the Memory 0 Single-Bit Correction Event. + * Write 1 to clear this field. This write also clears the corresponding interrupt notification, + * if CR0[ESCIE0] is enabled. + * + * \param[in] obj : pointer to ERM register instance + * \param[in] value : the value of Memory 0 Single-Bit Correction Event + * - 0b : No single-bit correction event on Memory 0 detected. + * - 1b : Single-bit correction event on Memory 0 detected. + */ +__attribute__((always_inline)) static inline void ErmReg_SetSrSbc0(ErmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << ERM_SR_SBC0_SHIFT)) & ERM_SR_SBC0_MASK); + obj->SR = tmp; +} + +/*! \brief Gets the Memory 0 Error Address + * + * This function gets the current Memory 0 Error Address. + * This field contains the faulting system address of the last recorded ECC event on Memory 0 + * + * \param[in] obj : pointer to ERM register instance + * \return Memory 0 Error Address + */ +__attribute__((always_inline)) static inline uint32_t ErmReg_GetCh0St0Adr0(const ErmRegType *obj) +{ + return ((obj->CH0_ST0 & ERM_CH0_ST0_ADR0_MASK) >> ERM_CH0_ST0_ADR0_SHIFT); +} + +/*! \brief Gets the Memory n Syndrome + * + * This function gets the current Memory n Syndrome. + * This field contains the ECC syndrome associated with the last recorded ECC event on Memory n + * + * \param[in] obj : pointer to ERM register instance + * \return Memory n Syndrome + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetCh0St1Syn0(const ErmRegType *obj) +{ + return ((obj->CH0_ST1 & ERM_CH0_ST1_SYN0_MASK) >> ERM_CH0_ST1_SYN0_SHIFT); +} + +/*! \brief Gets the Memory n Correctable Error Count + * + * This function gets the current Memory n Correctable Error Count. + * For each correctable error event, the ERM increments this field's error count value + * until the counter reaches its maximum value FFh. + * COUNT field description can be updated as required. + * COUNT value will stop once it reaches maximum value FFh and will not wrap even if error occurs. + * Read this field to determine the correctable error count value so far. + * Write all zeros to this field to reset the counter. Writing non-zero (or partial zero) values has no effect + * + * \param[in] obj : pointer to ERM register instance + * \return Memory n Correctable Error Count + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetCh0St2CorrCnt0(const ErmRegType *obj) +{ + return ((obj->CH0_ST2 & ERM_CH0_ST2_CORR_CNT0_MASK) >> ERM_CH0_ST2_CORR_CNT0_SHIFT); +} + +/*! \brief Sets the Memory n Correctable Error Count + * + * This function sets the Memory n Correctable Error Count. + * For each correctable error event, the ERM increments this field's error count value + * until the counter reaches its maximum value FFh. + * COUNT field description can be updated as required. + * COUNT value will stop once it reaches maximum value FFh and will not wrap even if error occurs. + * Read this field to determine the correctable error count value so far. + * Write all zeros to this field to reset the counter. Writing non-zero (or partial zero) values has no effect + * + * \param[in] obj : pointer to ERM register instance + * \param[in] value : the value of Memory n Correctable Error Count + */ +__attribute__((always_inline)) static inline void ErmReg_SetCh0St2CorrCnt0(ErmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CH0_ST2; + + tmp &= ~ERM_CH0_ST2_CORR_CNT0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ERM_CH0_ST2_CORR_CNT0_SHIFT)) & ERM_CH0_ST2_CORR_CNT0_MASK); + obj->CH0_ST2 = tmp; +} + +/*! \brief Gets the Memory 1 Error Address + * + * This function gets the current Memory 1 Error Address. + * This field contains the faulting system address of the last recorded ECC event on Memory 1 + * + * \param[in] obj : pointer to ERM register instance + * \return Memory 1 Error Address + */ +__attribute__((always_inline)) static inline uint32_t ErmReg_GetCh1St0Adr1(const ErmRegType *obj) +{ + return ((obj->CH1_ST0 & ERM_CH1_ST0_ADR1_MASK) >> ERM_CH1_ST0_ADR1_SHIFT); +} + +/*! \brief Gets the Memory n Syndrome + * + * This function gets the current Memory n Syndrome. + * This field contains the ECC syndrome associated with the last recorded ECC event on Memory 1 + * + * \param[in] obj : pointer to ERM register instance + * \return Memory n Syndrome + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetCh1St1Syn1(const ErmRegType *obj) +{ + return ((obj->CH1_ST1 & ERM_CH1_ST1_SYN1_MASK) >> ERM_CH1_ST1_SYN1_SHIFT); +} + +/*! \brief Gets the Memory n Correctable Error Count + * + * This function gets the current Memory n Correctable Error Count. + * For each correctable error event, the ERM increments this field's error count value + * until the counter reaches its maximum value FFh. + * COUNT value will stop once it reaches maximum value FFh and will not wrap even if error occurs. + * Read this field to determine the correctable error count value so far. + * Write all zeros to this field to reset the counter. + * Writing non-zero (or partial zero) values has no effect + * + * \param[in] obj : pointer to ERM register instance + * \return Memory n Correctable Error Count + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetCh1St2CorrCnt1(const ErmRegType *obj) +{ + return ((obj->CH1_ST2 & ERM_CH1_ST2_CORR_CNT1_MASK) >> ERM_CH1_ST2_CORR_CNT1_SHIFT); +} + +/*! \brief Sets the Memory n Correctable Error Count + * + * This function sets the Memory n Correctable Error Count. + * For each correctable error event, the ERM increments this field's error count value + * until the counter reaches its maximum value FFh. + * COUNT value will stop once it reaches maximum value FFh and will not wrap even if error occurs. + * Read this field to determine the correctable error count value so far. + * Write all zeros to this field to reset the counter. + * Writing non-zero (or partial zero) values has no effect + * + * \param[in] obj : pointer to ERM register instance + */ +__attribute__((always_inline)) static inline void ErmReg_SetCh1St2CorrCnt1(ErmRegType *obj) +{ + obj->CH1_ST2 = 0; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _ERM_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/fhu_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/fhu_reg.h new file mode 100644 index 0000000..047fd46 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/fhu_reg.h @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FHU_REG_H_ +#define _FHU_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the FHU Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* USER_KEY Bit Fields */ +#define FHU_USER_KEY_USER_KEY_MASK (0xFFFFFFFFu) +#define FHU_USER_KEY_USER_KEY_SHIFT (0u) +#define FHU_USER_KEY_USER_KEY_WIDTH (32u) + +/* USER_LOCK Bit Fields */ +#define FHU_USER_LOCK_USER_LOCK_MASK (0x01u) +#define FHU_USER_LOCK_USER_LOCK_SHIFT (0u) +#define FHU_USER_LOCK_USER_LOCK_WIDTH (1u) + +/* CHCTL Bit Fields */ +#define FHU_CHCTL_CHEN_CTL_MASK (0x1FFu) +#define FHU_CHCTL_CHEN_CTL_SHIFT (0u) +#define FHU_CHCTL_CHEN_CTL_WIDTH (9u) + +/* RSTCTL Bit Fields */ +#define FHU_RSTCTL_RST_CTL_MASK (0x1FFu) +#define FHU_RSTCTL_RST_CTL_SHIFT (0u) +#define FHU_RSTCTL_RST_CTL_WIDTH (9u) + +/* INTCTL Bit Fields */ +#define FHU_INTCTL_INT_CTL_MASK (0x1FFu) +#define FHU_INTCTL_INT_CTL_SHIFT (0u) +#define FHU_INTCTL_INT_CTL_WIDTH (9u) + +/* NMICTL Bit Fields */ +#define FHU_NMICTL_NMI_CTL_MASK (0x1FFu) +#define FHU_NMICTL_NMI_CTL_SHIFT (0u) +#define FHU_NMICTL_NMI_CTL_WIDTH (9u) + +/* CHNRCD Bit Fields */ +#define FHU_CHNRCD_CHN_RCD_MASK (0x3FFu) +#define FHU_CHNRCD_CHN_RCD_SHIFT (0u) +#define FHU_CHNRCD_CHN_RCD_WIDTH (10u) + +/* ADRCD Bit Fields */ +#define FHU_ADRCD_CHN_ADRCD_MASK (0x1Fu) +#define FHU_ADRCD_CHN_ADRCD_SHIFT (0u) +#define FHU_ADRCD_CHN_ADRCD_WIDTH (5u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of FHU registers + */ +typedef struct _FhuRegType_ +{ + volatile uint32_t USER_KEY; /*!< secure key register, offset: 0x00 */ + const volatile uint32_t USER_LOCK; /*!< register lock, offset: 0x04 */ + volatile uint32_t CHCTL; /*!< channel enable control register, offset: 0x08 */ + volatile uint32_t RSTCTL; /*!< channel reset control register, offset: 0x0C */ + volatile uint32_t INTCTL; /*!< channel interrupt control register, offset: 0x10 */ + volatile uint32_t NMICTL; /*!< channel NMI control register, offset: 0x14 */ + volatile uint32_t CHNRCD; /*!< fault channel record register, offset: 0x18 */ + const volatile uint32_t ADRCD; /*!< AD fault channel record register, offset: 0x1C */ +} FhuRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Sets the configure secure key + * + * This function sets the configure secure key. + * + * \param[in] obj : pointer to FHU register instance + * \param[in] value : the value of configure secure key + * - 0x97D356BA : key match + * - others : key mismatch + */ +__attribute__((always_inline)) static inline void FhuReg_SetUserKey(FhuRegType *obj, uint32_t value) +{ + uint32_t tmp = obj->USER_KEY; + + tmp &= ~FHU_USER_KEY_USER_KEY_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FHU_USER_KEY_USER_KEY_SHIFT)) & FHU_USER_KEY_USER_KEY_MASK); + obj->USER_KEY = tmp; +} + +/*! \brief Gets the configure register lock flag + * + * This function gets the current configure register lock flag. + * register lock flag; + * + * \param[in] obj : pointer to FHU register instance + * \return configure register lock flag + * - 0b : unlock + * - 1b : lock + */ +__attribute__((always_inline)) static inline uint8_t FhuReg_GetUserLock(const FhuRegType *obj) +{ + return ((obj->USER_LOCK & FHU_USER_LOCK_USER_LOCK_MASK) >> FHU_USER_LOCK_USER_LOCK_SHIFT); +} + +/*! \brief Gets the configure fault channel enable + * + * This function gets the current configure fault channel enable. + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * [5]:SRAM_SEC; + * [6]:SRAM_DED; + * [7]:FLS_DEC; + * [8]:FLS_DED; + * For each bit: + * - 0b: disable + * - 1b: enabl + * + * \param[in] obj : pointer to FHU register instance + * \return configure fault channel enable + */ +__attribute__((always_inline)) static inline uint16_t FhuReg_GetChCtl(const FhuRegType *obj) +{ + return ((obj->CHCTL & FHU_CHCTL_CHEN_CTL_MASK) >> FHU_CHCTL_CHEN_CTL_SHIFT); +} + +/*! \brief Sets the configure fault channel enable + * + * This function sets the configure fault channel enable. + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * [5]:SRAM_SEC; + * [6]:SRAM_DED; + * [7]:FLS_DEC; + * [8]:FLS_DED; + * For each bit: + * - 0b: disable + * - 1b: enabl + * + * \param[in] obj : pointer to FHU register instance + * \param[in] value : the value of configure fault channel enable + */ +__attribute__((always_inline)) static inline void FhuReg_SetChCtl(FhuRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->CHCTL; + + tmp &= ~FHU_CHCTL_CHEN_CTL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FHU_CHCTL_CHEN_CTL_SHIFT)) & FHU_CHCTL_CHEN_CTL_MASK); + obj->CHCTL = tmp; +} + +/*! \brief Gets the configure fault channel reset enable + * + * This function gets the current configure fault channel reset enable. + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * [5]:SRAM_SEC; + * [6]:SRAM_DED; + * [7]:FLS_DEC; + * [8]:FLS_DED; + * For each bit: + * - 0b: disable system reset generation + * - 1b: enable system reset generatio + * + * \param[in] obj : pointer to FHU register instance + * \return configure fault channel reset enable + */ +__attribute__((always_inline)) static inline uint16_t FhuReg_GetRstCtl(const FhuRegType *obj) +{ + return ((obj->RSTCTL & FHU_RSTCTL_RST_CTL_MASK) >> FHU_RSTCTL_RST_CTL_SHIFT); +} + +/*! \brief Sets the configure fault channel reset enable + * + * This function sets the configure fault channel reset enable. + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * [5]:SRAM_SEC; + * [6]:SRAM_DED; + * [7]:FLS_DEC; + * [8]:FLS_DED; + * For each bit: + * - 0b: disable system reset generation + * - 1b: enable system reset generatio + * + * \param[in] obj : pointer to FHU register instance + * \param[in] value : the value of configure fault channel reset enable + */ +__attribute__((always_inline)) static inline void FhuReg_SetRstCtl(FhuRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->RSTCTL; + + tmp &= ~FHU_RSTCTL_RST_CTL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FHU_RSTCTL_RST_CTL_SHIFT)) & FHU_RSTCTL_RST_CTL_MASK); + obj->RSTCTL = tmp; +} + +/*! \brief Gets the configure fault channel interrupt enable + * + * This function gets the current configure fault channel interrupt enable. + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * [5]:SRAM_SEC; + * [6]:SRAM_DED; + * [7]:FLS_DEC; + * [8]:FLS_DED; + * For each bit: + * -0b: disable interrupt generation + * -1b: enable interrupt generatio + * + * \param[in] obj : pointer to FHU register instance + * \return configure fault channel interrupt enable + */ +__attribute__((always_inline)) static inline uint16_t FhuReg_GetIntCtl(const FhuRegType *obj) +{ + return ((obj->INTCTL & FHU_INTCTL_INT_CTL_MASK) >> FHU_INTCTL_INT_CTL_SHIFT); +} + +/*! \brief Sets the configure fault channel interrupt enable + * + * This function sets the configure fault channel interrupt enable. + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * [5]:SRAM_SEC; + * [6]:SRAM_DED; + * [7]:FLS_DEC; + * [8]:FLS_DED; + * For each bit: + * -0b: disable interrupt generation + * -1b: enable interrupt generatio + * + * \param[in] obj : pointer to FHU register instance + * \param[in] value : the value of configure fault channel interrupt enable + */ +__attribute__((always_inline)) static inline void FhuReg_SetIntCtl(FhuRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->INTCTL; + + tmp &= ~FHU_INTCTL_INT_CTL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FHU_INTCTL_INT_CTL_SHIFT)) & FHU_INTCTL_INT_CTL_MASK); + obj->INTCTL = tmp; +} + +/*! \brief Gets the configure fault channel NMI enable + * + * This function gets the current configure fault channel NMI enable. + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * [5]:SRAM_SEC; + * [6]:SRAM_DED; + * [7]:FLS_DEC; + * [8]:FLS_DED; + * For each bit: + * - 0b: disable NMI generation + * - 1b: enable NMI generatio + * + * \param[in] obj : pointer to FHU register instance + * \return configure fault channel NMI enable + */ +__attribute__((always_inline)) static inline uint16_t FhuReg_GetNmiCtl(const FhuRegType *obj) +{ + return ((obj->NMICTL & FHU_NMICTL_NMI_CTL_MASK) >> FHU_NMICTL_NMI_CTL_SHIFT); +} + +/*! \brief Sets the configure fault channel NMI enable + * + * This function sets the configure fault channel NMI enable. + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * [5]:SRAM_SEC; + * [6]:SRAM_DED; + * [7]:FLS_DEC; + * [8]:FLS_DED; + * For each bit: + * - 0b: disable NMI generation + * - 1b: enable NMI generatio + * + * \param[in] obj : pointer to FHU register instance + * \param[in] value : the value of configure fault channel NMI enable + */ +__attribute__((always_inline)) static inline void FhuReg_SetNmiCtl(FhuRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->NMICTL; + + tmp &= ~FHU_NMICTL_NMI_CTL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FHU_NMICTL_NMI_CTL_SHIFT)) & FHU_NMICTL_NMI_CTL_MASK); + obj->NMICTL = tmp; +} + +/*! \brief Gets the fault channel record + * + * This function gets the current fault channel record. + * record the fault channel number + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * [5]:SRAM_SEC; + * [6]:SRAM_DED; + * [7]:FLS_DEC; + * [8]:FLS_DED; + * [9]:CPU_RET_DED; + * For each bit: + * - 0b: not fault occurs + * - 1b: fault has occurre + * + * \param[in] obj : pointer to FHU register instance + * \return fault channel record + */ +__attribute__((always_inline)) static inline uint16_t FhuReg_GetChnRcd(const FhuRegType *obj) +{ + return ((obj->CHNRCD & FHU_CHNRCD_CHN_RCD_MASK) >> FHU_CHNRCD_CHN_RCD_SHIFT); +} + +/*! \brief Sets the fault channel record + * + * This function sets the fault channel record. + * record the fault channel number + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * [5]:SRAM_SEC; + * [6]:SRAM_DED; + * [7]:FLS_DEC; + * [8]:FLS_DED; + * [9]:CPU_RET_DED; + * For each bit: + * - 0b: not fault occurs + * - 1b: fault has occurre + * + * \note Write 1 to clear for each bit. + * + * \param[in] obj : pointer to FHU register instance + * \param[in] value : the value of fault channel record + */ +__attribute__((always_inline)) static inline void FhuReg_SetChnRcd(FhuRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->CHNRCD; + + tmp &= ~FHU_CHNRCD_CHN_RCD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FHU_CHNRCD_CHN_RCD_SHIFT)) & FHU_CHNRCD_CHN_RCD_MASK); + obj->CHNRCD = tmp; +} + +/*! \brief Gets the AD fault channel record + * + * This function gets the current AD fault channel record. + * record the fault channel number + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * For each bit: + * - 0b: not fault occurs + * - 1b: fault has occurre + * + * \param[in] obj : pointer to FHU register instance + * \return AD fault channel record + */ +__attribute__((always_inline)) static inline uint8_t FhuReg_GetAdRcd(const FhuRegType *obj) +{ + return ((obj->ADRCD & FHU_ADRCD_CHN_ADRCD_MASK) >> FHU_ADRCD_CHN_ADRCD_SHIFT); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _FHU_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/flexcan_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/flexcan_reg.h new file mode 100644 index 0000000..e83db67 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/flexcan_reg.h @@ -0,0 +1,3426 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FLEXCAN_REG_H_ +#define _FLEXCAN_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the FLEXCAN Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +#define MESSAGE_BUFFER_ADDR_OFF (0x80UL) + +#define MESSAGE_BUFFER_CS_WORD_NUM (0) +#define MESSAGE_BUFFER_ID_WORD_NUM (1) + +/* message buffer CS field */ +#define MESSAGE_BUFFER_CS_EDL_SHIFT (31U) +#define MESSAGE_BUFFER_CS_EDL_MASK (0x1UL << MESSAGE_BUFFER_CS_EDL_SHIFT) +#define MESSAGE_BUFFER_CS_BRS_SHIFT (30U) +#define MESSAGE_BUFFER_CS_BRS_MASK (0x1UL << MESSAGE_BUFFER_CS_BRS_SHIFT) +#define MESSAGE_BUFFER_CS_CODE_SHIFT (24U) +#define MESSAGE_BUFFER_CS_CODE_MASK (0xFUL << MESSAGE_BUFFER_CS_CODE_SHIFT) +#define MESSAGE_BUFFER_CS_SRR_SHIFT (22U) +#define MESSAGE_BUFFER_CS_SRR_MASK (0x1UL << MESSAGE_BUFFER_CS_SRR_SHIFT) +#define MESSAGE_BUFFER_CS_IDE_SHIFT (21U) +#define MESSAGE_BUFFER_CS_IDE_MASK (0x1UL << MESSAGE_BUFFER_CS_IDE_SHIFT) +#define MESSAGE_BUFFER_CS_DLC_SHIFT (16U) +#define MESSAGE_BUFFER_CS_DLC_MASK (0xFUL << MESSAGE_BUFFER_CS_DLC_SHIFT) + +/* message buffer ID field */ +#define MESSAGE_BUFFER_ID_EXT_ID_SHIFT (0U) +#define MESSAGE_BUFFER_ID_EXT_ID_MASK (0x1FFFFFFFUL << MESSAGE_BUFFER_ID_EXT_ID_SHIFT) +#define MESSAGE_BUFFER_ID_STD_ID_SHIFT (18U) +#define MESSAGE_BUFFER_ID_STD_ID_MASK (0x7FFUL << MESSAGE_BUFFER_ID_STD_ID_SHIFT) + +/* MCR register */ +#define FLEXCAN_MCR_MDIS_SHIFT (31U) +#define FLEXCAN_MCR_MDIS_MASK (0x1UL << FLEXCAN_MCR_MDIS_SHIFT) +#define FLEXCAN_MCR_MDIS_WIDTH (1u) +#define FLEXCAN_MCR_FRZ_SHIFT (30U) +#define FLEXCAN_MCR_FRZ_MASK (0x1UL << FLEXCAN_MCR_FRZ_SHIFT) +#define FLEXCAN_MCR_FRZ_WIDTH (1u) +#define FLEXCAN_MCR_RFEN_SHIFT (29U) +#define FLEXCAN_MCR_RFEN_MASK (0x1UL << FLEXCAN_MCR_RFEN_SHIFT) +#define FLEXCAN_MCR_RFEN_WIDTH (1u) +#define FLEXCAN_MCR_HALT_SHIFT (28U) +#define FLEXCAN_MCR_HALT_MASK (0x1UL << FLEXCAN_MCR_HALT_SHIFT) +#define FLEXCAN_MCR_HALT_WIDTH (1u) +#define FLEXCAN_MCR_NOTRDY_SHIFT (27U) +#define FLEXCAN_MCR_NOTRDY_MASK (0x1UL << FLEXCAN_MCR_NOTRDY_SHIFT) +#define FLEXCAN_MCR_WAKMSK_SHIFT (26U) +#define FLEXCAN_MCR_WAKMSK_MASK (0x1UL << FLEXCAN_MCR_WAKMSK_SHIFT) +#define FLEXCAN_MCR_SOFTRST_SHIFT (25U) +#define FLEXCAN_MCR_SOFTRST_MASK (0x1UL << FLEXCAN_MCR_SOFTRST_SHIFT) +#define FLEXCAN_MCR_SOFTRST_WIDTH (1u) +#define FLEXCAN_MCR_FRZACK_SHIFT (24U) +#define FLEXCAN_MCR_FRZACK_MASK (0x1UL << FLEXCAN_MCR_FRZACK_SHIFT) +#define FLEXCAN_MCR_FRZACK_WIDTH (1u) +#define FLEXCAN_MCR_SUPV_SHIFT (23U) +#define FLEXCAN_MCR_SUPV_MASK (0x1UL << FLEXCAN_MCR_SUPV_SHIFT) +#define FLEXCAN_MCR_SUPV_WIDTH (1u) +#define FLEXCAN_MCR_SLFWAK_SHIFT (22U) +#define FLEXCAN_MCR_SLFWAK_MASK (0x1UL << FLEXCAN_MCR_SLFWAK_SHIFT) +#define FLEXCAN_MCR_SLFWAK_WIDTH (1u) +#define FLEXCAN_MCR_WRNEN_SHIFT (21U) +#define FLEXCAN_MCR_WRNEN_MASK (0x1UL << FLEXCAN_MCR_WRNEN_SHIFT) +#define FLEXCAN_MCR_WRNEN_WIDTH (1u) +#define FLEXCAN_MCR_LPMACK_SHIFT (20U) +#define FLEXCAN_MCR_LPMACK_MASK (0x1UL << FLEXCAN_MCR_LPMACK_SHIFT) +#define FLEXCAN_MCR_LPMACK_WIDTH (1u) +#define FLEXCAN_MCR_WAKSRC_SHIFT (19U) +#define FLEXCAN_MCR_WAKSRC_MASK (0x1UL << FLEXCAN_MCR_WAKSRC_SHIFT) +#define FLEXCAN_MCR_WAKSRC_WIDTH (1u) +#define FLEXCAN_MCR_DOZE_SHIFT (18U) +#define FLEXCAN_MCR_DOZE_MASK (0x1UL << FLEXCAN_MCR_DOZE_SHIFT) +#define FLEXCAN_MCR_DOZE_WIDTH (1u) +#define FLEXCAN_MCR_SRXDIS_SHIFT (17U) +#define FLEXCAN_MCR_SRXDIS_MASK (0x1UL << FLEXCAN_MCR_SRXDIS_SHIFT) +#define FLEXCAN_MCR_SRXDIS_WIDTH (1u) +#define FLEXCAN_MCR_IRQM_SHIFT (16U) +#define FLEXCAN_MCR_IRQM_MASK (0x1UL << FLEXCAN_MCR_IRQM_SHIFT) +#define FLEXCAN_MCR_IRMQ_WIDTH (1u) +#define FLEXCAN_MCR_DMA_SHIFT (15U) +#define FLEXCAN_MCR_DMA_MASK (0x1UL << FLEXCAN_MCR_DMA_SHIFT) +#define FLEXCAN_MCR_DMA_WIDTH (1u) +#define FLEXCAN_MCR_LPRIOEN_MASK (0x2000u) +#define FLEXCAN_MCR_LPRIOEN_SHIFT (13u) +#define FLEXCAN_MCR_LPRIOEN_WIDTH (1u) +#define FLEXCAN_MCR_AEN_SHIFT (12U) +#define FLEXCAN_MCR_AEN_MASK (0x1UL << FLEXCAN_MCR_AEN_SHIFT) +#define FELXCAN_MCR_AEN_WIDTH (1U) +#define FLEXCAN_MCR_FDEN_SHIFT (11U) +#define FLEXCAN_MCR_FDEN_MASK (0x1UL << FLEXCAN_MCR_FDEN_SHIFT) +#define FLEXCAN_MCR_FDEN_WIDTH (1u) +#define FLEXCAN_MCR_IDAM_SHIFT (8UL) +#define FLEXCAN_MCR_IDAM_MASK (0x3UL << FLEXCAN_MCR_IDAM_SHIFT) +#define FLEXCAN_MCR_IDAM_WIDTH (2U) +#define FLEXCAN_MCR_MAXMB_SHIFT (0U) +#define FLEXCAN_MCR_MAXMB_MASK (0x7FUL << FLEXCAN_MCR_MAXMB_SHIFT) +#define FLEXCAN_MCR_MAXMB_WIDTH (7u) + +/* CTRL1 register */ +#define FLEXCAN_CTRL1_PRESDIV_MASK (0xFF000000u) +#define FLEXCAN_CTRL1_PRESDIV_SHIFT (24u) +#define FLEXCAN_CTRL1_PRESDIV_WIDTH (8u) +#define FLEXCAN_CTRL1_RJW_MASK (0xC00000u) +#define FLEXCAN_CTRL1_RJW_SHIFT (22u) +#define FLEXCAN_CTRL1_RJW_WIDTH (2u) +#define FLEXCAN_CTRL1_PSEG1_MASK (0x380000u) +#define FLEXCAN_CTRL1_PSEG1_SHIFT (19u) +#define FLEXCAN_CTRL1_PSEG1_WIDTH (3u) +#define FLEXCAN_CTRL1_PSEG2_MASK (0x70000u) +#define FLEXCAN_CTRL1_PSEG2_SHIFT (16u) +#define FLEXCAN_CTRL1_PSEG2_WIDTH (3u) +#define FLEXCAN_CTRL1_BOFFMSK_SHIFT (15U) +#define FLEXCAN_CTRL1_BOFFMSK_MASK (0x1UL << FLEXCAN_CTRL1_BOFFMSK_SHIFT) +#define FLEXCAN_CTRL1_BOFFMSK_WIDTH (1U) +#define FLEXCAN_CTRL1_ERRMSK_SHIFT (14U) +#define FLEXCAN_CTRL1_ERRMSK_MASK (0x1UL << FLEXCAN_CTRL1_ERRMSK_SHIFT) +#define FLEXCAN_CTRL1_ERRMSK_WIDTH (1UL) +#define FLEXCAN_CTRL1_CLKSRC_SHIFT (13U) +#define FLEXCAN_CTRL1_CLKSRC_MASK (0x1UL << FLEXCAN_CTRL1_CLKSRC_SHIFT) +#define FLEXCAN_CTRL1_CLKSRC_WIDTH (1u) +#define FLEXCAN_CTRL1_LPB_SHIFT (12U) +#define FLEXCAN_CTRL1_LPB_MASK (0x1UL << FLEXCAN_CTRL1_LPB_SHIFT) +#define FLEXCAN_CTRL1_LPB_WIDTH (1u) +#define FLEXCAN_CTRL1_TWRNMSK_SHIFT (11U) +#define FLEXCAN_CTRL1_TWRNMSK_MASK (0x1UL << FLEXCAN_CTRL1_TWRNMSK_SHIFT) +#define FLEXCAN_CTRL1_TWRNMSK_WIDTH (1U) +#define FLEXCAN_CTRL1_RWRNMSK_SHIFT (10U) +#define FLEXCAN_CTRL1_RWRNMSK_MASK (1UL << FLEXCAN_CTRL1_RWRNMSK_SHIFT) +#define FLEXCAN_CTRL1_RWRNMSK_WIDTH (1U) +#define FLEXCAN_CTRL1_SMP_SHIFT (7U) +#define FLEXCAN_CTRL1_SMP_MASK (1UL << FLEXCAN_CTRL1_SMP_SHIFT) +#define FLEXCAN_CTRL1_SMP_WIDTH (1U) +#define FLEXCAN_CTRL1_BOFFREC_SHIFT (6U) +#define FLEXCAN_CTRL1_BOFFREC_MASK (1UL << FLEXCAN_CTRL1_BOFFREC_SHIFT) +#define FLEXCAN_CTRL1_BOFFREC_WIDTH (1U) +#define FLEXCAN_CTRL1_TSYN_SHIFT (5U) +#define FLEXCAN_CTRL1_TSYN_MASK (0x1UL << FLEXCAN_CTRL1_TSYN_SHIFT) +#define FLEXCAN_CTRL1_TSYN_WIDTH (1U) +#define FLEXCAN_CTRL1_LBUF_SHIFT (4U) +#define FLEXCAN_CTRL1_LBUF_MASK (0x1UL << FLEXCAN_CTRL1_LBUF_SHIFT) +#define FLEXCAN_CTRL1_LBUF_WIDTH (1U) +#define FLEXCAN_CTRL1_LOM_SHIFT (3U) +#define FLEXCAN_CTRL1_LOM_MASK (0x1UL << FLEXCAN_CTRL1_LOM_SHIFT) +#define FLEXCAN_CTRL1_LOM_WIDTH (1U) +#define FLEXCAN_CTRL1_PROPSEG_MASK (0x07u) +#define FLEXCAN_CTRL1_PROPSEG_SHIFT (0u) +#define FLEXCAN_CTRL1_PROPSEG_WIDTH (3u) + +/* TIMER register */ +#define FLEXCAN_TIMER_TIMER_MASK (0xFFFFu) +#define FLEXCAN_TIMER_TIMER_SHIFT (0u) +#define FLEXCAN_TIMER_TIMER_WIDTH (16u) + +/* RXMGMASK register */ +#define FLEXCAN_RXMGMASK_MG_MASK (0xFFFFFFFFu) +#define FLEXCAN_RXMGMASK_MG_SHIFT (0u) +#define FLEXCAN_RXMGMASK_MG_WIDTH (32u) + +/* RX14MASK register */ +#define FLEXCAN_RX14MASK_RX14M_MASK (0xFFFFFFFFu) +#define FLEXCAN_RX14MASK_RX14M_SHIFT (0u) +#define FLEXCAN_RX14MASK_RX14M_WIDTH (32u) + +/* RX15MASK register */ +#define FLEXCAN_RX15MASK_RX15M_MASK (0xFFFFFFFFu) +#define FLEXCAN_RX15MASK_RX15M_SHIFT (0u) +#define FLEXCAN_RX15MASK_RX15M_WIDTH (32u) + +/* ECR register */ +#define FLEXCAN_ECR_RXERRCNTFAST_MASK (0xFF000000u) +#define FLEXCAN_ECR_RXERRCNTFAST_SHIFT (24u) +#define FLEXCAN_ECR_RXERRCNTFAST_WIDTH (8u) +#define FLEXCAN_ECR_TXERRCNTFAST_MASK (0xFF0000u) +#define FLEXCAN_ECR_TXERRCNTFAST_SHIFT (16u) +#define FLEXCAN_ECR_TXERRCNTFAST_WIDTH (8u) +#define FLEXCAN_ECR_RXERRCNT_MASK (0xFF00u) +#define FLEXCAN_ECR_RXERRCNT_SHIFT (8u) +#define FLEXCAN_ECR_RXERRCNT_WIDTH (8u) +#define FLEXCAN_ECR_TXERRCNT_MASK (0xFFu) +#define FLEXCAN_ECR_TXERRCNT_SHIFT (0u) +#define FLEXCAN_ECR_TXERRCNT_WIDTH (8u) + +/* ESR1 register */ +#define FLEXCAN_ESR1_BIT1ERR_FAST_SHIFT (31U) +#define FLEXCAN_ESR1_BIT1ERR_FAST_MASK (1UL << FLEXCAN_ESR1_BIT1ERR_FAST_SHIFT) +#define FLEXCAN_ESR1_BIT1ERR_FAST_WIDTH (1U) +#define FLEXCAN_ESR1_BIT0ERR_FAST_SHIFT (30U) +#define FLEXCAN_ESR1_BIT0ERR_FAST_MASK (1UL << FLEXCAN_ESR1_BIT0ERR_FAST_SHIFT) +#define FLEXCAN_ESR1_BIT0ERR_FAST_WIDTH (1U) +#define FLEXCAN_ESR1_CRCERR_FAST_SHIFT (28U) +#define FLEXCAN_ESR1_CRCERR_FAST_MASK (1UL << FLEXCAN_ESR1_CRCERR_FAST_SHIFT) +#define FLEXCAN_ESR1_CRCERR_FAST_WIDTH (1U) +#define FLEXCAN_ESR1_FRMERR_FAST_SHIFT (27U) +#define FLEXCAN_ESR1_FRMERR_FAST_MASK (1UL << FLEXCAN_ESR1_FRMERR_FAST_SHIFT) +#define FLEXCAN_ESR1_FRMERR_FAST_WIDTH (1U) +#define FLEXCAN_ESR1_STFERR_FAST_SHIFT (26U) +#define FLEXCAN_ESR1_STFERR_FAST_MASK (1UL << FLEXCAN_ESR1_STFERR_FAST_SHIFT) +#define FLEXCAN_ESR1_STFERR_FAST_WIDTH (1U) +#define FLEXCAN_ESR1_ERROVR_SHIFT (21U) +#define FLEXCAN_ESR1_ERROVR_MASK (1UL << FLEXCAN_ESR1_ERROVR_SHIFT) +#define FLEXCAN_ESR1_ERROVR_WIDTH (1U) +#define FLEXCAN_ESR1_ERRINT_FAST_SHIFT (20U) +#define FLEXCAN_ESR1_ERRINT_FAST_MASK (1UL << FLEXCAN_ESR1_ERRINT_FAST_SHIFT) +#define FLEXCAN_ESR1_ERRINT_FAST_WIDTH (1U) +#define FLEXCAN_ESR1_BOFFDONEINT_SHIFT (19U) +#define FLEXCAN_ESR1_BOFFDONEINT_MASK (1UL << FLEXCAN_ESR1_BOFFDONEINT_SHIFT) +#define FLEXCAN_ESR1_BOFFDONEINT_WIDTH (1U) +#define FLEXCAN_ESR1_SYNCH_SHIFT (18U) +#define FLEXCAN_ESR1_SYNCH_MASK (1UL << FLEXCAN_ESR1_SYNCH_SHIFT) +#define FLEXCAN_ESR1_SYNCH_WIDTH (1U) +#define FLEXCAN_ESR1_TWRNINT_SHIFT (17U) +#define FLEXCAN_ESR1_TWRNINT_MASK (1UL << FLEXCAN_ESR1_TWRNINT_SHIFT) +#define FLEXCAN_ESR1_TWRNINT_WIDTH (1U) +#define FLEXCAN_ESR1_RWRNINT_SHIFT (16U) +#define FLEXCAN_ESR1_RWRNINT_MASK (1UL << FLEXCAN_ESR1_RWRNINT_SHIFT) +#define FLEXCAN_ESR1_RWRNINT_WIDTH (1U) +#define FLEXCAN_ESR1_BIT1ERR_SHIFT (15U) +#define FLEXCAN_ESR1_BIT1ERR_MASK (1UL << FLEXCAN_ESR1_BIT1ERR_SHIFT) +#define FLEXCAN_ESR1_BIT1ERR_WIDTH (1U) +#define FLEXCAN_ESR1_BIT0ERR_SHIFT (14U) +#define FLEXCAN_ESR1_BIT0ERR_MASK (1UL << FLEXCAN_ESR1_BIT0ERR_SHIFT) +#define FLEXCAN_ESR1_BIT0ERR_WIDTH (1U) +#define FLEXCAN_ESR1_ACKERR_SHIFT (13U) +#define FLEXCAN_ESR1_ACKERR_MASK (1UL << FLEXCAN_ESR1_ACKERR_SHIFT) +#define FLEXCAN_ESR1_ACKERR_WIDTH (1U) +#define FLEXCAN_ESR1_CRCERR_SHIFT (12U) +#define FLEXCAN_ESR1_CRCERR_MASK (1UL << FLEXCAN_ESR1_CRCERR_SHIFT) +#define FLEXCAN_ESR1_CRCERR_WIDTH (1U) +#define FLEXCAN_ESR1_FRMERR_SHIFT (11U) +#define FLEXCAN_ESR1_FRMERR_MASK (1UL << FLEXCAN_ESR1_FRMERR_SHIFT) +#define FLEXCAN_ESR1_FRMERR_WIDTH (1U) +#define FLEXCAN_ESR1_STFERR_SHIFT (10U) +#define FLEXCAN_ESR1_STFERR_MASK (1UL << FLEXCAN_ESR1_STFERR_SHIFT) +#define FLEXCAN_ESR1_STFERR_WIDTH (1U) +#define FLEXCAN_ESR1_TXWRN_SHIFT (9U) +#define FLEXCAN_ESR1_TXWRN_MASK (0x1UL << FLEXCAN_ESR1_TXWRN_SHIFT) +#define FLEXCAN_ESR1_TXWRN_WIDTH (1U) +#define FLEXCAN_ESR1_RXWRN_SHIFT (8U) +#define FLEXCAN_ESR1_RXWRN_MASK (0x1UL << FLEXCAN_ESR1_RXWRN_SHIFT) +#define FLEXCAN_ESR1_RXWRN_WIDTH (1U) +#define FLEXCAN_ESR1_IDLE_SHIFT (7U) +#define FLEXCAN_ESR1_IDLE_MASK (1UL << FLEXCAN_ESR1_IDLE_SHIFT) +#define FLEXCAN_ESR1_IDLE_WIDTH (1U) +#define FLEXCAN_ESR1_TX_SHIFT (6U) +#define FLEXCAN_ESR1_TX_MASK (1UL << FLEXCAN_ESR1_TX_SHIFT) +#define FLEXCAN_ESR1_TX_WIDTH (1U) +#define FLEXCAN_ESR1_FLTCONF_SHIFT (4U) +#define FLEXCAN_ESR1_FLTCONF_MASK (3UL << FLEXCAN_ESR1_FLTCONF_SHIFT) +#define FLEXCAN_ESR1_FLTCONF_WIDTH (2U) +#define FLEXCAN_ESR1_RX_SHIFT (3U) +#define FLEXCAN_ESR1_RX_MASK (1UL << FLEXCAN_ESR1_RX_SHIFT) +#define FLEXCAN_ESR1_RX_WIDTH (1U) +#define FLEXCAN_ESR1_BOFFINT_SHIFT (2U) +#define FLEXCAN_ESR1_BOFFINT_MASK (0x1UL << FLEXCAN_ESR1_BOFFINT_SHIFT) +#define FLEXCAN_ESR1_BOFFINT_WIDTH (1U) +#define FLEXCAN_ESR1_ERRINT_SHIFT (1U) +#define FLEXCAN_ESR1_ERRINT_MASK (0x1UL << FLEXCAN_ESR1_ERRINT_SHIFT) +#define FLEXCAN_ESR1_ERRINT_WIDTH (1U) +#define FLEXCAN_ESR1_WAKINT_SHIFT (0U) +#define FLEXCAN_ESR1_WAKINT_MASK (0x1UL << FLEXCAN_ESR1_WAKINT_SHIFT) +#define FLEXCAN_ESR1_WAKINT_WIDTH (1U) + +/* CTRL2 register */ +#define FLEXCAN_CTRL2_ERRMSKFAST_MASK (0x80000000u) +#define FLEXCAN_CTRL2_ERRMSKFAST_SHIFT (31u) +#define FLEXCAN_CTRL2_ERRMSKFAST_WIDTH (1u) +#define FLEXCAN_CTRL2_BOFFDONEMSK_MASK (0x40000000u) +#define FLEXCAN_CTRL2_BOFFDONEMSK_SHIFT (30u) +#define FLEXCAN_CTRL2_BOFFDONEMSK_WIDTH (1u) +#define FLEXCAN_CTRL2_ECRWRE_SHIFT (29U) +#define FLEXCAN_CTRL2_ECRWRE_MASK (0x1UL << FLEXCAN_CTRL2_ECRWRE_SHIFT) +#define FLEXCAN_CTRL2_ECRWRE_WIDTH (1u) +#define FLEXCAN_CTRL2_WRMFRZ_SHIFT (28U) +#define FLEXCAN_CTRL2_WRMFRZ_MASK (0x1UL << FLEXCAN_CTRL2_WRMFRZ_SHIFT) +#define FLEXCAN_CTRL2_WRMFRZ_WIDTH (1u) +#define FLEXCAN_CTRL2_RFFN_SHIFT (24U) +#define FLEXCAN_CTRL2_RFFN_MASK (0xFUL << FLEXCAN_CTRL2_RFFN_SHIFT) +#define FLEXCAN_CTRL2_RFFN_WIDTH (4U) +#define FLEXCAN_CTRL2_TASD_MASK (0xF80000u) +#define FLEXCAN_CTRL2_TASD_SHIFT (19u) +#define FLEXCAN_CTRL2_TASD_WIDTH (5u) +#define FLEXCAN_CTRL2_MRP_MASK (0x40000u) +#define FLEXCAN_CTRL2_MRP_SHIFT (18u) +#define FLEXCAN_CTRL2_MRP_WIDTH (1u) +#define FLEXCAN_CTRL2_RRS_MASK (0x20000u) +#define FLEXCAN_CTRL2_RRS_SHIFT (17u) +#define FLEXCAN_CTRL2_RRS_WIDTH (1u) +#define FLEXCAN_CTRL2_EACEN_MASK (0x10000u) +#define FLEXCAN_CTRL2_EACEN_SHIFT (16u) +#define FLEXCAN_CTRL2_EACEN_WIDTH (1u) +#define FLEXCAN_CTRL2_TIMERSRC_MASK (0x8000u) +#define FLEXCAN_CTRL2_TIMERSRC_SHIFT (15u) +#define FLEXCAN_CTRL2_TIMERSRC_WIDTH (1u) +#define FLEXCAN_CTRL2_PREXCEN_MASK (0x4000u) +#define FLEXCAN_CTRL2_PREXCEN_SHIFT (14u) +#define FLEXCAN_CTRL2_PREXCEN_WIDTH (1u) +#define FLEXCAN_CTRL2_ISOCANFDEN_SHIFT (12U) +#define FLEXCAN_CTRL2_ISOCANFDEN_MASK (0x1UL << FLEXCAN_CTRL2_ISOCANFDEN_SHIFT) +#define FLEXCAN_CTRL2_ISOCANFDEN_WIDTH (1u) +#define FLEXCAN_CTRL2_EDFLTDIS_MASK (0x800u) +#define FLEXCAN_CTRL2_EDFLTDIS_SHIFT (11u) +#define FLEXCAN_CTRL2_EDFLTDIS_WIDTH (1u) + +/* ESR2 register */ +#define FLEXCAN_ESR2_LPTM_MASK (0x7F0000u) +#define FLEXCAN_ESR2_LPTM_SHIFT (16u) +#define FLEXCAN_ESR2_LPTM_WIDTH (7u) +#define FLEXCAN_ESR2_VPS_MASK (0x4000u) +#define FLEXCAN_ESR2_VPS_SHIFT (14u) +#define FLEXCAN_ESR2_VPS_WIDTH (1u) +#define FLEXCAN_ESR2_IMB_MASK (0x2000u) +#define FLEXCAN_ESR2_IMB_SHIFT (13u) +#define FLEXCAN_ESR2_IMB_WIDTH (1u) + +/* CRCR register */ +#define FLEXCAN_CRCR_MBCRC_MASK (0x7F0000u) +#define FLEXCAN_CRCR_MBCRC_SHIFT (16u) +#define FLEXCAN_CRCR_MBCRC_WIDTH (7u) +#define FLEXCAN_CRCR_TXCRC_MASK (0x7FFFu) +#define FLEXCAN_CRCR_TXCRC_SHIFT (0u) +#define FLEXCAN_CRCR_TXCRC_WIDTH (15u) + +/* RXFGMASK register */ +#define FLEXCAN_RXFGMASK_FGM_MASK (0xFFFFFFFFu) +#define FLEXCAN_RXFGMASK_FGM_SHIFT (0u) +#define FLEXCAN_RXFGMASK_FGM_WIDTH (32u) + +/* RXFIR register */ +#define FLEXCAN_RXFIR_IDHIT_MASK (0x1FFu) +#define FLEXCAN_RXFIR_IDHIT_SHIFT (0u) +#define FLEXCAN_RXFIR_IDHIT_WIDTH (9u) + +/* CBT register */ +#define FLEXCAN_CBT_BTF_SHIFT (31U) +#define FLEXCAN_CBT_BTF_MASK (0x1UL << FLEXCAN_CBT_BTF_SHIFT) +#define FLEXCAN_CBT_BTF_WIDTH (1u) +#define FLEXCAN_CBT_EPRESDIV_SHIFT (21U) +#define FLEXCAN_CBT_EPRESDIV_MASK (0x3FFUL << FLEXCAN_CBT_EPRESDIV_SHIFT) +#define FLEXCAN_CBT_EPRESDIV_WIDTH (10u) +#define FLEXCAN_CBT_ERJW_SHIFT (16U) +#define FLEXCAN_CBT_ERJW_MASK (0x1FUL << FLEXCAN_CBT_ERJW_SHIFT) +#define FLEXCAN_CBT_ERJW_WIDTH (5u) +#define FLEXCAN_CBT_EPROPSEG_SHIFT (10U) +#define FLEXCAN_CBT_EPROPSEG_MASK (0x3FUL << FLEXCAN_CBT_EPROPSEG_SHIFT) +#define FLEXCAN_CBT_EPROPSEG_WIDTH (6u) +#define FLEXCAN_CBT_EPSEG1_SHIFT (5U) +#define FLEXCAN_CBT_EPSEG1_MASK (0x1FUL << FLEXCAN_CBT_EPSEG1_SHIFT) +#define FLEXCAN_CBT_EPSEG1_WIDTH (5u) +#define FLEXCAN_CBT_EPSEG2_SHIFT (0U) +#define FLEXCAN_CBT_EPSEG2_MASK (0x1FUL << FLEXCAN_CBT_EPSEG2_SHIFT) +#define FLEXCAN_CBT_EPSEG2_WIDTH (5u) + +/* IMASK4 register */ +#define FLEXCAN_IMASK4_BUF127TO96M_MASK (0xFFFFFFFFu) +#define FLEXCAN_IMASK4_BUF127TO96M_SHIFT (0u) +#define FLEXCAN_IMASK4_BUF127TO96M_WIDTH (32u) + +/* IMASK3 register */ +#define FLEXCAN_IMASK3_BUF95TO64M_MASK (0xFFFFFFFFu) +#define FLEXCAN_IMASK3_BUF95TO64M_SHIFT (0u) +#define FLEXCAN_IMASK3_BUF95TO64M_WIDTH (32u) + +/* IFLAG4 register */ +#define FLEXCAN_IFLAG4_BUF127TO96_MASK (0xFFFFFFFFu) +#define FLEXCAN_IFLAG4_BUF127TO96_SHIFT (0u) +#define FLEXCAN_IFLAG4_BUF127TO96_WIDTH (32u) + +/* IFLAG3 register */ +#define FLEXCAN_IFLAG3_BUF95TO64_MASK (0xFFFFFFFFu) +#define FLEXCAN_IFLAG3_BUF95TO64_SHIFT (0u) +#define FLEXCAN_IFLAG3_BUF95TO64_WIDTH (32u) + +/* RXIMRN register */ +#define FLEXCAN_RXIMRN_MI_MASK (0xFFFFFFFFu) +#define FLEXCAN_RXIMRN_MI_SHIFT (0u) +#define FLEXCAN_RXIMRN_MI_WIDTH (32u) + +/* MECR register */ +#define FLEXCAN_MECR_ECRWRDIS_SHIFT (31U) +#define FLEXCAN_MECR_ECRWRDIS_MASK (0x1UL << FLEXCAN_MECR_ECRWRDIS_SHIFT) +#define FLEXCAN_MECR_ECRWRDIS_WIDTH (1u) +#define FLEXCAN_MECR_HANCEIMSK_MASK (0x80000u) +#define FLEXCAN_MECR_HANCEIMSK_SHIFT (19u) +#define FLEXCAN_MECR_HANCEIMSK_WIDTH (1u) +#define FLEXCAN_MECR_FANCEIMSK_MASK (0x40000u) +#define FLEXCAN_MECR_FANCEIMSK_SHIFT (18u) +#define FLEXCAN_MECR_FANCEIMSK_WIDTH (1u) +#define FLEXCAN_MECR_CEIMSK_MASK (0x10000u) +#define FLEXCAN_MECR_CEIMSK_SHIFT (16u) +#define FLEXCAN_MECR_CEIMSK_WIDTH (1u) +#define FLEXCAN_MECR_HAERRIE_MASK (0x8000u) +#define FLEXCAN_MECR_HAERRIE_SHIFT (15u) +#define FLEXCAN_MECR_HAERRIE_WIDTH (1u) +#define FLEXCAN_MECR_FAERRIE_MASK (0x4000u) +#define FLEXCAN_MECR_FAERRIE_SHIFT (14u) +#define FLEXCAN_MECR_FAERRIE_WIDTH (1u) +#define FLEXCAN_MECR_EXTERRIE_MASK (0x2000u) +#define FLEXCAN_MECR_EXTERRIE_SHIFT (13u) +#define FLEXCAN_MECR_EXTERRIE_WIDTH (1u) +#define FLEXCAN_MECR_RERRDIS_MASK (0x200u) +#define FLEXCAN_MECR_RERRDIS_SHIFT (9u) +#define FLEXCAN_MECR_RERRDIS_WIDTH (1u) +#define FLEXCAN_MECR_ECCDIS_SHIFT (8U) +#define FLEXCAN_MECR_ECCDIS_MASK (0x1UL << FLEXCAN_MECR_ECCDIS_SHIFT) +#define FLEXCAN_MECR_ECCDIS_WIDTH (1u) +#define FLEXCAN_MECR_NCEFAFRZ_SHIFT (7U) +#define FLEXCAN_MECR_NCEFAFRZ_MASK (0x1UL << FLEXCAN_MECR_NCEFAFRZ_SHIFT) +#define FLEXCAN_MECR_NCEFAFRZ_WIDTH (1u) + +/* FDCTRL register */ +#define FLEXCAN_FDCTRL_FDRATE_SHIFT (31U) +#define FLEXCAN_FDCTRL_FDRATE_MASK (0x1UL << FLEXCAN_FDCTRL_FDRATE_SHIFT) +#define FLEXCAN_FDCTRL_FDRATE_WIDTH (1u) +#define FLEXCAN_FDCTRL_MBDSR3_SHIFT (25U) +#define FLEXCAN_FDCTRL_MBDSR3_MASK (0x3UL << FLEXCAN_FDCTRL_MBDSR3_SHIFT) +#define FLEXCAN_FDCTRL_MBDSR3_WIDTH (2u) +#define FLEXCAN_FDCTRL_MBDSR2_SHIFT (22U) +#define FLEXCAN_FDCTRL_MBDSR2_MASK (0x3UL << FLEXCAN_FDCTRL_MBDSR2_SHIFT) +#define FLEXCAN_FDCTRL_MBDSR2_WIDTH (2u) +#define FLEXCAN_FDCTRL_MBDSR1_SHIFT (19U) +#define FLEXCAN_FDCTRL_MBDSR1_MASK (0x3UL << FLEXCAN_FDCTRL_MBDSR1_SHIFT) +#define FLEXCAN_FDCTRL_MBDSR1_WIDTH (2u) +#define FLEXCAN_FDCTRL_MBDSR0_SHIFT (16U) +#define FLEXCAN_FDCTRL_MBDSR0_MASK (0x3UL << FLEXCAN_FDCTRL_MBDSR0_SHIFT) +#define FLEXCAN_FDCTRL_MBDSR0_WIDTH (2u) +#define FLEXCAN_FDCTRL_TDCEN_SHIFT (15U) +#define FLEXCAN_FDCTRL_TDCEN_MASK (0x1UL << FLEXCAN_FDCTRL_TDCEN_SHIFT) +#define FLEXCAN_FDCTRL_TDCEN_WIDTH (1u) +#define FLEXCAN_FDCTRL_TDCFAIL_MASK (0x4000u) +#define FLEXCAN_FDCTRL_TDCFAIL_SHIFT (14u) +#define FLEXCAN_FDCTRL_TDCFAIL_WIDTH (1u) +#define FLEXCAN_FDCTRL_TDCOFF_SHIFT (8U) +#define FLEXCAN_FDCTRL_TDCOFF_MASK (0x1FUL << FLEXCAN_FDCTRL_TDCOFF_SHIFT) +#define FLEXCAN_FDCTRL_TDCOFF_WIDTH (5u) +#define FLEXCAN_FDCTRL_TDCVAL_MASK (0x3Fu) +#define FLEXCAN_FDCTRL_TDCVAL_SHIFT (0u) +#define FLEXCAN_FDCTRL_TDCVAL_WIDTH (6u) + +/* FDCBT register */ +#define FLEXCAN_FDCBT_FPRESDIV_SHIFT (20U) +#define FLEXCAN_FDCBT_FPRESDIV_MASK (0x3FFUL << FLEXCAN_FDCBT_FPRESDIV_SHIFT) +#define FLEXCAN_FDCBT_FPRESDIV_WIDTH (10u) +#define FLEXCAN_FDCBT_FRJW_SHIFT (16U) +#define FLEXCAN_FDCBT_FRJW_MASK (0x7UL << FLEXCAN_FDCBT_FRJW_SHIFT) +#define FLEXCAN_FDCBT_FPJW_WIDTH (3u) +#define FLEXCAN_FDCBT_FPROPSEG_SHIFT (10U) +#define FLEXCAN_FDCBT_FPROPSEG_MASK (0x1FUL << FLEXCAN_FDCBT_FPROPSEG_SHIFT) +#define FLEXCAN_FDCBT_FPROPSEG_WIDTH (5u) +#define FLEXCAN_FDCBT_FPSEG1_SHIFT (5U) +#define FLEXCAN_FDCBT_FPSEG1_MASK (0x7UL << FLEXCAN_FDCBT_FPSEG1_SHIFT) +#define FLEXCAN_FDCBT_FPSEG1_WIDTH (3u) +#define FLEXCAN_FDCBT_FPSEG2_SHIFT (0U) +#define FLEXCAN_FDCBT_FPSEG2_MASK (0x7UL << FLEXCAN_FDCBT_FPSEG2_SHIFT) +#define FLEXCAN_FDCBT_FPSEG2_WIDTH (3u) + +/* FDCRC register */ +#define CAN_FDCRC_FDMBCRC_MASK (0x7F000000u) +#define CAN_FDCRC_FDMBCRC_SHIFT (24u) +#define CAN_FDCRC_FDMBCRC_WIDTH (7u) +#define CAN_FDCRC_FDTXCRC_MASK (0x1FFFFFu) +#define CAN_FDCRC_FDTXCRC_SHIFT (0u) +#define CAN_FDCRC_FDTXCRC_WIDTH (21u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of FLEXCAN registers + */ +typedef struct _FlexCanRegType_ +{ + volatile uint32_t MCR; /*!< module configuration register, offset: 0000H */ + volatile uint32_t CTRL1; /*!< control1 register, offset: 0004H */ + volatile uint32_t TIMER; /*!< free running timer register, offset: 0008H */ + volatile uint32_t REVERSED0; /*!< resverd register, offset: 000CH */ + volatile uint32_t RXMGMASK; /*!< rx mailbox global mask register, offset: 0010H */ + volatile uint32_t RX14MASK; /*!< rx 14 mask register, offset: 0014H */ + volatile uint32_t RX15MASK; /*!< rx 15 mask register, offset: 0018H */ + volatile uint32_t ECR; /*!< error countner register, offset: 001CH */ + volatile uint32_t ESR1; /*!< error and status 1 register, offset: 0020H */ + volatile uint32_t IMASK2; /*!< interrupt mask 2 register, offset: 0024H */ + volatile uint32_t IMASK1; /*!< interrupt mask 1 register, offset: 0028H */ + volatile uint32_t IFLAG2; /*!< interrupt flags 2 register, offset: 002CH */ + volatile uint32_t IFLAG1; /*!< interrupt flags 1 register, offset: 0030H */ + volatile uint32_t CTRL2; /*!< control 2 register, offset: 0034H */ + volatile uint32_t ESR2; /*!< error and status 2 register, offset: 0038H */ + volatile uint32_t REVERSED1[2]; /*!< reversed register, offset: 003CH */ + volatile uint32_t CRCR; /*!< crc register, offset: 0044H */ + volatile uint32_t RXFGMASK; /*!< rx fifo global mask register, offset: 0048H */ + volatile uint32_t RXFIR; /*!< rx fifo information register, offset: 004CH */ + volatile uint32_t CBT; /*!< CAN bit timing register, offset: 0050H */ + volatile uint32_t REVERSED2[5]; /*!< reversed register, offset: 0054H */ + volatile uint32_t IMASK4; /*!< interrupt mask 4 register, offset: 0068H */ + volatile uint32_t IMASK3; /*!< interrupt mask 3 register, offset: 006CH */ + volatile uint32_t IFLAG4; /*!< interrupt flags 4 register, offset: 0070H */ + volatile uint32_t IFLAG3; /*!< interrupt flags 3 register, offset: 0074H */ + volatile uint32_t REVERSED3[2]; /*!< reversed registers, offset: 0078H */ + volatile uint32_t MSGBUF[256]; /*!< message buffers, offset: 0080H */ + volatile uint32_t REVERSED4[256]; /*!< Reserved register, offset: 0x480 */ + volatile uint32_t RXIMR[64]; /*!< rx individual mask registers, offset: 0880H */ + volatile uint32_t REVERSED5[88]; /*!< reversed register, offset: 0980H */ + volatile uint32_t MECR; /*!< memory error control register, offset: 0AE0H */ + volatile uint32_t ERRIAR; /*!< error injection address register, offset: 0AE4H */ + volatile uint32_t ERRIDPR; /*!< error injection data pattern register, offset: 0AE8H */ + volatile uint32_t ERRIPPR; /*!< error injection parity pattern register, offset: 0AECH */ + volatile uint32_t RERRAR; /*!< error report address register, offset: 0AF0H */ + volatile uint32_t RERRDR; /*!< error report data register, offset: 0AF4H */ + volatile uint32_t RERRSYNR; /*!< error report syndrome register, offset: 0AF8H */ + volatile uint32_t ERRSR; /*!< error status register, offset: 0AFCH */ + volatile uint32_t CTRL1_PN; /*!< pretended networking control 1 register, offset: 0B00H */ + volatile uint32_t CTRL2_PN; /*!< pretended networking control 2 register, offset: 0B04H */ + volatile uint32_t WU_MTC; /*!< pretended networking wake up match register, offset: 0B08H */ + volatile uint32_t FLT_ID1; /*!< pretended networking ID filter 1 register, offset: 0B0CH */ + volatile uint32_t FLT_DLC; /*!< pretended networking DLC filter register, offset: 0B10H */ + volatile uint32_t PL1_LO; /*!< pretended networking payload low filter 1 register, offset: 0B14H */ + volatile uint32_t PL1_HI; /*!< pretended networking payload high filter 1 register, offset: 0B18H */ + volatile uint32_t FLT_ID2_IDMASK; /*!< pretended networking ID filter 2 register / ID mask register, offset: 0B1CH */ + volatile uint32_t PL2_PLMASK_LO; /*!< pretended networking payload low filter 2 register / payload low mask register, offset: 0B20H */ + volatile uint32_t PL2_PLMASK_HI; /*!< pretended networking payload high filter 2 high order bits / payload high mask register, offset: 0B24H */ + volatile uint32_t REVERSED6[6]; /*!< reversed registers, offset: 0B28H */ + volatile uint32_t WMB0_CS; /*!< wakeup message buffer 0 register for C/S, offset: 0B40H */ + volatile uint32_t WMB0_ID; /*!< wakeup message buffer 0 register for ID, offset: 0B44H */ + volatile uint32_t WMB0_D03; /*!< wakeup message buffer 0 register for data 0 - 3, offset: 0B48H */ + volatile uint32_t WMB0_D47; /*!< wakeup message buffer 0 register for data 4 - 7, offset: 0B4CH */ + volatile uint32_t WMB1_CS; /*!< wakeup message buffer 1 register for C/S, offset: 0B50H */ + volatile uint32_t WMB1_ID; /*!< wakeup message buffer 1 register for ID, offset: 0B54H */ + volatile uint32_t WMB1_D03; /*!< wakeup message buffer 1 register for data 0 - 3, offset: 0B58H */ + volatile uint32_t WMB1_D47; /*!< wakeup message buffer 1 register for data 4 - 7, offest: 0B5CH */ + volatile uint32_t WMB2_CS; /*!< wakeup message buffer 2 register for C/S, offset: 0B60H */ + volatile uint32_t WMB2_ID; /*!< wakeup message buffer 2 register for ID, offset: 0B64H */ + volatile uint32_t WMB2_D03; /*!< wakeup message buffer 2 register for data 0 - 3, offset: 0B68H */ + volatile uint32_t WMB2_D47; /*!< wakeup message buffer 2 register for data 4 - 7, offest: 0B6CH */ + volatile uint32_t WMB3_CS; /*!< wakeup message buffer 3 register for C/S, offset: 0B70H */ + volatile uint32_t WMB3_ID; /*!< wakeup message buffer 3 register for ID, offset: 0B74H */ + volatile uint32_t WMB3_D03; /*!< wakeup message buffer 3 register for data 0 - 3, offset: 0B78H */ + volatile uint32_t WMB3_D47; /*!< wakeup message buffer 3 register for data 4 - 7, offest: 0B7CH */ + volatile uint32_t REVERSED7[32]; /*!< reversed registers, offset: 0B80H */ + volatile uint32_t FDCTRL; /*!< CAN FD control register, offset: 0C00H */ + volatile uint32_t FDCBT; /*!< CAN FD bit timing register, offset: 0C04H */ + volatile uint32_t FDCRC; /*!< CAN FD CRC register, offset: 0C08H */ +} FlexCanRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ +/*! \brief Get FlexCAN module message buffer start address + * + * \param[in] obj : pointer to FlexCAN register instance + * \return module message buffer start address + */ +__attribute__((always_inline)) static inline uint32_t FlexCanReg_GetMsgBufferStartAddr(FlexCanRegType *obj) +{ + return (uint32_t)(&obj->MSGBUF[0]); +} + +/*! \brief Get FlexCAN module disable status + * + * \param[in] obj : pointer to FlexCAN register instance + * \return module disable status + * -0b: enable the FlexCAN module + * -1b: disable the FlexCAN module + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetModuleDisable(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_MDIS_MASK) >> FLEXCAN_MCR_MDIS_SHIFT); +} + +/*! \brief Set FlexCAN module enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : module enable + * -0b: enable the FlexCAN module + * -1b: disable the FlexCAN module + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetModuleDisable(FlexCanRegType *obj, uint8_t isDisable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_MDIS_MASK); + tempReg |= (((uint32_t)isDisable) << FLEXCAN_MCR_MDIS_SHIFT) & FLEXCAN_MCR_MDIS_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get freeze mode + * + * \param[in] obj : pointer to FlexCAN register instance + * \return freeze mode + * -0b: not enabled to enter freeze mode + * -1b: enabled to enter freeze mode + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFreezeMode(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_FRZ_MASK) >> FLEXCAN_MCR_FRZ_SHIFT); +} + +/*! \brief Set freeze mode + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] frzModeReq : freeze mode request + * -0b: not enabled to enter freeze mode + * -1b: enabled to enter freeze mode + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetFreezeMode(FlexCanRegType *obj, uint8_t frzModeReq) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_FRZ_MASK); + tempReg |= (((uint32_t)frzModeReq) << FLEXCAN_MCR_FRZ_SHIFT) & FLEXCAN_MCR_FRZ_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get Rx FIFO enable status + * + * \param[in] obj : pointer to flexCAN register instance + * \return freeze mode + * -0b: Rx FIFO not enable + * -1b: Rx FIFO enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetRxFIFOEnable(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_RFEN_MASK) >> FLEXCAN_MCR_RFEN_SHIFT); +} + +/*! \brief Set Rx FIFO enable status + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] fifoEnable : rx FIFO enable status + * -0b: Rx FIFO not enable + * -1b: Rx FIFO enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRxFIFOEnalbe(FlexCanRegType *obj, uint8_t fifoEnable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_RFEN_MASK); + tempReg |= (((uint32_t)fifoEnable) << FLEXCAN_MCR_RFEN_SHIFT) & FLEXCAN_MCR_RFEN_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get halt mode + * + * \param[in] obj : pointer to flexCAN register instance + * \return halt mode + * -0b: request halt mode + * -1b: no halt mode reuqest + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetHaltMode(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_HALT_MASK) >> FLEXCAN_MCR_HALT_SHIFT); +} + +/*! \brief Set halt mode + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] haltModeReq : halt mode request + * -0b: request halt mode + * -1b: no halt mode reuqest + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetHaltMode(FlexCanRegType *obj, uint8_t haltModeReq) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_HALT_MASK); + tempReg |= (((uint32_t)haltModeReq) << FLEXCAN_MCR_HALT_SHIFT) & FLEXCAN_MCR_HALT_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get not ready flag + * + * \param[in] obj : pointer to flexCAN register instance + * \return not ready flag + * -0b: FlexCAN is either in normal, listen-only, or loop-back mode + * -1b: FlexCAN is either in module disable, doze, stop, or freeze mode + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetNotReadyFlag(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_NOTRDY_MASK) >> FLEXCAN_MCR_NOTRDY_SHIFT); +} + +/*! \brief Get wakeup interrupt mask + * + * \param[in] obj : pointer to flexCAN register instance + * \return wakeup interrupt mask + * -0b: disable wakeup interrupt + * -1b: enable wakeup interrupt + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetWakupIntMask(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_WAKMSK_MASK) >> FLEXCAN_MCR_WAKMSK_SHIFT); +} + +/*! \brief Set wakeup interrupt mask + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] enable : wakeup interrupt mask enable + * -0b: disable wakeup interrupt + * -1b: enable wakeup interrupt + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetWakeupIntMask(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_WAKMSK_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_MCR_WAKMSK_SHIFT) & FLEXCAN_MCR_WAKMSK_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get soft reset request + * + * \param[in] obj : pointer to flexCAN register instance + * \return soft reset request + * -0b: reset the registers affected by soft reset + * -1b: no reset request + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetSoftResetRequest(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_SOFTRST_MASK) >> FLEXCAN_MCR_SOFTRST_SHIFT); +} + +/*! \brief Set soft reset request + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] enable : soft reset request + * -0b : reset the registers affected by soft reset + * -1b : no reset request + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetSoftResetRequest(FlexCanRegType *obj, uint8_t softRstReq) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_SOFTRST_MASK); + tempReg |= (((uint32_t)softRstReq) << FLEXCAN_MCR_SOFTRST_SHIFT) & FLEXCAN_MCR_SOFTRST_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get freeze mode acknowledge + * + * \param[in] obj : pointer to flexCAN register instance + * \return freeze mode acknowledge + * -0b : FlexCAN not in freeze mode, prescaler running + * -1b : FlexCAN in freeze mode, prescaler stopped + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFreezeAck(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_FRZACK_MASK) >> FLEXCAN_MCR_FRZACK_SHIFT); +} + +/*! \brief Get FlexCAN access mode + * + * \param[in] obj : pointer to flexCAN register instance + * \return access mode + * -0b : FlexCAN is in user mode, affected registers allow both + * supervisor and unrestricted access + * -1b : FlexCAN is in supervisor mode. Affected registers allow + * only supervisor access. Unrestricted access behaves as + * though the access was done to an unnimplemented register + * location. + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetAccessMode(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_SUPV_MASK) >> FLEXCAN_MCR_SUPV_SHIFT); +} + +/*! \brief Set FlexCAN access mode + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] accMode : access mode + * -0b : FlexCAN is in user mode, affected registers allow both + * supervisor and unrestricted access + * -1b : FlexCAN is in supervisor mode. Affected registers allow + * only supervisor access. Unrestricted access behaves as + * though the access was done to an unimplemented register + * location. + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetAccessMode(FlexCanRegType *obj, uint8_t accMode) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_SUPV_MASK); + tempReg |= (((uint32_t)accMode) << FLEXCAN_MCR_SUPV_SHIFT) & FLEXCAN_MCR_SUPV_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get self wakeup enable + * + * \param[in] obj : pointer to flexCAN register instance + * \return self wakeup enable + * -0b : Disable FlexCAN self wakeup feature + * -1b : Enable FlexCAN self wakeup feature + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetSelfWakeupEnable(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_SLFWAK_MASK) >> FLEXCAN_MCR_SLFWAK_SHIFT); +} + +/*! \brief Get self wakeup enable + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] enable : self wakeup enable + * -0b : Disable FlexCAN self wakeup feature + * -1b : Enable FlexCAN self wakeup feature + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetSelfWakeupEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_SLFWAK_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_MCR_SLFWAK_SHIFT) & FLEXCAN_MCR_SLFWAK_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get self warning interrupt enable + * + * \param[in] obj : pointer to flexCAN register instance + * \return warning interrupt enable + * -0b : warning interrupt not enable + * -1b : warning interrupt enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetWarningIntEnable(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_WRNEN_MASK) >> FLEXCAN_MCR_WRNEN_SHIFT); +} + +/*! \brief Set self warning interrupt enable + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] enable : warning interrupt enable + * -0b : warning interrupt not enable + * -1b : warning interrupt enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetWarningIntEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_WRNEN_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_MCR_WRNEN_SHIFT) & FLEXCAN_MCR_WRNEN_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get low power mode acknowledge + * + * \param[in] obj : pointer to FlexCAN register instance + * \return low power mode acknowledge + * -0b : FlexCAN is not in a low power mode + * -1b : FlexCAN is in a low power mode + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetLowPowerAck(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_LPMACK_MASK) >> FLEXCAN_MCR_LPMACK_SHIFT); +} + +/*! \brief Get wake up source + * + * \param[in] obj : pointer to FlexCAN register instance + * \return wake up source + * -0b : FlexCAN uses the unfiltered Rx input to detect recessive-to-dominant edges on the CAN bus + * -1b : FlexCAN uses the filtered Rx input to detect recessive-to-dominant edges on the CAN bus + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetWakeupSource(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_WAKSRC_MASK) >> FLEXCAN_MCR_WAKSRC_SHIFT); +} + +/*! \brief Set wake up source + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] enable : wake up source + * -0b : FlexCAN uses the unfiltered Rx input to detect recessive-to-dominant edges on the CAN bus + * -1b : FlexCAN uses the filtered Rx input to detect recessive-to-dominant edges on the CAN bus + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetWakeupSource(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_WAKSRC_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_MCR_WAKSRC_SHIFT) & FLEXCAN_MCR_WAKSRC_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get doze mode enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return doze mode enable + * -0b : FlexCAN is not enabled to enter low-power mode when Doze mode is request + * -1b : FlexCAN is enabled to enter low-power mode when Doze mode is request + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetDozeMode(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_DOZE_MASK) >> FLEXCAN_MCR_DOZE_SHIFT); +} + +/*! \brief Set doze mode enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : doze mode enable + * -0b : FlexCAN is not enabled to enter low-power mode when Doze mode is request + * -1b : FlexCAN is enabled to enter low-power mode when Doze mode is request + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetDozeMode(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_DOZE_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_MCR_DOZE_SHIFT) & FLEXCAN_MCR_DOZE_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get self reception + * + * \param[in] obj : pointer to FlexCAN register instance + * \return self reception enable + * -0b : self reception enable + * -1b : self reception disable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetSelfReceptionDisable(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_SRXDIS_MASK) >> FLEXCAN_MCR_SRXDIS_SHIFT); +} + +/*! \brief Set self reception + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] isDisable : self reception enable + * -0b : self reception enable + * -1b : self reception disable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetSelfReceptionDisable(FlexCanRegType *obj, uint8_t isDisable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_SRXDIS_MASK); + tempReg |= (((uint32_t)isDisable) << FLEXCAN_MCR_SRXDIS_SHIFT) & FLEXCAN_MCR_SRXDIS_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Set rx individual mask + * + * \param[in] obj : pointer to FlexCAN register instance + * \return individual mask enable + * -0b : individual mask disable + * -1b : individual mask enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetIndividualMaskEnable(const FlexCanRegType *obj) +{ + return ((obj->MCR & FLEXCAN_MCR_IRQM_MASK) >> FLEXCAN_MCR_IRQM_SHIFT); +} + +/*! \brief Set rx individual mask + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : individual mask enable + * -0b : individual mask disable + * -1b : individual mask enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetIndividualMaskEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_IRQM_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_MCR_IRQM_SHIFT) & FLEXCAN_MCR_IRQM_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get rx fifo dma enable or disable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return rx fifo dma enable + * -0b : rx fifo dma disable + * -1b : rx fifo dma enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetRxFIFODmaEnable(const FlexCanRegType *obj) +{ + return ((obj->MCR & FLEXCAN_MCR_DMA_MASK) >> FLEXCAN_MCR_DMA_SHIFT); +} + +/*! \brief Set rx fifo dma enable or disable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : rx fifo dma enable + * -0b : rx fifo dma disable + * -1b : rx fifo dma enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRxFIFODmaEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_DMA_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_MCR_DMA_SHIFT) & FLEXCAN_MCR_DMA_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get local priority enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return local priority enable + * -0b : local priority disable + * -1b : local priority enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetMcrLprioen(const FlexCanRegType *obj) +{ + return ((obj->MCR & FLEXCAN_MCR_LPRIOEN_MASK) >> FLEXCAN_MCR_LPRIOEN_SHIFT); +} + +/*! \brief Set local priority enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : local priority enable + * -0b : local priority disable + * -1b : local priority enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetMcrLprioen(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MCR; + + tmp &= ~FLEXCAN_MCR_LPRIOEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_MCR_LPRIOEN_SHIFT)) & FLEXCAN_MCR_LPRIOEN_MASK); + obj->MCR = tmp; +} + +/*! \brief Get Tx message pending abort mechanism enable + * + * \param[in] obj : pointer to flexCAN register instance + * \return Tx message pending abort mechanism enable + * -0b: disable abort + * -1b: enable abort + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetTxAbortEnable(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_AEN_MASK) >> FLEXCAN_MCR_AEN_SHIFT); +} + +/*! \brief Set Tx message pending abort mechanism enable + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] enable : Tx message pending abort mechanism enable + * -0b: disable abort + * -1b: enable abort + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetTxAbortEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_AEN_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_MCR_AEN_SHIFT) & FLEXCAN_MCR_AEN_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get CAN FD operation enable + * + * \param[in] obj : pointer to flexCAN register instance + * \return CAN FD operation enable + * -0b: CAN FD operation enable + * -1b: CAN FD operation disable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFdEnable(const FlexCanRegType *obj) +{ + return ((obj->MCR & FLEXCAN_MCR_FDEN_MASK) >> FLEXCAN_MCR_FDEN_SHIFT); +} + +/*! \brief Set CAN FD operation enable + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] enable : CAN FD operation enable + * -0b: CAN FD operation enable + * -1b: CAN FD operation disable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetFdEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_FDEN_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_MCR_FDEN_SHIFT) & FLEXCAN_MCR_FDEN_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Set Rx FIFO ID filter acceptance mode + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : Rx FIFO ID filter acceptance mode + * -0h : Format A One full ID (standard and extended) per + * ID filter table element + * -1h : Format B Two full standard IDs or two partial 14-bit + * (standard and extended) IDs per ID filter table element + * -2h : Format C Four partial 8-bit standard IDs per ID filter + * table element + * -3h : Format D All frames rejected + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRxFifoFiltMode(FlexCanRegType *obj, uint8_t val) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_IDAM_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_MCR_IDAM_SHIFT) & FLEXCAN_MCR_IDAM_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get Rx FIFO ID filter acceptance mode + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: Rx FIFO ID filter acceptance mode + * -0h : Format A One full ID (standard and extended) per + * ID filter table element + * -1h : Format B Two full standard IDs or two partial 14-bit + * (standard and extended) IDs per ID filter table element + * -2h : Format C Four partial 8-bit standard IDs per ID filter + * table element + * -3h : Format D All frames rejected + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetRxFifoFiltMode(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->MCR) & FLEXCAN_MCR_IDAM_MASK) >> FLEXCAN_MCR_IDAM_SHIFT); +} + +/*! \brief Get number of the last message buffer + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: number of the last message buffer + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetMcrMaxmb(const FlexCanRegType *obj) +{ + return ((obj->MCR & FLEXCAN_MCR_MAXMB_MASK) >> FLEXCAN_MCR_MAXMB_SHIFT); +} + +/*! \brief Set number of the last message buffer + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] maxNum : number of the last message buffer + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetMaxMsgBufferNum(FlexCanRegType *obj, uint8_t maxNum) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_MAXMB_MASK); + tempReg |= (((uint32_t)maxNum) << FLEXCAN_MCR_MAXMB_SHIFT) & FLEXCAN_MCR_MAXMB_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get prescaler division factor + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: prescaler division factor + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl1Presdiv(const FlexCanRegType *obj) +{ + return ((obj->CTRL1 & FLEXCAN_CTRL1_PRESDIV_MASK) >> FLEXCAN_CTRL1_PRESDIV_SHIFT); +} + +/*! \brief Set prescaler division factor + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : prescaler division factor + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl1Presdiv(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL1; + + tmp &= ~FLEXCAN_CTRL1_PRESDIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL1_PRESDIV_SHIFT)) & FLEXCAN_CTRL1_PRESDIV_MASK); + obj->CTRL1 = tmp; +} + +/*! \brief Get resync jump width + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: resync jump width + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl1Rjw(const FlexCanRegType *obj) +{ + return ((obj->CTRL1 & FLEXCAN_CTRL1_RJW_MASK) >> FLEXCAN_CTRL1_RJW_SHIFT); +} + +/*! \brief Set resync jump width + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : resync jump width + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl1Rjw(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL1; + + tmp &= ~FLEXCAN_CTRL1_RJW_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL1_RJW_SHIFT)) & FLEXCAN_CTRL1_RJW_MASK); + obj->CTRL1 = tmp; +} + +/*! \brief Get phase segment 1 + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: phase segment 1 + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl1Pseg1(const FlexCanRegType *obj) +{ + return ((obj->CTRL1 & FLEXCAN_CTRL1_PSEG1_MASK) >> FLEXCAN_CTRL1_PSEG1_SHIFT); +} + +/*! \brief Set phase segment 1 + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : phase segment 1 + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl1Pseg1(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL1; + + tmp &= ~FLEXCAN_CTRL1_PSEG1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL1_PSEG1_SHIFT)) & FLEXCAN_CTRL1_PSEG1_MASK); + obj->CTRL1 = tmp; +} + +/*! \brief Get phase segment 2 + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: phase segment 2 + */ +__attribute__((always_inline)) static inline uint8_t CanReg_GetCtrl1Pseg2(const FlexCanRegType *obj) +{ + return ((obj->CTRL1 & FLEXCAN_CTRL1_PSEG2_MASK) >> FLEXCAN_CTRL1_PSEG2_SHIFT); +} + +/*! \brief Set phase segment 2 + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : phase segment 2 + */ +__attribute__((always_inline)) static inline void CanReg_SetCtrl1Pseg2(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL1; + + tmp &= ~FLEXCAN_CTRL1_PSEG2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL1_PSEG2_SHIFT)) & FLEXCAN_CTRL1_PSEG2_MASK); + obj->CTRL1 = tmp; +} + +/*! \brief Set bus off interrupt enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : bus off interrupt enable + * -0b : bus off interrupt disabled + * -1b : bus off interrupt enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetBusOffIntEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_BOFFMSK_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL1_BOFFMSK_SHIFT) & FLEXCAN_CTRL1_BOFFMSK_MASK; + + obj->CTRL1 = tempReg; +} + +/*! \brief Get bus off interrupt enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: bus off interrupt enable + * -0b : bus off interrupt disabled + * -1b : bus off interrupt enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetBusOffIntEnable(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->CTRL1) & FLEXCAN_CTRL1_BOFFMSK_MASK) >> FLEXCAN_CTRL1_BOFFMSK_SHIFT); +} + +/*! \brief Set error interrupt enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : error interrupt enable + * -0b : error interrupt disabled + * -1b : error interrupt enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetErrorIntEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_ERRMSK_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL1_ERRMSK_SHIFT) & FLEXCAN_CTRL1_ERRMSK_MASK; + + obj->CTRL1 = tempReg; +} + +/*! \brief Get error interrupt enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: error interrupt enable + * -0b : error interrupt disabled + * -1b : error interrupt enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetErrorIntEnable(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->CTRL1) & FLEXCAN_CTRL1_ERRMSK_MASK) >> FLEXCAN_CTRL1_ERRMSK_SHIFT); +} + +/*! \brief Get module clock source + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: module clock source + * -0b : The PE clock source is the oscillator clock. + * -1b : The PE clock source is the peripheral clock. + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetClockSource(const FlexCanRegType *obj) +{ + return ((obj->CTRL1 & FLEXCAN_CTRL1_CLKSRC_MASK) >> FLEXCAN_CTRL1_CLKSRC_SHIFT); +} + +/*! \brief Selects the clock source to the PE submodule to be either the peripheral clock or the oscillator clock + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] clkSrc : + * 0b - The PE clock source is the oscillator clock. + * 1b - The PE clock source is the peripheral clock. + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetClockSource(FlexCanRegType *obj, uint8_t clkSrc) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_CLKSRC_MASK); + tempReg |= (((uint32_t)clkSrc) << FLEXCAN_CTRL1_CLKSRC_SHIFT) & FLEXCAN_CTRL1_CLKSRC_MASK; + + obj->CTRL1 = tempReg; +} + +/*! \brief Get can loop back mode + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: can loop back mode + * 0b - disable + * 1b - enable + */ +__attribute__((always_inline)) static inline uint8_t CanReg_GetLoopbackMode(const FlexCanRegType *obj) +{ + return ((obj->CTRL1 & FLEXCAN_CTRL1_LPB_MASK) >> FLEXCAN_CTRL1_LPB_SHIFT); +} + +/*! \brief Set can loop back mode + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : loop back mode feature select + * 0b - disable + * 1b - enable + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetLoopbackMode(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_LPB_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL1_LPB_SHIFT) & FLEXCAN_CTRL1_LPB_MASK; + + obj->CTRL1 = tempReg; +} + +/*! \brief Set tx warning interrupt enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : tx warning interrupt enable + * -0b : tx warning interrupt disabled + * -1b : tx warning interrupt enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetTxWarnIntEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_TWRNMSK_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL1_TWRNMSK_SHIFT) & FLEXCAN_CTRL1_TWRNMSK_MASK; + + obj->CTRL1 = tempReg; +} + +/*! \brief Get tx warning interrupt enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: tx warning interrupt enable + * -0b : tx warning interrupt disabled + * -1b : tx warning interrupt enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetTxWarnIntEnable(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->CTRL1) & FLEXCAN_CTRL1_TWRNMSK_MASK) >> FLEXCAN_CTRL1_TWRNMSK_SHIFT); +} + +/*! \brief Set rx warning interrupt enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : rx warning interrupt enable + * -0b : rx warning interrupt disabled + * -1b : rx warning interrupt enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRxWarnIntEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_RWRNMSK_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL1_RWRNMSK_SHIFT) & FLEXCAN_CTRL1_RWRNMSK_MASK; + + obj->CTRL1 = tempReg; +} + +/*! \brief Get rx warning interrupt enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: rx warning interrupt enable + * -0b : rx warning interrupt disabled + * -1b : rx warning interrupt enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetRxWarnIntEnable(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->CTRL1) & FLEXCAN_CTRL1_RWRNMSK_MASK) >> FLEXCAN_CTRL1_RWRNMSK_SHIFT); +} + +/*! \brief Get CAN bit sampling mode + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: CAN bit sampling mode + * -0b : one sample is used to determine the bit value + * -1b : three samples are used to determine the value of the received bit + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetBitSamplingType(const FlexCanRegType *obj) +{ + return ((obj->CTRL1 & FLEXCAN_CTRL1_SMP_MASK) >> FLEXCAN_CTRL1_SMP_SHIFT); +} + +/*! \brief Set CAN bit sampling mode + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] threeSamplingEn : can bit sampling + * -0b : one sample is used to determine the bit value + * -1b : three samples are used to determine the value of the received bit + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetBitSamplingType(FlexCanRegType *obj, uint8_t threeSamplingEn) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_SMP_MASK); + tempReg |= (((uint32_t)threeSamplingEn) << FLEXCAN_CTRL1_SMP_SHIFT) & FLEXCAN_CTRL1_SMP_MASK; + + obj->CTRL1 = tempReg; +} + +/*! \brief Set bus off automatic recovering enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : bus off automatic recovering enable + * -1b : bus off automatic recovering disabled + * -0b : bus off automatic recovering enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetBusOffRecEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_BOFFREC_MASK); + if(enable == true) + { + tempReg |= (((uint32_t)0) << FLEXCAN_CTRL1_BOFFREC_SHIFT) & FLEXCAN_CTRL1_BOFFREC_MASK; + } + else + { + tempReg |= (((uint32_t)1) << FLEXCAN_CTRL1_BOFFREC_SHIFT) & FLEXCAN_CTRL1_BOFFREC_MASK; + } + + obj->CTRL1 = tempReg; +} + +/*! \brief Get bus off automatic recovering enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: bus off automatic recovering enable + * -0b : bus off automatic recovering disabled + * -1b : bus off automatic recovering enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetBusOffRecEnable(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->CTRL1) & FLEXCAN_CTRL1_BOFFREC_MASK) >> FLEXCAN_CTRL1_BOFFREC_SHIFT); +} + +/*! \brief Set timer synchronze feature enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : timer synchronze feature enable + * -0b : timer sync feature disabled + * -1b : timer sync feature enabled + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetTimerSyncEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_TSYN_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL1_TSYN_SHIFT) & FLEXCAN_CTRL1_TSYN_MASK; + + obj->CTRL1 = tempReg; +} + +/*! \brief Get timer synchronze feature enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: timer synchronze feature enable + * -0b : timer sync feature disabled + * -1b : timer sync feature enabled + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetTimerSyncEnable(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->CTRL1) & FLEXCAN_CTRL1_TSYN_MASK) >> FLEXCAN_CTRL1_TSYN_SHIFT); +} + +/*! \brief Set lowest buffer transmit first enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : timer synchronze feature enable + * -0b : lowest buffer transmit first disable + * -1b : lowest buffer transmit first enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetLowestBufTxFirstEna(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_LBUF_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL1_LBUF_SHIFT) & FLEXCAN_CTRL1_LBUF_MASK; + + obj->CTRL1 = tempReg; +} + +/*! \brief Get lowest buffer transmit first enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: lowest buffer transmit first enable + * -0b : lowest buffer transmit first disable + * -1b : lowest buffer transmit first enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetLowestBufTxFirstEna(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->CTRL1) & FLEXCAN_CTRL1_LBUF_MASK) >> FLEXCAN_CTRL1_LBUF_SHIFT); +} + +/*! \brief Set listen only mode enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : listen only mode enable + * -0b : listen only mode disable + * -1b : listen only mode enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetListenOnlyModeEna(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_LOM_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL1_LOM_SHIFT) & FLEXCAN_CTRL1_LOM_MASK; + + obj->CTRL1 = tempReg; +} + +/*! \brief Get listen only mode enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: listen only mode enable + * -0b : listen only mode disable + * -1b : listen only mode enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetListenOnlyModeEna(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->CTRL1) & FLEXCAN_CTRL1_LOM_MASK) >> FLEXCAN_CTRL1_LOM_SHIFT); +} + +/*! \brief Get propagation segment + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: propagation segment length + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl1Propseg(const FlexCanRegType *obj) +{ + return ((obj->CTRL1 & FLEXCAN_CTRL1_PROPSEG_MASK) >> FLEXCAN_CTRL1_PROPSEG_SHIFT); +} + +/*! \brief Set propagation segment + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : propagation segment length + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl1Propseg(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL1; + + tmp &= ~FLEXCAN_CTRL1_PROPSEG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL1_PROPSEG_SHIFT)) & FLEXCAN_CTRL1_PROPSEG_MASK); + obj->CTRL1 = tmp; +} + +/*! \brief Get free running timer + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: free running timer counter + * + */ +__attribute__((always_inline)) static inline uint32_t FlexCanReg_GetFreeRunningTimer(FlexCanRegType *obj) +{ + return obj->TIMER; +} + +/*! \brief Get Rx mailboxes global mask + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: Rx mailboxes global mask + * + */ +__attribute__((always_inline)) static inline uint32_t FlexCanReg_GetRxMailboxGlobalMask(FlexCanRegType *obj) +{ + return obj->RXMGMASK; +} + +/*! \brief Set Rx mailboxes global mask + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] mask : Rx mailboxes global mask + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRxMailboxGlobalMask(FlexCanRegType *obj, uint32_t mask) +{ + obj->RXMGMASK = mask; +} + + +/*! \brief Set Rx mailbox 14 mask + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] mask : mask for Rx mailbox 14 + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRxMailbox14Mask(FlexCanRegType *obj, uint32_t mask) +{ + obj->RX14MASK = mask; +} + +/*! \brief Get Rx mailbox 14 mask + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: mask for Rx mailbox 14 + * + */ +__attribute__((always_inline)) static inline uint32_t FlexCanReg_GetRxMailbox14Mask(FlexCanRegType *obj) +{ + return (obj->RX14MASK); +} + +/*! \brief Set Rx mailbox 15 mask + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] mask : mask for Rx mailbox 15 + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRxMailbox15Mask(FlexCanRegType *obj, uint32_t mask) +{ + obj->RX15MASK = mask; +} + +/*! \brief Get Rx mailbox 15 mask + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: mask for Rx mailbox 15 + * + */ +__attribute__((always_inline)) static inline uint32_t FlexCanReg_GetRxMailbox15Mask(FlexCanRegType *obj) +{ + return (obj->RX15MASK); +} + +/*! \brief Get receive error counter for fast bits + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: receive error counter for fast bits + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEcrRxerrcntfast(const FlexCanRegType *obj) +{ + return ((obj->ECR & FLEXCAN_ECR_RXERRCNTFAST_MASK) >> FLEXCAN_ECR_RXERRCNTFAST_SHIFT); +} + +/*! \brief Set receive error counter for fast bits + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : receive error counter for fast bits + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetEcrRxerrcntfast(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ECR; + + tmp &= ~FLEXCAN_ECR_RXERRCNTFAST_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_ECR_RXERRCNTFAST_SHIFT)) & FLEXCAN_ECR_RXERRCNTFAST_MASK); + obj->ECR = tmp; +} + +/*! \brief Get transmit error counter for fast bits + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: transmit error counter for fast bits + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEcrTxerrcntfast(const FlexCanRegType *obj) +{ + return ((obj->ECR & FLEXCAN_ECR_TXERRCNTFAST_MASK) >> FLEXCAN_ECR_TXERRCNTFAST_SHIFT); +} + +/*! \brief Set transmit error counter for fast bits + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : transmit error counter for fast bits + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetEcrTxerrcntfast(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ECR; + + tmp &= ~FLEXCAN_ECR_TXERRCNTFAST_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_ECR_TXERRCNTFAST_SHIFT)) & FLEXCAN_ECR_TXERRCNTFAST_MASK); + obj->ECR = tmp; +} + +/*! \brief Get receive error counter + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: receive error counter + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEcrRxerrcnt(const FlexCanRegType *obj) +{ + return ((obj->ECR & FLEXCAN_ECR_RXERRCNT_MASK) >> FLEXCAN_ECR_RXERRCNT_SHIFT); +} + +/*! \brief Set receive error counter + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : receive error counter + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetEcrRxerrcnt(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ECR; + + tmp &= ~FLEXCAN_ECR_RXERRCNT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_ECR_RXERRCNT_SHIFT)) & FLEXCAN_ECR_RXERRCNT_MASK); + obj->ECR = tmp; +} + +/*! \brief Get transmit error counter + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: transmit error counter + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEcrTxerrcnt(const FlexCanRegType *obj) +{ + return ((obj->ECR & FLEXCAN_ECR_TXERRCNT_MASK) >> FLEXCAN_ECR_TXERRCNT_SHIFT); +} + +/*! \brief Set transmit error counter + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : transmit error counter + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetEcrTxerrcnt(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ECR; + + tmp &= ~FLEXCAN_ECR_TXERRCNT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_ECR_TXERRCNT_SHIFT)) & FLEXCAN_ECR_TXERRCNT_MASK); + obj->ECR = tmp; +} + + +/*! \brief Get bit 1 error in FD frame data phase + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: bit 1 error in FD frame data phase + * - 0 : no such error occurrence + * - 1 : at least one bit sent as recessive is received as dominant + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetBit1FastError(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_BIT1ERR_FAST_MASK) >> FLEXCAN_ESR1_BIT1ERR_FAST_SHIFT); +} + +/*! \brief Get bit 0 error in FD frame data phase + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: bit 0 error in FD frame data phase + * - 0 : no such error occurrence + * - 1 : at least one bit sent as dominant is received as recessive + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetBit0FastError(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_BIT0ERR_FAST_MASK) >> FLEXCAN_ESR1_BIT0ERR_FAST_SHIFT); +} + +/*! \brief Get CRC error in FD frame data phase + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: CRC error in FD frame data phase + * - 0 : no such error occurrence + * - 1 : a CRC error occurred since last read of this register + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCrcFastError(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_CRCERR_FAST_MASK) >> FLEXCAN_ESR1_CRCERR_FAST_SHIFT); +} + +/*! \brief Get form error in FD frame data phase + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: form error in FD frame data phase + * - 0 : no such error occurrence + * - 1 : a form error occurred since last read of this register + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFormFastError(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_FRMERR_FAST_MASK) >> FLEXCAN_ESR1_FRMERR_FAST_SHIFT); +} + +/*! \brief Get stuff error in FD frame data phase + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: stuff error in FD frame data phase + * - 0 : no such error occurrence + * - 1 : a stuff error occurred since last read of this register + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetStuffFastError(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_STFERR_FAST_MASK) >> FLEXCAN_ESR1_STFERR_FAST_SHIFT); +} + +/*! \brief Get error overrun + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: error overrun + * - 0 : overrun has occurred + * - 1 : overrun has not occurred + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEsr1Errovr(const FlexCanRegType *obj) +{ + return ((obj->ESR1 & FLEXCAN_ESR1_ERROVR_MASK) >> FLEXCAN_ESR1_ERROVR_SHIFT); +} + +/*! \brief Clear error overrun + * + * \param[in] obj : pointer to FlexCAN register instance + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_ClearEsr1Errovr(FlexCanRegType *obj) +{ + obj->ESR1 = FLEXCAN_ESR1_ERROVR_MASK; +} + +/*! \brief Get error interrupt for errors detected in the data phase of CAN FD frames with the + * BRS Bit set + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: error interrupt for errors detected in the data phase + * - 0 : no error + * - 1 : error has detected in CAN FD frame data phase + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEsr1Errintfast(const FlexCanRegType *obj) +{ + return ((obj->ESR1 & FLEXCAN_ESR1_ERRINT_FAST_MASK) >> FLEXCAN_ESR1_ERRINT_FAST_SHIFT); +} + +/*! \brief Clear error interrupt for errors detected in the data phase of CAN FD frames with the + * BRS Bit set + * + * \param[in] obj : pointer to FlexCAN register instance + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_ClearEsr1Errintfast(FlexCanRegType *obj) +{ + obj->ESR1 = FLEXCAN_ESR1_ERRINT_FAST_MASK; +} + +/*! \brief Get bus off done interrupt + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: bus off done interrupt + * - 0 : no such occurrence + * - 1 : module has completed bus off process + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEsr1Boffdoneint(const FlexCanRegType *obj) +{ + return ((obj->ESR1 & FLEXCAN_ESR1_BOFFDONEINT_MASK) >> FLEXCAN_ESR1_BOFFDONEINT_SHIFT); +} + +/*! \brief Clear bus off done interrupt + * + * \param[in] obj : pointer to FlexCAN register instance + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_ClearEsr1Boffdoneint(FlexCanRegType *obj) +{ + obj->ESR1 = FLEXCAN_ESR1_BOFFDONEINT_MASK; +} + +/*! \brief Get CAN synchronization status + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: CAN synchronization status + * - 0 : not synchronized to the can bus + * - 1 : synchronized to the can bus + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEsr1Synch(const FlexCanRegType *obj) +{ + return ((obj->ESR1 & FLEXCAN_ESR1_SYNCH_MASK) >> FLEXCAN_ESR1_SYNCH_SHIFT); +} + +/*! \brief Get Tx warning interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: Tx warning interrupt flag + * - 0 : no such occurrence + * - 1 : tx error counter transitioned from less than 96 to greater than or equal to 96 + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEsr1Twrnint(const FlexCanRegType *obj) +{ + return ((obj->ESR1 & FLEXCAN_ESR1_TWRNINT_MASK) >> FLEXCAN_ESR1_TWRNINT_SHIFT); +} + +/*! \brief Clear Tx warning interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_ClearEsr1Twrnint(FlexCanRegType *obj) +{ + obj->ESR1 = FLEXCAN_ESR1_TWRNINT_MASK; +} + +/*! \brief Get Rx warning interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: Rx warning interrupt flag + * - 0 : no such occurrence + * - 1 : Rx error counter transitioned from less than 96 to greater than or equal to 96 + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEsr1Rwrnint(const FlexCanRegType *obj) +{ + return ((obj->ESR1 & FLEXCAN_ESR1_RWRNINT_MASK) >> FLEXCAN_ESR1_RWRNINT_SHIFT); +} + +/*! \brief Clear Rx warning interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_ClearEsr1Rwrnint(FlexCanRegType *obj) +{ + obj->ESR1 = FLEXCAN_ESR1_RWRNINT_MASK; +} + +/*! \brief Get bit 1 error + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: bit 1 error + * - 0 : no such error occurrence + * - 1 : at least one bit sent as recessive is received as dominant + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetBit1Error(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_BIT1ERR_MASK) >> FLEXCAN_ESR1_BIT1ERR_SHIFT); +} + +/*! \brief Get bit 0 error + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: bit 0 error + * - 0 : no such error occurrence + * - 1 : at least one bit sent as dominant is received as recessive + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetBit0Error(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_BIT0ERR_MASK) >> FLEXCAN_ESR1_BIT0ERR_SHIFT); +} + +/*! \brief Get ACK error + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: ACK error + * - 0 : no such error occurrence + * - 1 : an ACK error occurred since last read of this register + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetAckError(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_ACKERR_MASK) >> FLEXCAN_ESR1_ACKERR_SHIFT); +} + +/*! \brief Get CRC error + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: CRC error + * - 0 : no such error occurrence + * - 1 : an CRC error occurred since last read of this register + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCrcError(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_CRCERR_MASK) >> FLEXCAN_ESR1_CRCERR_SHIFT); +} + +/*! \brief Get form error + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: form error + * - 0 : no such error occurrence + * - 1 : an form error occurred since last read of this register + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFormError(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_FRMERR_MASK) >> FLEXCAN_ESR1_FRMERR_SHIFT); +} + +/*! \brief Get stuff error + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: stuff error + * - 0 : no such error occurrence + * - 1 : an stuff error occurred since last read of this register + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetStuffError(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_STFERR_MASK) >> FLEXCAN_ESR1_STFERR_SHIFT); +} + +/*! \brief Get Tx error warning + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: Tx error warning + * - 0 : no such error occurrence + * - 1 : TXERRCNT is greater than or equal to 96 + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetTxErrWarning(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_TXWRN_MASK) >> FLEXCAN_ESR1_TXWRN_SHIFT); +} + +/*! \brief Get Rx error warning + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: Rx error warning + * - 0 : no such error occurrence + * - 1 : RXERRCNT is greater than or equal to 96 + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetRxErrWarning(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_RXWRN_MASK) >> FLEXCAN_ESR1_RXWRN_SHIFT); +} + +/*! \brief Get idle state + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: idle state + * - 0 : no such occurrence + * - 1 : CAN bus is now idle + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetIdleState(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_IDLE_MASK) >> FLEXCAN_ESR1_IDLE_SHIFT); +} + +/*! \brief Get Tx state + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: Tx state + * - 0 : FlexCan is not transmitting a message + * - 1 : FlexCan is transmitting a message + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetTxState(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_TX_MASK) >> FLEXCAN_ESR1_TX_SHIFT); +} + +/*! \brief Get fault confinement state + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: fault confinement state + * - 0b00 : error passive + * - 0b01 : error active + * - 0b1x : bus off + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFltConfinementState(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_FLTCONF_MASK) >> FLEXCAN_ESR1_FLTCONF_SHIFT); +} + +/*! \brief Get FlexCan Rx state + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: FlexCan Rx state + * - 0 : FlexCan is not receiving a message + * - 1 : FlexCan is receiving a message + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetRxState(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_RX_MASK) >> FLEXCAN_ESR1_RX_SHIFT); +} + +/*! \brief Get bus off interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: bus off interrupt flag + * - 0 : bus off interrupt assert + * - 1 : bus off interrupt deassert + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetBusoffIntFlag(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_BOFFINT_MASK) >> FLEXCAN_ESR1_BOFFINT_SHIFT); +} + +/*! \brief Clear bus off interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_ClearBusoffIntFlag(FlexCanRegType *obj) +{ + obj->ESR1 = FLEXCAN_ESR1_BOFFINT_MASK; +} + +/*! \brief Get error interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: error interrupt flag + * - 0 : error interrupt assert + * - 1 : error interrupt deassert + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetErrIntFlag(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_ERRINT_MASK) >> FLEXCAN_ESR1_ERRINT_SHIFT); +} + +/*! \brief Clear error interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_ClearErrIntFlag(FlexCanRegType *obj) +{ + obj->ESR1 = FLEXCAN_ESR1_ERRINT_MASK; +} + +/*! \brief Get edge wakeup interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: edge wakeup interrupt flag + * - 0 : wakeup interrupt assert + * - 1 : wakeup interrupt deassert + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEdgeWakeIntFlag(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_WAKINT_MASK) >> FLEXCAN_ESR1_WAKINT_SHIFT); +} + +/*! \brief Clear edge wakeup interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_ClearEdgeWakeIntFlag(FlexCanRegType *obj) +{ + obj->ESR1 = FLEXCAN_ESR1_WAKINT_MASK; +} + +/*! \brief Set FlexCan message buffer interrupt enable mask + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] regId : register index + * \param[in] val : message buffer interrupt enable mask + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetMsgBufInterruptEnable(FlexCanRegType *obj, uint32_t regId, uint32_t val) +{ + switch(regId) + { + case 0: + obj->IMASK1 |= val; + break; + case 1: + obj->IMASK2 |= val; + break; + case 2: + obj->IMASK3 |= val; + break; + case 3: + obj->IMASK4 |= val; + break; + default: + break; + } +} + +/*! \brief Set FlexCan message buffer interrupt disable mask + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] regId : register index + * \param[in] val : message buffer interrupt disable mask + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetMsgBufInterruptDisable(FlexCanRegType *obj, uint32_t regId, uint32_t val) +{ + switch(regId) + { + case 0: + obj->IMASK1 &= val; + break; + case 1: + obj->IMASK2 &= val; + break; + case 2: + obj->IMASK3 &= val; + break; + case 3: + obj->IMASK4 &= val; + break; + default: + break; + } +} + +/*! \brief Get FlexCan message buffer interrupt flag register mask + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] regId : register index + * \return: FlexCan message buffer interrupt flag register[n] mask + * + */ +__attribute__((always_inline)) static inline uint32_t FlexCanReg_GetMsgBufInterruptFlagReg(FlexCanRegType *obj, uint32_t regId) +{ + uint32_t retVal = 0; + + switch(regId) + { + case 0: + retVal = obj->IFLAG1; + break; + case 1: + retVal = obj->IFLAG2; + break; + case 2: + retVal = obj->IFLAG3; + break; + case 3: + retVal = obj->IFLAG4; + break; + default: + break; + } + + return retVal; +} + +/*! \brief Set FlexCan message buffer interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] regId : register index + * \param[in] val : message buffer interrupt flag + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetMsgBufInterruptFlagReg(FlexCanRegType *obj, uint32_t regId, uint32_t val) +{ + switch(regId) + { + case 0: + obj->IFLAG1 = val; + break; + case 1: + obj->IFLAG2 = val; + break; + case 2: + obj->IFLAG3 = val; + break; + case 3: + obj->IFLAG4 = val; + break; + default: + break; + } +} + +/*! \brief Get error interrupt mask in the data phase of CAN FD frame + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: error interrupt mask in the data phase of CAN FD frame + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl2Errmskfast(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_ERRMSKFAST_MASK) >> FLEXCAN_CTRL2_ERRMSKFAST_SHIFT); +} + +/*! \brief Set error interrupt mask in the data phase of CAN FD frame + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : error interrupt mask in the data phase of CAN FD frame + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl2Errmskfast(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL2; + + tmp &= ~FLEXCAN_CTRL2_ERRMSKFAST_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL2_ERRMSKFAST_SHIFT)) & FLEXCAN_CTRL2_ERRMSKFAST_MASK); + obj->CTRL2 = tmp; +} + +/*! \brief Get bus off done interrupt mask + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: bus off done interrupt mask + * 0: bus off done interrupt disable + * 1: bus off done interrupt enable + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl2Boffdonemsk(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_BOFFDONEMSK_MASK) >> FLEXCAN_CTRL2_BOFFDONEMSK_SHIFT); +} + +/*! \brief Set bus off done interrupt mask + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : bus off done interrupt mask + * 0: bus off done interrupt disable + * 1: bus off done interrupt enable + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl2Boffdonemsk(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL2; + + tmp &= ~FLEXCAN_CTRL2_BOFFDONEMSK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL2_BOFFDONEMSK_SHIFT)) & FLEXCAN_CTRL2_BOFFDONEMSK_MASK); + obj->CTRL2 = tmp; +} + +/*! \brief Get error correction configuration register write enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: error correction configuration register write enable + * 0: error correction configuration register write disable + * 1: error correction configuration register write enable + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetMemErrCtrlRegWriteEnable(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_ECRWRE_MASK) >> FLEXCAN_CTRL2_ECRWRE_SHIFT); +} + +/*! \brief Set error correction configuration register write enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : error correction configuration register write enable + * 0: error correction configuration register write disable + * 1: error correction configuration register write enable + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetMemErrCtrlRegWriteEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL2; + tempReg &= (~FLEXCAN_CTRL2_ECRWRE_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL2_ECRWRE_SHIFT) & FLEXCAN_CTRL2_ECRWRE_MASK; + + obj->CTRL2 = tempReg; +} + +/*! \brief Get write access to memory in freeze mode enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: write access to memory in freeze mode enable + * 0: write access to memory in freeze mode disable + * 1: write access to memory in freeze mode enable + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFreezeModeWriteAcc(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_WRMFRZ_MASK) >> FLEXCAN_CTRL2_WRMFRZ_SHIFT); +} + +/*! \brief Set write access to memory in freeze mode enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : write access to memory in freeze mode enable + * 0: write access to memory in freeze mode disable + * 1: write access to memory in freeze mode enable + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetFreezeModeWriteAcc(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL2; + tempReg &= (~FLEXCAN_CTRL2_WRMFRZ_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL2_WRMFRZ_SHIFT) & FLEXCAN_CTRL2_WRMFRZ_MASK; + + obj->CTRL2 = tempReg; +} + +/*! \brief Set number of legacy Rx FIFO filters + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : number of legacy Rx FIFO filters + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRxFifoFilterNum(FlexCanRegType *obj, uint8_t val) +{ + uint32_t tempReg; + tempReg = obj->CTRL2; + tempReg &= (~FLEXCAN_CTRL2_RFFN_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_CTRL2_RFFN_SHIFT) & FLEXCAN_CTRL2_RFFN_MASK; + + obj->CTRL2 = tempReg; +} + +/*! \brief Get number of legacy Rx FIFO filters + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: number of Rx FIFO filters + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetRxFifoFilterNum(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->CTRL2) & FLEXCAN_CTRL2_RFFN_MASK) >> FLEXCAN_CTRL2_RFFN_SHIFT); +} + +/*! \brief Get Tx arbitration start delay + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: Tx arbitration start delay + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl2Tasd(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_TASD_MASK) >> FLEXCAN_CTRL2_TASD_SHIFT); +} + +/*! \brief Set Tx arbitration start delay + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : Tx arbitration start delay + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl2Tasd(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL2; + + tmp &= ~FLEXCAN_CTRL2_TASD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL2_TASD_SHIFT)) & FLEXCAN_CTRL2_TASD_MASK); + obj->CTRL2 = tmp; +} + +/*! \brief Get mailboxes reception priority + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: mailboxes reception priority + * 0: matching starts from Rx FIFO and continues on mailboxes + * 1: matching starts from mailboxes and continues on Rx FIFO + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl2Mrp(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_MRP_MASK) >> FLEXCAN_CTRL2_MRP_SHIFT); +} + +/*! \brief Set mailboxes reception priority + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : mailboxes reception priority + * 0: matching starts from Rx FIFO and continues on mailboxes + * 1: matching starts from mailboxes and continues on Rx FIFO + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl2Mrp(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL2; + + tmp &= ~FLEXCAN_CTRL2_MRP_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL2_MRP_SHIFT)) & FLEXCAN_CTRL2_MRP_MASK); + obj->CTRL2 = tmp; +} + +/*! \brief Get remote request storing + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: remote request storing + * 0: remote response frame is generated + * 1: remote request frame is stored + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl2Rrs(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_RRS_MASK) >> FLEXCAN_CTRL2_RRS_SHIFT); +} + +/*! \brief Set remote request storing + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : remote request storing + * 0: remote response frame is generated + * 1: remote request frame is stored + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl2Rrs(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL2; + + tmp &= ~FLEXCAN_CTRL2_RRS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL2_RRS_SHIFT)) & FLEXCAN_CTRL2_RRS_MASK); + obj->CTRL2 = tmp; +} + +/*! \brief Get entire frame arbitration field comparison enable for rx mailboxes + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: entire frame arbitration field comparison enable for rx mailboxes + * 0: rx mailbox filter's IDE bit is always compared and RTR is never + * compared, regardless of mask bits + * 1: enable the comparison of both the IDE and RTR bits of an + * Rx mailbox filter with the corresponding bits of the incoming + * frame. Mask bits do apply + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl2Eacen(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_EACEN_MASK) >> FLEXCAN_CTRL2_EACEN_SHIFT); +} + +/*! \brief Set entire frame arbitration field comparison enable for rx mailboxes + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : entire frame arbitration field comparison enable for rx mailboxes + * 0: rx mailbox filter's IDE bit is always compared and RTR is never + * compared, regardless of mask bits + * 1: enable the comparison of both the IDE and RTR bits of an + * Rx mailbox filter with the corresponding bits of the incoming + * frame. Mask bits do apply + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl2Eacen(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL2; + + tmp &= ~FLEXCAN_CTRL2_EACEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL2_EACEN_SHIFT)) & FLEXCAN_CTRL2_EACEN_MASK); + obj->CTRL2 = tmp; +} + +/*! \brief Get free running timer source + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: free running timer source + * 0: clocked by CAN bit clock + * 1: clocked by an external time tick, the period can be either adjusted + * to be equal to the baud rate on the CAN bus or a different value as + * required + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl2Timersrc(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_TIMERSRC_MASK) >> FLEXCAN_CTRL2_TIMERSRC_SHIFT); +} + +/*! \brief Set free running timer source + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : free running timer source + * 0: clocked by CAN bit clock + * 1: clocked by an external time tick, the period can be either adjusted + * to be equal to the baud rate on the CAN bus or a different value as + * required + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl2Timersrc(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL2; + + tmp &= ~FLEXCAN_CTRL2_TIMERSRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL2_TIMERSRC_SHIFT)) & FLEXCAN_CTRL2_TIMERSRC_MASK); + obj->CTRL2 = tmp; +} + +/*! \brief Get protocol exception enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: protocol exception enable + * 0: protocol exception disable + * 1: protocol exception enable + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl2Prexcen(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_PREXCEN_MASK) >> FLEXCAN_CTRL2_PREXCEN_SHIFT); +} + +/*! \brief Set protocol exception enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : protocol exception enable + * 0: protocol exception disable + * 1: protocol exception enable + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl2Prexcen(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL2; + + tmp &= ~FLEXCAN_CTRL2_PREXCEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL2_PREXCEN_SHIFT)) & FLEXCAN_CTRL2_PREXCEN_MASK); + obj->CTRL2 = tmp; +} + +/*! \brief Get ISO CAN FD enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: ISO CAN FD enable + * 0: ISO CAN FD disable + * 1: ISO CAN FD enable + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetIsoFdEnalbe(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_ISOCANFDEN_MASK) >> FLEXCAN_CTRL2_ISOCANFDEN_SHIFT); +} + +/*! \brief Set ISO CAN FD enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : ISO CAN FD enable + * 0: ISO CAN FD disable + * 1: ISO CAN FD enable + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetIsoFdEnalbe(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL2; + tempReg &= (~FLEXCAN_CTRL2_ISOCANFDEN_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL2_ISOCANFDEN_SHIFT) & FLEXCAN_CTRL2_ISOCANFDEN_MASK; + + obj->CTRL2 = tempReg; +} + +/*! \brief Get edge filter enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: edge filter enable + * 0: edge filter enable + * 1: edge filter disable + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl2Edfltdis(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_EDFLTDIS_MASK) >> FLEXCAN_CTRL2_EDFLTDIS_SHIFT); +} + +/*! \brief Set edge filter enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : edge filter enable + * 0: edge filter enable + * 1: edge filter disable + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl2Edfltdis(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL2; + + tmp &= ~FLEXCAN_CTRL2_EDFLTDIS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL2_EDFLTDIS_SHIFT)) & FLEXCAN_CTRL2_EDFLTDIS_MASK); + obj->CTRL2 = tmp; +} + +/*! \brief Get lowest priority Tx mailbox + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: lowest priority Tx mailbox + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEsr2Lptm(const FlexCanRegType *obj) +{ + return ((obj->ESR2 & FLEXCAN_ESR2_LPTM_MASK) >> FLEXCAN_ESR2_LPTM_SHIFT); +} + +/*! \brief Get valid priority status + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: valid priority status + * 0: contents of IMB and LPTM are invalid + * 1: contents of IMB and LPTM are valid + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEsr2Vps(const FlexCanRegType *obj) +{ + return ((obj->ESR2 & FLEXCAN_ESR2_VPS_MASK) >> FLEXCAN_ESR2_VPS_SHIFT); +} + +/*! \brief Get Inactive mailbox + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: Inactive mailbox + * 0: if CAN_ESR2.VPS is asserted, CAN_ESR2.LPTM is not an inactive mailbox + * 1: if CAN_ESR2.VPS is asserted, there is at least one inactive maibox. + * CAN_ESR2.LPTM content is the number of the first one + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEsr2Imb(const FlexCanRegType *obj) +{ + return ((obj->ESR2 & FLEXCAN_ESR2_IMB_MASK) >> FLEXCAN_ESR2_IMB_SHIFT); +} + +/*! \brief Get CRC mailbox + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: CRC mailbox, indicats the number of the mailbox corresponding to the value + * in the CAN_CRCR.TXCRC field + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCrcrMbcrc(const FlexCanRegType *obj) +{ + return ((obj->CRCR & FLEXCAN_CRCR_MBCRC_MASK) >> FLEXCAN_CRCR_MBCRC_SHIFT); +} + +/*! \brief Get transmitted CRC mailbox + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: transmitted CRC mailbox, indicats the CRC value of the last transmitted + * message for non-FD frames + * + */ +__attribute__((always_inline)) static inline uint16_t FlexCanReg_GetCrcrTxcrc(const FlexCanRegType *obj) +{ + return ((obj->CRCR & FLEXCAN_CRCR_TXCRC_MASK) >> FLEXCAN_CRCR_TXCRC_SHIFT); +} + +/*! \brief Get Rx FIFO global mask + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: Rx FIFO global mask + * + */ +__attribute__((always_inline)) static inline uint32_t FlexCanReg_GetRxFifoGlobalMask(FlexCanRegType *obj) +{ + return (obj->RXFGMASK); +} + +/*! \brief Set Rx FIFO global mask + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : Rx FIFO global mask + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRxFifoGlobalMask(FlexCanRegType *obj, uint32_t val) +{ + obj->RXFGMASK = val; +} + +/*! \brief Get identifier acceptance filter hit indicator + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: identifier acceptance filter hit indicator + * + */ +__attribute__((always_inline)) static inline uint16_t FlexCanReg_GetRxfirIdhit(const FlexCanRegType *obj) +{ + return ((obj->RXFIR & FLEXCAN_RXFIR_IDHIT_MASK) >> FLEXCAN_RXFIR_IDHIT_SHIFT); +} + +/*! \brief Get extended bit timing format enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: extended bit timing format enable + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetExtendedBitTimingEnable(const FlexCanRegType *obj) +{ + return ((obj->CBT & FLEXCAN_CBT_BTF_MASK) >> FLEXCAN_CBT_BTF_SHIFT); +} + +/*! \brief Set extended bit timing format enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : extended bit timing format enable + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetExtendedBitTimingEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CBT; + tempReg &= (~FLEXCAN_CBT_BTF_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CBT_BTF_SHIFT) & FLEXCAN_CBT_BTF_MASK; + + obj->CBT = tempReg; +} + +/*! \brief Get extended prescaler division factor + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: extended prescaler division factor + * + */ +__attribute__((always_inline)) static inline uint16_t FlexCanReg_GetExtPresalerDivision(const FlexCanRegType *obj) +{ + return ((obj->CBT & FLEXCAN_CBT_EPRESDIV_MASK) >> FLEXCAN_CBT_EPRESDIV_SHIFT); +} + +/*! \brief Set extended prescaler division factor + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : extended prescaler division factor + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetExtPresalerDivision(FlexCanRegType *obj, uint16_t val) +{ + uint32_t tempReg; + tempReg = obj->CBT; + tempReg &= (~FLEXCAN_CBT_EPRESDIV_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_CBT_EPRESDIV_SHIFT) & FLEXCAN_CBT_EPRESDIV_MASK; + + obj->CBT = tempReg; +} + +/*! \brief Get extended resync jump width + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: extended resync jump width + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetExtResyncJumpWidth(const FlexCanRegType *obj) +{ + return ((obj->CBT & FLEXCAN_CBT_ERJW_MASK) >> FLEXCAN_CBT_ERJW_SHIFT); +} + +/*! \brief Set extended resync jump width + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : extended resync jump width + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetExtResyncJumpWidth(FlexCanRegType *obj, uint16_t val) +{ + uint32_t tempReg; + tempReg = obj->CBT; + tempReg &= (~FLEXCAN_CBT_ERJW_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_CBT_ERJW_SHIFT) & FLEXCAN_CBT_ERJW_MASK; + + obj->CBT = tempReg; +} + +/*! \brief Get extended propagation segment + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: extended propagation segment + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetExtPorpSeg(const FlexCanRegType *obj) +{ + return ((obj->CBT & FLEXCAN_CBT_EPROPSEG_MASK) >> FLEXCAN_CBT_EPROPSEG_SHIFT); +} + +/*! \brief Set extended propagation segment + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : extended propagation segment + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetExtPorpSeg(FlexCanRegType *obj, uint16_t val) +{ + uint32_t tempReg; + tempReg = obj->CBT; + tempReg &= (~FLEXCAN_CBT_EPROPSEG_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_CBT_EPROPSEG_SHIFT) & FLEXCAN_CBT_EPROPSEG_MASK; + + obj->CBT = tempReg; +} + +/*! \brief Get extended phase segment 1 + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: extended phase segment 1 + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetExtPhaseSeg1(const FlexCanRegType *obj) +{ + return ((obj->CBT & FLEXCAN_CBT_EPSEG1_MASK) >> FLEXCAN_CBT_EPSEG1_SHIFT); +} + +/*! \brief Set extended phase segment 1 + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : extended phase segment 1 + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetExtPhaseSeg1(FlexCanRegType *obj, uint16_t val) +{ + uint32_t tempReg; + tempReg = obj->CBT; + tempReg &= (~FLEXCAN_CBT_EPSEG1_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_CBT_EPSEG1_SHIFT) & FLEXCAN_CBT_EPSEG1_MASK; + + obj->CBT = tempReg; +} + +/*! \brief Get extended phase segment 2 + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: extended phase segment 2 + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetExtPhaseSeg2(const FlexCanRegType *obj) +{ + return ((obj->CBT & FLEXCAN_CBT_EPSEG2_MASK) >> FLEXCAN_CBT_EPSEG2_SHIFT); +} + +/*! \brief Set extended phase segment 2 + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : extended phase segment 2 + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetExtPhaseSeg2(FlexCanRegType *obj, uint16_t val) +{ + uint32_t tempReg; + tempReg = obj->CBT; + tempReg &= (~FLEXCAN_CBT_EPSEG2_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_CBT_EPSEG2_SHIFT) & FLEXCAN_CBT_EPSEG2_MASK; + + obj->CBT = tempReg; +} + +/*! \brief Set Rx individual mask n + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] num : number of Rx individual mask + * \param[in] mask: mask + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRxIndividualMask(FlexCanRegType *obj, uint8_t num, uint32_t mask) +{ + obj->RXIMR[num] = mask; +} + +/*! \brief Get Rx individual mask n + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] num : number of Rx individual mask + * \return : mask value + */ +__attribute__((always_inline)) static inline uint32_t FlexCanReg_GetRxIndividualMask(FlexCanRegType *obj, uint8_t num) +{ + return (obj->RXIMR[num]); +} + +/*! \brief Get bit rate switch enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : bit rate switch enable + * 0: transmit a frame in nominal rate, the BRS bit in the Tx MB has no effect + * 1: transmit a frame with bit rate switching if the BRS bit in the Tx MB is + * recessive + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFdRateSwitch(const FlexCanRegType *obj) +{ + return ((obj->FDCTRL & FLEXCAN_FDCTRL_FDRATE_MASK) >> FLEXCAN_FDCTRL_FDRATE_SHIFT); +} + +/*! \brief Set bit rate switch enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : bit rate switch enable + * 0: transmit a frame in nominal rate, the BRS bit in the Tx MB has no effect + * 1: transmit a frame with bit rate switching if the BRS bit in the Tx MB is + * recessive + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetFdRateSwitch(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->FDCTRL; + tempReg &= (~FLEXCAN_FDCTRL_FDRATE_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_FDCTRL_FDRATE_SHIFT) & FLEXCAN_FDCTRL_FDRATE_MASK; + + obj->FDCTRL = tempReg; +} + +/*! \brief Set message buffer data size for region n + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] region : region number + * \param[in] sizeSel : message buffer data size for region n + * 00: selects 8 bytes per message buffer + * 01: selects 16 bytes per message buffer + * 10: selects 32 bytes per message buffer + * 11: selects 64 bytes per message buffer + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRegionDataSizeSel(FlexCanRegType *obj, uint8_t region, uint8_t sizeSel) +{ + uint32_t tempReg; + tempReg = obj->FDCTRL; + + switch(region) + { + case 0: + tempReg &= (~FLEXCAN_FDCTRL_MBDSR0_MASK); + tempReg |= (((uint32_t)sizeSel) << FLEXCAN_FDCTRL_MBDSR0_SHIFT) & FLEXCAN_FDCTRL_MBDSR0_MASK; + break; + case 1: + tempReg &= (~FLEXCAN_FDCTRL_MBDSR1_MASK); + tempReg |= (((uint32_t)sizeSel) << FLEXCAN_FDCTRL_MBDSR1_SHIFT) & FLEXCAN_FDCTRL_MBDSR1_MASK; + break; + case 2: + tempReg &= (~FLEXCAN_FDCTRL_MBDSR2_MASK); + tempReg |= (((uint32_t)sizeSel) << FLEXCAN_FDCTRL_MBDSR2_SHIFT) & FLEXCAN_FDCTRL_MBDSR2_MASK; + break; + case 3: + tempReg &= (~FLEXCAN_FDCTRL_MBDSR3_MASK); + tempReg |= (((uint32_t)sizeSel) << FLEXCAN_FDCTRL_MBDSR3_SHIFT) & FLEXCAN_FDCTRL_MBDSR3_MASK; + break; + default: + /* size select wrong, do something */ + break; + } + + obj->FDCTRL = tempReg; +} + +/*! \brief Get message buffer data size for region n + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] region : region number + * \return : message buffer data size for region n + * 00: selects 8 bytes per message buffer + * 01: selects 16 bytes per message buffer + * 10: selects 32 bytes per message buffer + * 11: selects 64 bytes per message buffer + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetRegionDataSizeSel(FlexCanRegType *obj, uint8_t region) +{ + uint8_t retVal = 0; + + switch(region) + { + case 0: + retVal = (uint8_t)((obj->FDCTRL & FLEXCAN_FDCTRL_MBDSR0_MASK) >> FLEXCAN_FDCTRL_MBDSR0_SHIFT); + break; + case 1: + retVal = (uint8_t)((obj->FDCTRL & FLEXCAN_FDCTRL_MBDSR1_MASK) >> FLEXCAN_FDCTRL_MBDSR1_SHIFT); + break; + case 2: + retVal = (uint8_t)((obj->FDCTRL & FLEXCAN_FDCTRL_MBDSR2_MASK) >> FLEXCAN_FDCTRL_MBDSR2_SHIFT); + break; + case 3: + retVal = (uint8_t)((obj->FDCTRL & FLEXCAN_FDCTRL_MBDSR3_MASK) >> FLEXCAN_FDCTRL_MBDSR3_SHIFT); + break; + default: + /* size select wrong, do something */ + break; + } + + return retVal; +} + +/*! \brief Get bit rate switch enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : bit rate switch enable + * 0: transmit a frame in nominal rate, the BRS bit in the Tx MB has no effect + * 1: transmit a frame with bit rate switching if the BRS bit in the Tx MB is + * recessive + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetTdcEnable(const FlexCanRegType *obj) +{ + return ((obj->FDCTRL & FLEXCAN_FDCTRL_TDCEN_MASK) >> FLEXCAN_FDCTRL_TDCEN_SHIFT); +} + +/*! \brief Set bit rate switch enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : bit rate switch enable + * 0: transmit a frame in nominal rate, the BRS bit in the Tx MB has no effect + * 1: transmit a frame with bit rate switching if the BRS bit in the Tx MB is + * recessive + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetTdcEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->FDCTRL; + tempReg &= (~FLEXCAN_FDCTRL_TDCEN_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_FDCTRL_TDCEN_SHIFT) & FLEXCAN_FDCTRL_TDCEN_MASK; + + obj->FDCTRL = tempReg; +} + +/*! \brief Get transceiver delay compensation fail + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : transceiver delay compensation fail + * 0: measured loop delay is in range + * 1: transmit a frame with bit rate switching if the BRS bit in the Tx MB is + * recessive + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFdctrlTdcfail(const FlexCanRegType *obj) +{ + return ((obj->FDCTRL & FLEXCAN_FDCTRL_TDCFAIL_MASK) >> FLEXCAN_FDCTRL_TDCFAIL_SHIFT); +} + +/*! \brief Clear transceiver delay compensation fail + * + * \param[in] obj : pointer to FlexCAN register instance + */ +__attribute__((always_inline)) static inline void FlexCanReg_ClearFdctrlTdcfail(FlexCanRegType *obj) +{ + uint32_t tmp = obj->FDCTRL; + + tmp |= (((uint32_t)(((uint32_t)(1)) << FLEXCAN_FDCTRL_TDCFAIL_SHIFT)) & FLEXCAN_FDCTRL_TDCFAIL_MASK); + obj->FDCTRL = tmp; +} + +/*! \brief Get transceiver delay compensation offset + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : transceiver delay compensation offset + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFdctrlTdcoff(const FlexCanRegType *obj) +{ + return ((obj->FDCTRL & FLEXCAN_FDCTRL_TDCOFF_MASK) >> FLEXCAN_FDCTRL_TDCOFF_SHIFT); +} + +/*! \brief Set transceiver delay compensation offset + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] offset : transceiver delay compensation offset + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetTdcOffset(FlexCanRegType *obj, uint8_t offset) +{ + uint32_t tempReg; + tempReg = obj->FDCTRL; + tempReg &= (~FLEXCAN_FDCTRL_TDCOFF_MASK); + tempReg |= (((uint32_t)offset) << FLEXCAN_FDCTRL_TDCOFF_SHIFT) & FLEXCAN_FDCTRL_TDCOFF_MASK; + + obj->FDCTRL = tempReg; +} + +/*! \brief Get transceiver delay compensation value + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : transceiver delay compensation value + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFdctrlTdcval(const FlexCanRegType *obj) +{ + return ((obj->FDCTRL & FLEXCAN_FDCTRL_TDCVAL_MASK) >> FLEXCAN_FDCTRL_TDCVAL_SHIFT); +} + +/*! \brief Get fast prescaler division factor + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : fast prescaler division factor + */ +__attribute__((always_inline)) static inline uint16_t FlexCanReg_GetFdPrescalerDivision(const FlexCanRegType *obj) +{ + return ((obj->FDCBT & FLEXCAN_FDCBT_FPRESDIV_MASK) >> FLEXCAN_FDCBT_FPRESDIV_SHIFT); +} + +/*! \brief Set fast prescaler division factor + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : fast prescaler division factor + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetFdPrescalerDivision(FlexCanRegType *obj, uint16_t val) +{ + uint32_t tempReg; + tempReg = obj->FDCBT; + tempReg &= (~FLEXCAN_FDCBT_FPRESDIV_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_FDCBT_FPRESDIV_SHIFT) & FLEXCAN_FDCBT_FPRESDIV_MASK; + + obj->FDCBT = tempReg; +} + +/*! \brief Get fast resync jump width + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : fast resync jump width + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFdResyncJumpWidth(const FlexCanRegType *obj) +{ + return ((obj->FDCBT & FLEXCAN_FDCBT_FRJW_MASK) >> FLEXCAN_FDCBT_FRJW_SHIFT); +} + +/*! \brief Set fast resync jump width + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : fast resync jump width + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetFdResyncJumpWidth(FlexCanRegType *obj, uint16_t val) +{ + uint32_t tempReg; + tempReg = obj->FDCBT; + tempReg &= (~FLEXCAN_FDCBT_FRJW_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_FDCBT_FRJW_SHIFT) & FLEXCAN_FDCBT_FRJW_MASK; + + obj->FDCBT = tempReg; +} + +/*! \brief Get fast propagation segment + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : fast propagation segment + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFdPorpSeg(const FlexCanRegType *obj) +{ + return ((obj->FDCBT & FLEXCAN_FDCBT_FPROPSEG_MASK) >> FLEXCAN_FDCBT_FPROPSEG_SHIFT); +} + +/*! \brief Set fast propagation segment + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : fast propagation segment + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetFdPorpSeg(FlexCanRegType *obj, uint16_t val) +{ + uint32_t tempReg; + tempReg = obj->FDCBT; + tempReg &= (~FLEXCAN_FDCBT_FPROPSEG_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_FDCBT_FPROPSEG_SHIFT) & FLEXCAN_FDCBT_FPROPSEG_MASK; + + obj->FDCBT = tempReg; +} + +/*! \brief Get fast phase segment 1 + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : fast phase segment 1 + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFdPhaseSeg1(const FlexCanRegType *obj) +{ + return ((obj->FDCBT & FLEXCAN_FDCBT_FPSEG1_MASK) >> FLEXCAN_FDCBT_FPSEG1_SHIFT); +} + +/*! \brief Set fast phase segment 1 + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : fast phase segment 1 + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetFdPhaseSeg1(FlexCanRegType *obj, uint16_t val) +{ + uint32_t tempReg; + tempReg = obj->FDCBT; + tempReg &= (~FLEXCAN_FDCBT_FPSEG1_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_FDCBT_FPSEG1_SHIFT) & FLEXCAN_FDCBT_FPSEG1_MASK; + + obj->FDCBT = tempReg; +} + +/*! \brief Get fast phase segment 2 + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : fast phase segment 2 + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFdPhaseSeg2(const FlexCanRegType *obj) +{ + return ((obj->FDCBT & FLEXCAN_FDCBT_FPSEG2_MASK) >> FLEXCAN_FDCBT_FPSEG2_SHIFT); +} + +/*! \brief Set fast phase segment 2 + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : fast phase segment 2 + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetFdPhaseSeg2(FlexCanRegType *obj, uint16_t val) +{ + uint32_t tempReg; + tempReg = obj->FDCBT; + tempReg &= (~FLEXCAN_FDCBT_FPSEG2_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_FDCBT_FPSEG2_SHIFT) & FLEXCAN_FDCBT_FPSEG2_MASK; + + obj->FDCBT = tempReg; +} + +/*! \brief Get crc mailbox number for FD_TXCRC + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : crc mailbox number for FD_TXCRC + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFdcrcFdmbcrc(const FlexCanRegType *obj) +{ + return ((obj->FDCRC & CAN_FDCRC_FDMBCRC_MASK) >> CAN_FDCRC_FDMBCRC_SHIFT); +} + +/*! \brief Get extended transmitted CRC value + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : extended transmitted CRC value + */ +__attribute__((always_inline)) static inline uint32_t FlexCanReg_GetFdcrcFdtxcrc(const FlexCanRegType *obj) +{ + return ((obj->FDCRC & CAN_FDCRC_FDTXCRC_MASK) >> CAN_FDCRC_FDTXCRC_SHIFT); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _FLEXCAN_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/ftfc_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/ftfc_reg.h new file mode 100644 index 0000000..3fc7231 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/ftfc_reg.h @@ -0,0 +1,994 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FTFC_REG_H_ +#define _FTFC_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the FTFC Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* FSTAT Bit Fields */ +#define FTFC_FSTAT_CCI_CLR_MASK (0x10000u) /*!FSTAT = tmp; +} + +/*! \brief Gets the flash eee state page error flag + * + * This function gets the current flash eee state page error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash eee state page error flag + * - 0b : eee state pasges ok + * - 1b : eee state pasges error + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatEeeStpgErrF(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_EEE_SPERR_MASK) >> FTFC_FSTAT_EEE_SPERR_SHIFT); +} + +/*! \brief Sets the emulated eeprom full level overflow flag + * + * This function sets the emulated eeprom full level overflow flag. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of emulated eeprom full level overflow flag + * - 0b : no effect + * - 1b : clear the flag + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFstatEeeFlov(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = 0; + tmp = (((uint32_t)(((uint32_t)(value)) << FTFC_FSTAT_EEE_FLOV_SHIFT)) & FTFC_FSTAT_EEE_FLOV_MASK); + obj->FSTAT = tmp; +} + +/*! \brief Gets the emulated eeprom full level overflow flag + * + * This function gets the current emulated eeprom full level overflow flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return the emulated eeprom full level overflow flag + * - 0b : eee write pointer under full level + * - 1b : eee write pointer reach/over full level + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatEeeFlov(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_EEE_FLOV_MASK) >> FTFC_FSTAT_EEE_FLOV_SHIFT); +} + +/*! \brief Gets the emulated eeprom threshold level overflow flag + * + * This function gets the current emulated eeprom threshold level overflow flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return the emulated eeprom threshold level overflow flag + * - 0b : eee write pointer under threshold level + * - 1b : eee write pointer reach/over threshold level + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatEeeTlov(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_EEE_TLOV_MASK) >> FTFC_FSTAT_EEE_TLOV_SHIFT); +} + +/*! \brief Sets the emulated eeprom threshold level overflow flag + * + * This function sets the emulated eeprom threshold level overflow flag. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of emulated eeprom threshold level overflow flag + * - 0b : no effect + * - 1b : clear the flag + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFstatEeeTlov(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = 0; + tmp = (((uint32_t)(((uint32_t)(value)) << FTFC_FSTAT_EEE_TLOV_SHIFT)) & FTFC_FSTAT_EEE_TLOV_MASK); + obj->FSTAT = tmp; +} + +/*! \brief Sets the flash eee state page error flag + * + * This function sets the flash eee state page error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash eee state page error flag + * - 0b : no effect + * - 1b : clear the flag + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFstatStpgErrF(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = 0; + tmp = (((uint32_t)(((uint32_t)(value)) << FTFC_FSTAT_EEE_SPERR_SHIFT)) & FTFC_FSTAT_EEE_SPERR_MASK); + obj->FSTAT = tmp; +} + +/*! \brief Gets the ram ready flag + * + * This function gets the current ram ready flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return ram ready flag + * - 0b : flexram is not ready for system ram + * - 1b : flexram is ready for system ram + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatRamRdy(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_RAMRDY_MASK) >> FTFC_FSTAT_RAMRDY_SHIFT); +} + +/*! \brief Gets the eee_ram ready flag + * + * This function gets the current eee_ram ready flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return eee_ram ready flag + * - 0b : flexram is not ready for eee_ram + * - 1b : flexram is ready for eee_ram + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatEeeRamRdy(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_EEERDY_MASK) >> FTFC_FSTAT_EEERDY_SHIFT); +} + +/*! \brief Gets the flash loader error flag + * + * This function gets the current flash loader error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash loader error flag + * - 0b : flash loader no error + * - 1b : flash loader error + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatFlErrF(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_FL_ERRF_MASK) >> FTFC_FSTAT_FL_ERRF_SHIFT); +} + +/*! \brief Gets the flash loader done flag + * + * This function gets the current flash loader done flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash loader done flag + * - 0b : flash loader is not done + * - 1b : flash loader is done + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatFlDone(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_FL_DONE_MASK) >> FTFC_FSTAT_FL_DONE_SHIFT); +} + +/*! \brief Gets the flash erase sector flag + * + * This function gets the current flash erase sector flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash erase sector flag + * - 0b : not erasing sector + * - 1b : erasing sector + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatErsSctF(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_ERSA_REQ_MASK) >> FTFC_FSTAT_ERSA_REQ_SHIFT); +} + +/*! \brief Gets the flash command complete flag + * + * This function gets the current flash command complete flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return ftfc command complete flag + * - 0b : not completed + * - 1b : completed + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatCcif(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_CCIF_MASK) >> FTFC_FSTAT_CCIF_SHIFT); +} + +/*! \brief Sets the flash command complete flag + * + * This function sets the flash command complete flag. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash command complete flag + * - 0b : no effect + * - 1b : clear the flag + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFstatCcif(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = 0; + tmp = (((uint32_t)(((uint32_t)(value)) << FTFC_FSTAT_CCIF_SHIFT)) & FTFC_FSTAT_CCIF_MASK); + obj->FSTAT = tmp; +} + +/*! \brief Gets the flash read collide error flag + * + * This function gets the current flash read collide error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash read collide error flag + * - 0b : not collide + * - 1b : collided + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatRdColF(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_RDCOLERR_MASK) >> FTFC_FSTAT_RDCOLERR_SHIFT); +} + +/*! \brief Sets the flash read collide error flag + * + * This function sets the flash read collide error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash read collide error flag + * - 0b : no effect + * - 1b : clear the flag + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFstatRdColF(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = 0; + tmp = (((uint32_t)(((uint32_t)(value)) << FTFC_FSTAT_RDCOLERR_SHIFT)) & FTFC_FSTAT_RDCOLERR_MASK); + obj->FSTAT = tmp; +} + +/*! \brief Gets the flash command configuration error flag + * + * This function gets the current flash command configuration error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash command configuration error flag + * - 0b : no command configuration error + * - 1b : command configuration error has occurred + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatAccErrF(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_ACCERR_MASK) >> FTFC_FSTAT_ACCERR_SHIFT); +} + +/*! \brief Sets the flash command configuration error flag + * + * This function sets the flash command configuration error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash command configuration error flag + * - 0b : no effect + * - 1b : clear the flag + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFstatAccErrF(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = 0; + tmp = (((uint32_t)(((uint32_t)(value)) << FTFC_FSTAT_ACCERR_SHIFT)) & FTFC_FSTAT_ACCERR_MASK); + obj->FSTAT = tmp; +} + +/*! \brief Gets the flash protection violation error flag + * + * This function gets the current flash protection violation error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash protection violation error flag + * - 0b : not violation + * - 1b : violation + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatProtViolF(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_PVIOL_MASK) >> FTFC_FSTAT_PVIOL_SHIFT); +} + +/*! \brief Sets the flash protection violation error flag + * + * This function sets the flash protection violation error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash protection violation error flag + * - 0b : no effect + * - 1b : clear the flag + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFstatProtViolF(FtfcRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid + * side-effects */ + uint32_t tmp = 0; + tmp = (((uint32_t)(((uint32_t)(value)) << FTFC_FSTAT_PVIOL_SHIFT)) & FTFC_FSTAT_PVIOL_MASK); + obj->FSTAT = tmp; +} + +/*! \brief Gets the flash ecc sec error flag + * + * This function gets the current flash ecc sec error flag. + * presents whether flash happens ecc sec error + * + * \param[in] obj : pointer to FTFC register instance + * \return flash ecc sec error flag + * - 0b : not ecc sec error + * - 1b : ecc sec error + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatSecF(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_SECF_MASK) >> FTFC_FSTAT_SECF_SHIFT); +} + +/*! \brief Sets the flash ecc sec error flag + * + * This function sets the flash ecc sec error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash ecc sec error flag + * - 0b : no effect + * - 1b : clear the flag + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFstatSecF(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = 0; + tmp = (((uint32_t)(((uint32_t)(value)) << FTFC_FSTAT_SECF_SHIFT)) & FTFC_FSTAT_SECF_MASK); + obj->FSTAT = tmp; +} + +/*! \brief Gets the ftfc ecc ded error flag + * + * This function gets the current ftfc ecc ded error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return ftfc ecc ded error flag + * - 0b : not ecc ded error + * - 1b : ecc ded error + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatDedF(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_DEDF_MASK) >> FTFC_FSTAT_DEDF_SHIFT); +} + +/*! \brief Sets the flash ecc ded error flag + * + * This function sets the flash ecc ded error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash ecc ded error flag + * - 0b : no effect + * - 1b : clear the flag + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFstatDedF(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = 0; + tmp = (((uint32_t)(((uint32_t)(value)) << FTFC_FSTAT_DEDF_SHIFT)) & FTFC_FSTAT_DEDF_MASK); + obj->FSTAT = tmp; +} + +/*! \brief Gets the flash ahb bus response error flag + * + * This function gets the current flash ahb bus response error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash ahb bus response error flag + * - 0b : no response error + * - 1b : response error occurred + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatRspErrF(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_RSPERR_MASK) >> FTFC_FSTAT_RSPERR_SHIFT); +} + +/*! \brief Sets the flash ahb bus response error flag + * + * This function sets the current flash ahb bus response error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash ecc sec error flag + * - 0b : no effect + * - 1b : clear the flag + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFstatRspErrF(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = 0; + tmp = (((uint32_t)(((uint32_t)(value)) << FTFC_FSTAT_RSPERR_SHIFT)) & FTFC_FSTAT_RSPERR_MASK); + obj->FSTAT = tmp; +} + +/*! \brief Gets the flash command run error flag + * + * This function gets the current flash command run error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash command run error flag + * - 0b : no run error + * - 1b : run error has happened + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatMgStat(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_MGSTAT0_MASK) >> FTFC_FSTAT_MGSTAT0_SHIFT); +} + +/*! \brief Gets the flash ahb bus read access time + * + * This function gets the current flash ahb bus read access time. + * + * \param[in] obj : pointer to FTFC register instance + * \return the flash ahb bus read access time(T presents one cycle of ahb bus clock, requires "n*T >= 20.83ns" ) + * - 0h : 1T + * - 1h : 2T + * - 2h : 3T + * - 3h : 4T + * - 4h : 5T + * - 5h : 6T + * - 6h : 7T + * - 7h : 8T + * - 8h : 9T + * - 9h : 10T + * - Ah : 11T + * - Bh : 12T + * - Ch : 13T + * - Dh : 14T + * - Eh : 15T + * - Fh : 16T + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFcnfgBusReadTm(const FtfcRegType *obj) +{ + return ((obj->FCNFG & FTFC_FCNFG_BUSRD_T_MASK) >> FTFC_FCNFG_BUSRD_T_SHIFT); +} + +/*! \brief Sets the flash ahb bus read access time + * + * This function gets the current flash ahb bus read access time. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash ahb bus read access time + * (T presents one cycle of ahb bus clock, requires "n*T >= 20.83ns" ) + * - 0h : 1T + * - 1h : 2T + * - 2h : 3T + * - 3h : 4T + * - 4h : 5T + * - 5h : 6T + * - 6h : 7T + * - 7h : 8T + * - 8h : 9T + * - 9h : 10T + * - Ah : 11T + * - Bh : 12T + * - Ch : 13T + * - Dh : 14T + * - Eh : 15T + * - Fh : 16T + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFcnfgBusReadTm(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FCNFG; + + tmp &= ~FTFC_FCNFG_BUSRD_T_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FTFC_FCNFG_BUSRD_T_SHIFT)) & FTFC_FCNFG_BUSRD_T_MASK); + obj->FCNFG = tmp; +} + +/*! \brief Gets the erase sector suspend + * + * This function gets the current erase sector suspend. + * + * \param[in] obj : pointer to FTFC register instance + * \return erase sector suspend + * - 0b : not suspend + * - 1b : suspend + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFcnfgErsSus(const FtfcRegType *obj) +{ + return ((obj->FCNFG & FTFC_FCNFG_ERS_SUS_MASK) >> FTFC_FCNFG_ERS_SUS_SHIFT); +} + +/*! \brief Sets the erase sector suspend + * + * This function sets the erase sector suspend. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of erase sector suspend + * - 0b : not suspend + * - 1b : suspend + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFcnfgErsSus(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FCNFG; + + tmp &= ~FTFC_FCNFG_ERS_SUS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FTFC_FCNFG_ERS_SUS_SHIFT)) & FTFC_FCNFG_ERS_SUS_MASK); + obj->FCNFG = tmp; +} + +/*! \brief Gets the bus error response interrupt enable + * + * This function gets the current bus error response interrupt enable. + * + * \param[in] obj : pointer to FTFC register instance + * \return bus error response interrupt enable + * - 0b : disable interupt + * - 1b : enable interrupt + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFcnfgRspErrIE(const FtfcRegType *obj) +{ + return ((obj->FCNFG & FTFC_FCNFG_RSP_ERR_IE_MASK) >> FTFC_FCNFG_RSP_ERR_IE_SHIFT); +} + +/*! \brief Sets the bus error response interrupt enable + * + * This function sets the bus error response interrupt enable. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of bus error response interrupt enable + * - 0b : disable interupt + * - 1b : enable interrupt + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFcnfgRspErrIE(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FCNFG; + + tmp &= ~FTFC_FCNFG_RSP_ERR_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FTFC_FCNFG_RSP_ERR_IE_SHIFT)) & FTFC_FCNFG_RSP_ERR_IE_MASK); + obj->FCNFG = tmp; +} + +/*! \brief Gets the flash command complete interrupt enable + * + * This function gets the current flash command complete interrupt enable. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash command complete interrupt enable + * - 0b : disable interupt + * - 1b : enable interrupt + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFcnfgCcifIE(const FtfcRegType *obj) +{ + return ((obj->FCNFG & FTFC_FCNFG_CCIF_IE_MASK) >> FTFC_FCNFG_CCIF_IE_SHIFT); +} + +/*! \brief Sets the flash command complete interrupt enable + * + * This function sets the flash command complete interrupt enable. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash command complete interrupt enable + * - 0b : disable interupt + * - 1b : enable interrupt + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFcnfgCcifIE(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FCNFG; + + tmp &= ~FTFC_FCNFG_CCIF_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FTFC_FCNFG_CCIF_IE_SHIFT)) & FTFC_FCNFG_CCIF_IE_MASK); + obj->FCNFG = tmp; +} + +/*! \brief Gets the flash read collide interrupt enable + * + * This function gets the current flash read collide interrupt enable. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash read collide interrupt enable + * - 0b : disable interupt + * - 1b : enable interrupt + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFcnfgRdColIE(const FtfcRegType *obj) +{ + return ((obj->FCNFG & FTFC_FCNFG_RDCOL_IE_MASK) >> FTFC_FCNFG_RDCOL_IE_SHIFT); +} + +/*! \brief Sets the flash read collide interrupt enable + * + * This function sets the flash read collide interrupt enable. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash read collide interrupt enable + * - 0b : disable interupt + * - 1b : enable interrupt + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFcnfgRdColIE(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FCNFG; + + tmp &= ~FTFC_FCNFG_RDCOL_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FTFC_FCNFG_RDCOL_IE_SHIFT)) & FTFC_FCNFG_RDCOL_IE_MASK); + obj->FCNFG = tmp; +} + +/*! \brief Gets the verify backdoor key enable + * + * This function gets the current verify backdoor key enable. + * + * \param[in] obj : pointer to FTFC register instance + * \return verify backdoor key enable + * - 00b : disable + * - 01b : disable + * - 10b : enable + * - 11b : disable + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFsecKeyEn(const FtfcRegType *obj) +{ + return ((obj->FSEC & FTFC_FSEC_KEYEN_MASK) >> FTFC_FSEC_KEYEN_SHIFT); +} + +/*! \brief Gets the mass erase enable + * + * This function gets the current mass erase enable. + * + * \param[in] obj : pointer to FTFC register instance + * \return mass erase enable + * - 00b : enable + * - 01b : enable + * - 10b : disable + * - 11b : enable + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFsecMeen(const FtfcRegType *obj) +{ + return ((obj->FSEC & FTFC_FSEC_MEEN_MASK) >> FTFC_FSEC_MEEN_SHIFT); +} + +/*! \brief Gets the secure setting + * + * This function gets the current secure setting. + * + * \param[in] obj : pointer to FTFC register instance + * \return secure setting + * - 0b : unsecure + * - 1b : secure + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFsecSecure(const FtfcRegType *obj) +{ + return ((obj->FSEC & FTFC_FSEC_SECURE_MASK) >> FTFC_FSEC_SECURE_SHIFT); +} + +/*! \brief Gets the pflash protection setting + * + * This function gets the current pflash protection setting. + * + * \param[in] obj : pointer to FTFC register instance + * \return pflash protection setting + * - 0b : unprotect + * - 1b : protect + */ +__attribute__((always_inline)) static inline uint32_t FtfcReg_GetPfProtecion(const FtfcRegType *obj) +{ + return ((obj->PFPROT & FTFC_PFPROT_PFPROT_MASK) >> FTFC_PFPROT_PFPROT_SHIFT); +} + +/*! \brief Sets the pflash protection setting + * + * This function sets the pflash protection setting. + * pflash protection bits can only change from 0(unprotection) to 1(protection) + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of pflash protection setting + * - 0b : unprotect + * - 1b : protect + */ +__attribute__((always_inline)) static inline void FtfcReg_SetPfProtecion(FtfcRegType *obj, + uint32_t value) +{ + uint32_t tmp = obj->PFPROT; + + tmp &= ~FTFC_PFPROT_PFPROT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FTFC_PFPROT_PFPROT_SHIFT)) & FTFC_PFPROT_PFPROT_MASK); + obj->PFPROT = tmp; +} + +/*! \brief Gets the dflash protection setting + * + * This function gets the current dflash protection setting. + * + * \param[in] obj : pointer to FTFC register instance + * \return dflash protection setting + * - 0b : unprotect + * - 1b : protect + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetDfProtecion(const FtfcRegType *obj) +{ + return ((obj->DFPROT & FTFC_DFPROT_DFPROT_MASK) >> FTFC_DFPROT_DFPROT_SHIFT); +} + +/*! \brief Sets the dflash protection setting + * + * This function sets the dflash protection setting. + * dflash protection bits can only change from 0 to 1, unprotection to + * protection; + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of dflash protection setting + * - 0b : unprotect + * - 1b : protect + */ +__attribute__((always_inline)) static inline void FtfcReg_SetDfProtection(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DFPROT; + + tmp &= ~FTFC_DFPROT_DFPROT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FTFC_DFPROT_DFPROT_SHIFT)) & FTFC_DFPROT_DFPROT_MASK); + obj->DFPROT = tmp; +} + +/*! \brief Gets the eee_ram protection setting + * + * This function gets the current eee_ram protection setting. + * + * \param[in] obj : pointer to FTFC register instance + * \return eee_ram protection setting + * - 0b : unprotect + * - 1b : protect + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetEfProtecion(const FtfcRegType *obj) +{ + return ((obj->EFPROT & FTFC_EFPROT_EFPROT_MASK) >> FTFC_EFPROT_EFPROT_SHIFT); +} + +/*! \brief Sets the eee_ram protection setting + * + * This function sets the eee_ram protection setting. + * eee_ram protection bits can only change from 0 to 1, unprotection to + * protection; + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of eee_ram protection setting + * - 0b : unprotect + * - 1b : protect + */ +__attribute__((always_inline)) static inline void FtfcReg_SetEfProtection(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EFPROT; + + tmp &= ~FTFC_EFPROT_EFPROT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FTFC_EFPROT_EFPROT_SHIFT)) & FTFC_EFPROT_EFPROT_MASK); + obj->EFPROT = tmp; +} + +/*! \brief Gets the flash common command object + * + * This function gets the current flash common command object. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] index : the index of command object + * - 0 : FCCOB0 + * - 1 : FCCOB1 + * - 2 : FCCOB2 + * - 3 : FCCOB3 + * - 4 : FCCOB4 + * - 5 : FCCOB5 + * - 6 : FCCOB6 + * - 7 : FCCOB7 + * - 8 : FCCOB8 + * - 9 : FCCOB9 + * - 10 : FCCOBa + * - 11 : FCCOBb + * - 12 : FCCOBc + * - 13 : FCCOBd + * - 14 : FCCOBe + * - 15 : FCCOBf + * \return flash common command object + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFccob(const FtfcRegType *obj, uint8_t index) +{ + uint8_t retval = 0; + + retval = obj->FCCOB[index]; + + return retval; +} + +/*! \brief Sets the flash common command object + * + * This function sets the flash common command object. + * when CCIF=0, can not modify this register; + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] index : the index of command object + * - 0 : FCCOB0 + * - 1 : FCCOB1 + * - 2 : FCCOB2 + * - 3 : FCCOB3 + * - 4 : FCCOB4 + * - 5 : FCCOB5 + * - 6 : FCCOB6 + * - 7 : FCCOB7 + * - 8 : FCCOB8 + * - 9 : FCCOB9 + * - 10 : FCCOBa + * - 11 : FCCOBb + * - 12 : FCCOBc + * - 13 : FCCOBd + * - 14 : FCCOBe + * - 15 : FCCOBf + * \param[in] value : the value of flash common command object + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFccob(FtfcRegType *obj, uint8_t index, uint8_t value) +{ + uint32_t tmp = 0; + uint32_t mask = 0xff; + tmp = obj->FCCOB[index]; + tmp &= ~mask; + tmp |= ((uint8_t)(value)&mask); + obj->FCCOB[index] = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _FTFC_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/gpio_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/gpio_reg.h new file mode 100644 index 0000000..44fecdb --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/gpio_reg.h @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _GPIO_REG_H_ +#define _GPIO_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the GPIO Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of GPIO registers + */ +typedef struct _GpioRegType_ +{ + volatile uint32_t PDOR; /*!< Port data output, offset: 0x00 */ + volatile uint32_t PSOR; /*!< Port Set Output, offset: 0x04 */ + volatile uint32_t PCOR; /*!< Port clear output, offset: 0x08 */ + volatile uint32_t PTOR; /*!< Port toggle output, offset: 0x0C */ + const volatile uint32_t PDIR; /*!< Port data input, offset: 0x10 */ + volatile uint32_t PDDR; /*!< Port data direction, offset: 0x14 */ + volatile uint32_t PIDR; /*!< Port input disable, offset: 0x18 */ +} GpioRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the Port Data Output + * + * This function gets the current Port Data Output. + * Register bits for unbonded pins return an undefined value when read. + * + * \param[in] obj : pointer to GPIO register instance + * \return Port Data Output + * - 0b : Logic level 0 is driven on pin, provided pin is configured for general-purpose output. + * - 1b : Logic level 1 is driven on pin, provided pin is configured for general-purpose output. + */ +__attribute__((always_inline)) static inline uint32_t GpioReg_GetPdorDatOut(const GpioRegType *obj) +{ + return obj->PDOR; +} + +/*! \brief Sets the Port Data Output + * + * This function sets the Port Data Output. + * Register bits for unbonded pins return an undefined value when read. + * + * \param[in] obj : pointer to GPIO register instance + * \param[in] value : the value of Port Data Output + * - 0b : Logic level 0 is driven on pin, provided pin is configured for general-purpose output. + * - 1b : Logic level 1 is driven on pin, provided pin is configured for general-purpose output. + */ +__attribute__((always_inline)) static inline void GpioReg_SetPdorDatOut(GpioRegType *obj, uint32_t value) +{ + obj->PDOR = value; +} + +/*! \brief Sets the Port Set Output + * + * This function sets the Port Set Output. + * Writing to this register updates the contents of the corresponding bit in the PDOR + * + * \param[in] obj : pointer to GPIO register instance + * \param[in] value : the value of Port Set Output + * - 0b : Corresponding bit in PDORn does not change. + * - 1b : Corresponding bit in PDORn is set to logic 1. + */ +__attribute__((always_inline)) static inline void GpioReg_SetPsorDatSet(GpioRegType *obj, uint32_t value) +{ + obj->PSOR = value; +} + +/*! \brief Sets the Port Clear Output + * + * This function sets the Port Clear Output. + * Writing to this register updates the contents of the corresponding bit in the Port Data Output Register (PDOR) + * + * \param[in] obj : pointer to GPIO register instance + * \param[in] value : the value of Port Clear Output + * - 0b : Corresponding bit in PDORn does not change. + * - 1b : Corresponding bit in PDORn is cleared to logic 0. + */ +__attribute__((always_inline)) static inline void GpioReg_SetPcorDatClr(GpioRegType *obj, uint32_t value) +{ + obj->PCOR = value; +} + +/*! \brief Sets the Port Toggle Output + * + * This function sets the Port Toggle Output. + * Writing to this register updates the contents of the corresponding bit in the PDOR + * + * \param[in] obj : pointer to GPIO register instance + * \param[in] value : the value of Port Toggle Output + * - 0b : Corresponding bit in PDORn does not change. + * - 1b : Corresponding bit in PDORn is set to the inverse of its existing logic state. + */ +__attribute__((always_inline)) static inline void GpioReg_SetPtorDatTog(GpioRegType *obj, uint32_t value) +{ + obj->PTOR = value; +} + +/*! \brief Gets the Port Data Input + * + * This function gets the current Port Data Input. + * Reads 0 at the unimplemented pins for a particular device. + * Pins that are not configured for a digital function read 0. + * If the Port Control and Interrupt module is disabled, then the corresponding bit in PDIR does not update. + * + * \param[in] obj : pointer to GPIO register instance + * \return Port Data Input + * - 0b : Pin logic level is logic 0, or is not configured for use by digital function. + * - 1b : Pin logic level is logic 1. + */ +__attribute__((always_inline)) static inline uint32_t GpioReg_GetPdirDatIn(const GpioRegType *obj) +{ + return obj->PDIR; +} + +/*! \brief Gets the Port Data Direction + * + * This function gets the current Port Data Direction. + * Configures individual port pins for input or output. + * + * \param[in] obj : pointer to GPIO register instance + * \return Port Data Direction + * - 0b : Pin is configured as general-purpose input, for the GPIO function. + * The pin will be high-Z if the port input is disabled in GPIOx_PIDR register. + * - 1b : Pin is configured as general-purpose output, for the GPIO function. + */ +__attribute__((always_inline)) static inline uint32_t GpioReg_GetPddrDir(const GpioRegType *obj) +{ + return obj->PDDR; +} + +/*! \brief Sets the Port Data Direction + * + * This function sets the Port Data Direction. + * Configures individual port pins for input or output. + * + * \param[in] obj : pointer to GPIO register instance + * \param[in] value : the value of Port Data Direction + * - 0b : Pin is configured as general-purpose input, for the GPIO function. + * The pin will be high-Z if the port input is disabled in GPIOx_PIDR register. + * - 1b : Pin is configured as general-purpose output, for the GPIO function. + */ +__attribute__((always_inline)) static inline void GpioReg_SetPddrDir(GpioRegType *obj, uint32_t value) +{ + obj->PDDR = value; +} + +/*! \brief Gets the Port Input Disable + * + * This function gets the current Port Input Disable. + * + * \param[in] obj : pointer to GPIO register instance + * \return Port Input Disable + * - 0b : Pin is configured for General Purpose Input, provided the pin is configured for any digital function. + * - 1b : Pin is not configured as General Purpose Input. Corresponding Port Data Input Register bit will read zero. + */ +__attribute__((always_inline)) static inline uint32_t GpioReg_GetPidrInDisable(const GpioRegType *obj) +{ + return obj->PIDR; +} + +/*! \brief Sets the Port Input Disable + * + * This function sets the Port Input Disable. + * + * \param[in] obj : pointer to GPIO register instance + * \param[in] value : the value of Port Input Disable + * - 0b : Pin is configured for General Purpose Input, provided the pin is configured for any digital function. + * - 1b : Pin is not configured as General Purpose Input. Corresponding Port Data Input Register bit will read zero. + */ +__attribute__((always_inline)) static inline void GpioReg_SetPidrInDisable(GpioRegType *obj, uint32_t value) +{ + obj->PIDR = value; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _GPIO_REG_H_ */ \ No newline at end of file diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/i2c_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/i2c_reg.h new file mode 100644 index 0000000..33c2268 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/i2c_reg.h @@ -0,0 +1,1558 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _I2C_REG_H_ +#define _I2C_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of I2C module + */ + +/****************************************************************************** + * the includes + *****************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * the defines + *****************************************************************************/ + +/* CTRL Bit fields */ +#define I2C_CTRL_MST_MODE_MASK (0x00000001ul) +#define I2C_CTRL_MST_MODE_SHIFT (0u) + +#define I2C_CTRL_SPEED_MASK (0x00000006ul) +#define I2C_CTRL_SPEED_SHIFT (1u) + +#define I2C_CTRL_SLV_ADDR_MODE_MASK (0x00000008ul) +#define I2C_CTRL_SLV_ADDR_MODE_SHIFT (3u) + +#define I2C_CTRL_MST_ADDR_MODE_MASK (0x00000010ul) +#define I2C_CTRL_MST_ADDR_MODE_SHIFT (4u) + +#define I2C_CTRL_RESTART_EN_MASK (0x00000020ul) +#define I2C_CTRL_RESTART_EN_SHIFT (5u) + +#define I2C_CTRL_SLAVE_DISABLE_MASK (0x00000040ul) +#define I2C_CTRL_SLAVE_DISABLE_SHIFT (6u) + +#define I2C_CTRL_STOP_DET_IFADDRESSED_MASK (0x00000080ul) +#define I2C_CTRL_STOP_DET_IFADDRESSED_SHIFT (7u) + +#define I2C_CTRL_TX_EMPTY_CTRL_MASK (0x00000100ul) +#define I2C_CTRL_TX_EMPTY_CTRL_SHIFT (8u) + +/* TAR Bit fields */ +#define I2C_TAR_TAR_MASK (0x000003FFul) +#define I2C_TAR_TAR_SHIFT (0u) + +#define I2C_TAR_GC_OR_START_MASK (0x00000400ul) +#define I2C_TAR_GC_OR_START_SHIFT (10u) + +#define I2C_TAR_SPECIAL_MASK (0x00000800ul) +#define I2C_TAR_SPECIAL_SHIFT (11u) + +/* SAR Bit fields */ +#define I2C_SAR_SAR_MASK (0x000003FFul) +#define I2C_SAR_SAR_SHIFT (0u) + +/* DATA_CMD Bit fields */ +#define I2C_DATA_CMD_DATA_MASK (0x000000FFul) +#define I2C_DATA_CMD_DATA_SHIFT (0u) + +#define I2C_DATA_CMD_CMD_MASK (0x00000100ul) +#define I2C_DATA_CMD_CMD_SHIFT (8u) + +/* XX_SCL_XXX_CNT Bit fields */ +#define I2C_XX_SCL_XXX_CNT_COUNTER_MASK (0x0000FFFFul) +#define I2C_XX_SCL_XXX_CNT_COUNTER_SHIFT (0u) + +/* INTR_STAT Bit fields */ +#define I2C_INTR_STAT_RX_UNDER_MASK (0x00000001ul) +#define I2C_INTR_STAT_RX_UNDER_SHIFT (0u) + +#define I2C_INTR_STAT_RX_OVER_MASK (0x00000002ul) +#define I2C_INTR_STAT_RX_OVER_SHIFT (1u) + +#define I2C_INTR_STAT_RX_FULL_MASK (0x00000004ul) +#define I2C_INTR_STAT_RX_FULL_SHIFT (2u) + +#define I2C_INTR_STAT_TX_OVER_MASK (0x00000008ul) +#define I2C_INTR_STAT_TX_OVER_SHIFT (3u) + +#define I2C_INTR_STAT_TX_EMPTY_MASK (0x00000010ul) +#define I2C_INTR_STAT_TX_EMPTY_SHIFT (4u) + +#define I2C_INTR_STAT_RD_REQ_MASK (0x00000020ul) +#define I2C_INTR_STAT_RD_REQ_SHIFT (5u) + +#define I2C_INTR_STAT_TX_ABRT_MASK (0x00000040ul) +#define I2C_INTR_STAT_TX_ABRT_SHIFT (6u) + +#define I2C_INTR_STAT_RX_DONE_MASK (0x00000080ul) +#define I2C_INTR_STAT_RX_DONE_SHIFT (7u) + +#define I2C_INTR_STAT_ACTIVITY_MASK (0x00000100ul) +#define I2C_INTR_STAT_ACTIVITY_SHIFT (8u) + +#define I2C_INTR_STAT_STOP_DET_MASK (0x00000200ul) +#define I2C_INTR_STAT_STOP_DET_SHIFT (9u) + +#define I2C_INTR_STAT_START_DET_MASK (0x00000400ul) +#define I2C_INTR_STAT_START_DET_SHIFT (10u) + +#define I2C_INTR_STAT_GEN_CALL_MASK (0x00000800ul) +#define I2C_INTR_STAT_GEN_CALL_SHIFT (11u) + +#define I2C_INTR_STAT_RESTART_DET_MASK (0x00001000ul) +#define I2C_INTR_STAT_RESTART_DET_SHIFT (12u) + +#define I2C_INTR_STAT_MASTER_ON_HOLD_MASK (0x00002000ul) +#define I2C_INTR_STAT_MASTER_ON_HOLD_SHIFT (13u) + +#define I2C_INTR_STAT_SCL_STUCK_AT_LOW_MASK (0x00004000ul) +#define I2C_INTR_STAT_SCL_STUCK_AT_LOW_SHIFT (14u) + +/* INTR_MASK Bit fields */ +#define I2C_INTR_MASK_RX_UNDER_MASK (0x00000001ul) +#define I2C_INTR_MASK_RX_UNDER_SHIFT (0u) + +#define I2C_INTR_MASK_RX_OVER_MASK (0x00000002ul) +#define I2C_INTR_MASK_RX_OVER_SHIFT (1u) + +#define I2C_INTR_MASK_RX_FULL_MASK (0x00000004ul) +#define I2C_INTR_MASK_RX_FULL_SHIFT (2u) + +#define I2C_INTR_MASK_TX_OVER_MASK (0x00000008ul) +#define I2C_INTR_MASK_TX_OVER_SHIFT (3u) + +#define I2C_INTR_MASK_TX_EMPTY_MASK (0x00000010ul) +#define I2C_INTR_MASK_TX_EMPTY_SHIFT (4u) + +#define I2C_INTR_MASK_RD_REQ_MASK (0x00000020ul) +#define I2C_INTR_MASK_RD_REQ_SHIFT (5u) + +#define I2C_INTR_MASK_TX_ABRT_MASK (0x00000040ul) +#define I2C_INTR_MASK_TX_ABRT_SHIFT (6u) + +#define I2C_INTR_MASK_RX_DONE_MASK (0x00000080ul) +#define I2C_INTR_MASK_RX_DONE_SHIFT (7u) + +#define I2C_INTR_MASK_ACTIVITY_MASK (0x00000100ul) +#define I2C_INTR_MASK_ACTIVITY_SHIFT (8u) + +#define I2C_INTR_MASK_STOP_DET_MASK (0x00000200ul) +#define I2C_INTR_MASK_STOP_DET_SHIFT (9u) + +#define I2C_INTR_MASK_START_DET_MASK (0x00000400ul) +#define I2C_INTR_MASK_START_DET_SHIFT (10u) + +#define I2C_INTR_MASK_GEN_CALL_MASK (0x00000800ul) +#define I2C_INTR_MASK_GEN_CALL_SHIFT (11u) + +#define I2C_INTR_MASK_RESTART_DET_MASK (0x00001000ul) +#define I2C_INTR_MASK_RESTART_DET_SHIFT (12u) + +#define I2C_INTR_MASK_MASTER_ON_HOLD_MASK (0x00002000ul) +#define I2C_INTR_MASK_MASTER_ON_HOLD_SHIFT (13u) + +#define I2C_INTR_MASK_SCL_STUCK_AT_LOW_MASK (0x00004000ul) +#define I2C_INTR_MASK_SCL_STUCK_AT_LOW_SHIFT (14u) + +/* CLR_XXX Bit fields */ +#define I2C_CLR_XXX_CLR_REQ_MASK (0x00000001ul) +#define I2C_CLR_XXX_CLR_REQ_SHIFT (0u) + +/* ENABLE Bit fields */ +#define I2C_ENABLE_ENABLE_MASK (0x00000001ul) +#define I2C_ENABLE_ENABLE_SHIFT (0u) + +#define I2C_ENABLE_ABORT_MASK (0x00000002ul) +#define I2C_ENABLE_ABORT_SHIFT (1u) + +/* STATUS Bit fields */ +#define I2C_STAUTS_ACTIVITY_MASK (0x00000001ul) +#define I2C_STAUTS_ACTIVITY_SHIFT (0u) + +#define I2C_STAUTS_TFNF_MASK (0x00000002ul) +#define I2C_STAUTS_TFNF_SHIFT (1u) + +#define I2C_STAUTS_TFE_MASK (0x00000004ul) +#define I2C_STAUTS_TFE_SHIFT (2u) + +#define I2C_STAUTS_RFNE_MASK (0x00000008ul) +#define I2C_STAUTS_RFNE_SHIFT (3u) + +#define I2C_STAUTS_RFF_MASK (0x00000010ul) +#define I2C_STAUTS_RFF_SHIFT (4u) + +#define I2C_STAUTS_MST_ACTIVITY_MASK (0x00000020ul) +#define I2C_STAUTS_MST_ACTIVITY_SHIFT (5u) + +#define I2C_STAUTS_SLV_ACTIVITY_MASK (0x00000040ul) +#define I2C_STAUTS_SLV_ACTIVITY_SHIFT (6u) + +/* TXFLR Bit fields */ +#define I2C_TXFLR_TXFLR_MASK (0x0000001Ful) +#define I2C_TXFLR_TXFLR_SHIFT (0u) + +/* RXFLR Bit fields */ +#define I2C_RXFLR_RXFLR_MASK (0x0000001Ful) +#define I2C_RXFLR_RXFLR_SHIFT (0u) + +/* SDA_HOLD Bit fields */ +#define I2C_SDA_HOLD_RX_HOLD_MASK (0x000000FFul) +#define I2C_SDA_HOLD_RX_HOLD_SHIFT (16u) + +#define I2C_SDA_HOLD_TX_HOLD_MASK (0x0000FFFFul) +#define I2C_SDA_HOLD_TX_HOLD_SHIFT (0u) + +/* SDA_HOLD Bit fields */ +#define I2C_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK_MASK (0x00000001ul) +#define I2C_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK_SHIFT (0u) + +#define I2C_TX_ABRT_SOURCE_ABRT_10ADDR1_NOACK_MASK (0x00000002ul) +#define I2C_TX_ABRT_SOURCE_ABRT_10ADDR1_NOACK_SHIFT (1u) + +#define I2C_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK_MASK (0x00000004ul) +#define I2C_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK_SHIFT (2u) + +#define I2C_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK_MASK (0x00000008ul) +#define I2C_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK_SHIFT (3u) + +#define I2C_TX_ABRT_SOURCE_ABRT_GCALL_NOACK_MASK (0x00000010ul) +#define I2C_TX_ABRT_SOURCE_ABRT_GCALL_NOACK_SHIFT (4u) + +#define I2C_TX_ABRT_SOURCE_ABRT_GCALL_READ_MASK (0x00000020ul) +#define I2C_TX_ABRT_SOURCE_ABRT_GCALL_READ_SHIFT (5u) + +#define I2C_TX_ABRT_SOURCE_ABRT_HS_ACKDET_MASK (0x00000040ul) +#define I2C_TX_ABRT_SOURCE_ABRT_HS_ACKDET_SHIFT (6u) + +#define I2C_TX_ABRT_SOURCE_ABRT_SBYTE_ACKDET_MASK (0x00000080ul) +#define I2C_TX_ABRT_SOURCE_ABRT_SBYTE_ACKDET_SHIFT (7u) + +#define I2C_TX_ABRT_SOURCE_ABRT_HS_NORSTRT_MASK (0x00000100ul) +#define I2C_TX_ABRT_SOURCE_ABRT_HS_NORSTRT_SHIFT (8u) + +#define I2C_TX_ABRT_SOURCE_ARB_SBYTE_NORSTRT_MASK (0x00000200ul) +#define I2C_TX_ABRT_SOURCE_ARB_SBYTE_NORSTRT_SHIFT (9u) + +#define I2C_TX_ABRT_SOURCE_ARB_10B_RD_NORSTRT_MASK (0x00000400ul) +#define I2C_TX_ABRT_SOURCE_ARB_10B_RD_NORSTRT_SHIFT (10u) + +#define I2C_TX_ABRT_SOURCE_ARB_MASTER_DIS_MASK (0x00000800ul) +#define I2C_TX_ABRT_SOURCE_ARB_MASTER_DIS_SHIFT (11u) + +#define I2C_TX_ABRT_SOURCE_ARB_LOST_MASK (0x00001000ul) +#define I2C_TX_ABRT_SOURCE_ARB_LOST_SHIFT (12u) + +#define I2C_TX_ABRT_SOURCE_ABRT_SLVFLUSH_TXFIFO_MASK (0x00002000ul) +#define I2C_TX_ABRT_SOURCE_ABRT_SLVFLUSH_TXFIFO_SHIFT (13u) + +#define I2C_TX_ABRT_SOURCE_ABRT_SLV_ARBLOST_MASK (0x00004000ul) +#define I2C_TX_ABRT_SOURCE_ABRT_SLV_ARBLOST_SHIFT (14u) + +#define I2C_TX_ABRT_SOURCE_ABRT_SLVRD_INTX_MASK (0x00008000ul) +#define I2C_TX_ABRT_SOURCE_ABRT_SLVRD_INTX_SHIFT (15u) + +#define I2C_TX_ABRT_SOURCE_ABRT_USER_ABRT_MASK (0x00010000ul) +#define I2C_TX_ABRT_SOURCE_ABRT_USER_ABRT_SHIFT (16u) + +#define I2C_TX_ABRT_SOURCE_TX_FLUSH_CNT_MASK (0x0F800000ul) +#define I2C_TX_ABRT_SOURCE_TX_FLUSH_CNT_SHIFT (23u) + +/* I2C_DMA_CR Bit fields */ +#define I2C_DMA_CR_RDMAE_MASK (0x00000001ul) +#define I2C_DMA_CR_RDMAE_SHIFT (0u) + +#define I2C_DMA_CR_TDMAE_MASK (0x00000002ul) +#define I2C_DMA_CR_TDMAE_SHIFT (1u) + +/* I2C_DMA_TDLR Bit fields */ +#define I2C_DMA_TDLR_DMATDL_MASK (0x0000000Ful) +#define I2C_DMA_TDLR_DMATDL_SHIFT (0u) + +/* I2C_DMA_RDLR Bit fields */ +#define I2C_DMA_RDLR_DMARDL_MASK (0x0000000Ful) +#define I2C_DMA_RDLR_DMARDL_SHIFT (0u) + +/* I2C_SDA_SETUP Bit fields */ +#define I2C_SDA_SETUP_SDA_SETUP_MASK (0x000000FFul) +#define I2C_SDA_SETUP_SDA_SETUP_SHIFT (0u) + +/* I2C_ACK_GCALL Bit fields */ +#define I2C_ACK_GCALL_ACK_GEN_CALL_MASK (0x00000001ul) +#define I2C_ACK_GCALL_ACK_GEN_CALL_SHIFT (0u) + +/* I2C_ENABLE_STATUS Bit fields */ +#define I2C_ENABLE_STATUS_EN_MASK (0x00000001ul) +#define I2C_ENABLE_STATUS_EN_SHIFT (0u) + +#define I2C_ENABLE_STATUS_SLV_DISABLED_WHILE_BUSY_MASK (0x00000002ul) +#define I2C_ENABLE_STATUS_SLV_DISABLED_WHILE_BUSY_SHIFT (1u) + +#define I2C_ENABLE_STATUS_SLV_RX_DATA_LOST_MASK (0x00000004ul) +#define I2C_ENABLE_STATUS_SLV_RX_DATA_LOST_SHIFT (2u) + +/* I2C_SPKLEN Bit fields */ +#define I2C_SPKLEN_LEN_MASK (0x000000FFul) +#define I2C_SPKLEN_LEN_SHIFT (0u) + +/****************************************************************************** + * the typedefs + *****************************************************************************/ + +/*! \brief the definition of i2c register */ +typedef struct _I2cRegType_ +{ + volatile uint32_t CTRL; /*!< I2C Control Register, offset: 0x0 */ + volatile uint32_t TAR; /*!< I2C Target address Register, offset: 0x4 */ + volatile uint32_t SAR; /*!< I2C Slave address Register, offset: 0x8 */ + uint32_t Res0; + volatile uint32_t DATA_CMD; /*!< I2C Data & Command Register, offset: 0x10 */ + volatile uint32_t SS_SCL_HCNT; /*!< I2C Standard Speed I2C clock high count Register, offset: 0x14 */ + volatile uint32_t SS_SCL_LCNT; /*!< I2C Standard Speed I2C clock high count Register, offset: 0x18 */ + volatile uint32_t FS_SCL_HCNT; /*!< I2C Fast speed I2C clock high count Register, offset: 0x1c */ + volatile uint32_t FS_SCL_LCNT; /*!< I2C Fast speed I2C clock low count Register, offset: 0x20 */ + uint32_t Res1[2]; + volatile uint32_t INTR_STAT; /*!< I2C Interrupt status Register, offset: 0x2C */ + volatile uint32_t INTR_MASK; /*!< I2C Interrupt mask Register, offset: 0x30 */ + volatile uint32_t RAW_INTR_STAT; /*!< I2C RAW INTERRUPT Register, offset: 0x34 */ + volatile uint32_t RX_TL; /*!< I2C RX FIFO threshold Register, offset: 0x38 */ + volatile uint32_t TX_TL; /*!< I2C TX FIFO threshold Register, offset: 0x3C */ + volatile uint32_t CLR_INTR; /*!< I2C Clear interrupt Register, offset: 0x40 */ + volatile uint32_t CLR_RX_UNDER; /*!< I2C Clear RX_UNDER interrupt Register, offset: 0x44 */ + volatile uint32_t CLR_RX_OVER; /*!< I2C Clear RX OVER interrupt Register, offset: 0x48 */ + volatile uint32_t CLR_TX_OVER; /*!< I2C Clear TX OVER interrupt Register, offset: 0x4C */ + volatile uint32_t CLR_RD_REQ; /*!< I2C Clear RD_REQ interrupt Register, offset: 0x50 */ + volatile uint32_t CLR_TX_ABRT; /*!< I2C Clear TX_ABRT interrupt Register, offset: 0x54 */ + volatile uint32_t CLR_RX_DONE; /*!< I2C Clear RX DONE interrupt Register, offset: 0x58 */ + volatile uint32_t CLR_ACTIVITY; /*!< I2C Clear ACTIVITY interrupt Register, offset: 0x5C */ + volatile uint32_t CLR_STOP_DET; /*!< I2C Clear STOP_DET interrupt Register, offset: 0x60 */ + volatile uint32_t CLR_START_DET; /*!< I2C Clear START_DET interrupt Register, offset: 0x64 */ + volatile uint32_t CLR_GEN_CALL; /*!< I2C Clear GEN_CALL interrupt Register, offset: 0x68 */ + volatile uint32_t ENABLE; /*!< I2C ENABLE Register, offset: 0x6C */ + volatile uint32_t STATUS; /*!< I2C STATUS Register, offset: 0x70 */ + volatile uint32_t TXFLR; /*!< I2C TX FIFO LEVEL Register, offset: 0x74 */ + volatile uint32_t RXFLR; /*!< I2C RX FIFO LEVEL Register, offset: 0x78 */ + volatile uint32_t SDA_HOLD; /*!< I2C SDA HOLD TIME length Register, offset: 0x7C */ + volatile uint32_t TX_ABRT_SOURCE; /*!< I2C Transmit ABORT source Register, offset: 0x80 */ + uint32_t Res2; + volatile uint32_t DMA_CR; /*!< I2C DMA control Register, offset: 0x88 */ + volatile uint32_t DMA_TDLR; /*!< I2C DMA Transmit Data Level Register, offset: 0x8C */ + volatile uint32_t DMA_RDLR; /*!< I2C DMA Receive Data Level Register, offset: 0x90 */ + volatile uint32_t SDA_SETUP; /*!< I2C SDA SETUP Register, offset: 0x94 */ + volatile uint32_t ACK_GCALL; /*!< I2C Ack for General Call Register, offset: 0x98 */ + volatile uint32_t ENABLE_STATUS; /*!< I2C ENABLE status Register, offset: 0x9C */ + volatile uint32_t SPKLEN; /*!< I2C SS,FS,FM+ spike suppression limit Register, offset: 0xA0 */ + uint32_t Res3[23]; +} I2cRegType; + +/****************************************************************************** + * the globals + *****************************************************************************/ + +/****************************************************************************** + * the function prototypes + *****************************************************************************/ + +/*! \brief Set the method of controls the generation of TX_EMPTY interrupt. + * + * the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] ctrlMode: + * 0h: default behaviour + * 1h: controled generation + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetTxEmptyCtrl(I2cRegType *obj, uint8_t ctrlMode) +{ + uint32_t tRegValue = obj->CTRL; + + obj->CTRL = (((uint32_t)ctrlMode << I2C_CTRL_TX_EMPTY_CTRL_SHIFT) | ((~I2C_CTRL_TX_EMPTY_CTRL_MASK) & tRegValue)); +} + +/*! \brief Set the mode of detect stop bit condition + * + * the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] stopDetMode + * 0h: issue the STOP_DET irrespective of whether it is addressed or not + * 1h: issue the STOP_DET irrespective only when it is addressed + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetSlaveDetectStopBitMode(I2cRegType *obj, uint8_t stopDetMode) +{ + uint32_t tRegValue = obj->CTRL; + + obj->CTRL = (((uint32_t)stopDetMode << I2C_CTRL_STOP_DET_IFADDRESSED_SHIFT) | ((~I2C_CTRL_STOP_DET_IFADDRESSED_MASK) & tRegValue)); +} + +/*! \brief slave mode disable + * + * this function set the node as slave node or not + * + * \param[in] obj: base address for the i2cinstance + * \param[in] DdisableSlaveMode: + * false: enable slave mode + * true: disable slave mode + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetSlaveModeDisable(I2cRegType *obj, bool disableSlaveMode) +{ + uint32_t tRegValue = obj->CTRL; + + if(disableSlaveMode == true) + { + obj->CTRL = ((1ul << I2C_CTRL_SLAVE_DISABLE_SHIFT) | ((~I2C_CTRL_SLAVE_DISABLE_MASK) & tRegValue)); + } + else + { + obj->CTRL = ((0ul << I2C_CTRL_SLAVE_DISABLE_SHIFT) | ((~I2C_CTRL_SLAVE_DISABLE_MASK) & tRegValue)); + } +} + +/*! \brief master RESTART enable + * + * the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] restartEnable: + * false: Disabled + * true: Enabled + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetMasterRestartEnable(I2cRegType *obj, bool restartEnable) +{ + uint32_t tRegValue = obj->CTRL; + + if(restartEnable == true) + { + obj->CTRL = ((1ul << I2C_CTRL_RESTART_EN_SHIFT) | ((~I2C_CTRL_RESTART_EN_MASK) & tRegValue)); + } + else + { + obj->CTRL = ((0ul << I2C_CTRL_RESTART_EN_SHIFT) | ((~I2C_CTRL_RESTART_EN_MASK) & tRegValue)); + } +} + +/*! \brief Set master address mode + * + * the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] addressMode: + * 0h:7bit address + * 1h:10bit address + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetMasterAddressMode(I2cRegType *obj, uint8_t addressMode) +{ + uint32_t tRegValue = obj->CTRL; + + obj->CTRL = (((uint32_t)addressMode << I2C_CTRL_MST_ADDR_MODE_SHIFT) | ((~I2C_CTRL_MST_ADDR_MODE_MASK) & tRegValue)); +} + +/*! \brief Set slave address mode + * + * the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] addressMode: + * 0h:7bit address + * 1h:10bit address + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetSlaveAddressMode(I2cRegType *obj, uint8_t addressMode) +{ + uint32_t tRegValue = obj->CTRL; + + obj->CTRL = (((uint32_t)addressMode << I2C_CTRL_SLV_ADDR_MODE_SHIFT) | ((~I2C_CTRL_SLV_ADDR_MODE_MASK) & tRegValue)); +} + +/*! \brief Set the master speed + * + * the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] speedMode: + * 1h:standard mode,100kbit/s + * 2h:fast mode <=400kbit/s or fast mode plus<=1000kbit/s; + * 3h: high speed 3.4Mbit/s--not supported + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetSpeedMode(I2cRegType *obj, uint8_t speedMode) +{ + uint32_t tRegValue = obj->CTRL; + + obj->CTRL = (((uint32_t)speedMode << I2C_CTRL_SPEED_SHIFT) | ((~I2C_CTRL_SPEED_MASK) & tRegValue)); +} + +/*! \brief Get the master speed + * + * this function get the master speed + * + * \param[in] obj: base address for the i2cinstance + * \return: uint8_t + * 1h:standard mode,100kbit/s + * 2h:fast mode <=400kbit/s or fast mode plus<=1000kbit/s; + * 3h: high speed 3.4Mbit/s--not supported + */ +__attribute__((always_inline)) static inline uint8_t I2cReg_GetSpeedMode(const I2cRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->CTRL & I2C_CTRL_SPEED_MASK) >> I2C_CTRL_SPEED_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief I2C master mode control + * + * the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] masterMode: + * 0h: slave mode + * 1h: master mode + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetMasterMode(I2cRegType *obj, bool masterMode) +{ + uint32_t tRegValue = obj->CTRL; + + if(masterMode == true) + { + obj->CTRL = ((1ul << I2C_CTRL_MST_MODE_SHIFT) | ((~I2C_CTRL_MST_MODE_MASK) & tRegValue)); + } + else + { + obj->CTRL = ((0ul << I2C_CTRL_MST_MODE_SHIFT) | ((~I2C_CTRL_MST_MODE_MASK) & tRegValue)); + } +} + +/*! \brief Get the type of the node + * + * this function get the moudle whether it be used as master node + * + * \param[in] obj: base address for the i2cinstance + * \return: bool + * true: as a master node + * false:as a slave node + */ +__attribute__((always_inline)) static inline bool I2cReg_GetModuleAsMaster(const I2cRegType *obj) +{ + bool tRtn = false; + + if((obj->CTRL & I2C_CTRL_MST_MODE_MASK) != 0ul) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief indicates whether software performs a General Call or Start Byte command + * + * the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] supportedSpecialCmd: + * 0b: not support + * 1b: support + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetSpecialCommand(I2cRegType *obj, uint8_t supportedSpecialCmd) +{ + uint32_t tRegValue = obj->TAR; + + obj->TAR = (((uint32_t)supportedSpecialCmd << I2C_TAR_SPECIAL_SHIFT) | ((~I2C_TAR_SPECIAL_MASK) & tRegValue)); +} + +/*! \brief Set special type + * + * the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] SsecialCmdType: + * 0h:General Call + * 1h:Start byte + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetSpecialCmdType(I2cRegType *obj, uint8_t specialCmdType) +{ + uint32_t tRegValue = obj->TAR; + + obj->TAR = (((uint32_t)specialCmdType << I2C_TAR_GC_OR_START_SHIFT) | ((~I2C_TAR_GC_OR_START_MASK) & tRegValue)); +} + +/*! \brief Set target address for master + * + * It is the target address for master transaction. When transmitting a Genral Call, it is ignored, + * the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] targetAddr: the target address of node + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetTargetAddress(I2cRegType *obj, uint16_t targetAddr) +{ + uint32_t tRegValue = obj->TAR; + + obj->TAR = (((uint32_t)targetAddr << I2C_TAR_TAR_SHIFT) | ((~I2C_TAR_TAR_MASK) & tRegValue)); +} + +/*! \brief Get the current target address for master + * + * this function get the target address for master + * + * \param[in] obj: base address for the i2cinstance + * \return: the target node of address + */ +__attribute__((always_inline)) static inline uint32_t I2cReg_GetTargetAddress(const I2cRegType *obj) +{ + uint32_t tRtn = 0; + + tRtn = ((obj->TAR & I2C_TAR_TAR_MASK) >> I2C_TAR_TAR_SHIFT); + + return tRtn; +} + +/*! \brief Set slave address + * + * only be written when I2C interface is disabled.the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] slaveAddress: the slave node of address + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetSlaveAddress(I2cRegType *obj, uint16_t slaveAddress) +{ + uint32_t tRegValue = obj->SAR; + + obj->SAR = (((uint32_t)slaveAddress << I2C_SAR_SAR_SHIFT) | ((~I2C_SAR_SAR_MASK) & tRegValue)); +} + +/*! \brief Write transmit data and command + * + * Read or write data from this register + * + * \param[in] obj: base address for the i2cinstance + * \param[in] data: the transmit data + * \param[in] readCmd: + * 0b: write command + * 1b: read command + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetDataAndCmd(I2cRegType *obj, uint8_t data, bool readCmd) +{ + uint32_t tDataCmd = 0; + + tDataCmd = data; + + if(readCmd == true) + { + tDataCmd |= I2C_DATA_CMD_CMD_MASK; + } + + obj->DATA_CMD = tDataCmd; +} + +/*! \brief Get received data + * + * this function read out datas from rx fifo + * + * \param[in] obj: base address for the i2cinstance + * \return: received data + */ +__attribute__((always_inline)) static inline uint8_t I2cReg_GetData(const I2cRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->DATA_CMD & I2C_DATA_CMD_DATA_MASK) >> I2C_DATA_CMD_DATA_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Set Standard Speed I2C clock high count + * + * This register can be written only when the I2C interface is disabled + * + * \param[in] obj: base address for the i2cinstance + * \param[in] highCount: the i2c clock high count value + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetStandardModeHighLevelCount(I2cRegType *obj, uint16_t highCount) +{ + uint32_t tRegValue = obj->SS_SCL_HCNT; + + obj->SS_SCL_HCNT = (((uint32_t)highCount << I2C_XX_SCL_XXX_CNT_COUNTER_SHIFT) | ((~I2C_XX_SCL_XXX_CNT_COUNTER_MASK) & tRegValue)); +} + +/*! \brief Get Standard Speed I2C clock high count + * + * this function get the high counter in standard speed mode + * + * \param[in] obj: base address for the i2cinstance + * \return: the i2c clock high count value + */ +__attribute__((always_inline)) static inline uint16_t I2cReg_GetStandardModeHighLevelCount(const I2cRegType *obj) +{ + uint16_t tRtn = 0; + + tRtn = ((obj->SS_SCL_HCNT & I2C_XX_SCL_XXX_CNT_COUNTER_MASK) & 0xFFFF); + + return tRtn; +} + +/*! \brief Set Standard Speed I2C clock low count + * + * This register can be written only when the I2C interface is disabled + * + * \param[in] obj: base address for the i2cinstance + * \param[in] lowCount: Standard Speed I2C clock low count + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetStandardModeLowLevelCount(I2cRegType *obj, uint16_t lowCount) +{ + uint32_t tRegValue = obj->SS_SCL_LCNT; + + obj->SS_SCL_LCNT = (((uint32_t)lowCount << I2C_XX_SCL_XXX_CNT_COUNTER_SHIFT) | ((~I2C_XX_SCL_XXX_CNT_COUNTER_MASK) & tRegValue)); +} + +/*! \brief Get Standard Speed I2C clock low count + * + * this function get the low counter in standard speed mode + * + * \param[in] obj: base address for the i2cinstance + * \return: Standard Speed I2C clock low count + */ +__attribute__((always_inline)) static inline uint16_t I2cReg_GetStandardModeLowLevelCount(const I2cRegType *obj) +{ + uint16_t tRtn = 0; + + tRtn = ((obj->SS_SCL_LCNT & I2C_XX_SCL_XXX_CNT_COUNTER_MASK) & 0xFFFF); + + return tRtn; +} + +/*! \brief Set FAST Speed I2C clock high count + * + * This register can be written only when the I2C interface is disabled + * + * \param[in] obj: base address for the i2cinstance + * \param[in] highCount: FAST Speed I2C clock high count + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetFastModeHighLevelCount(I2cRegType *obj, uint16_t highCount) +{ + uint32_t tRegValue = obj->FS_SCL_HCNT; + + obj->FS_SCL_HCNT = (((uint32_t)highCount << I2C_XX_SCL_XXX_CNT_COUNTER_SHIFT) | ((~I2C_XX_SCL_XXX_CNT_COUNTER_MASK) & tRegValue)); +} + +/*! \brief Get Fast Speed I2C clock High count + * + * this function get the high counter in fast speed mode + * + * \param[in] obj: base address for the i2cinstance + * \return: Fast Speed I2C clock High count + */ +__attribute__((always_inline)) static inline uint16_t I2cReg_GetFastModeHighLevelCount(const I2cRegType *obj) +{ + uint16_t tRtn = 0; + + tRtn = ((obj->FS_SCL_HCNT & I2C_XX_SCL_XXX_CNT_COUNTER_MASK) & 0xFFFF); + + return tRtn; +} + +/*! \brief Set FAST Speed I2C clock low count + * + * This register can be written only when the I2C interface is disabled + * + * \param[in] obj: base address for the i2cinstance + * \param[in] lowCount: FAST Speed I2C clock low count + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetFastModeLowLevelCount(I2cRegType *obj, uint16_t lowCount) +{ + uint32_t tRegValue = obj->FS_SCL_LCNT; + + obj->FS_SCL_LCNT = (((uint32_t)lowCount << I2C_XX_SCL_XXX_CNT_COUNTER_SHIFT) | ((~I2C_XX_SCL_XXX_CNT_COUNTER_MASK) & tRegValue)); +} + +/*! \brief Get Fast Speed I2C clock low count + * + * Note:this function get the low counter in fast speed mode + * + * \param[in] obj: base address for the i2cinstance + * \return: Fast Speed I2C clock low count + */ +__attribute__((always_inline)) static inline uint16_t I2cReg_GetFastModeLowLevelCount(const I2cRegType *obj) +{ + uint16_t tRtn = 0; + + tRtn = ((obj->FS_SCL_LCNT & I2C_XX_SCL_XXX_CNT_COUNTER_MASK) & 0xFFFF); + + return tRtn; +} + +/*! \brief Get I2C interrupt status + * + * this function get the special interrupt status + * + * \param[in] obj: base address for the i2cinstance + * \param[in] interruptStatusMask: conbination of more than one status + * \return: bool + * 0h: inactive + * 1h: active + */ +__attribute__((always_inline)) static inline bool I2cReg_GetInterruptStatus(const I2cRegType *obj, uint32_t interruptStatusMask) +{ + uint32_t tIsrStatus = 0; + bool tRtn = false; + + tIsrStatus = obj->INTR_STAT; + + if((tIsrStatus & interruptStatusMask) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief Get I2C raw interrupt status + * + * this function get the interrupt raw status + * + * \param[in] obj: base address for the i2cinstance + * \param[in] interruptStatusMask: conbination of more than one status + * \return: bool + * 0h: inactive + * 1h: active + */ +__attribute__((always_inline)) static inline bool I2cReg_GetInterruptRawStatus(const I2cRegType *obj, uint32_t interruptStatusMask) +{ + uint32_t tStatus = 0; + bool tRtn = false; + + tStatus = obj->RAW_INTR_STAT; + + if((tStatus & interruptStatusMask) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief Get Ic Status + * + * this function get the ic module status + * + * \param[in] obj: base address for the i2cinstance + * \param[in] statusMask: conbination of more than one status + * \return: bool + * false: no happend + * true: happend + */ +__attribute__((always_inline)) static inline bool I2cReg_GetICStatus(const I2cRegType *obj, uint32_t statusMask) +{ + uint32_t tStatus = 0; + bool tRtn = false; + + tStatus = obj->STATUS; + + if((tStatus & statusMask) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief Enable or disable interrupt req + * + * this function set the special interrupt request action when condition is matched + * + * \param[in] obj: base address for the i2cinstance + * \param[in] interruptStatusMask: the special interrupt status + * \param[in] enInterruptReq: enable or disable + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetInterruptMask(I2cRegType *obj, uint32_t interruptStatusMask, bool enInterruptReq) +{ + if(enInterruptReq == true) + { + obj->INTR_MASK |= interruptStatusMask; + } + else + { + obj->INTR_MASK &= (~interruptStatusMask); + } +} + +/*! \brief Get the current interrupt status + * + * This function get the current inyrttupy is enabled or disabled + * + * \param[in] obj: base address for the i2cinstance + * \param[in] interruptStatusMask: the special interrupt status + * \return: bool + * true: is enabled + * false: is disabled + */ +__attribute__((always_inline)) static inline bool I2cReg_GetInterruptIsEnabled(const I2cRegType *obj, uint32_t interruptStatusMask) +{ + bool isEnabled = false; + + if((obj->INTR_MASK & interruptStatusMask) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief Set RX FIFO threshold + * + * I2C RX FIFO threshold FIFO depth is 16 + * + * \param[in] obj: base address for the i2cinstance + * \param[in] rxFifoThreshold: RX FIFO threshold value + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetRxFifoThreshold(I2cRegType *obj, uint8_t rxFifoThreshold) +{ + uint32_t tRegValue = obj->RX_TL; + + obj->RX_TL = (((uint32_t)rxFifoThreshold << I2C_RXFLR_RXFLR_SHIFT) | ((~I2C_RXFLR_RXFLR_MASK) & tRegValue)); +} + +/*! \brief Set TX FIFO threshold + * + * I2C TX FIFO threshold FIFO depth is 16 + * + * \param[in] obj: base address for the i2cinstance + * \param[in] txFifoThreshold: TX FIFO threshold + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetTxFifoThreshold(I2cRegType *obj, uint8_t txFifoThreshold) +{ + uint32_t tRegValue = obj->TX_TL; + + obj->TX_TL = (((uint32_t)txFifoThreshold << I2C_TXFLR_TXFLR_SHIFT) | ((~I2C_TXFLR_TXFLR_MASK) & tRegValue)); +} + +/*! \brief Clear all interrupt status + * + * Read this register to clear all interrupts and I2C_TX_ABRT_SOURCE, It does not clear hardware clearable interrupts but software clearable interrupts. + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearAllInterruptStatus(I2cRegType *obj) +{ + (void)((obj->CLR_INTR & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_INTR; +} + +/*! \brief clear interrupt status in the RAW_INTR_STAT + * + * this function clear the rx under status after interrupt request handler + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearRxUnderStatus(I2cRegType *obj) +{ + (void)((obj->CLR_RX_UNDER & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_RX_UNDER; +} + +/*! \brief clear interrupt status in the RAW_INTR_STAT + * + * Note:this function clear the rx overflow status after interrupt request handler + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearRxOverStatus(I2cRegType *obj) +{ + (void)((obj->CLR_RX_OVER & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_RX_OVER; +} + +/*! \brief clear interrupt status in the RAW_INTR_STAT + * + * Note:this function clear the tx overflow status after interrupt request handler + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearTxOverStatus(I2cRegType *obj) +{ + (void)((obj->CLR_TX_OVER & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_TX_OVER; +} + +/*! \brief clear interrupt status in the RAW_INTR_STAT + * + * Note:this function clear the rx read request status after interrupt request handler + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearReadReqStatus(I2cRegType *obj) +{ + (void)((obj->CLR_RD_REQ & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_RD_REQ; +} + +/*! \brief clear interrupt status in the RAW_INTR_STAT + * + * Note:this function clear the tx abort status after interrupt request handler + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearTxAbortStatus(I2cRegType *obj) +{ + (void)((obj->CLR_TX_ABRT & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_TX_ABRT; +} + +/*! \brief clear interrupt status in the RAW_INTR_STAT + * + * Note:this function clear the rx done status after interrupt request handler + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearRxDoneStatus(I2cRegType *obj) +{ + (void)((obj->CLR_RX_DONE & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_RX_DONE; +} + +/*! \brief clear interrupt status in the RAW_INTR_STAT + * + * Note:this function clear the activity status after interrupt request handler + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearActivityStatus(I2cRegType *obj) +{ + (void)((obj->CLR_ACTIVITY & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_ACTIVITY; +} + +/*! \brief clear interrupt status in the RAW_INTR_STAT + * + * Note:this function clear the stop bit detected status after interrupt request handler + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearStopBitDetectStatus(I2cRegType *obj) +{ + (void)((obj->CLR_STOP_DET & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_STOP_DET; +} + +/*! \brief clear interrupt status in the RAW_INTR_STAT + * + * Note:this function clear the start bit detected status after interrupt request handler + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearStartBitDetectStatus(I2cRegType *obj) +{ + (void)((obj->CLR_START_DET & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_START_DET; +} + +/*! \brief clear interrupt status in the RAW_INTR_STAT + * + * Note:this function clear the general call status after interrupt request handler + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearGeneralCallStatus(I2cRegType *obj) +{ + (void)((obj->CLR_GEN_CALL & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_GEN_CALL; +} + +/*! \brief Set module enable + * + * this function enable or disable the i2c module + * + * \param[in] obj: base address for the i2cinstance + * \param[in] ModuleEn: enable or disable + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetModuleEnable(I2cRegType *obj, bool moduleEn) +{ + uint32_t tRegValue = obj->ENABLE; + + if(moduleEn == true) + { + obj->ENABLE = ((1ul << I2C_ENABLE_ENABLE_SHIFT) | ((~I2C_ENABLE_ENABLE_MASK) & tRegValue)); + } + else + { + obj->ENABLE = ((0ul << I2C_ENABLE_ENABLE_SHIFT) | ((~I2C_ENABLE_ENABLE_MASK) & tRegValue)); + } +} + +/*! \brief Abort transfer + * + * only set one in the enable bit is 1, clear by hardware + * after set 1, the hardware will generate a stop condition and clear tx fifo, then hardware clear this bit again + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetAbortReq(I2cRegType *obj) +{ + uint32_t tRegValue = obj->ENABLE; + + obj->ENABLE = ((1ul << I2C_ENABLE_ABORT_SHIFT) | ((~I2C_ENABLE_ABORT_MASK) & tRegValue)); +} + +/*! \brief Get i2c status + * + * this function get the current status of module + * + * \param[in] obj: base address for the i2cinstance + * \param[in] StatusMask: one special status mask, only one status + * \return: bool + * false: not exist + * true: exist + */ +__attribute__((always_inline)) static inline bool I2cReg_GetModuleStatus(const I2cRegType *obj, uint32_t statusMask) +{ + uint32_t tStatus = 0; + bool tRtn = false; + + tStatus = obj->STATUS; + if((tStatus & statusMask) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief Contains the number of valid data entries in the transmit FIFO. + * + * this function get the number of valid data entries in the transmit FIFO + * + * \param[in] obj: base address for the i2cinstance + * \return: the number of valid data entries + */ +__attribute__((always_inline)) static inline uint8_t I2cReg_GetTxFifoLevel(const I2cRegType *obj) +{ + uint8_t tTxFifoLevel = 0; + + tTxFifoLevel = (((obj->TXFLR & I2C_TXFLR_TXFLR_MASK) >> I2C_TXFLR_TXFLR_SHIFT) & 0xFF); + + return tTxFifoLevel; +} + +/*! \brief Contains the number of valid data entries in the receive FIFO. + * + * this function get the number of valid data entries in the receive FIFO. + * + * \param[in] obj: base address for the i2cinstance + * \return: the number of valid data entries in the receive FIFO. + */ +__attribute__((always_inline)) static inline uint8_t I2cReg_GetRxFifoLevel(const I2cRegType *obj) +{ + uint8_t tRxFifoLevel = 0; + + tRxFifoLevel = (((obj->RXFLR & I2C_RXFLR_RXFLR_MASK) >> I2C_RXFLR_RXFLR_SHIFT) & 0xFF); + + return tRxFifoLevel; +} + +/*! \brief Set RX SDA hold time + * + * this function set IC SDA HOLD TIME length + * + * \param[in] obj: base address for the i2cinstance + * \param[in] HoldTime: IC SDA HOLD TIME length + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetRxDataHoldTime(I2cRegType *obj, uint16_t holdTime) +{ + uint32_t tRegValue = obj->SDA_HOLD; + + obj->SDA_HOLD = (((uint32_t)holdTime << I2C_SDA_HOLD_RX_HOLD_SHIFT) | ((~I2C_SDA_HOLD_RX_HOLD_MASK) & tRegValue)); +} + +/*! \brief Set TX SDA hold time + * + * This bit field can only be written when the I2C_ENABLE[ENABLE] is disabled . + * + * \param[in] obj: base address for the i2cinstance + * \param[in] HoldTime: TX SDA hold time + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetTxDataHoldTime(I2cRegType *obj, uint16_t holdTime) +{ + uint32_t tRegValue = obj->SDA_HOLD; + + obj->SDA_HOLD = (((uint32_t)holdTime << I2C_SDA_HOLD_TX_HOLD_SHIFT) | ((~I2C_SDA_HOLD_TX_HOLD_MASK) & tRegValue)); +} + +/*! \brief Get the Tx abort source information except the tx flush cnt + * + * this function get the tx abort information + * + * \param[in] obj: base address for the i2cinstance + * \param[in] AbortSourceMask: which abort source + * \return: bool + * true: abort detected + * false: abort not detected + */ +__attribute__((always_inline)) static inline bool I2cReg_GetTxAbortInfo(const I2cRegType *obj, uint32_t abortSourceMask) +{ + uint32_t tAbortSource = 0; + bool tRtn = false; + + tAbortSource = obj->TX_ABRT_SOURCE; + + if((tAbortSource & abortSourceMask) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief flush count in TX FIFO + * + * This field indicates the number of Tx FIFO Data Commands which are flushed due to TX_ABRT interrupt. It is cleared whenever I2C is disabled. + * + * \param[in] obj: base address for the i2cinstance + * \return: the number of Tx FIFO Data Commands which are flushed + */ +__attribute__((always_inline)) static inline uint8_t I2cReg_GetTxFlushCounter(const I2cRegType *obj) +{ + uint8_t tTxFlushCounter = 0; + + tTxFlushCounter = (((obj->TX_ABRT_SOURCE & I2C_TX_ABRT_SOURCE_TX_FLUSH_CNT_MASK) >> I2C_TX_ABRT_SOURCE_TX_FLUSH_CNT_SHIFT) & 0xFF); + + return tTxFlushCounter; +} + +/*! \brief This bit enables/disables the transmit FIFO DMA channel. + * + * this function enable or disable the tx with dma features + * + * \param[in] obj: base address for the i2cinstance + * \param[in] en: + * false: Dma tx disabled + * true: Dma tx enabled + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetTxDmaEnable(I2cRegType *obj, bool en) +{ + uint32_t tRegValue = obj->DMA_CR; + + if(en == true) + { + obj->DMA_CR = ((1ul << I2C_DMA_CR_TDMAE_SHIFT) | ((~I2C_DMA_CR_TDMAE_MASK) & tRegValue)); + } + else + { + obj->DMA_CR = ((0ul << I2C_DMA_CR_TDMAE_SHIFT) | ((~I2C_DMA_CR_TDMAE_MASK) & tRegValue)); + } +} + +/*! \brief Get enables/disables the transmit FIFO DMA channel. + * + * this function get the current tx mode is used with dma + * + * \param[in] obj: base address for the i2cinstance + * \return: bool + */ +__attribute__((always_inline)) static inline bool I2cReg_GetDmaTxIsEnabled(const I2cRegType *obj) +{ + bool tRtn = false; + + if((obj->DMA_CR & I2C_DMA_CR_TDMAE_MASK) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief This bit enables/disables the receiver FIFO DMA channel. + * + * this function enable or disable the rx with dma features + * + * \param[in] obj: base address for the i2cinstance + * \param[in] en: + * false: Dma rx disabled + * true: Dma rx enabled + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetRxDmaEnable(I2cRegType *obj, bool en) +{ + uint32_t tRegValue = obj->DMA_CR; + + if(en == true) + { + obj->DMA_CR = ((1ul << I2C_DMA_CR_RDMAE_SHIFT) | ((~I2C_DMA_CR_RDMAE_MASK) & tRegValue)); + } + else + { + obj->DMA_CR = ((0ul << I2C_DMA_CR_RDMAE_SHIFT) | ((~I2C_DMA_CR_RDMAE_MASK) & tRegValue)); + } +} + +/*! \brief Get enables/disables the transmit FIFO DMA channel. + * + * this function get the current rx mode is used with dma + * + * \param[in] obj: base address for the i2cinstance + * \return: bool + * false: Dma rx disabled + * true: Dma rx enabled + */ +__attribute__((always_inline)) static inline bool I2cReg_GetDmaRxIsEnabled(const I2cRegType *obj) +{ + bool tRtn = false; + + if((obj->DMA_CR & I2C_DMA_CR_RDMAE_MASK) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief controls the level at which a DMA request is made by the transmit logic + * + * It is equal to the watermark level; that is, the dma_tx_req signal is generated when the number of valid data entries in the transmit FIFO is equal to + * or below this field value, and TDMAE = 1 + * + * \param[in] obj: base address for the i2cinstance + * \param[in] txLevel: the watermark level + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetDmaTxLevel(I2cRegType *obj, uint8_t txLevel) +{ + uint32_t tRegValue = obj->DMA_TDLR; + + obj->DMA_TDLR = (((uint32_t)txLevel << I2C_DMA_TDLR_DMATDL_SHIFT) | ((~I2C_DMA_TDLR_DMATDL_MASK) & tRegValue)); +} + +/*! \brief controls the level at which a DMA request is made by the receive logic + * + * The watermark level = DMARDL+1; that is, dma_rx_req is generated when the number of valid data entries in the receive FIFO is equal + * to or more than this field value + 1, and RDMAE =1. + * + * \param[in] obj: base address for the i2cinstance + * \param[in] rxLevel: The rx watermark level + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetDmaRxLevel(I2cRegType *obj, uint8_t rxLevel) +{ + uint32_t tRegValue = obj->DMA_RDLR; + + obj->DMA_RDLR = (((uint32_t)rxLevel << I2C_DMA_RDLR_DMARDL_SHIFT) | ((~I2C_DMA_RDLR_DMARDL_MASK) & tRegValue)); +} + +/*! \brief SDA setup + * + * It is recommended that if the required delay is + * 1000ns, then for an I2C_clk frequency of 10 MHz,I2C_SDA_SETUP should be programmed to a value of 11. I2C_SDA_SETUP >=2 + * + * \param[in] obj: base address for the i2cinstance + * \param[in] SetUpTime: SDA setup + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetDataSetUpTime(I2cRegType *obj, uint8_t setUpTime) +{ + uint32_t tRegValue = obj->SDA_SETUP; + + obj->SDA_SETUP = (((uint32_t)setUpTime << I2C_SDA_SETUP_SDA_SETUP_SHIFT) | ((~I2C_SDA_SETUP_SDA_SETUP_MASK) & tRegValue)); +} + +/*! \brief Set ack for General Call + * + * this function configure the ack for the general call cmd + * + * \param[in] obj: base address for the i2cinstance + * \param[in] ackEn: + * false: Disable ack for general call + * true: Enable ack for general call + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetAckForGeneralCall(I2cRegType *obj, bool ackEn) +{ + uint32_t tRegValue = obj->ACK_GCALL; + + if(ackEn == true) + { + obj->ACK_GCALL = ((1ul << I2C_ACK_GCALL_ACK_GEN_CALL_SHIFT) | ((~I2C_ACK_GCALL_ACK_GEN_CALL_MASK) & tRegValue)); + } + else + { + obj->ACK_GCALL = ((0ul << I2C_ACK_GCALL_ACK_GEN_CALL_SHIFT) | ((~I2C_ACK_GCALL_ACK_GEN_CALL_MASK) & tRegValue)); + } +} + +/*! \brief Get slave rx data lost + * + * this function get the status if rx data is lost before + * + * \param[in] obj: base address for the i2cinstance + * \return: bool + * false: Slave RX data is not lost + * true: Slave RX data is lost + */ +__attribute__((always_inline)) static inline bool I2cReg_GetSlaveRxDataLostStatus(const I2cRegType *obj) +{ + bool tRtn = false; + + if((obj->ENABLE_STATUS & I2C_ENABLE_STATUS_SLV_RX_DATA_LOST_MASK) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief Get whether slave is disabled when active + * + * this function get the status if slave is disable but in busy status + * + * \param[in] obj: base address for the i2cinstance + * \return: bool + * false: slave is disabled when it is idle + * true: slave is disabled when it is active + */ +__attribute__((always_inline)) static inline bool I2cReg_GetSlaveDisabledWhileBusyStatus(const I2cRegType *obj) +{ + bool tRtn = false; + + if((obj->ENABLE_STATUS & I2C_ENABLE_STATUS_SLV_DISABLED_WHILE_BUSY_MASK) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief Get module enable status + * + * this function get the current status about module + * + * \param[in] obj: base address for the i2cinstance + * \return: bool + * false: disabled + * true: enabled + */ +__attribute__((always_inline)) static inline bool I2cReg_GetModuleEnableStatus(const I2cRegType *obj) +{ + bool tRtn = false; + + if((obj->ENABLE_STATUS & I2C_ENABLE_STATUS_EN_MASK) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief sets the duration about spike length + * + * ,measured in I2C_clk cycles, of the longest spike in the SCL or SDA lines that will be filtered out by the spike suppression logic + * + * \param[in] obj: base address for the i2cinstance + * \param[in] SpikeLen: the duration about spike length + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetSpikeLen(I2cRegType *obj, uint8_t spikeLen) +{ + uint32_t tRegValue = obj->SPKLEN; + + obj->SPKLEN = (((uint32_t)spikeLen << I2C_SPKLEN_LEN_SHIFT) | ((~I2C_SPKLEN_LEN_MASK) & tRegValue)); +} + +/*! \brief Gets the duration,measured in I2C_clk cycles + * + * this function get the spike length ticks + * + * \param[in] obj: base address for the i2cinstance + * \return: the duration,measured in I2C_clk cycles + */ +__attribute__((always_inline)) static inline uint8_t I2cReg_GetSpikeLen(const I2cRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->SPKLEN & I2C_SPKLEN_LEN_MASK) >> I2C_SPKLEN_LEN_SHIFT) & 0xFF); + + return tRtn; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _I2C_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/i2sm_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/i2sm_reg.h new file mode 100644 index 0000000..ad20c90 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/i2sm_reg.h @@ -0,0 +1,702 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _I2SM_REG_H_ +#define _I2SM_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the I2SM Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* IER Bit Fields */ +#define I2SM_IER_EN_MASK (0x01u) +#define I2SM_IER_EN_SHIFT (0u) +#define I2SM_IER_EN_WIDTH (1u) + +/* ITER Bit Fields */ +#define I2SM_ITER_TXEN_MASK (0x01u) +#define I2SM_ITER_TXEN_SHIFT (0u) +#define I2SM_ITER_TXEN_WIDTH (1u) + +/* CER Bit Fields */ +#define I2SM_CER_CLKEN_MASK (0x01u) +#define I2SM_CER_CLKEN_SHIFT (0u) +#define I2SM_CER_CLKEN_WIDTH (1u) + +/* CCR Bit Fields */ +#define I2SM_CCR_WSS_MASK (0x18u) +#define I2SM_CCR_WSS_SHIFT (3u) +#define I2SM_CCR_WSS_WIDTH (2u) +#define I2SM_CCR_SCLKG_MASK (0x07u) +#define I2SM_CCR_SCLKG_SHIFT (0u) +#define I2SM_CCR_SCLKG_WIDTH (3u) + +/* TXFFR Bit Fields */ +#define I2SM_TXFFR_TXFFR_MASK (0x01u) +#define I2SM_TXFFR_TXFFR_SHIFT (0u) +#define I2SM_TXFFR_TXFFR_WIDTH (1u) + +/* LTHR0 Bit Fields */ +#define I2SM_LTHR0_LTHR0_MASK (0xFFFFFFFFu) +#define I2SM_LTHR0_LTHR0_SHIFT (0u) +#define I2SM_LTHR0_LTHR0_WIDTH (32u) + +/* RTHR0 Bit Fields */ +#define I2SM_RTHR0_RTHR0_MASK (0xFFFFFFFFu) +#define I2SM_RTHR0_RTHR0_SHIFT (0u) +#define I2SM_RTHR0_RTHR0_WIDTH (32u) + +/* TER0 Bit Fields */ +#define I2SM_TER0_TXCHEN0_MASK (0x01u) +#define I2SM_TER0_TXCHEN0_SHIFT (0u) +#define I2SM_TER0_TXCHEN0_WIDTH (1u) + +/* TCR0 Bit Fields */ +#define I2SM_TCR0_TX_WLEN_MASK (0x07u) +#define I2SM_TCR0_TX_WLEN_SHIFT (0u) +#define I2SM_TCR0_TX_WLEN_WIDTH (3u) + +/* ISR0 Bit Fields */ +#define I2SM_ISR0_TXFO_MASK (0x20u) +#define I2SM_ISR0_TXFO_SHIFT (5u) +#define I2SM_ISR0_TXFO_WIDTH (1u) +#define I2SM_ISR0_TXFE_MASK (0x10u) +#define I2SM_ISR0_TXFE_SHIFT (4u) +#define I2SM_ISR0_TXFE_WIDTH (1u) + +/* IMR0 Bit Fields */ +#define I2SM_IMR0_TXFOM_MASK (0x20u) +#define I2SM_IMR0_TXFOM_SHIFT (5u) +#define I2SM_IMR0_TXFOM_WIDTH (1u) +#define I2SM_IMR0_TXFEM_MASK (0x10u) +#define I2SM_IMR0_TXFEM_SHIFT (4u) +#define I2SM_IMR0_TXFEM_WIDTH (1u) + +/* TOR0 Bit Fields */ +#define I2SM_TOR0_TXCHO_MASK (0x01u) +#define I2SM_TOR0_TXCHO_SHIFT (0u) +#define I2SM_TOR0_TXCHO_WIDTH (1u) + +/* TFCR0 Bit Fields */ +#define I2SM_TFCR0_TFCR0_MASK (0x0Fu) +#define I2SM_TFCR0_TFCR0_SHIFT (0u) +#define I2SM_TFCR0_TFCR0_WIDTH (4u) + +/* TFF0 Bit Fields */ +#define I2SM_TFF0_TXCHFR0_MASK (0x01u) +#define I2SM_TFF0_TXCHFR0_SHIFT (0u) +#define I2SM_TFF0_TXCHFR0_WIDTH (1u) + +/* TXDMA Bit Fields */ +#define I2SM_TXDMA_TXDMA_MASK (0xFFFFFFFFu) +#define I2SM_TXDMA_TXDMA_SHIFT (0u) +#define I2SM_TXDMA_TXDMA_WIDTH (32u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of I2SM registers + */ +typedef struct _I2smRegType_ +{ + volatile uint32_t IER; /*!< module enable, offset: 0x00 */ + uint32_t RESERVED0[1]; /*!< Reserverd block, offset: 0x04 */ + volatile uint32_t ITER; /*!< transmit block enable, offset: 0x08 */ + volatile uint32_t CER; /*!< clock enable, offset: 0x0C */ + volatile uint32_t CCR; /*!< clock configuration register, offset: 0x10 */ + uint32_t RESERVED1[1]; /*!< Reserverd block, offset: 0x14 */ + volatile uint32_t TXFFR; /*!< TX FIFO reset, offset: 0x18 */ + uint32_t RESERVED2[1]; /*!< Reserverd block, offset: 0x1C */ + volatile uint32_t LTHR0; /*!< left stereo data, offset: 0x20 */ + volatile uint32_t RTHR0; /*!< right stereo data, offset: 0x24 */ + uint32_t RESERVED3[1]; /*!< Reserverd block, offset: 0x28 */ + volatile uint32_t TER0; /*!< transmit channel enable, offset: 0x2C */ + uint32_t RESERVED4[1]; /*!< Reserverd block, offset: 0x30 */ + volatile uint32_t TCR0; /*!< transmit configuration, offset: 0x34 */ + volatile uint32_t ISR0; /*!< interrupt status, offset: 0x38 */ + volatile uint32_t IMR0; /*!< interrupt mask, offset: 0x3C */ + uint32_t RESERVED5[1]; /*!< Reserverd block, offset: 0x40 */ + volatile uint32_t TOR0; /*!< transmit overrun status, offset: 0x44 */ + uint32_t RESERVED6[1]; /*!< Reserverd block, offset: 0x48 */ + volatile uint32_t TFCR0; /*!< TX FIFO configuration, offset: 0x4C */ + uint32_t RESERVED7[1]; /*!< Reserverd block, offset: 0x50 */ + volatile uint32_t TFF0; /*!< TX FIFO flush, offset: 0x54 */ + uint32_t RESERVED8[92]; /*!< Reserverd block, offset: 0x58 */ + volatile uint32_t TXDMA; /*!< Transmit DMA register, offset: 0x1C8 */ +} I2smRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the IP enable + * + * This function gets the current IP enable. + * + * \param[in] obj : pointer to I2SM register instance + * \return IP enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetIerEn(const I2smRegType *obj) +{ + return ((obj->IER & I2SM_IER_EN_MASK) >> I2SM_IER_EN_SHIFT); +} + +/*! \brief Sets the IP enable + * + * This function sets the IP enable. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of IP enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void I2smReg_SetIerEn(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IER; + + tmp &= ~I2SM_IER_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_IER_EN_SHIFT)) & I2SM_IER_EN_MASK); + obj->IER = tmp; +} + +/*! \brief Gets the transmit block enable + * + * This function gets the current transmit block enable. + * It enables or disables the transmit. + * + * \param[in] obj : pointer to I2SM register instance + * \return transmit block enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetIterTxEn(const I2smRegType *obj) +{ + return ((obj->ITER & I2SM_ITER_TXEN_MASK) >> I2SM_ITER_TXEN_SHIFT); +} + +/*! \brief Sets the transmit block enable + * + * This function sets the transmit block enable. + * It enables or disables the transmit. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of transmit block enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void I2smReg_SetIterTxEn(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ITER; + + tmp &= ~I2SM_ITER_TXEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_ITER_TXEN_SHIFT)) & I2SM_ITER_TXEN_MASK); + obj->ITER = tmp; +} + +/*! \brief Gets the master clock generation enable + * + * This function gets the current master clock generation enable. + * + * \param[in] obj : pointer to I2SM register instance + * \return master clock generation enable + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetCerClkEn(const I2smRegType *obj) +{ + return ((obj->CER & I2SM_CER_CLKEN_MASK) >> I2SM_CER_CLKEN_SHIFT); +} + +/*! \brief Sets the master clock generation enable + * + * This function sets the master clock generation enable. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of master clock generation enable + */ +__attribute__((always_inline)) static inline void I2smReg_SetCerClkEn(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CER; + + tmp &= ~I2SM_CER_CLKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_CER_CLKEN_SHIFT)) & I2SM_CER_CLKEN_MASK); + obj->CER = tmp; +} + +/*! \brief Gets the left/right channel period + * + * This function gets the current left/right channel period. + * It is used to program the number of sclk cycles for which ws_out stays in the left or right sample mode. + * The I2S Clock Generation block must be disabled (CER[0] = 0) prior to any changes in this value. + * + * \param[in] obj : pointer to I2SM register instance + * \return left/right channel period + * - 0h : 16 sclk cycles + * - 1h : 24 sclk cycles + * - 2h : 32 sclk cycles + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetCcrWss(const I2smRegType *obj) +{ + return ((obj->CCR & I2SM_CCR_WSS_MASK) >> I2SM_CCR_WSS_SHIFT); +} + +/*! \brief Sets the left/right channel period + * + * This function sets the left/right channel period. + * It is used to program the number of sclk cycles for which ws_out stays in the left or right sample mode. + * The I2S Clock Generation block must be disabled (CER[0] = 0) prior to any changes in this value. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of left/right channel period + * - 0h : 16 sclk cycles + * - 1h : 24 sclk cycles + * - 2h : 32 sclk cycles + */ +__attribute__((always_inline)) static inline void I2smReg_SetCcrWss(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CCR; + + tmp &= ~I2SM_CCR_WSS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_CCR_WSS_SHIFT)) & I2SM_CCR_WSS_MASK); + obj->CCR = tmp; +} + +/*! \brief Gets the clock gate period + * + * This function gets the current clock gate period. + * It is used to program the gating of sclk. + * The programmed gating value must be less than or equal to the largest configured/ programmed audio resolution + * to prevent the truncating of RX/TX data. + * The I2S Clock Generation block must be disabled (CER[0] = 0) before making any changes in this value. + * + * \param[in] obj : pointer to I2SM register instance + * \return clock gate period + * - 0h : disabled + * - 1h : gating after 12 sclk cycles + * - 2h : gating after 16 sclk cycles + * - 3h : gating after 20 sclk cycles + * - 4h : gating after 24 sclk cycles + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetCcrSclkg(const I2smRegType *obj) +{ + return ((obj->CCR & I2SM_CCR_SCLKG_MASK) >> I2SM_CCR_SCLKG_SHIFT); +} + +/*! \brief Sets the clock gate period + * + * This function sets the clock gate period. + * It is used to program the gating of sclk. + * The programmed gating value must be less than or equal to the largest configured/ programmed audio resolution + * to prevent the truncating of RX/TX data. + * The I2S Clock Generation block must be disabled (CER[0] = 0) before making any changes in this value. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of clock gate period + * - 0h : disabled + * - 1h : gating after 12 sclk cycles + * - 2h : gating after 16 sclk cycles + * - 3h : gating after 20 sclk cycles + * - 4h : gating after 24 sclk cycles + */ +__attribute__((always_inline)) static inline void I2smReg_SetCcrSclkg(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CCR; + + tmp &= ~I2SM_CCR_SCLKG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_CCR_SCLKG_SHIFT)) & I2SM_CCR_SCLKG_MASK); + obj->CCR = tmp; +} + +/*! \brief Sets the TX FIFO reset + * + * This function sets the TX FIFO reset. + * Writing a 1 to this register flushes all the TX FIFOs (this is a self clearing bit). + * The Transmitter Block must be disabled prior to writing this bit. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of TX FIFO reset + * - 0b : does not flush the TX FIFO + * - 1b : flush the TX FIFO + */ +__attribute__((always_inline)) static inline void I2smReg_SetTxffrTxFFR(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->TXFFR; + + tmp &= ~I2SM_TXFFR_TXFFR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_TXFFR_TXFFR_SHIFT)) & I2SM_TXFFR_TXFFR_MASK); + obj->TXFFR = tmp; +} + +/*! \brief Sets the left stereo data + * + * This function sets the left stereo data. + * The left stereo data to be transmitted serially through the transmit channel output (sdox) is written through this register. + * Writing is a two-stage process: + * 1. A write to this register passes the left stereo sample to the transmitter. + * 2. This MUST be followed by writing the right stereo sample to the RTHRx register + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of left stereo data + */ +__attribute__((always_inline)) static inline void I2smReg_SetLthr0Lthr0(I2smRegType *obj, uint32_t value) +{ + uint32_t tmp = obj->LTHR0; + + tmp &= ~I2SM_LTHR0_LTHR0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_LTHR0_LTHR0_SHIFT)) & I2SM_LTHR0_LTHR0_MASK); + obj->LTHR0 = tmp; +} + +/*! \brief Sets the right stereo data + * + * This function sets the right stereo data. + * The right stereo data to be transmitted serially through the + * transmit channel output (sdox) is written through this register. + * Writing is a two-stage process: + * 1. A left stereo sample MUST be written to the LTHRx register. + * 2. A write to this register passes the right stereo sample to the transmitte + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of right stereo data + */ +__attribute__((always_inline)) static inline void I2smReg_SetRthr0Rthr0(I2smRegType *obj, uint32_t value) +{ + uint32_t tmp = obj->RTHR0; + + tmp &= ~I2SM_RTHR0_RTHR0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_RTHR0_RTHR0_SHIFT)) & I2SM_RTHR0_RTHR0_MASK); + obj->RTHR0 = tmp; +} + +/*! \brief Gets the transmit channel enable + * + * This function gets the current transmit channel enable. + * + * \param[in] obj : pointer to I2SM register instance + * \return transmit channel enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetTer0TxChEn0(const I2smRegType *obj) +{ + return ((obj->TER0 & I2SM_TER0_TXCHEN0_MASK) >> I2SM_TER0_TXCHEN0_SHIFT); +} + +/*! \brief Sets the transmit channel enable + * + * This function sets the transmit channel enable. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of transmit channel enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void I2smReg_SetTer0TxChEn0(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->TER0; + + tmp &= ~I2SM_TER0_TXCHEN0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_TER0_TXCHEN0_SHIFT)) & I2SM_TER0_TXCHEN0_MASK); + obj->TER0 = tmp; +} + +/*! \brief Gets the transmit data width + * + * This function gets the current transmit data width. + * These bits are used to program the data resolution of the transmitter and ensures the MSB of the data is transmitted first. + * + * \param[in] obj : pointer to I2SM register instance + * \return transmit data width + * - 0h : ignore + * - 1h : 12bit data + * - 2h : 16bit data + * - 3h : 20bit data + * - 4h : 24bit data + * - 5h : 32bit data + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetTcr0TxWLen(const I2smRegType *obj) +{ + return ((obj->TCR0 & I2SM_TCR0_TX_WLEN_MASK) >> I2SM_TCR0_TX_WLEN_SHIFT); +} + +/*! \brief Sets the transmit data width + * + * This function sets the transmit data width. + * These bits are used to program the data resolution of the transmitter and ensures the MSB of the data is transmitted first. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of transmit data width + * - 0h : ignore + * - 1h : 12bit data + * - 2h : 16bit data + * - 3h : 20bit data + * - 4h : 24bit data + * - 5h : 32bit data + */ +__attribute__((always_inline)) static inline void I2smReg_SetTcr0TxWLen(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->TCR0; + + tmp &= ~I2SM_TCR0_TX_WLEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_TCR0_TX_WLEN_SHIFT)) & I2SM_TCR0_TX_WLEN_MASK); + obj->TCR0 = tmp; +} + +/*! \brief Gets the TX FIFO write status + * + * This function gets the current TX FIFO write status. + * + * \param[in] obj : pointer to I2SM register instance + * \return TX FIFO write status + * - 0b : TX FIFO write valid + * - 1b : TX FIFO write overrun + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetIsr0TxFO(const I2smRegType *obj) +{ + return ((obj->ISR0 & I2SM_ISR0_TXFO_MASK) >> I2SM_ISR0_TXFO_SHIFT); +} + +/*! \brief Gets the TX FIFO reached trigger level + * + * This function gets the current TX FIFO reached trigger level. + * This bit specifies whether the TX FIFO trigger level has reached or not. TX FIFO is empty. + * + * \param[in] obj : pointer to I2SM register instance + * \return TX FIFO reached trigger level + * - 0b : TX FIFO trigger level is reached + * - 1b : TX FIFO trigger level is not reached + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetIsr0TxFE(const I2smRegType *obj) +{ + return ((obj->ISR0 & I2SM_ISR0_TXFE_MASK) >> I2SM_ISR0_TXFE_SHIFT); +} + +/*! \brief Gets the TX FIFO overrun interrupt mask + * + * This function gets the current TX FIFO overrun interrupt mask. + * + * \param[in] obj : pointer to I2SM register instance + * \return TX FIFO overrun interrupt mask + * - 0b : unmasks TX FIFO overrun interrupt + * - 1b : mask TX FIFO overrun interrupt + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetImr0TxFom(const I2smRegType *obj) +{ + return ((obj->IMR0 & I2SM_IMR0_TXFOM_MASK) >> I2SM_IMR0_TXFOM_SHIFT); +} + +/*! \brief Sets the TX FIFO overrun interrupt mask + * + * This function sets the TX FIFO overrun interrupt mask. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of TX FIFO overrun interrupt mask + * - 0b : unmasks TX FIFO overrun interrupt + * - 1b : mask TX FIFO overrun interrupt + */ +__attribute__((always_inline)) static inline void I2smReg_SetImr0TxFom(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IMR0; + + tmp &= ~I2SM_IMR0_TXFOM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_IMR0_TXFOM_SHIFT)) & I2SM_IMR0_TXFOM_MASK); + obj->IMR0 = tmp; +} + +/*! \brief Gets the TX FIFO empty interrupt mask + * + * This function gets the current TX FIFO empty interrupt mask. + * + * \param[in] obj : pointer to I2SM register instance + * \return TX FIFO empty interrupt mask + * - 0b : unmasks TX FIFO empty interrupt + * - 1b : mask TX FIFO empty interrupt + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetImr0TxFem(const I2smRegType *obj) +{ + return ((obj->IMR0 & I2SM_IMR0_TXFEM_MASK) >> I2SM_IMR0_TXFEM_SHIFT); +} + +/*! \brief Sets the TX FIFO empty interrupt mask + * + * This function sets the TX FIFO empty interrupt mask. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of TX FIFO empty interrupt mask + * - 0b : unmasks TX FIFO empty interrupt + * - 1b : mask TX FIFO empty interrupt + */ +__attribute__((always_inline)) static inline void I2smReg_SetImr0TxFem(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IMR0; + + tmp &= ~I2SM_IMR0_TXFEM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_IMR0_TXFEM_SHIFT)) & I2SM_IMR0_TXFEM_MASK); + obj->IMR0 = tmp; +} + +/*! \brief Gets the TX FIFO write overrun + * + * This function gets the current TX FIFO write overrun. + * + * \param[in] obj : pointer to I2SM register instance + * \return TX FIFO write overrun + * - 0b : TX FIFO write valid + * - 1b : TX FIFO write overrun + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetTor0TxChO(const I2smRegType *obj) +{ + return ((obj->TOR0 & I2SM_TOR0_TXCHO_MASK) >> I2SM_TOR0_TXCHO_SHIFT); +} + +/*! \brief Sets the TX FIFO write overrun + * + * This function sets the TX FIFO write overrun. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of TX FIFO write overrun + * - 0b : TX FIFO write valid + * - 1b : TX FIFO write overrun + */ +__attribute__((always_inline)) static inline void I2smReg_SetTor0TxChO(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->TOR0; + + tmp &= ~I2SM_TOR0_TXCHO_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_TOR0_TXCHO_SHIFT)) & I2SM_TOR0_TXCHO_MASK); + obj->TOR0 = tmp; +} + +/*! \brief Gets the FIFO level trigger + * + * This function gets the current FIFO level trigger. + * When the FIFO level reaches the register, interrupt triggers. + * These bits program the trigger level in the RX FIFO at which the Received Data Available interrupt is generated. + * Trigger Level = Programmed Value + 1 + * If an illegal value is programmed, these bits saturate to (I2S_RX_FIFO_x - 1). + * The channel must be disabled prior to any changes in this value (that is, RER0[0] = 0). + * + * \param[in] obj : pointer to I2SM register instance + * \return FIFO level trigger + * - 0h : 1 + * - 1h : 2 + * - 2h : 3 + * - 3h : 4 + * - 4h : 5 + * - 5h : 6 + * - 6h : 7 + * - 7h : 8 + * - ... + * - Fh : 16 + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetTfcr0Tfcr0(const I2smRegType *obj) +{ + return ((obj->TFCR0 & I2SM_TFCR0_TFCR0_MASK) >> I2SM_TFCR0_TFCR0_SHIFT); +} + +/*! \brief Sets the FIFO level trigger + * + * This function sets the FIFO level trigger. + * When the FIFO level reaches the register, interrupt triggers. + * These bits program the trigger level in the RX FIFO at which the Received Data Available interrupt is generated. + * Trigger Level = Programmed Value + 1 + * If an illegal value is programmed, these bits saturate to (I2S_RX_FIFO_x - 1). + * The channel must be disabled prior to any changes in this value (that is, RER0[0] = 0). + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of FIFO level trigger + * - 0h : 1 + * - 1h : 2 + * - 2h : 3 + * - 3h : 4 + * - 4h : 5 + * - 5h : 6 + * - 6h : 7 + * - 7h : 8 + * - ... + * - Fh : 16 + */ +__attribute__((always_inline)) static inline void I2smReg_SetTfcr0Tfcr0(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->TFCR0; + + tmp &= ~I2SM_TFCR0_TFCR0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_TFCR0_TFCR0_SHIFT)) & I2SM_TFCR0_TFCR0_MASK); + obj->TFCR0 = tmp; +} + +/*! \brief Sets the TX FIFO flush + * + * This function sets the TX FIFO flush. + * Writing a 1 to this register flushes channel's TX FIFO (This is a self clearing bit.). + * The TX channel or block must be disabled prior to writing to this bit. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of TX FIFO flush + * - 0b : Does not flush an individual TX FIFO + * - 1b : flush an individual TX FIFO + */ +__attribute__((always_inline)) static inline void I2smReg_SetTff0TxChfr0(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->TFF0; + + tmp &= ~I2SM_TFF0_TXCHFR0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_TFF0_TXCHFR0_SHIFT)) & I2SM_TFF0_TXCHFR0_MASK); + obj->TFF0 = tmp; +} + +/*! \brief Sets the Transmitter Block DMA Register + * + * This function sets the Transmitter Block DMA Register. + * The register bits can be used to cycle repeatedly through the enabled Transmit channels (from lowest numbered to + * highest) to allow writing of stereo data pairs + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of Transmitter Block DMA Register + */ +__attribute__((always_inline)) static inline void I2smReg_SetTxDmaTxDma(I2smRegType *obj, uint32_t value) +{ + uint32_t tmp = obj->TXDMA; + + tmp &= ~I2SM_TXDMA_TXDMA_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_TXDMA_TXDMA_SHIFT)) & I2SM_TXDMA_TXDMA_MASK); + obj->TXDMA = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _I2SM_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/i2ss_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/i2ss_reg.h new file mode 100644 index 0000000..d815bf7 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/i2ss_reg.h @@ -0,0 +1,549 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _I2SS_REG_H_ +#define _I2SS_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the I2SS Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* IER Bit Fields */ +#define I2SS_IER_EN_MASK (0x01u) +#define I2SS_IER_EN_SHIFT (0u) +#define I2SS_IER_EN_WIDTH (1u) + +/* IRER Bit Fields */ +#define I2SS_IRER_RXEN_MASK (0x01u) +#define I2SS_IRER_RXEN_SHIFT (0u) +#define I2SS_IRER_RXEN_WIDTH (1u) + +/* RXFFR Bit Fields */ +#define I2SS_RXFFR_RXFFR_MASK (0x01u) +#define I2SS_RXFFR_RXFFR_SHIFT (0u) +#define I2SS_RXFFR_RXFFR_WIDTH (1u) + +/* LRBR0 Bit Fields */ +#define I2SS_LRBR0_LRBR0_MASK (0x01u) +#define I2SS_LRBR0_LRBR0_SHIFT (0u) +#define I2SS_LRBR0_LRBR0_WIDTH (1u) + +/* RRBR0 Bit Fields */ +#define I2SS_RRBR0_RRBR0_MASK (0x01u) +#define I2SS_RRBR0_RRBR0_SHIFT (0u) +#define I2SS_RRBR0_RRBR0_WIDTH (1u) + +/* RER0 Bit Fields */ +#define I2SS_RER0_CH0_MASK (0x01u) +#define I2SS_RER0_CH0_SHIFT (0u) +#define I2SS_RER0_CH0_WIDTH (1u) + +/* RCR0 Bit Fields */ +#define I2SS_RCR0_RX_WLEN_MASK (0x07u) +#define I2SS_RCR0_RX_WLEN_SHIFT (0u) +#define I2SS_RCR0_RX_WLEN_WIDTH (3u) + +/* ISR0 Bit Fields */ +#define I2SS_ISR0_RXFO_MASK (0x02u) +#define I2SS_ISR0_RXFO_SHIFT (1u) +#define I2SS_ISR0_RXFO_WIDTH (1u) +#define I2SS_ISR0_RXDA_MASK (0x01u) +#define I2SS_ISR0_RXDA_SHIFT (0u) +#define I2SS_ISR0_RXDA_WIDTH (1u) + +/* IMR0 Bit Fields */ +#define I2SS_IMR0_RXFOM_MASK (0x02u) +#define I2SS_IMR0_RXFOM_SHIFT (1u) +#define I2SS_IMR0_RXFOM_WIDTH (1u) +#define I2SS_IMR0_RXDAM_MASK (0x01u) +#define I2SS_IMR0_RXDAM_SHIFT (0u) +#define I2SS_IMR0_RXDAM_WIDTH (1u) + +/* ROR0 Bit Fields */ +#define I2SS_ROR0_RXCHO_MASK (0x01u) +#define I2SS_ROR0_RXCHO_SHIFT (0u) +#define I2SS_ROR0_RXCHO_WIDTH (1u) + +/* RFCR0 Bit Fields */ +#define I2SS_RFCR0_RXCHDT_MASK (0x0Fu) +#define I2SS_RFCR0_RXCHDT_SHIFT (0u) +#define I2SS_RFCR0_RXCHDT_WIDTH (4u) + +/* RFF0 Bit Fields */ +#define I2SS_RFF0_RXCHFR0_MASK (0x01u) +#define I2SS_RFF0_RXCHFR0_SHIFT (0u) +#define I2SS_RFF0_RXCHFR0_WIDTH (1u) + +/* RXDMA Bit Fields */ +#define I2SS_RXDMA_RXDMA_MASK (0xFFFFFFFFu) +#define I2SS_RXDMA_RXDMA_SHIFT (0u) +#define I2SS_RXDMA_RXDMA_WIDTH (32u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of I2SS registers + */ +typedef struct _I2ssRegType_ +{ + volatile uint32_t IER; /*!< module enable, offset: 0x00 */ + volatile uint32_t IRER; /*!< receiver block enable, offset: 0x04 */ + uint32_t RESERVED0[3]; /*!< Reserverd block, offset: 0x08 */ + volatile uint32_t RXFFR; /*!< RX FIFO reset, offset: 0x14 */ + uint32_t RESERVED1[2]; /*!< Reserverd block, offset: 0x18 */ + const volatile uint32_t LRBR0; /*!< left receive buffer, offset: 0x20 */ + const volatile uint32_t RRBR0; /*!< right receive buffer, offset: 0x24 */ + volatile uint32_t RER0; /*!< receive channel0 enable, offset: 0x28 */ + uint32_t RESERVED2[1]; /*!< Reserverd block, offset: 0x2C */ + volatile uint32_t RCR0; /*!< receive configuration, offset: 0x30 */ + uint32_t RESERVED3[1]; /*!< Reserverd block, offset: 0x34 */ + const volatile uint32_t ISR0; /*!< interrupt status, offset: 0x38 */ + volatile uint32_t IMR0; /*!< interrupt mask, offset: 0x3C */ + volatile uint32_t ROR0; /*!< receive overrun, offset: 0x40 */ + uint32_t RESERVED4[1]; /*!< Reserverd block, offset: 0x44 */ + volatile uint32_t RFCR0; /*!< RX FIFO configuration, offset: 0x48 */ + uint32_t RESERVED5[1]; /*!< Reserverd block, offset: 0x4C */ + volatile uint32_t RFF0; /*!< RX FIFO flush, offset: 0x50 */ + uint32_t RESERVED6[91]; /*!< Reserverd block, offset: 0x54 */ + const volatile uint32_t RXDMA; /*!< Receive DMA register, offset: 0x1C0 */ +} I2ssRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the IP enable + * + * This function gets the current IP enable. + * + * \param[in] obj : pointer to I2SS register instance + * \return IP enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetIerEn(const I2ssRegType *obj) +{ + return ((obj->IER & I2SS_IER_EN_MASK) >> I2SS_IER_EN_SHIFT); +} + +/*! \brief Sets the IP enable + * + * This function sets the IP enable. + * + * \param[in] obj : pointer to I2SS register instance + * \param[in] value : the value of IP enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void I2ssReg_SetIerEn(I2ssRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IER; + + tmp &= ~I2SS_IER_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SS_IER_EN_SHIFT)) & I2SS_IER_EN_MASK); + obj->IER = tmp; +} + +/*! \brief Gets the receiver block enable + * + * This function gets the current receiver block enable. + * It enables or disables the receiver. + * + * \param[in] obj : pointer to I2SS register instance + * \return receiver block enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetIrerRxEn(const I2ssRegType *obj) +{ + return ((obj->IRER & I2SS_IRER_RXEN_MASK) >> I2SS_IRER_RXEN_SHIFT); +} + +/*! \brief Sets the receiver block enable + * + * This function sets the receiver block enable. + * It enables or disables the receiver. + * + * \param[in] obj : pointer to I2SS register instance + * \param[in] value : the value of receiver block enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void I2ssReg_SetIrerRxEn(I2ssRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IRER; + + tmp &= ~I2SS_IRER_RXEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SS_IRER_RXEN_SHIFT)) & I2SS_IRER_RXEN_MASK); + obj->IRER = tmp; +} + +/*! \brief Sets the RX FIFO reset + * + * This function sets the RX FIFO reset. + * Writing a 1 to this register flushes all the FIFOs (this is a self clearing bit). + * The Transmitter Block must be disabled prior to writing this bit. + * + * \param[in] obj : pointer to I2SS register instance + * \param[in] value : the value of RX FIFO reset + * - 0b : does not flush the FIFO + * - 1b : flush the FIFO + */ +__attribute__((always_inline)) static inline void I2ssReg_SetRxffrRxffr(I2ssRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RXFFR; + + tmp &= ~I2SS_RXFFR_RXFFR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SS_RXFFR_RXFFR_SHIFT)) & I2SS_RXFFR_RXFFR_MASK); + obj->RXFFR = tmp; +} + +/*! \brief Gets the left stereo data + * + * This function gets the current left stereo data. + * The left stereo data received serially from the receive channel input + * + * \param[in] obj : pointer to I2SS register instance + * \return left stereo data + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetLrbr0Lrbr0(const I2ssRegType *obj) +{ + return ((obj->LRBR0 & I2SS_LRBR0_LRBR0_MASK) >> I2SS_LRBR0_LRBR0_SHIFT); +} + +/*! \brief Gets the right stereo data + * + * This function gets the current right stereo data. + * The right stereo data received serially from the receive channel input + * + * \param[in] obj : pointer to I2SS register instance + * \return right stereo data + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetRrbr0Rrbr0(const I2ssRegType *obj) +{ + return ((obj->RRBR0 & I2SS_RRBR0_RRBR0_MASK) >> I2SS_RRBR0_RRBR0_SHIFT); +} + +/*! \brief Gets the receive channel enable + * + * This function gets the current receive channel enable. + * + * \param[in] obj : pointer to I2SS register instance + * \return receive channel enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetRer0Ch0(const I2ssRegType *obj) +{ + return ((obj->RER0 & I2SS_RER0_CH0_MASK) >> I2SS_RER0_CH0_SHIFT); +} + +/*! \brief Sets the receive channel enable + * + * This function sets the receive channel enable. + * + * \param[in] obj : pointer to I2SS register instance + * \param[in] value : the value of receive channel enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void I2ssReg_SetRer0Ch0(I2ssRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RER0; + + tmp &= ~I2SS_RER0_CH0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SS_RER0_CH0_SHIFT)) & I2SS_RER0_CH0_MASK); + obj->RER0 = tmp; +} + +/*! \brief Gets the receive data width + * + * This function gets the current receive data width. + * These bits are used to program the data resolution of the receiver and ensures the MSB of the data is transmitted first. + * + * \param[in] obj : pointer to I2SS register instance + * \return receive data width + * - 0h : ignore + * - 1h : 12bit data + * - 2h : 16bit data + * - 3h : 20bit data + * - 4h : 24bit data + * - 5h : 32bit data + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetRcr0RxWLen(const I2ssRegType *obj) +{ + return ((obj->RCR0 & I2SS_RCR0_RX_WLEN_MASK) >> I2SS_RCR0_RX_WLEN_SHIFT); +} + +/*! \brief Sets the receive data width + * + * This function sets the receive data width. + * These bits are used to program the data resolution of the receiver and ensures the MSB of the data is transmitted first. + * + * \param[in] obj : pointer to I2SS register instance + * \param[in] value : the value of receive data width + * - 0h : ignore + * - 1h : 12bit data + * - 2h : 16bit data + * - 3h : 20bit data + * - 4h : 24bit data + * - 5h : 32bit data + */ +__attribute__((always_inline)) static inline void I2ssReg_SetRcr0RxWLen(I2ssRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RCR0; + + tmp &= ~I2SS_RCR0_RX_WLEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SS_RCR0_RX_WLEN_SHIFT)) & I2SS_RCR0_RX_WLEN_MASK); + obj->RCR0 = tmp; +} + +/*! \brief Gets the RX FIFO data overrun interrupt + * + * This function gets the current RX FIFO data overrun interrupt. + * Incoming data lost due to a full RX FIFO. + * + * \param[in] obj : pointer to I2SS register instance + * \return RX FIFO data overrun interrupt + * - 0b : RX FIFO write valid + * - 1b : RX FIFO write overrun + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetIsr0RxFo(const I2ssRegType *obj) +{ + return ((obj->ISR0 & I2SS_ISR0_RXFO_MASK) >> I2SS_ISR0_RXFO_SHIFT); +} + +/*! \brief Gets the Status of Receive Data Available interrupt + * + * This function gets the current Status of Receive Data Available interrupt. + * This bit denotes the status of the RX FIFO trigger level. + * + * \param[in] obj : pointer to I2SS register instance + * \return Status of Receive Data Available interrupt + * - 0b : RX FIFO trigger level is reached + * - 1b : RX FIFO trigger level is not reached + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetIsr0RxDa(const I2ssRegType *obj) +{ + return ((obj->ISR0 & I2SS_ISR0_RXDA_MASK) >> I2SS_ISR0_RXDA_SHIFT); +} + +/*! \brief Gets the RX FIFO overrun interrupt mask + * + * This function gets the current RX FIFO overrun interrupt mask. + * + * \param[in] obj : pointer to I2SS register instance + * \return RX FIFO overrun interrupt mask + * - 0b : unmasks RX FIFO overrun interrupt + * - 1b : mask RX FIFO overrun interrupt + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetImr0RxFom(const I2ssRegType *obj) +{ + return ((obj->IMR0 & I2SS_IMR0_RXFOM_MASK) >> I2SS_IMR0_RXFOM_SHIFT); +} + +/*! \brief Sets the RX FIFO overrun interrupt mask + * + * This function sets the RX FIFO overrun interrupt mask. + * + * \param[in] obj : pointer to I2SS register instance + * \param[in] value : the value of RX FIFO overrun interrupt mask + * - 0b : unmasks RX FIFO overrun interrupt + * - 1b : mask RX FIFO overrun interrupt + */ +__attribute__((always_inline)) static inline void I2ssReg_SetImr0RxFom(I2ssRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IMR0; + + tmp &= ~I2SS_IMR0_RXFOM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SS_IMR0_RXFOM_SHIFT)) & I2SS_IMR0_RXFOM_MASK); + obj->IMR0 = tmp; +} + +/*! \brief Gets the Mask RX FIFO Data Available interrupt. + * + * This function gets the current Mask RX FIFO Data Available interrupt. + * This bit masks or unmasks an RX FIFO Data Available interrupt. + * + * \param[in] obj : pointer to I2SS register instance + * \return Mask RX FIFO Data Available interrupt. + * - 1b : Masks RX FIFO data available interrupt + * - 0b : Unmasks RX FIFO data available interrupt + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetImr0RxDam(const I2ssRegType *obj) +{ + return ((obj->IMR0 & I2SS_IMR0_RXDAM_MASK) >> I2SS_IMR0_RXDAM_SHIFT); +} + +/*! \brief Sets the Mask RX FIFO Data Available interrupt. + * + * This function sets the Mask RX FIFO Data Available interrupt. + * This bit masks or unmasks an RX FIFO Data Available interrupt. + * + * \param[in] obj : pointer to I2SS register instance + * \param[in] value : the value of Mask RX FIFO Data Available interrupt. + * - 1b : Masks RX FIFO data available interrupt + * - 0b : Unmasks RX FIFO data available interrupt + */ +__attribute__((always_inline)) static inline void I2ssReg_SetImr0RxDam(I2ssRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IMR0; + + tmp &= ~I2SS_IMR0_RXDAM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SS_IMR0_RXDAM_SHIFT)) & I2SS_IMR0_RXDAM_MASK); + obj->IMR0 = tmp; +} + +/*! \brief Gets the RX FIFO write overrun + * + * This function gets the current RX FIFO write overrun. + * + * \param[in] obj : pointer to I2SS register instance + * \return RX FIFO write overrun + * - 0b : RX FIFO write valid + * - 1b : RX FIFO write overrun + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetRor0RxChO(const I2ssRegType *obj) +{ + return ((obj->ROR0 & I2SS_ROR0_RXCHO_MASK) >> I2SS_ROR0_RXCHO_SHIFT); +} + +/*! \brief Sets the RX FIFO write overrun + * + * This function sets the RX FIFO write overrun. + * + * \param[in] obj : pointer to I2SS register instance + * \param[in] value : the value of RX FIFO write overrun + * - 0b : RX FIFO write valid + * - 1b : RX FIFO write overrun + */ +__attribute__((always_inline)) static inline void I2ssReg_SetRor0RxChO(I2ssRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ROR0; + + tmp &= ~I2SS_ROR0_RXCHO_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SS_ROR0_RXCHO_SHIFT)) & I2SS_ROR0_RXCHO_MASK); + obj->ROR0 = tmp; +} + +/*! \brief Gets the FIFO level trigger interrupt + * + * This function gets the current FIFO level trigger interrupt. + * When the FIFO level reaches the register, interrupt triggers. + * + * \param[in] obj : pointer to I2SS register instance + * \return FIFO level trigger interrupt + * - 0h : 1 + * - 1h : 2 + * - 2h : 3 + * - 3h : 4 + * - 4h : 5 + * - 5h : 6 + * - 6h : 7 + * - 7h : 8 + * - ... + * - Fh : 16 + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetRfcr0RxChdt(const I2ssRegType *obj) +{ + return ((obj->RFCR0 & I2SS_RFCR0_RXCHDT_MASK) >> I2SS_RFCR0_RXCHDT_SHIFT); +} + +/*! \brief Sets the FIFO level trigger interrupt + * + * This function sets the FIFO level trigger interrupt. + * When the FIFO level reaches the register, interrupt triggers. + * + * \param[in] obj : pointer to I2SS register instance + * \param[in] value : the value of FIFO level trigger interrupt + * - 0h : 1 + * - 1h : 2 + * - 2h : 3 + * - 3h : 4 + * - 4h : 5 + * - 5h : 6 + * - 6h : 7 + * - 7h : 8 + * - ... + * - Fh : 16 + */ +__attribute__((always_inline)) static inline void I2ssReg_SetRfcr0RxChdt(I2ssRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RFCR0; + + tmp &= ~I2SS_RFCR0_RXCHDT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SS_RFCR0_RXCHDT_SHIFT)) & I2SS_RFCR0_RXCHDT_MASK); + obj->RFCR0 = tmp; +} + +/*! \brief Sets the RX FIFO flush + * + * This function sets the RX FIFO flush. + * Writing a 1 to this register flushes an individual RX FIFO (This is a self clearing bit.). + * A Rx channel or block must be disabled prior to writing to this bit. + * + * \param[in] obj : pointer to I2SS register instance + * \param[in] value : the value of RX FIFO flush + * - 0b : Does not flush an individual RX FIFO + * - 1b : flush an individual RX FIFO + */ +__attribute__((always_inline)) static inline void I2ssReg_SetRff0RxChfr0(I2ssRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RFF0; + + tmp &= ~I2SS_RFF0_RXCHFR0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SS_RFF0_RXCHFR0_SHIFT)) & I2SS_RFF0_RXCHFR0_MASK); + obj->RFF0 = tmp; +} + +/*! \brief Gets the Receive Block DMA Register + * + * This function gets the current Receive Block DMA Register. + * These bits are used to cycle repeatedly through the enabled receive channels (from lowest numbered to highest), + * reading stereo data pairs + * + * \param[in] obj : pointer to I2SS register instance + * \return Receive Block DMA Register + */ +__attribute__((always_inline)) static inline uint32_t I2ssReg_GetRxDmaRxDma(const I2ssRegType *obj) +{ + return ((obj->RXDMA & I2SS_RXDMA_RXDMA_MASK) >> I2SS_RXDMA_RXDMA_SHIFT); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _I2SS_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/lpit_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/lpit_reg.h new file mode 100644 index 0000000..51dd74e --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/lpit_reg.h @@ -0,0 +1,813 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _LPIT_REG_H_ +#define _LPIT_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the LPIT (Low Power Interrupt Timer) Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* Size of TMR Registers Arrays */ +#define LPIT_TMR_COUNT (4) + +/* VERID Bit Fields */ +#define LPIT_VERID_VERID_MASK (0xFFFFFFFFu) +#define LPIT_VERID_VERID_SHIFT (0u) +#define LPIT_VERID_VERID_WIDTH (32u) + +/* PARAM Bit Fields */ +#define LPIT_PARAM_CHANNEL_MASK (0xFFu) +#define LPIT_PARAM_CHANNEL_SHIFT (0u) +#define LPIT_PARAM_CHANNEL_WIDTH (8u) +#define LPIT_PARAM_EXT_TRIG_MASK (0xFF00u) +#define LPIT_PARAM_EXT_TRIG_SHIFT (8u) +#define LPIT_PARAM_EXT_TRIG_WIDTH (8u) + +/* MCR Bit Fields */ +#define LPIT_MCR_M_CEN_MASK (0x1u) +#define LPIT_MCR_M_CEN_SHIFT (0u) +#define LPIT_MCR_M_CEN_WIDTH (1u) +#define LPIT_MCR_LP_EN_MASK (0x4u) +#define LPIT_MCR_LP_EN_SHIFT (2u) +#define LPIT_MCR_LP_EN_WIDTH (1u) +#define LPIT_MCR_DBG_EN_MASK (0x8u) +#define LPIT_MCR_DBG_EN_SHIFT (3u) +#define LPIT_MCR_DBG_EN_WIDTH (1u) + +/* MSR Bit Fields */ +#define LPIT_MSR_TIF0_MASK (0x1u) +#define LPIT_MSR_TIF0_SHIFT (0u) +#define LPIT_MSR_TIF0_WIDTH (1u) +#define LPIT_MSR_TIF1_MASK (0x2u) +#define LPIT_MSR_TIF1_SHIFT (1u) +#define LPIT_MSR_TIF1_WIDTH (1u) +#define LPIT_MSR_TIF2_MASK (0x4u) +#define LPIT_MSR_TIF2_SHIFT (2u) +#define LPIT_MSR_TIF2_WIDTH (1u) +#define LPIT_MSR_TIF3_MASK (0x8u) +#define LPIT_MSR_TIF3_SHIFT (3u) +#define LPIT_MSR_TIF3_WIDTH (1u) + +/* MIER Bit Fields */ +#define LPIT_MIER_TIE0_MASK (0x1u) +#define LPIT_MIER_TIE0_SHIFT (0u) +#define LPIT_MIER_TIE0_WIDTH (1u) +#define LPIT_MIER_TIE1_MASK (0x2u) +#define LPIT_MIER_TIE1_SHIFT (1u) +#define LPIT_MIER_TIE1_WIDTH (1u) +#define LPIT_MIER_TIE2_MASK (0x4u) +#define LPIT_MIER_TIE2_SHIFT (2u) +#define LPIT_MIER_TIE2_WIDTH (1u) +#define LPIT_MIER_TIE3_MASK (0x8u) +#define LPIT_MIER_TIE3_SHIFT (3u) +#define LPIT_MIER_TIE3_WIDTH (1u) + +/* SETTEN Bit Fields */ +#define LPIT_SETTEN_SET_T_EN_0_MASK (0x1u) +#define LPIT_SETTEN_SET_T_EN_0_SHIFT (0u) +#define LPIT_SETTEN_SET_T_EN_0_WIDTH (1u) +#define LPIT_SETTEN_SET_T_EN_1_MASK (0x2u) +#define LPIT_SETTEN_SET_T_EN_1_SHIFT (1u) +#define LPIT_SETTEN_SET_T_EN_1_WIDTH (1u) +#define LPIT_SETTEN_SET_T_EN_2_MASK (0x4u) +#define LPIT_SETTEN_SET_T_EN_2_SHIFT (2u) +#define LPIT_SETTEN_SET_T_EN_2_WIDTH (1u) +#define LPIT_SETTEN_SET_T_EN_3_MASK (0x8u) +#define LPIT_SETTEN_SET_T_EN_3_SHIFT (3u) +#define LPIT_SETTEN_SET_T_EN_3_WIDTH (1u) + +/* CLRTEN Bit Fields */ +#define LPIT_CLRTEN_CLR_T_EN_0_MASK (0x1u) +#define LPIT_CLRTEN_CLR_T_EN_0_SHIFT (0u) +#define LPIT_CLRTEN_CLR_T_EN_0_WIDTH (1u) +#define LPIT_CLRTEN_CLR_T_EN_1_MASK (0x2u) +#define LPIT_CLRTEN_CLR_T_EN_1_SHIFT (1u) +#define LPIT_CLRTEN_CLR_T_EN_1_WIDTH (1u) +#define LPIT_CLRTEN_CLR_T_EN_2_MASK (0x4u) +#define LPIT_CLRTEN_CLR_T_EN_2_SHIFT (2u) +#define LPIT_CLRTEN_CLR_T_EN_2_WIDTH (1u) +#define LPIT_CLRTEN_CLR_T_EN_3_MASK (0x8u) +#define LPIT_CLRTEN_CLR_T_EN_3_SHIFT (3u) +#define LPIT_CLRTEN_CLR_T_EN_3_WIDTH (1u) + +/* TMR_TVAL Bit Fields */ +#define LPIT_TMR_TVAL_TMR_VAL_MASK (0xFFFFFFFFu) +#define LPIT_TMR_TVAL_TMR_VAL_SHIFT (0u) +#define LPIT_TMR_TVAL_TMR_VAL_WIDTH (32u) + +/* TMR_CVAL Bit Fields */ +#define LPIT_TMR_CVAL_TMR_CUR_VAL_MASK (0xFFFFFFFFu) +#define LPIT_TMR_CVAL_TMR_CUR_VAL_SHIFT (0u) +#define LPIT_TMR_CVAL_TMR_CUR_VAL_WIDTH (32u) + +/* TMR_TCTRL Bit Fields */ +#define LPIT_TMR_TCTRL_T_EN_MASK (0x1u) +#define LPIT_TMR_TCTRL_T_EN_SHIFT (0u) +#define LPIT_TMR_TCTRL_T_EN_WIDTH (1u) +#define LPIT_TMR_TCTRL_CHAIN_MASK (0x2u) +#define LPIT_TMR_TCTRL_CHAIN_SHIFT (1u) +#define LPIT_TMR_TCTRL_CHAIN_WIDTH (1u) +#define LPIT_TMR_TCTRL_MODE_MASK (0xCu) +#define LPIT_TMR_TCTRL_MODE_SHIFT (2u) +#define LPIT_TMR_TCTRL_MODE_WIDTH (2u) +#define LPIT_TMR_TCTRL_TSOT_MASK (0x10000u) +#define LPIT_TMR_TCTRL_TSOT_SHIFT (16u) +#define LPIT_TMR_TCTRL_TSOT_WIDTH (1u) +#define LPIT_TMR_TCTRL_TSOI_MASK (0x20000u) +#define LPIT_TMR_TCTRL_TSOI_SHIFT (17u) +#define LPIT_TMR_TCTRL_TSOI_WIDTH (1u) +#define LPIT_TMR_TCTRL_TROT_MASK (0x40000u) +#define LPIT_TMR_TCTRL_TROT_SHIFT (18u) +#define LPIT_TMR_TCTRL_TROT_WIDTH (1u) +#define LPIT_TMR_TCTRL_TRG_SRC_MASK (0x800000u) +#define LPIT_TMR_TCTRL_TRG_SRC_SHIFT (23u) +#define LPIT_TMR_TCTRL_TRG_SRC_WIDTH (1u) +#define LPIT_TMR_TCTRL_TRG_SEL_MASK (0xF000000u) +#define LPIT_TMR_TCTRL_TRG_SEL_SHIFT (24u) +#define LPIT_TMR_TCTRL_TRG_SEL_WIDTH (4u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of LPIT registers + */ +typedef struct _LpitRegType_ +{ + const volatile uint32_t VERID; /*!< Version ID Register, offset: 0x0 */ + const volatile uint32_t PARAM; /*!< Parameter Register, offset: 0x4 */ + volatile uint32_t MCR; /*!< Module Control Register, offset: 0x8 */ + volatile uint32_t MSR; /*!< Module Status Register, offset: 0xC */ + volatile uint32_t MIER; /*!< Module Interrupt Enable Register, offset: 0x10 */ + volatile uint32_t SETTEN; /*!< Set Timer Enable Register, offset: 0x14 */ + volatile uint32_t CLRTEN; /*!< Clear Timer Enable Register, offset: 0x18 */ + uint32_t RESERVED; /*!< Reserved register, offset: 0x1C */ + struct + { /* offset: 0x20, array step: 0x10 */ + volatile uint32_t TVAL; /*!< Timer Value Register, array offset: 0x20, array step: 0x10 */ + const volatile uint32_t CVAL; /*!< Current Timer Value, array offset: 0x24, array step: 0x10 */ + volatile uint32_t TCTRL; /*!< Timer Control Register, array offset: 0x28, array step: 0x10 */ + uint32_t RESERVED; /*!< Reserved register, offset: 0x2C */ + } TMR[LPIT_TMR_COUNT]; +} LpitRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Get the version ID of LPIT module. + * + * This function returns the version ID of LPIT module of this chip + * + * \param[in] obj : pointer to LPIT register instance + * \return the version ID + */ +__attribute__((always_inline)) static inline uint32_t LpitReg_GetVersion(const LpitRegType *obj) +{ + return ((obj->VERID & LPIT_VERID_VERID_MASK) >> LPIT_VERID_VERID_SHIFT); +} + +/*! \brief Get the number of Timer Channels. + * + * This function returns the number of Timer Channels in this device + * + * \param[in] obj : pointer to LPIT register instance + * \return the number of Timer Channels + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetTimerChannelNum(const LpitRegType *obj) +{ + return ((obj->PARAM & LPIT_PARAM_CHANNEL_MASK) >> LPIT_PARAM_CHANNEL_SHIFT); +} + +/*! \brief Get the number of external triggers input. + * + * This function returns the external triggers implemented in this device + * + * \param[in] obj : pointer to LPIT register instance + * \return the number of external triggers input + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetExtTriggerNum(const LpitRegType *obj) +{ + return ((obj->PARAM & LPIT_PARAM_EXT_TRIG_MASK) >> LPIT_PARAM_EXT_TRIG_SHIFT); +} + +/*! \brief Enables the LPIT module. + * + * This function enables the functional clock of LPIT module (it does not + * affect the system clock gating control). + * + * \note The M_CEN bit must be asserted when accessing these registers: + * - Module Status Register (MSR) + * - Set Timer Enable Register (SETTEN) + * - Clear Timer Enable Register (CLRTEN) + * - Timer Value Registers (TVALn) + * - Current Timer Value Registers (CVALn) + * - Timer Control Registers (TCTRLn) + * Accessing the above mentioned registers while M_CEN = '0', will assert a transfer error for that bus cycle. + * - 0 : those registers above write disable + * - 1 : those registers above write enable + * + * \param[in] obj : pointer to LPIT register instance + */ +__attribute__((always_inline)) static inline void LpitReg_Enable(LpitRegType *obj) +{ + uint32_t tmp = obj->MCR; + + tmp &= ~LPIT_MCR_M_CEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(1u)) << LPIT_MCR_M_CEN_SHIFT)) & LPIT_MCR_M_CEN_MASK); + obj->MCR = tmp; +} + +/*! \brief Disable the LPIT module. + * + * This function disables functional clock of LPIT module (it does not + * affect the system clock gating control). + * + * \note The M_CEN bit must be asserted when accessing these registers: + * - Module Status Register (MSR) + * - Set Timer Enable Register (SETTEN) + * - Clear Timer Enable Register (CLRTEN) + * - Timer Value Registers (TVALn) + * - Current Timer Value Registers (CVALn) + * - Timer Control Registers (TCTRLn) + * Acessing the above mentioned registers while M_CEN = '0', will assert a transfer error for that bus cycle. + * - 0 : those registers above write disable + * - 1 : those registers above write enable + * + * \param[in] obj : pointer to LPIT register instance + */ +__attribute__((always_inline)) static inline void LpitReg_Disable(LpitRegType *obj) +{ + uint32_t tmp = obj->MCR; + + tmp &= ~LPIT_MCR_M_CEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(0u)) << LPIT_MCR_M_CEN_SHIFT)) & LPIT_MCR_M_CEN_MASK); + obj->MCR = tmp; +} + +/*! \brief Get the current command of LowPower Mode + * + * This function returns the current command of LowPower Mode + * + * \param[in] obj : pointer to LPIT register instance + * \return the current command of LP Mode + * - 0 : stop timer channels in LowPower mode + * - 1 : allow timer channels to continue to run in LP mode + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetLpModeCmd(const LpitRegType *obj) +{ + return ((obj->MCR & LPIT_MCR_LP_EN_MASK) >> LPIT_MCR_LP_EN_SHIFT); +} + +/*! \brief Sets operation of LPIT in LowPower Mode. + * + * When the device enters debug mode, the timer channels may or may not be frozen, + * based on the configuration of this function. The LPIT must use an external or + * internal clock source which remains operating during LowPower mode + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] value : the current command of LowPower Mode + * - 0 : stop timer channels in LP mode + * - 1 : allow timer channels to continue to run in LP mode + */ +__attribute__((always_inline)) static inline void LpitReg_SetLpModeCmd(LpitRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MCR; + + tmp &= ~LPIT_MCR_LP_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << LPIT_MCR_LP_EN_SHIFT)) & LPIT_MCR_LP_EN_MASK); + obj->MCR = tmp; +} + +/*! \brief Get the current command of debug mode + * + * This function returns the current command of debug mode + * + * \param[in] obj : pointer to LPIT register instance + * \return the current command of debug mode + * - 0 : stop timer channels in debug mode + * - 1 : allow timer channels to continue to run in debug mode + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetDebugModeCmd(const LpitRegType *obj) +{ + return ((obj->MCR & LPIT_MCR_DBG_EN_MASK) >> LPIT_MCR_DBG_EN_SHIFT); +} + +/*! \brief Sets operation of LPIT in debug mode. + * + * When the device enters debug mode, the timer channels may or may not be frozen, + * based on the configuration of this function. This is intended to aid software development, + * allowing the developer to halt the processor, investigate the current state of + * the system (for example, the timer channel values), and continue the operation. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] value : the current command of debug mode + * - 0 : stop timer channels in debug mode + * - 1 : allow timer channels to continue to run in debug mode + */ +__attribute__((always_inline)) static inline void LpitReg_SetDebugModeCmd(LpitRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MCR; + + tmp &= ~LPIT_MCR_DBG_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << LPIT_MCR_DBG_EN_SHIFT)) & LPIT_MCR_DBG_EN_MASK); + obj->MCR = tmp; +} + +/*! \brief Gets the interrupt flag of timer channels. + * + * This function gets current interrupt flag of timer channels. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] mask : the interrupt flag getting mask that decides which channels will be got interrupt flag. + * For example: + * - with mask = 0x01u then the interrupt flag of channel 0 only will be got + * - with mask = 0x02u then the interrupt flag of channel 1 only will be got + * - with mask = 0x03u then the interrupt flags of channel 0 and channel 1 will be got + * \return the interrupt flag of timer channels. + */ +__attribute__((always_inline)) static inline uint32_t LpitReg_GetInterruptFlag(const LpitRegType *obj, uint32_t mask) +{ + return (obj->MSR) & mask; +} + +/*! \brief Clears the interrupt flag of timer channels. + * + * This function clears current interrupt flag of timer channels. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] mask : the interrupt flag getting mask that decides which channels will be got interrupt flag. + * For example: + * - with mask = 0x01u then the interrupt flag of channel 0 only will be cleared + * - with mask = 0x02u then the interrupt flag of channel 1 only will be cleared + * - with mask = 0x03u then the interrupt flags of channel 0 and channel 1 will be cleared + */ +__attribute__((always_inline)) static inline void LpitReg_ClearInterruptFlag(LpitRegType *obj, uint32_t mask) +{ + /* Write 1 to clear the interrupt flag. */ + obj->MSR = mask; +} + +/*! \brief Enables the interrupt generation for timer channels. + * + * This function allows enabling interrupt generation for timer channels simultaneously. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] mask : the interrupt enabling mask that decides which channels will be enabled interrupt. + * For example: + * - with mask = 0x01u then will enable interrupt for channel 0 only + * - with mask = 0x02u then will enable interrupt for channel 1 only + * - with mask = 0x03u then will enable interrupt for channel 0 and channel 1 + */ +__attribute__((always_inline)) static inline void LpitReg_EnableInterruptTimerChannels(LpitRegType *obj, uint32_t mask) +{ + obj->MIER |= mask; +} + +/*! \brief Clears the interrupt flag of timer channels. + * + * This function allows disabling interrupt generation for timer channels simultaneously. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] mask : the interrupt disabling mask that decides which channels will be disabled interrupt. + * For example: + * - with mask = 0x01u then will disable interrupt for channel 0 only + * - with mask = 0x02u then will disable interrupt for channel 1 only + * - with mask = 0x03u then will disable interrupt for channel 0 and channel 1 + */ +__attribute__((always_inline)) static inline void LpitReg_DisableInterruptTimerChannels(LpitRegType *obj, uint32_t mask) +{ + obj->MIER &= ~mask; +} + +/*! \brief Starts the timer channel counting. + * + * This function allows starting timer channels simultaneously. + * After calling this function, timer channels are going operate depend on mode and + * control bits which controls timer channel start, reload and restart. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] mask : timer channels starting mask that decides which channels will be started + * For example: + * - with mask = 0x01U then channel 0 will be started + * - with mask = 0x02U then channel 1 will be started + * - with mask = 0x03U then channel 0 and channel 1 will be started + */ +__attribute__((always_inline)) static inline void LpitReg_StartTimerChannels(LpitRegType *obj, uint32_t mask) +{ + obj->SETTEN |= mask; +} + +/*! \brief Stops the timer channel from counting. + * + * This function allows stop timer channels simultaneously from counting. + * Timer channels reload their periods respectively after the next time + * they call the LPIT_DRV_StartTimerChannels. Note that: In 32-bit Trigger Accumulator + * mode, the counter will load on the first trigger rising edge. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] mask : timer channels stopping mask that decides which channels will be stopped + * For example: + * - with mask = 0x01U then channel 0 will be stopped + * - with mask = 0x02U then channel 1 will be stopped + * - with mask = 0x03U then channel 0 and channel 1 will be stopped + */ +__attribute__((always_inline)) static inline void LpitReg_StopTimerChannels(LpitRegType *obj, uint32_t mask) +{ + obj->CLRTEN |= mask; +} + +/*! \brief Gets the timer channel period in count unit. + * + * This function returns current period of timer channel given as argument. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \return timer channel period in count unit + */ +__attribute__((always_inline)) static inline uint32_t LpitReg_GetTimerPeriodByCount(const LpitRegType *obj, uint8_t channel) +{ + return obj->TMR[channel].TVAL; +} + +/*! \brief Sets the timer channel period in count unit. + * + * This function sets the timer channel period in count unit. + * - In compare mode: Timer Value (TMR_VAL) is the timer channel start value. + * - The timer will count down until the timer reaches 0, then the timer will generate + * an interrupt and load the Timer Value register (TVALn) value again. + * - Writing a new value to the Timer Value register (TVALn) will not restart the timer channel; + * instead the new value will be loaded after the timer expires. + * - To abort the current timer cycle and start a timer period with a new value, the timer channel must be disabled and enabled again. + * - In capture mode: whenever the trigger asserts, the Timer Value register stores the inverse of the counter value. + - 00000000h : Invalid load value in compare mode + - 00000001h : Invalid load value in compare mode + - 00000002h-ffffffffh : In compare mode: the value to be loaded; in capture mode, the value of the timer + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \param[in] count : timer channel period in count unit + */ +__attribute__((always_inline)) static inline void LpitReg_SetTimerPeriodByCount(LpitRegType *obj, uint8_t channel, uint32_t count) +{ + obj->TMR[channel].TVAL = count; +} + +/*! \brief Gets the current timer channel counting value. + * + * This function returns the real-time timer channel counting value, the value in + * a range from 0 to timer channel period. + * Need to make sure the running time does not exceed the timer channel period. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \return current timer channel counting value + */ +__attribute__((always_inline)) static inline uint32_t LpitReg_GetCurrentTimerCount(const LpitRegType *obj, uint8_t channel) +{ + return obj->TMR[channel].CVAL; +} + +/*! \brief Gets current state of time channel enable + * + * This function gets the current state of time channel enable + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \return the current state of time channel enable + * - 0 : timer Channel is disabled, counter reset to 0xffff_ffff + * - 1 : timer Channel is enabled + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetTimerChannelEnable(const LpitRegType *obj, uint8_t channel) +{ + return ((obj->TMR[channel].TCTRL & LPIT_TMR_TCTRL_T_EN_MASK) >> LPIT_TMR_TCTRL_T_EN_SHIFT); +} + +/*! \brief Enables or disables the Timer Channel + * + * This function enables or disables the Timer Channel + * + * \note If this bit is set, SET_T_EN_n will also be set + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \param[in] enable : operation mode of timer channel + * - 0 : timer Channel is disabled, counter reset to 0xffff_ffff + * - 1 : timer Channel is enabled + */ +__attribute__((always_inline)) static inline void LpitReg_SetTimerChannelEnable(LpitRegType *obj, uint8_t channel, uint8_t enable) +{ + uint32_t tmp = obj->TMR[channel].TCTRL; + + tmp &= ~LPIT_TMR_TCTRL_T_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(enable)) << LPIT_TMR_TCTRL_T_EN_SHIFT)) & LPIT_TMR_TCTRL_T_EN_MASK); + obj->TMR[channel].TCTRL = tmp; +} + +/*! \brief Gets current state of timer channel chaining. + * + * This function gets the current state of timer channel chaining. + * When enabled, the timer channel will decrement when timer channel N-1 trigger asserts. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \return the current state of timer channel chaining + * - 0 : Channel Chaining is disabled. The channel timer runs independently. + * - 1 : Channel Chaining is enabled. The timer decrements on the previous channel's timeout. + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetTimerChannelChainCmd(const LpitRegType *obj, uint8_t channel) +{ + return ((obj->TMR[channel].TCTRL & LPIT_TMR_TCTRL_CHAIN_MASK) >> LPIT_TMR_TCTRL_CHAIN_SHIFT); +} + +/*! \brief Sets timer channel chaining. + * + * This function sets the timer channel to be chained or not chained. + * When enabled, the timer channel will decrement when timer channel N-1 trigger asserts. + * + * \note Timer channel 0 cannot be chained. + * + * \note If this bit is set, SET_T_EN_n will also be set + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \param[in] isChannelChained : timer channel chaining + * - 0 : Channel Chaining is disabled. The channel timer runs independently. + * - 1 : Channel Chaining is enabled. The timer decrements on the previous channel's timeout. + */ +__attribute__((always_inline)) static inline void LpitReg_SetTimerChannelChainCmd(LpitRegType *obj, uint8_t channel, uint8_t isChannelChained) +{ + uint32_t tmp = obj->TMR[channel].TCTRL; + + tmp &= ~LPIT_TMR_TCTRL_CHAIN_MASK; + tmp |= (((uint32_t)(((uint32_t)(isChannelChained)) << LPIT_TMR_TCTRL_CHAIN_SHIFT)) & LPIT_TMR_TCTRL_CHAIN_MASK); + obj->TMR[channel].TCTRL = tmp; +} + +/*! \brief Gets current operation mode of timer channel. + * + * This function gets current operation mode of the timer channel given as argument. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \return operation mode of timer channel + * - 0 : 32-bit Periodic Counter + * - 1 : Dual 16-bit Periodic Counter + * - 2 : 32-bit Trigger Accumulator + * - 3 : 32-bit Trigger Input Capture + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetTimerChannelModeCmd(const LpitRegType *obj, uint8_t channel) +{ + return ((obj->TMR[channel].TCTRL & LPIT_TMR_TCTRL_MODE_MASK) >> LPIT_TMR_TCTRL_MODE_SHIFT); +} + +/*! \brief Sets operation mode of timer channel + * + * This function sets the timer channel operation mode which control how + * the timer channel decrements. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \param[in] mode : operation mode of timer channel + * - 0 : 32-bit Periodic Counter + * - 1 : Dual 16-bit Periodic Counter + * - 2 : 32-bit Trigger Accumulator + * - 3 : 32-bit Trigger Input Capture + */ +__attribute__((always_inline)) static inline void LpitReg_SetTimerChannelModeCmd(LpitRegType *obj, uint8_t channel, uint8_t mode) +{ + uint32_t tmp = obj->TMR[channel].TCTRL; + + tmp &= ~LPIT_TMR_TCTRL_MODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(mode)) << LPIT_TMR_TCTRL_MODE_SHIFT)) & LPIT_TMR_TCTRL_MODE_MASK); + obj->TMR[channel].TCTRL = tmp; +} + +/*! \brief Gets current command of timer channel start on trigger. + * + * This function gets current command of timer channel start on trigger. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \return current command of timer channel start on trigger. + * - 0 : Timer starts to decrement immediately based on the restart condition + * (controlled by the Timer Stop On Interrupt bit (TSOI)) + * - 1 : Timer starts to decrement when a rising edge on a selected trigger is detected + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetStartOnTriggerCmd(const LpitRegType *obj, uint8_t channel) +{ + return ((obj->TMR[channel].TCTRL & LPIT_TMR_TCTRL_TSOT_MASK) >> LPIT_TMR_TCTRL_TSOT_SHIFT); +} + +/*! \brief Sets timer channel start on trigger. + * + * This function sets the timer channel to starts/don't start on trigger. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \param[in] isStartOnTrigger : timer channel start on trigger + * - 0 : Timer starts to decrement immediately based on the restart condition + * (controlled by the Timer Stop On Interrupt bit (TSOI)) + * - 1 : Timer starts to decrement when a rising edge on a selected trigger is detected + */ +__attribute__((always_inline)) static inline void LpitReg_SetStartOnTriggerCmd(LpitRegType *obj, uint8_t channel, uint8_t isStartOnTrigger) +{ + uint32_t tmp = obj->TMR[channel].TCTRL; + + tmp &= ~LPIT_TMR_TCTRL_TSOT_MASK; + tmp |= (((uint32_t)(((uint32_t)(isStartOnTrigger)) << LPIT_TMR_TCTRL_TSOT_SHIFT)) & LPIT_TMR_TCTRL_TSOT_MASK); + obj->TMR[channel].TCTRL = tmp; +} + +/*! \brief Gets current command of timer channel stop on interrupt. + * + * This function gets current command of timer channel stop on interrupt. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \return current command of timer channel stop on interrupt. + * - 0 : the channel timer does not stop after timeout + * - 1 : The channel timer will stop after a timeout, + * and the channel timer will restart based on Timer Start On Trigger bit (TSOT). + * When TSOT = 0, the channel timer will restart after a rising edge on the Timer Enable bit (T_EN) is detected + * (which means that the timer channel is disabled and then enabled). + * When TSOT = 1, the channel timer will restart after a rising edge on the selected trigger is detected. + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetStopOnInterruptCmd(const LpitRegType *obj, uint8_t channel) +{ + return ((obj->TMR[channel].TCTRL & LPIT_TMR_TCTRL_TSOI_MASK) >> LPIT_TMR_TCTRL_TSOI_SHIFT); +} + +/*! \brief Sets timer channel stop on interrupt. + * + * This function sets the timer channel to stop or don't stop after it times out. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \param[in] isStopOnInterrupt : timer channel stop on interrupt + * - 0 : the channel timer does not stop after timeout + * - 1 : The channel timer will stop after a timeout, + * and the channel timer will restart based on Timer Start On Trigger bit (TSOT). + * When TSOT = 0, the channel timer will restart after a rising edge on the Timer Enable bit (T_EN) is detected + * (which means that the timer channel is disabled and then enabled). + * When TSOT = 1, the channel timer will restart after a rising edge on the selected trigger is detected. + */ +__attribute__((always_inline)) static inline void LpitReg_SetStopOnInterruptCmd(LpitRegType *obj, uint8_t channel, uint8_t isStopOnInterrupt) +{ + uint32_t tmp = obj->TMR[channel].TCTRL; + + tmp &= ~LPIT_TMR_TCTRL_TSOI_MASK; + tmp |= (((uint32_t)(((uint32_t)(isStopOnInterrupt)) << LPIT_TMR_TCTRL_TSOI_SHIFT)) & LPIT_TMR_TCTRL_TSOI_MASK); + obj->TMR[channel].TCTRL = tmp; +} + +/*! \brief Gets current command of timer channel reload on trigger. + * + * This function gets current command of timer channel reload on trigger. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \return current command of timer channel reload on trigger. + * - 0 : timer will not reload on the selected trigger + * - 1 : timer will reload on the selected trigger + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetReloadOnTriggerCmd(const LpitRegType *obj, uint8_t channel) +{ + return ((obj->TMR[channel].TCTRL & LPIT_TMR_TCTRL_TROT_MASK) >> LPIT_TMR_TCTRL_TROT_SHIFT); +} + +/*! \brief Sets timer channel reload on trigger. + * + * This function sets the timer channel to reload/don't reload on trigger. + * When set, the LPIT timer will reload when a rising edge is detected on the selected trigger input. + * The trigger input is ignored if the LPIT is disabled during debug mode (DBGEN = 0) or LowPower mode + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \param[in] isReloadOnTrigger : timer channel reload on trigger + * - 0 : timer will not reload on the selected trigger + * - 1 : timer will reload on the selected trigger + */ +__attribute__((always_inline)) static inline void LpitReg_SetReloadOnTriggerCmd(LpitRegType *obj, uint8_t channel, uint8_t isReloadOnTrigger) +{ + uint32_t tmp = obj->TMR[channel].TCTRL; + + tmp &= ~LPIT_TMR_TCTRL_TROT_MASK; + tmp |= (((uint32_t)(((uint32_t)(isReloadOnTrigger)) << LPIT_TMR_TCTRL_TROT_SHIFT)) & LPIT_TMR_TCTRL_TROT_MASK); + obj->TMR[channel].TCTRL = tmp; +} + +/*! \brief Gets current command of timer channel trigger source. + * + * This function gets current command of timer channel trigger source. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \return current trigger source of timer channel. + * - 0 : selects external triggers + * - 1 : selects internal triggers + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetTriggerSourceCmd(const LpitRegType *obj, uint8_t channel) +{ + return ((obj->TMR[channel].TCTRL & LPIT_TMR_TCTRL_TRG_SRC_MASK) >> LPIT_TMR_TCTRL_TRG_SRC_SHIFT); +} + +/*! \brief Sets trigger source of timer channel. + * + * This function sets trigger source of the timer channel to be internal or external trigger. + * Selects between internal or external trigger sources. The trigger to be used is selected using the TRG_SRC and TRG_SEL bits. + * Refer to the chip configuration section for available external trigger options. + * If a channel does not have an associated external trigger, then set the Trigger Source bit (TRG_SRC) = 1. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \param[in] triggerSource : timer channel reload on trigger + * - 0 : selects external triggers + * - 1 : selects internal triggers + */ +__attribute__((always_inline)) static inline void LpitReg_SetTriggerSourceCmd(LpitRegType *obj, uint8_t channel, uint8_t triggerSource) +{ + uint32_t tmp = obj->TMR[channel].TCTRL; + + tmp &= ~LPIT_TMR_TCTRL_TRG_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(triggerSource)) << LPIT_TMR_TCTRL_TRG_SRC_SHIFT)) & LPIT_TMR_TCTRL_TRG_SRC_MASK); + obj->TMR[channel].TCTRL = tmp; +} + +/*! \brief Gets the selection of the trigger to use for starting and/or reloading the LPIT timer. + * + * This function gets the selection of the trigger to use for starting and/or reloading the LPIT timer. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \return current selection. + * - 0 ~ 3 : timer channel 0 ~ 3 trigger source is selected + * - 4 ~ 15 : reserved + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetTriggerSelectCmd(const LpitRegType *obj, uint8_t channel) +{ + return ((obj->TMR[channel].TCTRL & LPIT_TMR_TCTRL_TRG_SEL_MASK) >> LPIT_TMR_TCTRL_TRG_SEL_SHIFT); +} + +/*! \brief Selects the trigger to use for starting and/or reloading the LPIT timer. + * + * This function selects the trigger to use for starting and/or reloading the LPIT timer. + * + * The TRG_SEL field selects one trigger from the set of internal or external triggers + * that are selected by the Trigger Source bit (TRG_SRC) + * Recall that the TRG_SRC bit selects between internal and external trigger signals for each channel + * + * \note The Trigger Select field should only be changed when the LPIT timer channel is disabled. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \param[in] triggerChannelSelect : selection of the trigger + * - 0 ~ 3 : timer channel 0 ~ 3 trigger source is selected + * - 4 ~ 15 : reserved + */ +__attribute__((always_inline)) static inline void LpitReg_SetTriggerSelectCmd(LpitRegType *obj, uint8_t channel, uint8_t triggerChannelSelect) +{ + uint32_t tmp = obj->TMR[channel].TCTRL; + + tmp &= ~LPIT_TMR_TCTRL_TRG_SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(triggerChannelSelect)) << LPIT_TMR_TCTRL_TRG_SEL_SHIFT)) & LPIT_TMR_TCTRL_TRG_SEL_MASK); + obj->TMR[channel].TCTRL = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _LPIT_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/lptmr_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/lptmr_reg.h new file mode 100644 index 0000000..9cf66a3 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/lptmr_reg.h @@ -0,0 +1,555 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _LPTMR_REG_H_ +#define _LPTMR_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the LPTMR (Low Power Timer) Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* CSR Bit Fields */ +#define LPTMR_CSR_TEN_MASK (0x1u) +#define LPTMR_CSR_TEN_SHIFT (0u) +#define LPTMR_CSR_TEN_WIDTH (1u) +#define LPTMR_CSR_TMS_MASK (0x2u) +#define LPTMR_CSR_TMS_SHIFT (1u) +#define LPTMR_CSR_TMS_WIDTH (1u) +#define LPTMR_CSR_TFC_MASK (0x4u) +#define LPTMR_CSR_TFC_SHIFT (2u) +#define LPTMR_CSR_TFC_WIDTH (1u) +#define LPTMR_CSR_TPP_MASK (0x8u) +#define LPTMR_CSR_TPP_SHIFT (3u) +#define LPTMR_CSR_TPP_WIDTH (1u) +#define LPTMR_CSR_TPS_MASK (0x30u) +#define LPTMR_CSR_TPS_SHIFT (4u) +#define LPTMR_CSR_TPS_WIDTH (2u) +#define LPTMR_CSR_TIE_MASK (0x40u) +#define LPTMR_CSR_TIE_SHIFT (6u) +#define LPTMR_CSR_TIE_WIDTH (1u) +#define LPTMR_CSR_TCF_MASK (0x80u) +#define LPTMR_CSR_TCF_SHIFT (7u) +#define LPTMR_CSR_TCF_WIDTH (1u) +#define LPTMR_CSR_TDRE_MASK (0x100u) +#define LPTMR_CSR_TDRE_SHIFT (8u) +#define LPTMR_CSR_TDRE_WIDTH (1u) + +/* PSR Bit Fields */ +#define LPTMR_PSR_PBYP_MASK (0x4u) +#define LPTMR_PSR_PBYP_SHIFT (2u) +#define LPTMR_PSR_PBYP_WIDTH (1u) +#define LPTMR_PSR_PRESCALE_MASK (0x78u) +#define LPTMR_PSR_PRESCALE_SHIFT (3u) +#define LPTMR_PSR_PRESCALE_WIDTH (4u) + +/* CMR Bit Fields */ +#define LPTMR_CMR_COMPARE_MASK (0xFFFFu) +#define LPTMR_CMR_COMPARE_SHIFT (0u) +#define LPTMR_CMR_COMPARE_WIDTH (16u) + +/* CNR Bit Fields */ +#define LPTMR_CNR_COUNTER_MASK (0xFFFFu) +#define LPTMR_CNR_COUNTER_SHIFT (0u) +#define LPTMR_CNR_COUNTER_WIDTH (16u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of LPTMR registers + */ +typedef struct _LptmrRegType_ +{ + volatile uint32_t CSR; /*!< Low Power Timer Control Status Register, offset: 0x0 */ + volatile uint32_t PSR; /*!< Low Power Timer Prescale Register, offset: 0x4 */ + volatile uint32_t CMR; /*!< Low Power Timer Compare Register, offset: 0x8 */ + volatile uint32_t CNR; /*!< Low Power Timer Counter Register, offset: 0xC */ +} LptmrRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Get the Enable state. + * + * This function get the enable state of LPTMR. + * When TEN is clear, it resets the LPTMR internal logic, including the CNR and TCF. + * When TEN is set, the LPTMR is enabled. + * + * \param[in] obj : pointer to LPTMR register instance + * \return the state of the LPTMR + * - 0 : LPTMR is disabled and internal logic is reset. + * - 1 : LPTMR is enabled. + */ +__attribute__((always_inline)) static inline uint8_t LptmrReg_GetEnable(const LptmrRegType *obj) +{ + return ((obj->CSR & LPTMR_CSR_TEN_MASK) >> LPTMR_CSR_TEN_SHIFT); +} + +/*! \brief Set the 32 bits of LPTMR data register + * + * This function write new data to LPTMR calculator + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to LPTMR register instance + * \param[in] value : the state of the LPTMR + * - 0 : LPTMR is disabled and internal logic is reset. + * - 1 : LPTMR is enabled. + */ +__attribute__((always_inline)) static inline void LptmrReg_SetEnable(LptmrRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CSR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~(LPTMR_CSR_TEN_MASK | LPTMR_CSR_TCF_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << LPTMR_CSR_TEN_SHIFT)) & LPTMR_CSR_TEN_MASK); + obj->CSR = tmp; +} + +/*! \brief Get current Work Mode. + * + * This function returns the currently configured Work Mode for the LPTMR. + * + * \param[in] obj : pointer to LPTMR register instance + * \return Work Mode + * - 0 : Timer Counter Mode + * - 1 : Pulse Counter Mode + */ +__attribute__((always_inline)) static inline uint8_t LptmrReg_GetWorkMode(const LptmrRegType *obj) +{ + return ((obj->CSR & LPTMR_CSR_TMS_MASK) >> LPTMR_CSR_TMS_SHIFT); +} + +/*! \brief Set the Work Mode of LPTMR + * + * This function configures the Work Mode for the LPTMR. + * + * \note TMS must be altered only when the LPTMR is disabled. + * + * \param[in] obj : pointer to LPTMR register instance + * \param[in] value : the work mode of the LPTMR + * - 0 : Timer Counter Mode. + * - 1 : Pulse Counter Mode. + */ +__attribute__((always_inline)) static inline void LptmrReg_SetWorkMode(LptmrRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CSR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~(LPTMR_CSR_TMS_MASK | LPTMR_CSR_TCF_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << LPTMR_CSR_TMS_SHIFT)) & LPTMR_CSR_TMS_MASK); + obj->CSR = tmp; +} + +/*! \brief Get Free Running state + * + * This function checks whether the Free Running feature of the LPTMR is enabled or disabled. + * When clear, TFC configures the CNR to reset whenever TCF is set. + * When set, TFC configures the CNR to reset on overflow + * + * \param[in] obj : pointer to LPTMR register instance + * \return free running mode state + * - 0 : CNR is reset whenever TCF is set + * - 1 : CNR is reset on overflow + */ +__attribute__((always_inline)) static inline uint8_t LptmrReg_GetFreeRunning(const LptmrRegType *obj) +{ + return ((obj->CSR & LPTMR_CSR_TFC_MASK) >> LPTMR_CSR_TFC_SHIFT); +} + +/*! \brief Set the Free Running state + * + * This function configures the Free Running state for the LPTMR. + * When clear, TFC configures the CNR to reset whenever TCF is set. + * When set, TFC configures the CNR to reset on overflow + * + * \note TFC must be altered only when the LPTMR is disabled. + * + * \param[in] obj : pointer to LPTMR register instance + * \param[in] value : free running mode state + * - 0 : CNR is reset whenever TCF is set + * - 1 : CNR is reset on overflow + */ +__attribute__((always_inline)) static inline void LptmrReg_SetFreeRunning(LptmrRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CSR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~(LPTMR_CSR_TFC_MASK | LPTMR_CSR_TCF_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << LPTMR_CSR_TFC_SHIFT)) & LPTMR_CSR_TFC_MASK); + obj->CSR = tmp; +} + +/*! \brief Get Pin Polarity for Pulse Counter Mode + * + * This function returns the configured pin polarity that triggers an increment + * in Pulse Counter Mode. + * + * \param[in] obj : pointer to LPTMR register instance + * \return the pin polarity for Pulse Counter Mode + * - 0 : Pulse Counter input source is active-high, and the CNR increments on the rising-edge. + * - 1 : Pulse Counter input source is active-low, and the CNR increments on the falling-edge. + */ +__attribute__((always_inline)) static inline uint8_t LptmrReg_GetPinPolarity(const LptmrRegType *obj) +{ + return ((obj->CSR & LPTMR_CSR_TPP_MASK) >> LPTMR_CSR_TPP_SHIFT); +} + +/*! \brief Set Pin Polarity for Pulse Counter Mode + * + * This function configures the pin polarity that triggers an increment in Pulse + * Counter Mode. This feature can be configured only when the LPTMR is disabled. + * + * \note TPP must be changed only when the LPTMR is disabled. + * + * \param[in] obj : pointer to LPTMR register instance + * \param[in] value : the pin polarity to count in Pulse Counter Mode + * - 0 : Pulse Counter input source is active-high, and the CNR increments on the rising-edge. + * - 1 : Pulse Counter input source is active-low, and the CNR increments on the falling-edge. + */ +__attribute__((always_inline)) static inline void LptmrReg_SetPinPolarity(LptmrRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CSR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~(LPTMR_CSR_TPP_MASK | LPTMR_CSR_TCF_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << LPTMR_CSR_TPP_SHIFT)) & LPTMR_CSR_TPP_MASK); + obj->CSR = tmp; +} + +/*! \brief Get the Pin select for Counter Mode + * + * This function returns the configured Input Pin for Pulse Counter Mode. + * The input connections vary by device. See the chip configuration information + * about connections to these inputs. + * + * \param[in] obj : pointer to LPTMR register instance + * \return pin selection + * - 0 : Pulse counter input 0 is selected. + * - 1 : Pulse counter input 1 is selected. + * - 2 : Pulse counter input 2 is selected. + * - 3 : Pulse counter input 3 is selected. + */ +__attribute__((always_inline)) static inline uint8_t LptmrReg_GetPinSelect(const LptmrRegType *obj) +{ + return ((obj->CSR & LPTMR_CSR_TPS_MASK) >> LPTMR_CSR_TPS_SHIFT); +} + +/*! \brief Set the Pin selection for Pulse Counter Mode + * + * This function configures the input source to be used in Pulse Counter mode. + * The input connections vary by device. See the chip configuration information + * about connections to these inputs. + * + * \note TPS must be altered only when the LPTMR is disabled. + * + * \param[in] obj : pointer to LPTMR register instance + * \param[in] value : pin selection + * - 0 : Pulse counter input 0 is selected. + * - 1 : Pulse counter input 1 is selected. + * - 2 : Pulse counter input 2 is selected. + * - 3 : Pulse counter input 3 is selected. + */ +__attribute__((always_inline)) static inline void LptmrReg_SetPinSelect(LptmrRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CSR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~(LPTMR_CSR_TPS_MASK | LPTMR_CSR_TCF_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << LPTMR_CSR_TPS_SHIFT)) & LPTMR_CSR_TPS_MASK); + obj->CSR = tmp; +} + +/*! \brief Get the Interrupt Enable state + * + * This function returns the Interrupt Enable state for the LPTMR. If enabled, + * an interrupt is generated when a Compare Match event occurs. + * + * \param[in] obj : pointer to LPTMR register instance + * \return interrupt enable state + * - 0 : timer interrupt disabled. + * - 1 : timer interrupt enabled. + */ +__attribute__((always_inline)) static inline uint8_t LptmrReg_GetInterruptEnable(const LptmrRegType *obj) +{ + return ((obj->CSR & LPTMR_CSR_TIE_MASK) >> LPTMR_CSR_TIE_SHIFT); +} + +/*! \brief Set the Interrupt Enable state + * + * This function configures the Interrupt Enable state for the LPTMR. If enabled, + * an interrupt is generated when a Compare Match event occurs. + * + * \note Either TIE or TDRE can be valid at the same time. + * \note Must be altered only when the LPTMR is disabled. + * + * \param[in] obj : pointer to LPTMR register instance + * \param[in] value : The new state for the interrupt + * - 0 : disable Interrupt. + * - 1 : enable Interrupt. + */ +__attribute__((always_inline)) static inline void LptmrReg_SetInterrupt(LptmrRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CSR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~(LPTMR_CSR_TIE_MASK | LPTMR_CSR_TCF_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << LPTMR_CSR_TIE_SHIFT)) & LPTMR_CSR_TIE_MASK); + obj->CSR = tmp; +} + +/*! \brief Get the Compare Flag state + * + * This function checks whether a Compare Match event has occurred or if there is + * an Interrupt Pending. + * TCF is set when the LPTMR is enabled and the CNR equals the CMR and increments. + * TCF is cleared when the LPTMR is disabled or a logic 1 is written to it. + * + * \param[in] obj : pointer to LPTMR register instance + * \return the Compare Flag state + * - 0 : the value of CNR is not equal to CMR and increments. + * - 1 : the value of CNR is equal to CMR and increments. + */ +__attribute__((always_inline)) static inline uint8_t LptmrReg_GetCompareFlag(const LptmrRegType *obj) +{ + return ((obj->CSR & LPTMR_CSR_TCF_MASK) >> LPTMR_CSR_TCF_SHIFT); +} + +/*! \brief Clear the Compare Flag + * + * This function clears the Compare Flag/Interrupt Pending state. + * TCF is set when the LPTMR is enabled and the CNR equals the CMR and increments. + * TCF is cleared when the LPTMR is disabled or a logic 1 is written to it. + * + * \note Ensure to clear this field before enabling the Timer interrupt or DMA request. + * + * \param[in] obj : pointer to LPTMR register instance + */ +__attribute__((always_inline)) static inline void LptmrReg_ClearCompareFlag(LptmrRegType *obj) +{ + uint32_t tmp = obj->CSR; + tmp |= (LPTMR_CSR_TCF_MASK); + obj->CSR = tmp; + /* Read back to avoid problem */ + (void)obj->CSR; +} + +/*! \brief Get the DMA Request Enable Flag + * + * This function checks whether a DMA Request feature of the LPTMR is enabled. + * The DMA Request is issued when a Compare Match is asserted. + * If enabled, the Compare Match/Interrupt Pending flag is cleared when + * the DMA controller is done. + * + * \param[in] obj : pointer to LPTMR register instance + * \return DMA Request enable + * - 0 : timer DMA Request disabled. + * - 1 : timer DMA Request enabled. + */ +__attribute__((always_inline)) static inline uint8_t LptmrReg_GetDmaRequest(const LptmrRegType *obj) +{ + return ((obj->CSR & LPTMR_CSR_TDRE_MASK) >> LPTMR_CSR_TDRE_SHIFT); +} + +/*! \brief Configure the DMA Request Enable Flag state + * + * This function configures the DMA Request feature of the LPTMR. + * If enabled, a DMA Request is issued when the Compare Match event occurs. + * If enabled, the Compare Match/Interrupt Pending flag is cleared when the DMA controller is done. + * + * \note Either TIE or TDRE can be valid at the same time. + * \note Must be altered only when the LPTMR is disabled. + * + * \param[in] obj : pointer to LPTMR register instance + * \param[in] value : the new state for DMA Request Enable Flag + * - 0 : disable DMA Request + * - 1 : enable DMA Request + */ +__attribute__((always_inline)) static inline void LptmrReg_SetDmaRequest(LptmrRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CSR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~(LPTMR_CSR_TDRE_MASK | LPTMR_CSR_TCF_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << LPTMR_CSR_TDRE_SHIFT)) & LPTMR_CSR_TDRE_MASK); + obj->CSR = tmp; +} + +/*! \brief Get the Prescaler/Glitch Filter Bypass enable state + * + * This function checks whether the Prescaler/Glitch Filter Bypass is enabled. + * When PBYP is set, the selected prescaler clock in Time Counter mode or + * selected input source in Pulse Counter mode directly clocks the CNR. + * When PBYP is clear, the CNR is clocked by the output of the prescaler/glitch filter. + * + * \param[in] obj : pointer to LPTMR register instance + * \return the Prescaler Bypass state + * - 0 : prescaler/glitch filter is used. + * - 1 : prescaler/glitch filter is bypassed. + */ +__attribute__((always_inline)) static inline uint8_t LptmrReg_GetBypass(const LptmrRegType *obj) +{ + return ((obj->PSR & LPTMR_PSR_PBYP_MASK) >> LPTMR_PSR_PBYP_SHIFT); +} + +/*! \brief Configure the Prescaler/Glitch Filter Bypass enable state + * + * This function configures the Prescaler/Glitch filter Bypass. + * + * \note Must be altered only when the LPTMR is disabled. + * + * \param[in] obj : pointer to LPTMR register instance + * \param[in] value : the new Prescaler/Glitch Filter Bypass state + * - 0 : use rescaler/glitch filter + * - 1 : bypass rescaler/glitch filter + */ +__attribute__((always_inline)) static inline void LptmrReg_SetBypass(LptmrRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PSR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~(LPTMR_PSR_PBYP_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << LPTMR_PSR_PBYP_SHIFT)) & LPTMR_PSR_PBYP_MASK); + obj->PSR = tmp; +} + +/*! \brief Get Prescaler/Glitch Filter divider value + * + * This function returns the currently configured Prescaler/Glitch Filter divider value. + * Prescale Value configures the size of the Prescaler in Time Counter mode or width of the + * glitch filter in Pulse Counter mode. + * The width of the glitch filter can vary by 1 cycle due to synchronization of the pulse counter input. + * + * \param[in] obj : pointer to LPTMR register instance + * \return the Prescaler/Glitch filter value + * - 0 : Prescaler divides the prescaler clock by 2; glitch filter does not support this configuration. + * - 1 : Prescaler divides the prescaler clock by 4; glitch filter recognizes change on input pin after 2 rising clock edges. + * - 2 : Prescaler divides the prescaler clock by 8; glitch filter recognizes change on input pin after 4 rising clock edges. + * - 3 : Prescaler divides the prescaler clock by 16; glitch filter recognizes change on input pin after 8 rising clock edges. + * - 4 : Prescaler divides the prescaler clock by 32; glitch filter recognizes change on input pin after 16 rising clock edges. + * - 5 : Prescaler divides the prescaler clock by 64; glitch filter recognizes change on input pin after 32 rising clock edges. + * - 6 : Prescaler divides the prescaler clock by 128; glitch filter recognizes change on input pin after 64 rising clock edges. + * - 7 : Prescaler divides the prescaler clock by 256; glitch filter recognizes change on input pin after 128 rising clock edges. + * - 8 : Prescaler divides the prescaler clock by 512; glitch filter recognizes change on input pin after 256 rising clock edges. + * - 9 : Prescaler divides the prescaler clock by 1024; glitch filter recognizes change on input pin after 512 rising clock edges. + * - 10 : Prescaler divides the prescaler clock by 2048; glitch filter recognizes change on input pin after 1024 rising clock edges. + * - 11 : Prescaler divides the prescaler clock by 4096; glitch filter recognizes change on input pin after 2048 rising clock edges. + * - 12 : Prescaler divides the prescaler clock by 8192; glitch filter recognizes change on input pin after 4096 rising clock edges. + * - 13 : Prescaler divides the prescaler clock by 16,384; glitch filter recognizes change on input pin after 8192 rising clock edges. + * - 14 : Prescaler divides the prescaler clock by 32,768; glitch filter recognizes change on input pin after 16,384 rising clock edges. + * - 15 : Prescaler divides the prescaler clock by 65,536; glitch filter recognizes change on input pin after 32,768 rising clock edges. + */ +__attribute__((always_inline)) static inline uint8_t LptmrReg_GetPrescaler(const LptmrRegType *obj) +{ + return ((obj->PSR & LPTMR_PSR_PRESCALE_MASK) >> LPTMR_PSR_PRESCALE_SHIFT); +} + +/*! \brief Configure the Prescaler/Glitch Filter divider value + * + * This function configures the value for the Prescaler/Glitch Filter. + * + * \note Must be altered only when the LPTMR is disabled. + * + * \param[in] obj : pointer to LPTMR register instance + * \param[in] value : the new Prescaler value + * - 0 : Prescaler divides the prescaler clock by 2; glitch filter does not support this configuration. + * - 1 : Prescaler divides the prescaler clock by 4; glitch filter recognizes change on input pin after 2 rising clock edges. + * - 2 : Prescaler divides the prescaler clock by 8; glitch filter recognizes change on input pin after 4 rising clock edges. + * - 3 : Prescaler divides the prescaler clock by 16; glitch filter recognizes change on input pin after 8 rising clock edges. + * - 4 : Prescaler divides the prescaler clock by 32; glitch filter recognizes change on input pin after 16 rising clock edges. + * - 5 : Prescaler divides the prescaler clock by 64; glitch filter recognizes change on input pin after 32 rising clock edges. + * - 6 : Prescaler divides the prescaler clock by 128; glitch filter recognizes change on input pin after 64 rising clock edges. + * - 7 : Prescaler divides the prescaler clock by 256; glitch filter recognizes change on input pin after 128 rising clock edges. + * - 8 : Prescaler divides the prescaler clock by 512; glitch filter recognizes change on input pin after 256 rising clock edges. + * - 9 : Prescaler divides the prescaler clock by 1024; glitch filter recognizes change on input pin after 512 rising clock edges. + * - 10 : Prescaler divides the prescaler clock by 2048; glitch filter recognizes change on input pin after 1024 rising clock edges. + * - 11 : Prescaler divides the prescaler clock by 4096; glitch filter recognizes change on input pin after 2048 rising clock edges. + * - 12 : Prescaler divides the prescaler clock by 8192; glitch filter recognizes change on input pin after 4096 rising clock edges. + * - 13 : Prescaler divides the prescaler clock by 16,384; glitch filter recognizes change on input pin after 8192 rising clock edges. + * - 14 : Prescaler divides the prescaler clock by 32,768; glitch filter recognizes change on input pin after 16,384 rising clock edges. + * - 15 : Prescaler divides the prescaler clock by 65,536; glitch filter recognizes change on input pin after 32,768 rising clock edges. + */ +__attribute__((always_inline)) static inline void LptmrReg_SetPrescaler(LptmrRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PSR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~(LPTMR_PSR_PRESCALE_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << LPTMR_PSR_PRESCALE_SHIFT)) & LPTMR_PSR_PRESCALE_MASK); + obj->PSR = tmp; +} + +/*! \brief Get the Compare Value + * + * This function returns the current Compare Value. + * + * \param[in] obj : pointer to LPTMR register instance + * \return the Compare Value + */ +__attribute__((always_inline)) static inline uint16_t LptmrReg_GetCompareValue(const LptmrRegType *obj) +{ + return ((obj->CMR & LPTMR_CMR_COMPARE_MASK) >> LPTMR_CMR_COMPARE_SHIFT); +} + +/*! \brief Configure the Prescaler/Glitch Filter Bypass enable state + * + * This function configures the Compare Value. If set to 0, the Compare Match + * event and the hardware trigger assert and remain asserted until the timer is + * disabled. + * + * \note Must be altered only when the LPTMR is disabled. + * + * \param[in] obj : pointer to LPTMR register instance + * \param[in] value : the new Compare Value + */ +__attribute__((always_inline)) static inline void LptmrReg_SetCompareValue(LptmrRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->CMR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~(LPTMR_CMR_COMPARE_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << LPTMR_CMR_COMPARE_SHIFT)) & LPTMR_CMR_COMPARE_MASK); + obj->CMR = tmp; +} + +/*! \brief Get the current Counter Value + * + * This function returns the Counter Value. + * The CNR returns the current value of the LPTMR counter at the time this register was last written. + * Cannot write directly. + * + * \param[in] obj : pointer to LPTMR register instance + * \return the Counter Value + */ +__attribute__((always_inline)) static inline uint16_t LptmrReg_GetCounterValue(const LptmrRegType *obj) +{ + return ((obj->CNR & LPTMR_CNR_COUNTER_MASK) >> LPTMR_CNR_COUNTER_SHIFT); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _LPTMR_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/mft_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/mft_reg.h new file mode 100644 index 0000000..96e45e8 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/mft_reg.h @@ -0,0 +1,8583 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MFT_REG_H_ +#define _MFT_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the MFT Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* Total number of MFT channels */ +#define MFT_CHANNEL_NUM (8) +/* Pair number of Deadtime channels */ +#define MFT_DEADTIME_PAIR (MFT_CHANNEL_NUM / 2) +/* Pair number of Deadtime channels */ +#define MFT_FAULT_INPUT_NUM (4) + +/* SC Bit Fields */ +#define MFT_SC_FLTPS_MASK (0xF000000u) +#define MFT_SC_FLTPS_SHIFT (24u) +#define MFT_SC_FLTPS_WIDTH (4u) +#define MFT_SC_PWMEN7_MASK (0x800000u) +#define MFT_SC_PWMEN7_SHIFT (23u) +#define MFT_SC_PWMEN7_WIDTH (1u) +#define MFT_SC_PWMEN6_MASK (0x400000u) +#define MFT_SC_PWMEN6_SHIFT (22u) +#define MFT_SC_PWMEN6_WIDTH (1u) +#define MFT_SC_PWMEN5_MASK (0x200000u) +#define MFT_SC_PWMEN5_SHIFT (21u) +#define MFT_SC_PWMEN5_WIDTH (1u) +#define MFT_SC_PWMEN4_MASK (0x100000u) +#define MFT_SC_PWMEN4_SHIFT (20u) +#define MFT_SC_PWMEN4_WIDTH (1u) +#define MFT_SC_PWMEN3_MASK (0x80000u) +#define MFT_SC_PWMEN3_SHIFT (19u) +#define MFT_SC_PWMEN3_WIDTH (1u) +#define MFT_SC_PWMEN2_MASK (0x40000u) +#define MFT_SC_PWMEN2_SHIFT (18u) +#define MFT_SC_PWMEN2_WIDTH (1u) +#define MFT_SC_PWMEN1_MASK (0x20000u) +#define MFT_SC_PWMEN1_SHIFT (17u) +#define MFT_SC_PWMEN1_WIDTH (1u) +#define MFT_SC_PWMEN0_MASK (0x10000u) +#define MFT_SC_PWMEN0_SHIFT (16u) +#define MFT_SC_PWMEN0_WIDTH (1u) +#define MFT_SC_TOF_MASK (0x200u) +#define MFT_SC_TOF_SHIFT (9u) +#define MFT_SC_TOF_WIDTH (1u) +#define MFT_SC_TOIE_MASK (0x100u) +#define MFT_SC_TOIE_SHIFT (8u) +#define MFT_SC_TOIE_WIDTH (1u) +#define MFT_SC_RF_MASK (0x80u) +#define MFT_SC_RF_SHIFT (7u) +#define MFT_SC_RF_WIDTH (1u) +#define MFT_SC_RIE_MASK (0x40u) +#define MFT_SC_RIE_SHIFT (6u) +#define MFT_SC_RIE_WIDTH (1u) +#define MFT_SC_CPWMS_MASK (0x20u) +#define MFT_SC_CPWMS_SHIFT (5u) +#define MFT_SC_CPWMS_WIDTH (1u) +#define MFT_SC_CLKS_MASK (0x18u) +#define MFT_SC_CLKS_SHIFT (3u) +#define MFT_SC_CLKS_WIDTH (2u) +#define MFT_SC_PS_MASK (0x07u) +#define MFT_SC_PS_SHIFT (0u) +#define MFT_SC_PS_WIDTH (3u) + +/* CNT Bit Fields */ +#define MFT_CNT_COUNT_MASK (0xFFFFu) +#define MFT_CNT_COUNT_SHIFT (0u) +#define MFT_CNT_COUNT_WIDTH (16u) + +/* MODULO Bit Fields */ +#define MFT_MODULO_MOD_MASK (0xFFFFu) +#define MFT_MODULO_MOD_SHIFT (0u) +#define MFT_MODULO_MOD_WIDTH (16u) + +/* CSC Bit Fields */ +#define MFT_CSC_CHOV_MASK (0x400u) +#define MFT_CSC_CHOV_SHIFT (10u) +#define MFT_CSC_CHOV_WIDTH (1u) +#define MFT_CSC_CHIS_MASK (0x200u) +#define MFT_CSC_CHIS_SHIFT (9u) +#define MFT_CSC_CHIS_WIDTH (1u) +#define MFT_CSC_TRIGMODE_MASK (0x100u) +#define MFT_CSC_TRIGMODE_SHIFT (8u) +#define MFT_CSC_TRIGMODE_WIDTH (1u) +#define MFT_CSC_CHF_MASK (0x80u) +#define MFT_CSC_CHF_SHIFT (7u) +#define MFT_CSC_CHF_WIDTH (1u) +#define MFT_CSC_CHIE_MASK (0x40u) +#define MFT_CSC_CHIE_SHIFT (6u) +#define MFT_CSC_CHIE_WIDTH (1u) +#define MFT_CSC_MSB_MASK (0x20u) +#define MFT_CSC_MSB_SHIFT (5u) +#define MFT_CSC_MSB_WIDTH (1u) +#define MFT_CSC_MSA_MASK (0x10u) +#define MFT_CSC_MSA_SHIFT (4u) +#define MFT_CSC_MSA_WIDTH (1u) +#define MFT_CSC_ELSB_MASK (0x08u) +#define MFT_CSC_ELSB_SHIFT (3u) +#define MFT_CSC_ELSB_WIDTH (1u) +#define MFT_CSC_ELSA_MASK (0x04u) +#define MFT_CSC_ELSA_SHIFT (2u) +#define MFT_CSC_ELSA_WIDTH (1u) +#define MFT_CSC_ICRST_MASK (0x02u) +#define MFT_CSC_ICRST_SHIFT (1u) +#define MFT_CSC_ICRST_WIDTH (1u) +#define MFT_CSC_DMA_MASK (0x01u) +#define MFT_CSC_DMA_SHIFT (0u) +#define MFT_CSC_DMA_WIDTH (1u) + +/* CV Bit Fields */ +#define MFT_CV_VAL_MASK (0xFFFFu) +#define MFT_CV_VAL_SHIFT (0u) +#define MFT_CV_VAL_WIDTH (16u) + +/* CNTIN Bit Fields */ +#define MFT_CNTIN_CNTINIT_MASK (0xFFFFu) +#define MFT_CNTIN_CNTINIT_SHIFT (0u) +#define MFT_CNTIN_CNTINIT_WIDTH (16u) + +/* STATUS Bit Fields */ +#define MFT_STATUS_CH7F_MASK (0x80u) +#define MFT_STATUS_CH7F_SHIFT (7u) +#define MFT_STATUS_CH7F_WIDTH (1u) +#define MFT_STATUS_CH6F_MASK (0x40u) +#define MFT_STATUS_CH6F_SHIFT (6u) +#define MFT_STATUS_CH6F_WIDTH (1u) +#define MFT_STATUS_CH5F_MASK (0x20u) +#define MFT_STATUS_CH5F_SHIFT (5u) +#define MFT_STATUS_CH5F_WIDTH (1u) +#define MFT_STATUS_CH4F_MASK (0x10u) +#define MFT_STATUS_CH4F_SHIFT (4u) +#define MFT_STATUS_CH4F_WIDTH (1u) +#define MFT_STATUS_CH3F_MASK (0x08u) +#define MFT_STATUS_CH3F_SHIFT (3u) +#define MFT_STATUS_CH3F_WIDTH (1u) +#define MFT_STATUS_CH2F_MASK (0x04u) +#define MFT_STATUS_CH2F_SHIFT (2u) +#define MFT_STATUS_CH2F_WIDTH (1u) +#define MFT_STATUS_CH1F_MASK (0x02u) +#define MFT_STATUS_CH1F_SHIFT (1u) +#define MFT_STATUS_CH1F_WIDTH (1u) +#define MFT_STATUS_CH0F_MASK (0x01u) +#define MFT_STATUS_CH0F_SHIFT (0u) +#define MFT_STATUS_CH0F_WIDTH (1u) + +/* MODE Bit Fields */ +#define MFT_MODE_FAULTIE_MASK (0x80u) +#define MFT_MODE_FAULTIE_SHIFT (7u) +#define MFT_MODE_FAULTIE_WIDTH (1u) +#define MFT_MODE_FAULTM_MASK (0x60u) +#define MFT_MODE_FAULTM_SHIFT (5u) +#define MFT_MODE_FAULTM_WIDTH (2u) +#define MFT_MODE_CAPTEST_MASK (0x10u) +#define MFT_MODE_CAPTEST_SHIFT (4u) +#define MFT_MODE_CAPTEST_WIDTH (1u) +#define MFT_MODE_PWMSYNC_MASK (0x08u) +#define MFT_MODE_PWMSYNC_SHIFT (3u) +#define MFT_MODE_PWMSYNC_WIDTH (1u) +#define MFT_MODE_WPDIS_MASK (0x04u) +#define MFT_MODE_WPDIS_SHIFT (2u) +#define MFT_MODE_WPDIS_WIDTH (1u) +#define MFT_MODE_INIT_MASK (0x02u) +#define MFT_MODE_INIT_SHIFT (1u) +#define MFT_MODE_INIT_WIDTH (1u) +#define MFT_MODE_MFTEN_MASK (0x01u) +#define MFT_MODE_MFTEN_SHIFT (0u) +#define MFT_MODE_MFTEN_WIDTH (1u) + +/* SYNC Bit Fields */ +#define MFT_SYNC_SWSYNC_MASK (0x80u) +#define MFT_SYNC_SWSYNC_SHIFT (7u) +#define MFT_SYNC_SWSYNC_WIDTH (1u) +#define MFT_SYNC_TRIG2_MASK (0x40u) +#define MFT_SYNC_TRIG2_SHIFT (6u) +#define MFT_SYNC_TRIG2_WIDTH (1u) +#define MFT_SYNC_TRIG1_MASK (0x20u) +#define MFT_SYNC_TRIG1_SHIFT (5u) +#define MFT_SYNC_TRIG1_WIDTH (1u) +#define MFT_SYNC_TRIG0_MASK (0x10u) +#define MFT_SYNC_TRIG0_SHIFT (4u) +#define MFT_SYNC_TRIG0_WIDTH (1u) +#define MFT_SYNC_SYNCHOM_MASK (0x08u) +#define MFT_SYNC_SYNCHOM_SHIFT (3u) +#define MFT_SYNC_SYNCHOM_WIDTH (1u) +#define MFT_SYNC_REINIT_MASK (0x04u) +#define MFT_SYNC_REINIT_SHIFT (2u) +#define MFT_SYNC_REINIT_WIDTH (1u) +#define MFT_SYNC_CNTMAX_MASK (0x02u) +#define MFT_SYNC_CNTMAX_SHIFT (1u) +#define MFT_SYNC_CNTMAX_WIDTH (1u) +#define MFT_SYNC_CNTMIN_MASK (0x01u) +#define MFT_SYNC_CNTMIN_SHIFT (0u) +#define MFT_SYNC_CNTMIN_WIDTH (1u) + +/* OUTINIT Bit Fields */ +#define MFT_OUTINIT_CH7OI_MASK (0x80u) +#define MFT_OUTINIT_CH7OI_SHIFT (7u) +#define MFT_OUTINIT_CH7OI_WIDTH (1u) +#define MFT_OUTINIT_CH6OI_MASK (0x40u) +#define MFT_OUTINIT_CH6OI_SHIFT (6u) +#define MFT_OUTINIT_CH6OI_WIDTH (1u) +#define MFT_OUTINIT_CH5OI_MASK (0x20u) +#define MFT_OUTINIT_CH5OI_SHIFT (5u) +#define MFT_OUTINIT_CH5OI_WIDTH (1u) +#define MFT_OUTINIT_CH4OI_MASK (0x10u) +#define MFT_OUTINIT_CH4OI_SHIFT (4u) +#define MFT_OUTINIT_CH4OI_WIDTH (1u) +#define MFT_OUTINIT_CH3OI_MASK (0x08u) +#define MFT_OUTINIT_CH3OI_SHIFT (3u) +#define MFT_OUTINIT_CH3OI_WIDTH (1u) +#define MFT_OUTINIT_CH2OI_MASK (0x04u) +#define MFT_OUTINIT_CH2OI_SHIFT (2u) +#define MFT_OUTINIT_CH2OI_WIDTH (1u) +#define MFT_OUTINIT_CH1OI_MASK (0x02u) +#define MFT_OUTINIT_CH1OI_SHIFT (1u) +#define MFT_OUTINIT_CH1OI_WIDTH (1u) +#define MFT_OUTINIT_CH0OI_MASK (0x01u) +#define MFT_OUTINIT_CH0OI_SHIFT (0u) +#define MFT_OUTINIT_CH0OI_WIDTH (1u) + +/* OUTMASK Bit Fields */ +#define MFT_OUTMASK_CH7OM_MASK (0x80u) +#define MFT_OUTMASK_CH7OM_SHIFT (7u) +#define MFT_OUTMASK_CH7OM_WIDTH (1u) +#define MFT_OUTMASK_CH6OM_MASK (0x40u) +#define MFT_OUTMASK_CH6OM_SHIFT (6u) +#define MFT_OUTMASK_CH6OM_WIDTH (1u) +#define MFT_OUTMASK_CH5OM_MASK (0x20u) +#define MFT_OUTMASK_CH5OM_SHIFT (5u) +#define MFT_OUTMASK_CH5OM_WIDTH (1u) +#define MFT_OUTMASK_CH4OM_MASK (0x10u) +#define MFT_OUTMASK_CH4OM_SHIFT (4u) +#define MFT_OUTMASK_CH4OM_WIDTH (1u) +#define MFT_OUTMASK_CH3OM_MASK (0x08u) +#define MFT_OUTMASK_CH3OM_SHIFT (3u) +#define MFT_OUTMASK_CH3OM_WIDTH (1u) +#define MFT_OUTMASK_CH2OM_MASK (0x04u) +#define MFT_OUTMASK_CH2OM_SHIFT (2u) +#define MFT_OUTMASK_CH2OM_WIDTH (1u) +#define MFT_OUTMASK_CH1OM_MASK (0x02u) +#define MFT_OUTMASK_CH1OM_SHIFT (1u) +#define MFT_OUTMASK_CH1OM_WIDTH (1u) +#define MFT_OUTMASK_CH0OM_MASK (0x01u) +#define MFT_OUTMASK_CH0OM_SHIFT (0u) +#define MFT_OUTMASK_CH0OM_WIDTH (1u) + +/* COMBINE Bit Fields */ +#define MFT_COMBINE_MCOMBINE3_MASK (0x80000000u) +#define MFT_COMBINE_MCOMBINE3_SHIFT (31u) +#define MFT_COMBINE_MCOMBINE3_WIDTH (1u) +#define MFT_COMBINE_FAULTEN3_MASK (0x40000000u) +#define MFT_COMBINE_FAULTEN3_SHIFT (30u) +#define MFT_COMBINE_FAULTEN3_WIDTH (1u) +#define MFT_COMBINE_SYNCEN3_MASK (0x20000000u) +#define MFT_COMBINE_SYNCEN3_SHIFT (29u) +#define MFT_COMBINE_SYNCEN3_WIDTH (1u) +#define MFT_COMBINE_DTEN3_MASK (0x10000000u) +#define MFT_COMBINE_DTEN3_SHIFT (28u) +#define MFT_COMBINE_DTEN3_WIDTH (1u) +#define MFT_COMBINE_DECAP3_MASK (0x8000000u) +#define MFT_COMBINE_DECAP3_SHIFT (27u) +#define MFT_COMBINE_DECAP3_WIDTH (1u) +#define MFT_COMBINE_DECAPEN3_MASK (0x4000000u) +#define MFT_COMBINE_DECAPEN3_SHIFT (26u) +#define MFT_COMBINE_DECAPEN3_WIDTH (1u) +#define MFT_COMBINE_COMP3_MASK (0x2000000u) +#define MFT_COMBINE_COMP3_SHIFT (25u) +#define MFT_COMBINE_COMP3_WIDTH (1u) +#define MFT_COMBINE_COMBINE3_MASK (0x1000000u) +#define MFT_COMBINE_COMBINE3_SHIFT (24u) +#define MFT_COMBINE_COMBINE3_WIDTH (1u) +#define MFT_COMBINE_MCOMBINE2_MASK (0x800000u) +#define MFT_COMBINE_MCOMBINE2_SHIFT (23u) +#define MFT_COMBINE_MCOMBINE2_WIDTH (1u) +#define MFT_COMBINE_FAULTEN2_MASK (0x400000u) +#define MFT_COMBINE_FAULTEN2_SHIFT (22u) +#define MFT_COMBINE_FAULTEN2_WIDTH (1u) +#define MFT_COMBINE_SYNCEN2_MASK (0x200000u) +#define MFT_COMBINE_SYNCEN2_SHIFT (21u) +#define MFT_COMBINE_SYNCEN2_WIDTH (1u) +#define MFT_COMBINE_DTEN2_MASK (0x100000u) +#define MFT_COMBINE_DTEN2_SHIFT (20u) +#define MFT_COMBINE_DTEN2_WIDTH (1u) +#define MFT_COMBINE_DECAP2_MASK (0x80000u) +#define MFT_COMBINE_DECAP2_SHIFT (19u) +#define MFT_COMBINE_DECAP2_WIDTH (1u) +#define MFT_COMBINE_DECAPEN2_MASK (0x40000u) +#define MFT_COMBINE_DECAPEN2_SHIFT (18u) +#define MFT_COMBINE_DECAPEN2_WIDTH (1u) +#define MFT_COMBINE_COMP2_MASK (0x20000u) +#define MFT_COMBINE_COMP2_SHIFT (17u) +#define MFT_COMBINE_COMP2_WIDTH (1u) +#define MFT_COMBINE_COMBINE2_MASK (0x10000u) +#define MFT_COMBINE_COMBINE2_SHIFT (16u) +#define MFT_COMBINE_COMBINE2_WIDTH (1u) +#define MFT_COMBINE_MCOMBINE1_MASK (0x8000u) +#define MFT_COMBINE_MCOMBINE1_SHIFT (15u) +#define MFT_COMBINE_MCOMBINE1_WIDTH (1u) +#define MFT_COMBINE_FAULTEN1_MASK (0x4000u) +#define MFT_COMBINE_FAULTEN1_SHIFT (14u) +#define MFT_COMBINE_FAULTEN1_WIDTH (1u) +#define MFT_COMBINE_SYNCEN1_MASK (0x2000u) +#define MFT_COMBINE_SYNCEN1_SHIFT (13u) +#define MFT_COMBINE_SYNCEN1_WIDTH (1u) +#define MFT_COMBINE_DTEN1_MASK (0x1000u) +#define MFT_COMBINE_DTEN1_SHIFT (12u) +#define MFT_COMBINE_DTEN1_WIDTH (1u) +#define MFT_COMBINE_DECAP1_MASK (0x800u) +#define MFT_COMBINE_DECAP1_SHIFT (11u) +#define MFT_COMBINE_DECAP1_WIDTH (1u) +#define MFT_COMBINE_DECAPEN1_MASK (0x400u) +#define MFT_COMBINE_DECAPEN1_SHIFT (10u) +#define MFT_COMBINE_DECAPEN1_WIDTH (1u) +#define MFT_COMBINE_COMP1_MASK (0x200u) +#define MFT_COMBINE_COMP1_SHIFT (9u) +#define MFT_COMBINE_COMP1_WIDTH (1u) +#define MFT_COMBINE_COMBINE1_MASK (0x100u) +#define MFT_COMBINE_COMBINE1_SHIFT (8u) +#define MFT_COMBINE_COMBINE1_WIDTH (1u) +#define MFT_COMBINE_MCOMBINE0_MASK (0x80u) +#define MFT_COMBINE_MCOMBINE0_SHIFT (7u) +#define MFT_COMBINE_MCOMBINE0_WIDTH (1u) +#define MFT_COMBINE_FAULTEN0_MASK (0x40u) +#define MFT_COMBINE_FAULTEN0_SHIFT (6u) +#define MFT_COMBINE_FAULTEN0_WIDTH (1u) +#define MFT_COMBINE_SYNCEN0_MASK (0x20u) +#define MFT_COMBINE_SYNCEN0_SHIFT (5u) +#define MFT_COMBINE_SYNCEN0_WIDTH (1u) +#define MFT_COMBINE_DTEN0_MASK (0x10u) +#define MFT_COMBINE_DTEN0_SHIFT (4u) +#define MFT_COMBINE_DTEN0_WIDTH (1u) +#define MFT_COMBINE_DECAP0_MASK (0x08u) +#define MFT_COMBINE_DECAP0_SHIFT (3u) +#define MFT_COMBINE_DECAP0_WIDTH (1u) +#define MFT_COMBINE_DECAPEN0_MASK (0x04u) +#define MFT_COMBINE_DECAPEN0_SHIFT (2u) +#define MFT_COMBINE_DECAPEN0_WIDTH (1u) +#define MFT_COMBINE_COMP0_MASK (0x02u) +#define MFT_COMBINE_COMP0_SHIFT (1u) +#define MFT_COMBINE_COMP0_WIDTH (1u) +#define MFT_COMBINE_COMBINE0_MASK (0x01u) +#define MFT_COMBINE_COMBINE0_SHIFT (0u) +#define MFT_COMBINE_COMBINE0_WIDTH (1u) + +/* DEADTIME Bit Fields */ +#define MFT_DEADTIME_DTVALEX_MASK (0xF0000u) +#define MFT_DEADTIME_DTVALEX_SHIFT (16u) +#define MFT_DEADTIME_DTVALEX_WIDTH (4u) +#define MFT_DEADTIME_DTPS_MASK (0xC0u) +#define MFT_DEADTIME_DTPS_SHIFT (6u) +#define MFT_DEADTIME_DTPS_WIDTH (2u) +#define MFT_DEADTIME_DTVAL_MASK (0x3Fu) +#define MFT_DEADTIME_DTVAL_SHIFT (0u) +#define MFT_DEADTIME_DTVAL_WIDTH (6u) + +/* EXTTRIG Bit Fields */ +#define MFT_EXTTRIG_CH7TRIG_MASK (0x200u) +#define MFT_EXTTRIG_CH7TRIG_SHIFT (9u) +#define MFT_EXTTRIG_CH7TRIG_WIDTH (1u) +#define MFT_EXTTRIG_CH6TRIG_MASK (0x100u) +#define MFT_EXTTRIG_CH6TRIG_SHIFT (8u) +#define MFT_EXTTRIG_CH6TRIG_WIDTH (1u) +#define MFT_EXTTRIG_TRIGF_MASK (0x80u) +#define MFT_EXTTRIG_TRIGF_SHIFT (7u) +#define MFT_EXTTRIG_TRIGF_WIDTH (1u) +#define MFT_EXTTRIG_INITTRIGEN_MASK (0x40u) +#define MFT_EXTTRIG_INITTRIGEN_SHIFT (6u) +#define MFT_EXTTRIG_INITTRIGEN_WIDTH (1u) +#define MFT_EXTTRIG_CH1TRIG_MASK (0x20u) +#define MFT_EXTTRIG_CH1TRIG_SHIFT (5u) +#define MFT_EXTTRIG_CH1TRIG_WIDTH (1u) +#define MFT_EXTTRIG_CH0TRIG_MASK (0x10u) +#define MFT_EXTTRIG_CH0TRIG_SHIFT (4u) +#define MFT_EXTTRIG_CH0TRIG_WIDTH (1u) +#define MFT_EXTTRIG_CH5TRIG_MASK (0x08u) +#define MFT_EXTTRIG_CH5TRIG_SHIFT (3u) +#define MFT_EXTTRIG_CH5TRIG_WIDTH (1u) +#define MFT_EXTTRIG_CH4TRIG_MASK (0x04u) +#define MFT_EXTTRIG_CH4TRIG_SHIFT (2u) +#define MFT_EXTTRIG_CH4TRIG_WIDTH (1u) +#define MFT_EXTTRIG_CH3TRIG_MASK (0x02u) +#define MFT_EXTTRIG_CH3TRIG_SHIFT (1u) +#define MFT_EXTTRIG_CH3TRIG_WIDTH (1u) +#define MFT_EXTTRIG_CH2TRIG_MASK (0x01u) +#define MFT_EXTTRIG_CH2TRIG_SHIFT (0u) +#define MFT_EXTTRIG_CH2TRIG_WIDTH (1u) + +/* POL Bit Fields */ +#define MFT_POL_POL7_MASK (0x80u) +#define MFT_POL_POL7_SHIFT (7u) +#define MFT_POL_POL7_WIDTH (1u) +#define MFT_POL_POL6_MASK (0x40u) +#define MFT_POL_POL6_SHIFT (6u) +#define MFT_POL_POL6_WIDTH (1u) +#define MFT_POL_POL5_MASK (0x20u) +#define MFT_POL_POL5_SHIFT (5u) +#define MFT_POL_POL5_WIDTH (1u) +#define MFT_POL_POL4_MASK (0x10u) +#define MFT_POL_POL4_SHIFT (4u) +#define MFT_POL_POL4_WIDTH (1u) +#define MFT_POL_POL3_MASK (0x08u) +#define MFT_POL_POL3_SHIFT (3u) +#define MFT_POL_POL3_WIDTH (1u) +#define MFT_POL_POL2_MASK (0x04u) +#define MFT_POL_POL2_SHIFT (2u) +#define MFT_POL_POL2_WIDTH (1u) +#define MFT_POL_POL1_MASK (0x02u) +#define MFT_POL_POL1_SHIFT (1u) +#define MFT_POL_POL1_WIDTH (1u) +#define MFT_POL_POL0_MASK (0x01u) +#define MFT_POL_POL0_SHIFT (0u) +#define MFT_POL_POL0_WIDTH (1u) + +/* FMS Bit Fields */ +#define MFT_FMS_FAULTF_MASK (0x80u) +#define MFT_FMS_FAULTF_SHIFT (7u) +#define MFT_FMS_FAULTF_WIDTH (1u) +#define MFT_FMS_WPEN_MASK (0x40u) +#define MFT_FMS_WPEN_SHIFT (6u) +#define MFT_FMS_WPEN_WIDTH (1u) +#define MFT_FMS_FAULTIN_MASK (0x20u) +#define MFT_FMS_FAULTIN_SHIFT (5u) +#define MFT_FMS_FAULTIN_WIDTH (1u) +#define MFT_FMS_FAULTF3_MASK (0x08u) +#define MFT_FMS_FAULTF3_SHIFT (3u) +#define MFT_FMS_FAULTF3_WIDTH (1u) +#define MFT_FMS_FAULTF2_MASK (0x04u) +#define MFT_FMS_FAULTF2_SHIFT (2u) +#define MFT_FMS_FAULTF2_WIDTH (1u) +#define MFT_FMS_FAULTF1_MASK (0x02u) +#define MFT_FMS_FAULTF1_SHIFT (1u) +#define MFT_FMS_FAULTF1_WIDTH (1u) +#define MFT_FMS_FAULTF0_MASK (0x01u) +#define MFT_FMS_FAULTF0_SHIFT (0u) +#define MFT_FMS_FAULTF0_WIDTH (1u) + +/* FILTER Bit Fields */ +#define MFT_FILTER_CH3FVAL_MASK (0xF000u) +#define MFT_FILTER_CH3FVAL_SHIFT (12u) +#define MFT_FILTER_CH3FVAL_WIDTH (4u) +#define MFT_FILTER_CH2FVAL_MASK (0xF00u) +#define MFT_FILTER_CH2FVAL_SHIFT (8u) +#define MFT_FILTER_CH2FVAL_WIDTH (4u) +#define MFT_FILTER_CH1FVAL_MASK (0xF0u) +#define MFT_FILTER_CH1FVAL_SHIFT (4u) +#define MFT_FILTER_CH1FVAL_WIDTH (4u) +#define MFT_FILTER_CH0FVAL_MASK (0x0Fu) +#define MFT_FILTER_CH0FVAL_SHIFT (0u) +#define MFT_FILTER_CH0FVAL_WIDTH (4u) + +/* FLTCTRL Bit Fields */ +#define MFT_FLTCTRL_FSTATE_MASK (0x8000u) +#define MFT_FLTCTRL_FSTATE_SHIFT (15u) +#define MFT_FLTCTRL_FSTATE_WIDTH (1u) +#define MFT_FLTCTRL_FFVAL_MASK (0xF00u) +#define MFT_FLTCTRL_FFVAL_SHIFT (8u) +#define MFT_FLTCTRL_FFVAL_WIDTH (4u) +#define MFT_FLTCTRL_FFLTR3EN_MASK (0x80u) +#define MFT_FLTCTRL_FFLTR3EN_SHIFT (7u) +#define MFT_FLTCTRL_FFLTR3EN_WIDTH (1u) +#define MFT_FLTCTRL_FFLTR2EN_MASK (0x40u) +#define MFT_FLTCTRL_FFLTR2EN_SHIFT (6u) +#define MFT_FLTCTRL_FFLTR2EN_WIDTH (1u) +#define MFT_FLTCTRL_FFLTR1EN_MASK (0x20u) +#define MFT_FLTCTRL_FFLTR1EN_SHIFT (5u) +#define MFT_FLTCTRL_FFLTR1EN_WIDTH (1u) +#define MFT_FLTCTRL_FFLTR0EN_MASK (0x10u) +#define MFT_FLTCTRL_FFLTR0EN_SHIFT (4u) +#define MFT_FLTCTRL_FFLTR0EN_WIDTH (1u) +#define MFT_FLTCTRL_FAULT3EN_MASK (0x08u) +#define MFT_FLTCTRL_FAULT3EN_SHIFT (3u) +#define MFT_FLTCTRL_FAULT3EN_WIDTH (1u) +#define MFT_FLTCTRL_FAULT2EN_MASK (0x04u) +#define MFT_FLTCTRL_FAULT2EN_SHIFT (2u) +#define MFT_FLTCTRL_FAULT2EN_WIDTH (1u) +#define MFT_FLTCTRL_FAULT1EN_MASK (0x02u) +#define MFT_FLTCTRL_FAULT1EN_SHIFT (1u) +#define MFT_FLTCTRL_FAULT1EN_WIDTH (1u) +#define MFT_FLTCTRL_FAULT0EN_MASK (0x01u) +#define MFT_FLTCTRL_FAULT0EN_SHIFT (0u) +#define MFT_FLTCTRL_FAULT0EN_WIDTH (1u) + +/* QDCTRL Bit Fields */ +#define MFT_QDCTRL_PHZCOF_MASK (0x1000u) +#define MFT_QDCTRL_PHZCOF_SHIFT (12) +#define MFT_QDCTRL_PHZCOF_WIDTH (1) +#define MFT_QDCTRL_PHZMODE_MASK (0xC00u) +#define MFT_QDCTRL_PHZMODE_SHIFT (10) +#define MFT_QDCTRL_PHZMODE_WIDTH (2) +#define MFT_QDCTRL_PHZPOL_MASK (0x200u) +#define MFT_QDCTRL_PHZPOL_SHIFT (9) +#define MFT_QDCTRL_PHZPOL_WIDTH (1) +#define MFT_QDCTRL_PHZFLTREN_MASK (0x100u) +#define MFT_QDCTRL_PHZFLTREN_SHIFT (8) +#define MFT_QDCTRL_PHZFLTREN_WIDTH (1) +#define MFT_QDCTRL_PHAFLTREN_MASK (0x80u) +#define MFT_QDCTRL_PHAFLTREN_SHIFT (7u) +#define MFT_QDCTRL_PHAFLTREN_WIDTH (1u) +#define MFT_QDCTRL_PHBFLTREN_MASK (0x40u) +#define MFT_QDCTRL_PHBFLTREN_SHIFT (6u) +#define MFT_QDCTRL_PHBFLTREN_WIDTH (1u) +#define MFT_QDCTRL_PHAPOL_MASK (0x20u) +#define MFT_QDCTRL_PHAPOL_SHIFT (5u) +#define MFT_QDCTRL_PHAPOL_WIDTH (1u) +#define MFT_QDCTRL_PHBPOL_MASK (0x10u) +#define MFT_QDCTRL_PHBPOL_SHIFT (4u) +#define MFT_QDCTRL_PHBPOL_WIDTH (1u) +#define MFT_QDCTRL_QUADMODE_MASK (0x08u) +#define MFT_QDCTRL_QUADMODE_SHIFT (3u) +#define MFT_QDCTRL_QUADMODE_WIDTH (1u) +#define MFT_QDCTRL_QUADIR_MASK (0x04u) +#define MFT_QDCTRL_QUADIR_SHIFT (2u) +#define MFT_QDCTRL_QUADIR_WIDTH (1u) +#define MFT_QDCTRL_TOFDIR_MASK (0x02u) +#define MFT_QDCTRL_TOFDIR_SHIFT (1u) +#define MFT_QDCTRL_TOFDIR_WIDTH (1u) +#define MFT_QDCTRL_QUADEN_MASK (0x01u) +#define MFT_QDCTRL_QUADEN_SHIFT (0u) +#define MFT_QDCTRL_QUADEN_WIDTH (1u) + +/* CONF Bit Fields */ +#define MFT_CONF_ITRIGR_MASK (0x800u) +#define MFT_CONF_ITRIGR_SHIFT (11u) +#define MFT_CONF_ITRIGR_WIDTH (1u) +#define MFT_CONF_GTBEOUT_MASK (0x400u) +#define MFT_CONF_GTBEOUT_SHIFT (10u) +#define MFT_CONF_GTBEOUT_WIDTH (1u) +#define MFT_CONF_GTBEEN_MASK (0x200u) +#define MFT_CONF_GTBEEN_SHIFT (9u) +#define MFT_CONF_GTBEEN_WIDTH (1u) +#define MFT_CONF_BDMMODE_MASK (0xC0u) +#define MFT_CONF_BDMMODE_SHIFT (6u) +#define MFT_CONF_BDMMODE_WIDTH (2u) +#define MFT_CONF_LDFQ_MASK (0x1Fu) +#define MFT_CONF_LDFQ_SHIFT (0u) +#define MFT_CONF_LDFQ_WIDTH (5u) + +/* FLTPOL Bit Fields */ +#define MFT_FLTPOL_FLT3POL_MASK (0x08u) +#define MFT_FLTPOL_FLT3POL_SHIFT (3u) +#define MFT_FLTPOL_FLT3POL_WIDTH (1u) +#define MFT_FLTPOL_FLT2POL_MASK (0x04u) +#define MFT_FLTPOL_FLT2POL_SHIFT (2u) +#define MFT_FLTPOL_FLT2POL_WIDTH (1u) +#define MFT_FLTPOL_FLT1POL_MASK (0x02u) +#define MFT_FLTPOL_FLT1POL_SHIFT (1u) +#define MFT_FLTPOL_FLT1POL_WIDTH (1u) +#define MFT_FLTPOL_FLT0POL_MASK (0x01u) +#define MFT_FLTPOL_FLT0POL_SHIFT (0u) +#define MFT_FLTPOL_FLT0POL_WIDTH (1u) + +/* SYNCONF Bit Fields */ +#define MFT_SYNCONF_HWSOC_MASK (0x100000u) +#define MFT_SYNCONF_HWSOC_SHIFT (20u) +#define MFT_SYNCONF_HWSOC_WIDTH (1u) +#define MFT_SYNCONF_HWINVC_MASK (0x80000u) +#define MFT_SYNCONF_HWINVC_SHIFT (19u) +#define MFT_SYNCONF_HWINVC_WIDTH (1u) +#define MFT_SYNCONF_HWOM_MASK (0x40000u) +#define MFT_SYNCONF_HWOM_SHIFT (18u) +#define MFT_SYNCONF_HWOM_WIDTH (1u) +#define MFT_SYNCONF_HWWRBUF_MASK (0x20000u) +#define MFT_SYNCONF_HWWRBUF_SHIFT (17u) +#define MFT_SYNCONF_HWWRBUF_WIDTH (1u) +#define MFT_SYNCONF_HWRSTCNT_MASK (0x10000u) +#define MFT_SYNCONF_HWRSTCNT_SHIFT (16u) +#define MFT_SYNCONF_HWRSTCNT_WIDTH (1u) +#define MFT_SYNCONF_SWSOC_MASK (0x1000u) +#define MFT_SYNCONF_SWSOC_SHIFT (12u) +#define MFT_SYNCONF_SWSOC_WIDTH (1u) +#define MFT_SYNCONF_SWINVC_MASK (0x800u) +#define MFT_SYNCONF_SWINVC_SHIFT (11u) +#define MFT_SYNCONF_SWINVC_WIDTH (1u) +#define MFT_SYNCONF_SWOM_MASK (0x400u) +#define MFT_SYNCONF_SWOM_SHIFT (10u) +#define MFT_SYNCONF_SWOM_WIDTH (1u) +#define MFT_SYNCONF_SWWRBUF_MASK (0x200u) +#define MFT_SYNCONF_SWWRBUF_SHIFT (9u) +#define MFT_SYNCONF_SWWRBUF_WIDTH (1u) +#define MFT_SYNCONF_SWRSTCNT_MASK (0x100u) +#define MFT_SYNCONF_SWRSTCNT_SHIFT (8u) +#define MFT_SYNCONF_SWRSTCNT_WIDTH (1u) +#define MFT_SYNCONF_SYNCMODE_MASK (0x80u) +#define MFT_SYNCONF_SYNCMODE_SHIFT (7u) +#define MFT_SYNCONF_SYNCMODE_WIDTH (1u) +#define MFT_SYNCONF_SWOC_MASK (0x20u) +#define MFT_SYNCONF_SWOC_SHIFT (5u) +#define MFT_SYNCONF_SWOC_WIDTH (1u) +#define MFT_SYNCONF_INVC_MASK (0x10u) +#define MFT_SYNCONF_INVC_SHIFT (4u) +#define MFT_SYNCONF_INVC_WIDTH (1u) +#define MFT_SYNCONF_CNTINC_MASK (0x04u) +#define MFT_SYNCONF_CNTINC_SHIFT (2u) +#define MFT_SYNCONF_CNTINC_WIDTH (1u) +#define MFT_SYNCONF_HWTRIGMODE_MASK (0x01u) +#define MFT_SYNCONF_HWTRIGMODE_SHIFT (0u) +#define MFT_SYNCONF_HWTRIGMODE_WIDTH (1u) + +/* INVCTRL Bit Fields */ +#define MFT_INVCTRL_INV3EN_MASK (0x08u) +#define MFT_INVCTRL_INV3EN_SHIFT (3u) +#define MFT_INVCTRL_INV3EN_WIDTH (1u) +#define MFT_INVCTRL_INV2EN_MASK (0x04u) +#define MFT_INVCTRL_INV2EN_SHIFT (2u) +#define MFT_INVCTRL_INV2EN_WIDTH (1u) +#define MFT_INVCTRL_INV1EN_MASK (0x02u) +#define MFT_INVCTRL_INV1EN_SHIFT (1u) +#define MFT_INVCTRL_INV1EN_WIDTH (1u) +#define MFT_INVCTRL_INV0EN_MASK (0x01u) +#define MFT_INVCTRL_INV0EN_SHIFT (0u) +#define MFT_INVCTRL_INV0EN_WIDTH (1u) + +/* SWOCTRL Bit Fields */ +#define MFT_SWOCTRL_CH7OCV_MASK (0x8000u) +#define MFT_SWOCTRL_CH7OCV_SHIFT (15u) +#define MFT_SWOCTRL_CH7OCV_WIDTH (1u) +#define MFT_SWOCTRL_CH6OCV_MASK (0x4000u) +#define MFT_SWOCTRL_CH6OCV_SHIFT (14u) +#define MFT_SWOCTRL_CH6OCV_WIDTH (1u) +#define MFT_SWOCTRL_CH5OCV_MASK (0x2000u) +#define MFT_SWOCTRL_CH5OCV_SHIFT (13u) +#define MFT_SWOCTRL_CH5OCV_WIDTH (1u) +#define MFT_SWOCTRL_CH4OCV_MASK (0x1000u) +#define MFT_SWOCTRL_CH4OCV_SHIFT (12u) +#define MFT_SWOCTRL_CH4OCV_WIDTH (1u) +#define MFT_SWOCTRL_CH3OCV_MASK (0x800u) +#define MFT_SWOCTRL_CH3OCV_SHIFT (11u) +#define MFT_SWOCTRL_CH3OCV_WIDTH (1u) +#define MFT_SWOCTRL_CH2OCV_MASK (0x400u) +#define MFT_SWOCTRL_CH2OCV_SHIFT (10u) +#define MFT_SWOCTRL_CH2OCV_WIDTH (1u) +#define MFT_SWOCTRL_CH1OCV_MASK (0x200u) +#define MFT_SWOCTRL_CH1OCV_SHIFT (9u) +#define MFT_SWOCTRL_CH1OCV_WIDTH (1u) +#define MFT_SWOCTRL_CH0OCV_MASK (0x100u) +#define MFT_SWOCTRL_CH0OCV_SHIFT (8u) +#define MFT_SWOCTRL_CH0OCV_WIDTH (1u) +#define MFT_SWOCTRL_CH7OC_MASK (0x80u) +#define MFT_SWOCTRL_CH7OC_SHIFT (7u) +#define MFT_SWOCTRL_CH7OC_WIDTH (1u) +#define MFT_SWOCTRL_CH6OC_MASK (0x40u) +#define MFT_SWOCTRL_CH6OC_SHIFT (6u) +#define MFT_SWOCTRL_CH6OC_WIDTH (1u) +#define MFT_SWOCTRL_CH5OC_MASK (0x20u) +#define MFT_SWOCTRL_CH5OC_SHIFT (5u) +#define MFT_SWOCTRL_CH5OC_WIDTH (1u) +#define MFT_SWOCTRL_CH4OC_MASK (0x10u) +#define MFT_SWOCTRL_CH4OC_SHIFT (4u) +#define MFT_SWOCTRL_CH4OC_WIDTH (1u) +#define MFT_SWOCTRL_CH3OC_MASK (0x08u) +#define MFT_SWOCTRL_CH3OC_SHIFT (3u) +#define MFT_SWOCTRL_CH3OC_WIDTH (1u) +#define MFT_SWOCTRL_CH2OC_MASK (0x04u) +#define MFT_SWOCTRL_CH2OC_SHIFT (2u) +#define MFT_SWOCTRL_CH2OC_WIDTH (1u) +#define MFT_SWOCTRL_CH1OC_MASK (0x02u) +#define MFT_SWOCTRL_CH1OC_SHIFT (1u) +#define MFT_SWOCTRL_CH1OC_WIDTH (1u) +#define MFT_SWOCTRL_CH0OC_MASK (0x01u) +#define MFT_SWOCTRL_CH0OC_SHIFT (0u) +#define MFT_SWOCTRL_CH0OC_WIDTH (1u) + +/* PWMLOAD Bit Fields */ +#define MFT_PWMLOAD_GLDOK_MASK (0x800u) +#define MFT_PWMLOAD_GLDOK_SHIFT (11u) +#define MFT_PWMLOAD_GLDOK_WIDTH (1u) +#define MFT_PWMLOAD_GLEN_MASK (0x400u) +#define MFT_PWMLOAD_GLEN_SHIFT (10u) +#define MFT_PWMLOAD_GLEN_WIDTH (1u) +#define MFT_PWMLOAD_LDOK_MASK (0x200u) +#define MFT_PWMLOAD_LDOK_SHIFT (9u) +#define MFT_PWMLOAD_LDOK_WIDTH (1u) +#define MFT_PWMLOAD_HCSEL_MASK (0x100u) +#define MFT_PWMLOAD_HCSEL_SHIFT (8u) +#define MFT_PWMLOAD_HCSEL_WIDTH (1u) +#define MFT_PWMLOAD_CH7SEL_MASK (0x80u) +#define MFT_PWMLOAD_CH7SEL_SHIFT (7u) +#define MFT_PWMLOAD_CH7SEL_WIDTH (1u) +#define MFT_PWMLOAD_CH6SEL_MASK (0x40u) +#define MFT_PWMLOAD_CH6SEL_SHIFT (6u) +#define MFT_PWMLOAD_CH6SEL_WIDTH (1u) +#define MFT_PWMLOAD_CH5SEL_MASK (0x20u) +#define MFT_PWMLOAD_CH5SEL_SHIFT (5u) +#define MFT_PWMLOAD_CH5SEL_WIDTH (1u) +#define MFT_PWMLOAD_CH4SEL_MASK (0x10u) +#define MFT_PWMLOAD_CH4SEL_SHIFT (4u) +#define MFT_PWMLOAD_CH4SEL_WIDTH (1u) +#define MFT_PWMLOAD_CH3SEL_MASK (0x08u) +#define MFT_PWMLOAD_CH3SEL_SHIFT (3u) +#define MFT_PWMLOAD_CH3SEL_WIDTH (1u) +#define MFT_PWMLOAD_CH2SEL_MASK (0x04u) +#define MFT_PWMLOAD_CH2SEL_SHIFT (2u) +#define MFT_PWMLOAD_CH2SEL_WIDTH (1u) +#define MFT_PWMLOAD_CH1SEL_MASK (0x02u) +#define MFT_PWMLOAD_CH1SEL_SHIFT (1u) +#define MFT_PWMLOAD_CH1SEL_WIDTH (1u) +#define MFT_PWMLOAD_CH0SEL_MASK (0x01u) +#define MFT_PWMLOAD_CH0SEL_SHIFT (0u) +#define MFT_PWMLOAD_CH0SEL_WIDTH (1u) + +/* HCR Bit Fields */ +#define MFT_HCR_HCVAL_MASK (0xFFFFu) +#define MFT_HCR_HCVAL_SHIFT (0u) +#define MFT_HCR_HCVAL_WIDTH (16u) + +/* PAIR_DEADTIME Bit Fields */ +#define MFT_PAIR_DEADTIME_DTVALEX_MASK (0xF0000u) +#define MFT_PAIR_DEADTIME_DTVALEX_SHIFT (16u) +#define MFT_PAIR_DEADTIME_DTVALEX_WIDTH (4u) +#define MFT_PAIR_DEADTIME_DTPS_MASK (0xC0u) +#define MFT_PAIR_DEADTIME_DTPS_SHIFT (6u) +#define MFT_PAIR_DEADTIME_DTPS_WIDTH (2u) +#define MFT_PAIR_DEADTIME_DTVAL_MASK (0x3Fu) +#define MFT_PAIR_DEADTIME_DTVAL_SHIFT (0u) +#define MFT_PAIR_DEADTIME_DTVAL_WIDTH (6u) + +/* MOD_MIRROR Bit Fields */ +#define MFT_MOD_MIRROR_MOD_M_MASK (0xFFFF0000u) +#define MFT_MOD_MIRROR_MOD_M_SHIFT (16u) +#define MFT_MOD_MIRROR_MOD_M_WIDTH (16u) +#define MFT_MOD_MIRROR_FRACMOD_M_MASK (0xF800u) +#define MFT_MOD_MIRROR_FRACMOD_M_SHIFT (11u) +#define MFT_MOD_MIRROR_FRACMOD_M_WIDTH (5u) + +/* CV_MIRROR Bit Fields */ +#define MFT_CV_MIRROR_VAL_M_MASK (0xFFFF0000u) +#define MFT_CV_MIRROR_VAL_M_SHIFT (16u) +#define MFT_CV_MIRROR_VAL_M_WIDTH (16u) +#define MFT_CV_MIRROR_FRACVAL_MASK (0xF800u) +#define MFT_CV_MIRROR_FRACVAL_SHIFT (11u) +#define MFT_CV_MIRROR_FRACVAL_WIDTH (5u) + +/* SIM_OBE Bit Fields */ +#define MFT_SIM_OBE_OBE_MASK (0x01u) +#define MFT_SIM_OBE_OBE_SHIFT (0u) +#define MFT_SIM_OBE_OBE_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +typedef struct _MftRegType_ +{ + volatile uint32_t SC; /*!< Status And Control, offset: 0x00 */ + volatile uint32_t CNT; /*!< Counter, offset: 0x04 */ + volatile uint32_t MODULO; /*!< Modulo, offset: 0x08 */ + struct + { + volatile uint32_t CSC; /*!< Channel Status And Control */ + volatile uint32_t CV; /*!< Channel Value */ + } CH[MFT_CHANNEL_NUM]; /*!< channels, offset: 0x0C */ + volatile uint32_t CNTIN; /*!< Counter Initial Value, offset: 0x4C */ + volatile uint32_t STATUS; /*!< Capture And Compare Status, offset: 0x50 */ + volatile uint32_t MODE; /*!< Features Mode Selection, offset: 0x54 */ + volatile uint32_t SYNC; /*!< Synchronization, offset: 0x58 */ + volatile uint32_t OUTINIT; /*!< Initial State For Channels Output, offset: 0x5C */ + volatile uint32_t OUTMASK; /*!< Output Mask, offset: 0x60 */ + volatile uint32_t COMBINE; /*!< Function For Linked Channels, offset: 0x64 */ + volatile uint32_t DEADTIME; /*!< Deadtime Configuration, offset: 0x68 */ + volatile uint32_t EXTTRIG; /*!< MFT External Trigger, offset: 0x6C */ + volatile uint32_t POL; /*!< Channels Polarity, offset: 0x70 */ + volatile uint32_t FMS; /*!< Fault Mode Status, offset: 0x74 */ + volatile uint32_t FILTER; /*!< Input Capture Filter Control, offset: 0x78 */ + volatile uint32_t FLTCTRL; /*!< Fault Control, offset: 0x7C */ + volatile uint32_t QDCTRL; /*!< Quadrature Decoder Control And Status, offset: 0x80 */ + volatile uint32_t CONF; /*!< Configuration, offset: 0x84 */ + volatile uint32_t FLTPOL; /*!< MFT Fault Input Polarity, offset: 0x88 */ + volatile uint32_t SYNCONF; /*!< Synchronization Configuration, offset: 0x8C */ + volatile uint32_t INVCTRL; /*!< MFT Inverting Control, offset: 0x90 */ + volatile uint32_t SWOCTRL; /*!< MFT Software Output Control, offset: 0x94 */ + volatile uint32_t PWMLOAD; /*!< MFT PWM Load, offset: 0x98 */ + volatile uint32_t HCR; /*!< Half Cycle Register, offset: 0x9C */ + struct + { + volatile uint32_t DEADTIME; /*!< Pair Deadtime Configuration */ + } PAIR[MFT_DEADTIME_PAIR]; /*!< Pairs, offset: 0xA0 */ + volatile uint32_t MOD_MIRROR; /*!< Mirror of Modulo Value, offset: 0xB0 */ + struct + { + volatile uint32_t CV; /*!< Mirror of Channel Match Value */ + } MIRROR[MFT_CHANNEL_NUM]; /*!< Mirror registers, offset: 0xB4 */ + uint32_t RESERVED[1]; /*!< Reserverd block, offset: 0xD4 */ + volatile uint32_t SIM_OBE; /*!< SIM Output Enable, offset: 0xD8 */ +} MftRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the Filter Prescaler + * + * This function gets the current Filter Prescaler. + * The bits FLTPS selects the clock prescaler used in the MFT filters: + * - channel input filters + * - fault inputs filters + * - quadrature decoder phase A and B inputs filters + * Writing to the bits FLTPS has immediate effect. + * + * \param[in] obj : pointer to MFT register instance + * \return Filter Prescaler + * - 0000b : Divide by 1 + * - 0001b : Divide by 2 + * - 0010b : Divide by 3 + * - 0011b : Divide by 4 + * - 0100b : Divide by 5 + * - 0101b : Divide by 6 + * - 0110b : Divide by 7 + * - 0111b : Divide by 8 + * - 1000b : Divide by 9 + * - 1001b : Divide by 10 + * - 1010b : Divide by 11 + * - 1011b : Divide by 12 + * - 1100b : Divide by 13 + * - 1101b : Divide by 14 + * - 1110b : Divide by 15 + * - 1111b : Divide by 16 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScFltPs(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_FLTPS_MASK) >> MFT_SC_FLTPS_SHIFT); +} + +/*! \brief Sets the Filter Prescaler + * + * This function sets the Filter Prescaler. + * The bits FLTPS selects the clock prescaler used in the MFT filters: + * - channel input filters + * - fault inputs filters + * - quadrature decoder phase A and B inputs filters + * Writing to the bits FLTPS has immediate effect. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Filter Prescaler + * - 0000b : Divide by 1 + * - 0001b : Divide by 2 + * - 0010b : Divide by 3 + * - 0011b : Divide by 4 + * - 0100b : Divide by 5 + * - 0101b : Divide by 6 + * - 0110b : Divide by 7 + * - 0111b : Divide by 8 + * - 1000b : Divide by 9 + * - 1001b : Divide by 10 + * - 1010b : Divide by 11 + * - 1011b : Divide by 12 + * - 1100b : Divide by 13 + * - 1101b : Divide by 14 + * - 1110b : Divide by 15 + * - 1111b : Divide by 16 + */ +__attribute__((always_inline)) static inline void MftReg_SetScFltPs(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_FLTPS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_FLTPS_SHIFT)) & MFT_SC_FLTPS_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Channel 7 PWM enable bit + * + * This function gets the current Channel 7 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 7 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScPwmEn7(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_PWMEN7_MASK) >> MFT_SC_PWMEN7_SHIFT); +} + +/*! \brief Sets the Channel 7 PWM enable bit + * + * This function sets the Channel 7 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 7 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetScPwmEn7(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_PWMEN7_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_PWMEN7_SHIFT)) & MFT_SC_PWMEN7_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Channel 6 PWM enable bit + * + * This function gets the current Channel 6 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 6 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScPwmEn6(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_PWMEN6_MASK) >> MFT_SC_PWMEN6_SHIFT); +} + +/*! \brief Sets the Channel 6 PWM enable bit + * + * This function sets the Channel 6 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 6 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetScPwmEn6(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_PWMEN6_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_PWMEN6_SHIFT)) & MFT_SC_PWMEN6_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Channel 5 PWM enable bit + * + * This function gets the current Channel 5 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 5 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScPwmEn5(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_PWMEN5_MASK) >> MFT_SC_PWMEN5_SHIFT); +} + +/*! \brief Sets the Channel 5 PWM enable bit + * + * This function sets the Channel 5 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 5 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetScPwmEn5(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_PWMEN5_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_PWMEN5_SHIFT)) & MFT_SC_PWMEN5_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Channel 4 PWM enable bit + * + * This function gets the current Channel 4 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 4 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScPwmEn4(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_PWMEN4_MASK) >> MFT_SC_PWMEN4_SHIFT); +} + +/*! \brief Sets the Channel 4 PWM enable bit + * + * This function sets the Channel 4 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 4 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetScPwmEn4(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_PWMEN4_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_PWMEN4_SHIFT)) & MFT_SC_PWMEN4_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Channel 3 PWM enable bit + * + * This function gets the current Channel 3 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 3 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScPwmEn3(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_PWMEN3_MASK) >> MFT_SC_PWMEN3_SHIFT); +} + +/*! \brief Sets the Channel 3 PWM enable bit + * + * This function sets the Channel 3 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 3 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetScPwmEn3(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_PWMEN3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_PWMEN3_SHIFT)) & MFT_SC_PWMEN3_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Channel 2 PWM enable bit + * + * This function gets the current Channel 2 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 2 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScPwmEn2(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_PWMEN2_MASK) >> MFT_SC_PWMEN2_SHIFT); +} + +/*! \brief Sets the Channel 2 PWM enable bit + * + * This function sets the Channel 2 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 2 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetScPwmEn2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_PWMEN2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_PWMEN2_SHIFT)) & MFT_SC_PWMEN2_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Channel 1 PWM enable bit + * + * This function gets the current Channel 1 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 1 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScPwmEn1(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_PWMEN1_MASK) >> MFT_SC_PWMEN1_SHIFT); +} + +/*! \brief Sets the Channel 1 PWM enable bit + * + * This function sets the Channel 1 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 1 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetScPwmEn1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_PWMEN1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_PWMEN1_SHIFT)) & MFT_SC_PWMEN1_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Channel 0 PWM enable bit + * + * This function gets the current Channel 0 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 0 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScPwmEn0(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_PWMEN0_MASK) >> MFT_SC_PWMEN0_SHIFT); +} + +/*! \brief Sets the Channel 0 PWM enable bit + * + * This function sets the Channel 0 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 0 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetScPwmEn0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_PWMEN0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_PWMEN0_SHIFT)) & MFT_SC_PWMEN0_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Timer Overflow Flag + * + * This function gets the current Timer Overflow Flag. + * Set by hardware when the MFT counter passes the value in the MOD register. The TOF bit is cleared by + * reading the SC register while TOF is set and then writing a 0 to TOF bit. Writing a 1 to TOF has no effect. + * If another MFT overflow occurs between the read and write operations, the write operation has no effect; + * therefore, TOF remains set indicating an overflow has occurred. In this case, a TOF interrupt request is + * not lost due to the clearing sequence for a previous TOF. + * + * \param[in] obj : pointer to MFT register instance + * \return Timer Overflow Flag + * - 0b : MFT counter has not overflowed. + * - 1b : MFT counter has overflowed. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScTof(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_TOF_MASK) >> MFT_SC_TOF_SHIFT); +} + +/*! \brief Sets the Timer Overflow Flag + * + * This function sets the Timer Overflow Flag. + * Set by hardware when the MFT counter passes the value in the MOD register. The TOF bit is cleared by + * reading the SC register while TOF is set and then writing a 0 to TOF bit. Writing a 1 to TOF has no effect. + * If another MFT overflow occurs between the read and write operations, the write operation has no effect; + * therefore, TOF remains set indicating an overflow has occurred. In this case, a TOF interrupt request is + * not lost due to the clearing sequence for a previous TOF. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Timer Overflow Flag + * - 0b : clear the flag + * - 1b : No effect + */ +__attribute__((always_inline)) static inline void MftReg_SetScTof(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_TOF_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_TOF_SHIFT)) & MFT_SC_TOF_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Timer Overflow Interrupt Enable + * + * This function gets the current Timer Overflow Interrupt Enable. + * Enables MFT overflow interrupts. + * + * \param[in] obj : pointer to MFT register instance + * \return Timer Overflow Interrupt Enable + * - 0b : Disable TOF interrupts. Use software polling. + * - 1b : Enable TOF interrupts. An interrupt is generated when TOF equals one. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScToie(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_TOIE_MASK) >> MFT_SC_TOIE_SHIFT); +} + +/*! \brief Sets the Timer Overflow Interrupt Enable + * + * This function sets the Timer Overflow Interrupt Enable. + * Enables MFT overflow interrupts. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Timer Overflow Interrupt Enable + * - 0b : Disable TOF interrupts. Use software polling. + * - 1b : Enable TOF interrupts. An interrupt is generated when TOF equals one. + */ +__attribute__((always_inline)) static inline void MftReg_SetScToie(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_TOIE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_TOIE_SHIFT)) & MFT_SC_TOIE_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Reload Flag + * + * This function gets the current Reload Flag. + * The RF bit is set at each selected reload point. See Reload Points. + * The RF bit is cleared by reading the SC register while RF is set and then writing a 0 to RF bit. Writing 1 to + * RF has no effect. If another selected reload point happens between the read and write operations, the + * write operation has no effect; therefore, RF remains set. + * + * \param[in] obj : pointer to MFT register instance + * \return Reload Flag + * - 0b : A selected reload point did not happen + * - 1b : A selected reload point happened + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScRf(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_RF_MASK) >> MFT_SC_RF_SHIFT); +} + +/*! \brief Sets the Reload Flag + * + * This function sets the Reload Flag. + * The RF bit is set at each selected reload point. See Reload Points. + * The RF bit is cleared by reading the SC register while RF is set and then writing a 0 to RF bit. Writing 1 to + * RF has no effect. If another selected reload point happens between the read and write operations, the + * write operation has no effect; therefore, RF remains set. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Reload Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetScRf(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_RF_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_RF_SHIFT)) & MFT_SC_RF_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Reload Point Interrupt Enable + * + * This function gets the current Reload Point Interrupt Enable. + * Enables the reload point interrupt. + * + * \param[in] obj : pointer to MFT register instance + * \return Reload Point Interrupt Enable + * - 0b : Reload point interrupt is disabled. + * - 1b : Reload point interrupt is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScRie(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_RIE_MASK) >> MFT_SC_RIE_SHIFT); +} + +/*! \brief Sets the Reload Point Interrupt Enable + * + * This function sets the Reload Point Interrupt Enable. + * Enables the reload point interrupt. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Reload Point Interrupt Enable + * - 0b : Reload point interrupt is disabled. + * - 1b : Reload point interrupt is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetScRie(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_RIE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_RIE_SHIFT)) & MFT_SC_RIE_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Center-Aligned PWM Select + * + * This function gets the current Center-Aligned PWM Select. + * Selects CPWM mode. This mode configures the MFT to operate in Up-Down Counting mode. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Center-Aligned PWM Select + * - 0b : MFT counter operates in Up Counting mode. + * - 1b : MFT counter operates in Up-Down Counting mode. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScCPwms(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_CPWMS_MASK) >> MFT_SC_CPWMS_SHIFT); +} + +/*! \brief Sets the Center-Aligned PWM Select + * + * This function sets the Center-Aligned PWM Select. + * Selects CPWM mode. This mode configures the MFT to operate in Up-Down Counting mode. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Center-Aligned PWM Select + * - 0b : MFT counter operates in Up Counting mode. + * - 1b : MFT counter operates in Up-Down Counting mode. + */ +__attribute__((always_inline)) static inline void MftReg_SetScCPwms(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_CPWMS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_CPWMS_SHIFT)) & MFT_SC_CPWMS_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Clock Source Selection + * + * This function gets the current Clock Source Selection. + * Selects one of the three MFT counter clock sources. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Clock Source Selection + * - 00b : No clock selected. This in effect disables the MFT counter. + * - 01b : MFT input clock + * - 10b : Fixed frequency + * - 11b : External clock + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScClks(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_CLKS_MASK) >> MFT_SC_CLKS_SHIFT); +} + +/*! \brief Sets the Clock Source Selection + * + * This function sets the Clock Source Selection. + * Selects one of the three MFT counter clock sources. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Clock Source Selection + * - 00b : No clock selected. This in effect disables the MFT counter. + * - 01b : MFT input clock + * - 10b : Fixed frequency + * - 11b : External clock + */ +__attribute__((always_inline)) static inline void MftReg_SetScClks(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_CLKS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_CLKS_SHIFT)) & MFT_SC_CLKS_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Prescale Factor Selection + * + * This function gets the current Prescale Factor Selection. + * Selects one of 8 division factors for the clock source selected by CLKS. The new prescaler factor affects + * the clock source on the next MFT input clock cycle after the new value is updated into the register bits. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Prescale Factor Selection + * - 000b : Divide by 1 + * - 001b : Divide by 2 + * - 010b : Divide by 4 + * - 011b : Divide by 8 + * - 100b : Divide by 16 + * - 101b : Divide by 32 + * - 110b : Divide by 64 + * - 111b : Divide by 128 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScPs(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_PS_MASK) >> MFT_SC_PS_SHIFT); +} + +/*! \brief Sets the Prescale Factor Selection + * + * This function sets the Prescale Factor Selection. + * Selects one of 8 division factors for the clock source selected by CLKS. The new prescaler factor affects + * the clock source on the next MFT input clock cycle after the new value is updated into the register bits. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Prescale Factor Selection + * - 000b : Divide by 1 + * - 001b : Divide by 2 + * - 010b : Divide by 4 + * - 011b : Divide by 8 + * - 100b : Divide by 16 + * - 101b : Divide by 32 + * - 110b : Divide by 64 + * - 111b : Divide by 128 + */ +__attribute__((always_inline)) static inline void MftReg_SetScPs(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_PS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_PS_SHIFT)) & MFT_SC_PS_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Counter Value + * + * This function gets the current Counter Value. + * The CNT register contains the MFT counter value. + * Reset clears the CNT register. Writing any value to COUNT updates the counter with its initial value, CNTIN + * + * \param[in] obj : pointer to MFT register instance + * \return Counter Value + */ +__attribute__((always_inline)) static inline uint16_t MftReg_GetCntCount(const MftRegType *obj) +{ + return ((obj->CNT & MFT_CNT_COUNT_MASK) >> MFT_CNT_COUNT_SHIFT); +} + +/*! \brief Sets the Counter Value + * + * This function sets the current Counter Value. + * The CNT register contains the MFT counter value. + * Reset clears the CNT register. Writing any value to COUNT updates the counter with its initial value, CNTIN + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : Counter Value + */ +__attribute__((always_inline)) static inline void MftReg_SetCntCount(MftRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->CNT; + + tmp &= ~MFT_CNT_COUNT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CNT_COUNT_SHIFT)) & MFT_CNT_COUNT_MASK); + obj->CNT = tmp; +} + +/*! \brief Gets the Modulo Value + * + * This function gets the current Modulo Value. + * Writes to the MOD register are done on its write buffer. + * The MOD register is updated with its write buffer value according to Registers updated from write buffers. + * If MFTEN = 0, a write to SC register resets manually this write coherency mechanism + * + * \param[in] obj : pointer to MFT register instance + * \return Modulo Value + */ +__attribute__((always_inline)) static inline uint16_t MftReg_GetModuloMod(const MftRegType *obj) +{ + return ((obj->MODULO & MFT_MODULO_MOD_MASK) >> MFT_MODULO_MOD_SHIFT); +} + +/*! \brief Sets the Modulo Value + * + * This function sets the Modulo Value. + * Writes to the MOD register are done on its write buffer. + * The MOD register is updated with its write buffer value according to Registers updated from write buffers. + * If MFTEN = 0, a write to SC register resets manually this write coherency mechanism + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Modulo Value + */ +__attribute__((always_inline)) static inline void MftReg_SetModuloMod(MftRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->MODULO; + + tmp &= ~MFT_MODULO_MOD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_MODULO_MOD_SHIFT)) & MFT_MODULO_MOD_MASK); + obj->MODULO = tmp; +} + +/*! \brief Gets the Channel (n) Output Value + * + * This function gets the current Channel (n) Output Value. + * The CHOV bit has the final value of the channel (n) output. + * + * \note The CHOV bit should be ignored when the channel (n) is not in an output mode. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Channel (n) Output Value + * - 0b : The channel (n) output is zero. + * - 1b : The channel (n) output is one. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscChov(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_CHOV_MASK) >> MFT_CSC_CHOV_SHIFT); +} + +/*! \brief Gets the Channel (n) Input State + * + * This function gets the current Channel (n) Input State. + * The CHIS bit has the value of the channel (n) input after the double-sampling or the filtering (if the + * channel (n) filter is enabled) both them are inside the MFT. + * + * \note The CHIS bit should be ignored when the channel (n) is not in an input mode. + * + * \note When the pair channels is on dual edge mode, the channel (n+1) CHIS bit is the channel (n+1) + * input value and not the channel (n) input value (this signal is the input signal used by the dual + * edge mode). + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Channel (n) Input State + * - 0b : The channel (n) input is zero. + * - 1b : The channel (n) input is one. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscChis(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_CHIS_MASK) >> MFT_CSC_CHIS_SHIFT); +} + +/*! \brief Gets the Trigger mode control + * + * This function gets the current Trigger mode control. + * This bit controls the trigger generation on MFT channel outputs. This mode is allowed only if when MFT + * channel is configured to EPWM or CPWM modes. If a match in the channel occurs, a trigger pulse with + * one MFT clock cycle width will be generated in the channel output. See Channel trigger output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Trigger mode control + * - 0b : Channel outputs will generate the normal PWM outputs without generating a pulse. + * - 1b : If a match in the channel occurs, a trigger generation on channel output will happen. + * The trigger pulse width has one MFT clock cycle. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscTrigMode(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_TRIGMODE_MASK) >> MFT_CSC_TRIGMODE_SHIFT); +} + +/*! \brief Sets the Trigger mode control + * + * This function sets the Trigger mode control. + * This bit controls the trigger generation on MFT channel outputs. This mode is allowed only if when MFT + * channel is configured to EPWM or CPWM modes. If a match in the channel occurs, a trigger pulse with + * one MFT clock cycle width will be generated in the channel output. See Channel trigger output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of Trigger mode control + * - 0b : Channel outputs will generate the normal PWM outputs without generating a pulse. + * - 1b : If a match in the channel occurs, a trigger generation on channel output will happen. + * The trigger pulse width has one MFT clock cycle. + */ +__attribute__((always_inline)) static inline void MftReg_SetCscTrigMode(MftRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->CH[channel].CSC; + + tmp &= ~MFT_CSC_TRIGMODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CSC_TRIGMODE_SHIFT)) & MFT_CSC_TRIGMODE_MASK); + obj->CH[channel].CSC = tmp; +} + +/*! \brief Gets the Channel (n) Flag + * + * This function gets the current Channel (n) Flag. + * Set by hardware when an event occurs on the channel (n). CHF is cleared by reading the CnSC register + * while CHF is set and then writing a 0 to the CHF bit. Writing a 1 to CHF has no effect. + * If another event occurs between the read and write operations, the write operation has no effect; + * therefore, CHF remains set indicating an event has occurred. In this case a CHF interrupt request is not + * lost due to the clearing sequence for a previous CHF. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Channel (n) Flag + * - 0b : No channel (n) event has occurred. + * - 1b : A channel (n) event has occurred. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscChf(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_CHF_MASK) >> MFT_CSC_CHF_SHIFT); +} + +/*! \brief Sets the Channel (n) Flag + * + * This function sets the Channel (n) Flag. + * Set by hardware when an event occurs on the channel (n). CHF is cleared by reading the CnSC register + * while CHF is set and then writing a 0 to the CHF bit. Writing a 1 to CHF has no effect. + * If another event occurs between the read and write operations, the write operation has no effect; + * therefore, CHF remains set indicating an event has occurred. In this case a CHF interrupt request is not + * lost due to the clearing sequence for a previous CHF. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of Channel (n) Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetCscChf(MftRegType *obj, uint8_t channel, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->CH[channel].CSC; + + tmp &= ~MFT_CSC_CHF_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CSC_CHF_SHIFT)) & MFT_CSC_CHF_MASK); + obj->CH[channel].CSC = tmp; +} + +/*! \brief Gets the Channel (n) Interrupt Enable + * + * This function gets the current Channel (n) Interrupt Enable. + * Enables channel (n) interrupt. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Channel (n) Interrupt Enable + * - 0b : Disable channel (n) interrupt. Use software polling. + * - 1b : Enable channel (n) interrupt. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscChie(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_CHIE_MASK) >> MFT_CSC_CHIE_SHIFT); +} + +/*! \brief Sets the Channel (n) Interrupt Enable + * + * This function sets the Channel (n) Interrupt Enable. + * Enables channel (n) interrupt. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of Channel (n) Interrupt Enable + * - 0b : Disable channel (n) interrupt. Use software polling. + * - 1b : Enable channel (n) interrupt. + */ +__attribute__((always_inline)) static inline void MftReg_SetCscChie(MftRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->CH[channel].CSC; + + tmp &= ~MFT_CSC_CHIE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CSC_CHIE_SHIFT)) & MFT_CSC_CHIE_MASK); + obj->CH[channel].CSC = tmp; +} + +/*! \brief Gets the Channel (n) Mode Select + * + * This function gets the current Channel (n) Mode Select. + * Used on the selection of the channel (n) mode. See Channel Modes. +This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Channel (n) Mode Select + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscMsb(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_MSB_MASK) >> MFT_CSC_MSB_SHIFT); +} + +/*! \brief Sets the Channel (n) Mode Select + * + * This function sets the Channel (n) Mode Select. + * Used on the selection of the channel (n) mode. See Channel Modes. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of Channel (n) Mode Select + */ +__attribute__((always_inline)) static inline void MftReg_SetCscMsb(MftRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->CH[channel].CSC; + + tmp &= ~MFT_CSC_MSB_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CSC_MSB_SHIFT)) & MFT_CSC_MSB_MASK); + obj->CH[channel].CSC = tmp; +} + +/*! \brief Gets the Channel (n) Mode Select + * + * This function gets the current Channel (n) Mode Select. + * Used on the selection of the channel (n) mode. See Channel Modes. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Channel (n) Mode Select + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscMsa(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_MSA_MASK) >> MFT_CSC_MSA_SHIFT); +} + +/*! \brief Sets the Channel (n) Mode Select + * + * This function sets the Channel (n) Mode Select. + * Used on the selection of the channel (n) mode. See Channel Modes. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of Channel (n) Mode Select + */ +__attribute__((always_inline)) static inline void MftReg_SetCscMsa(MftRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->CH[channel].CSC; + + tmp &= ~MFT_CSC_MSA_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CSC_MSA_SHIFT)) & MFT_CSC_MSA_MASK); + obj->CH[channel].CSC = tmp; +} + +/*! \brief Gets the Channel (n) Edge or Level Select + * + * This function gets the current Channel (n) Edge or Level Select. + * Used on the selection of the channel (n) mode. See Channel Modes. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Channel (n) Edge or Level Select + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscElsb(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_ELSB_MASK) >> MFT_CSC_ELSB_SHIFT); +} + +/*! \brief Sets the Channel (n) Edge or Level Select + * + * This function sets the Channel (n) Edge or Level Select. + * Used on the selection of the channel (n) mode. See Channel Modes. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of Channel (n) Edge or Level Select + */ +__attribute__((always_inline)) static inline void MftReg_SetCscElsb(MftRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->CH[channel].CSC; + + tmp &= ~MFT_CSC_ELSB_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CSC_ELSB_SHIFT)) & MFT_CSC_ELSB_MASK); + obj->CH[channel].CSC = tmp; +} + +/*! \brief Gets the Channel (n) Edge or Level Select + * + * This function gets the current Channel (n) Edge or Level Select. + * Used on the selection of the channel (n) mode. See Channel Modes. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Channel (n) Edge or Level Select + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscElsa(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_ELSA_MASK) >> MFT_CSC_ELSA_SHIFT); +} + +/*! \brief Sets the Channel (n) Edge or Level Select + * + * This function sets the Channel (n) Edge or Level Select. + * Used on the selection of the channel (n) mode. See Channel Modes. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of Channel (n) Edge or Level Select + */ +__attribute__((always_inline)) static inline void MftReg_SetCscElsa(MftRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->CH[channel].CSC; + + tmp &= ~MFT_CSC_ELSA_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CSC_ELSA_SHIFT)) & MFT_CSC_ELSA_MASK); + obj->CH[channel].CSC = tmp; +} + +/*! \brief Gets the MFT counter reset by the selected input capture event + * + * This function gets the current MFT counter reset by the selected input capture event. + * MFT counter reset is driven by the selected event of the channel (n) in the Input Capture mode. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return MFT counter reset by the selected input capture event + * - 0b : MFT counter is not reset when the selected channel (n) input event is detected. + * - 1b : MFT counter is reset when the selected channel (n) input event is detected. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscIcrst(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_ICRST_MASK) >> MFT_CSC_ICRST_SHIFT); +} + +/*! \brief Sets the MFT counter reset by the selected input capture event + * + * This function sets the MFT counter reset by the selected input capture event. + * MFT counter reset is driven by the selected event of the channel (n) in the Input Capture mode. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of MFT counter reset by the selected input capture event + * - 0b : MFT counter is not reset when the selected channel (n) input event is detected. + * - 1b : MFT counter is reset when the selected channel (n) input event is detected. + */ +__attribute__((always_inline)) static inline void MftReg_SetCscIcrst(MftRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->CH[channel].CSC; + + tmp &= ~MFT_CSC_ICRST_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CSC_ICRST_SHIFT)) & MFT_CSC_ICRST_MASK); + obj->CH[channel].CSC = tmp; +} + +/*! \brief Gets the DMA Enable + * + * This function gets the current DMA Enable. + * Enables DMA transfers for the channel. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return DMA Enable + * - 0b : Disable DMA transfers. + * - 1b : Enable DMA transfers. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscDma(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_DMA_MASK) >> MFT_CSC_DMA_SHIFT); +} + +/*! \brief Sets the DMA Enable + * + * This function sets the DMA Enable. + * Enables DMA transfers for the channel. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of DMA Enable + * - 0b : Disable DMA transfers. + * - 1b : Enable DMA transfers. + */ +__attribute__((always_inline)) static inline void MftReg_SetCscDma(MftRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->CH[channel].CSC; + + tmp &= ~MFT_CSC_DMA_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CSC_DMA_SHIFT)) & MFT_CSC_DMA_MASK); + obj->CH[channel].CSC = tmp; +} + +/*! \brief Gets the Channel Value + * + * This function gets the current Channel Value. + * Captured MFT counter value of the input modes or the match value for the output modes + * In Input Capture , Capture Test, and Dual Edge Capture modes, any write to a CnV register is ignored. + * In output modes, writes to the CnV register are done on its write buffer + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Channel Value + */ +__attribute__((always_inline)) static inline uint16_t MftReg_GetCvVal(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CV & MFT_CV_VAL_MASK) >> MFT_CV_VAL_SHIFT); +} + +/*! \brief Sets the Channel Value + * + * This function sets the current Channel Value. + * Captured MFT counter value of the input modes or the match value for the output modes + * In Input Capture , Capture Test, and Dual Edge Capture modes, any write to a CnV register is ignored. + * In output modes, writes to the CnV register are done on its write buffer + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : Channel Value + */ +__attribute__((always_inline)) static inline void MftReg_SetCvVal(MftRegType *obj, uint8_t channel, uint16_t value) +{ + uint32_t tmp = obj->CH[channel].CV; + + tmp &= ~MFT_CV_VAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CV_VAL_SHIFT)) & MFT_CV_VAL_MASK); + obj->CH[channel].CV = tmp; +} + +/*! \brief Gets the Initial Value Of The MFT Counter + * + * This function gets the current Initial Value Of The MFT Counter. + * Writing to the CNTIN register latches the value into a buffer. + * The CNTIN register is updated with the value of its write buffer according to Registers updated from write buffers + * + * \param[in] obj : pointer to MFT register instance + * \return Initial Value Of The MFT Counter + */ +__attribute__((always_inline)) static inline uint16_t MftReg_GetCntInCntInit(const MftRegType *obj) +{ + return ((obj->CNTIN & MFT_CNTIN_CNTINIT_MASK) >> MFT_CNTIN_CNTINIT_SHIFT); +} + +/*! \brief Sets the Initial Value Of The MFT Counter + * + * This function sets the Initial Value Of The MFT Counter. + * Writing to the CNTIN register latches the value into a buffer. + * The CNTIN register is updated with the value of its write buffer according to Registers updated from write buffers + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Initial Value Of The MFT Counter + */ +__attribute__((always_inline)) static inline void MftReg_SetCntInCntInit(MftRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->CNTIN; + + tmp &= ~MFT_CNTIN_CNTINIT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CNTIN_CNTINIT_SHIFT)) & MFT_CNTIN_CNTINIT_MASK); + obj->CNTIN = tmp; +} + +/*! \brief Gets the Channel 7 Flag + * + * This function gets the current Channel 7 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 7 Flag + * - 0b : No channel event has occurred. + * - 1b : A channel event has occurred. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetStatusCh7F(const MftRegType *obj) +{ + return ((obj->STATUS & MFT_STATUS_CH7F_MASK) >> MFT_STATUS_CH7F_SHIFT); +} + +/*! \brief Sets the Channel 7 Flag + * + * This function sets the Channel 7 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 7 Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetStatusCh7F(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->STATUS; + + tmp &= ~MFT_STATUS_CH7F_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_STATUS_CH7F_SHIFT)) & MFT_STATUS_CH7F_MASK); + obj->STATUS = tmp; +} + +/*! \brief Gets the Channel 6 Flag + * + * This function gets the current Channel 6 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 6 Flag + * - 0b : No channel event has occurred. + * - 1b : A channel event has occurred. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetStatusCh6F(const MftRegType *obj) +{ + return ((obj->STATUS & MFT_STATUS_CH6F_MASK) >> MFT_STATUS_CH6F_SHIFT); +} + +/*! \brief Sets the Channel 6 Flag + * + * This function sets the Channel 6 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 6 Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetStatusCh6F(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->STATUS; + + tmp &= ~MFT_STATUS_CH6F_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_STATUS_CH6F_SHIFT)) & MFT_STATUS_CH6F_MASK); + obj->STATUS = tmp; +} + +/*! \brief Gets the Channel 5 Flag + * + * This function gets the current Channel 5 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 5 Flag + * - 0b : No channel event has occurred. + * - 1b : A channel event has occurred. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetStatusCh5F(const MftRegType *obj) +{ + return ((obj->STATUS & MFT_STATUS_CH5F_MASK) >> MFT_STATUS_CH5F_SHIFT); +} + +/*! \brief Sets the Channel 5 Flag + * + * This function sets the Channel 5 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 5 Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetStatusCh5F(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->STATUS; + + tmp &= ~MFT_STATUS_CH5F_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_STATUS_CH5F_SHIFT)) & MFT_STATUS_CH5F_MASK); + obj->STATUS = tmp; +} + +/*! \brief Gets the Channel 4 Flag + * + * This function gets the current Channel 4 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 4 Flag + * - 0b : No channel event has occurred. + * - 1b : A channel event has occurred. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetStatusCh4F(const MftRegType *obj) +{ + return ((obj->STATUS & MFT_STATUS_CH4F_MASK) >> MFT_STATUS_CH4F_SHIFT); +} + +/*! \brief Sets the Channel 4 Flag + * + * This function sets the Channel 4 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 4 Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetStatusCh4F(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->STATUS; + + tmp &= ~MFT_STATUS_CH4F_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_STATUS_CH4F_SHIFT)) & MFT_STATUS_CH4F_MASK); + obj->STATUS = tmp; +} + +/*! \brief Gets the Channel 3 Flag + * + * This function gets the current Channel 3 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 3 Flag + * - 0b : No channel event has occurred. + * - 1b : A channel event has occurred. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetStatusCh3F(const MftRegType *obj) +{ + return ((obj->STATUS & MFT_STATUS_CH3F_MASK) >> MFT_STATUS_CH3F_SHIFT); +} + +/*! \brief Sets the Channel 3 Flag + * + * This function sets the Channel 3 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 3 Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetStatusCh3F(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->STATUS; + + tmp &= ~MFT_STATUS_CH3F_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_STATUS_CH3F_SHIFT)) & MFT_STATUS_CH3F_MASK); + obj->STATUS = tmp; +} + +/*! \brief Gets the Channel 2 Flag + * + * This function gets the current Channel 2 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 2 Flag + * - 0b : No channel event has occurred. + * - 1b : A channel event has occurred. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetStatusCh2F(const MftRegType *obj) +{ + return ((obj->STATUS & MFT_STATUS_CH2F_MASK) >> MFT_STATUS_CH2F_SHIFT); +} + +/*! \brief Sets the Channel 2 Flag + * + * This function sets the Channel 2 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 2 Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetStatusCh2F(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->STATUS; + + tmp &= ~MFT_STATUS_CH2F_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_STATUS_CH2F_SHIFT)) & MFT_STATUS_CH2F_MASK); + obj->STATUS = tmp; +} + +/*! \brief Gets the Channel 1 Flag + * + * This function gets the current Channel 1 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 1 Flag + * - 0b : No channel event has occurred. + * - 1b : A channel event has occurred. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetStatusCh1F(const MftRegType *obj) +{ + return ((obj->STATUS & MFT_STATUS_CH1F_MASK) >> MFT_STATUS_CH1F_SHIFT); +} + +/*! \brief Sets the Channel 1 Flag + * + * This function sets the Channel 1 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 1 Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetStatusCh1F(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->STATUS; + + tmp &= ~MFT_STATUS_CH1F_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_STATUS_CH1F_SHIFT)) & MFT_STATUS_CH1F_MASK); + obj->STATUS = tmp; +} + +/*! \brief Gets the Channel 0 Flag + * + * This function gets the current Channel 0 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 0 Flag + * - 0b : No channel event has occurred. + * - 1b : A channel event has occurred. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetStatusCh0F(const MftRegType *obj) +{ + return ((obj->STATUS & MFT_STATUS_CH0F_MASK) >> MFT_STATUS_CH0F_SHIFT); +} + +/*! \brief Sets the Channel 0 Flag + * + * This function sets the Channel 0 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 0 Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetStatusCh0F(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->STATUS; + + tmp &= ~MFT_STATUS_CH0F_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_STATUS_CH0F_SHIFT)) & MFT_STATUS_CH0F_MASK); + obj->STATUS = tmp; +} + +/*! \brief Gets the Fault Interrupt Enable + * + * This function gets the current Fault Interrupt Enable. + * Enables the generation of an interrupt when a fault is detected by MFT and the MFT fault control is enabled. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Interrupt Enable + * - 0b : Fault control interrupt is disabled. + * - 1b : Fault control interrupt is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetModeFaultIE(const MftRegType *obj) +{ + return ((obj->MODE & MFT_MODE_FAULTIE_MASK) >> MFT_MODE_FAULTIE_SHIFT); +} + +/*! \brief Sets the Fault Interrupt Enable + * + * This function sets the Fault Interrupt Enable. + * Enables the generation of an interrupt when a fault is detected by MFT and the MFT fault control is enabled. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Interrupt Enable + * - 0b : Fault control interrupt is disabled. + * - 1b : Fault control interrupt is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetModeFaultIE(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MODE; + + tmp &= ~MFT_MODE_FAULTIE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_MODE_FAULTIE_SHIFT)) & MFT_MODE_FAULTIE_MASK); + obj->MODE = tmp; +} + +/*! \brief Gets the Fault Control Mode + * + * This function gets the current Fault Control Mode. + * Defines the MFT fault control mode. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Control Mode + * - 00b : Fault control is disabled for all channels. + * - 01b : Fault control is enabled for even channels only (channels 0, 2, 4, and 6), and the selected mode is the manual fault clearing. + * - 10b : Fault control is enabled for all channels, and the selected mode is the manual fault clearing. + * - 11b : Fault control is enabled for all channels, and the selected mode is the automatic fault clearing. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetModeFaultM(const MftRegType *obj) +{ + return ((obj->MODE & MFT_MODE_FAULTM_MASK) >> MFT_MODE_FAULTM_SHIFT); +} + +/*! \brief Sets the Fault Control Mode + * + * This function sets the Fault Control Mode. + * Defines the MFT fault control mode. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Control Mode + * - 00b : Fault control is disabled for all channels. + * - 01b : Fault control is enabled for even channels only (channels 0, 2, 4, and 6), and the selected mode is the manual fault clearing. + * - 10b : Fault control is enabled for all channels, and the selected mode is the manual fault clearing. + * - 11b : Fault control is enabled for all channels, and the selected mode is the automatic fault clearing. + */ +__attribute__((always_inline)) static inline void MftReg_SetModeFaultM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MODE; + + tmp &= ~MFT_MODE_FAULTM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_MODE_FAULTM_SHIFT)) & MFT_MODE_FAULTM_MASK); + obj->MODE = tmp; +} + +/*! \brief Gets the Capture Test Mode Enable + * + * This function gets the current Capture Test Mode Enable. + * Enables the capture test mode. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Capture Test Mode Enable + * - 0b : Capture test mode is disabled. + * - 1b : Capture test mode is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetModeCapTest(const MftRegType *obj) +{ + return ((obj->MODE & MFT_MODE_CAPTEST_MASK) >> MFT_MODE_CAPTEST_SHIFT); +} + +/*! \brief Sets the Capture Test Mode Enable + * + * This function sets the Capture Test Mode Enable. + * Enables the capture test mode. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Capture Test Mode Enable + * - 0b : Capture test mode is disabled. + * - 1b : Capture test mode is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetModeCapTest(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MODE; + + tmp &= ~MFT_MODE_CAPTEST_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_MODE_CAPTEST_SHIFT)) & MFT_MODE_CAPTEST_MASK); + obj->MODE = tmp; +} + +/*! \brief Gets the PWM Synchronization Mode + * + * This function gets the current PWM Synchronization Mode. + * Selects which triggers can be used by MOD, CnV, OUTMASK, and MFT counter synchronization. + * The PWMSYNC bit configures the synchronization when SYNCMODE is 0. + * + * \param[in] obj : pointer to MFT register instance + * \return PWM Synchronization Mode + * - 0b : No restrictions. Software and hardware triggers can be used by + * MOD, CnV, OUTMASK, and MFT counter synchronization. + * - 1b : Software trigger can only be used by MOD and CnV synchronization, + * and hardware triggers can only be used by OUTMASK and MFT counter synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetModePwmSync(const MftRegType *obj) +{ + return ((obj->MODE & MFT_MODE_PWMSYNC_MASK) >> MFT_MODE_PWMSYNC_SHIFT); +} + +/*! \brief Sets the PWM Synchronization Mode + * + * This function sets the PWM Synchronization Mode. + * Selects which triggers can be used by MOD, CnV, OUTMASK, and MFT counter synchronization. The PWMSYNC bit configures the synchronization + * when SYNCMODE is 0. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of PWM Synchronization Mode + * - 0b : No restrictions. Software and hardware triggers can be used by + * MOD, CnV, OUTMASK, and MFT counter synchronization. + * - 1b : Software trigger can only be used by MOD and CnV synchronization, + * and hardware triggers can only be used by OUTMASK and MFT counter synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetModePwmSync(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MODE; + + tmp &= ~MFT_MODE_PWMSYNC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_MODE_PWMSYNC_SHIFT)) & MFT_MODE_PWMSYNC_MASK); + obj->MODE = tmp; +} + +/*! \brief Gets the Write Protection Disable + * + * This function gets the current Write Protection Disable. + * When write protection is enabled (WPDIS = 0), write protected bits cannot be written. When write + * protection is disabled (WPDIS = 1), write protected bits can be written. The WPDIS bit is the negation of + * the WPEN bit. WPDIS is cleared when 1 is written to WPEN. WPDIS is set when WPEN bit is read as a 1 + * and then 1 is written to WPDIS. Writing 0 to WPDIS has no effect. + * + * \param[in] obj : pointer to MFT register instance + * \return Write Protection Disable + * - 0b : Write protection is enabled. + * - 1b : Write protection is disabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetModeWpDis(const MftRegType *obj) +{ + return ((obj->MODE & MFT_MODE_WPDIS_MASK) >> MFT_MODE_WPDIS_SHIFT); +} + +/*! \brief Sets the Write Protection Disable + * + * This function sets the Write Protection Disable. + * When write protection is enabled (WPDIS = 0), write protected bits cannot be written. When write + * protection is disabled (WPDIS = 1), write protected bits can be written. The WPDIS bit is the negation of + * the WPEN bit. WPDIS is cleared when 1 is written to WPEN. WPDIS is set when WPEN bit is read as a 1 + * and then 1 is written to WPDIS. Writing 0 to WPDIS has no effect. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Write Protection Disable + * - 0b : Write protection is enabled. + * - 1b : Write protection is disabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetModeWpDis(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MODE; + + tmp &= ~MFT_MODE_WPDIS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_MODE_WPDIS_SHIFT)) & MFT_MODE_WPDIS_MASK); + obj->MODE = tmp; +} + +/*! \brief Sets the Initialize The Channels Output + * + * This function sets the Initialize The Channels Output. + * When a 1 is written to INIT bit the channels output is initialized according to the state of their + * corresponding bit in the OUTINIT register. Writing a 0 to INIT bit has no effect. + * The INIT bit is always read as 0 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Initialize The Channels Output + */ +__attribute__((always_inline)) static inline void MftReg_SetModeInit(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MODE; + + tmp &= ~MFT_MODE_INIT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_MODE_INIT_SHIFT)) & MFT_MODE_INIT_MASK); + obj->MODE = tmp; +} + +/*! \brief Gets the MFT Enable + * + * This function gets the current MFT Enable. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return MFT Enable + * - 0b : TPM compatibility. Free running counter and synchronization compatible with TPM. + * - 1b : Free running counter and synchronization are different from TPM behavior. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetModeMftEn(const MftRegType *obj) +{ + return ((obj->MODE & MFT_MODE_MFTEN_MASK) >> MFT_MODE_MFTEN_SHIFT); +} + +/*! \brief Sets the MFT Enable + * + * This function sets the MFT Enable. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of MFT Enable + * - 0b : TPM compatibility. Free running counter and synchronization compatible with TPM. + * - 1b : Free running counter and synchronization are different from TPM behavior. + */ +__attribute__((always_inline)) static inline void MftReg_SetModeMftEn(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MODE; + + tmp &= ~MFT_MODE_MFTEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_MODE_MFTEN_SHIFT)) & MFT_MODE_MFTEN_MASK); + obj->MODE = tmp; +} + +/*! \brief Gets the PWM Synchronization Software Trigger + * + * This function gets the current PWM Synchronization Software Trigger. + * Selects the software trigger as the PWM synchronization trigger. + * The software trigger happens when a 1 is written to SWSYNC bit. + * + * \param[in] obj : pointer to MFT register instance + * \return PWM Synchronization Software Trigger + * - 0b : Software trigger is not selected. + * - 1b : Software trigger is selected. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSyncSwSync(const MftRegType *obj) +{ + return ((obj->SYNC & MFT_SYNC_SWSYNC_MASK) >> MFT_SYNC_SWSYNC_SHIFT); +} + +/*! \brief Sets the PWM Synchronization Software Trigger + * + * This function sets the PWM Synchronization Software Trigger. + * Selects the software trigger as the PWM synchronization trigger. + * The software trigger happens when a 1 is written to SWSYNC bit. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of PWM Synchronization Software Trigger + * - 0b : Software trigger is not selected. + * - 1b : Software trigger is selected. + */ +__attribute__((always_inline)) static inline void MftReg_SetSyncSwSync(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNC; + + tmp &= ~MFT_SYNC_SWSYNC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNC_SWSYNC_SHIFT)) & MFT_SYNC_SWSYNC_MASK); + obj->SYNC = tmp; +} + +/*! \brief Gets the PWM Synchronization Hardware Trigger 2 + * + * This function gets the current PWM Synchronization Hardware Trigger 2. + * Enables hardware trigger 2 to the PWM synchronization. + * Hardware trigger 2 happens when a rising edge is detected at the trigger 2 input signal. + * + * \param[in] obj : pointer to MFT register instance + * \return PWM Synchronization Hardware Trigger 2 + * - 0b : Trigger is disabled. + * - 1b : Trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSyncTrig2(const MftRegType *obj) +{ + return ((obj->SYNC & MFT_SYNC_TRIG2_MASK) >> MFT_SYNC_TRIG2_SHIFT); +} + +/*! \brief Sets the PWM Synchronization Hardware Trigger 2 + * + * This function sets the PWM Synchronization Hardware Trigger 2. + * Enables hardware trigger 2 to the PWM synchronization. + * Hardware trigger 2 happens when a rising edge is detected at the trigger 2 input signal. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of PWM Synchronization Hardware Trigger 2 + * - 0b : Trigger is disabled. + * - 1b : Trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetSyncTrig2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNC; + + tmp &= ~MFT_SYNC_TRIG2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNC_TRIG2_SHIFT)) & MFT_SYNC_TRIG2_MASK); + obj->SYNC = tmp; +} + +/*! \brief Gets the PWM Synchronization Hardware Trigger 1 + * + * This function gets the current PWM Synchronization Hardware Trigger 1. + * Enables hardware trigger 1 to the PWM synchronization. + * Hardware trigger 1 happens when a rising edge is detected at the trigger 1 input signal. + * + * \param[in] obj : pointer to MFT register instance + * \return PWM Synchronization Hardware Trigger 1 + * - 0b : Trigger is disabled. + * - 1b : Trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSyncTrig1(const MftRegType *obj) +{ + return ((obj->SYNC & MFT_SYNC_TRIG1_MASK) >> MFT_SYNC_TRIG1_SHIFT); +} + +/*! \brief Sets the PWM Synchronization Hardware Trigger 1 + * + * This function sets the PWM Synchronization Hardware Trigger 1. + * Enables hardware trigger 1 to the PWM synchronization. + * Hardware trigger 1 happens when a rising edge is detected at the trigger 1 input signal. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of PWM Synchronization Hardware Trigger 1 + * - 0b : Trigger is disabled. + * - 1b : Trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetSyncTrig1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNC; + + tmp &= ~MFT_SYNC_TRIG1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNC_TRIG1_SHIFT)) & MFT_SYNC_TRIG1_MASK); + obj->SYNC = tmp; +} + +/*! \brief Gets the PWM Synchronization Hardware Trigger 0 + * + * This function gets the current PWM Synchronization Hardware Trigger 0. + * Enables hardware trigger 0 to the PWM synchronization. + * Hardware trigger 0 occurs when a rising edge is detected at the trigger 0 input signal. + * + * \param[in] obj : pointer to MFT register instance + * \return PWM Synchronization Hardware Trigger 0 + * - 0b : Trigger is disabled. + * - 1b : Trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSyncTrig0(const MftRegType *obj) +{ + return ((obj->SYNC & MFT_SYNC_TRIG0_MASK) >> MFT_SYNC_TRIG0_SHIFT); +} + +/*! \brief Sets the PWM Synchronization Hardware Trigger 0 + * + * This function sets the PWM Synchronization Hardware Trigger 0. + * Enables hardware trigger 0 to the PWM synchronization. + * Hardware trigger 0 occurs when a rising edge is detected at the trigger 0 input signal. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of PWM Synchronization Hardware Trigger 0 + * - 0b : Trigger is disabled. + * - 1b : Trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetSyncTrig0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNC; + + tmp &= ~MFT_SYNC_TRIG0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNC_TRIG0_SHIFT)) & MFT_SYNC_TRIG0_MASK); + obj->SYNC = tmp; +} + +/*! \brief Gets the Output Mask Synchronization + * + * This function gets the current Output Mask Synchronization. + * Selects when the OUTMASK register is updated with the value of its buffer. + * + * \param[in] obj : pointer to MFT register instance + * \return Output Mask Synchronization + * - 0b : OUTMASK register is updated with the value of its buffer in all rising edges of the MFT input clock. + * - 1b : OUTMASK register is updated with the value of its buffer only by the PWM synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSyncSynchOM(const MftRegType *obj) +{ + return ((obj->SYNC & MFT_SYNC_SYNCHOM_MASK) >> MFT_SYNC_SYNCHOM_SHIFT); +} + +/*! \brief Sets the Output Mask Synchronization + * + * This function sets the Output Mask Synchronization. + * Selects when the OUTMASK register is updated with the value of its buffer. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Output Mask Synchronization + * - 0b : OUTMASK register is updated with the value of its buffer in all rising edges of the MFT input clock. + * - 1b : OUTMASK register is updated with the value of its buffer only by the PWM synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSyncSynchOM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNC; + + tmp &= ~MFT_SYNC_SYNCHOM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNC_SYNCHOM_SHIFT)) & MFT_SYNC_SYNCHOM_MASK); + obj->SYNC = tmp; +} + +/*! \brief Gets the MFT Counter Reinitialization by Synchronization + * + * This function gets the current MFT Counter Reinitialization by Synchronization. + * Determines if the MFT counter is reinitialized when the selected trigger for the synchronization is detected + * (MFT counter synchronization). The REINIT bit configures the synchronization when SYNCMODE is zero. + * + * \param[in] obj : pointer to MFT register instance + * \return MFT Counter Reinitialization by Synchronization + * - 0b : MFT counter continues to count normally. + * - 1b : MFT counter is updated with its initial value when the selected trigger is detected. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSyncReInit(const MftRegType *obj) +{ + return ((obj->SYNC & MFT_SYNC_REINIT_MASK) >> MFT_SYNC_REINIT_SHIFT); +} + +/*! \brief Sets the MFT Counter Reinitialization by Synchronization + * + * This function sets the MFT Counter Reinitialization by Synchronization. + * Determines if the MFT counter is reinitialized when the selected trigger for the synchronization is detected + * (MFT counter synchronization). The REINIT bit configures the synchronization when SYNCMODE is zero. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of MFT Counter Reinitialization by Synchronization + * - 0b : MFT counter continues to count normally. + * - 1b : MFT counter is updated with its initial value when the selected trigger is detected. + */ +__attribute__((always_inline)) static inline void MftReg_SetSyncReInit(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNC; + + tmp &= ~MFT_SYNC_REINIT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNC_REINIT_SHIFT)) & MFT_SYNC_REINIT_MASK); + obj->SYNC = tmp; +} + +/*! \brief Gets the Maximum Loading Point Enable + * + * This function gets the current Maximum Loading Point Enable. + * Selects the maximum loading point to PWM synchronization (Synchronization Points). + * If CNTMAX is 1, the selected loading point is when the MFT counter reaches its maximum value (MOD register). + * + * \param[in] obj : pointer to MFT register instance + * \return Maximum Loading Point Enable + * - 0b : The maximum loading point is disabled. + * - 1b : The maximum loading point is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSyncCntMax(const MftRegType *obj) +{ + return ((obj->SYNC & MFT_SYNC_CNTMAX_MASK) >> MFT_SYNC_CNTMAX_SHIFT); +} + +/*! \brief Sets the Maximum Loading Point Enable + * + * This function sets the Maximum Loading Point Enable. + * Selects the maximum loading point to PWM synchronization (Synchronization Points). + * If CNTMAX is 1, the selected loading point is when the MFT counter reaches its maximum value (MOD register). + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Maximum Loading Point Enable + * - 0b : The maximum loading point is disabled. + * - 1b : The maximum loading point is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetSyncCntMax(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNC; + + tmp &= ~MFT_SYNC_CNTMAX_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNC_CNTMAX_SHIFT)) & MFT_SYNC_CNTMAX_MASK); + obj->SYNC = tmp; +} + +/*! \brief Gets the Minimum Loading Point Enable + * + * This function gets the current Minimum Loading Point Enable. + * Selects the minimum loading point to PWM synchronization (Synchronization Points). + * If CNTMIN is 1, the selected loading point is when the MFT counter reaches its minimum value (CNTIN register). + * + * \param[in] obj : pointer to MFT register instance + * \return Minimum Loading Point Enable + * - 0b : The minimum loading point is disabled. + * - 1b : The minimum loading point is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSyncCntMin(const MftRegType *obj) +{ + return ((obj->SYNC & MFT_SYNC_CNTMIN_MASK) >> MFT_SYNC_CNTMIN_SHIFT); +} + +/*! \brief Sets the Minimum Loading Point Enable + * + * This function sets the Minimum Loading Point Enable. + * Selects the minimum loading point to PWM synchronization (Synchronization Points). + * If CNTMIN is 1, the selected loading point is when the MFT counter reaches its minimum value (CNTIN register). + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Minimum Loading Point Enable + * - 0b : The minimum loading point is disabled. + * - 1b : The minimum loading point is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetSyncCntMin(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNC; + + tmp &= ~MFT_SYNC_CNTMIN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNC_CNTMIN_SHIFT)) & MFT_SYNC_CNTMIN_MASK); + obj->SYNC = tmp; +} + +/*! \brief Gets the Channel 7 Output Initialization Value + * + * This function gets the current Channel 7 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 7 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutInitCh7OI(const MftRegType *obj) +{ + return ((obj->OUTINIT & MFT_OUTINIT_CH7OI_MASK) >> MFT_OUTINIT_CH7OI_SHIFT); +} + +/*! \brief Sets the Channel 7 Output Initialization Value + * + * This function sets the Channel 7 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 7 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutInitCh7OI(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTINIT; + + tmp &= ~MFT_OUTINIT_CH7OI_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTINIT_CH7OI_SHIFT)) & MFT_OUTINIT_CH7OI_MASK); + obj->OUTINIT = tmp; +} + +/*! \brief Gets the Channel 6 Output Initialization Value + * + * This function gets the current Channel 6 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 6 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutInitCh6OI(const MftRegType *obj) +{ + return ((obj->OUTINIT & MFT_OUTINIT_CH6OI_MASK) >> MFT_OUTINIT_CH6OI_SHIFT); +} + +/*! \brief Sets the Channel 6 Output Initialization Value + * + * This function sets the Channel 6 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 6 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutInitCh6OI(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTINIT; + + tmp &= ~MFT_OUTINIT_CH6OI_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTINIT_CH6OI_SHIFT)) & MFT_OUTINIT_CH6OI_MASK); + obj->OUTINIT = tmp; +} + +/*! \brief Gets the Channel 5 Output Initialization Value + * + * This function gets the current Channel 5 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 5 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutInitCh5OI(const MftRegType *obj) +{ + return ((obj->OUTINIT & MFT_OUTINIT_CH5OI_MASK) >> MFT_OUTINIT_CH5OI_SHIFT); +} + +/*! \brief Sets the Channel 5 Output Initialization Value + * + * This function sets the Channel 5 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 5 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutInitCh5OI(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTINIT; + + tmp &= ~MFT_OUTINIT_CH5OI_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTINIT_CH5OI_SHIFT)) & MFT_OUTINIT_CH5OI_MASK); + obj->OUTINIT = tmp; +} + +/*! \brief Gets the Channel 4 Output Initialization Value + * + * This function gets the current Channel 4 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 4 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutInitCh4OI(const MftRegType *obj) +{ + return ((obj->OUTINIT & MFT_OUTINIT_CH4OI_MASK) >> MFT_OUTINIT_CH4OI_SHIFT); +} + +/*! \brief Sets the Channel 4 Output Initialization Value + * + * This function sets the Channel 4 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 4 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutInitCh4OI(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTINIT; + + tmp &= ~MFT_OUTINIT_CH4OI_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTINIT_CH4OI_SHIFT)) & MFT_OUTINIT_CH4OI_MASK); + obj->OUTINIT = tmp; +} + +/*! \brief Gets the Channel 3 Output Initialization Value + * + * This function gets the current Channel 3 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 3 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutInitCh3OI(const MftRegType *obj) +{ + return ((obj->OUTINIT & MFT_OUTINIT_CH3OI_MASK) >> MFT_OUTINIT_CH3OI_SHIFT); +} + +/*! \brief Sets the Channel 3 Output Initialization Value + * + * This function sets the Channel 3 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 3 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutInitCh3OI(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTINIT; + + tmp &= ~MFT_OUTINIT_CH3OI_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTINIT_CH3OI_SHIFT)) & MFT_OUTINIT_CH3OI_MASK); + obj->OUTINIT = tmp; +} + +/*! \brief Gets the Channel 2 Output Initialization Value + * + * This function gets the current Channel 2 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 2 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutInitCh2OI(const MftRegType *obj) +{ + return ((obj->OUTINIT & MFT_OUTINIT_CH2OI_MASK) >> MFT_OUTINIT_CH2OI_SHIFT); +} + +/*! \brief Sets the Channel 2 Output Initialization Value + * + * This function sets the Channel 2 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 2 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutInitCh2OI(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTINIT; + + tmp &= ~MFT_OUTINIT_CH2OI_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTINIT_CH2OI_SHIFT)) & MFT_OUTINIT_CH2OI_MASK); + obj->OUTINIT = tmp; +} + +/*! \brief Gets the Channel 1 Output Initialization Value + * + * This function gets the current Channel 1 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 1 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutInitCh1OI(const MftRegType *obj) +{ + return ((obj->OUTINIT & MFT_OUTINIT_CH1OI_MASK) >> MFT_OUTINIT_CH1OI_SHIFT); +} + +/*! \brief Sets the Channel 1 Output Initialization Value + * + * This function sets the Channel 1 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 1 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutInitCh1OI(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTINIT; + + tmp &= ~MFT_OUTINIT_CH1OI_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTINIT_CH1OI_SHIFT)) & MFT_OUTINIT_CH1OI_MASK); + obj->OUTINIT = tmp; +} + +/*! \brief Gets the Channel 0 Output Initialization Value + * + * This function gets the current Channel 0 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 0 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutInitCh0OI(const MftRegType *obj) +{ + return ((obj->OUTINIT & MFT_OUTINIT_CH0OI_MASK) >> MFT_OUTINIT_CH0OI_SHIFT); +} + +/*! \brief Sets the Channel 0 Output Initialization Value + * + * This function sets the Channel 0 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 0 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutInitCh0OI(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTINIT; + + tmp &= ~MFT_OUTINIT_CH0OI_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTINIT_CH0OI_SHIFT)) & MFT_OUTINIT_CH0OI_MASK); + obj->OUTINIT = tmp; +} + +/*! \brief Gets the Channel 7 Output Mask + * + * This function gets the current Channel 7 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 7 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutMaskCh7OM(const MftRegType *obj) +{ + return ((obj->OUTMASK & MFT_OUTMASK_CH7OM_MASK) >> MFT_OUTMASK_CH7OM_SHIFT); +} + +/*! \brief Sets the Channel 7 Output Mask + * + * This function sets the Channel 7 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 7 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutMaskCh7OM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTMASK; + + tmp &= ~MFT_OUTMASK_CH7OM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTMASK_CH7OM_SHIFT)) & MFT_OUTMASK_CH7OM_MASK); + obj->OUTMASK = tmp; +} + +/*! \brief Gets the Channel 6 Output Mask + * + * This function gets the current Channel 6 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 6 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutMaskCh6OM(const MftRegType *obj) +{ + return ((obj->OUTMASK & MFT_OUTMASK_CH6OM_MASK) >> MFT_OUTMASK_CH6OM_SHIFT); +} + +/*! \brief Sets the Channel 6 Output Mask + * + * This function sets the Channel 6 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 6 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutMaskCh6OM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTMASK; + + tmp &= ~MFT_OUTMASK_CH6OM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTMASK_CH6OM_SHIFT)) & MFT_OUTMASK_CH6OM_MASK); + obj->OUTMASK = tmp; +} + +/*! \brief Gets the Channel 5 Output Mask + * + * This function gets the current Channel 5 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 5 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutMaskCh5OM(const MftRegType *obj) +{ + return ((obj->OUTMASK & MFT_OUTMASK_CH5OM_MASK) >> MFT_OUTMASK_CH5OM_SHIFT); +} + +/*! \brief Sets the Channel 5 Output Mask + * + * This function sets the Channel 5 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 5 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutMaskCh5OM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTMASK; + + tmp &= ~MFT_OUTMASK_CH5OM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTMASK_CH5OM_SHIFT)) & MFT_OUTMASK_CH5OM_MASK); + obj->OUTMASK = tmp; +} + +/*! \brief Gets the Channel 4 Output Mask + * + * This function gets the current Channel 4 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 4 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutMaskCh4OM(const MftRegType *obj) +{ + return ((obj->OUTMASK & MFT_OUTMASK_CH4OM_MASK) >> MFT_OUTMASK_CH4OM_SHIFT); +} + +/*! \brief Sets the Channel 4 Output Mask + * + * This function sets the Channel 4 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 4 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutMaskCh4OM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTMASK; + + tmp &= ~MFT_OUTMASK_CH4OM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTMASK_CH4OM_SHIFT)) & MFT_OUTMASK_CH4OM_MASK); + obj->OUTMASK = tmp; +} + +/*! \brief Gets the Channel 3 Output Mask + * + * This function gets the current Channel 3 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 3 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutMaskCh3OM(const MftRegType *obj) +{ + return ((obj->OUTMASK & MFT_OUTMASK_CH3OM_MASK) >> MFT_OUTMASK_CH3OM_SHIFT); +} + +/*! \brief Sets the Channel 3 Output Mask + * + * This function sets the Channel 3 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 3 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutMaskCh3OM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTMASK; + + tmp &= ~MFT_OUTMASK_CH3OM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTMASK_CH3OM_SHIFT)) & MFT_OUTMASK_CH3OM_MASK); + obj->OUTMASK = tmp; +} + +/*! \brief Gets the Channel 2 Output Mask + * + * This function gets the current Channel 2 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 2 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutMaskCh2OM(const MftRegType *obj) +{ + return ((obj->OUTMASK & MFT_OUTMASK_CH2OM_MASK) >> MFT_OUTMASK_CH2OM_SHIFT); +} + +/*! \brief Sets the Channel 2 Output Mask + * + * This function sets the Channel 2 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 2 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutMaskCh2OM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTMASK; + + tmp &= ~MFT_OUTMASK_CH2OM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTMASK_CH2OM_SHIFT)) & MFT_OUTMASK_CH2OM_MASK); + obj->OUTMASK = tmp; +} + +/*! \brief Gets the Channel 1 Output Mask + * + * This function gets the current Channel 1 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 1 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutMaskCh1OM(const MftRegType *obj) +{ + return ((obj->OUTMASK & MFT_OUTMASK_CH1OM_MASK) >> MFT_OUTMASK_CH1OM_SHIFT); +} + +/*! \brief Sets the Channel 1 Output Mask + * + * This function sets the Channel 1 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 1 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutMaskCh1OM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTMASK; + + tmp &= ~MFT_OUTMASK_CH1OM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTMASK_CH1OM_SHIFT)) & MFT_OUTMASK_CH1OM_MASK); + obj->OUTMASK = tmp; +} + +/*! \brief Gets the Channel 0 Output Mask + * + * This function gets the current Channel 0 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 0 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutMaskCh0OM(const MftRegType *obj) +{ + return ((obj->OUTMASK & MFT_OUTMASK_CH0OM_MASK) >> MFT_OUTMASK_CH0OM_SHIFT); +} + +/*! \brief Sets the Channel 0 Output Mask + * + * This function sets the Channel 0 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 0 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutMaskCh0OM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTMASK; + + tmp &= ~MFT_OUTMASK_CH0OM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTMASK_CH0OM_SHIFT)) & MFT_OUTMASK_CH0OM_MASK); + obj->OUTMASK = tmp; +} + +/*! \brief Gets the Modified Combine Mode For n = 6 + * + * This function gets the current Modified Combine Mode For n = 6. + * Used on the selection of the modified combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Modified Combine Mode For n = 6 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineMCombine3(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_MCOMBINE3_MASK) >> MFT_COMBINE_MCOMBINE3_SHIFT); +} + +/*! \brief Sets the Modified Combine Mode For n = 6 + * + * This function sets the Modified Combine Mode For n = 6. + * Used on the selection of the modified combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Modified Combine Mode For n = 6 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineMCombine3(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_MCOMBINE3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_MCOMBINE3_SHIFT)) & MFT_COMBINE_MCOMBINE3_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Fault Control Enable For n = 6 + * + * This function gets the current Fault Control Enable For n = 6. + * Enables the fault control in channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Control Enable For n = 6 + * - 0b : The fault control in this pair of channels is disabled. + * - 1b : The fault control in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineFaultEn3(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_FAULTEN3_MASK) >> MFT_COMBINE_FAULTEN3_SHIFT); +} + +/*! \brief Sets the Fault Control Enable For n = 6 + * + * This function sets the Fault Control Enable For n = 6. + * Enables the fault control in channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Control Enable For n = 6 + * - 0b : The fault control in this pair of channels is disabled. + * - 1b : The fault control in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineFaultEn3(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_FAULTEN3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_FAULTEN3_SHIFT)) & MFT_COMBINE_FAULTEN3_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Synchronization Enable For n = 6 + * + * This function gets the current Synchronization Enable For n = 6. + * Enables PWM synchronization of registers C(n)V and C(n+1)V. + * + * \param[in] obj : pointer to MFT register instance + * \return Synchronization Enable For n = 6 + * - 0b : The PWM synchronization in this pair of channels is disabled. + * - 1b : The PWM synchronization in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineSyncEn3(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_SYNCEN3_MASK) >> MFT_COMBINE_SYNCEN3_SHIFT); +} + +/*! \brief Sets the Synchronization Enable For n = 6 + * + * This function sets the Synchronization Enable For n = 6. + * Enables PWM synchronization of registers C(n)V and C(n+1)V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Synchronization Enable For n = 6 + * - 0b : The PWM synchronization in this pair of channels is disabled. + * - 1b : The PWM synchronization in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineSyncEn3(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_SYNCEN3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_SYNCEN3_SHIFT)) & MFT_COMBINE_SYNCEN3_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Deadtime Enable For n = 6 + * + * This function gets the current Deadtime Enable For n = 6. + * Enables the deadtime insertion in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Deadtime Enable For n = 6 + * - 0b : The deadtime insertion in this pair of channels is disabled. + * - 1b : The deadtime insertion in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDtEn3(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DTEN3_MASK) >> MFT_COMBINE_DTEN3_SHIFT); +} + +/*! \brief Sets the Deadtime Enable For n = 6 + * + * This function sets the Deadtime Enable For n = 6. + * Enables the deadtime insertion in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Deadtime Enable For n = 6 + * - 0b : The deadtime insertion in this pair of channels is disabled. + * - 1b : The deadtime insertion in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDtEn3(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DTEN3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DTEN3_SHIFT)) & MFT_COMBINE_DTEN3_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Dual Edge Capture Mode Captures For n = 6 + * + * This function gets the current Dual Edge Capture Mode Captures For n = 6. + * Enables the capture of the MFT counter value according to the channel (n) input event and the + * configuration of the dual edge capture bits. + * This field applies only when DECAPEN = 1. + * DECAP bit is cleared automatically by hardware if dual edge capture ¨C one-shot mode is selected and + * when the capture of channel (n+1) event is made. + * + * \param[in] obj : pointer to MFT register instance + * \return Dual Edge Capture Mode Captures For n = 6 + * - 0b : The dual edge captures are inactive. + * - 1b : The dual edge captures are active. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDecap3(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DECAP3_MASK) >> MFT_COMBINE_DECAP3_SHIFT); +} + +/*! \brief Sets the Dual Edge Capture Mode Captures For n = 6 + * + * This function sets the Dual Edge Capture Mode Captures For n = 6. + * Enables the capture of the MFT counter value according to the channel (n) input event and the + * configuration of the dual edge capture bits. + * This field applies only when DECAPEN = 1. + * DECAP bit is cleared automatically by hardware if dual edge capture ¨C one-shot mode is selected and + * when the capture of channel (n+1) event is made. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Dual Edge Capture Mode Captures For n = 6 + * - 0b : The dual edge captures are inactive. + * - 1b : The dual edge captures are active. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDecap3(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DECAP3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DECAP3_SHIFT)) & MFT_COMBINE_DECAP3_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Dual Edge Capture Mode Enable For n = 6 + * + * This function gets the current Dual Edge Capture Mode Enable For n = 6. + * Enables the Dual Edge Capture mode in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Dual Edge Capture Mode Enable For n = 6 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDecapEn3(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DECAPEN3_MASK) >> MFT_COMBINE_DECAPEN3_SHIFT); +} + +/*! \brief Sets the Dual Edge Capture Mode Enable For n = 6 + * + * This function sets the Dual Edge Capture Mode Enable For n = 6. + * Enables the Dual Edge Capture mode in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Dual Edge Capture Mode Enable For n = 6 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDecapEn3(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DECAPEN3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DECAPEN3_SHIFT)) & MFT_COMBINE_DECAPEN3_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Complement Of Channel (n) for n = 6 + * + * This function gets the current Complement Of Channel (n) for n = 6. + * In Complementary mode the channel (n+1) output is the inverse of the channel (n) output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Complement Of Channel (n) for n = 6 + * - 0b : If the channels (n) and (n+1) are in Combine Mode or Modified Combine PWM Mode, + * the channel (n+1) output is the same as the channel (n) output. + * If the channel (n+1) is in Output Compare Mode, EPWM or CPWM, + * the channel (n+1) output is independent from channel (n) output. + * - 1b : The channel (n+1) output is the complement of the channel (n) output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineComp3(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_COMP3_MASK) >> MFT_COMBINE_COMP3_SHIFT); +} + +/*! \brief Sets the Complement Of Channel (n) for n = 6 + * + * This function sets the Complement Of Channel (n) for n = 6. + * In Complementary mode the channel (n+1) output is the inverse of the channel (n) output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Complement Of Channel (n) for n = 6 + * - 0b : If the channels (n) and (n+1) are in Combine Mode or Modified Combine PWM Mode, + * the channel (n+1) output is the same as the channel (n) output. + * If the channel (n+1) is in Output Compare Mode, EPWM or CPWM, + * the channel (n+1) output is independent from channel (n) output. + * - 1b : The channel (n+1) output is the complement of the channel (n) output. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineComp3(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_COMP3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_COMP3_SHIFT)) & MFT_COMBINE_COMP3_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Combine Channels For n = 6 + * + * This function gets the current Combine Channels For n = 6. + * Used on the selection of the combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Combine Channels For n = 6 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineCombine3(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_COMBINE3_MASK) >> MFT_COMBINE_COMBINE3_SHIFT); +} + +/*! \brief Sets the Combine Channels For n = 6 + * + * This function sets the Combine Channels For n = 6. + * Used on the selection of the combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Combine Channels For n = 6 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineCombine3(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_COMBINE3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_COMBINE3_SHIFT)) & MFT_COMBINE_COMBINE3_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Modified Combine Mode For n = 4 + * + * This function gets the current Modified Combine Mode For n = 4. + * Used on the selection of the modified combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Modified Combine Mode For n = 4 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineMCombine2(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_MCOMBINE2_MASK) >> MFT_COMBINE_MCOMBINE2_SHIFT); +} + +/*! \brief Sets the Modified Combine Mode For n = 4 + * + * This function sets the Modified Combine Mode For n = 4. + * Used on the selection of the modified combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Modified Combine Mode For n = 4 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineMCombine2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_MCOMBINE2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_MCOMBINE2_SHIFT)) & MFT_COMBINE_MCOMBINE2_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Fault Control Enable For n = 4 + * + * This function gets the current Fault Control Enable For n = 4. + * Enables the fault control in channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Control Enable For n = 4 + * - 0b : The fault control in this pair of channels is disabled. + * - 1b : The fault control in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineFaultEn2(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_FAULTEN2_MASK) >> MFT_COMBINE_FAULTEN2_SHIFT); +} + +/*! \brief Sets the Fault Control Enable For n = 4 + * + * This function sets the Fault Control Enable For n = 4. + * Enables the fault control in channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Control Enable For n = 4 + * - 0b : The fault control in this pair of channels is disabled. + * - 1b : The fault control in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineFaultEn2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_FAULTEN2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_FAULTEN2_SHIFT)) & MFT_COMBINE_FAULTEN2_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Synchronization Enable For n = 4 + * + * This function gets the current Synchronization Enable For n = 4. + * Enables PWM synchronization of registers C(n)V and C(n+1)V. + * + * \param[in] obj : pointer to MFT register instance + * \return Synchronization Enable For n = 4 + * - 0b : The PWM synchronization in this pair of channels is disabled. + * - 1b : The PWM synchronization in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineSyncEn2(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_SYNCEN2_MASK) >> MFT_COMBINE_SYNCEN2_SHIFT); +} + +/*! \brief Sets the Synchronization Enable For n = 4 + * + * This function sets the Synchronization Enable For n = 4. + * Enables PWM synchronization of registers C(n)V and C(n+1)V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Synchronization Enable For n = 4 + * - 0b : The PWM synchronization in this pair of channels is disabled. + * - 1b : The PWM synchronization in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineSyncEn2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_SYNCEN2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_SYNCEN2_SHIFT)) & MFT_COMBINE_SYNCEN2_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Deadtime Enable For n = 4 + * + * This function gets the current Deadtime Enable For n = 4. + * Enables the deadtime insertion in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Deadtime Enable For n = 4 + * - 0b : The deadtime insertion in this pair of channels is disabled. + * - 1b : The deadtime insertion in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDtEn2(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DTEN2_MASK) >> MFT_COMBINE_DTEN2_SHIFT); +} + +/*! \brief Sets the Deadtime Enable For n = 4 + * + * This function sets the Deadtime Enable For n = 4. + * Enables the deadtime insertion in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Deadtime Enable For n = 4 + * - 0b : The deadtime insertion in this pair of channels is disabled. + * - 1b : The deadtime insertion in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDtEn2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DTEN2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DTEN2_SHIFT)) & MFT_COMBINE_DTEN2_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Dual Edge Capture Mode Captures For n = 4 + * + * This function gets the current Dual Edge Capture Mode Captures For n = 4. + * Enables the capture of the MFT counter value according to the channel (n) input event and the + * configuration of the dual edge capture bits. + * This field applies only when DECAPEN = 1. + * DECAP bit is cleared automatically by hardware if dual edge capture ¨C one-shot mode is selected and + * when the capture of channel (n+1) event is made. + * + * \param[in] obj : pointer to MFT register instance + * \return Dual Edge Capture Mode Captures For n = 4 + * - 0b : The dual edge captures are inactive. + * - 1b : The dual edge captures are active. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDecap2(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DECAP2_MASK) >> MFT_COMBINE_DECAP2_SHIFT); +} + +/*! \brief Sets the Dual Edge Capture Mode Captures For n = 4 + * + * This function sets the Dual Edge Capture Mode Captures For n = 4. + * Enables the capture of the MFT counter value according to the channel (n) input event and the + * configuration of the dual edge capture bits. + * This field applies only when DECAPEN = 1. + * DECAP bit is cleared automatically by hardware if dual edge capture ¨C one-shot mode is selected and + * when the capture of channel (n+1) event is made. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Dual Edge Capture Mode Captures For n = 4 + * - 0b : The dual edge captures are inactive. + * - 1b : The dual edge captures are active. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDecap2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DECAP2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DECAP2_SHIFT)) & MFT_COMBINE_DECAP2_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Dual Edge Capture Mode Enable For n = 4 + * + * This function gets the current Dual Edge Capture Mode Enable For n = 4. + * Enables the Dual Edge Capture mode in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Dual Edge Capture Mode Enable For n = 4 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDecapEn2(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DECAPEN2_MASK) >> MFT_COMBINE_DECAPEN2_SHIFT); +} + +/*! \brief Sets the Dual Edge Capture Mode Enable For n = 4 + * + * This function sets the Dual Edge Capture Mode Enable For n = 4. + * Enables the Dual Edge Capture mode in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Dual Edge Capture Mode Enable For n = 4 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDecapEn2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DECAPEN2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DECAPEN2_SHIFT)) & MFT_COMBINE_DECAPEN2_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Complement Of Channel (n) for n = 4 + * + * This function gets the current Complement Of Channel (n) for n = 4. + * In Complementary mode the channel (n+1) output is the inverse of the channel (n) output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Complement Of Channel (n) for n = 4 + * - 0b : If the channels (n) and (n+1) are in Combine Mode or Modified Combine PWM Mode, + * the channel (n+1) output is the same as the channel (n) output. + * If the channel (n+1) is in Output Compare Mode, EPWM or CPWM, + * the channel (n+1) output is independent from channel (n) output. + * - 1b : The channel (n+1) output is the complement of the channel (n) output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineComp2(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_COMP2_MASK) >> MFT_COMBINE_COMP2_SHIFT); +} + +/*! \brief Sets the Complement Of Channel (n) for n = 4 + * + * This function sets the Complement Of Channel (n) for n = 4. + * In Complementary mode the channel (n+1) output is the inverse of the channel (n) output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Complement Of Channel (n) for n = 4 + * - 0b : If the channels (n) and (n+1) are in Combine Mode or Modified Combine PWM Mode, + * the channel (n+1) output is the same as the channel (n) output. + * If the channel (n+1) is in Output Compare Mode, EPWM or CPWM, + * the channel (n+1) output is independent from channel (n) output. + * - 1b : The channel (n+1) output is the complement of the channel (n) output. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineComp2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_COMP2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_COMP2_SHIFT)) & MFT_COMBINE_COMP2_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Combine Channels For n = 4 + * + * This function gets the current Combine Channels For n = 4. + * Used on the selection of the combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Combine Channels For n = 4 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineCombine2(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_COMBINE2_MASK) >> MFT_COMBINE_COMBINE2_SHIFT); +} + +/*! \brief Sets the Combine Channels For n = 4 + * + * This function sets the Combine Channels For n = 4. + * Used on the selection of the combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Combine Channels For n = 4 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineCombine2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_COMBINE2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_COMBINE2_SHIFT)) & MFT_COMBINE_COMBINE2_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Modified Combine Mode For n = 2 + * + * This function gets the current Modified Combine Mode For n = 2. + * Used on the selection of the modified combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Modified Combine Mode For n = 2 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineMCombine1(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_MCOMBINE1_MASK) >> MFT_COMBINE_MCOMBINE1_SHIFT); +} + +/*! \brief Sets the Modified Combine Mode For n = 2 + * + * This function sets the Modified Combine Mode For n = 2. + * Used on the selection of the modified combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Modified Combine Mode For n = 2 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineMCombine1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_MCOMBINE1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_MCOMBINE1_SHIFT)) & MFT_COMBINE_MCOMBINE1_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Fault Control Enable For n = 2 + * + * This function gets the current Fault Control Enable For n = 2. + * Enables the fault control in channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Control Enable For n = 2 + * - 0b : The fault control in this pair of channels is disabled. + * - 1b : The fault control in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineFaultEn1(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_FAULTEN1_MASK) >> MFT_COMBINE_FAULTEN1_SHIFT); +} + +/*! \brief Sets the Fault Control Enable For n = 2 + * + * This function sets the Fault Control Enable For n = 2. + * Enables the fault control in channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Control Enable For n = 2 + * - 0b : The fault control in this pair of channels is disabled. + * - 1b : The fault control in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineFaultEn1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_FAULTEN1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_FAULTEN1_SHIFT)) & MFT_COMBINE_FAULTEN1_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Synchronization Enable For n = 2 + * + * This function gets the current Synchronization Enable For n = 2. + * Enables PWM synchronization of registers C(n)V and C(n+1)V. + * + * \param[in] obj : pointer to MFT register instance + * \return Synchronization Enable For n = 2 + * - 0b : The PWM synchronization in this pair of channels is disabled. + * - 1b : The PWM synchronization in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineSyncEn1(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_SYNCEN1_MASK) >> MFT_COMBINE_SYNCEN1_SHIFT); +} + +/*! \brief Sets the Synchronization Enable For n = 2 + * + * This function sets the Synchronization Enable For n = 2. + * Enables PWM synchronization of registers C(n)V and C(n+1)V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Synchronization Enable For n = 2 + * - 0b : The PWM synchronization in this pair of channels is disabled. + * - 1b : The PWM synchronization in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineSyncEn1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_SYNCEN1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_SYNCEN1_SHIFT)) & MFT_COMBINE_SYNCEN1_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Deadtime Enable For n = 2 + * + * This function gets the current Deadtime Enable For n = 2. + * Enables the deadtime insertion in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Deadtime Enable For n = 2 + * - 0b : The deadtime insertion in this pair of channels is disabled. + * - 1b : The deadtime insertion in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDtEn1(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DTEN1_MASK) >> MFT_COMBINE_DTEN1_SHIFT); +} + +/*! \brief Sets the Deadtime Enable For n = 2 + * + * This function sets the Deadtime Enable For n = 2. + * Enables the deadtime insertion in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Deadtime Enable For n = 2 + * - 0b : The deadtime insertion in this pair of channels is disabled. + * - 1b : The deadtime insertion in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDtEn1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DTEN1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DTEN1_SHIFT)) & MFT_COMBINE_DTEN1_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Dual Edge Capture Mode Captures For n = 2 + * + * This function gets the current Dual Edge Capture Mode Captures For n = 2. + * Enables the capture of the MFT counter value according to the channel (n) input event and the + * configuration of the dual edge capture bits. + * This field applies only when DECAPEN = 1. + * DECAP bit is cleared automatically by hardware if dual edge capture ¨C one-shot mode is selected and + * when the capture of channel (n+1) event is made. + * + * \param[in] obj : pointer to MFT register instance + * \return Dual Edge Capture Mode Captures For n = 2 + * - 0b : The dual edge captures are inactive. + * - 1b : The dual edge captures are active. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDecap1(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DECAP1_MASK) >> MFT_COMBINE_DECAP1_SHIFT); +} + +/*! \brief Sets the Dual Edge Capture Mode Captures For n = 2 + * + * This function sets the Dual Edge Capture Mode Captures For n = 2. + * Enables the capture of the MFT counter value according to the channel (n) input event and the + * configuration of the dual edge capture bits. + * This field applies only when DECAPEN = 1. + * DECAP bit is cleared automatically by hardware if dual edge capture ¨C one-shot mode is selected and + * when the capture of channel (n+1) event is made. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Dual Edge Capture Mode Captures For n = 2 + * - 0b : The dual edge captures are inactive. + * - 1b : The dual edge captures are active. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDecap1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DECAP1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DECAP1_SHIFT)) & MFT_COMBINE_DECAP1_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Dual Edge Capture Mode Enable For n = 2 + * + * This function gets the current Dual Edge Capture Mode Enable For n = 2. + * Enables the Dual Edge Capture mode in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Dual Edge Capture Mode Enable For n = 2 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDecapEn1(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DECAPEN1_MASK) >> MFT_COMBINE_DECAPEN1_SHIFT); +} + +/*! \brief Sets the Dual Edge Capture Mode Enable For n = 2 + * + * This function sets the Dual Edge Capture Mode Enable For n = 2. + * Enables the Dual Edge Capture mode in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Dual Edge Capture Mode Enable For n = 2 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDecapEn1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DECAPEN1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DECAPEN1_SHIFT)) & MFT_COMBINE_DECAPEN1_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Complement Of Channel (n) for n = 2 + * + * This function gets the current Complement Of Channel (n) for n = 2. + * In Complementary mode the channel (n+1) output is the inverse of the channel (n) output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Complement Of Channel (n) for n = 2 + * - 0b : If the channels (n) and (n+1) are in Combine Mode or Modified Combine PWM Mode, + * the channel (n+1) output is the same as the channel (n) output. + * If the channel (n+1) is in Output Compare Mode, EPWM or CPWM, + * the channel (n+1) output is independent from channel (n) output. + * - 1b : The channel (n+1) output is the complement of the channel (n) output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineComp1(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_COMP1_MASK) >> MFT_COMBINE_COMP1_SHIFT); +} + +/*! \brief Sets the Complement Of Channel (n) for n = 2 + * + * This function sets the Complement Of Channel (n) for n = 2. + * In Complementary mode the channel (n+1) output is the inverse of the channel (n) output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Complement Of Channel (n) for n = 2 + * - 0b : If the channels (n) and (n+1) are in Combine Mode or Modified Combine PWM Mode, + * the channel (n+1) output is the same as the channel (n) output. + * If the channel (n+1) is in Output Compare Mode, EPWM or CPWM, + * the channel (n+1) output is independent from channel (n) output. + * - 1b : The channel (n+1) output is the complement of the channel (n) output. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineComp1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_COMP1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_COMP1_SHIFT)) & MFT_COMBINE_COMP1_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Combine Channels For n = 2 + * + * This function gets the current Combine Channels For n = 2. + * Used on the selection of the combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Combine Channels For n = 2 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineCombine1(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_COMBINE1_MASK) >> MFT_COMBINE_COMBINE1_SHIFT); +} + +/*! \brief Sets the Combine Channels For n = 2 + * + * This function sets the Combine Channels For n = 2. + * Used on the selection of the combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Combine Channels For n = 2 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineCombine1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_COMBINE1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_COMBINE1_SHIFT)) & MFT_COMBINE_COMBINE1_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Modified Combine Mode For n = 0 + * + * This function gets the current Modified Combine Mode For n = 0. + * Used on the selection of the modified combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Modified Combine Mode For n = 0 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineMCombine0(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_MCOMBINE0_MASK) >> MFT_COMBINE_MCOMBINE0_SHIFT); +} + +/*! \brief Sets the Modified Combine Mode For n = 0 + * + * This function sets the Modified Combine Mode For n = 0. + * Used on the selection of the modified combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Modified Combine Mode For n = 0 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineMCombine0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_MCOMBINE0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_MCOMBINE0_SHIFT)) & MFT_COMBINE_MCOMBINE0_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Fault Control Enable For n = 0 + * + * This function gets the current Fault Control Enable For n = 0. + * Enables the fault control in channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Control Enable For n = 0 + * - 0b : The fault control in this pair of channels is disabled. + * - 1b : The fault control in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineFaultEn0(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_FAULTEN0_MASK) >> MFT_COMBINE_FAULTEN0_SHIFT); +} + +/*! \brief Sets the Fault Control Enable For n = 0 + * + * This function sets the Fault Control Enable For n = 0. + * Enables the fault control in channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Control Enable For n = 0 + * - 0b : The fault control in this pair of channels is disabled. + * - 1b : The fault control in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineFaultEn0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_FAULTEN0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_FAULTEN0_SHIFT)) & MFT_COMBINE_FAULTEN0_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Synchronization Enable For n = 0 + * + * This function gets the current Synchronization Enable For n = 0. + * Enables PWM synchronization of registers C(n)V and C(n+1)V. + * + * \param[in] obj : pointer to MFT register instance + * \return Synchronization Enable For n = 0 + * - 0b : The PWM synchronization in this pair of channels is disabled. + * - 1b : The PWM synchronization in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineSyncEn0(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_SYNCEN0_MASK) >> MFT_COMBINE_SYNCEN0_SHIFT); +} + +/*! \brief Sets the Synchronization Enable For n = 0 + * + * This function sets the Synchronization Enable For n = 0. + * Enables PWM synchronization of registers C(n)V and C(n+1)V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Synchronization Enable For n = 0 + * - 0b : The PWM synchronization in this pair of channels is disabled. + * - 1b : The PWM synchronization in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineSyncEn0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_SYNCEN0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_SYNCEN0_SHIFT)) & MFT_COMBINE_SYNCEN0_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Deadtime Enable For n = 0 + * + * This function gets the current Deadtime Enable For n = 0. + * Enables the deadtime insertion in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Deadtime Enable For n = 0 + * - 0b : The deadtime insertion in this pair of channels is disabled. + * - 1b : The deadtime insertion in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDtEn0(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DTEN0_MASK) >> MFT_COMBINE_DTEN0_SHIFT); +} + +/*! \brief Sets the Deadtime Enable For n = 0 + * + * This function sets the Deadtime Enable For n = 0. + * Enables the deadtime insertion in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Deadtime Enable For n = 0 + * - 0b : The deadtime insertion in this pair of channels is disabled. + * - 1b : The deadtime insertion in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDtEn0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DTEN0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DTEN0_SHIFT)) & MFT_COMBINE_DTEN0_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Dual Edge Capture Mode Captures For n = 0 + * + * This function gets the current Dual Edge Capture Mode Captures For n = 0. + * Enables the capture of the MFT counter value according to the channel (n) input event and the + * configuration of the dual edge capture bits. + * This field applies only when DECAPEN = 1. + * DECAP bit is cleared automatically by hardware if dual edge capture ¨C one-shot mode is selected and + * when the capture of channel (n+1) event is made. + * + * \param[in] obj : pointer to MFT register instance + * \return Dual Edge Capture Mode Captures For n = 0 + * - 0b : The dual edge captures are inactive. + * - 1b : The dual edge captures are active. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDecap0(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DECAP0_MASK) >> MFT_COMBINE_DECAP0_SHIFT); +} + +/*! \brief Sets the Dual Edge Capture Mode Captures For n = 0 + * + * This function sets the Dual Edge Capture Mode Captures For n = 0. + * Enables the capture of the MFT counter value according to the channel (n) input event and the + * configuration of the dual edge capture bits. + * This field applies only when DECAPEN = 1. + * DECAP bit is cleared automatically by hardware if dual edge capture ¨C one-shot mode is selected and + * when the capture of channel (n+1) event is made. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Dual Edge Capture Mode Captures For n = 0 + * - 0b : The dual edge captures are inactive. + * - 1b : The dual edge captures are active. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDecap0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DECAP0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DECAP0_SHIFT)) & MFT_COMBINE_DECAP0_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Dual Edge Capture Mode Enable For n = 0 + * + * This function gets the current Dual Edge Capture Mode Enable For n = 0. + * Enables the Dual Edge Capture mode in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Dual Edge Capture Mode Enable For n = 0 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDecapEn0(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DECAPEN0_MASK) >> MFT_COMBINE_DECAPEN0_SHIFT); +} + +/*! \brief Sets the Dual Edge Capture Mode Enable For n = 0 + * + * This function sets the Dual Edge Capture Mode Enable For n = 0. + * Enables the Dual Edge Capture mode in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Dual Edge Capture Mode Enable For n = 0 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDecapEn0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DECAPEN0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DECAPEN0_SHIFT)) & MFT_COMBINE_DECAPEN0_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Complement Of Channel (n) for n = 0 + * + * This function gets the current Complement Of Channel (n) for n = 0. + * In Complementary mode the channel (n+1) output is the inverse of the channel (n) output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Complement Of Channel (n) for n = 0 + * - 0b : If the channels (n) and (n+1) are in Combine Mode or Modified Combine PWM Mode, + * the channel (n+1) output is the same as the channel (n) output. + * If the channel (n+1) is in Output Compare Mode, EPWM or CPWM, + * the channel (n+1) output is independent from channel (n) output. + * - 1b : The channel (n+1) output is the complement of the channel (n) output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineComp0(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_COMP0_MASK) >> MFT_COMBINE_COMP0_SHIFT); +} + +/*! \brief Sets the Complement Of Channel (n) for n = 0 + * + * This function sets the Complement Of Channel (n) for n = 0. + * In Complementary mode the channel (n+1) output is the inverse of the channel (n) output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Complement Of Channel (n) for n = 0 + * - 0b : If the channels (n) and (n+1) are in Combine Mode or Modified Combine PWM Mode, + * the channel (n+1) output is the same as the channel (n) output. + * If the channel (n+1) is in Output Compare Mode, EPWM or CPWM, + * the channel (n+1) output is independent from channel (n) output. + * - 1b : The channel (n+1) output is the complement of the channel (n) output. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineComp0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_COMP0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_COMP0_SHIFT)) & MFT_COMBINE_COMP0_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Combine Channels For n = 0 + * + * This function gets the current Combine Channels For n = 0. + * Used on the selection of the combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Combine Channels For n = 0 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineCombine0(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_COMBINE0_MASK) >> MFT_COMBINE_COMBINE0_SHIFT); +} + +/*! \brief Sets the Combine Channels For n = 0 + * + * This function sets the Combine Channels For n = 0. + * Used on the selection of the combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Combine Channels For n = 0 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineCombine0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_COMBINE0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_COMBINE0_SHIFT)) & MFT_COMBINE_COMBINE0_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Extended Deadtime Value + * + * This function gets the current Extended Deadtime Value. + * This field is a bit extension of the DTVAL field. It defines the 4 most significant bits of the deadtime value. + * The maximum deadtime value is extended to 1023 using the concatenation {DTVALEX, DTVAL}. + * Deadtime insert value = (DTPS * {DTVALEX, DTVAL}). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \note If full compatibility is needed with previous software versions, write 0 to DTVALEX bits + * + * \param[in] obj : pointer to MFT register instance + * \return Extended Deadtime Value + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetDeadTimeDtValEx(const MftRegType *obj) +{ + return ((obj->DEADTIME & MFT_DEADTIME_DTVALEX_MASK) >> MFT_DEADTIME_DTVALEX_SHIFT); +} + +/*! \brief Sets the Extended Deadtime Value + * + * This function sets the Extended Deadtime Value. + * This field is a bit extension of the DTVAL field. It defines the 4 most significant bits of the deadtime value. + * The maximum deadtime value is extended to 1023 using the concatenation {DTVALEX, DTVAL}. + * Deadtime insert value = (DTPS * {DTVALEX, DTVAL}). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \note If full compatibility is needed with previous software versions, write 0 to DTVALEX bits + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Extended Deadtime Value + */ +__attribute__((always_inline)) static inline void MftReg_SetDeadTimeDtValEx(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DEADTIME; + + tmp &= ~MFT_DEADTIME_DTVALEX_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_DEADTIME_DTVALEX_SHIFT)) & MFT_DEADTIME_DTVALEX_MASK); + obj->DEADTIME = tmp; +} + +/*! \brief Gets the Deadtime Prescaler Value + * + * This function gets the current Deadtime Prescaler Value. + * Selects the division factor of the MFT input clock. This prescaled clock is used by the deadtime counter. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Deadtime Prescaler Value + * - 0xb : Divide the MFT input clock by 1. + * - 10b : Divide the MFT input clock by 4. + * - 11b : Divide the MFT input clock by 16. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetDeadTimeDtPs(const MftRegType *obj) +{ + return ((obj->DEADTIME & MFT_DEADTIME_DTPS_MASK) >> MFT_DEADTIME_DTPS_SHIFT); +} + +/*! \brief Sets the Deadtime Prescaler Value + * + * This function sets the Deadtime Prescaler Value. + * Selects the division factor of the MFT input clock. This prescaled clock is used by the deadtime counter. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Deadtime Prescaler Value + * - 0xb : Divide the MFT input clock by 1. + * - 10b : Divide the MFT input clock by 4. + * - 11b : Divide the MFT input clock by 16. + */ +__attribute__((always_inline)) static inline void MftReg_SetDeadTimeDtPs(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DEADTIME; + + tmp &= ~MFT_DEADTIME_DTPS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_DEADTIME_DTPS_SHIFT)) & MFT_DEADTIME_DTPS_MASK); + obj->DEADTIME = tmp; +} + +/*! \brief Gets the Deadtime Value + * + * This function gets the current Deadtime Value. + * Selects the deadtime value. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Deadtime Value + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetDeadTimeDtVal(const MftRegType *obj) +{ + return ((obj->DEADTIME & MFT_DEADTIME_DTVAL_MASK) >> MFT_DEADTIME_DTVAL_SHIFT); +} + +/*! \brief Sets the Deadtime Value + * + * This function sets the Deadtime Value. + * Selects the deadtime value. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Deadtime Value + */ +__attribute__((always_inline)) static inline void MftReg_SetDeadTimeDtVal(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DEADTIME; + + tmp &= ~MFT_DEADTIME_DTVAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_DEADTIME_DTVAL_SHIFT)) & MFT_DEADTIME_DTVAL_MASK); + obj->DEADTIME = tmp; +} + +/*! \brief Gets the Channel 7 External Trigger Enable + * + * This function gets the current Channel 7 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 7 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetExtTrigCh7Trig(const MftRegType *obj) +{ + return ((obj->EXTTRIG & MFT_EXTTRIG_CH7TRIG_MASK) >> MFT_EXTTRIG_CH7TRIG_SHIFT); +} + +/*! \brief Sets the Channel 7 External Trigger Enable + * + * This function sets the Channel 7 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 7 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetExtTrigCh7Trig(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTTRIG; + + tmp &= ~MFT_EXTTRIG_CH7TRIG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_EXTTRIG_CH7TRIG_SHIFT)) & MFT_EXTTRIG_CH7TRIG_MASK); + obj->EXTTRIG = tmp; +} + +/*! \brief Gets the Channel 6 External Trigger Enable + * + * This function gets the current Channel 6 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 6 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetExtTrigCh6Trig(const MftRegType *obj) +{ + return ((obj->EXTTRIG & MFT_EXTTRIG_CH6TRIG_MASK) >> MFT_EXTTRIG_CH6TRIG_SHIFT); +} + +/*! \brief Sets the Channel 6 External Trigger Enable + * + * This function sets the Channel 6 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 6 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetExtTrigCh6Trig(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTTRIG; + + tmp &= ~MFT_EXTTRIG_CH6TRIG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_EXTTRIG_CH6TRIG_SHIFT)) & MFT_EXTTRIG_CH6TRIG_MASK); + obj->EXTTRIG = tmp; +} + +/*! \brief Gets the Channel Trigger Flag + * + * This function gets the current Channel Trigger Flag. + * Set by hardware when a channel trigger is generated. + * Clear TRIGF by reading EXTTRIG while TRIGF is set and then writing a 0 to TRIGF. + * Writing a 1 to TRIGF has no effect. + * If another channel trigger is generated before the clearing sequence is completed, + * the sequence is reset so TRIGF remains set after the clear sequence is completed for the earlier TRIGF. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel Trigger Flag + * - 0b : No channel trigger was generated. + * - 1b : A channel trigger was generated. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetExtTrigTrigF(const MftRegType *obj) +{ + return ((obj->EXTTRIG & MFT_EXTTRIG_TRIGF_MASK) >> MFT_EXTTRIG_TRIGF_SHIFT); +} + +/*! \brief Sets the Channel Trigger Flag + * + * This function sets the Channel Trigger Flag. + * Set by hardware when a channel trigger is generated. + * Clear TRIGF by reading EXTTRIG while TRIGF is set and then writing a 0 to TRIGF. + * Writing a 1 to TRIGF has no effect. + * If another channel trigger is generated before the clearing sequence is completed, + * the sequence is reset so TRIGF remains set after the clear sequence is completed for the earlier TRIGF. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel Trigger Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetExtTrigTrigF(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->EXTTRIG; + + tmp &= ~MFT_EXTTRIG_TRIGF_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_EXTTRIG_TRIGF_SHIFT)) & MFT_EXTTRIG_TRIGF_MASK); + obj->EXTTRIG = tmp; +} + +/*! \brief Gets the Initialization Trigger Enable + * + * This function gets the current Initialization Trigger Enable. + * Enables the generation of the trigger when the MFT counter is equal to the CNTIN register. + * + * \param[in] obj : pointer to MFT register instance + * \return Initialization Trigger Enable + * - 0b : The generation of initialization trigger is disabled. + * - 1b : The generation of initialization trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetExtTrigInitTrigEn(const MftRegType *obj) +{ + return ((obj->EXTTRIG & MFT_EXTTRIG_INITTRIGEN_MASK) >> MFT_EXTTRIG_INITTRIGEN_SHIFT); +} + +/*! \brief Sets the Initialization Trigger Enable + * + * This function sets the Initialization Trigger Enable. + * Enables the generation of the trigger when the MFT counter is equal to the CNTIN register. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Initialization Trigger Enable + * - 0b : The generation of initialization trigger is disabled. + * - 1b : The generation of initialization trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetExtTrigInitTrigEn(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTTRIG; + + tmp &= ~MFT_EXTTRIG_INITTRIGEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_EXTTRIG_INITTRIGEN_SHIFT)) & MFT_EXTTRIG_INITTRIGEN_MASK); + obj->EXTTRIG = tmp; +} + +/*! \brief Gets the Channel 1 External Trigger Enable + * + * This function gets the current Channel 1 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 1 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetExtTrigCh1Trig(const MftRegType *obj) +{ + return ((obj->EXTTRIG & MFT_EXTTRIG_CH1TRIG_MASK) >> MFT_EXTTRIG_CH1TRIG_SHIFT); +} + +/*! \brief Sets the Channel 1 External Trigger Enable + * + * This function sets the Channel 1 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 1 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetExtTrigCh1Trig(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTTRIG; + + tmp &= ~MFT_EXTTRIG_CH1TRIG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_EXTTRIG_CH1TRIG_SHIFT)) & MFT_EXTTRIG_CH1TRIG_MASK); + obj->EXTTRIG = tmp; +} + +/*! \brief Gets the Channel 0 External Trigger Enable + * + * This function gets the current Channel 0 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 0 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetExtTrigCh0Trig(const MftRegType *obj) +{ + return ((obj->EXTTRIG & MFT_EXTTRIG_CH0TRIG_MASK) >> MFT_EXTTRIG_CH0TRIG_SHIFT); +} + +/*! \brief Sets the Channel 0 External Trigger Enable + * + * This function sets the Channel 0 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 0 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetExtTrigCh0Trig(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTTRIG; + + tmp &= ~MFT_EXTTRIG_CH0TRIG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_EXTTRIG_CH0TRIG_SHIFT)) & MFT_EXTTRIG_CH0TRIG_MASK); + obj->EXTTRIG = tmp; +} + +/*! \brief Gets the Channel 5 External Trigger Enable + * + * This function gets the current Channel 5 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 5 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetExtTrigCh5Trig(const MftRegType *obj) +{ + return ((obj->EXTTRIG & MFT_EXTTRIG_CH5TRIG_MASK) >> MFT_EXTTRIG_CH5TRIG_SHIFT); +} + +/*! \brief Sets the Channel 5 External Trigger Enable + * + * This function sets the Channel 5 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 5 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetExtTrigCh5Trig(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTTRIG; + + tmp &= ~MFT_EXTTRIG_CH5TRIG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_EXTTRIG_CH5TRIG_SHIFT)) & MFT_EXTTRIG_CH5TRIG_MASK); + obj->EXTTRIG = tmp; +} + +/*! \brief Gets the Channel 4 External Trigger Enable + * + * This function gets the current Channel 4 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 4 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetExtTrigCh4Trig(const MftRegType *obj) +{ + return ((obj->EXTTRIG & MFT_EXTTRIG_CH4TRIG_MASK) >> MFT_EXTTRIG_CH4TRIG_SHIFT); +} + +/*! \brief Sets the Channel 4 External Trigger Enable + * + * This function sets the Channel 4 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 4 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetExtTrigCh4Trig(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTTRIG; + + tmp &= ~MFT_EXTTRIG_CH4TRIG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_EXTTRIG_CH4TRIG_SHIFT)) & MFT_EXTTRIG_CH4TRIG_MASK); + obj->EXTTRIG = tmp; +} + +/*! \brief Gets the Channel 3 External Trigger Enable + * + * This function gets the current Channel 3 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 3 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetExtTrigCh3Trig(const MftRegType *obj) +{ + return ((obj->EXTTRIG & MFT_EXTTRIG_CH3TRIG_MASK) >> MFT_EXTTRIG_CH3TRIG_SHIFT); +} + +/*! \brief Sets the Channel 3 External Trigger Enable + * + * This function sets the Channel 3 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 3 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetExtTrigCh3Trig(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTTRIG; + + tmp &= ~MFT_EXTTRIG_CH3TRIG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_EXTTRIG_CH3TRIG_SHIFT)) & MFT_EXTTRIG_CH3TRIG_MASK); + obj->EXTTRIG = tmp; +} + +/*! \brief Gets the Channel 2 External Trigger Enable + * + * This function gets the current Channel 2 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 2 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetExtTrigCh2Trig(const MftRegType *obj) +{ + return ((obj->EXTTRIG & MFT_EXTTRIG_CH2TRIG_MASK) >> MFT_EXTTRIG_CH2TRIG_SHIFT); +} + +/*! \brief Sets the Channel 2 External Trigger Enable + * + * This function sets the Channel 2 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 2 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetExtTrigCh2Trig(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTTRIG; + + tmp &= ~MFT_EXTTRIG_CH2TRIG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_EXTTRIG_CH2TRIG_SHIFT)) & MFT_EXTTRIG_CH2TRIG_MASK); + obj->EXTTRIG = tmp; +} + +/*! \brief Gets the Channel 7 Polarity + * + * This function gets the current Channel 7 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 7 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPolPol7(const MftRegType *obj) +{ + return ((obj->POL & MFT_POL_POL7_MASK) >> MFT_POL_POL7_SHIFT); +} + +/*! \brief Sets the Channel 7 Polarity + * + * This function sets the Channel 7 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 7 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline void MftReg_SetPolPol7(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->POL; + + tmp &= ~MFT_POL_POL7_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_POL_POL7_SHIFT)) & MFT_POL_POL7_MASK); + obj->POL = tmp; +} + +/*! \brief Gets the Channel 6 Polarity + * + * This function gets the current Channel 6 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 6 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPolPol6(const MftRegType *obj) +{ + return ((obj->POL & MFT_POL_POL6_MASK) >> MFT_POL_POL6_SHIFT); +} + +/*! \brief Sets the Channel 6 Polarity + * + * This function sets the Channel 6 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 6 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline void MftReg_SetPolPol6(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->POL; + + tmp &= ~MFT_POL_POL6_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_POL_POL6_SHIFT)) & MFT_POL_POL6_MASK); + obj->POL = tmp; +} + +/*! \brief Gets the Channel 5 Polarity + * + * This function gets the current Channel 5 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 5 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPolPol5(const MftRegType *obj) +{ + return ((obj->POL & MFT_POL_POL5_MASK) >> MFT_POL_POL5_SHIFT); +} + +/*! \brief Sets the Channel 5 Polarity + * + * This function sets the Channel 5 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 5 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline void MftReg_SetPolPol5(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->POL; + + tmp &= ~MFT_POL_POL5_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_POL_POL5_SHIFT)) & MFT_POL_POL5_MASK); + obj->POL = tmp; +} + +/*! \brief Gets the Channel 4 Polarity + * + * This function gets the current Channel 4 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 4 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPolPol4(const MftRegType *obj) +{ + return ((obj->POL & MFT_POL_POL4_MASK) >> MFT_POL_POL4_SHIFT); +} + +/*! \brief Sets the Channel 4 Polarity + * + * This function sets the Channel 4 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 4 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline void MftReg_SetPolPol4(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->POL; + + tmp &= ~MFT_POL_POL4_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_POL_POL4_SHIFT)) & MFT_POL_POL4_MASK); + obj->POL = tmp; +} + +/*! \brief Gets the Channel 3 Polarity + * + * This function gets the current Channel 3 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 3 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPolPol3(const MftRegType *obj) +{ + return ((obj->POL & MFT_POL_POL3_MASK) >> MFT_POL_POL3_SHIFT); +} + +/*! \brief Sets the Channel 3 Polarity + * + * This function sets the Channel 3 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 3 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline void MftReg_SetPolPol3(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->POL; + + tmp &= ~MFT_POL_POL3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_POL_POL3_SHIFT)) & MFT_POL_POL3_MASK); + obj->POL = tmp; +} + +/*! \brief Gets the Channel 2 Polarity + * + * This function gets the current Channel 2 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 2 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPolPol2(const MftRegType *obj) +{ + return ((obj->POL & MFT_POL_POL2_MASK) >> MFT_POL_POL2_SHIFT); +} + +/*! \brief Sets the Channel 2 Polarity + * + * This function sets the Channel 2 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 2 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline void MftReg_SetPolPol2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->POL; + + tmp &= ~MFT_POL_POL2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_POL_POL2_SHIFT)) & MFT_POL_POL2_MASK); + obj->POL = tmp; +} + +/*! \brief Gets the Channel 1 Polarity + * + * This function gets the current Channel 1 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 1 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPolPol1(const MftRegType *obj) +{ + return ((obj->POL & MFT_POL_POL1_MASK) >> MFT_POL_POL1_SHIFT); +} + +/*! \brief Sets the Channel 1 Polarity + * + * This function sets the Channel 1 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 1 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline void MftReg_SetPolPol1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->POL; + + tmp &= ~MFT_POL_POL1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_POL_POL1_SHIFT)) & MFT_POL_POL1_MASK); + obj->POL = tmp; +} + +/*! \brief Gets the Channel 0 Polarity + * + * This function gets the current Channel 0 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 0 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPolPol0(const MftRegType *obj) +{ + return ((obj->POL & MFT_POL_POL0_MASK) >> MFT_POL_POL0_SHIFT); +} + +/*! \brief Sets the Channel 0 Polarity + * + * This function sets the Channel 0 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 0 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline void MftReg_SetPolPol0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->POL; + + tmp &= ~MFT_POL_POL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_POL_POL0_SHIFT)) & MFT_POL_POL0_MASK); + obj->POL = tmp; +} + +/*! \brief Gets the Fault Detection Flag + * + * This function gets the current Fault Detection Flag. + * Represents the logic OR of the FAULTF bit of each enabled fault input. + * Clear FAULTF by reading the FMS register while FAULTF is set and then writing a 0 to FAULTF + * while there is no existing fault condition at the enabled fault inputs. Writing a 1 to FAULTF has no effect. + * If another fault condition is detected in an enabled fault input before the clearing sequence is completed, + * the sequence is reset so FAULTF remains set after the clearing sequence is completed for the earlier fault condition. + * FAULTF is also cleared when FAULTF bit of each enabled fault input is cleared. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Detection Flag + * - 0b : No fault condition was detected. + * - 1b : A fault condition was detected. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFmsFaultF(const MftRegType *obj) +{ + return ((obj->FMS & MFT_FMS_FAULTF_MASK) >> MFT_FMS_FAULTF_SHIFT); +} + +/*! \brief Sets the Fault Detection Flag + * + * This function sets the Fault Detection Flag. + * Represents the logic OR of the FAULTF bit of each enabled fault input. + * Clear FAULTF by reading the FMS register while FAULTF is set and then writing a 0 to FAULTF + * while there is no existing fault condition at the enabled fault inputs. Writing a 1 to FAULTF has no effect. + * If another fault condition is detected in an enabled fault input before the clearing sequence is completed, + * the sequence is reset so FAULTF remains set after the clearing sequence is completed for the earlier fault condition. + * FAULTF is also cleared when FAULTF bit of each enabled fault input is cleared. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Detection Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetFmsFaultF(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->FMS; + + tmp &= ~MFT_FMS_FAULTF_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FMS_FAULTF_SHIFT)) & MFT_FMS_FAULTF_MASK); + obj->FMS = tmp; +} + +/*! \brief Gets the Write Protection Enable + * + * This function gets the current Write Protection Enable. + * The WPEN bit is the negation of the WPDIS bit. WPEN is set when 1 is written to it. WPEN is cleared + * when WPEN bit is read as a 1 and then 1 is written to WPDIS. Writing 0 to WPEN has no effect. + * + * \param[in] obj : pointer to MFT register instance + * \return Write Protection Enable + * - 0b : Write protection is disabled. Write protected bits can be written. + * - 1b : Write protection is enabled. Write protected bits cannot be written. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFmsWpEn(const MftRegType *obj) +{ + return ((obj->FMS & MFT_FMS_WPEN_MASK) >> MFT_FMS_WPEN_SHIFT); +} + +/*! \brief Sets the Write Protection Enable + * + * This function sets the Write Protection Enable. + * The WPEN bit is the negation of the WPDIS bit. WPEN is set when 1 is written to it. WPEN is cleared + * when WPEN bit is read as a 1 and then 1 is written to WPDIS. Writing 0 to WPEN has no effect. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Write Protection Enable + * - 0b : Write protection is disabled. Write protected bits can be written. + * - 1b : Write protection is enabled. Write protected bits cannot be written. + */ +__attribute__((always_inline)) static inline void MftReg_SetFmsWpEn(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FMS; + + tmp &= ~MFT_FMS_WPEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FMS_WPEN_SHIFT)) & MFT_FMS_WPEN_MASK); + obj->FMS = tmp; +} + +/*! \brief Gets the Fault Inputs + * + * This function gets the current Fault Inputs. + * Represents the logic OR of the enabled fault inputs after their filter (if their filter is enabled) + * when fault control is enabled. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Inputs + * - 0b : The logic OR of the enabled fault inputs is 0. + * - 1b : The logic OR of the enabled fault inputs is 1. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFmsFaultIn(const MftRegType *obj) +{ + return ((obj->FMS & MFT_FMS_FAULTIN_MASK) >> MFT_FMS_FAULTIN_SHIFT); +} + +/*! \brief Gets the Fault Detection Flag 3 + * + * This function gets the current Fault Detection Flag 3. + * Set by hardware when fault control is enabled, + * the corresponding fault input is enabled and a fault condition is detected at the fault input. + * Clear FAULTF3 by reading the FMS register while FAULTF3 is set and then writing a 0 to FAULTF3 + * while there is no existing fault condition at the corresponding fault input. Writing a 1 to FAULTF3 has no effect. + * FAULTF3 bit is also cleared when FAULTF bit is cleared. + * If another fault condition is detected at the corresponding fault input before the clearing sequence is completed, + * the sequence is reset so FAULTF3 remains set after the clearing sequence is completed for the earlier fault condition + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Detection Flag 3 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFmsFaultF3(const MftRegType *obj) +{ + return ((obj->FMS & MFT_FMS_FAULTF3_MASK) >> MFT_FMS_FAULTF3_SHIFT); +} + +/*! \brief Sets the Fault Detection Flag 3 + * + * This function sets the Fault Detection Flag 3. + * Set by hardware when fault control is enabled, + * the corresponding fault input is enabled and a fault condition is detected at the fault input. + * Clear FAULTF3 by reading the FMS register while FAULTF3 is set and then writing a 0 to FAULTF3 + * while there is no existing fault condition at the corresponding fault input. Writing a 1 to FAULTF3 has no effect. + * FAULTF3 bit is also cleared when FAULTF bit is cleared. + * If another fault condition is detected at the corresponding fault input before the clearing sequence is completed, + * the sequence is reset so FAULTF3 remains set after the clearing sequence is completed for the earlier fault condition + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Detection Flag 3 + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetFmsFaultF3(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->FMS; + + tmp &= ~MFT_FMS_FAULTF3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FMS_FAULTF3_SHIFT)) & MFT_FMS_FAULTF3_MASK); + obj->FMS = tmp; +} + +/*! \brief Gets the Fault Detection Flag 2 + * + * This function gets the current Fault Detection Flag 2. + * Set by hardware when fault control is enabled, + * the corresponding fault input is enabled and a fault condition is detected at the fault input. + * Clear FAULTF2 by reading the FMS register while FAULTF2 is set and then writing a 0 to FAULTF2 + * while there is no existing fault condition at the corresponding fault input. Writing a 1 to FAULTF2 has no effect. + * FAULTF2 bit is also cleared when FAULTF bit is cleared. + * If another fault condition is detected at the corresponding fault input before the clearing sequence is completed, + * the sequence is reset so FAULTF2 remains set after the clearing sequence is completed for the earlier fault condition + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Detection Flag 2 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFmsFaultF2(const MftRegType *obj) +{ + return ((obj->FMS & MFT_FMS_FAULTF2_MASK) >> MFT_FMS_FAULTF2_SHIFT); +} + +/*! \brief Sets the Fault Detection Flag 2 + * + * This function sets the Fault Detection Flag 2. + * Set by hardware when fault control is enabled, + * the corresponding fault input is enabled and a fault condition is detected at the fault input. + * Clear FAULTF2 by reading the FMS register while FAULTF2 is set and then writing a 0 to FAULTF2 + * while there is no existing fault condition at the corresponding fault input. Writing a 1 to FAULTF2 has no effect. + * FAULTF2 bit is also cleared when FAULTF bit is cleared. + * If another fault condition is detected at the corresponding fault input before the clearing sequence is completed, + * the sequence is reset so FAULTF2 remains set after the clearing sequence is completed for the earlier fault condition + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Detection Flag 2 + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetFmsFaultF2(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->FMS; + + tmp &= ~MFT_FMS_FAULTF2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FMS_FAULTF2_SHIFT)) & MFT_FMS_FAULTF2_MASK); + obj->FMS = tmp; +} + +/*! \brief Gets the Fault Detection Flag 1 + * + * This function gets the current Fault Detection Flag 1. + * Set by hardware when fault control is enabled, + * the corresponding fault input is enabled and a fault condition is detected at the fault input. + * Clear FAULTF1 by reading the FMS register while FAULTF1 is set and then writing a 0 to FAULTF1 + * while there is no existing fault condition at the corresponding fault input. Writing a 1 to FAULTF1 has no effect. + * FAULTF1 bit is also cleared when FAULTF bit is cleared. + * If another fault condition is detected at the corresponding fault input before the clearing sequence is completed, + * the sequence is reset so FAULTF1 remains set after the clearing sequence is completed for the earlier fault condition + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Detection Flag 1 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFmsFaultF1(const MftRegType *obj) +{ + return ((obj->FMS & MFT_FMS_FAULTF1_MASK) >> MFT_FMS_FAULTF1_SHIFT); +} + +/*! \brief Sets the Fault Detection Flag 1 + * + * This function sets the Fault Detection Flag 1. + * Set by hardware when fault control is enabled, + * the corresponding fault input is enabled and a fault condition is detected at the fault input. + * Clear FAULTF1 by reading the FMS register while FAULTF1 is set and then writing a 0 to FAULTF1 + * while there is no existing fault condition at the corresponding fault input. Writing a 1 to FAULTF1 has no effect. + * FAULTF1 bit is also cleared when FAULTF bit is cleared. + * If another fault condition is detected at the corresponding fault input before the clearing sequence is completed, + * the sequence is reset so FAULTF1 remains set after the clearing sequence is completed for the earlier fault condition + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Detection Flag 1 + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetFmsFaultF1(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->FMS; + + tmp &= ~MFT_FMS_FAULTF1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FMS_FAULTF1_SHIFT)) & MFT_FMS_FAULTF1_MASK); + obj->FMS = tmp; +} + +/*! \brief Gets the Fault Detection Flag 0 + * + * This function gets the current Fault Detection Flag 0. + * Set by hardware when fault control is enabled, + * the corresponding fault input is enabled and a fault condition is detected at the fault input. + * Clear FAULTF0 by reading the FMS register while FAULTF0 is set and then writing a 0 to FAULTF0 + * while there is no existing fault condition at the corresponding fault input. Writing a 1 to FAULTF0 has no effect. + * FAULTF0 bit is also cleared when FAULTF bit is cleared. + * If another fault condition is detected at the corresponding fault input before the clearing sequence is completed, + * the sequence is reset so FAULTF0 remains set after the clearing sequence is completed for the earlier fault condition + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Detection Flag 0 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFmsFaultF0(const MftRegType *obj) +{ + return ((obj->FMS & MFT_FMS_FAULTF0_MASK) >> MFT_FMS_FAULTF0_SHIFT); +} + +/*! \brief Sets the Fault Detection Flag 0 + * + * This function sets the Fault Detection Flag 0. + * Set by hardware when fault control is enabled, + * the corresponding fault input is enabled and a fault condition is detected at the fault input. + * Clear FAULTF0 by reading the FMS register while FAULTF0 is set and then writing a 0 to FAULTF0 + * while there is no existing fault condition at the corresponding fault input. Writing a 1 to FAULTF0 has no effect. + * FAULTF0 bit is also cleared when FAULTF bit is cleared. + * If another fault condition is detected at the corresponding fault input before the clearing sequence is completed, + * the sequence is reset so FAULTF0 remains set after the clearing sequence is completed for the earlier fault condition + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Detection Flag 0 + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetFmsFaultF0(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->FMS; + + tmp &= ~MFT_FMS_FAULTF0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FMS_FAULTF0_SHIFT)) & MFT_FMS_FAULTF0_MASK); + obj->FMS = tmp; +} + +/*! \brief Gets the Channel 3 Input Filter + * + * This function gets the current Channel 3 Input Filter. + * Selects the filter value for the channel input. + * The filter is disabled when the value is zero + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 3 Input Filter + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFilterCh3FVal(const MftRegType *obj) +{ + return ((obj->FILTER & MFT_FILTER_CH3FVAL_MASK) >> MFT_FILTER_CH3FVAL_SHIFT); +} + +/*! \brief Sets the Channel 3 Input Filter + * + * This function sets the Channel 3 Input Filter. + * Selects the filter value for the channel input. + * The filter is disabled when the value is zero + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 3 Input Filter + */ +__attribute__((always_inline)) static inline void MftReg_SetFilterCh3FVal(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FILTER; + + tmp &= ~MFT_FILTER_CH3FVAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FILTER_CH3FVAL_SHIFT)) & MFT_FILTER_CH3FVAL_MASK); + obj->FILTER = tmp; +} + +/*! \brief Gets the Channel 2 Input Filter + * + * This function gets the current Channel 2 Input Filter. + * Selects the filter value for the channel input. + * The filter is disabled when the value is zero + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 2 Input Filter + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFilterCh2FVal(const MftRegType *obj) +{ + return ((obj->FILTER & MFT_FILTER_CH2FVAL_MASK) >> MFT_FILTER_CH2FVAL_SHIFT); +} + +/*! \brief Sets the Channel 2 Input Filter + * + * This function sets the Channel 2 Input Filter. + * Selects the filter value for the channel input. + * The filter is disabled when the value is zero + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 2 Input Filter + */ +__attribute__((always_inline)) static inline void MftReg_SetFilterCh2FVal(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FILTER; + + tmp &= ~MFT_FILTER_CH2FVAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FILTER_CH2FVAL_SHIFT)) & MFT_FILTER_CH2FVAL_MASK); + obj->FILTER = tmp; +} + +/*! \brief Gets the Channel 1 Input Filter + * + * This function gets the current Channel 1 Input Filter. + * Selects the filter value for the channel input. + * The filter is disabled when the value is zero + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 1 Input Filter + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFilterCh1FVal(const MftRegType *obj) +{ + return ((obj->FILTER & MFT_FILTER_CH1FVAL_MASK) >> MFT_FILTER_CH1FVAL_SHIFT); +} + +/*! \brief Sets the Channel 1 Input Filter + * + * This function sets the Channel 1 Input Filter. + * Selects the filter value for the channel input. + * The filter is disabled when the value is zero + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 1 Input Filter + */ +__attribute__((always_inline)) static inline void MftReg_SetFilterCh1FVal(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FILTER; + + tmp &= ~MFT_FILTER_CH1FVAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FILTER_CH1FVAL_SHIFT)) & MFT_FILTER_CH1FVAL_MASK); + obj->FILTER = tmp; +} + +/*! \brief Gets the Channel 0 Input Filter + * + * This function gets the current Channel 0 Input Filter. + * Selects the filter value for the channel input. + * The filter is disabled when the value is zero + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 0 Input Filter + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFilterCh0FVal(const MftRegType *obj) +{ + return ((obj->FILTER & MFT_FILTER_CH0FVAL_MASK) >> MFT_FILTER_CH0FVAL_SHIFT); +} + +/*! \brief Sets the Channel 0 Input Filter + * + * This function sets the Channel 0 Input Filter. + * Selects the filter value for the channel input. + * The filter is disabled when the value is zero + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 0 Input Filter + */ +__attribute__((always_inline)) static inline void MftReg_SetFilterCh0FVal(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FILTER; + + tmp &= ~MFT_FILTER_CH0FVAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FILTER_CH0FVAL_SHIFT)) & MFT_FILTER_CH0FVAL_MASK); + obj->FILTER = tmp; +} + +/*! \brief Gets the Fault output state + * + * This function gets the current Fault output state. + * This configuration allows to put the MFT outputs tri-stated when a fault event is ongoing. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault output state + * - 0b : MFT outputs will be placed into safe values when fault events in ongoing (defined by POL bits). + * - 1b : MFT outputs will be tri-stated when fault event is ongoing + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltCtrlFstate(const MftRegType *obj) +{ + return ((obj->FLTCTRL & MFT_FLTCTRL_FSTATE_MASK) >> MFT_FLTCTRL_FSTATE_SHIFT); +} + +/*! \brief Sets the Fault output state + * + * This function sets the Fault output state. + * This configuration allows to put the MFT outputs tri-stated when a fault event is ongoing. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault output state + * - 0b : MFT outputs will be placed into safe values when fault events in ongoing (defined by POL bits). + * - 1b : MFT outputs will be tri-stated when fault event is ongoing + */ +__attribute__((always_inline)) static inline void MftReg_SetFltCtrlFstate(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTCTRL; + + tmp &= ~MFT_FLTCTRL_FSTATE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTCTRL_FSTATE_SHIFT)) & MFT_FLTCTRL_FSTATE_MASK); + obj->FLTCTRL = tmp; +} + +/*! \brief Gets the Fault Input Filter + * + * This function gets the current Fault Input Filter. + * Selects the filter value for the fault inputs. + * The fault filter is disabled when the value is zero. + * + * \note Writing to this field has immediate effect and must be done only when the fault contro + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input Filter + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltCtrlFFVal(const MftRegType *obj) +{ + return ((obj->FLTCTRL & MFT_FLTCTRL_FFVAL_MASK) >> MFT_FLTCTRL_FFVAL_SHIFT); +} + +/*! \brief Sets the Fault Input Filter + * + * This function sets the Fault Input Filter. + * Selects the filter value for the fault inputs. + * The fault filter is disabled when the value is zero. + * + * \note Writing to this field has immediate effect and must be done only when the fault contro + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input Filter + */ +__attribute__((always_inline)) static inline void MftReg_SetFltCtrlFFVal(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTCTRL; + + tmp &= ~MFT_FLTCTRL_FFVAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTCTRL_FFVAL_SHIFT)) & MFT_FLTCTRL_FFVAL_MASK); + obj->FLTCTRL = tmp; +} + +/*! \brief Gets the Fault Input 3 Filter Enable + * + * This function gets the current Fault Input 3 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 3 Filter Enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltCtrlFFltr3En(const MftRegType *obj) +{ + return ((obj->FLTCTRL & MFT_FLTCTRL_FFLTR3EN_MASK) >> MFT_FLTCTRL_FFLTR3EN_SHIFT); +} + +/*! \brief Sets the Fault Input 3 Filter Enable + * + * This function sets the Fault Input 3 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 3 Filter Enable + */ +__attribute__((always_inline)) static inline void MftReg_SetFltCtrlFFltr3En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTCTRL; + + tmp &= ~MFT_FLTCTRL_FFLTR3EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTCTRL_FFLTR3EN_SHIFT)) & MFT_FLTCTRL_FFLTR3EN_MASK); + obj->FLTCTRL = tmp; +} + +/*! \brief Gets the Fault Input 2 Filter Enable + * + * This function gets the current Fault Input 2 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 2 Filter Enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltCtrlFFltr2En(const MftRegType *obj) +{ + return ((obj->FLTCTRL & MFT_FLTCTRL_FFLTR2EN_MASK) >> MFT_FLTCTRL_FFLTR2EN_SHIFT); +} + +/*! \brief Sets the Fault Input 2 Filter Enable + * + * This function sets the Fault Input 2 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 2 Filter Enable + */ +__attribute__((always_inline)) static inline void MftReg_SetFltCtrlFFltr2En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTCTRL; + + tmp &= ~MFT_FLTCTRL_FFLTR2EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTCTRL_FFLTR2EN_SHIFT)) & MFT_FLTCTRL_FFLTR2EN_MASK); + obj->FLTCTRL = tmp; +} + +/*! \brief Gets the Fault Input 1 Filter Enable + * + * This function gets the current Fault Input 1 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 1 Filter Enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltCtrlFFltr1En(const MftRegType *obj) +{ + return ((obj->FLTCTRL & MFT_FLTCTRL_FFLTR1EN_MASK) >> MFT_FLTCTRL_FFLTR1EN_SHIFT); +} + +/*! \brief Sets the Fault Input 1 Filter Enable + * + * This function sets the Fault Input 1 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 1 Filter Enable + */ +__attribute__((always_inline)) static inline void MftReg_SetFltCtrlFFltr1En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTCTRL; + + tmp &= ~MFT_FLTCTRL_FFLTR1EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTCTRL_FFLTR1EN_SHIFT)) & MFT_FLTCTRL_FFLTR1EN_MASK); + obj->FLTCTRL = tmp; +} + +/*! \brief Gets the Fault Input 0 Filter Enable + * + * This function gets the current Fault Input 0 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 0 Filter Enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltCtrlFFltr0En(const MftRegType *obj) +{ + return ((obj->FLTCTRL & MFT_FLTCTRL_FFLTR0EN_MASK) >> MFT_FLTCTRL_FFLTR0EN_SHIFT); +} + +/*! \brief Sets the Fault Input 0 Filter Enable + * + * This function sets the Fault Input 0 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 0 Filter Enable + */ +__attribute__((always_inline)) static inline void MftReg_SetFltCtrlFFltr0En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTCTRL; + + tmp &= ~MFT_FLTCTRL_FFLTR0EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTCTRL_FFLTR0EN_SHIFT)) & MFT_FLTCTRL_FFLTR0EN_MASK); + obj->FLTCTRL = tmp; +} + +/*! \brief Gets the Fault Input 3 Filter Enable + * + * This function gets the current Fault Input 3 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 3 Filter Enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltCtrlFault3En(const MftRegType *obj) +{ + return ((obj->FLTCTRL & MFT_FLTCTRL_FAULT3EN_MASK) >> MFT_FLTCTRL_FAULT3EN_SHIFT); +} + +/*! \brief Sets the Fault Input 3 Filter Enable + * + * This function sets the Fault Input 3 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 3 Filter Enable + */ +__attribute__((always_inline)) static inline void MftReg_SetFltCtrlFault3En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTCTRL; + + tmp &= ~MFT_FLTCTRL_FAULT3EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTCTRL_FAULT3EN_SHIFT)) & MFT_FLTCTRL_FAULT3EN_MASK); + obj->FLTCTRL = tmp; +} + +/*! \brief Gets the Fault Input 2 Filter Enable + * + * This function gets the current Fault Input 2 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 2 Filter Enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltCtrlFault2En(const MftRegType *obj) +{ + return ((obj->FLTCTRL & MFT_FLTCTRL_FAULT2EN_MASK) >> MFT_FLTCTRL_FAULT2EN_SHIFT); +} + +/*! \brief Sets the Fault Input 2 Filter Enable + * + * This function sets the Fault Input 2 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 2 Filter Enable + */ +__attribute__((always_inline)) static inline void MftReg_SetFltCtrlFault2En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTCTRL; + + tmp &= ~MFT_FLTCTRL_FAULT2EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTCTRL_FAULT2EN_SHIFT)) & MFT_FLTCTRL_FAULT2EN_MASK); + obj->FLTCTRL = tmp; +} + +/*! \brief Gets the Fault Input 1 Filter Enable + * + * This function gets the current Fault Input 1 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 1 Filter Enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltCtrlFault1En(const MftRegType *obj) +{ + return ((obj->FLTCTRL & MFT_FLTCTRL_FAULT1EN_MASK) >> MFT_FLTCTRL_FAULT1EN_SHIFT); +} + +/*! \brief Sets the Fault Input 1 Filter Enable + * + * This function sets the Fault Input 1 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 1 Filter Enable + */ +__attribute__((always_inline)) static inline void MftReg_SetFltCtrlFault1En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTCTRL; + + tmp &= ~MFT_FLTCTRL_FAULT1EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTCTRL_FAULT1EN_SHIFT)) & MFT_FLTCTRL_FAULT1EN_MASK); + obj->FLTCTRL = tmp; +} + +/*! \brief Gets the Fault Input 0 Filter Enable + * + * This function gets the current Fault Input 0 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 0 Filter Enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltCtrlFault0En(const MftRegType *obj) +{ + return ((obj->FLTCTRL & MFT_FLTCTRL_FAULT0EN_MASK) >> MFT_FLTCTRL_FAULT0EN_SHIFT); +} + +/*! \brief Sets the Fault Input 0 Filter Enable + * + * This function sets the Fault Input 0 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 0 Filter Enable + */ +__attribute__((always_inline)) static inline void MftReg_SetFltCtrlFault0En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTCTRL; + + tmp &= ~MFT_FLTCTRL_FAULT0EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTCTRL_FAULT0EN_SHIFT)) & MFT_FLTCTRL_FAULT0EN_MASK); + obj->FLTCTRL = tmp; +} + +/*! \brief Gets the Phase Z Input Filter Enable + * + * This function gets the current Phase Z Input Filter Enable. + * Enables the filter for the quadrature decoder phase Z input. + * The filter value for the phase Z input is defined by the CH0FVAL field of FILTER. + * The phase Z filter is also disabled when CH0FVAL is zero + * + * \param[in] obj : pointer to MFT register instance + * \return Phase Z Input Filter Enable + * - 0 : disable + * - 1 : enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlPhzFltrEn(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_PHZFLTREN_MASK) >> MFT_QDCTRL_PHZFLTREN_SHIFT); +} + +/*! \brief Sets the Phase Z Input Filter Enable + * + * This function sets the Phase Z Input Filter Enable. + * Enables the filter for the quadrature decoder phase Z input. + * The filter value for the phase Z input is defined by the CH0FVAL field of FILTER. + * The phase Z filter is also disabled when CH0FVAL is zero + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Phase Z Input Filter Enable + * - 0 : disable + * - 1 : enable + */ +__attribute__((always_inline)) static inline void MftReg_SetQDCtrlPhzFltrEn(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->QDCTRL; + + tmp &= ~MFT_QDCTRL_PHZFLTREN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_QDCTRL_PHZFLTREN_SHIFT)) & MFT_QDCTRL_PHZFLTREN_MASK); + obj->QDCTRL = tmp; +} + +/*! \brief Gets the Phase Z Input Polarity + * + * This function gets the current Phase Z Input Polarity. + * Selects the polarity for the quadrature decoder phase Z input. + * + * \param[in] obj : pointer to MFT register instance + * \return Phase A Input Polarity + * - 0b : Normal polarity. Phase Z input signal is not inverted + * before identifying the rising and falling edges of this signal. + * - 1b : Inverted polarity. Phase Z input signal is inverted + * before identifying the rising and falling edges of this signal. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlPhzPol(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_PHZPOL_MASK) >> MFT_QDCTRL_PHZPOL_SHIFT); +} + +/*! \brief Sets the Phase Z Input Polarity + * + * This function sets the Phase Z Input Polarity. + * Selects the polarity for the quadrature decoder phase Z input. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Phase Z Input Polarity + * - 0b : Normal polarity. Phase Z input signal is not inverted + * before identifying the rising and falling edges of this signal. + * - 1b : Inverted polarity. Phase Z input signal is inverted + * before identifying the rising and falling edges of this signal. + */ +__attribute__((always_inline)) static inline void MftReg_SetQDCtrlPhzPol(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->QDCTRL; + + tmp &= ~MFT_QDCTRL_PHZPOL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_QDCTRL_PHZPOL_SHIFT)) & MFT_QDCTRL_PHZPOL_MASK); + obj->QDCTRL = tmp; +} + +/*! \brief Gets the Phase Z Clearing Mode + * + * This function gets the Phase Z Clearing Mode. + * Selects the condition in which phase Z input signal clears the counter. + * + * \param[in] obj : pointer to MFT register instance + * \return Phase Z clear Mode + * - 00b : phase Z input does not reset the counter. + * - 01b : every effective edge of phase Z input resets the counter + * (Reseting does not happen immediately, but after the first or + * recorded phase A or phase B input edge). + * - 10b : phase Z input resets the counter only once + * (Reseting does not happen immediately, but after the first + * phase A or phase B input edge). + * - 11b : Clear immediately when the effective edge of Phase Z signal comes. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlPhzClearMode(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_PHZMODE_MASK) >> MFT_QDCTRL_PHZMODE_SHIFT); +} + +/*! \brief Sets the Phase Z Clearing Mode + * + * This function sets the Phase Z Clearing Mode. + * Selects the condition in which phase Z input signal clears the counter. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Phase Z Clearing Mode + * - 00b : phase Z input does not reset the counter. + * - 01b : every effective edge of phase Z input resets the counter + * (Reseting does not happen immediately, but after the first or + * recorded phase A or phase B input edge). + * - 10b : phase Z input resets the counter only once + * (Reseting does not happen immediately, but after the first + * phase A or phase B input edge). + * - 11b : Clear immediately when the effective edge of Phase Z signal comes. + * + */ +__attribute__((always_inline)) static inline void MftReg_SetQDCtrlPhzClearMode(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->QDCTRL; + + tmp &= ~MFT_QDCTRL_PHZMODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_QDCTRL_PHZMODE_SHIFT)) & MFT_QDCTRL_PHZMODE_MASK); + obj->QDCTRL = tmp; +} + +/*! \brief Gets the Phase Z First has occurred status + * + * This function gets the Phase Z First index pulse has occurred status. + * + * \param[in] obj : pointer to MFT register instance + * \return Phase Z First occurred status + * - 0b : phase Z clearing once has not happened + * - 1b : phase Z clearing once has happened + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlPhzFirstHappened(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_PHZCOF_MASK) >> MFT_QDCTRL_PHZCOF_SHIFT); +} + +/*! \brief Clear the Phase Z has occurred status + * + * This function clear the Phase Z First index pulse has occurred status. + * + * \param[in] obj : pointer to MFT register instance + */ +__attribute__((always_inline)) static inline void MftReg_ClearQDCtrlPhzFirstHappend(MftRegType *obj) +{ + uint32_t tmp = obj->QDCTRL; + + tmp &= ~MFT_QDCTRL_PHZCOF_MASK; + tmp |= (((uint32_t)(((uint32_t)(1)) << MFT_QDCTRL_PHZCOF_SHIFT)) & MFT_QDCTRL_PHZCOF_MASK); + obj->QDCTRL = tmp; +} + +/*! \brief Gets the Phase A Input Filter Enable + * + * This function gets the current Phase A Input Filter Enable. + * Enables the filter for the quadrature decoder phase A input. + * The filter value for the phase A input is defined by the CH0FVAL field of FILTER. + * The phase A filter is also disabled when CH0FVAL is zero + * + * \param[in] obj : pointer to MFT register instance + * \return Phase A Input Filter Enable + * - 0 : disable + * - 1 : enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlPhaFltrEn(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_PHAFLTREN_MASK) >> MFT_QDCTRL_PHAFLTREN_SHIFT); +} + +/*! \brief Sets the Phase A Input Filter Enable + * + * This function sets the Phase A Input Filter Enable. + * Enables the filter for the quadrature decoder phase A input. + * The filter value for the phase A input is defined by the CH0FVAL field of FILTER. + * The phase A filter is also disabled when CH0FVAL is zero + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Phase A Input Filter Enable + * - 0 : disable + * - 1 : enable + */ +__attribute__((always_inline)) static inline void MftReg_SetQDCtrlPhaFltrEn(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->QDCTRL; + + tmp &= ~MFT_QDCTRL_PHAFLTREN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_QDCTRL_PHAFLTREN_SHIFT)) & MFT_QDCTRL_PHAFLTREN_MASK); + obj->QDCTRL = tmp; +} + +/*! \brief Gets the Phase B Input Filter Enable + * + * This function gets the current Phase B Input Filter Enable. + * Enables the filter for the quadrature decoder phase B input. + * The filter value for the phase B input is defined by the CH1FVAL field of FILTER. + * The phase B filter is also disabled when CH1FVAL is zero + * + * \param[in] obj : pointer to MFT register instance + * \return Phase B Input Filter Enable + * - 0 : disable + * - 1 : enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlPhbFltrEn(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_PHBFLTREN_MASK) >> MFT_QDCTRL_PHBFLTREN_SHIFT); +} + +/*! \brief Sets the Phase B Input Filter Enable + * + * This function sets the Phase B Input Filter Enable. + * Enables the filter for the quadrature decoder phase B input. + * The filter value for the phase B input is defined by the CH1FVAL field of FILTER. + * The phase B filter is also disabled when CH1FVAL is zero + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Phase B Input Filter Enable + * - 0 : disable + * - 1 : enable + */ +__attribute__((always_inline)) static inline void MftReg_SetQDCtrlPhbFltrEn(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->QDCTRL; + + tmp &= ~MFT_QDCTRL_PHBFLTREN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_QDCTRL_PHBFLTREN_SHIFT)) & MFT_QDCTRL_PHBFLTREN_MASK); + obj->QDCTRL = tmp; +} + +/*! \brief Gets the Phase A Input Polarity + * + * This function gets the current Phase A Input Polarity. + * Selects the polarity for the quadrature decoder phase A input. + * + * \param[in] obj : pointer to MFT register instance + * \return Phase A Input Polarity + * - 0b : Normal polarity. Phase A input signal is not inverted + * before identifying the rising and falling edges of this signal. + * - 1b : Inverted polarity. Phase A input signal is inverted + * before identifying the rising and falling edges of this signal. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlPhaPol(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_PHAPOL_MASK) >> MFT_QDCTRL_PHAPOL_SHIFT); +} + +/*! \brief Sets the Phase A Input Polarity + * + * This function sets the Phase A Input Polarity. + * Selects the polarity for the quadrature decoder phase A input. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Phase A Input Polarity + * - 0b : Normal polarity. Phase A input signal is not inverted + * before identifying the rising and falling edges of this signal. + * - 1b : Inverted polarity. Phase A input signal is inverted + * before identifying the rising and falling edges of this signal. + */ +__attribute__((always_inline)) static inline void MftReg_SetQDCtrlPhaPol(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->QDCTRL; + + tmp &= ~MFT_QDCTRL_PHAPOL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_QDCTRL_PHAPOL_SHIFT)) & MFT_QDCTRL_PHAPOL_MASK); + obj->QDCTRL = tmp; +} + +/*! \brief Gets the Phase B Input Polarity + * + * This function gets the current Phase B Input Polarity. + * Selects the polarity for the quadrature decoder phase B input. + * + * \param[in] obj : pointer to MFT register instance + * \return Phase B Input Polarity + * - 0b : Normal polarity. Phase B input signal is not inverted + * before identifying the rising and falling edges of this signal. + * - 1b : Inverted polarity. Phase B input signal is inverted + * before identifying the rising and falling edges of this signal. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlPhbPol(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_PHBPOL_MASK) >> MFT_QDCTRL_PHBPOL_SHIFT); +} + +/*! \brief Sets the Phase B Input Polarity + * + * This function sets the Phase B Input Polarity. + * Selects the polarity for the quadrature decoder phase B input. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Phase B Input Polarity + * - 0b : Normal polarity. Phase B input signal is not inverted + * before identifying the rising and falling edges of this signal. + * - 1b : Inverted polarity. Phase B input signal is inverted + * before identifying the rising and falling edges of this signal. + */ +__attribute__((always_inline)) static inline void MftReg_SetQDCtrlPhbPol(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->QDCTRL; + + tmp &= ~MFT_QDCTRL_PHBPOL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_QDCTRL_PHBPOL_SHIFT)) & MFT_QDCTRL_PHBPOL_MASK); + obj->QDCTRL = tmp; +} + +/*! \brief Gets the Quadrature Decoder Mode + * + * This function gets the current Quadrature Decoder Mode. + * Selects the encoding mode used in the Quadrature Decoder mode. + * + * \param[in] obj : pointer to MFT register instance + * \return Quadrature Decoder Mode + * - 0b : Phase A and phase B encoding mode. + * - 1b : Count and direction encoding mode. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlQuadMode(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_QUADMODE_MASK) >> MFT_QDCTRL_QUADMODE_SHIFT); +} + +/*! \brief Sets the Quadrature Decoder Mode + * + * This function sets the Quadrature Decoder Mode. + * Selects the encoding mode used in the Quadrature Decoder mode. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Quadrature Decoder Mode + * - 0b : Phase A and phase B encoding mode. + * - 1b : Count and direction encoding mode. + */ +__attribute__((always_inline)) static inline void MftReg_SetQDCtrlQuadMode(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->QDCTRL; + + tmp &= ~MFT_QDCTRL_QUADMODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_QDCTRL_QUADMODE_SHIFT)) & MFT_QDCTRL_QUADMODE_MASK); + obj->QDCTRL = tmp; +} + +/*! \brief Gets the MFT Counter Direction In Quadrature Decoder Mode + * + * This function gets the current MFT Counter Direction In Quadrature Decoder Mode. + * Indicates the counting direction. + * + * \param[in] obj : pointer to MFT register instance + * \return MFT Counter Direction In Quadrature Decoder Mode + * - 0b : Counting direction is decreasing (MFT counter decrement). + * - 1b : Counting direction is increasing (MFT counter increment). + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlQuaDir(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_QUADIR_MASK) >> MFT_QDCTRL_QUADIR_SHIFT); +} + +/*! \brief Gets the Timer Overflow Direction In Quadrature Decoder Mode + * + * This function gets the current Timer Overflow Direction In Quadrature Decoder Mode. + * Indicates if the TOF bit was set on the top or the bottom of counting. + * + * \param[in] obj : pointer to MFT register instance + * \return Timer Overflow Direction In Quadrature Decoder Mode + * - 0b : TOF bit was set on the bottom of counting. + * There was an MFT counter decrement and MFT counter changes + * from its minimum value (CNTIN register) to its maximum value (MOD register). + * - 1b : TOF bit was set on the top of counting. + * There was an MFT counter increment and MFT counter changes + * from its maximum value (MOD register) to its minimum value (CNTIN register). + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlTorDir(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_TOFDIR_MASK) >> MFT_QDCTRL_TOFDIR_SHIFT); +} + +/*! \brief Gets the Quadrature Decoder Mode Enable + * + * This function gets the current Quadrature Decoder Mode Enable. + * Enables the Quadrature Decoder mode. + * In this mode, the phase A and B input signals control the MFT counter direction. + * The Quadrature Decoder mode has precedence over the other modes. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Quadrature Decoder Mode Enable + * - 0b : Quadrature Decoder mode is disabled. + * - 1b : Quadrature Decoder mode is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlQuadEn(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_QUADEN_MASK) >> MFT_QDCTRL_QUADEN_SHIFT); +} + +/*! \brief Sets the Quadrature Decoder Mode Enable + * + * This function sets the Quadrature Decoder Mode Enable. + * Enables the Quadrature Decoder mode. + * In this mode, the phase A and B input signals control the MFT counter direction. + * The Quadrature Decoder mode has precedence over the other modes. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Quadrature Decoder Mode Enable + * - 0b : Quadrature Decoder mode is disabled. + * - 1b : Quadrature Decoder mode is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetQDCtrlQuadEn(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->QDCTRL; + + tmp &= ~MFT_QDCTRL_QUADEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_QDCTRL_QUADEN_SHIFT)) & MFT_QDCTRL_QUADEN_MASK); + obj->QDCTRL = tmp; +} + +/*! \brief Gets the Initialization trigger on Reload Point + * + * This function gets the current Initialization trigger on Reload Point. + * This bit controls whether an initialization trigger is generated when a reload point configured by + * PWMLOAD register is reached considering the MFT_CONF[LDFQ] settings. + * + * \param[in] obj : pointer to MFT register instance + * \return Initialization trigger on Reload Point + * - 0b : Initialization trigger is generated on counter wrap events. + * - 1b : Initialization trigger is generated when a reload point is reached. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetConfITrigR(const MftRegType *obj) +{ + return ((obj->CONF & MFT_CONF_ITRIGR_MASK) >> MFT_CONF_ITRIGR_SHIFT); +} + +/*! \brief Sets the Initialization trigger on Reload Point + * + * This function sets the Initialization trigger on Reload Point. + * This bit controls whether an initialization trigger is generated when a reload point configured by + * PWMLOAD register is reached considering the MFT_CONF[LDFQ] settings. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Initialization trigger on Reload Point + * - 0b : Initialization trigger is generated on counter wrap events. + * - 1b : Initialization trigger is generated when a reload point is reached. + */ +__attribute__((always_inline)) static inline void MftReg_SetConfITrigR(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CONF; + + tmp &= ~MFT_CONF_ITRIGR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CONF_ITRIGR_SHIFT)) & MFT_CONF_ITRIGR_MASK); + obj->CONF = tmp; +} + +/*! \brief Gets the Global Time Base Output + * + * This function gets the current Global Time Base Output. + * Enables the global time base signal generation to other MFTs. + * + * \param[in] obj : pointer to MFT register instance + * \return Global Time Base Output + * - 0b : A global time base signal generation is disabled. + * - 1b : A global time base signal generation is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetConfGtbeOut(const MftRegType *obj) +{ + return ((obj->CONF & MFT_CONF_GTBEOUT_MASK) >> MFT_CONF_GTBEOUT_SHIFT); +} + +/*! \brief Sets the Global Time Base Output + * + * This function sets the Global Time Base Output. + * Enables the global time base signal generation to other MFTs. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Global Time Base Output + * - 0b : A global time base signal generation is disabled. + * - 1b : A global time base signal generation is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetConfGtbeOut(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CONF; + + tmp &= ~MFT_CONF_GTBEOUT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CONF_GTBEOUT_SHIFT)) & MFT_CONF_GTBEOUT_MASK); + obj->CONF = tmp; +} + +/*! \brief Gets the Global Time Base Enable + * + * This function gets the current Global Time Base Enable. + * Configures the MFT to use an external global time base signal that is generated by another MFT. + * + * \param[in] obj : pointer to MFT register instance + * \return Global Time Base Enable + * - 0b : Use of an external global time base is disabled. + * - 1b : Use of an external global time base is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetConfGtbeEn(const MftRegType *obj) +{ + return ((obj->CONF & MFT_CONF_GTBEEN_MASK) >> MFT_CONF_GTBEEN_SHIFT); +} + +/*! \brief Sets the Global Time Base Enable + * + * This function sets the Global Time Base Enable. + * Configures the MFT to use an external global time base signal that is generated by another MFT. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Global Time Base Enable + * - 0b : Use of an external global time base is disabled. + * - 1b : Use of an external global time base is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetConfGtbeEn(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CONF; + + tmp &= ~MFT_CONF_GTBEEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CONF_GTBEEN_SHIFT)) & MFT_CONF_GTBEEN_MASK); + obj->CONF = tmp; +} + +/*! \brief Gets the Debug Mode + * + * This function gets the current Debug Mode. + * Selects the MFT behavior in Debug mod + * + * \param[in] obj : pointer to MFT register instance + * \return Debug Mode + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetConfBdmMode(const MftRegType *obj) +{ + return ((obj->CONF & MFT_CONF_BDMMODE_MASK) >> MFT_CONF_BDMMODE_SHIFT); +} + +/*! \brief Sets the Debug Mode + * + * This function sets the Debug Mode. + * Selects the MFT behavior in Debug mod + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Debug Mode + */ +__attribute__((always_inline)) static inline void MftReg_SetConfBdmMode(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CONF; + + tmp &= ~MFT_CONF_BDMMODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CONF_BDMMODE_SHIFT)) & MFT_CONF_BDMMODE_MASK); + obj->CONF = tmp; +} + +/*! \brief Gets the Frequency of the Reload Opportunities + * + * This function gets the current Frequency of the Reload Opportunities. + * The LDFQ[4:0] bits define the number of enabled reload opportunities should happen + * until an enabled reload opportunity becomes a reload point. See Reload Points + * LDFQ = 0: All reload opportunities are reload points. + * LDFQ = 1: There is a reload point each 2 reload oportunities. + * LDFQ = 2: There is a reload point each 3 reload oportunities. + * LDFQ = 3: There is a reload point each 4 reload oportunities. + * This pattern continues up to a maximum of 32 + * + * \param[in] obj : pointer to MFT register instance + * \return Frequency of the Reload Opportunities + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetConfLdfq(const MftRegType *obj) +{ + return ((obj->CONF & MFT_CONF_LDFQ_MASK) >> MFT_CONF_LDFQ_SHIFT); +} + +/*! \brief Sets the Frequency of the Reload Opportunities + * + * This function sets the Frequency of the Reload Opportunities. + * The LDFQ[4:0] bits define the number of enabled reload opportunities should happen + * until an enabled reload opportunity becomes a reload point. See Reload Points + * LDFQ = 0: All reload opportunities are reload points. + * LDFQ = 1: There is a reload point each 2 reload oportunities. + * LDFQ = 2: There is a reload point each 3 reload oportunities. + * LDFQ = 3: There is a reload point each 4 reload oportunities. + * This pattern continues up to a maximum of 32 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Frequency of the Reload Opportunities + */ +__attribute__((always_inline)) static inline void MftReg_SetConfLdfq(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CONF; + + tmp &= ~MFT_CONF_LDFQ_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CONF_LDFQ_SHIFT)) & MFT_CONF_LDFQ_MASK); + obj->CONF = tmp; +} + +/*! \brief Gets the Fault Input 3 Polarity + * + * This function gets the current Fault Input 3 Polarity. + * Defines the polarity of the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 3 Polarity + * - 0b : The fault input polarity is active high. A 1 at the fault input indicates a fault. + * - 1b : The fault input polarity is active low. A 0 at the fault input indicates a fault. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltPolFlt3Pol(const MftRegType *obj) +{ + return ((obj->FLTPOL & MFT_FLTPOL_FLT3POL_MASK) >> MFT_FLTPOL_FLT3POL_SHIFT); +} + +/*! \brief Sets the Fault Input 3 Polarity + * + * This function sets the Fault Input 3 Polarity. + * Defines the polarity of the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 3 Polarity + * - 0b : The fault input polarity is active high. A 1 at the fault input indicates a fault. + * - 1b : The fault input polarity is active low. A 0 at the fault input indicates a fault. + */ +__attribute__((always_inline)) static inline void MftReg_SetFltPolFlt3Pol(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTPOL; + + tmp &= ~MFT_FLTPOL_FLT3POL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTPOL_FLT3POL_SHIFT)) & MFT_FLTPOL_FLT3POL_MASK); + obj->FLTPOL = tmp; +} + +/*! \brief Gets the Fault Input 2 Polarity + * + * This function gets the current Fault Input 2 Polarity. + * Defines the polarity of the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 2 Polarity + * - 0b : The fault input polarity is active high. A 1 at the fault input indicates a fault. + * - 1b : The fault input polarity is active low. A 0 at the fault input indicates a fault. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltPolFlt2Pol(const MftRegType *obj) +{ + return ((obj->FLTPOL & MFT_FLTPOL_FLT2POL_MASK) >> MFT_FLTPOL_FLT2POL_SHIFT); +} + +/*! \brief Sets the Fault Input 2 Polarity + * + * This function sets the Fault Input 2 Polarity. + * Defines the polarity of the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 2 Polarity + * - 0b : The fault input polarity is active high. A 1 at the fault input indicates a fault. + * - 1b : The fault input polarity is active low. A 0 at the fault input indicates a fault. + */ +__attribute__((always_inline)) static inline void MftReg_SetFltPolFlt2Pol(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTPOL; + + tmp &= ~MFT_FLTPOL_FLT2POL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTPOL_FLT2POL_SHIFT)) & MFT_FLTPOL_FLT2POL_MASK); + obj->FLTPOL = tmp; +} + +/*! \brief Gets the Fault Input 1 Polarity + * + * This function gets the current Fault Input 1 Polarity. + * Defines the polarity of the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 1 Polarity + * - 0b : The fault input polarity is active high. A 1 at the fault input indicates a fault. + * - 1b : The fault input polarity is active low. A 0 at the fault input indicates a fault. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltPolFlt1Pol(const MftRegType *obj) +{ + return ((obj->FLTPOL & MFT_FLTPOL_FLT1POL_MASK) >> MFT_FLTPOL_FLT1POL_SHIFT); +} + +/*! \brief Sets the Fault Input 1 Polarity + * + * This function sets the Fault Input 1 Polarity. + * Defines the polarity of the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 1 Polarity + * - 0b : The fault input polarity is active high. A 1 at the fault input indicates a fault. + * - 1b : The fault input polarity is active low. A 0 at the fault input indicates a fault. + */ +__attribute__((always_inline)) static inline void MftReg_SetFltPolFlt1Pol(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTPOL; + + tmp &= ~MFT_FLTPOL_FLT1POL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTPOL_FLT1POL_SHIFT)) & MFT_FLTPOL_FLT1POL_MASK); + obj->FLTPOL = tmp; +} + +/*! \brief Gets the Fault Input 0 Polarity + * + * This function gets the current Fault Input 0 Polarity. + * Defines the polarity of the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 0 Polarity + * - 0b : The fault input polarity is active high. A 1 at the fault input indicates a fault. + * - 1b : The fault input polarity is active low. A 0 at the fault input indicates a fault. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltPolFlt0Pol(const MftRegType *obj) +{ + return ((obj->FLTPOL & MFT_FLTPOL_FLT0POL_MASK) >> MFT_FLTPOL_FLT0POL_SHIFT); +} + +/*! \brief Sets the Fault Input 0 Polarity + * + * This function sets the Fault Input 0 Polarity. + * Defines the polarity of the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 0 Polarity + * - 0b : The fault input polarity is active high. A 1 at the fault input indicates a fault. + * - 1b : The fault input polarity is active low. A 0 at the fault input indicates a fault. + */ +__attribute__((always_inline)) static inline void MftReg_SetFltPolFlt0Pol(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTPOL; + + tmp &= ~MFT_FLTPOL_FLT0POL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTPOL_FLT0POL_SHIFT)) & MFT_FLTPOL_FLT0POL_MASK); + obj->FLTPOL = tmp; +} + +/*! \brief Gets the Software output control synchronization is activated by a hardware trigger + * + * This function gets the current Software output control synchronization is activated by a hardware trigger. + * + * \param[in] obj : pointer to MFT register instance + * \return Software output control synchronization is activated by a hardware trigger + * - 0b : A hardware trigger does not activate the SWOCTRL register synchronization. + * - 1b : A hardware trigger activates the SWOCTRL register synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfHwSoc(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_HWSOC_MASK) >> MFT_SYNCONF_HWSOC_SHIFT); +} + +/*! \brief Sets the Software output control synchronization is activated by a hardware trigger + * + * This function sets the Software output control synchronization is activated by a hardware trigger. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Software output control synchronization is activated by a hardware trigger + * - 0b : A hardware trigger does not activate the SWOCTRL register synchronization. + * - 1b : A hardware trigger activates the SWOCTRL register synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfHwSoc(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_HWSOC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_HWSOC_SHIFT)) & MFT_SYNCONF_HWSOC_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the Inverting control synchronization is activated by a hardware trigger + * + * This function gets the current Inverting control synchronization is activated by a hardware trigger. + * + * \param[in] obj : pointer to MFT register instance + * \return Inverting control synchronization is activated by a hardware trigger + * - 0b : A hardware trigger does not activate the INVCTRL register synchronization. + * - 1b : A hardware trigger activates the INVCTRL register synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfHwInvC(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_HWINVC_MASK) >> MFT_SYNCONF_HWINVC_SHIFT); +} + +/*! \brief Sets the Inverting control synchronization is activated by a hardware trigger + * + * This function sets the Inverting control synchronization is activated by a hardware trigger. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Inverting control synchronization is activated by a hardware trigger + * - 0b : A hardware trigger does not activate the INVCTRL register synchronization. + * - 1b : A hardware trigger activates the INVCTRL register synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfHwInvC(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_HWINVC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_HWINVC_SHIFT)) & MFT_SYNCONF_HWINVC_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the Output mask synchronization is activated by a hardware trigger + * + * This function gets the current Output mask synchronization is activated by a hardware trigger. + * + * \param[in] obj : pointer to MFT register instance + * \return Output mask synchronization is activated by a hardware trigger + * - 0b : A hardware trigger does not activate the OUTMASK register synchronization. + * - 1b : A hardware trigger activates the OUTMASK register synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfHwOM(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_HWOM_MASK) >> MFT_SYNCONF_HWOM_SHIFT); +} + +/*! \brief Sets the Output mask synchronization is activated by a hardware trigger + * + * This function sets the Output mask synchronization is activated by a hardware trigger. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Output mask synchronization is activated by a hardware trigger + * - 0b : A hardware trigger does not activate the OUTMASK register synchronization. + * - 1b : A hardware trigger activates the OUTMASK register synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfHwOM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_HWOM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_HWOM_SHIFT)) & MFT_SYNCONF_HWOM_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the MOD, HCR, CNTIN, and CV registers synchronization is activated by a hardware trigger + * + * This function gets the current MOD, HCR, CNTIN, and CV registers synchronization is activated by a hardware trigger. + * + * \param[in] obj : pointer to MFT register instance + * \return MOD, HCR, CNTIN, and CV registers synchronization is activated by a hardware trigger + * - 0b : A hardware trigger does not activate MOD, HCR, CNTIN, and CV registers synchronization. + * - 1b : A hardware trigger activates MOD, HCR, CNTIN, and CV registers synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfHwWrbuf(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_HWWRBUF_MASK) >> MFT_SYNCONF_HWWRBUF_SHIFT); +} + +/*! \brief Sets the MOD, HCR, CNTIN, and CV registers synchronization is activated by a hardware trigger + * + * This function sets the MOD, HCR, CNTIN, and CV registers synchronization is activated by a hardware trigger. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of MOD, HCR, CNTIN, and CV registers synchronization is activated by a hardware trigger + * - 0b : A hardware trigger does not activate MOD, HCR, CNTIN, and CV registers synchronization. + * - 1b : A hardware trigger activates MOD, HCR, CNTIN, and CV registers synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfHwWrbuf(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_HWWRBUF_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_HWWRBUF_SHIFT)) & MFT_SYNCONF_HWWRBUF_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the MFT counter synchronization is activated by a hardware trigger + * + * This function gets the current MFT counter synchronization is activated by a hardware trigger. + * + * \param[in] obj : pointer to MFT register instance + * \return MFT counter synchronization is activated by a hardware trigger + * - 0b : A hardware trigger does not activate the MFT counter synchronization. + * - 1b : A hardware trigger activates the MFT counter synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfHwRstCnt(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_HWRSTCNT_MASK) >> MFT_SYNCONF_HWRSTCNT_SHIFT); +} + +/*! \brief Sets the MFT counter synchronization is activated by a hardware trigger + * + * This function sets the MFT counter synchronization is activated by a hardware trigger. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of MFT counter synchronization is activated by a hardware trigger + * - 0b : A hardware trigger does not activate the MFT counter synchronization. + * - 1b : A hardware trigger activates the MFT counter synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfHwRstCnt(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_HWRSTCNT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_HWRSTCNT_SHIFT)) & MFT_SYNCONF_HWRSTCNT_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the Software output control synchronization is activated by the software trigger + * + * This function gets the current Software output control synchronization is activated by the software trigger. + * + * \param[in] obj : pointer to MFT register instance + * \return Software output control synchronization is activated by the software trigger + * - 0b : The software trigger does not activate the SWOCTRL register synchronization. + * - 1b : The software trigger activates the SWOCTRL register synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfSwSoc(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_SWSOC_MASK) >> MFT_SYNCONF_SWSOC_SHIFT); +} + +/*! \brief Sets the Software output control synchronization is activated by the software trigger + * + * This function sets the Software output control synchronization is activated by the software trigger. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Software output control synchronization is activated by the software trigger + * - 0b : The software trigger does not activate the SWOCTRL register synchronization. + * - 1b : The software trigger activates the SWOCTRL register synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfSwSoc(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_SWSOC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_SWSOC_SHIFT)) & MFT_SYNCONF_SWSOC_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the Inverting control synchronization is activated by the software trigger + * + * This function gets the current Inverting control synchronization is activated by the software trigger. + * + * \param[in] obj : pointer to MFT register instance + * \return Inverting control synchronization is activated by the software trigger + * - 0b : The software trigger does not activate the INVCTRL register synchronization. + * - 1b : The software trigger activates the INVCTRL register synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfSwInvC(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_SWINVC_MASK) >> MFT_SYNCONF_SWINVC_SHIFT); +} + +/*! \brief Sets the Inverting control synchronization is activated by the software trigger + * + * This function sets the Inverting control synchronization is activated by the software trigger. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Inverting control synchronization is activated by the software trigger + * - 0b : The software trigger does not activate the INVCTRL register synchronization. + * - 1b : The software trigger activates the INVCTRL register synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfSwInvC(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_SWINVC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_SWINVC_SHIFT)) & MFT_SYNCONF_SWINVC_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the Output mask synchronization is activated by the software trigger + * + * This function gets the current Output mask synchronization is activated by the software trigger. + * + * \param[in] obj : pointer to MFT register instance + * \return Output mask synchronization is activated by the software trigger + * - 0b : The software trigger does not activate the OUTMASK register synchronization. + * - 1b : The software trigger activates the OUTMASK register synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfSwOM(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_SWOM_MASK) >> MFT_SYNCONF_SWOM_SHIFT); +} + +/*! \brief Sets the Output mask synchronization is activated by the software trigger + * + * This function sets the Output mask synchronization is activated by the software trigger. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Output mask synchronization is activated by the software trigger + * - 0b : The software trigger does not activate the OUTMASK register synchronization. + * - 1b : The software trigger activates the OUTMASK register synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfSwOM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_SWOM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_SWOM_SHIFT)) & MFT_SYNCONF_SWOM_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the MOD, HCR, CNTIN, and CV registers synchronization is activated by the software trigger + * + * This function gets the current MOD, HCR, CNTIN, and CV registers synchronization is activated by the software trigger. + * + * \param[in] obj : pointer to MFT register instance + * \return MOD, HCR, CNTIN, and CV registers synchronization is activated by the software trigger + * - 0b : The software trigger does not activate MOD, HCR, CNTIN, and CV registers synchronization. + * - 1b : The software trigger activates MOD, HCR, CNTIN, and CV registers synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfSwWrbuf(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_SWWRBUF_MASK) >> MFT_SYNCONF_SWWRBUF_SHIFT); +} + +/*! \brief Sets the MOD, HCR, CNTIN, and CV registers synchronization is activated by the software trigger + * + * This function sets the MOD, HCR, CNTIN, and CV registers synchronization is activated by the software trigger. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of MOD, HCR, CNTIN, and CV registers synchronization is activated by the software trigger + * - 0b : The software trigger does not activate MOD, HCR, CNTIN, and CV registers synchronization. + * - 1b : The software trigger activates MOD, HCR, CNTIN, and CV registers synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfSwWrbuf(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_SWWRBUF_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_SWWRBUF_SHIFT)) & MFT_SYNCONF_SWWRBUF_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the MFT counter synchronization is activated by the software trigger + * + * This function gets the current MFT counter synchronization is activated by the software trigger. + * + * \param[in] obj : pointer to MFT register instance + * \return MFT counter synchronization is activated by the software trigger + * - 0b : The software trigger does not activate the MFT counter synchronization. + * - 1b : The software trigger activates the MFT counter synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfSwRstCnt(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_SWRSTCNT_MASK) >> MFT_SYNCONF_SWRSTCNT_SHIFT); +} + +/*! \brief Sets the MFT counter synchronization is activated by the software trigger + * + * This function sets the MFT counter synchronization is activated by the software trigger. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of MFT counter synchronization is activated by the software trigger + * - 0b : The software trigger does not activate the MFT counter synchronization. + * - 1b : The software trigger activates the MFT counter synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfSwRstCnt(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_SWRSTCNT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_SWRSTCNT_SHIFT)) & MFT_SYNCONF_SWRSTCNT_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the Synchronization Mode + * + * This function gets the current Synchronization Mode. + * Selects the PWM Synchronization mode. + * + * \param[in] obj : pointer to MFT register instance + * \return Synchronization Mode + * - 0b : Legacy PWM synchronization is selected. + * - 1b : Enhanced PWM synchronization is selected. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfSyncMode(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_SYNCMODE_MASK) >> MFT_SYNCONF_SYNCMODE_SHIFT); +} + +/*! \brief Sets the Synchronization Mode + * + * This function sets the Synchronization Mode. + * Selects the PWM Synchronization mode. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Synchronization Mode + * - 0b : Legacy PWM synchronization is selected. + * - 1b : Enhanced PWM synchronization is selected. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfSyncMode(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_SYNCMODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_SYNCMODE_SHIFT)) & MFT_SYNCONF_SYNCMODE_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the SWOCTRL Register Synchronization + * + * This function gets the current SWOCTRL Register Synchronization. + * + * \param[in] obj : pointer to MFT register instance + * \return SWOCTRL Register Synchronization + * - 0b : SWOCTRL register is updated with its buffer value at all rising edges of MFT input clock. + * - 1b : SWOCTRL register is updated with its buffer value by the PWM synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfSwOC(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_SWOC_MASK) >> MFT_SYNCONF_SWOC_SHIFT); +} + +/*! \brief Sets the SWOCTRL Register Synchronization + * + * This function sets the SWOCTRL Register Synchronization. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of SWOCTRL Register Synchronization + * - 0b : SWOCTRL register is updated with its buffer value at all rising edges of MFT input clock. + * - 1b : SWOCTRL register is updated with its buffer value by the PWM synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfSwOC(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_SWOC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_SWOC_SHIFT)) & MFT_SYNCONF_SWOC_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the INVCTRL Register Synchronization + * + * This function gets the current INVCTRL Register Synchronization. + * + * \param[in] obj : pointer to MFT register instance + * \return INVCTRL Register Synchronization + * - 0b : INVCTRL register is updated with its buffer value at all rising edges of MFT input clock. + * - 1b : INVCTRL register is updated with its buffer value by the PWM synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfInvC(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_INVC_MASK) >> MFT_SYNCONF_INVC_SHIFT); +} + +/*! \brief Sets the INVCTRL Register Synchronization + * + * This function sets the INVCTRL Register Synchronization. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of INVCTRL Register Synchronization + * - 0b : INVCTRL register is updated with its buffer value at all rising edges of MFT input clock. + * - 1b : INVCTRL register is updated with its buffer value by the PWM synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfInvC(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_INVC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_INVC_SHIFT)) & MFT_SYNCONF_INVC_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the CNTIN Register Synchronization + * + * This function gets the current CNTIN Register Synchronization. + * + * \param[in] obj : pointer to MFT register instance + * \return CNTIN Register Synchronization + * - 0b : CNTIN register is updated with its buffer value at all rising edges of MFT input clock. + * - 1b : CNTIN register is updated with its buffer value by the PWM synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfCntInC(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_CNTINC_MASK) >> MFT_SYNCONF_CNTINC_SHIFT); +} + +/*! \brief Sets the CNTIN Register Synchronization + * + * This function sets the CNTIN Register Synchronization. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of CNTIN Register Synchronization + * - 0b : CNTIN register is updated with its buffer value at all rising edges of MFT input clock. + * - 1b : CNTIN register is updated with its buffer value by the PWM synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfCntInC(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_CNTINC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_CNTINC_SHIFT)) & MFT_SYNCONF_CNTINC_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the Hardware Trigger Mode + * + * This function gets the current Hardware Trigger Mode. + * + * \param[in] obj : pointer to MFT register instance + * \return Hardware Trigger Mode + * - 0b : MFT clears the TRIGj bit when the hardware trigger j is detected, where j = 0, 1,2. + * - 1b : MFT does not clear the TRIGj bit when the hardware trigger j is detected, where j = 0, 1,2. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfHwTrigMode(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_HWTRIGMODE_MASK) >> MFT_SYNCONF_HWTRIGMODE_SHIFT); +} + +/*! \brief Sets the Hardware Trigger Mode + * + * This function sets the Hardware Trigger Mode. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Hardware Trigger Mode + * - 0b : MFT clears the TRIGj bit when the hardware trigger j is detected, where j = 0, 1,2. + * - 1b : MFT does not clear the TRIGj bit when the hardware trigger j is detected, where j = 0, 1,2. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfHwTrigMode(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_HWTRIGMODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_HWTRIGMODE_SHIFT)) & MFT_SYNCONF_HWTRIGMODE_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the Pair Channels 3 Inverting Enable + * + * This function gets the current Pair Channels 3 Inverting Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Pair Channels 3 Inverting Enable + * - 0b : Inverting is disabled. + * - 1b : Inverting is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetInvCtrlInv3En(const MftRegType *obj) +{ + return ((obj->INVCTRL & MFT_INVCTRL_INV3EN_MASK) >> MFT_INVCTRL_INV3EN_SHIFT); +} + +/*! \brief Sets the Pair Channels 3 Inverting Enable + * + * This function sets the Pair Channels 3 Inverting Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Pair Channels 3 Inverting Enable + * - 0b : Inverting is disabled. + * - 1b : Inverting is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetInvCtrlInv3En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->INVCTRL; + + tmp &= ~MFT_INVCTRL_INV3EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_INVCTRL_INV3EN_SHIFT)) & MFT_INVCTRL_INV3EN_MASK); + obj->INVCTRL = tmp; +} + +/*! \brief Gets the Pair Channels 2 Inverting Enable + * + * This function gets the current Pair Channels 2 Inverting Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Pair Channels 2 Inverting Enable + * - 0b : Inverting is disabled. + * - 1b : Inverting is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetInvCtrlInv2En(const MftRegType *obj) +{ + return ((obj->INVCTRL & MFT_INVCTRL_INV2EN_MASK) >> MFT_INVCTRL_INV2EN_SHIFT); +} + +/*! \brief Sets the Pair Channels 2 Inverting Enable + * + * This function sets the Pair Channels 2 Inverting Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Pair Channels 2 Inverting Enable + * - 0b : Inverting is disabled. + * - 1b : Inverting is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetInvCtrlInv2En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->INVCTRL; + + tmp &= ~MFT_INVCTRL_INV2EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_INVCTRL_INV2EN_SHIFT)) & MFT_INVCTRL_INV2EN_MASK); + obj->INVCTRL = tmp; +} + +/*! \brief Gets the Pair Channels 1 Inverting Enable + * + * This function gets the current Pair Channels 1 Inverting Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Pair Channels 1 Inverting Enable + * - 0b : Inverting is disabled. + * - 1b : Inverting is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetInvCtrlInv1En(const MftRegType *obj) +{ + return ((obj->INVCTRL & MFT_INVCTRL_INV1EN_MASK) >> MFT_INVCTRL_INV1EN_SHIFT); +} + +/*! \brief Sets the Pair Channels 1 Inverting Enable + * + * This function sets the Pair Channels 1 Inverting Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Pair Channels 1 Inverting Enable + * - 0b : Inverting is disabled. + * - 1b : Inverting is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetInvCtrlInv1En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->INVCTRL; + + tmp &= ~MFT_INVCTRL_INV1EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_INVCTRL_INV1EN_SHIFT)) & MFT_INVCTRL_INV1EN_MASK); + obj->INVCTRL = tmp; +} + +/*! \brief Gets the Pair Channels 0 Inverting Enable + * + * This function gets the current Pair Channels 0 Inverting Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Pair Channels 0 Inverting Enable + * - 0b : Inverting is disabled. + * - 1b : Inverting is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetInvCtrlInv0En(const MftRegType *obj) +{ + return ((obj->INVCTRL & MFT_INVCTRL_INV0EN_MASK) >> MFT_INVCTRL_INV0EN_SHIFT); +} + +/*! \brief Sets the Pair Channels 0 Inverting Enable + * + * This function sets the Pair Channels 0 Inverting Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Pair Channels 0 Inverting Enable + * - 0b : Inverting is disabled. + * - 1b : Inverting is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetInvCtrlInv0En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->INVCTRL; + + tmp &= ~MFT_INVCTRL_INV0EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_INVCTRL_INV0EN_SHIFT)) & MFT_INVCTRL_INV0EN_MASK); + obj->INVCTRL = tmp; +} + +/*! \brief Gets the Channel 7 Software Output Control Value + * + * This function gets the current Channel 7 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 7 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh7Ocv(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH7OCV_MASK) >> MFT_SWOCTRL_CH7OCV_SHIFT); +} + +/*! \brief Sets the Channel 7 Software Output Control Value + * + * This function sets the Channel 7 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 7 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh7Ocv(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH7OCV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH7OCV_SHIFT)) & MFT_SWOCTRL_CH7OCV_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 6 Software Output Control Value + * + * This function gets the current Channel 6 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 6 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh6Ocv(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH6OCV_MASK) >> MFT_SWOCTRL_CH6OCV_SHIFT); +} + +/*! \brief Sets the Channel 6 Software Output Control Value + * + * This function sets the Channel 6 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 6 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh6Ocv(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH6OCV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH6OCV_SHIFT)) & MFT_SWOCTRL_CH6OCV_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 5 Software Output Control Value + * + * This function gets the current Channel 5 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 5 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh5Ocv(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH5OCV_MASK) >> MFT_SWOCTRL_CH5OCV_SHIFT); +} + +/*! \brief Sets the Channel 5 Software Output Control Value + * + * This function sets the Channel 5 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 5 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh5Ocv(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH5OCV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH5OCV_SHIFT)) & MFT_SWOCTRL_CH5OCV_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 4 Software Output Control Value + * + * This function gets the current Channel 4 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 4 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh4Ocv(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH4OCV_MASK) >> MFT_SWOCTRL_CH4OCV_SHIFT); +} + +/*! \brief Sets the Channel 4 Software Output Control Value + * + * This function sets the Channel 4 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 4 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh4Ocv(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH4OCV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH4OCV_SHIFT)) & MFT_SWOCTRL_CH4OCV_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 3 Software Output Control Value + * + * This function gets the current Channel 3 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 3 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh3Ocv(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH3OCV_MASK) >> MFT_SWOCTRL_CH3OCV_SHIFT); +} + +/*! \brief Sets the Channel 3 Software Output Control Value + * + * This function sets the Channel 3 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 3 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh3Ocv(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH3OCV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH3OCV_SHIFT)) & MFT_SWOCTRL_CH3OCV_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 2 Software Output Control Value + * + * This function gets the current Channel 2 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 2 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh2Ocv(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH2OCV_MASK) >> MFT_SWOCTRL_CH2OCV_SHIFT); +} + +/*! \brief Sets the Channel 2 Software Output Control Value + * + * This function sets the Channel 2 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 2 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh2Ocv(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH2OCV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH2OCV_SHIFT)) & MFT_SWOCTRL_CH2OCV_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 1 Software Output Control Value + * + * This function gets the current Channel 1 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 1 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh1Ocv(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH1OCV_MASK) >> MFT_SWOCTRL_CH1OCV_SHIFT); +} + +/*! \brief Sets the Channel 1 Software Output Control Value + * + * This function sets the Channel 1 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 1 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh1Ocv(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH1OCV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH1OCV_SHIFT)) & MFT_SWOCTRL_CH1OCV_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 0 Software Output Control Value + * + * This function gets the current Channel 0 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 0 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh0Ocv(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH0OCV_MASK) >> MFT_SWOCTRL_CH0OCV_SHIFT); +} + +/*! \brief Sets the Channel 0 Software Output Control Value + * + * This function sets the Channel 0 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 0 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh0Ocv(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH0OCV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH0OCV_SHIFT)) & MFT_SWOCTRL_CH0OCV_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 7 Software Output Control Enable + * + * This function gets the current Channel 7 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 7 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh7Oc(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH7OC_MASK) >> MFT_SWOCTRL_CH7OC_SHIFT); +} + +/*! \brief Sets the Channel 7 Software Output Control Enable + * + * This function sets the Channel 7 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 7 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh7Oc(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH7OC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH7OC_SHIFT)) & MFT_SWOCTRL_CH7OC_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 6 Software Output Control Enable + * + * This function gets the current Channel 6 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 6 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh6Oc(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH6OC_MASK) >> MFT_SWOCTRL_CH6OC_SHIFT); +} + +/*! \brief Sets the Channel 6 Software Output Control Enable + * + * This function sets the Channel 6 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 6 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh6Oc(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH6OC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH6OC_SHIFT)) & MFT_SWOCTRL_CH6OC_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 5 Software Output Control Enable + * + * This function gets the current Channel 5 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 5 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh5Oc(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH5OC_MASK) >> MFT_SWOCTRL_CH5OC_SHIFT); +} + +/*! \brief Sets the Channel 5 Software Output Control Enable + * + * This function sets the Channel 5 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 5 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh5Oc(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH5OC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH5OC_SHIFT)) & MFT_SWOCTRL_CH5OC_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 4 Software Output Control Enable + * + * This function gets the current Channel 4 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 4 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh4Oc(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH4OC_MASK) >> MFT_SWOCTRL_CH4OC_SHIFT); +} + +/*! \brief Sets the Channel 4 Software Output Control Enable + * + * This function sets the Channel 4 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 4 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh4Oc(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH4OC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH4OC_SHIFT)) & MFT_SWOCTRL_CH4OC_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 3 Software Output Control Enable + * + * This function gets the current Channel 3 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 3 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh3Oc(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH3OC_MASK) >> MFT_SWOCTRL_CH3OC_SHIFT); +} + +/*! \brief Sets the Channel 3 Software Output Control Enable + * + * This function sets the Channel 3 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 3 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh3Oc(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH3OC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH3OC_SHIFT)) & MFT_SWOCTRL_CH3OC_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 2 Software Output Control Enable + * + * This function gets the current Channel 2 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 2 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh2Oc(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH2OC_MASK) >> MFT_SWOCTRL_CH2OC_SHIFT); +} + +/*! \brief Sets the Channel 2 Software Output Control Enable + * + * This function sets the Channel 2 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 2 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh2Oc(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH2OC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH2OC_SHIFT)) & MFT_SWOCTRL_CH2OC_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 1 Software Output Control Enable + * + * This function gets the current Channel 1 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 1 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh1Oc(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH1OC_MASK) >> MFT_SWOCTRL_CH1OC_SHIFT); +} + +/*! \brief Sets the Channel 1 Software Output Control Enable + * + * This function sets the Channel 1 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 1 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh1Oc(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH1OC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH1OC_SHIFT)) & MFT_SWOCTRL_CH1OC_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 0 Software Output Control Enable + * + * This function gets the current Channel 0 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 0 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh0Oc(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH0OC_MASK) >> MFT_SWOCTRL_CH0OC_SHIFT); +} + +/*! \brief Sets the Channel 0 Software Output Control Enable + * + * This function sets the Channel 0 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 0 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh0Oc(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH0OC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH0OC_SHIFT)) & MFT_SWOCTRL_CH0OC_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Sets the Global Load OK + * + * This function sets the Global Load OK. + * This bit controls the global load mechanism. + * It generates a pulse at MFT module global load output with one MFT clock cycle width, + * which is used to set LDOK bits of MFT and other modules (including other MFTs). + * This bit is self-cleared and read value is always zero. + * The global load mechanism depends on SoC specific information. Refer to MFT SoC specific information to more details. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Global Load OK + * - 0b : No action. + * - 1b : LDOK bit is set. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadGLdOk(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_GLDOK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_GLDOK_SHIFT)) & MFT_PWMLOAD_GLDOK_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Global Load Enable + * + * This function gets the current Global Load Enable. + * This bit enables the global load mechanism implemented by GLDOK. If GLEN bit is set, then an external + * event on the MFT global load input sets the LDOK bit. The clear of the LDOK bit is done by CPU writes '0' + * to the bit. + * + * \param[in] obj : pointer to MFT register instance + * \return Global Load Enable + * - 0b : Global Load Ok disabled. + * - 1b : Global Load OK enabled. A pulse event on the module global load input sets the LDOK bit. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadGLEn(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_GLEN_MASK) >> MFT_PWMLOAD_GLEN_SHIFT); +} + +/*! \brief Sets the Global Load Enable + * + * This function sets the Global Load Enable. + * This bit enables the global load mechanism implemented by GLDOK. If GLEN bit is set, then an external + * event on the MFT global load input sets the LDOK bit. The clear of the LDOK bit is done by CPU writes '0' + * to the bit. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Global Load Enable + * - 0b : Global Load Ok disabled. + * - 1b : Global Load OK enabled. A pulse event on the module global load input sets the LDOK bit. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadGLEn(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_GLEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_GLEN_SHIFT)) & MFT_PWMLOAD_GLEN_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Load Enable + * + * This function gets the current Load Enable. + * Enables the loading of the MOD, CNTIN, HCR and CV registers with the values of their buffers. + * The LDOK bit can also be set by the Global Load mechanism if GLEN bit is enabled. + * + * \param[in] obj : pointer to MFT register instance + * \return Load Enable + * - 0b : Loading updated values is disabled. + * - 1b : Loading updated values is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadLdOk(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_LDOK_MASK) >> MFT_PWMLOAD_LDOK_SHIFT); +} + +/*! \brief Sets the Load Enable + * + * This function sets the Load Enable. + * Enables the loading of the MOD, CNTIN, HCR and CV registers with the values of their buffers. + * The LDOK bit can also be set by the Global Load mechanism if GLEN bit is enabled. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Load Enable + * - 0b : Loading updated values is disabled. + * - 1b : Loading updated values is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadLdOk(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_LDOK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_LDOK_SHIFT)) & MFT_PWMLOAD_LDOK_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Half Cycle Select + * + * This function gets the current Half Cycle Select. + * This bit enables the half cycle match as a reload oportunity. A half cycle is defined by when the MFT + * counter matches the HCR register. + * + * \param[in] obj : pointer to MFT register instance + * \return Half Cycle Select + * - 0b : Half cycle reload is disabled and it is not considered as a reload opportunity. + * - 1b : Half cycle reload is enabled and it is considered as a reload opportunity. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadHCSel(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_HCSEL_MASK) >> MFT_PWMLOAD_HCSEL_SHIFT); +} + +/*! \brief Sets the Half Cycle Select + * + * This function sets the Half Cycle Select. + * This bit enables the half cycle match as a reload oportunity. A half cycle is defined by when the MFT + * counter matches the HCR register. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Half Cycle Select + * - 0b : Half cycle reload is disabled and it is not considered as a reload opportunity. + * - 1b : Half cycle reload is enabled and it is considered as a reload opportunity. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadHCSel(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_HCSEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_HCSEL_SHIFT)) & MFT_PWMLOAD_HCSEL_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Channel 7 Select + * + * This function gets the current Channel 7 Select. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 7 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadCh7Sel(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_CH7SEL_MASK) >> MFT_PWMLOAD_CH7SEL_SHIFT); +} + +/*! \brief Sets the Channel 7 Select + * + * This function sets the Channel 7 Select. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 7 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadCh7Sel(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_CH7SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_CH7SEL_SHIFT)) & MFT_PWMLOAD_CH7SEL_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Channel 6 Select + * + * This function gets the current Channel 6 Select. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 6 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadCh6Sel(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_CH6SEL_MASK) >> MFT_PWMLOAD_CH6SEL_SHIFT); +} + +/*! \brief Sets the Channel 6 Select + * + * This function sets the Channel 6 Select. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 6 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadCh6Sel(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_CH6SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_CH6SEL_SHIFT)) & MFT_PWMLOAD_CH6SEL_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Channel 5 Select + * + * This function gets the current Channel 5 Select. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 5 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadCh5Sel(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_CH5SEL_MASK) >> MFT_PWMLOAD_CH5SEL_SHIFT); +} + +/*! \brief Sets the Channel 5 Select + * + * This function sets the Channel 5 Select. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 5 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadCh5Sel(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_CH5SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_CH5SEL_SHIFT)) & MFT_PWMLOAD_CH5SEL_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Channel 4 Select + * + * This function gets the current Channel 4 Select. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 4 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadCh4Sel(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_CH4SEL_MASK) >> MFT_PWMLOAD_CH4SEL_SHIFT); +} + +/*! \brief Sets the Channel 4 Select + * + * This function sets the Channel 4 Select. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 4 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadCh4Sel(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_CH4SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_CH4SEL_SHIFT)) & MFT_PWMLOAD_CH4SEL_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Channel 3 Select + * + * This function gets the current Channel 3 Select. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 3 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadCh3Sel(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_CH3SEL_MASK) >> MFT_PWMLOAD_CH3SEL_SHIFT); +} + +/*! \brief Sets the Channel 3 Select + * + * This function sets the Channel 3 Select. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 3 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadCh3Sel(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_CH3SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_CH3SEL_SHIFT)) & MFT_PWMLOAD_CH3SEL_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Channel 2 Select + * + * This function gets the current Channel 2 Select. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 2 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadCh2Sel(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_CH2SEL_MASK) >> MFT_PWMLOAD_CH2SEL_SHIFT); +} + +/*! \brief Sets the Channel 2 Select + * + * This function sets the Channel 2 Select. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 2 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadCh2Sel(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_CH2SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_CH2SEL_SHIFT)) & MFT_PWMLOAD_CH2SEL_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Channel 1 Select + * + * This function gets the current Channel 1 Select. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 1 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadCh1Sel(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_CH1SEL_MASK) >> MFT_PWMLOAD_CH1SEL_SHIFT); +} + +/*! \brief Sets the Channel 1 Select + * + * This function sets the Channel 1 Select. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 1 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadCh1Sel(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_CH1SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_CH1SEL_SHIFT)) & MFT_PWMLOAD_CH1SEL_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Channel 0 Select + * + * This function gets the current Channel 0 Select. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 0 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadCh0Sel(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_CH0SEL_MASK) >> MFT_PWMLOAD_CH0SEL_SHIFT); +} + +/*! \brief Sets the Channel 0 Select + * + * This function sets the Channel 0 Select. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 0 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadCh0Sel(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_CH0SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_CH0SEL_SHIFT)) & MFT_PWMLOAD_CH0SEL_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Half Cycle Value + * + * This function gets the current Half Cycle Value. + * + * \param[in] obj : pointer to MFT register instance + * \return Half Cycle Value + */ +__attribute__((always_inline)) static inline uint16_t MftReg_GetHcrHCVal(const MftRegType *obj) +{ + return ((obj->HCR & MFT_HCR_HCVAL_MASK) >> MFT_HCR_HCVAL_SHIFT); +} + +/*! \brief Sets the Half Cycle Value + * + * This function sets the Half Cycle Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Half Cycle Value + */ +__attribute__((always_inline)) static inline void MftReg_SetHcrHCVal(MftRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->HCR; + + tmp &= ~MFT_HCR_HCVAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_HCR_HCVAL_SHIFT)) & MFT_HCR_HCVAL_MASK); + obj->HCR = tmp; +} + +/*! \brief Gets the Extended Deadtime Value + * + * This function gets the current Extended Deadtime Value. + * This field is a bit extension of the DTVAL field. It defines the 4 most significant bits of the deadtime value. + * The maximum deadtime value is extended to 1023 using the concatenation {DTVALEX, DTVAL}. + * Deadtime insert value = (DTPS * {DTVALEX, DTVAL}). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] pairIndex : the pair index + * \return Extended Deadtime Value + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPairDeadTimeDtValEx(const MftRegType *obj, uint8_t pairIndex) +{ + return ((obj->PAIR[pairIndex].DEADTIME & MFT_PAIR_DEADTIME_DTVALEX_MASK) >> MFT_PAIR_DEADTIME_DTVALEX_SHIFT); +} + +/*! \brief Sets the Extended Deadtime Value + * + * This function sets the Extended Deadtime Value. + * This field is a bit extension of the DTVAL field. It defines the 4 most significant bits of the deadtime value. + * The maximum deadtime value is extended to 1023 using the concatenation {DTVALEX, DTVAL}. + * Deadtime insert value = (DTPS * {DTVALEX, DTVAL}). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] pairIndex : the pair index + * \param[in] value : the value of Extended Deadtime Value + */ +__attribute__((always_inline)) static inline void MftReg_SetPairDeadTimeDtValEx(MftRegType *obj, uint8_t pairIndex, uint8_t value) +{ + uint32_t tmp = obj->PAIR[pairIndex].DEADTIME; + + tmp &= ~MFT_PAIR_DEADTIME_DTVALEX_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PAIR_DEADTIME_DTVALEX_SHIFT)) & MFT_PAIR_DEADTIME_DTVALEX_MASK); + obj->PAIR[pairIndex].DEADTIME = tmp; +} + +/*! \brief Gets the Deadtime Prescaler Value + * + * This function gets the current Deadtime Prescaler Value. + * Selects the division factor of the MFT input clock. This prescaled clock is used by the deadtime counter. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] pairIndex : the pair index + * \return Deadtime Prescaler Value + * - 0xb : Divide the MFT input clock by 1. + * - 10b : Divide the MFT input clock by 4. + * - 11b : Divide the MFT input clock by 16. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPairDeadTimeDtPs(const MftRegType *obj, uint8_t pairIndex) +{ + return ((obj->PAIR[pairIndex].DEADTIME & MFT_PAIR_DEADTIME_DTPS_MASK) >> MFT_PAIR_DEADTIME_DTPS_SHIFT); +} + +/*! \brief Sets the Deadtime Prescaler Value + * + * This function sets the Deadtime Prescaler Value. + * Selects the division factor of the MFT input clock. This prescaled clock is used by the deadtime counter. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] pairIndex : the pair index + * \param[in] value : the value of Deadtime Prescaler Value + * - 0xb : Divide the MFT input clock by 1. + * - 10b : Divide the MFT input clock by 4. + * - 11b : Divide the MFT input clock by 16. + */ +__attribute__((always_inline)) static inline void MftReg_SetPairDeadTimeDtPs(MftRegType *obj, uint8_t pairIndex, uint8_t value) +{ + uint32_t tmp = obj->PAIR[pairIndex].DEADTIME; + + tmp &= ~MFT_PAIR_DEADTIME_DTPS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PAIR_DEADTIME_DTPS_SHIFT)) & MFT_PAIR_DEADTIME_DTPS_MASK); + obj->PAIR[pairIndex].DEADTIME = tmp; +} + +/*! \brief Gets the Deadtime Value + * + * This function gets the current Deadtime Value. + * Selects the deadtime value. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] pairIndex : the pair index + * \return Deadtime Value + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPairDeadTimeDtVal(const MftRegType *obj, uint8_t pairIndex) +{ + return ((obj->PAIR[pairIndex].DEADTIME & MFT_PAIR_DEADTIME_DTVAL_MASK) >> MFT_PAIR_DEADTIME_DTVAL_SHIFT); +} + +/*! \brief Sets the Deadtime Value + * + * This function sets the Deadtime Value. + * Selects the deadtime value. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] pairIndex : the pair index + * \param[in] value : the value of Deadtime Value + */ +__attribute__((always_inline)) static inline void MftReg_SetPairDeadTimeDtVal(MftRegType *obj, uint8_t pairIndex, uint8_t value) +{ + uint32_t tmp = obj->PAIR[pairIndex].DEADTIME; + + tmp &= ~MFT_PAIR_DEADTIME_DTVAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PAIR_DEADTIME_DTVAL_SHIFT)) & MFT_PAIR_DEADTIME_DTVAL_MASK); + obj->PAIR[pairIndex].DEADTIME = tmp; +} + +/*! \brief Gets the Mirror of the Modulo Integer Value + * + * This function gets the current Mirror of the Modulo Integer Value. + * See the field MOD of the register MOD + * + * \param[in] obj : pointer to MFT register instance + * \return Mirror of the Modulo Integer Value + */ +__attribute__((always_inline)) static inline uint16_t MftReg_GetModMirrorModM(const MftRegType *obj) +{ + return ((obj->MOD_MIRROR & MFT_MOD_MIRROR_MOD_M_MASK) >> MFT_MOD_MIRROR_MOD_M_SHIFT); +} + +/*! \brief Sets the Mirror of the Modulo Integer Value + * + * This function sets the Mirror of the Modulo Integer Value. + * See the field MOD of the register MOD + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Mirror of the Modulo Integer Value + */ +__attribute__((always_inline)) static inline void MftReg_SetModMirrorModM(MftRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->MOD_MIRROR; + + tmp &= ~MFT_MOD_MIRROR_MOD_M_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_MOD_MIRROR_MOD_M_SHIFT)) & MFT_MOD_MIRROR_MOD_M_MASK); + obj->MOD_MIRROR = tmp; +} + +/*! \brief Gets the Modulo Fractional Value + * + * This function gets the current Modulo Fractional Value. + * The modulo fractional value is used in the PWM period dithering. + * This value is added to an internal accumulator at the end of each PWM period. + * Writes to the field FRACMOD are done on its write buffer. + * The FRACMOD is updated with its write buffer value according to Registers updated from write buffers. + * If MFTEN = 0, a write to SC register resets manually this write coherency mechanism + * + * \param[in] obj : pointer to MFT register instance + * \return Modulo Fractional Value + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetModMirrorFracModM(const MftRegType *obj) +{ + return ((obj->MOD_MIRROR & MFT_MOD_MIRROR_FRACMOD_M_MASK) >> MFT_MOD_MIRROR_FRACMOD_M_SHIFT); +} + +/*! \brief Sets the Modulo Fractional Value + * + * This function sets the Modulo Fractional Value. + * The modulo fractional value is used in the PWM period dithering. + * This value is added to an internal accumulator at the end of each PWM period. + * Writes to the field FRACMOD are done on its write buffer. + * The FRACMOD is updated with its write buffer value according to Registers updated from write buffers. + * If MFTEN = 0, a write to SC register resets manually this write coherency mechanism + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Modulo Fractional Value + */ +__attribute__((always_inline)) static inline void MftReg_SetModMirrorFracModM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MOD_MIRROR; + + tmp &= ~MFT_MOD_MIRROR_FRACMOD_M_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_MOD_MIRROR_FRACMOD_M_SHIFT)) & MFT_MOD_MIRROR_FRACMOD_M_MASK); + obj->MOD_MIRROR = tmp; +} + +/*! \brief Gets the Mirror of the Channel Match Integer Value + * + * This function gets the current Mirror of the Channel Match Integer Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Mirror of the Channel Match Integer Value + */ +__attribute__((always_inline)) static inline uint16_t MftReg_GetCvMirrorValM(const MftRegType *obj, uint8_t channel) +{ + return ((obj->MIRROR[channel].CV & MFT_CV_MIRROR_VAL_M_MASK) >> MFT_CV_MIRROR_VAL_M_SHIFT); +} + +/*! \brief Sets the Mirror of the Channel Match Integer Value + * + * This function sets the Mirror of the Channel Match Integer Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of Mirror of the Channel Match Integer Value + */ +__attribute__((always_inline)) static inline void MftReg_SetCvMirrorValM(MftRegType *obj, uint8_t channel, uint16_t value) +{ + uint32_t tmp = obj->MIRROR[channel].CV; + + tmp &= ~MFT_CV_MIRROR_VAL_M_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CV_MIRROR_VAL_M_SHIFT)) & MFT_CV_MIRROR_VAL_M_MASK); + obj->MIRROR[channel].CV = tmp; +} + +/*! \brief Gets the Channel Match Fractional Value + * + * This function gets the current Channel Match Fractional Value. + * The channel match fractional value is used in the PWM edge dithering. + * This value is added to the channel internal accumulator at the end of each PWM period. + * Writes to the field FRACVAL are done on its write buffer. + * The FRACVAL is updated with its write buffer value according to Registers updated from write buffers. + * If MFTEN = 0, a write to CnSC register resets manually this write coherency mechanism + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Channel Match Fractional Value + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCvMirrorFracVal(const MftRegType *obj, uint8_t channel) +{ + return ((obj->MIRROR[channel].CV & MFT_CV_MIRROR_FRACVAL_MASK) >> MFT_CV_MIRROR_FRACVAL_SHIFT); +} + +/*! \brief Sets the Channel Match Fractional Value + * + * This function sets the Channel Match Fractional Value. + * The channel match fractional value is used in the PWM edge dithering. + * This value is added to the channel internal accumulator at the end of each PWM period. + * Writes to the field FRACVAL are done on its write buffer. + * The FRACVAL is updated with its write buffer value according to Registers updated from write buffers. + * If MFTEN = 0, a write to CnSC register resets manually this write coherency mechanism + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of Channel Match Fractional Value + */ +__attribute__((always_inline)) static inline void MftReg_SetCvMirrorFracVal(MftRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->MIRROR[channel].CV; + + tmp &= ~MFT_CV_MIRROR_FRACVAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CV_MIRROR_FRACVAL_SHIFT)) & MFT_CV_MIRROR_FRACVAL_MASK); + obj->MIRROR[channel].CV = tmp; +} + +/*! \brief Gets the Channel Output Enable Signal + * + * This function gets the current Channel Output Enable Signal. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel Output Enable Signal + * - 0b : The MFT channel output is put to safe state when the MFT counter is enabled and the MFT + * channel output is enabled by Fault Control (MFT_MODE[FAULTM]!=2'b00 and + * MFT_FLTCTRL[FSTATE]=1'b0) and PWM is enabled (MFT_SC[PWMENn] = 1'b1). + * Otherwise the channel output is tristated. + * - 1b : The MFT channel output state is retained when the channel is in output mode. + * The output channel is tristated when the channel is in input capture [DECAPEN=1'b0, COMBINE=1'b0, + * MSnB:MSnA=2'b00] or dual edge capture mode [DECAPEN=1'b1]. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSimObeObe(const MftRegType *obj) +{ + return ((obj->SIM_OBE & MFT_SIM_OBE_OBE_MASK) >> MFT_SIM_OBE_OBE_SHIFT); +} + +/*! \brief Sets the Channel Output Enable Signal + * + * This function sets the Channel Output Enable Signal. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel Output Enable Signal + * - 0b : The MFT channel output is put to safe state when the MFT counter is enabled and the MFT + * channel output is enabled by Fault Control (MFT_MODE[FAULTM]!=2'b00 and + * MFT_FLTCTRL[FSTATE]=1'b0) and PWM is enabled (MFT_SC[PWMENn] = 1'b1). Otherwise the + * channel output is tristated. + * - 1b : The MFT channel output state is retained when the channel is in output mode. The output + * channel is tristated when the channel is in input capture [DECAPEN=1'b0, COMBINE=1'b0, + * MSnB:MSnA=2'b00] or dual edge capture mode [DECAPEN=1'b1]. + */ +__attribute__((always_inline)) static inline void MftReg_SetSimObeObe(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SIM_OBE; + + tmp &= ~MFT_SIM_OBE_OBE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SIM_OBE_OBE_SHIFT)) & MFT_SIM_OBE_OBE_MASK); + obj->SIM_OBE = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _MFT_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/mpu_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/mpu_reg.h new file mode 100644 index 0000000..8c3da35 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/mpu_reg.h @@ -0,0 +1,1082 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MPU_REG_H_ +#define _MPU_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the MPU Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +/* Error Value */ +#define MPU_RES_ERR (0xFFu) +/* Size of Reserved Registers Arrays */ +#define MPU_REG_EADR_RESEERVED_CONUT (3) +#define MPU_REG_RGDN_RESEERVED_CONUT (0x38) +#define MPU_REG_AACN_RESEERVED_CONUT (0x20) + + +/* Size of Slave Port Arrays */ +#define MPU_SLVPORT_COUNT (2) + +/* Size of Region Descption Arrays */ +#define MPU_REGIONDESC_COUNT (8) + +/* Size of Region Descption Alternate Access Control Arrays */ +#define MPU_REGIONDESCAAC_COUNT (8) + +/* Slave Port Number Set */ +#define MPU_SLVPORT3 (3) +#define MPU_SLVPORT2 (2) +#define MPU_SLVPORT1 (1) +#define MPU_SLVPORT0 (0) + +/* CESR Bit Fields */ +#define MPU_CESR_VLD_MASK (0x1u) +#define MPU_CESR_VLD_SHIFT (0u) +#define MPU_CESR_VLD_WIDTH (1u) +#define MPU_CESR_NRGD_MASK (0xF00u) +#define MPU_CESR_NRGD_SHIFT (8u) +#define MPU_CESR_NRGD_WIDTH (4u) +#define MPU_CESR_NSP_MASK (0xF000u) +#define MPU_CESR_NSP_SHIFT (12u) +#define MPU_CESR_NSP_WIDTH (4u) +#define MPU_CESR_HRL_MASK (0xF0000u) +#define MPU_CESR_HRL_SHIFT (16u) +#define MPU_CESR_HRL_WIDTH (4u) +#define MPU_CESR_SPERR3_MASK (0x10000000u) +#define MPU_CESR_SPERR3_SHIFT (28u) +#define MPU_CESR_SPERR3_WIDTH (1u) +#define MPU_CESR_SPERR2_MASK (0x20000000u) +#define MPU_CESR_SPERR2_SHIFT (29u) +#define MPU_CESR_SPERR2_WIDTH (1u) +#define MPU_CESR_SPERR1_MASK (0x40000000u) +#define MPU_CESR_SPERR1_SHIFT (30u) +#define MPU_CESR_SPERR1_WIDTH (1u) +#define MPU_CESR_SPERR0_MASK (0x80000000u) +#define MPU_CESR_SPERR0_SHIFT (31u) +#define MPU_CESR_SPERR0_WIDTH (1u) + +/* EARn(0~3) Bit Fields */ +#define MPU_EAR_EADDR_MASK (0xFFFFFFFFu) +#define MPU_EAR_EADDR_SHIFT (0u) +#define MPU_EAR_EADDR_WIDTH (32u) + +/* EDRn(0~3) Bit Fields */ +#define MPU_EDR_ERW_MASK (0x1u) +#define MPU_EDR_ERW_SHIFT (0u) +#define MPU_EDR_ERW_WIDTH (1u) +#define MPU_EDR_EATTR_MASK (0xEu) +#define MPU_EDR_EATTR_SHIFT (1u) +#define MPU_EDR_EATTR_WIDTH (3u) +#define MPU_EDR_EMN_MASK (0xF0u) +#define MPU_EDR_EMN_SHIFT (4u) +#define MPU_EDR_EMN_WIDTH (4u) +#define MPU_EDR_EPID_MASK (0xFF00u) +#define MPU_EDR_EPID_SHIFT (8u) +#define MPU_EDR_EPID_WIDTH (8u) +#define MPU_EDR_EACD_MASK (0xFFFF0000u) +#define MPU_EDR_EACD_SHIFT (16u) +#define MPU_EDR_EACD_WIDTH (16u) + +/* RGDn_WD0(0~15) Bit Fields */ +#define MPU_RGD_WD0_SRTADDR_MASK (0xFFFFFFE0u) +#define MPU_RGD_WD0_SRTADDR_SHIFT (0u) +#define MPU_RGD_WD0_SRTADDR_WIDTH (27u) + +/* RGDn_WD1(0~15) Bit Fields */ +#define MPU_RGD_WD1_ENDADDR_MASK (0xFFFFFFE0u) +#define MPU_RGD_WD1_ENDADDR_SHIFT (0u) +#define MPU_RGD_WD1_ENDADDR_WIDTH (27u) + +/* RGDn_WD2(0~15) Bit Fields */ +#define MPU_RGD_WD2_M0UM_MASK (0x7u) +#define MPU_RGD_WD2_M0UM_SHIFT (0u) +#define MPU_RGD_WD2_M0UM_WIDTH (3u) +#define MPU_RGD_WD2_M0SM_MASK (0x18u) +#define MPU_RGD_WD2_M0SM_SHIFT (3u) +#define MPU_RGD_WD2_M0SM_WIDTH (2u) +#define MPU_RGD_WD2_M0PE_MASK (0x20u) +#define MPU_RGD_WD2_M0PE_SHIFT (5u) +#define MPU_RGD_WD2_M0PE_WIDTH (1u) +#define MPU_RGD_WD2_M1UM_MASK (0x1C0u) +#define MPU_RGD_WD2_M1UM_SHIFT (6u) +#define MPU_RGD_WD2_M1UM_WIDTH (3u) +#define MPU_RGD_WD2_M1SM_MASK (0x600u) +#define MPU_RGD_WD2_M1SM_SHIFT (9u) +#define MPU_RGD_WD2_M1SM_WIDTH (2u) +#define MPU_RGD_WD2_M1PE_MASK (0x800u) +#define MPU_RGD_WD2_M1PE_SHIFT (11u) +#define MPU_RGD_WD2_M1PE_WIDTH (1u) +#define MPU_RGD_WD2_M2UM_MASK (0x7000u) +#define MPU_RGD_WD2_M2UM_SHIFT (12u) +#define MPU_RGD_WD2_M2UM_WIDTH (3u) +#define MPU_RGD_WD2_M2SM_MASK (0x18000u) +#define MPU_RGD_WD2_M2SM_SHIFT (15u) +#define MPU_RGD_WD2_M2SM_WIDTH (2u) +#define MPU_RGD_WD2_M3UM_MASK (0x1C0000u) +#define MPU_RGD_WD2_M3UM_SHIFT (18u) +#define MPU_RGD_WD2_M3UM_WIDTH (3u) +#define MPU_RGD_WD2_M3SM_MASK (0x600000u) +#define MPU_RGD_WD2_M3SM_SHIFT (21u) +#define MPU_RGD_WD2_M3SM_WIDTH (2u) + +/* RGDn_WD3(0~15) Bit Fields */ +#define MPU_RGD_WD3_VLD_MASK (0x1u) +#define MPU_RGD_WD3_VLD_SHIFT (0u) +#define MPU_RGD_WD3_VLD_WIDTH (1u) +#define MPU_RGD_WD3_PIDMASK_MASK (0xFF0000u) +#define MPU_RGD_WD3_PIDMASK_SHIFT (16u) +#define MPU_RGD_WD3_PIDMASK_WIDTH (8u) +#define MPU_RGD_WD3_PID_MASK (0xFF000000u) +#define MPU_RGD_WD3_PID_SHIFT (24u) +#define MPU_RGD_WD3_PID_WIDTH (8u) + +/* RGDAAC(0~15) Bit Fields */ +#define MPU_RGDAAC_M0UM_MASK (0x7u) +#define MPU_RGDAAC_M0UM_SHIFT (0u) +#define MPU_RGDAAC_M0UM_WIDTH (3u) +#define MPU_RGDAAC_M0SM_MASK (0x18u) +#define MPU_RGDAAC_M0SM_SHIFT (3u) +#define MPU_RGDAAC_M0SM_WIDTH (2u) +#define MPU_RGDAAC_M0PE_MASK (0x20u) +#define MPU_RGDAAC_M0PE_SHIFT (5u) +#define MPU_RGDAAC_M0PE_WIDTH (1u) +#define MPU_RGDAAC_M1UM_MASK (0x1C0u) +#define MPU_RGDAAC_M1UM_SHIFT (6u) +#define MPU_RGDAAC_M1UM_WIDTH (3u) +#define MPU_RGDAAC_M1SM_MASK (0x600u) +#define MPU_RGDAAC_M1SM_SHIFT (9u) +#define MPU_RGDAAC_M1SM_WIDTH (2u) +#define MPU_RGDAAC_M1PE_MASK (0x800u) +#define MPU_RGDAAC_M1PE_SHIFT (11u) +#define MPU_RGDAAC_M1PE_WIDTH (1u) +#define MPU_RGDAAC_M2UM_MASK (0x7000u) +#define MPU_RGDAAC_M2UM_SHIFT (12u) +#define MPU_RGDAAC_M2UM_WIDTH (3u) +#define MPU_RGDAAC_M2SM_MASK (0x18000u) +#define MPU_RGDAAC_M2SM_SHIFT (15u) +#define MPU_RGDAAC_M2SM_WIDTH (2u) +#define MPU_RGDAAC_M3UM_MASK (0x1C0000u) +#define MPU_RGDAAC_M3UM_SHIFT (18u) +#define MPU_RGDAAC_M3UM_WIDTH (3u) +#define MPU_RGDAAC_M3SM_MASK (0x600000u) +#define MPU_RGDAAC_M3SM_SHIFT (21u) +#define MPU_RGDAAC_M3SM_WIDTH (3u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of MPU registers + */ +typedef struct _MpuRegType_ +{ + volatile uint32_t CESR; /*!< Control, Error info and Mpu Enable Register, offset: 0x0 */ + uint32_t RESERVED0[MPU_REG_EADR_RESEERVED_CONUT]; /* Reserved Register, offset: 0x04, array step: 0x0C */ + struct + { /*!< offset: 0x10, array step: 0x08 */ + const volatile uint32_t EAR; /*!< Slave Port Error Register Address, offset: 0x10, array step: 0x08 */ + const volatile uint32_t EDR; /*!< Slave Port Error Detail Register, offset: 0x14, array step: 0x08 */ + } SLVPORT[MPU_SLVPORT_COUNT]; + uint32_t RESERVED1[MPU_REG_RGDN_RESEERVED_CONUT]; + struct + { /*!< offset: 0x100, array step: 0x10 */ + volatile uint32_t WORD0; /*!< Value of Access Start Register Address, offset: 0x100, array step: 0x10 */ + volatile uint32_t WORD1; /*!< Value of Access End Register Address, offset : 0x104, array step: 0x10 */ + volatile uint32_t WORD2; /*!< Configure of Master Access Rights Register, offset: 0x108, array step: 0x10 */ + volatile uint32_t WORD3; /*!< Configure of PID, PID Mask and Region Description valid, offset: 0x10C, array step: 0x10 */ + } RGD[MPU_REGIONDESC_COUNT]; + uint32_t RESERVED2[MPU_REG_AACN_RESEERVED_CONUT]; + volatile uint32_t + AAC[MPU_REGIONDESC_COUNT]; /*!< Configure of Master Alternate Access Rights Register, offset: 0x200, array step: 0x04 */ +} MpuRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ +/*! \brief Enables the MPU module. + * + * This function enables the functional of MPU module + * + * \param[in] obj : pointer to MPU register instance + * \param[in] enable State + * - 1 : Enable the MPU module. + * - 0 : Disable the MPU module. + * \return None + */ +__attribute__((always_inline)) static inline void MpuReg_GlobalEnable(MpuRegType *obj, uint8_t enable) +{ + uint32_t tmp = obj->CESR; + + tmp &= ~MPU_CESR_VLD_MASK; + tmp |= (((uint32_t)(enable ? 1u << MPU_CESR_VLD_SHIFT : 0u << MPU_CESR_VLD_SHIFT)) & MPU_CESR_VLD_MASK); + obj->CESR = tmp; +} + +/*! \brief Get MPU module status. + * + * This function get the functional of MPU module status + * + * \param[in] obj : pointer to MPU register instance + * \return MPU Global Enable valid or invalid + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetMpuGlobalEnableStatus(const MpuRegType *obj) +{ + return ((obj->CESR & MPU_CESR_VLD_MASK) >> MPU_CESR_VLD_SHIFT); +} + +/*! \brief Get Number of Region Description. + * + * This function get the Number of Region Description. + * + * \param[in] obj : pointer to MPU register instance + * \return the current command of debug mode + * - 0 : 8 of Region Description + * - 1 : 12 of Region Description + * - 2 : 16 of Region Description + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetNumOfRegionDesc(const MpuRegType *obj) +{ + return ((obj->CESR & MPU_CESR_NRGD_MASK) >> MPU_CESR_NRGD_SHIFT); +} + +/*! \brief Get Number of Slave Port. + * + * This function get the Number of Slave Port. + * + * \param[in] obj : pointer to MPU register instance + * \return the Number of Slave Port + * - 4 : default value is 4, other values are undefined + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetNumOfSlavePort(const MpuRegType *obj) +{ + return ((obj->CESR & MPU_CESR_NSP_MASK) >> MPU_CESR_NSP_SHIFT); +} + +/*! \brief Get Hardware Revision Level. + * + * This function get the Get Hardware Revision Level. + * + * \param[in] obj : pointer to MPU register instance + * \return the Hardware Revision Level + * - 1 : version of this chip + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetHwOfRevLvl(const MpuRegType *obj) +{ + return ((obj->CESR & MPU_CESR_HRL_MASK) >> MPU_CESR_HRL_SHIFT); +} + +/*! \brief Get Slave Port Error Status. + * + * This function get the Slave Port Error Status. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] port : set number of port + * \return the Hardware Revision Level + * - 1 : An error has occurred for slave port + * * - 0 : None error has occurred for slave port + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetSlvPortErrStatus(const MpuRegType *obj, uint8_t port) +{ + switch(port) + { + case MPU_SLVPORT3: + return ((obj->CESR & MPU_CESR_SPERR3_MASK) >> MPU_CESR_SPERR3_SHIFT); + case MPU_SLVPORT2: + return ((obj->CESR & MPU_CESR_SPERR2_MASK) >> MPU_CESR_SPERR2_SHIFT); + case MPU_SLVPORT1: + return ((obj->CESR & MPU_CESR_SPERR1_MASK) >> MPU_CESR_SPERR1_SHIFT); + case MPU_SLVPORT0: + return ((obj->CESR & MPU_CESR_SPERR0_MASK) >> MPU_CESR_SPERR0_SHIFT); + default: + return MPU_RES_ERR; + } +} + +/*! \brief Clear Slave Port Error status. + * + * This function clear the Slave Port Error Status. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] port : set number of port + */ +__attribute__((always_inline)) static inline void MpuReg_ClrSlvPortErrStatus(MpuRegType *obj, uint8_t port) +{ + switch(port) + { + case MPU_SLVPORT3: + obj->CESR |= MPU_CESR_SPERR3_MASK; + break; + case MPU_SLVPORT2: + obj->CESR |= MPU_CESR_SPERR2_MASK; + break; + case MPU_SLVPORT1: + obj->CESR |= MPU_CESR_SPERR1_MASK; + break; + case MPU_SLVPORT0: + obj->CESR |= MPU_CESR_SPERR0_MASK; + break; + default: + break; + } +} + +/*! \brief Get Slave Port Error Address. + * + * This function get the Slave Port Error Address. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] port : set number of port + * \return Error Address + * An error has occurred for slave port, return error address + */ +__attribute__((always_inline)) static inline uint32_t MpuReg_GetSlvPortErrAddr(const MpuRegType *obj, uint8_t port) +{ + return ((obj->SLVPORT[port].EAR & MPU_EAR_EADDR_MASK) >> MPU_EAR_EADDR_SHIFT); +} + +/*! \brief Get Slave Port Error Detail Type R/W. + * + * This function get the Slave Port Error Detail Type R/W. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] port : set number of port + * \return Error Type for R/W + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetSlvPortErrDetailERW(const MpuRegType *obj, uint8_t port) +{ + return ((obj->SLVPORT[port].EDR & MPU_EDR_ERW_MASK) >> MPU_EDR_ERW_SHIFT); +} + +/*! \brief Get Slave Port Error Detail Type Attribute. + * + * This function get the Slave Port Error Detail Type Attribute. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] port : set number of port + * \return Error Type for Attribute + * - 0 : Mode - User, Access - Instruction + * - 1 : Mode - User, Access - Data + * - 2 : Mode - privilege, Access - Instruction + * - 3 : Mode - privilege, Access - Data + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetSlvPortErrDetailEAttr(const MpuRegType *obj, uint8_t port) +{ + return ((obj->SLVPORT[port].EDR & MPU_EDR_EATTR_MASK) >> MPU_EDR_EATTR_SHIFT); +} + +/*! \brief Get Slave Port Error Detail Type ErrMasterNumber. + * + * This function get the Slave Port Error Detail Type ErrMasterNumber. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] port : set number of port + * \return Error Type for ErrMasterNumber + * - 0 : CPU CORE + * - 1 : DEBUG + * - 2 : CPU CORE + * - 3 : CPU CORE + * - 4 : DMA + * - 5 : CSE + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetSlvPortErrDetailEMN(const MpuRegType *obj, uint8_t port) +{ + return ((obj->SLVPORT[port].EDR & MPU_EDR_EMN_MASK) >> MPU_EDR_EMN_SHIFT); +} + +/*! \brief Get Error Process ID + * + * This function record error process identification. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] port : set number of port + * \return Error Type for Error Process ID Number. + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetSlvPortErrPID(const MpuRegType *obj, uint8_t port) +{ + return ((obj->SLVPORT[port].EDR & MPU_EDR_EPID_MASK) >> MPU_EDR_EPID_SHIFT); +} + +/*! \brief Get Access Region Error Description. + * + * This function record error process identification. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] port : set number of port + * \return Access Error Description. + * - 0 : Hit none region + * - one bit set : Hit protect single unoverlapping description + * - multi bit set : Hit protect multi overlapping description + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetSlvPortEACD(const MpuRegType *obj, uint8_t port) +{ + return (uint8_t)((obj->SLVPORT[port].EDR & MPU_EDR_EACD_MASK) >> MPU_EDR_EACD_SHIFT); +} + +/*! \brief Set Region Description Start Address. + * + * This function set region description start address. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] startAddr : protect start address + * \param[in] regDescNumber : Region Description number set + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetRegionDescStartAddr(MpuRegType *obj, uint32_t startAddr, uint8_t regDescNum) +{ + uint32_t tmp = obj->RGD[regDescNum].WORD0; + + tmp &= ~MPU_RGD_WD0_SRTADDR_MASK; + tmp |= (((uint32_t)((uint32_t)startAddr << MPU_RGD_WD0_SRTADDR_SHIFT)) & MPU_RGD_WD0_SRTADDR_MASK); + obj->RGD[regDescNum].WORD0 = tmp; +} + +/*! \brief Get Region Description Start Address. + * + * This function get region description start address. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] startAddr : protect start address + * \return current region description protect start address + * + */ +__attribute__((always_inline)) static inline uint32_t MpuReg_GetRegionDescStartAddr(const MpuRegType *obj, uint8_t regDescNum) +{ + return ((obj->RGD[regDescNum].WORD0 & MPU_RGD_WD0_SRTADDR_MASK) >> MPU_RGD_WD0_SRTADDR_SHIFT); +} + +/*! \brief Set Region Description End Address. + * + * This function set region description end address. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] endAddr : protect end address + * \param[in] regDescNum : Region Description number set + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetRegionDescEndAddr(MpuRegType *obj, uint32_t endAddr, uint8_t regDescNum) +{ + uint32_t tmp = obj->RGD[regDescNum].WORD1; + + tmp &= ~MPU_RGD_WD1_ENDADDR_MASK; + tmp |= (((uint32_t)((uint32_t)endAddr << MPU_RGD_WD1_ENDADDR_SHIFT)) & MPU_RGD_WD1_ENDADDR_MASK); + obj->RGD[regDescNum].WORD1 = tmp; +} + +/*! \brief Get Region Description End Address. + * + * This function get region description end address. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] endAddr : protect start address + * \return current region description protect end address + * + */ +__attribute__((always_inline)) static inline uint32_t MpuReg_GetRegionDescEndAddr(const MpuRegType *obj, uint8_t regDescNum) +{ + return ((obj->RGD[regDescNum].WORD1 & MPU_RGD_WD1_ENDADDR_MASK) >> MPU_RGD_WD1_ENDADDR_SHIFT); +} + +/*! \brief Set Region Description User Bus Masterx Authority mode. + * + * This function set region description user bus master authority mode. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master number + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * - 2 : Bus Master2 + * - 3 : Bus Master3 + * \param[in] userMode : Configure Masterx Access Authority bit[0/1/2] + * - 0 : Try to access may abort by error, and do not excute Access + * - 1 : Access will be grant + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetRegionDescUserAuthority(MpuRegType *obj, uint8_t regDescNum, uint8_t masterNo, uint8_t userMode) +{ + uint32_t tmp = obj->RGD[regDescNum].WORD2; + + switch(masterNo) + { + case 0: + tmp &= ~MPU_RGD_WD2_M0UM_MASK; /*!< Bus Master0 User mode */ + tmp |= (((uint32_t)((uint32_t)userMode << MPU_RGD_WD2_M0UM_SHIFT)) & MPU_RGD_WD2_M0UM_MASK); + obj->RGD[regDescNum].WORD2 = tmp; + break; + case 1: + tmp &= ~MPU_RGD_WD2_M1UM_MASK; /*!< Bus Master1 User mode */ + tmp |= (((uint32_t)((uint32_t)userMode << MPU_RGD_WD2_M1UM_SHIFT)) & MPU_RGD_WD2_M1UM_MASK); + obj->RGD[regDescNum].WORD2 = tmp; + break; + case 2: + tmp &= ~MPU_RGD_WD2_M2UM_MASK; /*!< Bus Master2 User mode */ + tmp |= (((uint32_t)((uint32_t)userMode << MPU_RGD_WD2_M2UM_SHIFT)) & MPU_RGD_WD2_M2UM_MASK); + obj->RGD[regDescNum].WORD2 = tmp; + break; + case 3: + tmp &= ~MPU_RGD_WD2_M3UM_MASK; /*!< Bus Master3 User mode */ + tmp |= (((uint32_t)((uint32_t)userMode << MPU_RGD_WD2_M3UM_SHIFT)) & MPU_RGD_WD2_M3UM_MASK); + obj->RGD[regDescNum].WORD2 = tmp; + break; + default: + break; + } +} + +/*! \brief Get Region Description User Bus Masterx Authority mode. + * + * This function get region description user bus master authority mode. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master number + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * - 2 : Bus Master2 + * - 3 : Bus Master3 + * \return Masterx Access Authority bit[0/1/2] + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetRegionDescUserAuthority(const MpuRegType *obj, uint8_t regDescNum, uint8_t masterNo) +{ + switch(masterNo) + { + case 0: + return ((obj->RGD[regDescNum].WORD2 & MPU_RGD_WD2_M0UM_MASK) >> MPU_RGD_WD2_M0UM_SHIFT); /*!< Bus Master0 User mode */ + case 1: + return ((obj->RGD[regDescNum].WORD2 & MPU_RGD_WD2_M1UM_MASK) >> MPU_RGD_WD2_M1UM_SHIFT); /*!< Bus Master1 User mode */ + case 2: + return ((obj->RGD[regDescNum].WORD2 & MPU_RGD_WD2_M2UM_MASK) >> MPU_RGD_WD2_M2UM_SHIFT); /*!< Bus Master2 User mode */ + case 3: + return ((obj->RGD[regDescNum].WORD2 & MPU_RGD_WD2_M3UM_MASK) >> MPU_RGD_WD2_M3UM_SHIFT); /*!< Bus Master3 User mode */ + default: + return MPU_RES_ERR; + } +} + +/*! \brief Set Region Description Privilege Bus Masterx Authority mode. + * + * This function set region description privilege bus master authority mode. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master number + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * - 2 : Bus Master2 + * - 3 : Bus Master3 + * \param[in] userMode : Configure Masterx Access Authority + * - 0 : R/W/X + * - 1 : R/X + * - 2 : R/W + * - 3 : same as user masterx + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetRegionDescPrivilegeAuthority(MpuRegType *obj, uint8_t regDescNum, uint8_t masterNo, uint8_t privilegeMode) +{ + uint32_t tmp = obj->RGD[regDescNum].WORD2; + + switch(masterNo) + { + case 0: + tmp &= ~MPU_RGD_WD2_M0SM_MASK; /*!< Bus Master0 Privilege mode */ + tmp |= (((uint32_t)((uint32_t)privilegeMode << MPU_RGD_WD2_M0SM_SHIFT)) & MPU_RGD_WD2_M0SM_MASK); + obj->RGD[regDescNum].WORD2 = tmp; + break; + case 1: + tmp &= ~MPU_RGD_WD2_M1SM_MASK; /*!< Bus Master1 Privilege mode */ + tmp |= (((uint32_t)((uint32_t)privilegeMode << MPU_RGD_WD2_M1SM_SHIFT)) & MPU_RGD_WD2_M1SM_MASK); + obj->RGD[regDescNum].WORD2 = tmp; + break; + case 2: + tmp &= ~MPU_RGD_WD2_M2SM_MASK; /*!< Bus Master2 Privilege mode */ + tmp |= (((uint32_t)((uint32_t)privilegeMode << MPU_RGD_WD2_M2SM_SHIFT)) & MPU_RGD_WD2_M2SM_MASK); + obj->RGD[regDescNum].WORD2 = tmp; + break; + case 3: + tmp &= ~MPU_RGD_WD2_M3SM_MASK; /*!< Bus Master3 Privilege mode */ + tmp |= (((uint32_t)((uint32_t)privilegeMode << MPU_RGD_WD2_M3SM_SHIFT)) & MPU_RGD_WD2_M3SM_MASK); + obj->RGD[regDescNum].WORD2 = tmp; + break; + default: + break; + } +} + +/*! \brief Get Region Description Privilege Bus Masterx Authority mode. + * + * This function get region description privilege bus master authority mode. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master number + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * - 2 : Bus Master2 + * - 3 : Bus Master3 + * \return Masterx Access Authority + * - 0 : R/W/X + * - 1 : R/X + * - 2 : R/W + * - 3 : same as user masterx + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetRegionDescPrivilegeAuthority(const MpuRegType *obj, uint8_t regDescNum, uint8_t masterNo) +{ + switch(masterNo) + { + case 0: + return ((obj->RGD[regDescNum].WORD2 & MPU_RGD_WD2_M0SM_MASK) >> MPU_RGD_WD2_M0SM_SHIFT); /*!< Bus Master0 Privilege mode */ + case 1: + return ((obj->RGD[regDescNum].WORD2 & MPU_RGD_WD2_M1SM_MASK) >> MPU_RGD_WD2_M1SM_SHIFT); /*!< Bus Master1 Privilege mode */ + case 2: + return ((obj->RGD[regDescNum].WORD2 & MPU_RGD_WD2_M2SM_MASK) >> MPU_RGD_WD2_M2SM_SHIFT); /*!< Bus Master2 Privilege mode */ + case 3: + return ((obj->RGD[regDescNum].WORD2 & MPU_RGD_WD2_M3SM_MASK) >> MPU_RGD_WD2_M3SM_SHIFT); /*!< Bus Master3 Privilege mode */ + default: + return MPU_RES_ERR; + } +} + +/*! \brief Set Evaluate if Processing include PID. + * + * This function set evaluate if processing include Process Identification. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master number + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * \param[in] pidMode : Configure Evaluate Process + * - 0 : Evaluate processing do not include PID + * - 1 : Evaluate processing include PID + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetRegionDescPIDFlagEnable(MpuRegType *obj, uint8_t regDescNum, uint8_t masterNo, uint8_t pidMode) +{ + uint32_t tmp = obj->RGD[regDescNum].WORD2; + + switch(masterNo) + { + case 0: + tmp &= ~MPU_RGD_WD2_M0PE_MASK; /*!< Bus Master0 PID mode */ + tmp |= (((uint32_t)((uint32_t)pidMode << MPU_RGD_WD2_M0PE_SHIFT)) & MPU_RGD_WD2_M0PE_MASK); + obj->RGD[regDescNum].WORD2 = tmp; + break; + case 1: + tmp &= ~MPU_RGD_WD2_M1PE_MASK; /*!< Bus Master1 PID mode */ + tmp |= (((uint32_t)((uint32_t)pidMode << MPU_RGD_WD2_M1PE_SHIFT)) & MPU_RGD_WD2_M1PE_MASK); + obj->RGD[regDescNum].WORD2 = tmp; + break; + default: + break; + } +} + +/*! \brief Get Evaluate Processing include PID. + * + * This function get evaluate processing include Process Identification. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master number + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * \return Evaluate Process + * - 0 : Evaluate processing do not include PID + * - 1 : Evaluate processing include PID + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetRegionDescPIDFlagEnableStatus(const MpuRegType *obj, uint8_t regDescNum, uint8_t masterNo) +{ + switch(masterNo) + { + case 0: + return ((obj->RGD[regDescNum].WORD2 & MPU_RGD_WD2_M0PE_MASK) >> MPU_RGD_WD2_M0PE_SHIFT); /*!< Bus Master0 PID mode */ + case 1: + return ((obj->RGD[regDescNum].WORD2 & MPU_RGD_WD2_M1PE_MASK) >> MPU_RGD_WD2_M1PE_SHIFT); /*!< Bus Master1 PID mode */ + default: + return MPU_RES_ERR; + } +} + +/*! \brief Set Region Description valid or invalid. + * + * This function set region description valid or not. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] valid : Configure Region Description + * - 0 : Region Description invalid + * - 1 : Region Description valid + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetRegionDescValid(MpuRegType *obj, uint8_t regDescNum, uint8_t valid) +{ + uint32_t tmp = obj->RGD[regDescNum].WORD3; + + tmp &= ~MPU_RGD_WD3_VLD_MASK; + tmp |= (((uint32_t)((uint32_t)valid << MPU_RGD_WD3_VLD_SHIFT)) & MPU_RGD_WD3_VLD_MASK); + obj->RGD[regDescNum].WORD3 = tmp; +} + +/*! \brief Get Region Description valid or invalid. + * + * This function get region description valid or not. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \return Region Description + * - 0 : Region Description invalid + * - 1 : Region Description valid + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetRegionDescValid(const MpuRegType *obj, uint8_t regDescNum) +{ + return ((obj->RGD[regDescNum].WORD3 & MPU_RGD_WD3_VLD_MASK) >> MPU_RGD_WD3_VLD_SHIFT); +} + +/*! \brief Set Processing Identification Mask. + * + * This function set processing identification mask. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] PIDMask : Configure Processing ID Mask + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetPIDMask(MpuRegType *obj, uint8_t regDescNum, uint8_t pidMask) +{ + uint32_t tmp = obj->RGD[regDescNum].WORD3; + + tmp &= ~MPU_RGD_WD3_PIDMASK_MASK; + tmp |= (((uint32_t)((uint32_t)pidMask << MPU_RGD_WD3_PIDMASK_SHIFT)) & MPU_RGD_WD3_PIDMASK_MASK); + obj->RGD[regDescNum].WORD3 = tmp; +} + +/*! \brief Get Processing Identification Mask. + * + * This function get processing identification mask. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \return Processing ID Mask value + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetPIDMask(const MpuRegType *obj, uint8_t regDescNum) +{ + return ((obj->RGD[regDescNum].WORD3 & MPU_RGD_WD3_PIDMASK_MASK) >> MPU_RGD_WD3_PIDMASK_SHIFT); +} + +/*! \brief Set Processing Identification. + * + * This function set processing identification. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] PID : Configure Processing ID Mask + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetPID(MpuRegType *obj, uint8_t regDescNum, uint8_t pid) +{ + uint32_t tmp = obj->RGD[regDescNum].WORD3; + + tmp &= ~MPU_RGD_WD3_PID_MASK; + tmp |= (((uint32_t)((uint32_t)pid << MPU_RGD_WD3_PID_SHIFT)) & MPU_RGD_WD3_PID_MASK); + obj->RGD[regDescNum].WORD3 = tmp; +} + +/*! \brief Get Processing Identification. + * + * This function get processing identification. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \return Processing ID value + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetPID(const MpuRegType *obj, uint8_t regDescNum) +{ + return ((obj->RGD[regDescNum].WORD3 & MPU_RGD_WD3_PID_MASK) >> MPU_RGD_WD3_PID_SHIFT); +} + +/*! \brief Set Region Description Alternate Access Control User Bus Masterx Authority mode. + * + * This function set region description alternate access control user bus master authority mode. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master Num + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * - 2 : Bus Master2 + * - 3 : Bus Master3 + * \param[in] aacUserMode : Configure Masterx Access Authority bit[0/1/2] + * - 0 : Try to access may abort by error, and do not excute Access + * - 1 : Access will be grant + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetRegionDescAACUserAuthority(MpuRegType *obj, uint8_t aacChnNum, uint8_t masterNo, uint8_t aacUserMode) +{ + uint32_t tmp = obj->AAC[aacChnNum]; + + switch(masterNo) + { + case 0: + tmp &= ~MPU_RGDAAC_M0UM_MASK; /*!< AAC Master0 User mode */ + tmp |= (((uint32_t)((uint32_t)aacUserMode << MPU_RGDAAC_M0UM_SHIFT)) & MPU_RGDAAC_M0UM_MASK); + obj->AAC[aacChnNum] = tmp; + break; + case 1: + tmp &= ~MPU_RGDAAC_M1UM_MASK; /*!< AAC Master1 User mode */ + tmp |= (((uint32_t)((uint32_t)aacUserMode << MPU_RGDAAC_M1UM_SHIFT)) & MPU_RGDAAC_M1UM_MASK); + obj->AAC[aacChnNum] = tmp; + break; + case 2: + tmp &= ~MPU_RGDAAC_M2UM_MASK; /*!< AAC Master2 User mode */ + tmp |= (((uint32_t)((uint32_t)aacUserMode << MPU_RGDAAC_M2UM_SHIFT)) & MPU_RGDAAC_M2UM_MASK); + obj->AAC[aacChnNum] = tmp; + break; + case 3: + tmp &= ~MPU_RGDAAC_M3UM_MASK; /*!< AAC Master2 User mode */ + tmp |= (((uint32_t)((uint32_t)aacUserMode << MPU_RGDAAC_M3UM_SHIFT)) & MPU_RGDAAC_M3UM_MASK); + obj->AAC[aacChnNum] = tmp; + break; + default: + break; + } +} + +/*! \brief Get Region Description Alternate Access Control User Bus Masterx Authority mode. + * + * This function get region description alternate access control user bus master authority mode. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master number + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * - 2 : Bus Master2 + * - 3 : Bus Master3 + * \return Masterx Access Authority bit[0/1/2] + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetRegionDescAACUserAuthority(const MpuRegType *obj, uint8_t aacChnNum, uint8_t masterNo) +{ + switch(masterNo) + { + case 0: + return (uint8_t)((obj->AAC[aacChnNum] & MPU_RGDAAC_M0UM_MASK) >> MPU_RGDAAC_M0UM_SHIFT); /*!< AAC Master0 User mode */ + case 1: + return (uint8_t)((obj->AAC[aacChnNum] & MPU_RGDAAC_M1UM_MASK) >> MPU_RGDAAC_M1UM_SHIFT); /*!< AAC Master1 User mode */ + case 2: + return (uint8_t)((obj->AAC[aacChnNum] & MPU_RGDAAC_M2UM_MASK) >> MPU_RGDAAC_M2UM_SHIFT); /*!< AAC Master2 User mode */ + case 3: + return (uint8_t)((obj->AAC[aacChnNum] & MPU_RGDAAC_M3UM_MASK) >> MPU_RGDAAC_M3UM_SHIFT); /*!< AAC Master3 User mode */ + default: + return MPU_RES_ERR; + } +} + +/*! \brief Set Region Description Alternate Access Control Privilege Bus Masterx Authority mode. + * + * This function set region description alternate access control privilege bus master authority mode. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master number + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * - 2 : Bus Master2 + * - 3 : Bus Master3 + * \param[in] aacPrivilegeMode : Configure Masterx Access Authority + * - 0 : R/W/X + * - 1 : R/X + * - 2 : R/W + * - 3 : same as user masterx + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetRegionDescAACPrivilegeAuthority(MpuRegType *obj, + uint8_t aacChnNum, + uint8_t masterNo, + uint8_t aacPrivilegeMode) +{ + uint32_t tmp = obj->AAC[aacChnNum]; + + switch(masterNo) + { + case 0: + tmp &= ~MPU_RGDAAC_M0SM_MASK; /*!< AAC Bus Master0 Privilege mode */ + tmp |= (((uint32_t)((uint32_t)aacPrivilegeMode << MPU_RGDAAC_M0SM_SHIFT)) & MPU_RGDAAC_M0SM_MASK); + obj->AAC[aacChnNum] = tmp; + break; + case 1: + tmp &= ~MPU_RGDAAC_M1SM_MASK; /*!< AAC Bus Master1 Privilege mode */ + tmp |= (((uint32_t)((uint32_t)aacPrivilegeMode << MPU_RGDAAC_M1SM_SHIFT)) & MPU_RGDAAC_M1SM_MASK); + obj->AAC[aacChnNum] = tmp; + break; + case 2: + tmp &= ~MPU_RGDAAC_M2SM_MASK; /*!< AAC Bus Master2 Privilege mode */ + tmp |= (((uint32_t)((uint32_t)aacPrivilegeMode << MPU_RGDAAC_M2SM_SHIFT)) & MPU_RGDAAC_M2SM_MASK); + obj->AAC[aacChnNum] = tmp; + break; + case 3: + tmp &= ~MPU_RGDAAC_M3SM_MASK; /*!< AAC Bus Master3 Privilege mode */ + tmp |= (((uint32_t)((uint32_t)aacPrivilegeMode << MPU_RGDAAC_M3SM_SHIFT)) & MPU_RGDAAC_M3SM_MASK); + obj->AAC[aacChnNum] = tmp; + break; + default: + break; + } +} + +/*! \brief Get Region Description Alternate Access Control Privilege Bus Masterx Authority mode. + * + * This function get region description alternate access control privilege bus master authority mode. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master Num + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * - 2 : Bus Master2 + * - 3 : Bus Master3 + * \return Masterx Access Authority + * - 0 : R/W/X + * - 1 : R/X + * - 2 : R/W + * - 3 : same as user masterx + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetRegionDescAACPrivilegeAuthority(const MpuRegType *obj, uint8_t aacChnNum, uint8_t masterNo) +{ + switch(masterNo) + { + case 0: + return ((obj->AAC[aacChnNum] & MPU_RGDAAC_M0SM_MASK) >> MPU_RGDAAC_M0SM_SHIFT); /*!< AAC Bus Master0 Privilege mode */ + case 1: + return ((obj->AAC[aacChnNum] & MPU_RGDAAC_M1SM_MASK) >> MPU_RGDAAC_M1SM_SHIFT); /*!< AAC Bus Master1 Privilege mode */ + case 2: + return ((obj->AAC[aacChnNum] & MPU_RGDAAC_M2SM_MASK) >> MPU_RGDAAC_M2SM_SHIFT); /*!< AAC Bus Master2 Privilege mode */ + case 3: + return ((obj->AAC[aacChnNum] & MPU_RGDAAC_M3SM_MASK) >> MPU_RGDAAC_M3SM_SHIFT); /*!< AAC Bus Master3 Privilege mode */ + default: + return MPU_RES_ERR; + } +} + +/*! \brief Set Evaluate Alternate Access Control if Processing include PID. + * + * This function set evaluate alternate access control if processing include Process Identification. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master number + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * \param[in] aacPIDMode : Configure Evaluate Process + * - 0 : Evaluate processing do not include PID + * - 1 : Evaluate processing include PID + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetRegionDescAACPIDFlagEnable(MpuRegType *obj, uint8_t aacChnNum, uint8_t masterNo, uint8_t aacPIDMode) +{ + uint32_t tmp = obj->AAC[aacChnNum]; + + switch(masterNo) + { + case 0: + tmp &= ~MPU_RGDAAC_M0PE_MASK; /*!< AAC Bus Master0 PID mode */ + tmp |= (((uint32_t)((uint32_t)aacPIDMode << MPU_RGDAAC_M0PE_SHIFT)) & MPU_RGDAAC_M0PE_MASK); + obj->AAC[aacChnNum] = tmp; + break; + case 1: + tmp &= ~MPU_RGDAAC_M1PE_MASK; /*!< AAC Bus Master1 PID mode */ + tmp |= (((uint32_t)((uint32_t)aacPIDMode << MPU_RGDAAC_M1PE_SHIFT)) & MPU_RGDAAC_M1PE_MASK); + obj->AAC[aacChnNum] = tmp; + break; + default: + break; + } +} + +/*! \brief Get Evaluate Alternate Access Control Processing include PID. + * + * This function get evaluate alternate access control processing include Process Identification. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master number + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * \return Evaluate Process + - 0 : Evaluate processing do not include PID + * - 1 : Evaluate processing include PID + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetRegionDescAACPIDFlagEnableStatus(const MpuRegType *obj, uint8_t aacChnNum, uint8_t masterNo) +{ + switch(masterNo) + { + case 0: + return ((obj->AAC[aacChnNum] & MPU_RGDAAC_M0PE_MASK) >> MPU_RGDAAC_M0PE_SHIFT); /*!< AAC Bus Master0 PID mode */ + case 1: + return ((obj->AAC[aacChnNum] & MPU_RGDAAC_M0PE_MASK) >> MPU_RGDAAC_M0PE_SHIFT); /*!< AAC Bus Master1 PID mode */ + default: + return MPU_RES_ERR; + } +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _MPU_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/mscm_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/mscm_reg.h new file mode 100644 index 0000000..298fdca --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/mscm_reg.h @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MSCM_REG_H_ +#define _MSCM_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the MSCM Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* CPU_TYPE Bit Fields */ +#define MSCM_CPU_TYPE_TYPE_MASK (0xFFFFFF00u) +#define MSCM_CPU_TYPE_TYPE_SHIFT (8u) +#define MSCM_CPU_TYPE_TYPE_WIDTH (24u) +#define MSCM_CPU_TYPE_REVISION_MASK (0xFFu) +#define MSCM_CPU_TYPE_REVISION_SHIFT (0u) +#define MSCM_CPU_TYPE_REVISION_WIDTH (8u) + +/* CPU_NUM Bit Fields */ +#define MSCM_CPU_NUM_CPNX_MASK (0x01u) +#define MSCM_CPU_NUM_CPNX_SHIFT (0u) +#define MSCM_CPU_NUM_CPNX_WIDTH (1u) + +/* CPU_CNT Bit Fields */ +#define MSCM_CPU_CNT_PCNT_MASK (0x03u) +#define MSCM_CPU_CNT_PCNT_SHIFT (0u) +#define MSCM_CPU_CNT_PCNT_WIDTH (2u) + +/* CPU_CACHE Bit Fields */ +#define MSCM_CPU_CACHE_ICACHE_SIZE_MASK (0xFF000000u) +#define MSCM_CPU_CACHE_ICACHE_SIZE_SHIFT (24u) +#define MSCM_CPU_CACHE_ICACHE_SIZE_WIDTH (8u) +#define MSCM_CPU_CACHE_ICACHE_WAYS_MASK (0xFF0000u) +#define MSCM_CPU_CACHE_ICACHE_WAYS_SHIFT (16u) +#define MSCM_CPU_CACHE_ICACHE_WAYS_WIDTH (8u) +#define MSCM_CPU_CACHE_DCACHE_SIZE_MASK (0xFF00u) +#define MSCM_CPU_CACHE_DCACHE_SIZE_SHIFT (8u) +#define MSCM_CPU_CACHE_DCACHE_SIZE_WIDTH (8u) +#define MSCM_CPU_CACHE_DCACHE_WAYS_MASK (0xFFu) +#define MSCM_CPU_CACHE_DCACHE_WAYS_SHIFT (0u) +#define MSCM_CPU_CACHE_DCACHE_WAYS_WIDTH (8u) + +/* CPU_MEM Bit Fields */ +#define MSCM_CPU_MEM_SRAMU_SIZE_MASK (0xFF000000u) +#define MSCM_CPU_MEM_SRAMU_SIZE_SHIFT (24u) +#define MSCM_CPU_MEM_SRAMU_SIZE_WIDTH (8u) +#define MSCM_CPU_MEM_SRAML_SIZE_MASK (0xFF00u) +#define MSCM_CPU_MEM_SRAML_SIZE_SHIFT (8u) +#define MSCM_CPU_MEM_SRAML_SIZE_WIDTH (8u) + +/* CPU_CFG Bit Fields */ +#define MSCM_CPU_CFG_BUS_PORTS_MASK (0x300u) +#define MSCM_CPU_CFG_BUS_PORTS_SHIFT (8u) +#define MSCM_CPU_CFG_BUS_PORTS_WIDTH (2u) +#define MSCM_CPU_CFG_BB_MASK (0x40u) +#define MSCM_CPU_CFG_BB_SHIFT (6u) +#define MSCM_CPU_CFG_BB_WIDTH (1u) +#define MSCM_CPU_CFG_SMPU_MASK (0x20u) +#define MSCM_CPU_CFG_SMPU_SHIFT (5u) +#define MSCM_CPU_CFG_SMPU_WIDTH (1u) +#define MSCM_CPU_CFG_MMU_MASK (0x10u) +#define MSCM_CPU_CFG_MMU_SHIFT (4u) +#define MSCM_CPU_CFG_MMU_WIDTH (1u) +#define MSCM_CPU_CFG_TRUST_ZONE_MASK (0x08u) +#define MSCM_CPU_CFG_TRUST_ZONE_SHIFT (3u) +#define MSCM_CPU_CFG_TRUST_ZONE_WIDTH (1u) +#define MSCM_CPU_CFG_JAZ_MASK (0x04u) +#define MSCM_CPU_CFG_JAZ_SHIFT (2u) +#define MSCM_CPU_CFG_JAZ_WIDTH (1u) +#define MSCM_CPU_CFG_SIMD_MASK (0x02u) +#define MSCM_CPU_CFG_SIMD_SHIFT (1u) +#define MSCM_CPU_CFG_SIMD_WIDTH (1u) +#define MSCM_CPU_CFG_FPU_MASK (0x01u) +#define MSCM_CPU_CFG_FPU_SHIFT (0u) +#define MSCM_CPU_CFG_FPU_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of MSCM registers + */ +typedef struct _MscmRegType_ +{ + const volatile uint32_t CPU_TYPE; /*!< Processor info register, offset: 0x00 */ + const volatile uint32_t CPU_NUM; /*!< Process NUMBER, offset: 0x04 */ + uint32_t RESERVED0[1]; /*!< Reserverd block, offset: 0x08 */ + const volatile uint32_t CPU_CNT; /*!< Total number of processor cores, offset: 0x0C */ + const volatile uint32_t CPU_CACHE; /*!< CPU cache info register, offset: 0x10 */ + const volatile uint32_t CPU_MEM; /*!< System memory info register, offset: 0x14 */ + const volatile uint32_t CPU_CFG; /*!< CPU configuration register, offset: 0x18 */ +} MscmRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the CPU type name + * + * This function gets the current CPU type name. + * The default value 0x434D34 is ASICC of "CM4" + * + * \param[in] obj : pointer to MSCM register instance + * \return CPU type name + */ +__attribute__((always_inline)) static inline uint32_t MscmReg_GetCpuTypeType(const MscmRegType *obj) +{ + return ((obj->CPU_TYPE & MSCM_CPU_TYPE_TYPE_MASK) >> MSCM_CPU_TYPE_TYPE_SHIFT); +} + +/*! \brief Gets the revision of processor + * + * This function gets the current revision of processor. + * + * \param[in] obj : pointer to MSCM register instance + * \return revision of processor + * - 0b : r0p0 + * - 1b : r0p1 + * - other : reserved + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuTypeRevision(const MscmRegType *obj) +{ + return ((obj->CPU_TYPE & MSCM_CPU_TYPE_REVISION_MASK) >> MSCM_CPU_TYPE_REVISION_SHIFT); +} + +/*! \brief Gets the Processor x Number + * + * This function gets the current Processor x Number. + * This zero-filled word defines the logical processor number for CPUx. + * If single core configuration, then CPN = 0 + * + * \param[in] obj : pointer to MSCM register instance + * \return Processor x Number + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuNumCpnx(const MscmRegType *obj) +{ + return ((obj->CPU_NUM & MSCM_CPU_NUM_CPNX_MASK) >> MSCM_CPU_NUM_CPNX_SHIFT); +} + +/*! \brief Gets the Processor Count + * + * This function gets the current Processor Count. + * This read-only field defines the processor count for the chip configuration + * + * \param[in] obj : pointer to MSCM register instance + * \return Processor Count + * - 00b : single core + * - 01b : dual cores + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCntPCnt(const MscmRegType *obj) +{ + return ((obj->CPU_CNT & MSCM_CPU_CNT_PCNT_MASK) >> MSCM_CPU_CNT_PCNT_SHIFT); +} + +/*! \brief Gets the Instruction cache Size + * + * This function gets the current Instruction cache Size. + * ICACHE_SIZE=0 means no memory, else memory size(byte) is 2^(8+ICACHE_SIZE) + * + * \param[in] obj : pointer to MSCM register instance + * \return Instruction cache Size + * - 0h : no cache + * - 1h : 512 + * - 2h : 1K + * - 3h : 2K + * - 4h : 4K + * - 5h : 8K + * - 6h : 16K + * - 7h : 32K + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCacheICacheSize(const MscmRegType *obj) +{ + return ((obj->CPU_CACHE & MSCM_CPU_CACHE_ICACHE_SIZE_MASK) >> MSCM_CPU_CACHE_ICACHE_SIZE_SHIFT); +} + +/*! \brief Gets the Instruction cache Ways + * + * This function gets the current Instruction cache Ways. + * This read-only field provides the number of cache ways for the Instruction cache. + * + * \param[in] obj : pointer to MSCM register instance + * \return Instruction cache Ways + * - 0h : not present. + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCacheICacheWays(const MscmRegType *obj) +{ + return ((obj->CPU_CACHE & MSCM_CPU_CACHE_ICACHE_WAYS_MASK) >> MSCM_CPU_CACHE_ICACHE_WAYS_SHIFT); +} + +/*! \brief Gets the Data Cache Size + * + * This function gets the current Data Cache Size. + * DCACHE_SIZE=0 means no memory, else memory size(byte) is 2^(8+DCACHE_SIZE) + * + * \param[in] obj : pointer to MSCM register instance + * \return Data Cache Size + * - 0h : no cache + * - 1h : 512 + * - 2h : 1K + * - 3h : 2K + * - 4h : 4K + * - 5h : 8K + * - 6h : 16K + * - 7h : 32K + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCacheDCacheSize(const MscmRegType *obj) +{ + return ((obj->CPU_CACHE & MSCM_CPU_CACHE_DCACHE_SIZE_MASK) >> MSCM_CPU_CACHE_DCACHE_SIZE_SHIFT); +} + +/*! \brief Gets the Data Cache Ways + * + * This function gets the current Data Cache Ways. + * This read-only field provides the number of cache ways for the Data Cache. + * + * \param[in] obj : pointer to MSCM register instance + * \return Data Cache Ways + * - 0h : not present. + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCacheDCacheWays(const MscmRegType *obj) +{ + return ((obj->CPU_CACHE & MSCM_CPU_CACHE_DCACHE_WAYS_MASK) >> MSCM_CPU_CACHE_DCACHE_WAYS_SHIFT); +} + +/*! \brief Gets the SRAMU Size + * + * This function gets the current SRAMU Size. + * SRAMU_SIZE=0 means no memory,else memory size(byte) is 2^(8+SRAMU_SIZE) -4 + * + * \param[in] obj : pointer to MSCM register instance + * \return SRAMU Size + * - 0h : no sramu + * - 8h : 60Kbyte + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuMemSRamUSize(const MscmRegType *obj) +{ + return ((obj->CPU_MEM & MSCM_CPU_MEM_SRAMU_SIZE_MASK) >> MSCM_CPU_MEM_SRAMU_SIZE_SHIFT); +} + +/*! \brief Gets the SRAML Size + * + * This function gets the current SRAML Size. + * SRAML_SIZE=0 means no memory, else memory size(byte) is 2^(8+SRAML_SIZE) + * + * \param[in] obj : pointer to MSCM register instance + * \return SRAML Size + * - 0h : no cache + * - 1h : 512byte + * - 2h : 1Kbyte + * - 3h : 2Kbyte + * - 4h : 4Kbyte + * - 5h : 8Kbyte + * - 6h : 16Kbyte + * - 7h : 32Kbyte + * - 8h : 64Kbyte + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuMemSRamLSize(const MscmRegType *obj) +{ + return ((obj->CPU_MEM & MSCM_CPU_MEM_SRAML_SIZE_MASK) >> MSCM_CPU_MEM_SRAML_SIZE_SHIFT); +} + +/*! \brief Gets the System Bus Ports + * + * This function gets the current System Bus Ports. + * This field defines the number of physical connections to the system bus fabric for this processor + * + * \param[in] obj : pointer to MSCM register instance + * \return System Bus Ports + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCfgBusPorts(const MscmRegType *obj) +{ + return ((obj->CPU_CFG & MSCM_CPU_CFG_BUS_PORTS_MASK) >> MSCM_CPU_CFG_BUS_PORTS_SHIFT); +} + +/*! \brief Gets the Bit Banding enable + * + * This function gets the current Bit Banding enable. + * This field defines if the processor supports "bit banding". + * + * \param[in] obj : pointer to MSCM register instance + * \return Bit Banding enable + * - 0b : Bit Banding is not supported. + * - 1b : Bit Banding is supported. + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCfgBB(const MscmRegType *obj) +{ + return ((obj->CPU_CFG & MSCM_CPU_CFG_BB_MASK) >> MSCM_CPU_CFG_BB_SHIFT); +} + +/*! \brief Gets the Core Memory Protection unit + * + * This function gets the current Core Memory Protection unit. + * This field indicates if the core memory protection hardware is included in the processor. + * + * \param[in] obj : pointer to MSCM register instance + * \return Core Memory Protection unit + * - 0b : Core Memory Protection is not included. + * - 1b : Core Memory Protection is included. + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCfgSmpu(const MscmRegType *obj) +{ + return ((obj->CPU_CFG & MSCM_CPU_CFG_SMPU_MASK) >> MSCM_CPU_CFG_SMPU_SHIFT); +} + +/*! \brief Gets the Memory Management Unit + * + * This function gets the current Memory Management Unit. + * This field indicates if the virtual memory management capabilities are supported in the processor. + * + * \param[in] obj : pointer to MSCM register instance + * \return Memory Management Unit + * - 0b : MMU support is not included. + * - 1b : MMU support is included. + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCfgMmu(const MscmRegType *obj) +{ + return ((obj->CPU_CFG & MSCM_CPU_CFG_MMU_MASK) >> MSCM_CPU_CFG_MMU_SHIFT); +} + +/*! \brief Gets the Trust Zone + * + * This function gets the current Trust Zone. + * This field indicates if the Trust Zone capabilities are supported in the processor.. + * + * \param[in] obj : pointer to MSCM register instance + * \return Trust Zone + * - 0b : Trust Zone support is not included. + * - 1b : Trust Zone support is included. + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCfgTrustZone(const MscmRegType *obj) +{ + return ((obj->CPU_CFG & MSCM_CPU_CFG_TRUST_ZONE_MASK) >> MSCM_CPU_CFG_TRUST_ZONE_SHIFT); +} + +/*! \brief Gets the Jazelle support + * + * This function gets the current Jazelle support. + * This field indicates if Jazelle hardware is supported in the processor. + * + * \param[in] obj : pointer to MSCM register instance + * \return Jazelle support + * - 0b : Jazelle support is not included. + * - 1b : Jazelle support is included. + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCfgJaz(const MscmRegType *obj) +{ + return ((obj->CPU_CFG & MSCM_CPU_CFG_JAZ_MASK) >> MSCM_CPU_CFG_JAZ_SHIFT); +} + +/*! \brief Gets the SIMD/NEON instruction support + * + * This function gets the current SIMD/NEON instruction support. + * This field indicates if the instruction set extensions supporting SIMD and/or NEON capabilities + * are supported in the processor. + * + * \param[in] obj : pointer to MSCM register instance + * \return SIMD/NEON instruction support + * - 0b : SIMD/NEON support is not included. + * - 1b : SIMD/NEON support is included. + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCfgSimd(const MscmRegType *obj) +{ + return ((obj->CPU_CFG & MSCM_CPU_CFG_SIMD_MASK) >> MSCM_CPU_CFG_SIMD_SHIFT); +} + +/*! \brief Gets the FPU support + * + * This function gets the current FPU support. + * + * \param[in] obj : pointer to MSCM register instance + * \return FPU support + * - 0b : FPU support is not included. + * - 1b : FPU support is included. + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCfgFpu(const MscmRegType *obj) +{ + return ((obj->CPU_CFG & MSCM_CPU_CFG_FPU_MASK) >> MSCM_CPU_CFG_FPU_SHIFT); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _MSCM_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/pcc0_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/pcc0_reg.h new file mode 100644 index 0000000..21e40f0 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/pcc0_reg.h @@ -0,0 +1,1261 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PCC0_REG_H_ +#define _PCC0_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the PCC0 Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* CMP Bit Fields */ +#define PCC0_CMP_SRC_MASK (0x10000u) +#define PCC0_CMP_SRC_SHIFT (16u) +#define PCC0_CMP_SRC_WIDTH (1u) +#define PCC0_CMP_CKEN_MASK (0x10u) +#define PCC0_CMP_CKEN_SHIFT (4u) +#define PCC0_CMP_CKEN_WIDTH (1u) +#define PCC0_CMP_SWR_MASK (0x01u) +#define PCC0_CMP_SWR_SHIFT (0u) +#define PCC0_CMP_SWR_WIDTH (1u) + +/* PORTA Bit Fields */ +#define PCC0_PORTA_CKEN_MASK (0x10u) +#define PCC0_PORTA_CKEN_SHIFT (4u) +#define PCC0_PORTA_CKEN_WIDTH (1u) +#define PCC0_PORTA_SWR_MASK (0x01u) +#define PCC0_PORTA_SWR_SHIFT (0u) +#define PCC0_PORTA_SWR_WIDTH (1u) + +/* PORTB Bit Fields */ +#define PCC0_PORTB_CKEN_MASK (0x10u) +#define PCC0_PORTB_CKEN_SHIFT (4u) +#define PCC0_PORTB_CKEN_WIDTH (1u) +#define PCC0_PORTB_SWR_MASK (0x01u) +#define PCC0_PORTB_SWR_SHIFT (0u) +#define PCC0_PORTB_SWR_WIDTH (1u) + +/* PORTC Bit Fields */ +#define PCC0_PORTC_CKEN_MASK (0x10u) +#define PCC0_PORTC_CKEN_SHIFT (4u) +#define PCC0_PORTC_CKEN_WIDTH (1u) +#define PCC0_PORTC_SWR_MASK (0x01u) +#define PCC0_PORTC_SWR_SHIFT (0u) +#define PCC0_PORTC_SWR_WIDTH (1u) + +/* PORTD Bit Fields */ +#define PCC0_PORTD_CKEN_MASK (0x10u) +#define PCC0_PORTD_CKEN_SHIFT (4u) +#define PCC0_PORTD_CKEN_WIDTH (1u) +#define PCC0_PORTD_SWR_MASK (0x01u) +#define PCC0_PORTD_SWR_SHIFT (0u) +#define PCC0_PORTD_SWR_WIDTH (1u) + +/* PORTE Bit Fields */ +#define PCC0_PORTE_CKEN_MASK (0x10u) +#define PCC0_PORTE_CKEN_SHIFT (4u) +#define PCC0_PORTE_CKEN_WIDTH (1u) +#define PCC0_PORTE_SWR_MASK (0x01u) +#define PCC0_PORTE_SWR_SHIFT (0u) +#define PCC0_PORTE_SWR_WIDTH (1u) + +/* LPTMR Bit Fields */ +#define PCC0_LPTMR_SRC_MASK (0x70000u) +#define PCC0_LPTMR_SRC_SHIFT (16u) +#define PCC0_LPTMR_SRC_WIDTH (3u) +#define PCC0_LPTMR_DIV_MASK (0x700u) +#define PCC0_LPTMR_DIV_SHIFT (8u) +#define PCC0_LPTMR_DIV_WIDTH (3u) +#define PCC0_LPTMR_CKEN_MASK (0x10u) +#define PCC0_LPTMR_CKEN_SHIFT (4u) +#define PCC0_LPTMR_CKEN_WIDTH (1u) +#define PCC0_LPTMR_SWR_MASK (0x01u) +#define PCC0_LPTMR_SWR_SHIFT (0u) +#define PCC0_LPTMR_SWR_WIDTH (1u) + +/* LPIT Bit Fields */ +#define PCC0_LPIT_SRC_MASK (0x30000u) +#define PCC0_LPIT_SRC_SHIFT (16u) +#define PCC0_LPIT_SRC_WIDTH (2u) +#define PCC0_LPIT_CKEN_MASK (0x10u) +#define PCC0_LPIT_CKEN_SHIFT (4u) +#define PCC0_LPIT_CKEN_WIDTH (1u) +#define PCC0_LPIT_SWR_MASK (0x01u) +#define PCC0_LPIT_SWR_SHIFT (0u) +#define PCC0_LPIT_SWR_WIDTH (1u) + +/* RTC_CNT Bit Fields */ +#define PCC0_RTC_CNT_SRC_MASK (0x30000u) +#define PCC0_RTC_CNT_SRC_SHIFT (16u) +#define PCC0_RTC_CNT_SRC_WIDTH (2u) +#define PCC0_RTC_CNT_CKEN_MASK (0x10u) +#define PCC0_RTC_CNT_CKEN_SHIFT (4u) +#define PCC0_RTC_CNT_CKEN_WIDTH (1u) + +/* WDG Bit Fields */ +#define PCC0_WDG_SWR_MASK (0x01u) +#define PCC0_WDG_SWR_SHIFT (0u) +#define PCC0_WDG_SWR_WIDTH (1u) + +/* PORTA_FLT Bit Fields */ +#define PCC0_PORTA_FLT_SRC_MASK (0x10000u) +#define PCC0_PORTA_FLT_SRC_SHIFT (16u) +#define PCC0_PORTA_FLT_SRC_WIDTH (1u) + +/* PORTB_FLT Bit Fields */ +#define PCC0_PORTB_FLT_SRC_MASK (0x10000u) +#define PCC0_PORTB_FLT_SRC_SHIFT (16u) +#define PCC0_PORTB_FLT_SRC_WIDTH (1u) + +/* PORTC_FLT Bit Fields */ +#define PCC0_PORTC_FLT_SRC_MASK (0x10000u) +#define PCC0_PORTC_FLT_SRC_SHIFT (16u) +#define PCC0_PORTC_FLT_SRC_WIDTH (1u) + +/* PORTD_FLT Bit Fields */ +#define PCC0_PORTD_FLT_SRC_MASK (0x10000u) +#define PCC0_PORTD_FLT_SRC_SHIFT (16u) +#define PCC0_PORTD_FLT_SRC_WIDTH (1u) + +/* PORTE_FLT Bit Fields */ +#define PCC0_PORTE_FLT_SRC_MASK (0x10000u) +#define PCC0_PORTE_FLT_SRC_SHIFT (16u) +#define PCC0_PORTE_FLT_SRC_WIDTH (1u) + +/* LPO32 Bit Fields */ +#define PCC0_LPO32_CKEN_MASK (0x10u) +#define PCC0_LPO32_CKEN_SHIFT (4u) +#define PCC0_LPO32_CKEN_WIDTH (1u) + +/* LPO1 Bit Fields */ +#define PCC0_LPO1_CKEN_MASK (0x10u) +#define PCC0_LPO1_CKEN_SHIFT (4u) +#define PCC0_LPO1_CKEN_WIDTH (1u) + +/* LOCK Bit Fields */ +#define PCC0_LOCK_LOCK_MASK (0x01u) +#define PCC0_LOCK_LOCK_SHIFT (0u) +#define PCC0_LOCK_LOCK_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of PCC0 registers + */ +typedef struct _Pcc0RegType_ +{ + uint32_t RESERVED0[1]; /*!< Reserved register, offset: 0x0 */ + volatile uint32_t CMP; /*!< CMP clock and software reset control register, offset: 0x4 */ + volatile uint32_t PORTA; /*!< PORTA clock and software reset control register, offset: 0x8 */ + volatile uint32_t PORTB; /*!< PORTB clock and software reset control register, offset: 0xC */ + volatile uint32_t PORTC; /*!< PORTC clock and software reset control register, offset: 0x10 */ + volatile uint32_t PORTD; /*!< PORTD clock and software reset control register, offset: 0x14 */ + volatile uint32_t PORTE; /*!< PORTE clock and software reset control register, offset: 0x18 */ + volatile uint32_t LPTMR; /*!< LPTMR clock and software reset control register, offset: 0x1C */ + volatile uint32_t LPIT; /*!< LPIT clock and software reset control register, offset: 0x20 */ + uint32_t RESERVED1[1]; /*!< Reserved register, offset: 0x24 */ + volatile uint32_t RTC_CNT; /*!< RTC clock and software reset control register, offset: 0x28 */ + volatile uint32_t WDG; /*!< WDG clock and software reset control register, offset: 0x2C */ + volatile uint32_t PORTA_FLT; /*!< PORTA digital filter clock and software reset control register, offset: 0x30 */ + volatile uint32_t PORTB_FLT; /*!< PORTB digital filter clock and software reset control register, offset: 0x34 */ + volatile uint32_t PORTC_FLT; /*!< PORTC digital filter clock and software reset control register, offset: 0x38 */ + volatile uint32_t PORTD_FLT; /*!< PORTD digital filter clock and software reset control register, offset: 0x3C */ + volatile uint32_t PORTE_FLT; /*!< PORTE digital filter clock and software reset control register, offset: 0x40 */ + volatile uint32_t LPO32; /*!< LPO32 clock and software reset control register, offset: 0x44 */ + volatile uint32_t LPO1; /*!< LPO1 clock and software reset control register, offset: 0x48 */ + uint32_t RESERVED2[13]; /*!< Reserved register, offset: 0x4C */ + volatile uint32_t KEY; /*!< PCC module unlock/lock control, offset: 0x80 */ + const volatile uint32_t LOCK; /*!< PCC module unlock/lock status, offset: 0x84 */ +} Pcc0RegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the CMP module function clock source + * + * This function gets the current CMP module function clock source. + * In RUN mode, the source should be clk_core. In STOP and STANDBY mode, the source may be changed to clk_lptmr. + * + * \param[in] obj : pointer to PCC0 register instance + * \return CMP module function clock source + * - 0b : clk_core + * - 1b : clk_lptmr + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetCmpSrc(const Pcc0RegType *obj) +{ + return ((obj->CMP & PCC0_CMP_SRC_MASK) >> PCC0_CMP_SRC_SHIFT); +} + +/*! \brief Sets the CMP module function clock source + * + * This function sets the CMP module function clock source. + * In RUN mode, the source should be clk_core. In STOP and STANDBY mode, the source may be changed to clk_lptmr. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of CMP module function clock source + * - 0b : clk_core + * - 1b : clk_lptmr + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetCmpSrc(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CMP; + + tmp &= ~PCC0_CMP_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_CMP_SRC_SHIFT)) & PCC0_CMP_SRC_MASK); + obj->CMP = tmp; +} + +/*! \brief Gets the CMP module clock enable for both config clock and function + * + * This function gets the current CMP module clock enable for both config clock and function . + * + * \param[in] obj : pointer to PCC0 register instance + * \return CMP module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetCmpCkEn(const Pcc0RegType *obj) +{ + return ((obj->CMP & PCC0_CMP_CKEN_MASK) >> PCC0_CMP_CKEN_SHIFT); +} + +/*! \brief Sets the CMP module clock enable for both config clock and function + * + * This function sets the CMP module clock enable for both config clock and function . + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of CMP module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetCmpCkEn(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CMP; + + tmp &= ~PCC0_CMP_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_CMP_CKEN_SHIFT)) & PCC0_CMP_CKEN_MASK); + obj->CMP = tmp; +} + +/*! \brief Gets the CMP0 module software reset for both config clock domain and function clock domain + * + * This function gets the current CMP0 module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \return CMP0 module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetCmpSwR(const Pcc0RegType *obj) +{ + return ((obj->CMP & PCC0_CMP_SWR_MASK) >> PCC0_CMP_SWR_SHIFT); +} + +/*! \brief Sets the CMP0 module software reset for both config clock domain and function clock domain + * + * This function sets the CMP0 module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of CMP0 module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetCmpSwR(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CMP; + + tmp &= ~PCC0_CMP_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_CMP_SWR_SHIFT)) & PCC0_CMP_SWR_MASK); + obj->CMP = tmp; +} + +/*! \brief Gets the PORTA module clock enable for both config clock and function + * + * This function gets the current PORTA module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTA module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortACkEn(const Pcc0RegType *obj) +{ + return ((obj->PORTA & PCC0_PORTA_CKEN_MASK) >> PCC0_PORTA_CKEN_SHIFT); +} + +/*! \brief Sets the PORTA module clock enable for both config clock and function + * + * This function sets the PORTA module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTA module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortACkEn(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTA; + + tmp &= ~PCC0_PORTA_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTA_CKEN_SHIFT)) & PCC0_PORTA_CKEN_MASK); + obj->PORTA = tmp; +} + +/*! \brief Gets the PORTA module software reset for both config clock domain and function clock domain + * + * This function gets the current PORTA module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTA module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortASwR(const Pcc0RegType *obj) +{ + return ((obj->PORTA & PCC0_PORTA_SWR_MASK) >> PCC0_PORTA_SWR_SHIFT); +} + +/*! \brief Sets the PORTA module software reset for both config clock domain and function clock domain + * + * This function sets the PORTA module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTA module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortASwR(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTA; + + tmp &= ~PCC0_PORTA_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTA_SWR_SHIFT)) & PCC0_PORTA_SWR_MASK); + obj->PORTA = tmp; +} + +/*! \brief Gets the PORTB module clock enable for both config clock and function + * + * This function gets the current PORTB module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTB module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortBCkEn(const Pcc0RegType *obj) +{ + return ((obj->PORTB & PCC0_PORTB_CKEN_MASK) >> PCC0_PORTB_CKEN_SHIFT); +} + +/*! \brief Sets the PORTB module clock enable for both config clock and function + * + * This function sets the PORTB module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTB module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortBCkEn(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTB; + + tmp &= ~PCC0_PORTB_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTB_CKEN_SHIFT)) & PCC0_PORTB_CKEN_MASK); + obj->PORTB = tmp; +} + +/*! \brief Gets the PORTB module software reset for both config clock domain and function clock domain + * + * This function gets the current PORTB module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTB module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortBSwR(const Pcc0RegType *obj) +{ + return ((obj->PORTB & PCC0_PORTB_SWR_MASK) >> PCC0_PORTB_SWR_SHIFT); +} + +/*! \brief Sets the PORTB module software reset for both config clock domain and function clock domain + * + * This function sets the PORTB module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTB module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortBSwR(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTB; + + tmp &= ~PCC0_PORTB_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTB_SWR_SHIFT)) & PCC0_PORTB_SWR_MASK); + obj->PORTB = tmp; +} + +/*! \brief Gets the PORTC module clock enable for both config clock and function + * + * This function gets the current PORTC module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTC module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortCCkEn(const Pcc0RegType *obj) +{ + return ((obj->PORTC & PCC0_PORTC_CKEN_MASK) >> PCC0_PORTC_CKEN_SHIFT); +} + +/*! \brief Sets the PORTC module clock enable for both config clock and function + * + * This function sets the PORTC module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTC module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortCCkEn(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTC; + + tmp &= ~PCC0_PORTC_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTC_CKEN_SHIFT)) & PCC0_PORTC_CKEN_MASK); + obj->PORTC = tmp; +} + +/*! \brief Gets the PORTC module software reset for both config clock domain and function clock domain + * + * This function gets the current PORTC module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTC module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortCSwR(const Pcc0RegType *obj) +{ + return ((obj->PORTC & PCC0_PORTC_SWR_MASK) >> PCC0_PORTC_SWR_SHIFT); +} + +/*! \brief Sets the PORTC module software reset for both config clock domain and function clock domain + * + * This function sets the PORTC module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTC module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortCSwR(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTC; + + tmp &= ~PCC0_PORTC_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTC_SWR_SHIFT)) & PCC0_PORTC_SWR_MASK); + obj->PORTC = tmp; +} + +/*! \brief Gets the PORTD module clock enable for both config clock and function + * + * This function gets the current PORTD module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTD module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortDCkEn(const Pcc0RegType *obj) +{ + return ((obj->PORTD & PCC0_PORTD_CKEN_MASK) >> PCC0_PORTD_CKEN_SHIFT); +} + +/*! \brief Sets the PORTD module clock enable for both config clock and function + * + * This function sets the PORTD module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTD module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortDCkEn(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTD; + + tmp &= ~PCC0_PORTD_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTD_CKEN_SHIFT)) & PCC0_PORTD_CKEN_MASK); + obj->PORTD = tmp; +} + +/*! \brief Gets the PORTD module software reset for both config clock domain and function clock domain + * + * This function gets the current PORTD module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTD module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortDSwR(const Pcc0RegType *obj) +{ + return ((obj->PORTD & PCC0_PORTD_SWR_MASK) >> PCC0_PORTD_SWR_SHIFT); +} + +/*! \brief Sets the PORTD module software reset for both config clock domain and function clock domain + * + * This function sets the PORTD module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTD module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortDSwR(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTD; + + tmp &= ~PCC0_PORTD_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTD_SWR_SHIFT)) & PCC0_PORTD_SWR_MASK); + obj->PORTD = tmp; +} + +/*! \brief Gets the PORTE module clock enable for both config clock and function + * + * This function gets the current PORTE module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTE module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortECkEn(const Pcc0RegType *obj) +{ + return ((obj->PORTE & PCC0_PORTE_CKEN_MASK) >> PCC0_PORTE_CKEN_SHIFT); +} + +/*! \brief Sets the PORTE module clock enable for both config clock and function + * + * This function sets the PORTE module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTE module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortECkEn(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTE; + + tmp &= ~PCC0_PORTE_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTE_CKEN_SHIFT)) & PCC0_PORTE_CKEN_MASK); + obj->PORTE = tmp; +} + +/*! \brief Gets the PORTE module software reset for both config clock domain and function clock domain + * + * This function gets the current PORTE module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTE module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortESwR(const Pcc0RegType *obj) +{ + return ((obj->PORTE & PCC0_PORTE_SWR_MASK) >> PCC0_PORTE_SWR_SHIFT); +} + +/*! \brief Sets the PORTE module software reset for both config clock domain and function clock domain + * + * This function sets the PORTE module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTE module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortESwR(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTE; + + tmp &= ~PCC0_PORTE_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTE_SWR_SHIFT)) & PCC0_PORTE_SWR_MASK); + obj->PORTE = tmp; +} + +/*! \brief Gets the LPTMR module function clock source + * + * This function gets the current LPTMR module function clock source. + * This register should be changed after the clock is disabled at least 2 pre-changed clock cycles + * and 2 after-changed clock cycles. + * + * \param[in] obj : pointer to PCC0 register instance + * \return LPTMR module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_lpo128 + * - 4h : clk_lpo1 + * - 5h : clk_lpo32 + * - 6h : RTC_CLKIN from PAD_PTA7 + * - 7h : clk_sirc_div + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetLptmrSrc(const Pcc0RegType *obj) +{ + return ((obj->LPTMR & PCC0_LPTMR_SRC_MASK) >> PCC0_LPTMR_SRC_SHIFT); +} + +/*! \brief Sets the LPTMR module function clock source + * + * This function sets the LPTMR module function clock source. + * This register should be changed after the clock is disabled at least 2 pre-changed clock cycles + * and 2 after-changed clock cycles. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of LPTMR module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_lpo128 + * - 4h : clk_lpo1 + * - 5h : clk_lpo32 + * - 6h : RTC_CLKIN from PAD_PTA7 + * - 7h : clk_sirc_div + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetLptmrSrc(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPTMR; + + tmp &= ~PCC0_LPTMR_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_LPTMR_SRC_SHIFT)) & PCC0_LPTMR_SRC_MASK); + obj->LPTMR = tmp; +} + +/*! \brief Gets the LPTMR module function clock divide ratio + * + * This function gets the current LPTMR module function clock divide ratio . + * This register should be changed after the clock is disabled at least 2 pre-changed clock cycles + * and 2 after-changed clock cycles. + * + * \param[in] obj : pointer to PCC0 register instance + * \return LPTMR module function clock divide ratio + * - 0h : 1 + * - 1h : 2 + * - 2h : 3 + * - 3h : 4 + * - 4h : 5 + * - 5h : 6 + * - 6h : 7 + * - 7h : 8 + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetLptmrDiv(const Pcc0RegType *obj) +{ + return ((obj->LPTMR & PCC0_LPTMR_DIV_MASK) >> PCC0_LPTMR_DIV_SHIFT); +} + +/*! \brief Sets the LPTMR module function clock divide ratio + * + * This function sets the LPTMR module function clock divide ratio . + * This register should be changed after the clock is disabled at least 2 pre-changed clock cycles + * and 2 after-changed clock cycles. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of LPTMR module function clock divide ratio + * - 0h : 1 + * - 1h : 2 + * - 2h : 3 + * - 3h : 4 + * - 4h : 5 + * - 5h : 6 + * - 6h : 7 + * - 7h : 8 + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetLptmrDiv(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPTMR; + + tmp &= ~PCC0_LPTMR_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_LPTMR_DIV_SHIFT)) & PCC0_LPTMR_DIV_MASK); + obj->LPTMR = tmp; +} + +/*! \brief Gets the LPTMR module clock enable for both config clock and function clock + * + * This function gets the current LPTMR module clock enable for both config clock and function clock. + * + * \param[in] obj : pointer to PCC0 register instance + * \return LPTMR module clock enable for both config clock and function clock + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetLptmrCken(const Pcc0RegType *obj) +{ + return ((obj->LPTMR & PCC0_LPTMR_CKEN_MASK) >> PCC0_LPTMR_CKEN_SHIFT); +} + +/*! \brief Sets the LPTMR module clock enable for both config clock and function clock + * + * This function sets the LPTMR module clock enable for both config clock and function clock. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of LPTMR module clock enable for both config clock and function clock + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetLptmrCken(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPTMR; + + tmp &= ~PCC0_LPTMR_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_LPTMR_CKEN_SHIFT)) & PCC0_LPTMR_CKEN_MASK); + obj->LPTMR = tmp; +} + +/*! \brief Gets the LPTMR module software reset for both config clock domain and function clock domain + * + * This function gets the current LPTMR module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \return LPTMR module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetLptmrSwR(const Pcc0RegType *obj) +{ + return ((obj->LPTMR & PCC0_LPTMR_SWR_MASK) >> PCC0_LPTMR_SWR_SHIFT); +} + +/*! \brief Sets the LPTMR module software reset for both config clock domain and function clock domain + * + * This function sets the LPTMR module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of LPTMR module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetLptmrSwR(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPTMR; + + tmp &= ~PCC0_LPTMR_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_LPTMR_SWR_SHIFT)) & PCC0_LPTMR_SWR_MASK); + obj->LPTMR = tmp; +} + +/*! \brief Gets the LPIT module function clock source + * + * This function gets the current LPIT module function clock source. + * This register should be changed after the clock is disabled at least 2 pre-changed clock cycles + * and 2 after-changed clock cycles. + * + * \param[in] obj : pointer to PCC0 register instance + * \return LPIT module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_pll_div + * - 2h : clk_sosc_div + * - 3h : clk_lpo128 + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetLpitSrc(const Pcc0RegType *obj) +{ + return ((obj->LPIT & PCC0_LPIT_SRC_MASK) >> PCC0_LPIT_SRC_SHIFT); +} + +/*! \brief Sets the LPIT module function clock source + * + * This function sets the LPIT module function clock source. + * This register should be changed after the clock is disabled at least 2 pre-changed clock cycles + * and 2 after-changed clock cycles. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of LPIT module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_pll_div + * - 2h : clk_sosc_div + * - 3h : clk_lpo128 + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetLpitSrc(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPIT; + + tmp &= ~PCC0_LPIT_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_LPIT_SRC_SHIFT)) & PCC0_LPIT_SRC_MASK); + obj->LPIT = tmp; +} + +/*! \brief Gets the LPIT module clock enable for both config clock and function + * + * This function gets the current LPIT module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \return LPIT module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetLpitCken(const Pcc0RegType *obj) +{ + return ((obj->LPIT & PCC0_LPIT_CKEN_MASK) >> PCC0_LPIT_CKEN_SHIFT); +} + +/*! \brief Sets the LPIT module clock enable for both config clock and function + * + * This function sets the LPIT module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of LPIT module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetLpitCken(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPIT; + + tmp &= ~PCC0_LPIT_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_LPIT_CKEN_SHIFT)) & PCC0_LPIT_CKEN_MASK); + obj->LPIT = tmp; +} + +/*! \brief Gets the LPIT module software reset for both config clock domain and function clock domain + * + * This function gets the current LPIT module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \return LPIT module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetLpitSwR(const Pcc0RegType *obj) +{ + return ((obj->LPIT & PCC0_LPIT_SWR_MASK) >> PCC0_LPIT_SWR_SHIFT); +} + +/*! \brief Sets the LPIT module software reset for both config clock domain and function clock domain + * + * This function sets the LPIT module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of LPIT module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetLpitSwR(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPIT; + + tmp &= ~PCC0_LPIT_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_LPIT_SWR_SHIFT)) & PCC0_LPIT_SWR_MASK); + obj->LPIT = tmp; +} + +/*! \brief Gets the RTC module clock source select + * + * This function gets the current RTC module clock source select. + * This register should be changed after the clock is disabled at least 2 pre-changed clock cycles + * and 2 after-changed clock cycles. + * + * \param[in] obj : pointer to PCC0 register instance + * \return RTC module clock source select + * - 0h : clk_lpo32 + * - 1h : PAD RTC_CLKIN + * - 2h : lpo1 + * - 3h : lpo1 + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetRtcCntSrc(const Pcc0RegType *obj) +{ + return ((obj->RTC_CNT & PCC0_RTC_CNT_SRC_MASK) >> PCC0_RTC_CNT_SRC_SHIFT); +} + +/*! \brief Sets the RTC module clock source select + * + * This function sets the RTC module clock source select. + * This register should be changed after the clock is disabled at least 2 pre-changed clock cycles + * and 2 after-changed clock cycles. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of RTC module clock source select + * - 0h : clk_lpo32 + * - 1h : PAD RTC_CLKIN + * - 2h : lpo1 + * - 3h : lpo1 + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetRtcCntSrc(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RTC_CNT; + + tmp &= ~PCC0_RTC_CNT_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_RTC_CNT_SRC_SHIFT)) & PCC0_RTC_CNT_SRC_MASK); + obj->RTC_CNT = tmp; +} + +/*! \brief Gets the RTC module clock enable for both config clock and function clock + * + * This function gets the current RTC module clock enable for both config clock and function clock. + * + * \param[in] obj : pointer to PCC0 register instance + * \return RTC module clock enable for both config clock and function clock + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetRtcCntCken(const Pcc0RegType *obj) +{ + return ((obj->RTC_CNT & PCC0_RTC_CNT_CKEN_MASK) >> PCC0_RTC_CNT_CKEN_SHIFT); +} + +/*! \brief Sets the RTC module clock enable for both config clock and function clock + * + * This function sets the RTC module clock enable for both config clock and function clock. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of RTC module clock enable for both config clock and function clock + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetRtcCntCken(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RTC_CNT; + + tmp &= ~PCC0_RTC_CNT_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_RTC_CNT_CKEN_SHIFT)) & PCC0_RTC_CNT_CKEN_MASK); + obj->RTC_CNT = tmp; +} + +/*! \brief Gets the WDG module software reset for both config clock domain and function clock domain + * + * This function gets the current WDG module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \return WDG module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetWdgSwR(const Pcc0RegType *obj) +{ + return ((obj->WDG & PCC0_WDG_SWR_MASK) >> PCC0_WDG_SWR_SHIFT); +} + +/*! \brief Sets the WDG module software reset for both config clock domain and function clock domain + * + * This function sets the WDG module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of WDG module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetWdgSwR(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->WDG; + + tmp &= ~PCC0_WDG_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_WDG_SWR_SHIFT)) & PCC0_WDG_SWR_MASK); + obj->WDG = tmp; +} + +/*! \brief Gets the PORTA digital filter clock source + * + * This function gets the current PORTA digital filter clock source. + * Changing the filter clock source must be done only when all digital filters are disabled. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTA digital filter clock source + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortAFltSrc(const Pcc0RegType *obj) +{ + return ((obj->PORTA_FLT & PCC0_PORTA_FLT_SRC_MASK) >> PCC0_PORTA_FLT_SRC_SHIFT); +} + +/*! \brief Sets the PORTA digital filter clock source + * + * This function sets the PORTA digital filter clock source. + * Changing the filter clock source must be done only when all digital filters are disabled. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTA digital filter clock source + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortAFltSrc(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTA_FLT; + + tmp &= ~PCC0_PORTA_FLT_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTA_FLT_SRC_SHIFT)) & PCC0_PORTA_FLT_SRC_MASK); + obj->PORTA_FLT = tmp; +} + +/*! \brief Gets the PORTB digital filter clock source + * + * This function gets the current PORTB digital filter clock source. + * Changing the filter clock source must be done only when all digital filters are disabled. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTB digital filter clock source + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortBFltSrc(const Pcc0RegType *obj) +{ + return ((obj->PORTB_FLT & PCC0_PORTB_FLT_SRC_MASK) >> PCC0_PORTB_FLT_SRC_SHIFT); +} + +/*! \brief Sets the PORTB digital filter clock source + * + * This function sets the PORTB digital filter clock source. + * Changing the filter clock source must be done only when all digital filters are disabled. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTB digital filter clock source + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortBFltSrc(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTB_FLT; + + tmp &= ~PCC0_PORTB_FLT_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTB_FLT_SRC_SHIFT)) & PCC0_PORTB_FLT_SRC_MASK); + obj->PORTB_FLT = tmp; +} + +/*! \brief Gets the PORTC digital filter clock source + * + * This function gets the current PORTC digital filter clock source. + * Changing the filter clock source must be done only when all digital filters are disabled. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTC digital filter clock source + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortCFltSrc(const Pcc0RegType *obj) +{ + return ((obj->PORTC_FLT & PCC0_PORTC_FLT_SRC_MASK) >> PCC0_PORTC_FLT_SRC_SHIFT); +} + +/*! \brief Sets the PORTC digital filter clock source + * + * This function sets the PORTC digital filter clock source. + * Changing the filter clock source must be done only when all digital filters are disabled. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTC digital filter clock source + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortCFltSrc(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTC_FLT; + + tmp &= ~PCC0_PORTC_FLT_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTC_FLT_SRC_SHIFT)) & PCC0_PORTC_FLT_SRC_MASK); + obj->PORTC_FLT = tmp; +} + +/*! \brief Gets the PORTD digital filter clock source + * + * This function gets the current PORTD digital filter clock source. + * Changing the filter clock source must be done only when all digital filters are disabled. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTD digital filter clock source + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortDFltSrc(const Pcc0RegType *obj) +{ + return ((obj->PORTD_FLT & PCC0_PORTD_FLT_SRC_MASK) >> PCC0_PORTD_FLT_SRC_SHIFT); +} + +/*! \brief Sets the PORTD digital filter clock source + * + * This function sets the PORTD digital filter clock source. + * Changing the filter clock source must be done only when all digital filters are disabled. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTD digital filter clock source + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortDFltSrc(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTD_FLT; + + tmp &= ~PCC0_PORTD_FLT_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTD_FLT_SRC_SHIFT)) & PCC0_PORTD_FLT_SRC_MASK); + obj->PORTD_FLT = tmp; +} + +/*! \brief Gets the PORTE digital filter clock source + * + * This function gets the current PORTE digital filter clock source. + * Changing the filter clock source must be done only when all digital filters are disabled. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTE digital filter clock source + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortEFltSrc(const Pcc0RegType *obj) +{ + return ((obj->PORTE_FLT & PCC0_PORTE_FLT_SRC_MASK) >> PCC0_PORTE_FLT_SRC_SHIFT); +} + +/*! \brief Sets the PORTE digital filter clock source + * + * This function sets the PORTE digital filter clock source. + * Changing the filter clock source must be done only when all digital filters are disabled. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTE digital filter clock source + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortEFltSrc(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTE_FLT; + + tmp &= ~PCC0_PORTE_FLT_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTE_FLT_SRC_SHIFT)) & PCC0_PORTE_FLT_SRC_MASK); + obj->PORTE_FLT = tmp; +} + +/*! \brief Gets the clk_lpo32 enable + * + * This function gets the current clk_lpo32 enable. + * + * \param[in] obj : pointer to PCC0 register instance + * \return clk_lpo32 enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetLpo32Cken(const Pcc0RegType *obj) +{ + return ((obj->LPO32 & PCC0_LPO32_CKEN_MASK) >> PCC0_LPO32_CKEN_SHIFT); +} + +/*! \brief Sets the clk_lpo32 enable + * + * This function sets the clk_lpo32 enable. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of clk_lpo32 enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetLpo32Cken(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPO32; + + tmp &= ~PCC0_LPO32_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_LPO32_CKEN_SHIFT)) & PCC0_LPO32_CKEN_MASK); + obj->LPO32 = tmp; +} + +/*! \brief Gets the clk_lpo1 enable + * + * This function gets the current clk_lpo1 enable. + * + * \param[in] obj : pointer to PCC0 register instance + * \return clk_lpo1 enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetLpo1Cken(const Pcc0RegType *obj) +{ + return ((obj->LPO1 & PCC0_LPO1_CKEN_MASK) >> PCC0_LPO1_CKEN_SHIFT); +} + +/*! \brief Sets the clk_lpo1 enable + * + * This function sets the clk_lpo1 enable. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of clk_lpo1 enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetLpo1Cken(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPO1; + + tmp &= ~PCC0_LPO1_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_LPO1_CKEN_SHIFT)) & PCC0_LPO1_CKEN_MASK); + obj->LPO1 = tmp; +} + +/*! \brief Sets the PCC register unlock key + * + * This function sets the PCC register unlock key. + * Registers in PCC is locked by default. Before writing registers in pcc, write unlock key to this register. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PCC register unlock key + * - 0x55534552 : unlock(USER), user key + * - other : lock + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetKey(Pcc0RegType *obj, uint32_t value) +{ + obj->KEY = value; +} + +/*! \brief Gets the PCC register unlock key + * + * This function gets the current PCC register unlock key. + * Registers in PCC is locked by default. Before writing registers in pcc, write unlock key to this register. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PCC register unlock key + * - 0b : unlock + * - 1b : lock + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetLock(const Pcc0RegType *obj) +{ + return ((obj->LOCK & PCC0_LOCK_LOCK_MASK) >> PCC0_LOCK_LOCK_SHIFT); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _PCC0_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/pcc1_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/pcc1_reg.h new file mode 100644 index 0000000..3575fb5 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/pcc1_reg.h @@ -0,0 +1,2728 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PCC1_REG_H_ +#define _PCC1_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the PCC1 Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* DMA Bit Fields */ +#define PCC1_DMA_CKEN_MASK (0x10u) +#define PCC1_DMA_CKEN_SHIFT (4u) +#define PCC1_DMA_CKEN_WIDTH (1u) +#define PCC1_DMA_SWR_MASK (0x01u) +#define PCC1_DMA_SWR_SHIFT (0u) +#define PCC1_DMA_SWR_WIDTH (1u) + +/* MSCM Bit Fields */ +#define PCC1_MSCM_CKEN_MASK (0x10u) +#define PCC1_MSCM_CKEN_SHIFT (4u) +#define PCC1_MSCM_CKEN_WIDTH (1u) +#define PCC1_MSCM_SWR_MASK (0x01u) +#define PCC1_MSCM_SWR_SHIFT (0u) +#define PCC1_MSCM_SWR_WIDTH (1u) + +/* CRC Bit Fields */ +#define PCC1_CRC_CKEN_MASK (0x10u) +#define PCC1_CRC_CKEN_SHIFT (4u) +#define PCC1_CRC_CKEN_WIDTH (1u) +#define PCC1_CRC_SWR_MASK (0x01u) +#define PCC1_CRC_SWR_SHIFT (0u) +#define PCC1_CRC_SWR_WIDTH (1u) + +/* EIM Bit Fields */ +#define PCC1_EIM_CKEN_MASK (0x10u) +#define PCC1_EIM_CKEN_SHIFT (4u) +#define PCC1_EIM_CKEN_WIDTH (1u) +#define PCC1_EIM_SWR_MASK (0x01u) +#define PCC1_EIM_SWR_SHIFT (0u) +#define PCC1_EIM_SWR_WIDTH (1u) + +/* ERM Bit Fields */ +#define PCC1_ERM_CKEN_MASK (0x10u) +#define PCC1_ERM_CKEN_SHIFT (4u) +#define PCC1_ERM_CKEN_WIDTH (1u) +#define PCC1_ERM_SWR_MASK (0x01u) +#define PCC1_ERM_SWR_SHIFT (0u) +#define PCC1_ERM_SWR_WIDTH (1u) + +/* FHU Bit Fields */ +#define PCC1_FHU_CKEN_MASK (0x10u) +#define PCC1_FHU_CKEN_SHIFT (4u) +#define PCC1_FHU_CKEN_WIDTH (1u) +#define PCC1_FHU_SWR_MASK (0x01u) +#define PCC1_FHU_SWR_SHIFT (0u) +#define PCC1_FHU_SWR_WIDTH (1u) + +/* ADC Bit Fields */ +#define PCC1_ADC_SRC_MASK (0x30000u) +#define PCC1_ADC_SRC_SHIFT (16u) +#define PCC1_ADC_SRC_WIDTH (2u) +#define PCC1_ADC_DIV_MASK (0x300u) +#define PCC1_ADC_DIV_SHIFT (8u) +#define PCC1_ADC_DIV_WIDTH (2u) +#define PCC1_ADC_CKEN_MASK (0x10u) +#define PCC1_ADC_CKEN_SHIFT (4u) +#define PCC1_ADC_CKEN_WIDTH (1u) +#define PCC1_ADC_SWR_MASK (0x01u) +#define PCC1_ADC_SWR_SHIFT (0u) +#define PCC1_ADC_SWR_WIDTH (1u) + +/* PDB Bit Fields */ +#define PCC1_PDB_CKEN_MASK (0x10u) +#define PCC1_PDB_CKEN_SHIFT (4u) +#define PCC1_PDB_CKEN_WIDTH (1u) +#define PCC1_PDB_SWR_MASK (0x01u) +#define PCC1_PDB_SWR_SHIFT (0u) +#define PCC1_PDB_SWR_WIDTH (1u) + +/* SPI0 Bit Fields */ +#define PCC1_SPI0_SRC_MASK (0x30000u) +#define PCC1_SPI0_SRC_SHIFT (16u) +#define PCC1_SPI0_SRC_WIDTH (2u) +#define PCC1_SPI0_CKEN_MASK (0x10u) +#define PCC1_SPI0_CKEN_SHIFT (4u) +#define PCC1_SPI0_CKEN_WIDTH (1u) +#define PCC1_SPI0_SWR_MASK (0x01u) +#define PCC1_SPI0_SWR_SHIFT (0u) +#define PCC1_SPI0_SWR_WIDTH (1u) + +/* SPI1 Bit Fields */ +#define PCC1_SPI1_SRC_MASK (0x30000u) +#define PCC1_SPI1_SRC_SHIFT (16u) +#define PCC1_SPI1_SRC_WIDTH (2u) +#define PCC1_SPI1_CKEN_MASK (0x10u) +#define PCC1_SPI1_CKEN_SHIFT (4u) +#define PCC1_SPI1_CKEN_WIDTH (1u) +#define PCC1_SPI1_SWR_MASK (0x01u) +#define PCC1_SPI1_SWR_SHIFT (0u) +#define PCC1_SPI1_SWR_WIDTH (1u) + +/* UART0 Bit Fields */ +#define PCC1_UART0_SRC_MASK (0x30000u) +#define PCC1_UART0_SRC_SHIFT (16u) +#define PCC1_UART0_SRC_WIDTH (2u) +#define PCC1_UART0_CKEN_MASK (0x10u) +#define PCC1_UART0_CKEN_SHIFT (4u) +#define PCC1_UART0_CKEN_WIDTH (1u) +#define PCC1_UART0_SWR_MASK (0x01u) +#define PCC1_UART0_SWR_SHIFT (0u) +#define PCC1_UART0_SWR_WIDTH (1u) + +/* UART1 Bit Fields */ +#define PCC1_UART1_SRC_MASK (0x30000u) +#define PCC1_UART1_SRC_SHIFT (16u) +#define PCC1_UART1_SRC_WIDTH (2u) +#define PCC1_UART1_CKEN_MASK (0x10u) +#define PCC1_UART1_CKEN_SHIFT (4u) +#define PCC1_UART1_CKEN_WIDTH (1u) +#define PCC1_UART1_SWR_MASK (0x01u) +#define PCC1_UART1_SWR_SHIFT (0u) +#define PCC1_UART1_SWR_WIDTH (1u) + +/* UART2 Bit Fields */ +#define PCC1_UART2_SRC_MASK (0x30000u) +#define PCC1_UART2_SRC_SHIFT (16u) +#define PCC1_UART2_SRC_WIDTH (2u) +#define PCC1_UART2_CKEN_MASK (0x10u) +#define PCC1_UART2_CKEN_SHIFT (4u) +#define PCC1_UART2_CKEN_WIDTH (1u) +#define PCC1_UART2_SWR_MASK (0x01u) +#define PCC1_UART2_SWR_SHIFT (0u) +#define PCC1_UART2_SWR_WIDTH (1u) + +/* CAN Bit Fields */ +#define PCC1_CAN_CFG_CKEN_MASK (0x20u) +#define PCC1_CAN_CFG_CKEN_SHIFT (5u) +#define PCC1_CAN_CFG_CKEN_WIDTH (1u) +#define PCC1_CAN_CKEN_MASK (0x10u) +#define PCC1_CAN_CKEN_SHIFT (4u) +#define PCC1_CAN_CKEN_WIDTH (1u) +#define PCC1_CAN_SWR_MASK (0x01u) +#define PCC1_CAN_SWR_SHIFT (0u) +#define PCC1_CAN_SWR_WIDTH (1u) + +/* I2C Bit Fields */ +#define PCC1_I2C_SRC_MASK (0x30000u) +#define PCC1_I2C_SRC_SHIFT (16u) +#define PCC1_I2C_SRC_WIDTH (2u) +#define PCC1_I2C_CKEN_MASK (0x10u) +#define PCC1_I2C_CKEN_SHIFT (4u) +#define PCC1_I2C_CKEN_WIDTH (1u) +#define PCC1_I2C_SWR_MASK (0x01u) +#define PCC1_I2C_SWR_SHIFT (0u) +#define PCC1_I2C_SWR_WIDTH (1u) + +/* I2SM Bit Fields */ +#define PCC1_I2SM_SRC_MASK (0x30000u) +#define PCC1_I2SM_SRC_SHIFT (16u) +#define PCC1_I2SM_SRC_WIDTH (2u) +#define PCC1_I2SM_DIV_MASK (0x3F00u) +#define PCC1_I2SM_DIV_SHIFT (8u) +#define PCC1_I2SM_DIV_WIDTH (6u) +#define PCC1_I2SM_CKEN_MASK (0x10u) +#define PCC1_I2SM_CKEN_SHIFT (4u) +#define PCC1_I2SM_CKEN_WIDTH (1u) +#define PCC1_I2SM_SWR_MASK (0x01u) +#define PCC1_I2SM_SWR_SHIFT (0u) +#define PCC1_I2SM_SWR_WIDTH (1u) + +/* I2SS Bit Fields */ +#define PCC1_I2SS_CKEN_MASK (0x10u) +#define PCC1_I2SS_CKEN_SHIFT (4u) +#define PCC1_I2SS_CKEN_WIDTH (1u) +#define PCC1_I2SS_SWR_MASK (0x01u) +#define PCC1_I2SS_SWR_SHIFT (0u) +#define PCC1_I2SS_SWR_WIDTH (1u) + +/* PWM0 Bit Fields */ +#define PCC1_PWM0_CKEN_MASK (0x10u) +#define PCC1_PWM0_CKEN_SHIFT (4u) +#define PCC1_PWM0_CKEN_WIDTH (1u) +#define PCC1_PWM0_SWR_MASK (0x01u) +#define PCC1_PWM0_SWR_SHIFT (0u) +#define PCC1_PWM0_SWR_WIDTH (1u) + +/* PWM1 Bit Fields */ +#define PCC1_PWM1_CKEN_MASK (0x10u) +#define PCC1_PWM1_CKEN_SHIFT (4u) +#define PCC1_PWM1_CKEN_WIDTH (1u) +#define PCC1_PWM1_SWR_MASK (0x01u) +#define PCC1_PWM1_SWR_SHIFT (0u) +#define PCC1_PWM1_SWR_WIDTH (1u) + +/* MFT0 Bit Fields */ +#define PCC1_MFT0_CKEN_MASK (0x10u) +#define PCC1_MFT0_CKEN_SHIFT (4u) +#define PCC1_MFT0_CKEN_WIDTH (1u) +#define PCC1_MFT0_SWR_MASK (0x01u) +#define PCC1_MFT0_SWR_SHIFT (0u) +#define PCC1_MFT0_SWR_WIDTH (1u) + +/* MFT1 Bit Fields */ +#define PCC1_MFT1_CKEN_MASK (0x10u) +#define PCC1_MFT1_CKEN_SHIFT (4u) +#define PCC1_MFT1_CKEN_WIDTH (1u) +#define PCC1_MFT1_SWR_MASK (0x01u) +#define PCC1_MFT1_SWR_SHIFT (0u) +#define PCC1_MFT1_SWR_WIDTH (1u) + +/* GPIO Bit Fields */ +#define PCC1_GPIO_SWR_MASK (0x01u) +#define PCC1_GPIO_SWR_SHIFT (0u) +#define PCC1_GPIO_SWR_WIDTH (1u) + +/* CMUS Bit Fields */ +#define PCC1_CMUS_CKEN_MASK (0x10u) +#define PCC1_CMUS_CKEN_SHIFT (4u) +#define PCC1_CMUS_CKEN_WIDTH (1u) +#define PCC1_CMUS_SWR_MASK (0x01u) +#define PCC1_CMUS_SWR_SHIFT (0u) +#define PCC1_CMUS_SWR_WIDTH (1u) + +/* CMUP Bit Fields */ +#define PCC1_CMUP_CKEN_MASK (0x10u) +#define PCC1_CMUP_CKEN_SHIFT (4u) +#define PCC1_CMUP_CKEN_WIDTH (1u) +#define PCC1_CMUP_SWR_MASK (0x01u) +#define PCC1_CMUP_SWR_SHIFT (0u) +#define PCC1_CMUP_SWR_WIDTH (1u) + +/* EXT_MFT0 Bit Fields */ +#define PCC1_EXT_MFT0_SRC_MASK (0x70000u) +#define PCC1_EXT_MFT0_SRC_SHIFT (16u) +#define PCC1_EXT_MFT0_SRC_WIDTH (3u) + +/* EXT_MFT1 Bit Fields */ +#define PCC1_EXT_MFT1_SRC_MASK (0x70000u) +#define PCC1_EXT_MFT1_SRC_SHIFT (16u) +#define PCC1_EXT_MFT1_SRC_WIDTH (3u) + +/* FIX_MFT0 Bit Fields */ +#define PCC1_FIX_MFT0_SRC_MASK (0x10000u) +#define PCC1_FIX_MFT0_SRC_SHIFT (16u) +#define PCC1_FIX_MFT0_SRC_WIDTH (1u) + +/* FIX_MFT1 Bit Fields */ +#define PCC1_FIX_MFT1_SRC_MASK (0x10000u) +#define PCC1_FIX_MFT1_SRC_SHIFT (16u) +#define PCC1_FIX_MFT1_SRC_WIDTH (1u) + +/* FLS_CTL Bit Fields */ +#define PCC1_FLS_CTL_CNT_SRC_MASK (0x30000u) +#define PCC1_FLS_CTL_CNT_SRC_SHIFT (16u) +#define PCC1_FLS_CTL_CNT_SRC_WIDTH (2u) +#define PCC1_FLS_CTL_CNT_DIV_MASK (0xF00u) +#define PCC1_FLS_CTL_CNT_DIV_SHIFT (8u) +#define PCC1_FLS_CTL_CNT_DIV_WIDTH (4u) +#define PCC1_FLS_CTL_CKEN_MASK (0x10u) +#define PCC1_FLS_CTL_CKEN_SHIFT (4u) +#define PCC1_FLS_CTL_CKEN_WIDTH (1u) +#define PCC1_FLS_CTL_SWR_MASK (0x01u) +#define PCC1_FLS_CTL_SWR_SHIFT (0u) +#define PCC1_FLS_CTL_SWR_WIDTH (1u) + +/* MPU Bit Fields */ +#define PCC1_MPU_CKEN_MASK (0x10u) +#define PCC1_MPU_CKEN_SHIFT (4u) +#define PCC1_MPU_CKEN_WIDTH (1u) +#define PCC1_MPU_SWR_MASK (0x01u) +#define PCC1_MPU_SWR_SHIFT (0u) +#define PCC1_MPU_SWR_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of PCC1 registers + */ +typedef struct _Pcc1RegType_ +{ + volatile uint32_t DMA; /*!< DMA clock and software reset control register, offset: 0x0 */ + volatile uint32_t MSCM; /*!< MSCM clock and software reset control register, offset: 0x4 */ + uint32_t RESERVED0[2]; /*!< Reserved register, offset: 0x8 */ + volatile uint32_t CRC; /*!< CRC clock and software reset control register, offset: 0x10 */ + volatile uint32_t EIM; /*!< EIM clock and software reset control register, offset: 0x14 */ + volatile uint32_t ERM; /*!< ERM clock and software reset control register, offset: 0x18 */ + volatile uint32_t FHU; /*!< FHU clock and software reset control register, offset: 0x1C */ + volatile uint32_t ADC; /*!< ADC clock and software reset control register, offset: 0x20 */ + uint32_t RESERVED1[1]; /*!< Reserved register, offset: 0x24 */ + volatile uint32_t PDB; /*!< PDB clock and software reset control register, offset: 0x28 */ + uint32_t RESERVED2[1]; /*!< Reserved register, offset: 0x2C */ + volatile uint32_t SPI0; /*!< SPI0 clock and software reset control register, offset: 0x30 */ + volatile uint32_t SPI1; /*!< SPI1 clock and software reset control register, offset: 0x34 */ + uint32_t RESERVED3[2]; /*!< Reserved register, offset: 0x38 */ + volatile uint32_t UART0; /*!< UART0 clock and software reset control register, offset: 0x40 */ + volatile uint32_t UART1; /*!< UART1 clock and software reset control register, offset: 0x44 */ + volatile uint32_t UART2; /*!< UART2 clock and software reset control register, offset: 0x48 */ + uint32_t RESERVED4[1]; /*!< Reserved register, offset: 0x4C */ + volatile uint32_t CAN; /*!< CAN clock and software reset control register, offset: 0x50 */ + uint32_t RESERVED5[3]; /*!< Reserved register, offset: 0x54 */ + volatile uint32_t I2C; /*!< I2C clock and software reset control register, offset: 0x60 */ + volatile uint32_t I2SM; /*!< I2SM clock and software reset control register, offset: 0x64 */ + volatile uint32_t I2SS; /*!< I2SS clock and software reset control register, offset: 0x68 */ + volatile uint32_t PWM0; /*!< PWM0 clock and software reset control register, offset: 0x6C */ + volatile uint32_t PWM1; /*!< PWM1 clock and software reset control register, offset: 0x70 */ + uint32_t RESERVED6[3]; /*!< Reserved register, offset: 0x74 */ + volatile uint32_t MFT0; /*!< MFT0 clock and software reset control register, offset: 0x80 */ + volatile uint32_t MFT1; /*!< MFT1 clock and software reset control register, offset: 0x84 */ + uint32_t RESERVED7[2]; /*!< Reserved register, offset: 0x88 */ + volatile uint32_t GPIO; /*!< GPIO clock and software reset control register, offset: 0x90 */ + volatile uint32_t CMUS; /*!< CMUS clock and software reset control register, offset: 0x94 */ + uint32_t RESERVED8[1]; /*!< Reserved register, offset: 0x98 */ + volatile uint32_t CMUP; /*!< CMUP clock and software reset control register, offset: 0x9C */ + volatile uint32_t EXT_MFT0; /*!< MFT0 external clock and software reset control register, offset: 0xA0 */ + volatile uint32_t EXT_MFT1; /*!< MFT1 external clock and software reset control register, offset: 0xA4 */ + uint32_t RESERVED9[6]; /*!< Reserved register, offset: 0xA8 */ + volatile uint32_t FIX_MFT0; /*!< MFT0 fix clock and software reset control register, offset: 0xC0 */ + volatile uint32_t FIX_MFT1; /*!< MFT1 fix clock and software reset control register, offset: 0xC4 */ + volatile uint32_t FLS_CTL; /*!< CMUP clock and software reset control register, offset: 0xC8 */ + volatile uint32_t MPU; /*!< MPU clock and software reset control register, offset: 0xCC */ +} Pcc1RegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the DMA clock enable + * + * This function gets the current DMA clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return DMA clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetDmaCkEn(const Pcc1RegType *obj) +{ + return ((obj->DMA & PCC1_DMA_CKEN_MASK) >> PCC1_DMA_CKEN_SHIFT); +} + +/*! \brief Sets the DMA clock enable + * + * This function sets the DMA clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of DMA clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetDmaCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DMA; + + tmp &= ~PCC1_DMA_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_DMA_CKEN_SHIFT)) & PCC1_DMA_CKEN_MASK); + obj->DMA = tmp; +} + +/*! \brief Gets the DMA software reset + * + * This function gets the current DMA software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return DMA software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetDmaSwR(const Pcc1RegType *obj) +{ + return ((obj->DMA & PCC1_DMA_SWR_MASK) >> PCC1_DMA_SWR_SHIFT); +} + +/*! \brief Sets the DMA software reset + * + * This function sets the DMA software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of DMA software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetDmaSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DMA; + + tmp &= ~PCC1_DMA_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_DMA_SWR_SHIFT)) & PCC1_DMA_SWR_MASK); + obj->DMA = tmp; +} + +/*! \brief Gets the MSCM clock enable + * + * This function gets the current MSCM clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MSCM clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetMscmCkEn(const Pcc1RegType *obj) +{ + return ((obj->MSCM & PCC1_MSCM_CKEN_MASK) >> PCC1_MSCM_CKEN_SHIFT); +} + +/*! \brief Sets the MSCM clock enable + * + * This function sets the MSCM clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MSCM clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetMscmCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MSCM; + + tmp &= ~PCC1_MSCM_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_MSCM_CKEN_SHIFT)) & PCC1_MSCM_CKEN_MASK); + obj->MSCM = tmp; +} + +/*! \brief Gets the MSCM software reset + * + * This function gets the current MSCM software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MSCM software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetMscmSwR(const Pcc1RegType *obj) +{ + return ((obj->MSCM & PCC1_MSCM_SWR_MASK) >> PCC1_MSCM_SWR_SHIFT); +} + +/*! \brief Sets the MSCM software reset + * + * This function sets the MSCM software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MSCM software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetMscmSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MSCM; + + tmp &= ~PCC1_MSCM_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_MSCM_SWR_SHIFT)) & PCC1_MSCM_SWR_MASK); + obj->MSCM = tmp; +} + +/*! \brief Gets the CRC clock enable + * + * This function gets the current CRC clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return CRC clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetCrcCkEn(const Pcc1RegType *obj) +{ + return ((obj->CRC & PCC1_CRC_CKEN_MASK) >> PCC1_CRC_CKEN_SHIFT); +} + +/*! \brief Sets the CRC clock enable + * + * This function sets the CRC clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of CRC clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetCrcCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CRC; + + tmp &= ~PCC1_CRC_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_CRC_CKEN_SHIFT)) & PCC1_CRC_CKEN_MASK); + obj->CRC = tmp; +} + +/*! \brief Gets the CRC software reset + * + * This function gets the current CRC software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return CRC software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetCrcSwR(const Pcc1RegType *obj) +{ + return ((obj->CRC & PCC1_CRC_SWR_MASK) >> PCC1_CRC_SWR_SHIFT); +} + +/*! \brief Sets the CRC software reset + * + * This function sets the CRC software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of CRC software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetCrcSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CRC; + + tmp &= ~PCC1_CRC_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_CRC_SWR_SHIFT)) & PCC1_CRC_SWR_MASK); + obj->CRC = tmp; +} + +/*! \brief Gets the EIM clock enable + * + * This function gets the current EIM clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return EIM clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetEimCkEn(const Pcc1RegType *obj) +{ + return ((obj->EIM & PCC1_EIM_CKEN_MASK) >> PCC1_EIM_CKEN_SHIFT); +} + +/*! \brief Sets the EIM clock enable + * + * This function sets the EIM clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of EIM clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetEimCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EIM; + + tmp &= ~PCC1_EIM_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_EIM_CKEN_SHIFT)) & PCC1_EIM_CKEN_MASK); + obj->EIM = tmp; +} + +/*! \brief Gets the EIM software reset + * + * This function gets the current EIM software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return EIM software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetEimSwR(const Pcc1RegType *obj) +{ + return ((obj->EIM & PCC1_EIM_SWR_MASK) >> PCC1_EIM_SWR_SHIFT); +} + +/*! \brief Sets the EIM software reset + * + * This function sets the EIM software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of EIM software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetEimSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EIM; + + tmp &= ~PCC1_EIM_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_EIM_SWR_SHIFT)) & PCC1_EIM_SWR_MASK); + obj->EIM = tmp; +} + +/*! \brief Gets the ERM clock enable + * + * This function gets the current ERM clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return ERM clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetErmCkEn(const Pcc1RegType *obj) +{ + return ((obj->ERM & PCC1_ERM_CKEN_MASK) >> PCC1_ERM_CKEN_SHIFT); +} + +/*! \brief Sets the ERM clock enable + * + * This function sets the ERM clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of ERM clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetErmCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ERM; + + tmp &= ~PCC1_ERM_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_ERM_CKEN_SHIFT)) & PCC1_ERM_CKEN_MASK); + obj->ERM = tmp; +} + +/*! \brief Gets the ERM software reset + * + * This function gets the current ERM software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return ERM software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetErmSwR(const Pcc1RegType *obj) +{ + return ((obj->ERM & PCC1_ERM_SWR_MASK) >> PCC1_ERM_SWR_SHIFT); +} + +/*! \brief Sets the ERM software reset + * + * This function sets the ERM software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of ERM software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetErmSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ERM; + + tmp &= ~PCC1_ERM_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_ERM_SWR_SHIFT)) & PCC1_ERM_SWR_MASK); + obj->ERM = tmp; +} + +/*! \brief Gets the FHU clock enable + * + * This function gets the current FHU clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return FHU clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetFhuCkEn(const Pcc1RegType *obj) +{ + return ((obj->FHU & PCC1_FHU_CKEN_MASK) >> PCC1_FHU_CKEN_SHIFT); +} + +/*! \brief Sets the FHU clock enable + * + * This function sets the FHU clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of FHU clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetFhuCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FHU; + + tmp &= ~PCC1_FHU_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_FHU_CKEN_SHIFT)) & PCC1_FHU_CKEN_MASK); + obj->FHU = tmp; +} + +/*! \brief Gets the FHU software reset + * + * This function gets the current FHU software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return FHU software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetFhuSwR(const Pcc1RegType *obj) +{ + return ((obj->FHU & PCC1_FHU_SWR_MASK) >> PCC1_FHU_SWR_SHIFT); +} + +/*! \brief Sets the FHU software reset + * + * This function sets the FHU software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of FHU software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetFhuSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FHU; + + tmp &= ~PCC1_FHU_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_FHU_SWR_SHIFT)) & PCC1_FHU_SWR_MASK); + obj->FHU = tmp; +} + +/*! \brief Gets the ADC0 module function clock source + * + * This function gets the current ADC0 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return ADC0 module function clock source + * - 0h : clk_sirc + * - 1h : clk_sosc + * - 2h : clk_pll + * - 3h : clk_sirc + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetAdcSrc(const Pcc1RegType *obj) +{ + return ((obj->ADC & PCC1_ADC_SRC_MASK) >> PCC1_ADC_SRC_SHIFT); +} + +/*! \brief Sets the ADC0 module function clock source + * + * This function sets the ADC0 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of ADC0 module function clock source + * - 0h : clk_sirc + * - 1h : clk_sosc + * - 2h : clk_pll + * - 3h : clk_sirc + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetAdcSrc(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~PCC1_ADC_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_ADC_SRC_SHIFT)) & PCC1_ADC_SRC_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the module function clock divide ration + * + * This function gets the current module function clock divide ration. + * + * \param[in] obj : pointer to PCC1 register instance + * \return module function clock divide ration + * - 0h : 1 + * - 1h : 2 + * - 2h : 4 + * - 3h : 8 + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetAdcDiv(const Pcc1RegType *obj) +{ + return ((obj->ADC & PCC1_ADC_DIV_MASK) >> PCC1_ADC_DIV_SHIFT); +} + +/*! \brief Sets the module function clock divide ration + * + * This function sets the module function clock divide ration. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of module function clock divide ration + * - 0h : 1 + * - 1h : 2 + * - 2h : 4 + * - 3h : 8 + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetAdcDiv(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~PCC1_ADC_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_ADC_DIV_SHIFT)) & PCC1_ADC_DIV_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the ADC0 clock enable + * + * This function gets the current ADC0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return ADC0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetAdcCkEn(const Pcc1RegType *obj) +{ + return ((obj->ADC & PCC1_ADC_CKEN_MASK) >> PCC1_ADC_CKEN_SHIFT); +} + +/*! \brief Sets the ADC0 clock enable + * + * This function sets the ADC0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of ADC0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetAdcCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~PCC1_ADC_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_ADC_CKEN_SHIFT)) & PCC1_ADC_CKEN_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the ADC0 software reset + * + * This function gets the current ADC0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return ADC0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetAdcSwR(const Pcc1RegType *obj) +{ + return ((obj->ADC & PCC1_ADC_SWR_MASK) >> PCC1_ADC_SWR_SHIFT); +} + +/*! \brief Sets the ADC0 software reset + * + * This function sets the ADC0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of ADC0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetAdcSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~PCC1_ADC_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_ADC_SWR_SHIFT)) & PCC1_ADC_SWR_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the PDB0 clock enable + * + * This function gets the current PDB0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return PDB0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetPdbCkEn(const Pcc1RegType *obj) +{ + return ((obj->PDB & PCC1_PDB_CKEN_MASK) >> PCC1_PDB_CKEN_SHIFT); +} + +/*! \brief Sets the PDB0 clock enable + * + * This function sets the PDB0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of PDB0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetPdbCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PDB; + + tmp &= ~PCC1_PDB_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_PDB_CKEN_SHIFT)) & PCC1_PDB_CKEN_MASK); + obj->PDB = tmp; +} + +/*! \brief Gets the PDB0 software reset + * + * This function gets the current PDB0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return PDB0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetPdbSwR(const Pcc1RegType *obj) +{ + return ((obj->PDB & PCC1_PDB_SWR_MASK) >> PCC1_PDB_SWR_SHIFT); +} + +/*! \brief Sets the PDB0 software reset + * + * This function sets the PDB0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of PDB0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetPdbSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PDB; + + tmp &= ~PCC1_PDB_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_PDB_SWR_SHIFT)) & PCC1_PDB_SWR_MASK); + obj->PDB = tmp; +} + +/*! \brief Gets the SPI0 module function clock source + * + * This function gets the current SPI0 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return SPI0 module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetSpi0Src(const Pcc1RegType *obj) +{ + return ((obj->SPI0 & PCC1_SPI0_SRC_MASK) >> PCC1_SPI0_SRC_SHIFT); +} + +/*! \brief Sets the SPI0 module function clock source + * + * This function sets the SPI0 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of SPI0 module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetSpi0Src(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SPI0; + + tmp &= ~PCC1_SPI0_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_SPI0_SRC_SHIFT)) & PCC1_SPI0_SRC_MASK); + obj->SPI0 = tmp; +} + +/*! \brief Gets the SPI0 clock enable + * + * This function gets the current SPI0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return SPI0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetSpi0CkEn(const Pcc1RegType *obj) +{ + return ((obj->SPI0 & PCC1_SPI0_CKEN_MASK) >> PCC1_SPI0_CKEN_SHIFT); +} + +/*! \brief Sets the SPI0 clock enable + * + * This function sets the SPI0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of SPI0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetSpi0CkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SPI0; + + tmp &= ~PCC1_SPI0_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_SPI0_CKEN_SHIFT)) & PCC1_SPI0_CKEN_MASK); + obj->SPI0 = tmp; +} + +/*! \brief Gets the SPI0 software reset + * + * This function gets the current SPI0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return SPI0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetSpi0SwR(const Pcc1RegType *obj) +{ + return ((obj->SPI0 & PCC1_SPI0_SWR_MASK) >> PCC1_SPI0_SWR_SHIFT); +} + +/*! \brief Sets the SPI0 software reset + * + * This function sets the SPI0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of SPI0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetSpi0SwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SPI0; + + tmp &= ~PCC1_SPI0_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_SPI0_SWR_SHIFT)) & PCC1_SPI0_SWR_MASK); + obj->SPI0 = tmp; +} + +/*! \brief Gets the SPI1 module function clock source + * + * This function gets the current SPI1 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return SPI1 module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetSpi1Src(const Pcc1RegType *obj) +{ + return ((obj->SPI1 & PCC1_SPI1_SRC_MASK) >> PCC1_SPI1_SRC_SHIFT); +} + +/*! \brief Sets the SPI1 module function clock source + * + * This function sets the SPI1 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of SPI1 module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetSpi1Src(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SPI1; + + tmp &= ~PCC1_SPI1_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_SPI1_SRC_SHIFT)) & PCC1_SPI1_SRC_MASK); + obj->SPI1 = tmp; +} + +/*! \brief Gets the SPI1 clock enable + * + * This function gets the current SPI1 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return SPI1 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetSpi1CkEn(const Pcc1RegType *obj) +{ + return ((obj->SPI1 & PCC1_SPI1_CKEN_MASK) >> PCC1_SPI1_CKEN_SHIFT); +} + +/*! \brief Sets the SPI1 clock enable + * + * This function sets the SPI1 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of SPI1 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetSpi1CkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SPI1; + + tmp &= ~PCC1_SPI1_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_SPI1_CKEN_SHIFT)) & PCC1_SPI1_CKEN_MASK); + obj->SPI1 = tmp; +} + +/*! \brief Gets the SPI1 software reset + * + * This function gets the current SPI1 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return SPI1 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetSpi1SwR(const Pcc1RegType *obj) +{ + return ((obj->SPI1 & PCC1_SPI1_SWR_MASK) >> PCC1_SPI1_SWR_SHIFT); +} + +/*! \brief Sets the SPI1 software reset + * + * This function sets the SPI1 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of SPI1 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetSpi1SwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SPI1; + + tmp &= ~PCC1_SPI1_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_SPI1_SWR_SHIFT)) & PCC1_SPI1_SWR_MASK); + obj->SPI1 = tmp; +} + +/*! \brief Gets the UART0 module function clock source + * + * This function gets the current UART0 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return UART0 module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetUart0Src(const Pcc1RegType *obj) +{ + return ((obj->UART0 & PCC1_UART0_SRC_MASK) >> PCC1_UART0_SRC_SHIFT); +} + +/*! \brief Sets the UART0 module function clock source + * + * This function sets the UART0 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of UART0 module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetUart0Src(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->UART0; + + tmp &= ~PCC1_UART0_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_UART0_SRC_SHIFT)) & PCC1_UART0_SRC_MASK); + obj->UART0 = tmp; +} + +/*! \brief Gets the UART0 clock enable + * + * This function gets the current UART0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return UART0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetUart0CkEn(const Pcc1RegType *obj) +{ + return ((obj->UART0 & PCC1_UART0_CKEN_MASK) >> PCC1_UART0_CKEN_SHIFT); +} + +/*! \brief Sets the UART0 clock enable + * + * This function sets the UART0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of UART0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetUart0CkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->UART0; + + tmp &= ~PCC1_UART0_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_UART0_CKEN_SHIFT)) & PCC1_UART0_CKEN_MASK); + obj->UART0 = tmp; +} + +/*! \brief Gets the UART0 software reset + * + * This function gets the current UART0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return UART0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetUart0SwR(const Pcc1RegType *obj) +{ + return ((obj->UART0 & PCC1_UART0_SWR_MASK) >> PCC1_UART0_SWR_SHIFT); +} + +/*! \brief Sets the UART0 software reset + * + * This function sets the UART0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of UART0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetUart0SwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->UART0; + + tmp &= ~PCC1_UART0_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_UART0_SWR_SHIFT)) & PCC1_UART0_SWR_MASK); + obj->UART0 = tmp; +} + +/*! \brief Gets the UART1 module function clock source + * + * This function gets the current UART1 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return UART1 module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetUart1Src(const Pcc1RegType *obj) +{ + return ((obj->UART1 & PCC1_UART1_SRC_MASK) >> PCC1_UART1_SRC_SHIFT); +} + +/*! \brief Sets the UART1 module function clock source + * + * This function sets the UART1 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of UART1 module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetUart1Src(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->UART1; + + tmp &= ~PCC1_UART1_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_UART1_SRC_SHIFT)) & PCC1_UART1_SRC_MASK); + obj->UART1 = tmp; +} + +/*! \brief Gets the UART1 clock enable + * + * This function gets the current UART1 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return UART1 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetUart1CkEn(const Pcc1RegType *obj) +{ + return ((obj->UART1 & PCC1_UART1_CKEN_MASK) >> PCC1_UART1_CKEN_SHIFT); +} + +/*! \brief Sets the UART1 clock enable + * + * This function sets the UART1 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of UART1 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetUart1CkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->UART1; + + tmp &= ~PCC1_UART1_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_UART1_CKEN_SHIFT)) & PCC1_UART1_CKEN_MASK); + obj->UART1 = tmp; +} + +/*! \brief Gets the UART1 software reset + * + * This function gets the current UART1 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return UART1 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetUart1SwR(const Pcc1RegType *obj) +{ + return ((obj->UART1 & PCC1_UART1_SWR_MASK) >> PCC1_UART1_SWR_SHIFT); +} + +/*! \brief Sets the UART1 software reset + * + * This function sets the UART1 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of UART1 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetUart1SwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->UART1; + + tmp &= ~PCC1_UART1_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_UART1_SWR_SHIFT)) & PCC1_UART1_SWR_MASK); + obj->UART1 = tmp; +} + +/*! \brief Gets the UART2 module function clock source + * + * This function gets the current UART2 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return UART2 module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetUart2Src(const Pcc1RegType *obj) +{ + return ((obj->UART2 & PCC1_UART2_SRC_MASK) >> PCC1_UART2_SRC_SHIFT); +} + +/*! \brief Sets the UART2 module function clock source + * + * This function sets the UART2 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of UART2 module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetUart2Src(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->UART2; + + tmp &= ~PCC1_UART2_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_UART2_SRC_SHIFT)) & PCC1_UART2_SRC_MASK); + obj->UART2 = tmp; +} + +/*! \brief Gets the UART2 clock enable + * + * This function gets the current UART2 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return UART2 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetUart2CkEn(const Pcc1RegType *obj) +{ + return ((obj->UART2 & PCC1_UART2_CKEN_MASK) >> PCC1_UART2_CKEN_SHIFT); +} + +/*! \brief Sets the UART2 clock enable + * + * This function sets the UART2 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of UART2 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetUart2CkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->UART2; + + tmp &= ~PCC1_UART2_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_UART2_CKEN_SHIFT)) & PCC1_UART2_CKEN_MASK); + obj->UART2 = tmp; +} + +/*! \brief Gets the UART2 software reset + * + * This function gets the current UART2 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return UART2 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetUart2SwR(const Pcc1RegType *obj) +{ + return ((obj->UART2 & PCC1_UART2_SWR_MASK) >> PCC1_UART2_SWR_SHIFT); +} + +/*! \brief Sets the UART2 software reset + * + * This function sets the UART2 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of UART2 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetUart2SwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->UART2; + + tmp &= ~PCC1_UART2_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_UART2_SWR_SHIFT)) & PCC1_UART2_SWR_MASK); + obj->UART2 = tmp; +} + +/*! \brief Gets the CAN configure clock enable + * + * This function gets the current CAN configure clock enable. + * It works for both function clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return CAN configure clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetCanCfgCkEn(const Pcc1RegType *obj) +{ + return ((obj->CAN & PCC1_CAN_CFG_CKEN_MASK) >> PCC1_CAN_CFG_CKEN_SHIFT); +} + +/*! \brief Sets the CAN configure clock enable + * + * This function sets the CAN configure clock enable. + * It works for both function clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of CAN configure clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetCanCfgCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CAN; + + tmp &= ~PCC1_CAN_CFG_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_CAN_CFG_CKEN_SHIFT)) & PCC1_CAN_CFG_CKEN_MASK); + obj->CAN = tmp; +} + +/*! \brief Gets the CAN work clock enable + * + * This function gets the current CAN work clock enable. + * It works for both function clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return CAN work clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetCanCkEn(const Pcc1RegType *obj) +{ + return ((obj->CAN & PCC1_CAN_CKEN_MASK) >> PCC1_CAN_CKEN_SHIFT); +} + +/*! \brief Sets the CAN work clock enable + * + * This function sets the CAN work clock enable. + * It works for both function clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of CAN work clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetCanCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CAN; + + tmp &= ~PCC1_CAN_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_CAN_CKEN_SHIFT)) & PCC1_CAN_CKEN_MASK); + obj->CAN = tmp; +} + +/*! \brief Gets the CAN software reset + * + * This function gets the current CAN software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return CAN software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetCanSwR(const Pcc1RegType *obj) +{ + return ((obj->CAN & PCC1_CAN_SWR_MASK) >> PCC1_CAN_SWR_SHIFT); +} + +/*! \brief Sets the CAN software reset + * + * This function sets the CAN software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of CAN software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetCanSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CAN; + + tmp &= ~PCC1_CAN_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_CAN_SWR_SHIFT)) & PCC1_CAN_SWR_MASK); + obj->CAN = tmp; +} + +/*! \brief Gets the I2C module function clock source + * + * This function gets the current I2C module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return I2C module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetI2CSrc(const Pcc1RegType *obj) +{ + return ((obj->I2C & PCC1_I2C_SRC_MASK) >> PCC1_I2C_SRC_SHIFT); +} + +/*! \brief Sets the I2C module function clock source + * + * This function sets the I2C module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of I2C module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetI2CSrc(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2C; + + tmp &= ~PCC1_I2C_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_I2C_SRC_SHIFT)) & PCC1_I2C_SRC_MASK); + obj->I2C = tmp; +} + +/*! \brief Gets the I2C clock enable + * + * This function gets the current I2C clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return I2C clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetI2CCkEn(const Pcc1RegType *obj) +{ + return ((obj->I2C & PCC1_I2C_CKEN_MASK) >> PCC1_I2C_CKEN_SHIFT); +} + +/*! \brief Sets the I2C clock enable + * + * This function sets the I2C clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of I2C clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetI2CCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2C; + + tmp &= ~PCC1_I2C_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_I2C_CKEN_SHIFT)) & PCC1_I2C_CKEN_MASK); + obj->I2C = tmp; +} + +/*! \brief Gets the I2C software reset + * + * This function gets the current I2C software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return I2C software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetI2CSwR(const Pcc1RegType *obj) +{ + return ((obj->I2C & PCC1_I2C_SWR_MASK) >> PCC1_I2C_SWR_SHIFT); +} + +/*! \brief Sets the I2C software reset + * + * This function sets the I2C software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of I2C software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetI2CSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2C; + + tmp &= ~PCC1_I2C_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_I2C_SWR_SHIFT)) & PCC1_I2C_SWR_MASK); + obj->I2C = tmp; +} + +/*! \brief Gets the I2SM module function clock source + * + * This function gets the current I2SM module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return I2SM module function clock source + * - 0h : clk_sirc + * - 1h : clk_sosc + * - 2h : clk_pll + * - 3h : clk_sirc + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetI2SMSrc(const Pcc1RegType *obj) +{ + return ((obj->I2SM & PCC1_I2SM_SRC_MASK) >> PCC1_I2SM_SRC_SHIFT); +} + +/*! \brief Sets the I2SM module function clock source + * + * This function sets the I2SM module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of I2SM module function clock source + * - 0h : clk_sirc + * - 1h : clk_sosc + * - 2h : clk_pll + * - 3h : clk_sirc + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetI2SMSrc(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2SM; + + tmp &= ~PCC1_I2SM_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_I2SM_SRC_SHIFT)) & PCC1_I2SM_SRC_MASK); + obj->I2SM = tmp; +} + +/*! \brief Gets the I2S MST module clock divide ratio + * + * This function gets the current I2S MST module clock divide ratio. + * + * \param[in] obj : pointer to PCC1 register instance + * \return I2S MST module clock divide ratio + * - 0h : 2 + * - 1h : 2 + * - 2h : 3 + * . + * . + * . + * - 63h : 64 + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetI2SMDiv(const Pcc1RegType *obj) +{ + return ((obj->I2SM & PCC1_I2SM_DIV_MASK) >> PCC1_I2SM_DIV_SHIFT); +} + +/*! \brief Sets the I2S MST module clock divide ratio + * + * This function sets the I2S MST module clock divide ratio. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of I2S MST module clock divide ratio + * - 0h : 2 + * - 1h : 2 + * - 2h : 3 + * . + * . + * . + * - 63h : 64 + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetI2SMDiv(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2SM; + + tmp &= ~PCC1_I2SM_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_I2SM_DIV_SHIFT)) & PCC1_I2SM_DIV_MASK); + obj->I2SM = tmp; +} + +/*! \brief Gets the I2S master clock enable + * + * This function gets the current I2S master clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return I2S master clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetI2SMCkEn(const Pcc1RegType *obj) +{ + return ((obj->I2SM & PCC1_I2SM_CKEN_MASK) >> PCC1_I2SM_CKEN_SHIFT); +} + +/*! \brief Sets the I2S master clock enable + * + * This function sets the I2S master clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of I2S master clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetI2SMCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2SM; + + tmp &= ~PCC1_I2SM_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_I2SM_CKEN_SHIFT)) & PCC1_I2SM_CKEN_MASK); + obj->I2SM = tmp; +} + +/*! \brief Gets the I2S MASTER software reset + * + * This function gets the current I2S MASTER software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return I2S MASTER software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetI2SMSwR(const Pcc1RegType *obj) +{ + return ((obj->I2SM & PCC1_I2SM_SWR_MASK) >> PCC1_I2SM_SWR_SHIFT); +} + +/*! \brief Sets the I2S MASTER software reset + * + * This function sets the I2S MASTER software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of I2S MASTER software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetI2SMSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2SM; + + tmp &= ~PCC1_I2SM_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_I2SM_SWR_SHIFT)) & PCC1_I2SM_SWR_MASK); + obj->I2SM = tmp; +} + +/*! \brief Gets the I2S slave clock enable + * + * This function gets the current I2S slave clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return I2S slave clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetI2SSCkEn(const Pcc1RegType *obj) +{ + return ((obj->I2SS & PCC1_I2SS_CKEN_MASK) >> PCC1_I2SS_CKEN_SHIFT); +} + +/*! \brief Sets the I2S slave clock enable + * + * This function sets the I2S slave clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of I2S slave clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetI2SSCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2SS; + + tmp &= ~PCC1_I2SS_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_I2SS_CKEN_SHIFT)) & PCC1_I2SS_CKEN_MASK); + obj->I2SS = tmp; +} + +/*! \brief Gets the I2S SLAVE software reset + * + * This function gets the current I2S SLAVE software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return I2S SLAVE software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetI2SSSwR(const Pcc1RegType *obj) +{ + return ((obj->I2SS & PCC1_I2SS_SWR_MASK) >> PCC1_I2SS_SWR_SHIFT); +} + +/*! \brief Sets the I2S SLAVE software reset + * + * This function sets the I2S SLAVE software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of I2S SLAVE software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetI2SSSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2SS; + + tmp &= ~PCC1_I2SS_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_I2SS_SWR_SHIFT)) & PCC1_I2SS_SWR_MASK); + obj->I2SS = tmp; +} + +/*! \brief Gets the PWM0 clock enable + * + * This function gets the current PWM0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return PWM0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetPwm0CkEn(const Pcc1RegType *obj) +{ + return ((obj->PWM0 & PCC1_PWM0_CKEN_MASK) >> PCC1_PWM0_CKEN_SHIFT); +} + +/*! \brief Sets the PWM0 clock enable + * + * This function sets the PWM0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of PWM0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetPwm0CkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWM0; + + tmp &= ~PCC1_PWM0_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_PWM0_CKEN_SHIFT)) & PCC1_PWM0_CKEN_MASK); + obj->PWM0 = tmp; +} + +/*! \brief Gets the PWM0 software reset + * + * This function gets the current PWM0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return PWM0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetPwm0SwR(const Pcc1RegType *obj) +{ + return ((obj->PWM0 & PCC1_PWM0_SWR_MASK) >> PCC1_PWM0_SWR_SHIFT); +} + +/*! \brief Sets the PWM0 software reset + * + * This function sets the PWM0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of PWM0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetPwm0SwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWM0; + + tmp &= ~PCC1_PWM0_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_PWM0_SWR_SHIFT)) & PCC1_PWM0_SWR_MASK); + obj->PWM0 = tmp; +} + +/*! \brief Gets the PWM1 clock enable + * + * This function gets the current PWM1 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return PWM1 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetPwm1CkEn(const Pcc1RegType *obj) +{ + return ((obj->PWM1 & PCC1_PWM1_CKEN_MASK) >> PCC1_PWM1_CKEN_SHIFT); +} + +/*! \brief Sets the PWM1 clock enable + * + * This function sets the PWM1 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of PWM1 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetPwm1CkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWM1; + + tmp &= ~PCC1_PWM1_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_PWM1_CKEN_SHIFT)) & PCC1_PWM1_CKEN_MASK); + obj->PWM1 = tmp; +} + +/*! \brief Gets the PWM1 software reset + * + * This function gets the current PWM1 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return PWM1 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetPwm1SwR(const Pcc1RegType *obj) +{ + return ((obj->PWM1 & PCC1_PWM1_SWR_MASK) >> PCC1_PWM1_SWR_SHIFT); +} + +/*! \brief Sets the PWM1 software reset + * + * This function sets the PWM1 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of PWM1 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetPwm1SwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWM1; + + tmp &= ~PCC1_PWM1_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_PWM1_SWR_SHIFT)) & PCC1_PWM1_SWR_MASK); + obj->PWM1 = tmp; +} + +/*! \brief Gets the MFT0 clock enable + * + * This function gets the current MFT0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MFT0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetMft0CkEn(const Pcc1RegType *obj) +{ + return ((obj->MFT0 & PCC1_MFT0_CKEN_MASK) >> PCC1_MFT0_CKEN_SHIFT); +} + +/*! \brief Sets the MFT0 clock enable + * + * This function sets the MFT0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MFT0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetMft0CkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT0; + + tmp &= ~PCC1_MFT0_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_MFT0_CKEN_SHIFT)) & PCC1_MFT0_CKEN_MASK); + obj->MFT0 = tmp; +} + +/*! \brief Gets the MFT0 software reset + * + * This function gets the current MFT0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MFT0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetMft0SwR(const Pcc1RegType *obj) +{ + return ((obj->MFT0 & PCC1_MFT0_SWR_MASK) >> PCC1_MFT0_SWR_SHIFT); +} + +/*! \brief Sets the MFT0 software reset + * + * This function sets the MFT0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MFT0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetMft0SwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT0; + + tmp &= ~PCC1_MFT0_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_MFT0_SWR_SHIFT)) & PCC1_MFT0_SWR_MASK); + obj->MFT0 = tmp; +} + +/*! \brief Gets the MFT1 clock enable + * + * This function gets the current MFT1 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MFT1 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetMft1CkEn(const Pcc1RegType *obj) +{ + return ((obj->MFT1 & PCC1_MFT1_CKEN_MASK) >> PCC1_MFT1_CKEN_SHIFT); +} + +/*! \brief Sets the MFT1 clock enable + * + * This function sets the MFT1 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MFT1 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetMft1CkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT1; + + tmp &= ~PCC1_MFT1_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_MFT1_CKEN_SHIFT)) & PCC1_MFT1_CKEN_MASK); + obj->MFT1 = tmp; +} + +/*! \brief Gets the MFT1 software reset + * + * This function gets the current MFT1 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MFT1 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetMft1SwR(const Pcc1RegType *obj) +{ + return ((obj->MFT1 & PCC1_MFT1_SWR_MASK) >> PCC1_MFT1_SWR_SHIFT); +} + +/*! \brief Sets the MFT1 software reset + * + * This function sets the MFT1 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MFT1 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetMft1SwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT1; + + tmp &= ~PCC1_MFT1_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_MFT1_SWR_SHIFT)) & PCC1_MFT1_SWR_MASK); + obj->MFT1 = tmp; +} + +/*! \brief Gets the GPIO software reset + * + * This function gets the current GPIO software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return GPIO software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetGpioSwR(const Pcc1RegType *obj) +{ + return ((obj->GPIO & PCC1_GPIO_SWR_MASK) >> PCC1_GPIO_SWR_SHIFT); +} + +/*! \brief Sets the GPIO software reset + * + * This function sets the GPIO software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of GPIO software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetGpioSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->GPIO; + + tmp &= ~PCC1_GPIO_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_GPIO_SWR_SHIFT)) & PCC1_GPIO_SWR_MASK); + obj->GPIO = tmp; +} + +/*! \brief Gets the CMUS clock enable + * + * This function gets the current CMUS clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return CMUS clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetCmusCkEn(const Pcc1RegType *obj) +{ + return ((obj->CMUS & PCC1_CMUS_CKEN_MASK) >> PCC1_CMUS_CKEN_SHIFT); +} + +/*! \brief Sets the CMUS clock enable + * + * This function sets the CMUS clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of CMUS clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetCmusCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CMUS; + + tmp &= ~PCC1_CMUS_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_CMUS_CKEN_SHIFT)) & PCC1_CMUS_CKEN_MASK); + obj->CMUS = tmp; +} + +/*! \brief Gets the CMUS software reset + * + * This function gets the current CMUS software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return CMUS software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetCmusSwR(const Pcc1RegType *obj) +{ + return ((obj->CMUS & PCC1_CMUS_SWR_MASK) >> PCC1_CMUS_SWR_SHIFT); +} + +/*! \brief Sets the CMUS software reset + * + * This function sets the CMUS software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of CMUS software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetCmusSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CMUS; + + tmp &= ~PCC1_CMUS_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_CMUS_SWR_SHIFT)) & PCC1_CMUS_SWR_MASK); + obj->CMUS = tmp; +} + +/*! \brief Gets the CMUP clock enable + * + * This function gets the current CMUP clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return CMUP clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetCmupCkEn(const Pcc1RegType *obj) +{ + return ((obj->CMUP & PCC1_CMUP_CKEN_MASK) >> PCC1_CMUP_CKEN_SHIFT); +} + +/*! \brief Sets the CMUP clock enable + * + * This function sets the CMUP clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of CMUP clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetCmupCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CMUP; + + tmp &= ~PCC1_CMUP_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_CMUP_CKEN_SHIFT)) & PCC1_CMUP_CKEN_MASK); + obj->CMUP = tmp; +} + +/*! \brief Gets the CMUP software reset + * + * This function gets the current CMUP software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return CMUP software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetCmupSwR(const Pcc1RegType *obj) +{ + return ((obj->CMUP & PCC1_CMUP_SWR_MASK) >> PCC1_CMUP_SWR_SHIFT); +} + +/*! \brief Sets the CMUP software reset + * + * This function sets the CMUP software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of CMUP software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetCmupSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CMUP; + + tmp &= ~PCC1_CMUP_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_CMUP_SWR_SHIFT)) & PCC1_CMUP_SWR_MASK); + obj->CMUP = tmp; +} + +/*! \brief Gets the MFT0 external clock source + * + * This function gets the current MFT0 external clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MFT0 external clock source + * - 0h : TCLK0 + * - 1h : TCLK1 + * - 2h : TCLK2 + * - 3h : clk_sirc_div_mft + * - 4h : clk_sosc_div_mft + * - 5h : clk_pll_div_mft + * - 6h : clk_sirc_div_mft + * - 7h : clk_sirc_div_mft + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetExtMft0Src(const Pcc1RegType *obj) +{ + return ((obj->EXT_MFT0 & PCC1_EXT_MFT0_SRC_MASK) >> PCC1_EXT_MFT0_SRC_SHIFT); +} + +/*! \brief Sets the MFT0 external clock source + * + * This function sets the MFT0 external clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MFT0 external clock source + * - 0h : TCLK0 + * - 1h : TCLK1 + * - 2h : TCLK2 + * - 3h : clk_sirc_div_mft + * - 4h : clk_sosc_div_mft + * - 5h : clk_pll_div_mft + * - 6h : clk_sirc_div_mft + * - 7h : clk_sirc_div_mft + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetExtMft0Src(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXT_MFT0; + + tmp &= ~PCC1_EXT_MFT0_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_EXT_MFT0_SRC_SHIFT)) & PCC1_EXT_MFT0_SRC_MASK); + obj->EXT_MFT0 = tmp; +} + +/*! \brief Gets the MFT1 external clock source + * + * This function gets the current MFT1 external clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MFT1 external clock source + * - 0h : TCLK0 + * - 1h : TCLK1 + * - 2h : TCLK2 + * - 3h : clk_sirc_div_mft + * - 4h : clk_sosc_div_mft + * - 5h : clk_pll_div_mft + * - 6h : clk_sirc_div_mft + * - 7h : clk_sirc_div_mft + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetExtMft1Src(const Pcc1RegType *obj) +{ + return ((obj->EXT_MFT1 & PCC1_EXT_MFT1_SRC_MASK) >> PCC1_EXT_MFT1_SRC_SHIFT); +} + +/*! \brief Sets the MFT1 external clock source + * + * This function sets the MFT1 external clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MFT1 external clock source + * - 0h : TCLK0 + * - 1h : TCLK1 + * - 2h : TCLK2 + * - 3h : clk_sirc_div_mft + * - 4h : clk_sosc_div_mft + * - 5h : clk_pll_div_mft + * - 6h : clk_sirc_div_mft + * - 7h : clk_sirc_div_mft + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetExtMft1Src(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXT_MFT1; + + tmp &= ~PCC1_EXT_MFT1_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_EXT_MFT1_SRC_SHIFT)) & PCC1_EXT_MFT1_SRC_MASK); + obj->EXT_MFT1 = tmp; +} + +/*! \brief Gets the MFT0 fix clock source + * + * This function gets the current MFT0 fix clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MFT0 fix clock source + * - 0b : clk_lpo32 + * - 1b : RTC_CLKIN + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetFixMft0Src(const Pcc1RegType *obj) +{ + return ((obj->FIX_MFT0 & PCC1_FIX_MFT0_SRC_MASK) >> PCC1_FIX_MFT0_SRC_SHIFT); +} + +/*! \brief Sets the MFT0 fix clock source + * + * This function sets the MFT0 fix clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MFT0 fix clock source + * - 0b : clk_lpo32 + * - 1b : RTC_CLKIN + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetFixMft0Src(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FIX_MFT0; + + tmp &= ~PCC1_FIX_MFT0_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_FIX_MFT0_SRC_SHIFT)) & PCC1_FIX_MFT0_SRC_MASK); + obj->FIX_MFT0 = tmp; +} + +/*! \brief Gets the MFT1 fix clock source + * + * This function gets the current MFT1 fix clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MFT1 fix clock source + * - 0b : clk_lpo32 + * - 1b : RTC_CLKIN + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetFixMft1Src(const Pcc1RegType *obj) +{ + return ((obj->FIX_MFT1 & PCC1_FIX_MFT1_SRC_MASK) >> PCC1_FIX_MFT1_SRC_SHIFT); +} + +/*! \brief Sets the MFT1 fix clock source + * + * This function sets the MFT1 fix clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MFT1 fix clock source + * - 0b : clk_lpo32 + * - 1b : RTC_CLKIN + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetFixMft1Src(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FIX_MFT1; + + tmp &= ~PCC1_FIX_MFT1_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_FIX_MFT1_SRC_SHIFT)) & PCC1_FIX_MFT1_SRC_MASK); + obj->FIX_MFT1 = tmp; +} + +/*! \brief Gets the flash_ctrl module counter clock source + * + * This function gets the current flash_ctrl module counter clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return flash_ctrl module counter clock source + * - 0h : clk_sirc + * - 1h : clk_sosc + * - 2h : clk_pll + * - 3h : clk_sirc + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetFlsCtlCntSrc(const Pcc1RegType *obj) +{ + return ((obj->FLS_CTL & PCC1_FLS_CTL_CNT_SRC_MASK) >> PCC1_FLS_CTL_CNT_SRC_SHIFT); +} + +/*! \brief Sets the flash_ctrl module counter clock source + * + * This function sets the flash_ctrl module counter clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of flash_ctrl module counter clock source + * - 0h : clk_sirc + * - 1h : clk_sosc + * - 2h : clk_pll + * - 3h : clk_sirc + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetFlsCtlCntSrc(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLS_CTL; + + tmp &= ~PCC1_FLS_CTL_CNT_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_FLS_CTL_CNT_SRC_SHIFT)) & PCC1_FLS_CTL_CNT_SRC_MASK); + obj->FLS_CTL = tmp; +} + +/*! \brief Gets the FLS_CTRL modulecounter clock divide ratio + * + * This function gets the current FLS_CTRL modulecounter clock divide ratio. + * + * \param[in] obj : pointer to PCC1 register instance + * \return FLS_CTRL modulecounter clock divide ratio + * - 0h : 1 + * - 1h : 2 + * - 2h : 3 + * . + * . + * . + * - Fh : 16 + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetFlsCtlCntDiv(const Pcc1RegType *obj) +{ + return ((obj->FLS_CTL & PCC1_FLS_CTL_CNT_DIV_MASK) >> PCC1_FLS_CTL_CNT_DIV_SHIFT); +} + +/*! \brief Sets the FLS_CTRL modulecounter clock divide ratio + * + * This function sets the FLS_CTRL modulecounter clock divide ratio. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of FLS_CTRL modulecounter clock divide ratio + * - 0h : 1 + * - 1h : 2 + * - 2h : 3 + * . + * . + * . + * - Fh : 16 + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetFlsCtlCntDiv(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLS_CTL; + + tmp &= ~PCC1_FLS_CTL_CNT_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_FLS_CTL_CNT_DIV_SHIFT)) & PCC1_FLS_CTL_CNT_DIV_MASK); + obj->FLS_CTL = tmp; +} + +/*! \brief Gets the FLS_CTL clock enable + * + * This function gets the current FLS_CTL clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return FLS_CTL clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetFlsCtlCkEn(const Pcc1RegType *obj) +{ + return ((obj->FLS_CTL & PCC1_FLS_CTL_CKEN_MASK) >> PCC1_FLS_CTL_CKEN_SHIFT); +} + +/*! \brief Sets the FLS_CTL clock enable + * + * This function sets the FLS_CTL clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of FLS_CTL clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetFlsCtlCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLS_CTL; + + tmp &= ~PCC1_FLS_CTL_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_FLS_CTL_CKEN_SHIFT)) & PCC1_FLS_CTL_CKEN_MASK); + obj->FLS_CTL = tmp; +} + +/*! \brief Gets the FLS_CTL software reset + * + * This function gets the current FLS_CTL software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return FLS_CTL software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetFlsCtlSwR(const Pcc1RegType *obj) +{ + return ((obj->FLS_CTL & PCC1_FLS_CTL_SWR_MASK) >> PCC1_FLS_CTL_SWR_SHIFT); +} + +/*! \brief Sets the FLS_CTL software reset + * + * This function sets the FLS_CTL software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of FLS_CTL software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetFlsCtlSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLS_CTL; + + tmp &= ~PCC1_FLS_CTL_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_FLS_CTL_SWR_SHIFT)) & PCC1_FLS_CTL_SWR_MASK); + obj->FLS_CTL = tmp; +} + +/*! \brief Gets the MPU clock enable + * + * This function gets the current MPU clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MPU clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetMpuCkEn(const Pcc1RegType *obj) +{ + return ((obj->MPU & PCC1_MPU_CKEN_MASK) >> PCC1_MPU_CKEN_SHIFT); +} + +/*! \brief Sets the MPU clock enable + * + * This function sets the MPU clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MPU clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetMpuCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MPU; + + tmp &= ~PCC1_MPU_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_MPU_CKEN_SHIFT)) & PCC1_MPU_CKEN_MASK); + obj->MPU = tmp; +} + +/*! \brief Gets the MPU software reset + * + * This function gets the current MPU software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MPU software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetMpuSwR(const Pcc1RegType *obj) +{ + return ((obj->MPU & PCC1_MPU_SWR_MASK) >> PCC1_MPU_SWR_SHIFT); +} + +/*! \brief Sets the MPU software reset + * + * This function sets the MPU software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MPU software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetMpuSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MPU; + + tmp &= ~PCC1_MPU_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_MPU_SWR_SHIFT)) & PCC1_MPU_SWR_MASK); + obj->MPU = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _PCC1_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/pdb_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/pdb_reg.h new file mode 100644 index 0000000..2feaabf --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/pdb_reg.h @@ -0,0 +1,1032 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PDB_REG_H_ +#define _PDB_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the PDB (Programmable Delay Block) Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* PDB - Size of Registers Arrays */ +#define PDB_CH_COUNT (2u) +#define PDB_DLY_COUNT (8u) +#define PDB_PODLY_COUNT (1u) + +/* SC Bit Fields */ +#define PDB_SC_LDMOD_MASK (0xC0000u) +#define PDB_SC_LDMOD_SHIFT (18u) +#define PDB_SC_LDMOD_WIDTH (2u) +#define PDB_SC_PDBEIE_MASK (0x20000u) +#define PDB_SC_PDBEIE_SHIFT (17u) +#define PDB_SC_PDBEIE_WIDTH (1u) +#define PDB_SC_SWTRIG_MASK (0x10000u) +#define PDB_SC_SWTRIG_SHIFT (16u) +#define PDB_SC_SWTRIG_WIDTH (1u) +#define PDB_SC_DMAEN_MASK (0x8000u) +#define PDB_SC_DMAEN_SHIFT (15u) +#define PDB_SC_DMAEN_WIDTH (1u) +#define PDB_SC_PRESCALER_MASK (0x7000u) +#define PDB_SC_PRESCALER_SHIFT (12u) +#define PDB_SC_PRESCALER_WIDTH (3u) +#define PDB_SC_TRGSEL_MASK (0xF00u) +#define PDB_SC_TRGSEL_SHIFT (8u) +#define PDB_SC_TRGSEL_WIDTH (4u) +#define PDB_SC_PDBEN_MASK (0x80u) +#define PDB_SC_PDBEN_SHIFT (7u) +#define PDB_SC_PDBEN_WIDTH (1u) +#define PDB_SC_PDBIF_MASK (0x40u) +#define PDB_SC_PDBIF_SHIFT (6u) +#define PDB_SC_PDBIF_WIDTH (1u) +#define PDB_SC_PDBIE_MASK (0x20u) +#define PDB_SC_PDBIE_SHIFT (5u) +#define PDB_SC_PDBIE_WIDTH (1u) +#define PDB_SC_MULT_MASK (0xCu) +#define PDB_SC_MULT_SHIFT (2u) +#define PDB_SC_MULT_WIDTH (2u) +#define PDB_SC_CONT_MASK (0x2u) +#define PDB_SC_CONT_SHIFT (1u) +#define PDB_SC_CONT_WIDTH (1u) +#define PDB_SC_LDOK_MASK (0x1u) +#define PDB_SC_LDOK_SHIFT (0u) +#define PDB_SC_LDOK_WIDTH (1u) + +/* MOD Bit Fields */ +#define PDB_MOD_MOD_MASK (0xFFFFu) +#define PDB_MOD_MOD_SHIFT (0u) +#define PDB_MOD_MOD_WIDTH (16u) + +/* CNT Bit Fields */ +#define PDB_CNT_CNT_MASK (0xFFFFu) +#define PDB_CNT_CNT_SHIFT (0u) +#define PDB_CNT_CNT_WIDTH (16u) + +/* IDLY Bit Fields */ +#define PDB_IDLY_IDLY_MASK (0xFFFFu) +#define PDB_IDLY_IDLY_SHIFT (0u) +#define PDB_IDLY_IDLY_WIDTH (16u) + +/* CHnC1 Bit Fields */ +#define PDB_CHnC1_BB_MASK (0xFF0000u) +#define PDB_CHnC1_BB_SHIFT (16u) +#define PDB_CHnC1_BB_WIDTH (8u) +#define PDB_CHnC1_TOS_MASK (0xFF00u) +#define PDB_CHnC1_TOS_SHIFT (8u) +#define PDB_CHnC1_TOS_WIDTH (8u) +#define PDB_CHnC1_EN_MASK (0xFFu) +#define PDB_CHnC1_EN_SHIFT (0u) +#define PDB_CHnC1_EN_WIDTH (8u) + +/* CHnS Bit Fields */ +#define PDB_CHnS_CF_MASK (0xFF0000u) +#define PDB_CHnS_CF_SHIFT (16u) +#define PDB_CHnS_CF_WIDTH (8u) +#define PDB_CHnS_ERR_MASK (0xFFu) +#define PDB_CHnS_ERR_SHIFT (0u) +#define PDB_CHnS_ERR_WIDTH (8u) + +/* CHnDLY Bit Fields */ +#define PDB_CHnDLY_DLY_MASK (0xFFFFu) +#define PDB_CHnDLY_DLY_SHIFT (0u) +#define PDB_CHnDLY_DLY_WIDTH (16u) + +/* POEN Bit Fields */ +#define PDB_POEN_POEN_MASK (0xFFu) +#define PDB_POEN_POEN_SHIFT (0u) +#define PDB_POEN_POEN_WIDTH (8u) + +/* POnDLY Bit Fields */ +#define PDB_POnDLY_DLY1_MASK (0xFFFF0000u) +#define PDB_POnDLY_DLY1_SHIFT (16u) +#define PDB_POnDLY_DLY1_WIDTH (16u) +#define PDB_POnDLY_DLY2_MASK (0xFFFFu) +#define PDB_POnDLY_DLY2_SHIFT (0u) +#define PDB_POnDLY_DLY2_WIDTH (16u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of PDB registers + */ +typedef struct _PdbRegType_ +{ + volatile uint32_t SC; /*!< status and control register, offset: 0000H */ + volatile uint32_t MOD; /*!< modulus register, offset: 0004H */ + volatile uint32_t CNT; /*!< counter register, offset: 0008H */ + volatile uint32_t IDLY; /*!< interrupt delay register, offset: 000CH */ + struct { + volatile uint32_t C1; /*!< channel n control register, offset: 0010H + n*0028H */ + volatile uint32_t S; /*!< channel n status register, offset: 0014H + n*0028H*/ + volatile uint32_t DLY[PDB_DLY_COUNT]; /*!< channel n delay register, offset: 0018H + n*0028H*/ + }CH[PDB_CH_COUNT]; + uint32_t RESERVED[76]; /*!< Reserved register, offset: 0060H */ + volatile uint32_t POEN; /*!< pulse out enable register, offset: 0190H */ + volatile uint32_t PODLY[PDB_PODLY_COUNT]; /*!< pulse out delay register, offset: 0194H */ + +} PdbRegType; + + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Get the current PDB LDMOD register configuration + * + * This function gets the current PDB LDMOD register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB LDMOD register configuration. + * - 00b: The internal registers are loaded with the values from their buffers, immediately after 1 is written to LDOK. + * - 01b: The internal registers are loaded with the values from their buffers when the PDB counter (CNT) = MOD + 1 CNT delay elapsed, after 1 is written to LDOK. + * - 10b: The internal registers are loaded with the values from their buffers when a trigger input event is detected, after 1 is written to LDOK. + * - 11b: The internal registers are loaded with the values from their buffers when either the PDB counter (CNT) = MOD + 1 CNT delay elapsed, or a trigger + * input event is detected, after 1 is written to LDOK. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetLdmodReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_LDMOD_MASK) >> PDB_SC_LDMOD_SHIFT); +} + +/*! \brief Set PDB LDMODR configuration + * + * This function writes new configuration to PDB LDMODR register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB LDMODR register configuration + * - 00b: The internal registers are loaded with the values from their buffers, immediately after 1 is written to LDOK. + * - 01b: The internal registers are loaded with the values from their buffers when the PDB counter (CNT) = MOD + 1 CNT delay elapsed, after 1 is written to LDOK. + * - 10b: The internal registers are loaded with the values from their buffers when a trigger input event is detected, after 1 is written to LDOK. + * - 11b: The internal registers are loaded with the values from their buffers when either the PDB counter (CNT) = MOD + 1 CNT delay elapsed, or a trigger + * input event is detected, after 1 is written to LDOK. + */ +__attribute__((always_inline)) static inline void PdbReg_SetLdmodReg(PdbRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_LDMOD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_SC_LDMOD_SHIFT)) & PDB_SC_LDMOD_MASK); + obj->SC = tmp; +} + +/*! \brief Get the current PDB PDBEIE register configuration + * + * This function gets the current PDB PDBEIE register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB PDBEIE register configuration. + * - 0b: PDB sequence error interrupt disabled. + * - 1b: PDB sequence error interrupt enabled. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetPdbeieReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_PDBEIE_MASK) >> PDB_SC_PDBEIE_SHIFT); +} + +/*! \brief Set PDB PDBEIE configuration + * + * This function writes new configuration to PDB PDBEIE register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB PDBEIE register configuration + * - 0b: PDB sequence error interrupt disabled. + * - 1b: PDB sequence error interrupt enabled. + */ +__attribute__((always_inline)) static inline void PdbReg_SetPdbeieReg(PdbRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_PDBEIE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_SC_PDBEIE_SHIFT)) & PDB_SC_PDBEIE_MASK); + obj->SC = tmp; +} + +/*! \brief Software Trigger + * + * When PDB is enabled and the software trigger is selected as the trigger input source, + * writing 1 to SWTRIG resets and restarts the counter. + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + */ +__attribute__((always_inline)) static inline void PdbReg_SwtrigReg(PdbRegType *obj) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_SWTRIG_MASK; + tmp &= ~PDB_SC_LDOK_MASK; + tmp |= (((uint32_t)(((uint32_t)(1u)) << PDB_SC_SWTRIG_SHIFT)) & PDB_SC_SWTRIG_MASK); + obj->SC = tmp; +} + +/*! \brief Get the current PDB DMAEN register configuration + * + * This function gets the current PDB DMAEN register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB DMAEN register configuration. + * - 0b: DMA disabled. + * - 1b: DMA enabled. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetDmaenReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_PDBEIE_MASK) >> PDB_SC_PDBEIE_SHIFT); +} + +/*! \brief Set PDB DMAEN configuration + * + * This function writes new configuration to PDB DMAEN register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB DMAEN register configuration + * - 0b: DMA disabled. + * - 1b: DMA enabled. + */ +__attribute__((always_inline)) static inline void PdbReg_SetDmaenReg(PdbRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_DMAEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_SC_DMAEN_SHIFT)) & PDB_SC_DMAEN_MASK); + obj->SC = tmp; +} + +/*! \brief Get the current PDB PRESCALER register configuration + * + * This function gets the current PDB PRESCALER register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB PRESCALER register configuration. + * - 000b: Counting uses the peripheral clock divided by MULT (the multiplication factor). + * - 001b: Counting uses the peripheral clock divided by 2 x MULT (the multiplication factor). + * - 010b: Counting uses the peripheral clock divided by 4 x MULT (the multiplication factor). + * - 011b: Counting uses the peripheral clock divided by 8 x MULT (the multiplication factor). + * - 100b: Counting uses the peripheral clock divided by 16 x MULT (the multiplication factor). + * - 101b: Counting uses the peripheral clock divided by 32 x MULT (the multiplication factor). + * - 110b: Counting uses the peripheral clock divided by 64 x MULT (the multiplication factor). + * - 111b: Counting uses the peripheral clock divided by 128 x MULT (the multiplication factor). + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetPrescalerReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_PRESCALER_MASK) >> PDB_SC_PRESCALER_SHIFT); +} + +/*! \brief Set PDB PRESCALER configuration + * + * This function writes new configuration to PDB PRESCALER register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB PRESCALER register configuration + * - 000b: Counting uses the peripheral clock divided by MULT (the multiplication factor). + * - 001b: Counting uses the peripheral clock divided by 2 x MULT (the multiplication factor). + * - 010b: Counting uses the peripheral clock divided by 4 x MULT (the multiplication factor). + * - 011b: Counting uses the peripheral clock divided by 8 x MULT (the multiplication factor). + * - 100b: Counting uses the peripheral clock divided by 16 x MULT (the multiplication factor). + * - 101b: Counting uses the peripheral clock divided by 32 x MULT (the multiplication factor). + * - 110b: Counting uses the peripheral clock divided by 64 x MULT (the multiplication factor). + * - 111b: Counting uses the peripheral clock divided by 128 x MULT (the multiplication factor). + */ +__attribute__((always_inline)) static inline void PdbReg_SetPrescalerReg(PdbRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_PRESCALER_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_SC_PRESCALER_SHIFT)) & PDB_SC_PRESCALER_MASK); + obj->SC = tmp; +} + +/*! \brief Get the current PDB TRGSEL register configuration + * + * This function gets the current PDB TRGSEL register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB TRGSEL register configuration. + * - 0000b: Trigger-In 0 is selected. + * - 0001b: Trigger-In 1 is selected. + * - 0010b: Trigger-In 2 is selected. + * - 0011b: Trigger-In 3 is selected. + * - 0100b: Trigger-In 4 is selected. + * - 0101b: Trigger-In 5 is selected. + * - 0110b: Trigger-In 6 is selected. + * - 0111b: Trigger-In 7 is selected. + * - 1000b: Trigger-In 8 is selected. + * - 1001b: Trigger-In 9 is selected. + * - 1010b: Trigger-In 10 is selected. + * - 1011b: Trigger-In 11 is selected. + * - 1100b: Trigger-In 12 is selected. + * - 1101b: Trigger-In 13 is selected. + * - 1110b: Trigger-In 14 is selected. + * - 1111b: Software trigger is selected. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetTrgselReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_TRGSEL_MASK) >> PDB_SC_TRGSEL_SHIFT); +} + +/*! \brief Set PDB TRGSEL configuration + * + * This function writes new configuration to PDB TRGSEL register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB TRGSEL register configuration + * - 0000b: Trigger-In 0 is selected. + * - 0001b: Trigger-In 1 is selected. + * - 0010b: Trigger-In 2 is selected. + * - 0011b: Trigger-In 3 is selected. + * - 0100b: Trigger-In 4 is selected. + * - 0101b: Trigger-In 5 is selected. + * - 0110b: Trigger-In 6 is selected. + * - 0111b: Trigger-In 7 is selected. + * - 1000b: Trigger-In 8 is selected. + * - 1001b: Trigger-In 9 is selected. + * - 1010b: Trigger-In 10 is selected. + * - 1011b: Trigger-In 11 is selected. + * - 1100b: Trigger-In 12 is selected. + * - 1101b: Trigger-In 13 is selected. + * - 1110b: Trigger-In 14 is selected. + * - 1111b: Software trigger is selected. + */ +__attribute__((always_inline)) static inline void PdbReg_SetTrgselReg(PdbRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_TRGSEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_SC_TRGSEL_SHIFT)) & PDB_SC_TRGSEL_MASK); + obj->SC = tmp; +} + +/*! \brief Get the current PDB PDBEN register configuration + * + * This function gets the current PDB PDBEN register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB PDBEN register configuration. + * - 0b: PDB disabled. Counter is off. + * - 1b: PDB enabled. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetPdbenReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_PDBEN_MASK) >> PDB_SC_PDBEN_SHIFT); +} + +/*! \brief Set PDB PDBEN configuration + * + * This function writes new configuration to PDB PDBEN register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB PDBEN register configuration + * - 0b: PDB disabled. Counter is off. + * - 1b: PDB enabled. + */ +__attribute__((always_inline)) static inline void PdbReg_SetPdbenReg(PdbRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_PDBEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_SC_PDBEN_SHIFT)) & PDB_SC_PDBEN_MASK); + obj->SC = tmp; +} + +/*! \brief Get the current PDB PDBIF register configuration + * + * This function gets the current PDB PDBIF register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB PDBEN register configuration. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetPdbifReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_PDBIF_MASK) >> PDB_SC_PDBIF_SHIFT); +} + +/*! \brief Clear PDB PDBIF + * + * This function clear PDB PDBIF register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * Write 0 to clear PDBIF. + * Writing 1 to PDBIF has no effect. + * + * \param[in] obj : pointer to PDB register instance + */ +__attribute__((always_inline)) static inline void PdbReg_ClrPdbifReg(PdbRegType *obj) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_PDBIF_MASK; + obj->SC = tmp; +} + +/*! \brief Get the current PDB PDBIE register configuration + * + * This function gets the current PDB PDBIE register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB PDBIE register configuration. + * - 0b: PDB interrupt disabled. + * - 1b: PDB interrupt enabled. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetPdbieReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_PDBIE_MASK) >> PDB_SC_PDBIE_SHIFT); +} + +/*! \brief Set PDB PDBIE configuration + * + * This function writes new configuration to PDB PDBIE register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB PDBIE register configuration + * - 0b: PDB interrupt disabled. + * - 1b: PDB interrupt enabled. + */ +__attribute__((always_inline)) static inline void PdbReg_SetPdbieReg(PdbRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_PDBIE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_SC_PDBIE_SHIFT)) & PDB_SC_PDBIE_MASK); + obj->SC = tmp; +} + +/*! \brief Get the current PDB MULT register configuration + * + * This function gets the current PDB MULT register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB MULT register configuration. + * - 00b: Multiplication factor is 1. + * - 01b: Multiplication factor is 10. + * - 10b: Multiplication factor is 20. + * - 11b: Multiplication factor is 40. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetMultReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_MULT_MASK) >> PDB_SC_MULT_SHIFT); +} + +/*! \brief Set PDB MULT configuration + * + * This function writes new configuration to PDB MULT register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB MULT register configuration + * - 00b: Multiplication factor is 1. + * - 01b: Multiplication factor is 10. + * - 10b: Multiplication factor is 20. + * - 11b: Multiplication factor is 40. + */ +__attribute__((always_inline)) static inline void PdbReg_SetMultReg(PdbRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_MULT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_SC_MULT_SHIFT)) & PDB_SC_MULT_MASK); + obj->SC = tmp; +} + +/*! \brief Get the current PDB CONT register configuration + * + * This function gets the current PDB CONT register configuration. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB CONT register configuration. + * - 0b: PDB operation in One-Shot mode + * - 1b: PDB operation in Continuous mode + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetContReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_CONT_MASK) >> PDB_SC_CONT_SHIFT); +} + +/*! \brief Set PDB CONT configuration + * + * This function writes new configuration to PDB CONT register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB CONT register configuration + * - 0b: PDB operation in One-Shot mode + * - 1b: PDB operation in Continuous mode + */ +__attribute__((always_inline)) static inline void PdbReg_SetContReg(PdbRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_CONT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_SC_CONT_SHIFT)) & PDB_SC_CONT_MASK); + obj->SC = tmp; +} + +/*! \brief Get the current PDB LDOK state + * + * This function gets the current PDB LDOK state. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB LDOK register configuration. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetLdokReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_LDOK_MASK) >> PDB_SC_LDOK_SHIFT); +} + +/*! \brief Start PDB Load + * + * This function writing 1 to LDOK bit updates the MOD, IDLY, CHnDLYm, and POyDLY registers. + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * Writing 1 to LDOK bit updates the MOD, IDLY, CHnDLYm, and POyDLY registers with the values previously written to their internal buffers (and stored there). + * The new values of MOD, IDLY, CHnDLYm, and POyDLY registers will take effect according to the setting of the LDMOD field (Load Mode Select). + * Before 1 is written to the LDOK field, the values in the internal buffers of these registers are not effective. + * LDOK can be written only when PDBEN is set, or LDOK can be written at the same time when PDBEN is written to 1. + * LDOK is automatically cleared when the values in the internal buffers are loaded into the registers or when PDBEN bit (PDB Enable) is cleared. + * Writing 0 to LDOK has no effect. + * \param[in] obj : pointer to PDB register instance + */ +__attribute__((always_inline)) static inline void PdbReg_StartLoadReg(PdbRegType *obj) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_LDOK_MASK; + tmp |= (((uint32_t)(((uint32_t)(1u)) << PDB_SC_LDOK_SHIFT)) & PDB_SC_LDOK_MASK); + obj->SC = tmp; +} + +/*! \brief Get the current PDB MOD register configuration + * + * This function gets the current PDB MOD register configuration. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB MOD register configuration. + * Specifies the period of the counter. When the counter reaches this value, it will be reset back to zero. + * If the PDB is in Continuous mode, the count begins anew. + * Reading this field returns the value of the internal register that is effective for the current cycle of PDB. + */ +__attribute__((always_inline)) static inline uint16_t PdbReg_GetModReg(const PdbRegType *obj) +{ + return ((obj->MOD & PDB_MOD_MOD_MASK) >> PDB_MOD_MOD_SHIFT); +} + +/*! \brief Set PDB MOD configuration + * + * This function writes new configuration to PDB MOD register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB MOD register configuration + */ +__attribute__((always_inline)) static inline void PdbReg_SetModReg(PdbRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->MOD; + + tmp &= ~PDB_MOD_MOD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_MOD_MOD_SHIFT)) & PDB_MOD_MOD_MASK); + obj->MOD = tmp; +} + +/*! \brief Get the current PDB CNT register + * + * This function gets the contains the current value of the counter. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB counter. + */ +__attribute__((always_inline)) static inline uint16_t PdbReg_GetCntReg(const PdbRegType *obj) +{ + return ((obj->CNT & PDB_CNT_CNT_MASK) >> PDB_CNT_CNT_SHIFT); +} + +/*! \brief Get the current PDB IDLY register configuration + * + * This function gets the current PDB IDLY register configuration. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * Specifies the delay value to schedule the PDB interrupt. + * It can be used to schedule an independent interrupt at some point in the PDB cycle. + * If enabled, a PDB interrupt is generated, when the counter is equal to the IDLY. Reading this field returns the value + * of internal register that is effective for the current cycle of the PDB. + * \param[in] obj : pointer to PDB register instance + * \return the current PDB IDLY register configuration. + */ +__attribute__((always_inline)) static inline uint16_t PdbReg_GetIdlyReg(const PdbRegType *obj) +{ + return ((obj->IDLY & PDB_IDLY_IDLY_MASK) >> PDB_IDLY_IDLY_SHIFT); +} + +/*! \brief Set PDB IDLY configuration + * + * This function writes new configuration to PDB IDLY register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB IDLY register configuration + */ +__attribute__((always_inline)) static inline void PdbReg_SetIdlyReg(PdbRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->IDLY; + + tmp &= ~PDB_IDLY_IDLY_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_IDLY_IDLY_SHIFT)) & PDB_IDLY_IDLY_MASK); + obj->IDLY = tmp; +} + +/*! \brief Get the current PDB CHnC1[BB] register configuration + * + * This function gets the current PDB CHnC1[BB] register configuration. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] chn : channel number + * + * |---------|---------|-----|---------|---------| + * |CH7_state|CH6_state|.....|CH1_state|CH0_state| + * |---------|---------|-----|---------|---------| + * - 0b: PDB channel's corresponding pre-trigger back-to-back operation disabled. + * - 1b: PDB channel's corresponding pre-trigger back-to-back operation enabled. + * \return the current PDB CHnC1[BB] register configuration. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetChnBbReg(const PdbRegType *obj,uint8_t chn) +{ + return ((obj->CH[chn].C1 & PDB_CHnC1_BB_MASK) >> PDB_CHnC1_BB_SHIFT); +} + +/*! \brief Set PDB CHnC1[BB] configuration + * + * This function writes new configuration to PDB CHnC1[BB] register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * + * |---------|---------|-----|---------|---------| + * |CH7_state|CH6_state|.....|CH1_state|CH0_state| + * |---------|---------|-----|---------|---------| + * - 0b: PDB channel's corresponding pre-trigger back-to-back operation disabled. + * - 1b: PDB channel's corresponding pre-trigger back-to-back operation enabled. + * \param[in] value : expected PDB CHnC1[BB] register configuration + * + * \param[in] chn : channel number + */ +__attribute__((always_inline)) static inline void PdbReg_SetChnBbReg(PdbRegType *obj, uint8_t value,uint8_t chn) +{ + uint32_t tmp = obj->CH[chn].C1; + + tmp &= ~PDB_CHnC1_BB_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_CHnC1_BB_SHIFT)) & PDB_CHnC1_BB_MASK); + obj->CH[chn].C1= tmp; +} + +/*! \brief Get the current PDB CHnC1[TOS] register configuration + * + * This function gets the current PDB CHnC1[TOS] register configuration. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] chn : channel number + * + * |---------|---------|-----|---------|---------| + * |CH7_state|CH6_state|.....|CH1_state|CH0_state| + * |---------|---------|-----|---------|---------| + * - 0b: PDB channel's corresponding pre-trigger is in bypassed mode. The pre-trigger asserts one peripheral clock cycle after a rising edge + is detected on selected trigger input source or software trigger is selected and SWTRIG is written with 1. + * - 1b: PDB channel's corresponding pre-trigger asserts when the counter reaches the channel delay register plus one peripheral clock cycle + after a rising edge is detected on selected trigger input source or software trigger is selected and SWTRIG is written with 1. + * \return the current PDB CHnC1[TOS] register configuration. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetChnTosReg(const PdbRegType *obj,uint8_t chn) +{ + return ((obj->CH[chn].C1 & PDB_CHnC1_TOS_MASK) >> PDB_CHnC1_TOS_SHIFT); +} + +/*! \brief Set PDB CHnC1[TOS] configuration + * + * This function writes new configuration to PDB CHnC1[TOS] register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * + * |---------|---------|-----|---------|---------| + * |CH7_state|CH6_state|.....|CH1_state|CH0_state| + * |---------|---------|-----|---------|---------| + * - 0b: PDB channel's corresponding pre-trigger is in bypassed mode. The pre-trigger asserts one peripheral clock cycle after a rising edge + is detected on selected trigger input source or software trigger is selected and SWTRIG is written with 1. + * - 1b: PDB channel's corresponding pre-trigger asserts when the counter reaches the channel delay register plus one peripheral clock cycle + after a rising edge is detected on selected trigger input source or software trigger is selected and SWTRIG is written with 1. + * \param[in] value : expected PDB CHnC1[TOS] register configuration + * \param[in] chn : channel number + */ +__attribute__((always_inline)) static inline void PdbReg_SetChnTosReg(PdbRegType *obj, uint8_t value,uint8_t chn) +{ + uint32_t tmp = obj->CH[chn].C1; + + tmp &= ~PDB_CHnC1_TOS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_CHnC1_TOS_SHIFT)) & PDB_CHnC1_TOS_MASK); + obj->CH[chn].C1= tmp; +} + +/*! \brief Get the current PDB CHnC1[EN] register configuration + * + * This function gets the current PDB CHnC1[EN] register configuration. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] chn : channel number + * + * |---------|---------|-----|---------|---------| + * |CH7_state|CH6_state|.....|CH1_state|CH0_state| + * |---------|---------|-----|---------|---------| + * - 0b: PDB channel's corresponding pre-trigger disabled. + * * 1b: PDB channel's corresponding pre-trigger enabled. + * \return the current PDB CHnC1[EN] register configuration. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetChnEnReg(const PdbRegType *obj,uint8_t chn) +{ + return ((obj->CH[chn].C1 & PDB_CHnC1_EN_MASK) >> PDB_CHnC1_EN_SHIFT); +} + +/*! \brief Set PDB CHnC1[EN] configuration + * + * This function writes new configuration to PDB CHnC1[EN] register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * + * |---------|---------|-----|---------|---------| + * |CH7_state|CH6_state|.....|CH1_state|CH0_state| + * |---------|---------|-----|---------|---------| + * - 0b: PDB channel's corresponding pre-trigger disabled. + * * 1b: PDB channel's corresponding pre-trigger enabled. + * + * \param[in] value : expected PDB CHnC1[EN] register configuration + * \param[in] chn : channel number + */ +__attribute__((always_inline)) static inline void PdbReg_SetChnEnReg(PdbRegType *obj, uint8_t value,uint8_t chn) +{ + uint32_t tmp = obj->CH[chn].C1; + + tmp &= ~PDB_CHnC1_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_CHnC1_EN_SHIFT)) & PDB_CHnC1_EN_MASK); + obj->CH[chn].C1= tmp; +} + +/*! \brief Get the current PDB CHnS[CF] register. + * + * This function gets the current PDB CHnS[CF] register. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] chn : channel number + * + * |---------|---------|-----|---------|---------| + * |CH7_state|CH6_state|.....|CH1_state|CH0_state| + * |---------|---------|-----|---------|---------| + * \return the current PDB CHnS[CF] register. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetChnCfReg(const PdbRegType *obj,uint8_t chn) +{ + return ((obj->CH[chn].S & PDB_CHnS_CF_MASK) >> PDB_CHnS_CF_SHIFT); +} + +/*! \brief clear PDB CHnS[CF]. + * + * This function writes new configuration to PDB CHnS[CF] register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * Write 0 to clear CHn[preCH[0-7]]CF. + * \param[in] obj : pointer to PDB register instance + * \param[in] chn : channel number + */ +__attribute__((always_inline)) static inline void PdbReg_ClrChnCfReg(PdbRegType *obj,uint8_t chn) +{ + uint32_t tmp = obj->CH[chn].S; + tmp &= ~PDB_CHnS_CF_MASK; + obj->CH[chn].S= tmp; +} + +/*! \brief Get the current PDB CHnS[ERR] register. + * + * This function gets the current PDB CHnS[ERR] register. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] chn : channel number + * + * |---------|---------|-----|---------|---------| + * |CH7_state|CH6_state|.....|CH1_state|CH0_state| + * |---------|---------|-----|---------|---------| + * - 0b: Sequence error not detected on PDB channel's corresponding pre-trigger. + * - 1b: Sequence error detected on PDB channel's corresponding pre-trigger. + * \return the current PDB CHnS[ERR] register. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetChnErrReg(const PdbRegType *obj,uint8_t chn) +{ + return ((obj->CH[chn].S & PDB_CHnS_ERR_MASK) >> PDB_CHnS_ERR_SHIFT); +} + +/*! \brief clear PDB CHnS[ERR] configuration + * + * This function writes new configuration to PDB CHnS[ERR] register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * Write 0 to clear CHn[preCH[0-7]]ERR. + * \param[in] obj : pointer to PDB register instance + * \param[in] chn : channel number + */ +__attribute__((always_inline)) static inline void PdbReg_ClrChnErrReg(PdbRegType *obj,uint8_t chn) +{ + uint32_t tmp = obj->CH[chn].S; + tmp &= ~PDB_CHnS_ERR_MASK; + obj->CH[chn].S= tmp; +} + +/*! \brief Get the current PDB CHnDLY[DLY] register. + * + * This function gets the current PDB CHnDLY[DLY] register. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * Reading these bits returns the value of internal register that is effective for the current PDB cycle. + * \param[in] obj : pointer to PDB register instance + * \param[in] chn : channel number + * \param[in] preChn : pre-trigger number + * \return the current PDB CHnDLY[DLY] register. + */ +__attribute__((always_inline)) static inline uint16_t PdbReg_GetChnDlyReg(const PdbRegType *obj,uint8_t chn, uint8_t preChn) +{ + return ((obj->CH[chn].DLY[preChn] & PDB_CHnDLY_DLY_MASK) >> PDB_CHnDLY_DLY_SHIFT); +} + +/*! \brief Set PDB CHnDLY[DLY] configuration + * + * This function writes new configuration to PDB CHnDLY[DLY] register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB CHnDLY[DLY] register configuration + * \param[in] chn : channel number + * \param[in] preChn : pre-trigger number + */ +__attribute__((always_inline)) static inline void PdbReg_SetChnDlyReg(PdbRegType *obj, uint16_t value,uint8_t chn, uint8_t preChn) +{ + uint32_t tmp = obj->CH[chn].DLY[preChn]; + + tmp &= ~PDB_CHnDLY_DLY_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_CHnDLY_DLY_SHIFT)) & PDB_CHnDLY_DLY_MASK); + obj->CH[chn].DLY[preChn]= tmp; +} + +/*! \brief Get the current PDB POEN register. + * + * This function gets the current PDB POEN register. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * + * |---------|---------|-----|---------|---------| + * |CH7_state|CH6_state|.....|CH1_state|CH0_state| + * |---------|---------|-----|---------|---------| + * - 0b: PDB Pulse-Out disabled + * - 1b: PDB Pulse-Out enabled + * \return the current PDB POEN register. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetPoenReg(const PdbRegType *obj) +{ + return ((obj->POEN & PDB_POEN_POEN_MASK) >> PDB_POEN_POEN_SHIFT); +} + +/*! \brief Set PDB POEN configuration + * + * This function writes new configuration to PDB POEN register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * + * |---------|---------|-----|---------|---------| + * |CH7_state|CH6_state|.....|CH1_state|CH0_state| + * |---------|---------|-----|---------|---------| + * - 0b: PDB Pulse-Out disabled + * - 1b: PDB Pulse-Out enabled + * \param[in] value : expected PDB POEN register configuration + */ +__attribute__((always_inline)) static inline void PdbReg_SetPoenReg(PdbRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->POEN; + + tmp &= ~PDB_POEN_POEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_POEN_POEN_SHIFT)) & PDB_POEN_POEN_MASK); + obj->POEN = tmp; +} + +/*! \brief Get the current PDB POnDLY[DLY1] register. + * + * This function gets the current PDB POnDLY[DLY1] register. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * Reading these bits returns the value of internal register that is effective for the current PDB cycle. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] Pon : PO number + * \return the current PDB POnDLY[DLY1] register. + */ +__attribute__((always_inline)) static inline uint16_t PdbReg_GetPonDly1Reg(const PdbRegType *obj,uint8_t Pon) +{ + return ((obj->PODLY[Pon] & PDB_POnDLY_DLY1_MASK) >> PDB_POnDLY_DLY1_SHIFT); +} + +/*! \brief Get the current PDB POnDLY[DLY2] register. + * + * This function gets the current PDB POnDLY[DLY2] register. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * Reading these bits returns the value of internal register that is effective for the current PDB cycle. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] Pon : PO number + * \return the current PDB POnDLY[DLY2] register. + */ +__attribute__((always_inline)) static inline uint16_t PdbReg_GetPonDly2Reg(const PdbRegType *obj,uint8_t Pon) +{ + return ((obj->PODLY[Pon] & PDB_POnDLY_DLY2_MASK) >> PDB_POnDLY_DLY2_SHIFT); +} + +/*! \brief Set PDB POnDLY configuration + * + * This function writes new configuration to PDB POnDLY[DLY1] register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB POnDLY register configuration(bit0~15 is DLY2,bit 16~31 is DLY1) + * \param[in] Pon : PO number + */ +__attribute__((always_inline)) static inline void PdbReg_SetPonDlyReg(PdbRegType *obj, uint32_t value,uint8_t Pon) +{ + obj->PODLY[Pon] = value; +} +#ifdef __cplusplus +} +#endif /* extern "C" */ + + +#endif /* _PDB_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/pmc_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/pmc_reg.h new file mode 100644 index 0000000..bac415b --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/pmc_reg.h @@ -0,0 +1,781 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PMC_REG_H_ +#define _PMC_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the PMC Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* GLB_CTRL Bit Fields */ +#define PMC_GLB_CTRL_CPU_RETION_EN_MASK (0x20u) +#define PMC_GLB_CTRL_CPU_RETION_EN_SHIFT (5u) +#define PMC_GLB_CTRL_CPU_RETION_EN_WIDTH (1u) +#define PMC_GLB_CTRL_STOP_EN_MASK (0x04u) +#define PMC_GLB_CTRL_STOP_EN_SHIFT (2u) +#define PMC_GLB_CTRL_STOP_EN_WIDTH (1u) +#define PMC_GLB_CTRL_STDBY_EN_MASK (0x02u) +#define PMC_GLB_CTRL_STDBY_EN_SHIFT (1u) +#define PMC_GLB_CTRL_STDBY_EN_WIDTH (1u) + +/* DAINTF_CTRL Bit Fields */ +#define PMC_DAINTF_CTRL_EN_FLDO_VDET_MASK (0x80000u) +#define PMC_DAINTF_CTRL_EN_FLDO_VDET_SHIFT (19u) +#define PMC_DAINTF_CTRL_EN_FLDO_VDET_WIDTH (1u) +#define PMC_DAINTF_CTRL_SEL_LVW_MASK (0xC000u) +#define PMC_DAINTF_CTRL_SEL_LVW_SHIFT (14u) +#define PMC_DAINTF_CTRL_SEL_LVW_WIDTH (2u) +#define PMC_DAINTF_CTRL_EN_LVW_MASK (0x2000u) +#define PMC_DAINTF_CTRL_EN_LVW_SHIFT (13u) +#define PMC_DAINTF_CTRL_EN_LVW_WIDTH (1u) +#define PMC_DAINTF_CTRL_EN_LVD_MASK (0x1000u) +#define PMC_DAINTF_CTRL_EN_LVD_SHIFT (12u) +#define PMC_DAINTF_CTRL_EN_LVD_WIDTH (1u) +#define PMC_DAINTF_CTRL_OTP_EN_MASK (0x80u) +#define PMC_DAINTF_CTRL_OTP_EN_SHIFT (7u) +#define PMC_DAINTF_CTRL_OTP_EN_WIDTH (1u) + +/* WAKUP_FLG Bit Fields */ +#define PMC_WAKUP_FLG_CMP_WAKUP_EVT_FLG_MASK (0x400u) +#define PMC_WAKUP_FLG_CMP_WAKUP_EVT_FLG_SHIFT (10u) +#define PMC_WAKUP_FLG_CMP_WAKUP_EVT_FLG_WIDTH (1u) +#define PMC_WAKUP_FLG_LPTMR_WAKUP_EVT_FLG_MASK (0x200u) +#define PMC_WAKUP_FLG_LPTMR_WAKUP_EVT_FLG_SHIFT (9u) +#define PMC_WAKUP_FLG_LPTMR_WAKUP_EVT_FLG_WIDTH (1u) +#define PMC_WAKUP_FLG_LPIT_WAKUP_EVT_FLG_MASK (0x100u) +#define PMC_WAKUP_FLG_LPIT_WAKUP_EVT_FLG_SHIFT (8u) +#define PMC_WAKUP_FLG_LPIT_WAKUP_EVT_FLG_WIDTH (1u) +#define PMC_WAKUP_FLG_RTC_WAKUP_EVT_FLG_MASK (0x40u) +#define PMC_WAKUP_FLG_RTC_WAKUP_EVT_FLG_SHIFT (6u) +#define PMC_WAKUP_FLG_RTC_WAKUP_EVT_FLG_WIDTH (1u) +#define PMC_WAKUP_FLG_EXTRST_WAKUP_EVT_FLG_MASK (0x20u) +#define PMC_WAKUP_FLG_EXTRST_WAKUP_EVT_FLG_SHIFT (5u) +#define PMC_WAKUP_FLG_EXTRST_WAKUP_EVT_FLG_WIDTH (1u) +#define PMC_WAKUP_FLG_PORTE_WAKUP_EVT_FLG_MASK (0x10u) +#define PMC_WAKUP_FLG_PORTE_WAKUP_EVT_FLG_SHIFT (4u) +#define PMC_WAKUP_FLG_PORTE_WAKUP_EVT_FLG_WIDTH (1u) +#define PMC_WAKUP_FLG_PORTD_WAKUP_EVT_FLG_MASK (0x08u) +#define PMC_WAKUP_FLG_PORTD_WAKUP_EVT_FLG_SHIFT (3u) +#define PMC_WAKUP_FLG_PORTD_WAKUP_EVT_FLG_WIDTH (1u) +#define PMC_WAKUP_FLG_PORTC_WAKUP_EVT_FLG_MASK (0x04u) +#define PMC_WAKUP_FLG_PORTC_WAKUP_EVT_FLG_SHIFT (2u) +#define PMC_WAKUP_FLG_PORTC_WAKUP_EVT_FLG_WIDTH (1u) +#define PMC_WAKUP_FLG_PORTB_WAKUP_EVT_FLG_MASK (0x02u) +#define PMC_WAKUP_FLG_PORTB_WAKUP_EVT_FLG_SHIFT (1u) +#define PMC_WAKUP_FLG_PORTB_WAKUP_EVT_FLG_WIDTH (1u) +#define PMC_WAKUP_FLG_PORTA_WAKUP_EVT_FLG_MASK (0x01u) +#define PMC_WAKUP_FLG_PORTA_WAKUP_EVT_FLG_SHIFT (0u) +#define PMC_WAKUP_FLG_PORTA_WAKUP_EVT_FLG_WIDTH (1u) + +/* STATUS Bit Fields */ +#define PMC_STATUS_RUN_MODE_MASK (0x20u) +#define PMC_STATUS_RUN_MODE_SHIFT (5u) +#define PMC_STATUS_RUN_MODE_WIDTH (1u) +#define PMC_STATUS_STDBY_ABORT_STS_MASK (0x10u) +#define PMC_STATUS_STDBY_ABORT_STS_SHIFT (4u) +#define PMC_STATUS_STDBY_ABORT_STS_WIDTH (1u) +#define PMC_STATUS_PAD_KEEP_MASK (0x02u) +#define PMC_STATUS_PAD_KEEP_SHIFT (1u) +#define PMC_STATUS_PAD_KEEP_WIDTH (1u) +#define PMC_STATUS_LOCK_MASK (0x01u) +#define PMC_STATUS_LOCK_SHIFT (0u) +#define PMC_STATUS_LOCK_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of PMC registers + */ +typedef struct _PmcRegType_ +{ + volatile uint32_t GLB_CTRL; /*!< wakeup source regsiter, offset: 0x0 */ + uint32_t RESERVED0[2]; /*!< Reserverd block, offset: 0x04 */ + volatile uint32_t DAINTF_CTRL; /*!< digital to analog interface control signal register, offset: 0xC */ + uint32_t RESERVED1[1]; /*!< Reserverd block, offset: 0x10 */ + volatile uint32_t WAKUP_FLG; /*!< wake up flag register, offset: 0x14 */ + volatile uint32_t STATUS; /*!< status register register, offset: 0x18 */ + uint32_t RESERVED2[13]; /*!< Reserverd block, offset: 0x1C */ + volatile uint32_t KEY; /*!< key register, offset: 0x50 */ +} PmcRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the CPU retention enable + * + * This function gets the current CPU retention enable. + * enable the PMC cpu retention function, when lock function disable this register can write access. + * CPU after reset then start to excute instruction from the begining when exit standby mode + * or CPU start to excute instruction from the states before enter standby mode when exit standby mode. + * + * \param[in] obj : pointer to PMC register instance + * \return CPU retention enable + * - 0 : excute instruction from the begining. + * - 1 : excute instruction from the states before enter standby mode. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetGlbCtrlCpuRetionEn(const PmcRegType *obj) +{ + return ((obj->GLB_CTRL & PMC_GLB_CTRL_CPU_RETION_EN_MASK) >> PMC_GLB_CTRL_CPU_RETION_EN_SHIFT); +} + +/*! \brief Sets the CPU retention enable + * + * This function sets the CPU retention enable. + * enable the PMC cpu retention function, when lock function disable this register can write access. + * CPU after reset then start to excute instruction from the begining when exit standby mode + * or CPU start to excute instruction from the states before enter standby mode when exit standby mode. + * + * \param[in] obj : pointer to PMC register instance + * \param[in] value : the value of CPU retention enable + * - 0 : excute instruction from the begining. + * - 1 : excute instruction from the states before enter standby mode. + */ +__attribute__((always_inline)) static inline void PmcReg_SetGlbCtrlCpuRetionEn(PmcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->GLB_CTRL; + + tmp &= ~PMC_GLB_CTRL_CPU_RETION_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PMC_GLB_CTRL_CPU_RETION_EN_SHIFT)) & PMC_GLB_CTRL_CPU_RETION_EN_MASK); + obj->GLB_CTRL = tmp; +} + +/*! \brief Gets the Stop mode enable + * + * This function gets the current Stop mode enable. + * PMC stop mode enable, when lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \return Stop mode enable + * - 0 : stop mode disable. + * - 1 : stop mode enable. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetGlbCtrlStopEn(const PmcRegType *obj) +{ + return ((obj->GLB_CTRL & PMC_GLB_CTRL_STOP_EN_MASK) >> PMC_GLB_CTRL_STOP_EN_SHIFT); +} + +/*! \brief Sets the Stop mode enable + * + * This function sets the Stop mode enable. + * PMC stop mode enable, when lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \param[in] value : the value of Stop mode enable + * - 0 : stop mode disable. + * - 1 : stop mode enable. + */ +__attribute__((always_inline)) static inline void PmcReg_SetGlbCtrlStopEn(PmcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->GLB_CTRL; + + tmp &= ~PMC_GLB_CTRL_STOP_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PMC_GLB_CTRL_STOP_EN_SHIFT)) & PMC_GLB_CTRL_STOP_EN_MASK); + obj->GLB_CTRL = tmp; +} + +/*! \brief Gets the standby mode enable + * + * This function gets the current standby mode enable. + * PMC standby mode enable, when lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \return standby mode enable + * - 0 : standby mode disable. + * - 1 : standby mode enable. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetGlbCtrlStdbyEn(const PmcRegType *obj) +{ + return ((obj->GLB_CTRL & PMC_GLB_CTRL_STDBY_EN_MASK) >> PMC_GLB_CTRL_STDBY_EN_SHIFT); +} + +/*! \brief Sets the standby mode enable + * + * This function sets the standby mode enable. + * PMC standby mode enable, when lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \param[in] value : the value of standby mode enable + * - 0 : standby mode disable. + * - 1 : standby mode enable. + */ +__attribute__((always_inline)) static inline void PmcReg_SetGlbCtrlStdbyEn(PmcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->GLB_CTRL; + + tmp &= ~PMC_GLB_CTRL_STDBY_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PMC_GLB_CTRL_STDBY_EN_SHIFT)) & PMC_GLB_CTRL_STDBY_EN_MASK); + obj->GLB_CTRL = tmp; +} + +/*! \brief Gets the Flash LDO(FLDO) voltage detect control + * + * This function gets the current Flash LDO(FLDO) voltage detect control. + * when write lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \return Flash LDO(FLDO) voltage detect control + * - 1 : Enable voltage detect. + * - 0 : Disable voltage detect. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetDAIntfCtrlEnFldoVDet(const PmcRegType *obj) +{ + return ((obj->DAINTF_CTRL & PMC_DAINTF_CTRL_EN_FLDO_VDET_MASK) >> PMC_DAINTF_CTRL_EN_FLDO_VDET_SHIFT); +} + +/*! \brief Sets the Flash LDO(FLDO) voltage detect control + * + * This function sets the Flash LDO(FLDO) voltage detect control. + * when write lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \param[in] value : the value of Flash LDO(FLDO) voltage detect control + * - 1 : Enable voltage detect. + * - 0 : Disable voltage detect. + */ +__attribute__((always_inline)) static inline void PmcReg_SetDAIntfCtrlEnFldoVDet(PmcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DAINTF_CTRL; + + tmp &= ~PMC_DAINTF_CTRL_EN_FLDO_VDET_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PMC_DAINTF_CTRL_EN_FLDO_VDET_SHIFT)) & PMC_DAINTF_CTRL_EN_FLDO_VDET_MASK); + obj->DAINTF_CTRL = tmp; +} + +/*! \brief Gets the Low voltage warning(LVW) level select + * + * This function gets the current Low voltage warning(LVW) level select. + * when write lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \return Low voltage warning(LVW) level select + * - 00b : V_LVW1. + * - 01b : V_LVW2. + * - 01b : V_LVW3. + * - 11b : Not defined. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetDAIntfCtrlSelLvw(const PmcRegType *obj) +{ + return ((obj->DAINTF_CTRL & PMC_DAINTF_CTRL_SEL_LVW_MASK) >> PMC_DAINTF_CTRL_SEL_LVW_SHIFT); +} + +/*! \brief Sets the Low voltage warning(LVW) level select + * + * This function sets the Low voltage warning(LVW) level select. + * when write lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \param[in] value : the value of Low voltage warning(LVW) level select + * - 00b : V_LVW1. + * - 01b : V_LVW2. + * - 01b : V_LVW3. + * - 11b : Not defined. + */ +__attribute__((always_inline)) static inline void PmcReg_SetDAIntfCtrlSelLvw(PmcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DAINTF_CTRL; + + tmp &= ~PMC_DAINTF_CTRL_SEL_LVW_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PMC_DAINTF_CTRL_SEL_LVW_SHIFT)) & PMC_DAINTF_CTRL_SEL_LVW_MASK); + obj->DAINTF_CTRL = tmp; +} + +/*! \brief Gets the Low voltage detect warning(LVW) control + * + * This function gets the current Low voltage detect warning(LVW) control. + * when write lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \return Low voltage detect warning(LVW) control + * - 0b : Disable low voltage warning. + * - 1b : Enable low voltage warning. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetDAIntfCtrlEnLvw(const PmcRegType *obj) +{ + return ((obj->DAINTF_CTRL & PMC_DAINTF_CTRL_EN_LVW_MASK) >> PMC_DAINTF_CTRL_EN_LVW_SHIFT); +} + +/*! \brief Sets the Low voltage detect warning(LVW) control + * + * This function sets the Low voltage detect warning(LVW) control. + * when write lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \param[in] value : the value of Low voltage detect warning(LVW) control + * - 0b : Disable low voltage warning. + * - 1b : Enable low voltage warning. + */ +__attribute__((always_inline)) static inline void PmcReg_SetDAIntfCtrlEnLvw(PmcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DAINTF_CTRL; + + tmp &= ~PMC_DAINTF_CTRL_EN_LVW_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PMC_DAINTF_CTRL_EN_LVW_SHIFT)) & PMC_DAINTF_CTRL_EN_LVW_MASK); + obj->DAINTF_CTRL = tmp; +} + +/*! \brief Gets the Low voltage detect enable control + * + * This function gets the current Low voltage detect enable control. + * when write lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \return Low voltage detect enable control + * - 0b : Disable low voltage detect. + * - 1b : Enable low voltage detect. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetDAIntfCtrlEnLvd(const PmcRegType *obj) +{ + return ((obj->DAINTF_CTRL & PMC_DAINTF_CTRL_EN_LVD_MASK) >> PMC_DAINTF_CTRL_EN_LVD_SHIFT); +} + +/*! \brief Sets the Low voltage detect enable control + * + * This function sets the Low voltage detect enable control. + * when write lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \param[in] value : the value of Low voltage detect enable control + * - 0b : Disable low voltage detect. + * - 1b : Enable low voltage detect. + */ +__attribute__((always_inline)) static inline void PmcReg_SetDAIntfCtrlEnLvd(PmcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DAINTF_CTRL; + + tmp &= ~PMC_DAINTF_CTRL_EN_LVD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PMC_DAINTF_CTRL_EN_LVD_SHIFT)) & PMC_DAINTF_CTRL_EN_LVD_MASK); + obj->DAINTF_CTRL = tmp; +} + +/*! \brief Gets the OTP function enable control + * + * This function gets the current OTP function enable control. + * when write lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \return OTP function enable control + * - 0 : Disable. + * - 1 : Enable. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetDAIntfCtrlOtpEn(const PmcRegType *obj) +{ + return ((obj->DAINTF_CTRL & PMC_DAINTF_CTRL_OTP_EN_MASK) >> PMC_DAINTF_CTRL_OTP_EN_SHIFT); +} + +/*! \brief Sets the OTP function enable control + * + * This function sets the OTP function enable control. + * when write lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \param[in] value : the value of OTP function enable control + * - 0 : Disable. + * - 1 : Enable. + */ +__attribute__((always_inline)) static inline void PmcReg_SetDAIntfCtrlOtpEn(PmcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DAINTF_CTRL; + + tmp &= ~PMC_DAINTF_CTRL_OTP_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PMC_DAINTF_CTRL_OTP_EN_SHIFT)) & PMC_DAINTF_CTRL_OTP_EN_MASK); + obj->DAINTF_CTRL = tmp; +} + +/*! \brief Gets the cmp wake up event flag + * + * This function gets the current cmp wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + * \return cmp wake up event flag + * - 0 : cmp wake up event flag not exist. + * - 1 : cmp wake up event flag exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetWakupFlgCmpWakupEvtFlag(const PmcRegType *obj) +{ + return ((obj->WAKUP_FLG & PMC_WAKUP_FLG_CMP_WAKUP_EVT_FLG_MASK) >> PMC_WAKUP_FLG_CMP_WAKUP_EVT_FLG_SHIFT); +} + +/*! \brief Sets the cmp wake up event flag + * + * This function sets the cmp wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearWakupFlgCmpWakupEvtFlag(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->WAKUP_FLG = (((uint32_t)(((uint32_t)(1)) << PMC_WAKUP_FLG_CMP_WAKUP_EVT_FLG_SHIFT)) & PMC_WAKUP_FLG_CMP_WAKUP_EVT_FLG_MASK); +} + +/*! \brief Gets the lptmr wake up event flag + * + * This function gets the current lptmr wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + * \return lptmr wake up event flag + * - 0 : lptmr wake up event flag not exist. + * - 1 : lptmr wake up event flag exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetWakupFlgLptmrWakupEvtFlg(const PmcRegType *obj) +{ + return ((obj->WAKUP_FLG & PMC_WAKUP_FLG_LPTMR_WAKUP_EVT_FLG_MASK) >> PMC_WAKUP_FLG_LPTMR_WAKUP_EVT_FLG_SHIFT); +} + +/*! \brief Sets the lptmr wake up event flag + * + * This function sets the lptmr wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearWakupFlgLptmrWakupEvtFlg(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->WAKUP_FLG = (((uint32_t)(((uint32_t)(1)) << PMC_WAKUP_FLG_LPTMR_WAKUP_EVT_FLG_SHIFT)) & PMC_WAKUP_FLG_LPTMR_WAKUP_EVT_FLG_MASK); +} + +/*! \brief Gets the low power interrupt timer wake up event flag + * + * This function gets the current low power interrupt timer wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + * \return low power interrupt timer wake up event flag + * - 0 : lpit wake up event flag not exist. + * - 1 : lpit wake up event flag exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetWakupFlgLpitWakupEvtFlg(const PmcRegType *obj) +{ + return ((obj->WAKUP_FLG & PMC_WAKUP_FLG_LPIT_WAKUP_EVT_FLG_MASK) >> PMC_WAKUP_FLG_LPIT_WAKUP_EVT_FLG_SHIFT); +} + +/*! \brief Sets the low power interrupt timer wake up event flag + * + * This function sets the low power interrupt timer wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearWakupFlgLpitWakupEvtFlg(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->WAKUP_FLG = (((uint32_t)(((uint32_t)(1)) << PMC_WAKUP_FLG_LPIT_WAKUP_EVT_FLG_SHIFT)) & PMC_WAKUP_FLG_LPIT_WAKUP_EVT_FLG_MASK); +} + +/*! \brief Gets the real time clock wake up event flag + * + * This function gets the current real time clock wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + * \return real time clock wake up event flag + * - 0 : rtc wake up event flag not exist. + * - 1 : rtc wake up event flag exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetWakupFlgRtcWakupEvtFlg(const PmcRegType *obj) +{ + return ((obj->WAKUP_FLG & PMC_WAKUP_FLG_RTC_WAKUP_EVT_FLG_MASK) >> PMC_WAKUP_FLG_RTC_WAKUP_EVT_FLG_SHIFT); +} + +/*! \brief Sets the real time clock wake up event flag + * + * This function sets the real time clock wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearWakupFlgRtcWakupEvtFlg(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->WAKUP_FLG = (((uint32_t)(((uint32_t)(1)) << PMC_WAKUP_FLG_RTC_WAKUP_EVT_FLG_SHIFT)) & PMC_WAKUP_FLG_RTC_WAKUP_EVT_FLG_MASK); +} + +/*! \brief Gets the External reset wake up event flag + * + * This function gets the current External reset wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + * \return External reset wake up event flag + * - 0 : extrst wake up event flag not exist. + * - 1 : extrst wake up event flag exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetWakupFlgExtrstWakupEvtFlg(const PmcRegType *obj) +{ + return ((obj->WAKUP_FLG & PMC_WAKUP_FLG_EXTRST_WAKUP_EVT_FLG_MASK) >> PMC_WAKUP_FLG_EXTRST_WAKUP_EVT_FLG_SHIFT); +} + +/*! \brief Sets the External reset wake up event flag + * + * This function sets the External reset wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearWakupFlgExtrstWakupEvtFlg(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->WAKUP_FLG = (((uint32_t)(((uint32_t)(1)) << PMC_WAKUP_FLG_EXTRST_WAKUP_EVT_FLG_SHIFT)) & PMC_WAKUP_FLG_EXTRST_WAKUP_EVT_FLG_MASK); +} + +/*! \brief Gets the port E wake up event flag + * + * This function gets the current port E wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + * \return port E wake up event flag + * - 0 : porte wake up event flag not exist. + * - 1 : porte wake up event flag exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetWakupFlgPortEWakupEvtFlg(const PmcRegType *obj) +{ + return ((obj->WAKUP_FLG & PMC_WAKUP_FLG_PORTE_WAKUP_EVT_FLG_MASK) >> PMC_WAKUP_FLG_PORTE_WAKUP_EVT_FLG_SHIFT); +} + +/*! \brief Sets the port E wake up event flag + * + * This function sets the port E wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearWakupFlgPortEWakupEvtFlg(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->WAKUP_FLG = (((uint32_t)(((uint32_t)(1)) << PMC_WAKUP_FLG_PORTE_WAKUP_EVT_FLG_SHIFT)) & PMC_WAKUP_FLG_PORTE_WAKUP_EVT_FLG_MASK); +} + +/*! \brief Gets the port D wake up event flag + * + * This function gets the current port D wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + * \return port D wake up event flag + * - 0 : portd wake up event flag not exist. + * - 1 : portd wake up event flag exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetWakupFlgPortDWakupEvtFlg(const PmcRegType *obj) +{ + return ((obj->WAKUP_FLG & PMC_WAKUP_FLG_PORTD_WAKUP_EVT_FLG_MASK) >> PMC_WAKUP_FLG_PORTD_WAKUP_EVT_FLG_SHIFT); +} + +/*! \brief Sets the port D wake up event flag + * + * This function sets the port D wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearWakupFlgPortDWakupEvtFlg(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->WAKUP_FLG = (((uint32_t)(((uint32_t)(1)) << PMC_WAKUP_FLG_PORTD_WAKUP_EVT_FLG_SHIFT)) & PMC_WAKUP_FLG_PORTD_WAKUP_EVT_FLG_MASK); +} + +/*! \brief Gets the port C wake up event flag + * + * This function gets the current port C wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + * \return port C wake up event flag + * - 0 : portc wake up event flag not exist. + * - 1 : portc wake up event flag exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetWakupFlgPortCWakupEvtFlg(const PmcRegType *obj) +{ + return ((obj->WAKUP_FLG & PMC_WAKUP_FLG_PORTC_WAKUP_EVT_FLG_MASK) >> PMC_WAKUP_FLG_PORTC_WAKUP_EVT_FLG_SHIFT); +} + +/*! \brief Sets the port C wake up event flag + * + * This function sets the port C wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearWakupFlgPortCWakupEvtFlg(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->WAKUP_FLG = (((uint32_t)(((uint32_t)(1)) << PMC_WAKUP_FLG_PORTC_WAKUP_EVT_FLG_SHIFT)) & PMC_WAKUP_FLG_PORTC_WAKUP_EVT_FLG_MASK); +} + +/*! \brief Gets the port B wake up event flag + * + * This function gets the current port B wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + * \return port B wake up event flag + * - 0 : portb wake up event flag not exist. + * - 1 : portb wake up event flag exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetWakupFlgPortBWakupEvtFlg(const PmcRegType *obj) +{ + return ((obj->WAKUP_FLG & PMC_WAKUP_FLG_PORTB_WAKUP_EVT_FLG_MASK) >> PMC_WAKUP_FLG_PORTB_WAKUP_EVT_FLG_SHIFT); +} + +/*! \brief Sets the port B wake up event flag + * + * This function sets the port B wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearWakupFlgPortBWakupEvtFlg(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->WAKUP_FLG = (((uint32_t)(((uint32_t)(1)) << PMC_WAKUP_FLG_PORTB_WAKUP_EVT_FLG_SHIFT)) & PMC_WAKUP_FLG_PORTB_WAKUP_EVT_FLG_MASK); +} + +/*! \brief Gets the port A wake up event flag + * + * This function gets the current port A wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + * \return port A wake up event flag + * - 0 : porta wake up event flag not exist. + * - 1 : porta wake up event flag exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetWakupFlgPortAWakupEvtFlg(const PmcRegType *obj) +{ + return ((obj->WAKUP_FLG & PMC_WAKUP_FLG_PORTA_WAKUP_EVT_FLG_MASK) >> PMC_WAKUP_FLG_PORTA_WAKUP_EVT_FLG_SHIFT); +} + +/*! \brief Sets the port A wake up event flag + * + * This function sets the port A wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearWakupFlgPortAWakupEvtFlg(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->WAKUP_FLG = (((uint32_t)(((uint32_t)(1)) << PMC_WAKUP_FLG_PORTA_WAKUP_EVT_FLG_SHIFT)) & PMC_WAKUP_FLG_PORTA_WAKUP_EVT_FLG_MASK); +} + +/*! \brief Gets the normal run mode status + * + * This function gets the current normal run mode status. + * + * \param[in] obj : pointer to PMC register instance + * \return normal run mode status + * - 0 : normal run mode status not exist. + * - 1 : normal run mode status exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetStatusRunMode(const PmcRegType *obj) +{ + return ((obj->STATUS & PMC_STATUS_RUN_MODE_MASK) >> PMC_STATUS_RUN_MODE_SHIFT); +} + +/*! \brief Gets the standby abort status + * + * This function gets the current standby abort status. + * + * \param[in] obj : pointer to PMC register instance + * \return standby abort status + * - 0 : standby abort status not exist. + * - 1 : standby abort status exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetStatusStdbyAbortSts(const PmcRegType *obj) +{ + return ((obj->STATUS & PMC_STATUS_STDBY_ABORT_STS_MASK) >> PMC_STATUS_STDBY_ABORT_STS_SHIFT); +} + +/*! \brief Sets the standby abort status + * + * This function sets the standby abort status. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearStatusStdbyAbortSts(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->STATUS = (((uint32_t)(((uint32_t)(1)) << PMC_STATUS_STDBY_ABORT_STS_SHIFT)) & PMC_STATUS_STDBY_ABORT_STS_MASK); +} + +/*! \brief Gets the pad keep status + * + * This function gets the current pad keep status. + * + * \param[in] obj : pointer to PMC register instance + * \return pad keep status + * - 0 : pad keep disable. + * - 1 : pad keep enable. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetStatusPadKeep(const PmcRegType *obj) +{ + return ((obj->STATUS & PMC_STATUS_PAD_KEEP_MASK) >> PMC_STATUS_PAD_KEEP_SHIFT); +} + +/*! \brief Sets the pad keep status + * + * This function sets the pad keep status. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearStatusPadKeep(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->STATUS = (((uint32_t)(((uint32_t)(1)) << PMC_STATUS_PAD_KEEP_SHIFT)) & PMC_STATUS_PAD_KEEP_MASK); +} + +/*! \brief Gets the key lock enable + * + * This function gets the current key lock enable. + * + * \param[in] obj : pointer to PMC register instance + * \return key lock enable + * - 0 : disable. + * - 1 : enable. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetStatusKeyLock(const PmcRegType *obj) +{ + return ((obj->STATUS & PMC_STATUS_LOCK_MASK) >> PMC_STATUS_LOCK_SHIFT); +} + +/*! \brief Sets the PMC key lock enable + * + * This function sets the PMC key lock enable. + * pmc write public function register hit key, the initial confirm key is 0x20220509, + * when cpu write data is 0x20220509, PMC public function register lock is invalid, + * CPU can write the pmc public function register. + * When cpu write data is not equal 0x20220509, PMC public register function lock is valid, + * CPU can not write the pmc function register + * + * \param[in] obj : pointer to PMC register instance + * \param[in] value : the value of PMC key lock enable + * - 0x20220509 : unlock + * - others : lock + */ +__attribute__((always_inline)) static inline void PmcReg_SetKey(PmcRegType *obj, uint32_t value) +{ + obj->KEY = value; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _PMC_REG_H_ */ \ No newline at end of file diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/port_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/port_reg.h new file mode 100644 index 0000000..cc3f1e7 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/port_reg.h @@ -0,0 +1,761 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PORT_REG_H_ +#define _PORT_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the PORT Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* Length of PCR register array */ +#define PORT_PCR_COUNT (18U) + +/* PCR Bit Fields */ +#define PORT_PCR_ISF_MASK (0x1000000u) +#define PORT_PCR_ISF_SHIFT (24u) +#define PORT_PCR_ISF_WIDTH (1u) +#define PORT_PCR_IRQ_CFG_MASK (0xF0000u) +#define PORT_PCR_IRQ_CFG_SHIFT (16u) +#define PORT_PCR_IRQ_CFG_WIDTH (4u) +#define PORT_PCR_LOCK_MASK (0x8000u) +#define PORT_PCR_LOCK_SHIFT (15u) +#define PORT_PCR_LOCK_WIDTH (1u) +#define PORT_PCR_MUX_MASK (0x700u) +#define PORT_PCR_MUX_SHIFT (8u) +#define PORT_PCR_MUX_WIDTH (3u) +#define PORT_PCR_ODE_MASK (0x80u) +#define PORT_PCR_ODE_SHIFT (7u) +#define PORT_PCR_ODE_WIDTH (1u) +#define PORT_PCR_DRV_STR_MASK (0x40u) +#define PORT_PCR_DRV_STR_SHIFT (6u) +#define PORT_PCR_DRV_STR_WIDTH (1u) +#define PORT_PCR_SR_MASK (0x20u) +#define PORT_PCR_SR_SHIFT (5u) +#define PORT_PCR_SR_WIDTH (1u) +#define PORT_PCR_PAS_FLT_MASK (0x10u) +#define PORT_PCR_PAS_FLT_SHIFT (4u) +#define PORT_PCR_PAS_FLT_WIDTH (1u) +#define PORT_PCR_AEN_MASK (0x04u) +#define PORT_PCR_AEN_SHIFT (2u) +#define PORT_PCR_AEN_WIDTH (1u) +#define PORT_PCR_PDE_MASK (0x02u) +#define PORT_PCR_PDE_SHIFT (1u) +#define PORT_PCR_PDE_WIDTH (1u) +#define PORT_PCR_PUE_MASK (0x01u) +#define PORT_PCR_PUE_SHIFT (0u) +#define PORT_PCR_PUE_WIDTH (1u) + +/* GPCLR Bit Fields */ +#define PORT_GPCLR_LDAT_MASK (0xFFFF0000u) +#define PORT_GPCLR_LDAT_SHIFT (16u) +#define PORT_GPCLR_LDAT_WIDTH (16u) +#define PORT_GPCLR_LWEN_MASK (0xFFFFu) +#define PORT_GPCLR_LWEN_SHIFT (0u) +#define PORT_GPCLR_LWEN_WIDTH (16u) + +/* GPCHR Bit Fields */ +#define PORT_GPCHR_HDAT_MASK (0xFFFF0000u) +#define PORT_GPCHR_HDAT_SHIFT (16u) +#define PORT_GPCHR_HDAT_WIDTH (16u) +#define PORT_GPCHR_HWEN_MASK (0xFFFFu) +#define PORT_GPCHR_HWEN_SHIFT (0u) +#define PORT_GPCHR_HWEN_WIDTH (16u) + +/* GICLR Bit Fields */ +#define PORT_GICLR_INT_LDAT_MASK (0xFFFF0000u) +#define PORT_GICLR_INT_LDAT_SHIFT (16u) +#define PORT_GICLR_INT_LDAT_WIDTH (16u) +#define PORT_GICLR_INT_LWEN_MASK (0xFFFFu) +#define PORT_GICLR_INT_LWEN_SHIFT (0u) +#define PORT_GICLR_INT_LWEN_WIDTH (16u) + +/* GICHR Bit Fields */ +#define PORT_GICHR_INT_HDAT_MASK (0xFFFF0000u) +#define PORT_GICHR_INT_HDAT_SHIFT (16u) +#define PORT_GICHR_INT_HDAT_WIDTH (16u) +#define PORT_GICHR_INT_HWEN_MASK (0xFFFFu) +#define PORT_GICHR_INT_HWEN_SHIFT (0u) +#define PORT_GICHR_INT_HWEN_WIDTH (16u) + +/* DFWR Bit Fields */ +#define PORT_DFWR_LEN_MASK (0x1Fu) +#define PORT_DFWR_LEN_SHIFT (0u) +#define PORT_DFWR_LEN_WIDTH (5u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of PORT registers + */ +typedef struct _PortRegType_ +{ + volatile uint32_t PCR[PORT_PCR_COUNT]; /*!< PORT control, offset: 0x00 */ + uint32_t RESERVED0[14]; /*!< Reserved registers, offset: 0x48 */ + volatile uint32_t GPCLR; /*!< Global Pin Control Low bits, offset: 0x80 */ + volatile uint32_t GPCHR; /*!< Global pin control high bits, offset: 0x84 */ + volatile uint32_t GICLR; /*!< Global Interrupt Control Low, offset: 0x88 */ + volatile uint32_t GICHR; /*!< Global Interrupt Control High, offset: 0x8C */ + uint32_t RESERVED1[4]; /*!< Reserved registers, offset: 0x90 */ + volatile uint32_t ISFR; /*!< Interrupt Status Flag, offset: 0xA0 */ + uint32_t RESERVED2[7]; /*!< Reserved registers, offset: 0xA4 */ + volatile uint32_t DFER; /*!< Digital Filter Enable, offset: 0xC0 */ + uint32_t RESERVED3; /*!< Reserved register, offset: 0xC4 */ + volatile uint32_t DFWR; /*!< Digital Filter Width, offset: 0xC8 */ +} PortRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the Interrupt Status Flag + * + * This function gets the current Interrupt Status Flag. + * The pin interrupt configuration is valid in all digital pin muxing modes. + * + * \note If the pin is configured to generate a DMA request, + * then the corresponding flag will be cleared automatically at the completion of the requested DMA transfer. + * Otherwise, the flag remains set until a logic 1 is written to the flag. + * If the pin is configured for a level sensitive interrupt and the pin remains asserted, + * then the flag is set again immediately after it is cleared. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return Interrupt Status Flag + * - 0b : Configured interrupt is not detected. + * - 1b : Configured interrupt is detected. + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrIsf(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_ISF_MASK) >> PORT_PCR_ISF_SHIFT); +} + +/*! \brief Sets the Interrupt Status Flag + * + * This function sets the Interrupt Status Flag. + * The pin interrupt configuration is valid in all digital pin muxing modes. + * + * \note If the pin is configured to generate a DMA request, + * then the corresponding flag will be cleared automatically at the completion of the requested DMA transfer. + * Otherwise, the flag remains set until a logic 1 is written to the flag. + * If the pin is configured for a level sensitive interrupt and the pin remains asserted, + * then the flag is set again immediately after it is cleared. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of Interrupt Status Flag + * - 0b : Configured interrupt is not detected. + * - 1b : Configured interrupt is detected. + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrIsf(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_ISF_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_ISF_SHIFT)) & PORT_PCR_ISF_MASK); + obj->PCR[pin] = tmp; + /* Read back to avoid problem */ + (void)obj->PCR[pin]; +} + +/*! \brief Gets the Interrupt Configuration + * + * This function gets the current Interrupt Configuration. + * The pin interrupt configuration is valid in all digital pin muxing modes. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return Interrupt Configuration + * - 0000b : Interrupt Status Flag (ISF) is disabled. + * - 0001b : ISF flag and DMA request on rising edge. + * - 0010b : ISF flag and DMA request on falling edge. + * - 0011b : ISF flag and DMA request on either edge. + * - 0100b : Reserved. + * - 0101b : Reserved. + * - 0110b : Reserved. + * - 0111b : Reserved. + * - 1000b : ISF flag and Interrupt when logic 0. + * - 1001b : ISF flag and Interrupt on rising-edge. + * - 1010b : ISF flag and Interrupt on falling-edge. + * - 1011b : ISF flag and Interrupt on either edge. + * - 1100b : ISF flag and Interrupt when logic 1. + * - 1101b : Reserved. + * - 1110b : Reserved. + * - 1111b : Reserved + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrIrqCfg(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_IRQ_CFG_MASK) >> PORT_PCR_IRQ_CFG_SHIFT); +} + +/*! \brief Sets the Interrupt Configuration + * + * This function sets the Interrupt Configuration. + * The pin interrupt configuration is valid in all digital pin muxing modes. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of Interrupt Configuration + * - 0000b : Interrupt Status Flag (ISF) is disabled. + * - 0001b : ISF flag and DMA request on rising edge. + * - 0010b : ISF flag and DMA request on falling edge. + * - 0011b : ISF flag and DMA request on either edge. + * - 0100b : Reserved. + * - 0101b : Reserved. + * - 0110b : Reserved. + * - 0111b : Reserved. + * - 1000b : ISF flag and Interrupt when logic 0. + * - 1001b : ISF flag and Interrupt on rising-edge. + * - 1010b : ISF flag and Interrupt on falling-edge. + * - 1011b : ISF flag and Interrupt on either edge. + * - 1100b : ISF flag and Interrupt when logic 1. + * - 1101b : Reserved. + * - 1110b : Reserved. + * - 1111b : Reserved + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrIrqCfg(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_IRQ_CFG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_IRQ_CFG_SHIFT)) & PORT_PCR_IRQ_CFG_MASK); + obj->PCR[pin] = tmp; +} + +/*! \brief Gets the Lock Register + * + * This function gets the current Lock Register. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return Lock Register + * - 0b : Pin Control Register fields [15:0] are not locked. + * - 1b : Pin Control Register fields [15:0] are locked and cannot be updated until the next system reset + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrLock(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_LOCK_MASK) >> PORT_PCR_LOCK_SHIFT); +} + +/*! \brief Sets the Lock Register + * + * This function sets the Lock Register. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of Lock Register + * - 0b : Pin Control Register fields [15:0] are not locked. + * - 1b : Pin Control Register fields [15:0] are locked and cannot be updated until the next system reset + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrLock(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_LOCK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_LOCK_SHIFT)) & PORT_PCR_LOCK_MASK); + obj->PCR[pin] = tmp; +} + +/*! \brief Gets the Pin Mux Control + * + * This function gets the current Pin Mux Control. + * Not all pins support all pin muxing slots. + * Unimplemented pin muxing slots are reserved and may result in configuring the pin for a different pin muxing slot. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return Pin Mux Control + * - 000b : Pin disabled (Alternative 0) (analog). + * - 001b : Alternative 1 (GPIO). + * - 010b : Alternative 2 (chip-specific). + * - 011b : Alternative 3 (chip-specific). + * - 100b : Alternative 4 (chip-specific). + * - 101b : Alternative 5 (chip-specific). + * - 110b : Alternative 6 (chip-specific). + * - 111b : Alternative 7 (chip-specific) + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrMux(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_MUX_MASK) >> PORT_PCR_MUX_SHIFT); +} + +/*! \brief Sets the Pin Mux Control + * + * This function sets the Pin Mux Control. + * Not all pins support all pin muxing slots. + * Unimplemented pin muxing slots are reserved and may result in configuring the pin for a different pin muxing slot. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of Pin Mux Control + * - 000b : Pin disabled (Alternative 0) (analog). + * - 001b : Alternative 1 (GPIO). + * - 010b : Alternative 2 (chip-specific). + * - 011b : Alternative 3 (chip-specific). + * - 100b : Alternative 4 (chip-specific). + * - 101b : Alternative 5 (chip-specific). + * - 110b : Alternative 6 (chip-specific). + * - 111b : Alternative 7 (chip-specific) + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrMux(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_MUX_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_MUX_SHIFT)) & PORT_PCR_MUX_MASK); + obj->PCR[pin] = tmp; +} + +/*! \brief Gets the Open drain enable + * + * This function gets the current Open drain enable. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return Open drain enable + * - 0b : push pull + * - 1b : open drain + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrOde(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_ODE_MASK) >> PORT_PCR_ODE_SHIFT); +} + +/*! \brief Sets the Open drain enable + * + * This function sets the Open drain enable. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of Open drain enable + * - 0b : push pull + * - 1b : open drain + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrOde(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_ODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_ODE_SHIFT)) & PORT_PCR_ODE_MASK); + obj->PCR[pin] = tmp; +} + +/*! \brief Gets the Drive Strength Enable + * + * This function gets the current Drive Strength Enable. + * Drive strength configuration is valid in all digital pin muxing modes. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return Drive Strength Enable + * - 0b : Low drive strength is configured on the corresponding pin, if pin is configured as a digital output. + * - 1b : High drive strength is configured on the corresponding pin, if pin is configured as a digital output. + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrDrvStr(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_DRV_STR_MASK) >> PORT_PCR_DRV_STR_SHIFT); +} + +/*! \brief Sets the Drive Strength Enable + * + * This function sets the Drive Strength Enable. + * Drive strength configuration is valid in all digital pin muxing modes. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of Drive Strength Enable + * - 0b : Low drive strength is configured on the corresponding pin, if pin is configured as a digital output. + * - 1b : High drive strength is configured on the corresponding pin, if pin is configured as a digital output. + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrDrvStr(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_DRV_STR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_DRV_STR_SHIFT)) & PORT_PCR_DRV_STR_MASK); + obj->PCR[pin] = tmp; +} + +/*! \brief Gets the slew rate + * + * This function gets the current slew rate. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return slew rate + * - 0b : slow slew rate + * - 1b : fast slew rate + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrSr(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_SR_MASK) >> PORT_PCR_SR_SHIFT); +} + +/*! \brief Sets the slew rate + * + * This function sets the slew rate. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of slew rate + * - 0b : slow slew rate + * - 1b : fast slew rate + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrSr(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_SR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_SR_SHIFT)) & PORT_PCR_SR_MASK); + obj->PCR[pin] = tmp; +} + +/*! \brief Gets the Passive Filter Enable + * + * This function gets the current Passive Filter Enable. + * Passive filter configuration is valid in all digital pin muxing modes. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return Passive Filter Enable + * - 0b : Passive input filter is disabled on the corresponding pin. + * - 1b : Passive input filter is enabled on the corresponding pin, if the pin is configured as a digital input. + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrPasFlt(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_PAS_FLT_MASK) >> PORT_PCR_PAS_FLT_SHIFT); +} + +/*! \brief Sets the Passive Filter Enable + * + * This function sets the Passive Filter Enable. + * Passive filter configuration is valid in all digital pin muxing modes. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of Passive Filter Enable + * - 0b : Passive input filter is disabled on the corresponding pin. + * - 1b : Passive input filter is enabled on the corresponding pin, if the pin is configured as a digital input. + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrPasFlt(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_PAS_FLT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_PAS_FLT_SHIFT)) & PORT_PCR_PAS_FLT_MASK); + obj->PCR[pin] = tmp; +} + +/*! \brief Gets the Analog mode enable + * + * This function gets the current Analog mode enable. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return Analog mode enable + * - 0b : analog mode is disabled on the corresponding pin + * - 1b : analog mode is enabled on the corresponding pin + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrAen(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_AEN_MASK) >> PORT_PCR_AEN_SHIFT); +} + +/*! \brief Sets the Analog mode enable + * + * This function sets the Analog mode enable. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of Analog mode enable + * - 0b : analog mode is disabled on the corresponding pin + * - 1b : analog mode is enabled on the corresponding pin + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrAen(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_AEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_AEN_SHIFT)) & PORT_PCR_AEN_MASK); + obj->PCR[pin] = tmp; +} + +/*! \brief Gets the Pull down enable + * + * This function gets the current Pull down enable. + * Pull configuration is valid in all digital pin muxing modes. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return Pull down enable + * - 0b : Internal pulldown resistor is disabled + * - 1b : Internal pulldown resistor is enabled + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrPde(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_PDE_MASK) >> PORT_PCR_PDE_SHIFT); +} + +/*! \brief Sets the Pull down enable + * + * This function sets the Pull down enable. + * Pull configuration is valid in all digital pin muxing modes. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of Pull down enable + * - 0b : Internal pulldown resistor is disabled + * - 1b : Internal pulldown resistor is enabled + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrPde(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_PDE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_PDE_SHIFT)) & PORT_PCR_PDE_MASK); + obj->PCR[pin] = tmp; +} + +/*! \brief Gets the Pull up enable + * + * This function gets the current Pull up enable. + * Pull configuration is valid in all digital pin muxing modes. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return Pull up enable + * - 0b : Internal pullup resistor is disabled + * - 1b : Internal pullup resistor is enabled + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrPue(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_PUE_MASK) >> PORT_PCR_PUE_SHIFT); +} + +/*! \brief Sets the Pull up enable + * + * This function sets the Pull up enable. + * Pull configuration is valid in all digital pin muxing modes. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of Pull up enable + * - 0b : Internal pullup resistor is disabled + * - 1b : Internal pullup resistor is enabled + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrPue(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_PUE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_PUE_SHIFT)) & PORT_PCR_PUE_MASK); + obj->PCR[pin] = tmp; +} + +/*! \brief Sets the Global Pin Control register low 16 bits + * + * This function sets the Global Pin Control register low 16 bits + * Write value that is written to all Pin Control Registers bits [15:0] that are selected by GPWE + * + * \param[in] obj : pointer to PORT register instance + * \param[in] value : the value of Global Pin Write Data and write Enable + */ +__attribute__((always_inline)) static inline void PortReg_SetGpclr(PortRegType *obj, uint32_t value) +{ + obj->GPCLR = value; +} + +/*! \brief Sets the global Pin Control register high 16 bits + * + * This function sets the global Pin Control register high 16 bits. + * Write value that is written to all Pin Control Registers bits [15:0] that are selected by GPWE + * + * \param[in] obj : pointer to PORT register instance + * \param[in] value : the value of global write data and write enable + */ +__attribute__((always_inline)) static inline void PortReg_SetGpchr(PortRegType *obj, uint32_t value) +{ + obj->GPCHR = value; +} + +/*! \brief Sets the Global Interrupt register low 16 bits + * + * This function sets the Global Interrupt register low 16 bits. + * Write value that is written to all Pin Control Registers bits [31:16] that are selected by [15:0] + * + * \param[in] obj : pointer to PORT register instance + * \param[in] value : the value of Global Interrupt write data and write enable + */ +__attribute__((always_inline)) static inline void PortReg_SetGiclrInt(PortRegType *obj, uint32_t value) +{ + obj->GICLR = value; +} + +/*! \brief Sets the Global Interrupt register high 16 bits + * + * This function sets the Global Interrupt register high 16 bits. + * Write value that is written to all Pin Control Registers bits [31:16] that are selected by [15:0] + * + * \param[in] obj : pointer to PORT register instance + * \param[in] value : the value of Global Interrupt write data and enable + */ +__attribute__((always_inline)) static inline void PortReg_SetGichrInt(PortRegType *obj, uint32_t value) +{ + obj->GICHR = value; +} + +/*! \brief Gets the Interrupt Status Flag + * + * This function gets the current Interrupt Status Flag. + * Each bit in the field indicates the detection of the configured interrupt of the same number as the field. + * + * \note If the pin is configured to generate a DMA request, + * then the corresponding flag will be cleared automatically at the completion of the requested DMA transfer. + * Otherwise, the flag remains set until a logic 1 is written to the flag. + * If the pin is configured for a level sensitive interrupt and the pin remains asserted, + * then the flag is set again immediately after it is cleared. + * + * \param[in] obj : pointer to PORT register instance + * \return Interrupt Status Flag + * - 0b : Configured interrupt is not detected. + * - 1b : Configured interrupt is detected. + */ +__attribute__((always_inline)) static inline uint32_t PortReg_GetIsfrIsf(const PortRegType *obj) +{ + return obj->ISFR; +} + +/*! \brief Sets the Interrupt Status Flag + * + * This function sets the Interrupt Status Flag. + * Each bit in the field indicates the detection of the configured interrupt of the same number as the field. + * + * \note If the pin is configured to generate a DMA request, + * then the corresponding flag will be cleared automatically at the completion of the requested DMA transfer. + * Otherwise, the flag remains set until a logic 1 is written to the flag. + * If the pin is configured for a level sensitive interrupt and the pin remains asserted, + * then the flag is set again immediately after it is cleared. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] value : the value of Interrupt Status Flag + * - 0b : corresponding interrupt is not cleared. + * - 1b : corresponding interrupt is cleared. + */ +__attribute__((always_inline)) static inline void PortReg_SetIsfrIsf(PortRegType *obj, uint32_t value) +{ + obj->ISFR = value; + /* Read back to avoid problem */ + (void)obj->ISFR; +} + +/*! \brief Gets the Digital Filter Enable + * + * This function gets the current Digital Filter Enable. + * The digital filter configuration is valid in all digital pin muxing modes. + * The output of each digital filter is reset to zero at system reset and whenever the digital filter is disabled. + * Each bit in the field enables the digital filter of the same number as the field. + * + * \param[in] obj : pointer to PORT register instance + * \return Digital Filter Enable + * - 0b : Digital filter is disabled on the corresponding pin and output of the digital filter is reset to zero. + * - 1b : Digital filter is enabled on the corresponding pin, if the pin is configured as a digital input. + */ +__attribute__((always_inline)) static inline uint32_t PortReg_GetDferEn(const PortRegType *obj) +{ + return obj->DFER; +} + +/*! \brief Sets the Digital Filter Enable + * + * This function sets the Digital Filter Enable. + * The digital filter configuration is valid in all digital pin muxing modes. + * The output of each digital filter is reset to zero at system reset and whenever the digital filter is disabled. + * Each bit in the field enables the digital filter of the same number as the field. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] value : the value of Digital Filter Enable + * - 0b : Digital filter is disabled on the corresponding pin and output of the digital filter is reset to zero. + * - 1b : Digital filter is enabled on the corresponding pin, if the pin is configured as a digital input. + */ +__attribute__((always_inline)) static inline void PortReg_SetDferEn(PortRegType *obj, uint32_t value) +{ + obj->DFER = value; +} + +/*! \brief Gets the Filter Length + * + * This function gets the current Filter Length. + * The digital filter configuration is valid in all digital pin muxing modes. + * Configures the maximum size of the glitches, in clock cycles, + * that the digital filter absorbs for the enabled digital filters. + * Glitches that are longer than this register setting will pass through the digital filter, + * and glitches that are equal to or less than this register setting are filtered. + * Changing the filter length must be done only after all filters are disable + * + * \param[in] obj : pointer to PORT register instance + * \return Filter Length + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetDfwrLen(const PortRegType *obj) +{ + return ((obj->DFWR & PORT_DFWR_LEN_MASK) >> PORT_DFWR_LEN_SHIFT); +} + +/*! \brief Sets the Filter Length + * + * This function sets the Filter Length. + * The digital filter configuration is valid in all digital pin muxing modes. + * Configures the maximum size of the glitches, in clock cycles, + * that the digital filter absorbs for the enabled digital filters. + * Glitches that are longer than this register setting will pass through the digital filter, + * and glitches that are equal to or less than this register setting are filtered. + * Changing the filter length must be done only after all filters are disable + * + * \param[in] obj : pointer to PORT register instance + * \param[in] value : the value of Filter Length + */ +__attribute__((always_inline)) static inline void PortReg_SetDfwrLen(PortRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DFWR; + + tmp &= ~PORT_DFWR_LEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_DFWR_LEN_SHIFT)) & PORT_DFWR_LEN_MASK); + obj->DFWR = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _PORT_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/pwmlite_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/pwmlite_reg.h new file mode 100644 index 0000000..c8f8031 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/pwmlite_reg.h @@ -0,0 +1,429 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PWMLITE_REG_H_ +#define _PWMLITE_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the PWMLITE Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/*! The number of PWMLITE channels */ +#define PWMLITE_CHANNEL_NUM (6) + +/* CTRL Bit Fields */ +#define PWMLITE_CTRL_SYNC_MODE_MASK (0x02u) +#define PWMLITE_CTRL_SYNC_MODE_SHIFT (1u) +#define PWMLITE_CTRL_SYNC_MODE_WIDTH (1u) +#define PWMLITE_CTRL_EN_MASK (0x01u) +#define PWMLITE_CTRL_EN_SHIFT (0u) +#define PWMLITE_CTRL_EN_WIDTH (1u) + +/* PRD Bit Fields */ +#define PWMLITE_PRD_PERIOD_MASK (0xFFFFFFFFu) +#define PWMLITE_PRD_PERIOD_SHIFT (0u) +#define PWMLITE_PRD_PERIOD_WIDTH (32u) + +/* STOP Bit Fields */ +#define PWMLITE_STOP_PAUSE_MASK (0x01u) +#define PWMLITE_STOP_PAUSE_SHIFT (0u) +#define PWMLITE_STOP_PAUSE_WIDTH (1u) + +/* SYNC Bit Fields */ +#define PWMLITE_SYNC_START_MASK (0x02u) +#define PWMLITE_SYNC_START_SHIFT (1u) +#define PWMLITE_SYNC_START_WIDTH (1u) +#define PWMLITE_SYNC_STATUS_MASK (0x01u) +#define PWMLITE_SYNC_STATUS_SHIFT (0u) +#define PWMLITE_SYNC_STATUS_WIDTH (1u) + +/* CH_CTRL Bit Fields */ +#define PWMLITE_CH_CTRL_CTRL1_MASK (0x0Cu) +#define PWMLITE_CH_CTRL_CTRL1_SHIFT (2u) +#define PWMLITE_CH_CTRL_CTRL1_WIDTH (2u) +#define PWMLITE_CH_CTRL_CTRL0_MASK (0x03u) +#define PWMLITE_CH_CTRL_CTRL0_SHIFT (0u) +#define PWMLITE_CH_CTRL_CTRL0_WIDTH (2u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of PWMLITE registers + */ +typedef struct _PwmLiteRegType_ +{ + volatile uint32_t CTRL; /*!< PWMLITE control, offset: 0x00 */ + volatile uint32_t PRD; /*!< PWMLITE counter period, offset: 0x04 */ + volatile uint32_t STOP; /*!< pause module register, offset: 0x08 */ + volatile uint32_t SYNC; /*!< register sync control and status, offset: 0x0C */ + struct + { + volatile uint32_t CTRL; /*!< channel n control, offset: 0x00 */ + volatile uint32_t THR0; /*!< channel n threshold0, offset: 0x04 */ + volatile uint32_t THR1; /*!< channel n threshold1, offset: 0x08 */ + uint32_t RESERVED0[1]; /*!< Reserverd block, offset: 0x0C */ + } CH[PWMLITE_CHANNEL_NUM]; +} PwmLiteRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the register update mode + * + * This function gets the current register update mode. + * + * \param[in] obj : pointer to PWMLITE register instance + * \return register update mode + * - 0b : async update, update when the register is configured + * - 1b : sync update + */ +__attribute__((always_inline)) static inline uint8_t PwmLiteReg_GetCtrlSyncMode(const PwmLiteRegType *obj) +{ + return ((obj->CTRL & PWMLITE_CTRL_SYNC_MODE_MASK) >> PWMLITE_CTRL_SYNC_MODE_SHIFT); +} + +/*! \brief Sets the register update mode + * + * This function sets the register update mode. + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] value : the value of register update mode + * - 0b : async update,update when the register is configured + * - 1b : sync update + */ +__attribute__((always_inline)) static inline void PwmLiteReg_SetCtrlSyncMode(PwmLiteRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL; + + tmp &= ~PWMLITE_CTRL_SYNC_MODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PWMLITE_CTRL_SYNC_MODE_SHIFT)) & PWMLITE_CTRL_SYNC_MODE_MASK); + obj->CTRL = tmp; +} + +/*! \brief Gets the pwm module enable + * + * This function gets the current pwm module enable. + * + * \param[in] obj : pointer to PWMLITE register instance + * \return pwm module enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t PwmLiteReg_GetCtrlEn(const PwmLiteRegType *obj) +{ + return ((obj->CTRL & PWMLITE_CTRL_EN_MASK) >> PWMLITE_CTRL_EN_SHIFT); +} + +/*! \brief Sets the pwm module enable + * + * This function sets the pwm module enable. + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] value : the value of pwm module enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void PwmLiteReg_SetCtrlEn(PwmLiteRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL; + + tmp &= ~PWMLITE_CTRL_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PWMLITE_CTRL_EN_SHIFT)) & PWMLITE_CTRL_EN_MASK); + obj->CTRL = tmp; +} + +/*! \brief Gets the pwm counter period + * + * This function gets the current pwm counter period. + * + * \note This value should be > 0, if configured 0, the real period is 0x100000000. + * + * \param[in] obj : pointer to PWMLITE register instance + * \return pwm counter period + * - 0h : 0xFFFFFFFF + * - 1 : 1 + * - 2 : 2 + * ... + * - 0xFFFFFFFF : 0xFFFFFFFF + */ +__attribute__((always_inline)) static inline uint32_t PwmLiteReg_GetPrdPeriod(const PwmLiteRegType *obj) +{ + return ((obj->PRD & PWMLITE_PRD_PERIOD_MASK) >> PWMLITE_PRD_PERIOD_SHIFT); +} + +/*! \brief Sets the pwm counter period + * + * This function sets the pwm counter period. + * + * \note This value should be > 0, if configured 0, the real period is 0x100000000. + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] value : the value of pwm counter period + * - 0h : 0xFFFF_FFFF + * - 1h : 1 + * - 2h : 2 + * ... + * - 0xFFFFFFFF : 0xFFFFFFFF + */ +__attribute__((always_inline)) static inline void PwmLiteReg_SetPrdPeriod(PwmLiteRegType *obj, uint32_t value) +{ + uint32_t tmp = obj->PRD; + + tmp &= ~PWMLITE_PRD_PERIOD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PWMLITE_PRD_PERIOD_SHIFT)) & PWMLITE_PRD_PERIOD_MASK); + obj->PRD = tmp; +} + +/*! \brief Gets the pwm module pause + * + * This function gets the current pwm module pause. + * + * \param[in] obj : pointer to PWMLITE register instance + * \return pwm module pause + * - 0b : counter is working + * - 1b : stop counter + */ +__attribute__((always_inline)) static inline uint8_t PwmLiteReg_GetStopPause(const PwmLiteRegType *obj) +{ + return ((obj->STOP & PWMLITE_STOP_PAUSE_MASK) >> PWMLITE_STOP_PAUSE_SHIFT); +} + +/*! \brief Sets the pwm module pause + * + * This function sets the pwm module pause. + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] value : the value of pwm module pause + * - 0b : counter is working + * - 1b : stop counter + */ +__attribute__((always_inline)) static inline void PwmLiteReg_SetStopPause(PwmLiteRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->STOP; + + tmp &= ~PWMLITE_STOP_PAUSE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PWMLITE_STOP_PAUSE_SHIFT)) & PWMLITE_STOP_PAUSE_MASK); + obj->STOP = tmp; +} + +/*! \brief Sets the update register action + * + * This function sets the update register action. + * write to this register shall cause all registers take effect when counter reaches the PWM_PRD register + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] value : the value of update register action + */ +__attribute__((always_inline)) static inline void PwmLiteReg_SetSyncStart(PwmLiteRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNC; + + tmp &= ~PWMLITE_SYNC_START_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PWMLITE_SYNC_START_SHIFT)) & PWMLITE_SYNC_START_MASK); + obj->SYNC = tmp; +} + +/*! \brief Gets the configuration update status + * + * This function gets the current configuration update status. + * + * \param[in] obj : pointer to PWMLITE register instance + * \return configuration update status + * - 0b : update done + * - 1b : during update + */ +__attribute__((always_inline)) static inline uint8_t PwmLiteReg_GetSyncStatus(const PwmLiteRegType *obj) +{ + return ((obj->SYNC & PWMLITE_SYNC_STATUS_MASK) >> PWMLITE_SYNC_STATUS_SHIFT); +} + +/*! \brief Gets the action when counter reaches threshold1 + * + * This function gets the current action when counter reaches threshold1. + * When channel counter reaches the threshold PWMn_THR1, pwm output should be one of the following + * - 0h : keep + * - 1h : low + * - 2h : high + * - 3h : toggle + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] channel : the channel number, 0-7 + * \return action when counter reaches threshold1 + * - 0h : keep + * - 1h : low + * - 2h : high + * - 3h : toggle + */ +__attribute__((always_inline)) static inline uint8_t PwmLiteReg_GetChCtrl1(const PwmLiteRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CTRL & PWMLITE_CH_CTRL_CTRL1_MASK) >> PWMLITE_CH_CTRL_CTRL1_SHIFT); +} + +/*! \brief Sets the action when counter reaches threshold1 + * + * This function sets the action when counter reaches threshold1. + * When channel counter reaches the threshold PWMn_THR1, pwm output should be one of the following + * - 0h : keep + * - 1h : low + * - 2h : high + * - 3h : toggle + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] channel : the channel number, 0-7 + * \param[in] value : the value of action when counter reaches threshold1 + * - 0h : keep + * - 1h : low + * - 2h : high + * - 3h : toggle + */ +__attribute__((always_inline)) static inline void PwmLiteReg_SetChCtrl1(PwmLiteRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->CH[channel].CTRL; + + tmp &= ~PWMLITE_CH_CTRL_CTRL1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PWMLITE_CH_CTRL_CTRL1_SHIFT)) & PWMLITE_CH_CTRL_CTRL1_MASK); + obj->CH[channel].CTRL = tmp; +} + +/*! \brief Gets the action when counter reaches threshold0 + * + * This function gets the current action when counter reaches threshold0. + * When channel counter reaches the threshold PWM0_THR0, pwm output should be one of the following + * - 0h : keep + * - 1h : low + * - 2h : high + * - 3h : toggle + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] channel : the channel number, 0-7 + * \return action when counter reaches threshold0 + * - 0h : keep + * - 1h : low + * - 2h : high + * - 3h : toggle + */ +__attribute__((always_inline)) static inline uint8_t PwmLiteReg_GetChCtrl0(const PwmLiteRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CTRL & PWMLITE_CH_CTRL_CTRL0_MASK) >> PWMLITE_CH_CTRL_CTRL0_SHIFT); +} + +/*! \brief Sets the action when counter reaches threshold0 + * + * This function sets the action when counter reaches threshold0. + * When channel counter reaches the threshold PWM0_THR0, pwm output should be one of the following + * - 0h : keep + * - 1h : low + * - 2h : high + * - 3h : toggle + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] channel : the channel number, 0-7 + * \param[in] value : the value of action when counter reaches threshold0 + * - 0h : keep + * - 1h : low + * - 2h : high + * - 3h : toggle + */ +__attribute__((always_inline)) static inline void PwmLiteReg_SetChCtrl0(PwmLiteRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->CH[channel].CTRL; + + tmp &= ~PWMLITE_CH_CTRL_CTRL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PWMLITE_CH_CTRL_CTRL0_SHIFT)) & PWMLITE_CH_CTRL_CTRL0_MASK); + obj->CH[channel].CTRL = tmp; +} + +/*! \brief Gets the channel threshold0 + * + * This function gets the current channel threshold0. + * This value should be > 0, if configured 0, the real threshold is PWM_PR + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] channel : the channel number, 0-7 + * \return channel threshold0 + */ +__attribute__((always_inline)) static inline uint32_t PwmLiteReg_GetChThr0(const PwmLiteRegType *obj, uint8_t channel) +{ + return obj->CH[channel].THR0; +} + +/*! \brief Sets the channel threshold0 + * + * This function sets the channel threshold0. + * This value should be > 0, if configured 0, the real threshold is PWM_PR + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] channel : the channel number, 0-7 + * \param[in] value : the value of channel threshold0 + */ +__attribute__((always_inline)) static inline void PwmLiteReg_SetChThr0(PwmLiteRegType *obj, uint8_t channel, uint32_t value) +{ + obj->CH[channel].THR0 = value; +} + +/*! \brief Gets the channel threshold1 + * + * This function gets the current channel threshold1. + * This value should be > 0, if configured 0, the real threshold is PWM_PR + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] channel : the channel number, 0-7 + * \return channel threshold1 + */ +__attribute__((always_inline)) static inline uint32_t PwmLiteReg_GetChThr1(const PwmLiteRegType *obj, uint8_t channel) +{ + return obj->CH[channel].THR1; +} + +/*! \brief Sets the channel threshold1 + * + * This function sets the channel threshold1. + * This value should be > 0, if configured 0, the real threshold is PWM_PR + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] channel : the channel number, 0-7 + * \param[in] value : the value of channel threshold1 + */ +__attribute__((always_inline)) static inline void PwmLiteReg_SetChThr1(PwmLiteRegType *obj, uint8_t channel, uint32_t value) +{ + obj->CH[channel].THR1 = value; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _PWMLITE_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/rcm_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/rcm_reg.h new file mode 100644 index 0000000..f19af84 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/rcm_reg.h @@ -0,0 +1,1326 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _RCM_REG_H_ +#define _RCM_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the RCM Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* RST_FLAG Bit Fields */ +#define RCM_RST_FLAG_POR_RST_MASK (0x2000u) +#define RCM_RST_FLAG_POR_RST_SHIFT (13u) +#define RCM_RST_FLAG_POR_RST_WIDTH (1u) +#define RCM_RST_FLAG_LVR_RST_MASK (0x1000u) +#define RCM_RST_FLAG_LVR_RST_SHIFT (12u) +#define RCM_RST_FLAG_LVR_RST_WIDTH (1u) +#define RCM_RST_FLAG_FLS_INITIAL_MASK (0x800u) +#define RCM_RST_FLAG_FLS_INITIAL_SHIFT (11u) +#define RCM_RST_FLAG_FLS_INITIAL_WIDTH (1u) +#define RCM_RST_FLAG_STDBY_EXIT_F_MASK (0x400u) +#define RCM_RST_FLAG_STDBY_EXIT_F_SHIFT (10u) +#define RCM_RST_FLAG_STDBY_EXIT_F_WIDTH (1u) +#define RCM_RST_FLAG_FHU_RESET_F_MASK (0x200u) +#define RCM_RST_FLAG_FHU_RESET_F_SHIFT (9u) +#define RCM_RST_FLAG_FHU_RESET_F_WIDTH (1u) +#define RCM_RST_FLAG_CMU_SOSC_F_MASK (0x100u) +#define RCM_RST_FLAG_CMU_SOSC_F_SHIFT (8u) +#define RCM_RST_FLAG_CMU_SOSC_F_WIDTH (1u) +#define RCM_RST_FLAG_CMU_PLL_F_MASK (0x80u) +#define RCM_RST_FLAG_CMU_PLL_F_SHIFT (7u) +#define RCM_RST_FLAG_CMU_PLL_F_WIDTH (1u) +#define RCM_RST_FLAG_PLL_LOSS_F_MASK (0x20u) +#define RCM_RST_FLAG_PLL_LOSS_F_SHIFT (5u) +#define RCM_RST_FLAG_PLL_LOSS_F_WIDTH (1u) +#define RCM_RST_FLAG_MDMAP_RST_F_MASK (0x10u) +#define RCM_RST_FLAG_MDMAP_RST_F_SHIFT (4u) +#define RCM_RST_FLAG_MDMAP_RST_F_WIDTH (1u) +#define RCM_RST_FLAG_PIN_RST_F_MASK (0x08u) +#define RCM_RST_FLAG_PIN_RST_F_SHIFT (3u) +#define RCM_RST_FLAG_PIN_RST_F_WIDTH (1u) +#define RCM_RST_FLAG_LOCKUP_RST_F_MASK (0x04u) +#define RCM_RST_FLAG_LOCKUP_RST_F_SHIFT (2u) +#define RCM_RST_FLAG_LOCKUP_RST_F_WIDTH (1u) +#define RCM_RST_FLAG_SYS_RST_F_MASK (0x02u) +#define RCM_RST_FLAG_SYS_RST_F_SHIFT (1u) +#define RCM_RST_FLAG_SYS_RST_F_WIDTH (1u) +#define RCM_RST_FLAG_WDG_RST_F_MASK (0x01u) +#define RCM_RST_FLAG_WDG_RST_F_SHIFT (0u) +#define RCM_RST_FLAG_WDG_RST_F_WIDTH (1u) + +/* RST_SFLAG Bit Fields */ +#define RCM_RST_SFLAG_POR_RST_SF_MASK (0x2000u) +#define RCM_RST_SFLAG_POR_RST_SF_SHIFT (13u) +#define RCM_RST_SFLAG_POR_RST_SF_WIDTH (1u) +#define RCM_RST_SFLAG_LVR_RST_SF_MASK (0x1000u) +#define RCM_RST_SFLAG_LVR_RST_SF_SHIFT (12u) +#define RCM_RST_SFLAG_LVR_RST_SF_WIDTH (1u) +#define RCM_RST_SFLAG_FLS_INITIAL_SF_MASK (0x800u) +#define RCM_RST_SFLAG_FLS_INITIAL_SF_SHIFT (11u) +#define RCM_RST_SFLAG_FLS_INITIAL_SF_WIDTH (1u) +#define RCM_RST_SFLAG_STDBY_EXIT_SF_MASK (0x400u) +#define RCM_RST_SFLAG_STDBY_EXIT_SF_SHIFT (10u) +#define RCM_RST_SFLAG_STDBY_EXIT_SF_WIDTH (1u) +#define RCM_RST_SFLAG_FHU_RESET_SF_MASK (0x200u) +#define RCM_RST_SFLAG_FHU_RESET_SF_SHIFT (9u) +#define RCM_RST_SFLAG_FHU_RESET_SF_WIDTH (1u) +#define RCM_RST_SFLAG_CMU_SOSC_SF_MASK (0x100u) +#define RCM_RST_SFLAG_CMU_SOSC_SF_SHIFT (8u) +#define RCM_RST_SFLAG_CMU_SOSC_SF_WIDTH (1u) +#define RCM_RST_SFLAG_CMU_PLL_SF_MASK (0x80u) +#define RCM_RST_SFLAG_CMU_PLL_SF_SHIFT (7u) +#define RCM_RST_SFLAG_CMU_PLL_SF_WIDTH (1u) +#define RCM_RST_SFLAG_PLL_LOSS_SF_MASK (0x20u) +#define RCM_RST_SFLAG_PLL_LOSS_SF_SHIFT (5u) +#define RCM_RST_SFLAG_PLL_LOSS_SF_WIDTH (1u) +#define RCM_RST_SFLAG_MDMAP_RST_SF_MASK (0x10u) +#define RCM_RST_SFLAG_MDMAP_RST_SF_SHIFT (4u) +#define RCM_RST_SFLAG_MDMAP_RST_SF_WIDTH (1u) +#define RCM_RST_SFLAG_PIN_RST_SF_MASK (0x08u) +#define RCM_RST_SFLAG_PIN_RST_SF_SHIFT (3u) +#define RCM_RST_SFLAG_PIN_RST_SF_WIDTH (1u) +#define RCM_RST_SFLAG_LOCKUP_RST_SF_MASK (0x04u) +#define RCM_RST_SFLAG_LOCKUP_RST_SF_SHIFT (2u) +#define RCM_RST_SFLAG_LOCKUP_RST_SF_WIDTH (1u) +#define RCM_RST_SFLAG_SYS_RST_SF_MASK (0x02u) +#define RCM_RST_SFLAG_SYS_RST_SF_SHIFT (1u) +#define RCM_RST_SFLAG_SYS_RST_SF_WIDTH (1u) +#define RCM_RST_SFLAG_WDG_RST_SF_MASK (0x01u) +#define RCM_RST_SFLAG_WDG_RST_SF_SHIFT (0u) +#define RCM_RST_SFLAG_WDG_RST_SF_WIDTH (1u) + +/* RST_CTRL Bit Fields */ +#define RCM_RST_CTRL_LOCKUP_EN_MASK (0x20000u) +#define RCM_RST_CTRL_LOCKUP_EN_SHIFT (17u) +#define RCM_RST_CTRL_LOCKUP_EN_WIDTH (1u) +#define RCM_RST_CTRL_PLL_LOSS_EN_MASK (0x10000u) +#define RCM_RST_CTRL_PLL_LOSS_EN_SHIFT (16u) +#define RCM_RST_CTRL_PLL_LOSS_EN_WIDTH (1u) +#define RCM_RST_CTRL_CMU_SOSC_IE_MASK (0x1000u) +#define RCM_RST_CTRL_CMU_SOSC_IE_SHIFT (12u) +#define RCM_RST_CTRL_CMU_SOSC_IE_WIDTH (1u) +#define RCM_RST_CTRL_CMU_PLL_IE_MASK (0x800u) +#define RCM_RST_CTRL_CMU_PLL_IE_SHIFT (11u) +#define RCM_RST_CTRL_CMU_PLL_IE_WIDTH (1u) +#define RCM_RST_CTRL_PLL_LOSS_IE_MASK (0x200u) +#define RCM_RST_CTRL_PLL_LOSS_IE_SHIFT (9u) +#define RCM_RST_CTRL_PLL_LOSS_IE_WIDTH (1u) +#define RCM_RST_CTRL_MDMAP_RST_IE_MASK (0x100u) +#define RCM_RST_CTRL_MDMAP_RST_IE_SHIFT (8u) +#define RCM_RST_CTRL_MDMAP_RST_IE_WIDTH (1u) +#define RCM_RST_CTRL_PIN_RST_IE_MASK (0x80u) +#define RCM_RST_CTRL_PIN_RST_IE_SHIFT (7u) +#define RCM_RST_CTRL_PIN_RST_IE_WIDTH (1u) +#define RCM_RST_CTRL_SYS_RST_IE_MASK (0x20u) +#define RCM_RST_CTRL_SYS_RST_IE_SHIFT (5u) +#define RCM_RST_CTRL_SYS_RST_IE_WIDTH (1u) +#define RCM_RST_CTRL_WDG_RST_IE_MASK (0x10u) +#define RCM_RST_CTRL_WDG_RST_IE_SHIFT (4u) +#define RCM_RST_CTRL_WDG_RST_IE_WIDTH (1u) +#define RCM_RST_CTRL_GLOBAL_IE_MASK (0x04u) +#define RCM_RST_CTRL_GLOBAL_IE_SHIFT (2u) +#define RCM_RST_CTRL_GLOBAL_IE_WIDTH (1u) +#define RCM_RST_CTRL_RST_DELAY_MASK (0x03u) +#define RCM_RST_CTRL_RST_DELAY_SHIFT (0u) +#define RCM_RST_CTRL_RST_DELAY_WIDTH (2u) + +/* EXTRST Bit Fields */ +#define RCM_EXTRST_FLT_LEN_MASK (0x1F00u) +#define RCM_EXTRST_FLT_LEN_SHIFT (8u) +#define RCM_EXTRST_FLT_LEN_WIDTH (5u) +#define RCM_EXTRST_FLT_CK_MASK (0x10u) +#define RCM_EXTRST_FLT_CK_SHIFT (4u) +#define RCM_EXTRST_FLT_CK_WIDTH (1u) +#define RCM_EXTRST_FLT_EN_MASK (0x01u) +#define RCM_EXTRST_FLT_EN_SHIFT (0u) +#define RCM_EXTRST_FLT_EN_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of RCM registers + */ +typedef struct _RcmRegType_ +{ + const volatile uint32_t RST_FLAG; /*!< Recent reset flag, offset: 0x0 */ + volatile uint32_t RST_SFLAG; /*!< Sticky reset flag, offset: 0x4 */ + volatile uint32_t RST_CTRL; /*!< Reset control register, offset: 0x8 */ + volatile uint32_t EXTRST; /*!< External reset register, offset: 0xC */ + uint32_t RESERVED0[28]; /*!< Reserved register, offset: 0x10 */ + volatile uint32_t KEY; /*!< RCM lock/unlock key register, offset: 0x80 */ + const volatile uint32_t LOCK; /*!< RCM unlock/lock flag, offset: 0x84 */ +} RcmRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the power up reset flag + * + * This function gets the current power up reset flag. + * Indicates a reset has been caused by power up reset. + * + * \param[in] obj : pointer to RCM register instance + * \return power up reset flag + * - 0b : Reset not caused by power up reset + * - 1b : Reset caused by power up reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagPor(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_POR_RST_MASK) >> RCM_RST_FLAG_POR_RST_SHIFT); +} + +/*! \brief Gets the low power reset flag + * + * This function gets the current low power reset flag. + * Indicates a reset has been caused by low power reset. + * + * \param[in] obj : pointer to RCM register instance + * \return low power reset flag + * - 0b : Reset not caused by low power reset + * - 1b : Reset caused by low power reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagLvr(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_LVR_RST_MASK) >> RCM_RST_FLAG_LVR_RST_SHIFT); +} + +/*! \brief Gets the Flash initial reset flag + * + * This function gets the current Flash initial reset flag. + * Indicates a reset has been caused by Flash initial reset. + * + * \param[in] obj : pointer to RCM register instance + * \return Flash initial reset flag + * - 0b : Reset not caused by Flash initial reset + * - 1b : Reset caused by Flash initial reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagFlsInitial(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_FLS_INITIAL_MASK) >> RCM_RST_FLAG_FLS_INITIAL_SHIFT); +} + +/*! \brief Gets the exit standby mode reset flag + * + * This function gets the current exit standby mode reset flag. + * Indicates a reset has been caused by standby exit reset. + * + * \param[in] obj : pointer to RCM register instance + * \return exit standby mode reset flag + * - 0b : Reset not caused by standby exit reset + * - 1b : Reset caused by standby exit reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagStdbyExit(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_STDBY_EXIT_F_MASK) >> RCM_RST_FLAG_STDBY_EXIT_F_SHIFT); +} + +/*! \brief Gets the FHU reset flag + * + * This function gets the current FHU reset flag. + * Indicates a reset has been caused by FHU reset. + * + * \param[in] obj : pointer to RCM register instance + * \return FHU reset flag + * - 0b : Reset not caused by FHU reset + * - 1b : Reset caused by FHU reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagFhu(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_FHU_RESET_F_MASK) >> RCM_RST_FLAG_FHU_RESET_F_SHIFT); +} + +/*! \brief Gets the SOSC clock monitor reset flag + * + * This function gets the current SOSC clock monitor reset flag. + * Indicates a reset has been caused by CMU SOSC reset. + * + * \param[in] obj : pointer to RCM register instance + * \return SOSC clock monitor reset flag + * - 0b : Reset not caused by CMU SOSC reset + * - 1b : Reset caused by CMU SOSC reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagCmuSosc(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_CMU_SOSC_F_MASK) >> RCM_RST_FLAG_CMU_SOSC_F_SHIFT); +} + +/*! \brief Gets the PLL clock monitor reset flag + * + * This function gets the current PLL clock monitor reset flag. + * Indicates a reset has been caused by CMU PLL reset. + * + * \param[in] obj : pointer to RCM register instance + * \return PLL clock monitor reset flag + * - 0b : Reset not caused by CMU PLL reset + * - 1b : Reset caused by CMU PLL reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagCmuPll(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_CMU_PLL_F_MASK) >> RCM_RST_FLAG_CMU_PLL_F_SHIFT); +} + +/*! \brief Gets the PLL lock loss reset flag + * + * This function gets the current PLL lock loss reset flag. + * Indicates a reset has been caused by PLL loss lock reset. + * + * \param[in] obj : pointer to RCM register instance + * \return PLL lock loss reset flag + * - 0b : Reset not caused by PLL lock loss reset + * - 1b : Reset caused by PLL lock loss reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagPllLoss(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_PLL_LOSS_F_MASK) >> RCM_RST_FLAG_PLL_LOSS_F_SHIFT); +} + +/*! \brief Gets the MDMAP reset flag + * + * This function gets the current MDMAP reset flag. + * Indicates a reset has been caused by MDMAP system reset. + * + * \param[in] obj : pointer to RCM register instance + * \return MDMAP reset flag + * - 0b : Reset not caused by MDMAP system reset + * - 1b : Reset caused by MDMAP system reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagMdmap(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_MDMAP_RST_F_MASK) >> RCM_RST_FLAG_MDMAP_RST_F_SHIFT); +} + +/*! \brief Gets the External PIN reset flag + * + * This function gets the current External PIN reset flag. + * Indicates a reset has been caused by an active-low level on the external RESET (RESET_b) pin. + * + * \param[in] obj : pointer to RCM register instance + * \return External PIN reset flag + * - 0b : Reset not caused by external reset pin + * - 1b : Reset caused by external reset pin + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagPin(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_PIN_RST_F_MASK) >> RCM_RST_FLAG_PIN_RST_F_SHIFT); +} + +/*! \brief Gets the Core Lockup reset flag + * + * This function gets the current Core Lockup reset flag. + * Indicates a reset has been caused by the Arm core indication of a LOCKUP event. + * + * \param[in] obj : pointer to RCM register instance + * \return Core Lockup reset flag + * - 0b : Reset not caused by core LOCKUP event + * - 1b : Reset caused by core LOCKUP event + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagLockup(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_LOCKUP_RST_F_MASK) >> RCM_RST_FLAG_LOCKUP_RST_F_SHIFT); +} + +/*! \brief Gets the CPU Software reset flag + * + * This function gets the current CPU Software reset flag. + * Indicates a reset has been caused by software setting of SYSRESETREQ bit in + * Application Interrupt and Reset Control Register in the Arm core. + * + * \param[in] obj : pointer to RCM register instance + * \return CPU Software reset flag + * - 0b : Reset not caused by software setting of SYSRESETREQ bit + * - 1b : Reset caused by software setting of SYSRESETREQ bit + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagSys(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_SYS_RST_F_MASK) >> RCM_RST_FLAG_SYS_RST_F_SHIFT); +} + +/*! \brief Gets the Watchdog reset flag + * + * This function gets the current Watchdog reset flag. + * Indicates a reset has been caused by the watchdog timer timing out. + * This reset source can be blocked by disabling the watchdog. + * + * \param[in] obj : pointer to RCM register instance + * \return Watchdog reset flag + * - 0b : Reset not caused by watchdog timeout + * - 1b : Reset caused by watchdog timeout + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagWdg(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_WDG_RST_F_MASK) >> RCM_RST_FLAG_WDG_RST_F_SHIFT); +} + +/*! \brief Gets the Sticky power up reset flag + * + * This function gets the current Sticky power up reset flag. + * Indicates a reset has been caused by power up reset. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky power up reset flag + * - 0b : Reset not caused by power up reset + * - 1b : Reset caused by power up reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagPor(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_POR_RST_SF_MASK) >> RCM_RST_SFLAG_POR_RST_SF_SHIFT); +} + +/*! \brief Sets the Sticky power up reset flag + * + * This function sets the Sticky power up reset flag. + * Indicates a reset has been caused by power up reset. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky power up reset flag + * - 0b : Reset not caused by power up reset + * - 1b : Reset caused by power up reset + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagPor(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_POR_RST_SF_SHIFT)) & RCM_RST_SFLAG_POR_RST_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky low power reset flag + * + * This function gets the current Sticky low power reset flag. + * Indicates a reset has been caused by low power reset. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky low power reset flag + * - 0b : Reset not caused by low power reset + * - 1b : Reset caused by low power reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagLvr(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_LVR_RST_SF_MASK) >> RCM_RST_SFLAG_LVR_RST_SF_SHIFT); +} + +/*! \brief Sets the Sticky low power reset flag + * + * This function sets the Sticky low power reset flag. + * Indicates a reset has been caused by low power reset. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky low power reset flag + * - 0b : Reset not caused by low power reset + * - 1b : Reset caused by low power reset + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagLvr(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_LVR_RST_SF_SHIFT)) & RCM_RST_SFLAG_LVR_RST_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky Flash initial reset flag + * + * This function gets the current Sticky Flash initial reset flag. + * Indicates a reset has been caused by Flash initial reset. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky Flash initial reset flag + * - 0b : Reset not caused by Flash initial reset + * - 1b : Reset caused by Flash initial reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagFlsInitial(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_FLS_INITIAL_SF_MASK) >> RCM_RST_SFLAG_FLS_INITIAL_SF_SHIFT); +} + +/*! \brief Sets the Sticky Flash initial reset flag + * + * This function sets the Sticky Flash initial reset flag. + * Indicates a reset has been caused by Flash initial reset. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky Flash initial reset flag + * - 0b : Reset not caused by Flash initial reset + * - 1b : Reset caused by Flash initial reset + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagFlsInitial(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_FLS_INITIAL_SF_SHIFT)) & RCM_RST_SFLAG_FLS_INITIAL_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky exit standby mode reset flag + * + * This function gets the current Sticky exit standby mode reset flag. + * Indicates a reset has been caused by standby exit reset. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky exit standby mode reset flag + * - 0b : Reset not caused by standby exit reset + * - 1b : Reset caused by standby exit reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagStdbyExit(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_STDBY_EXIT_SF_MASK) >> RCM_RST_SFLAG_STDBY_EXIT_SF_SHIFT); +} + +/*! \brief Sets the Sticky exit standby mode reset flag + * + * This function sets the Sticky exit standby mode reset flag. + * Indicates a reset has been caused by standby exit reset. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky exit standby mode reset flag + * - 0b : Reset not caused by standby exit reset + * - 1b : Reset caused by standby exit reset + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagStdbyExit(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_STDBY_EXIT_SF_SHIFT)) & RCM_RST_SFLAG_STDBY_EXIT_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky FHU reset flag + * + * This function gets the current Sticky FHU reset flag. + * Indicates a reset has been caused by FHU reset. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky FHU reset flag + * - 0b : Reset not caused by FHU reset + * - 1b : Reset caused by FHU reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagFhu(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_FHU_RESET_SF_MASK) >> RCM_RST_SFLAG_FHU_RESET_SF_SHIFT); +} + +/*! \brief Sets the Sticky FHU reset flag + * + * This function sets the Sticky FHU reset flag. + * Indicates a reset has been caused by FHU reset. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky FHU reset flag + * - 0b : Reset not caused by FHU reset + * - 1b : Reset caused by FHU reset + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagFhu(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_FHU_RESET_SF_SHIFT)) & RCM_RST_SFLAG_FHU_RESET_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky SOSC clock monitor reset flag + * + * This function gets the current Sticky SOSC clock monitor reset flag. + * Indicates a reset has been caused by CMU SOSC reset. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky SOSC clock monitor reset flag + * - 0b : Reset not caused by CMU SOSC reset + * - 1b : Reset caused by CMU SOSC reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagCmuSosc(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_CMU_SOSC_SF_MASK) >> RCM_RST_SFLAG_CMU_SOSC_SF_SHIFT); +} + +/*! \brief Sets the Sticky SOSC clock monitor reset flag + * + * This function sets the Sticky SOSC clock monitor reset flag. + * Indicates a reset has been caused by CMU SOSC reset. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky SOSC clock monitor reset flag + * - 0b : Reset not caused by CMU SOSC reset + * - 1b : Reset caused by CMU SOSC reset + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagCmuSosc(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_CMU_SOSC_SF_SHIFT)) & RCM_RST_SFLAG_CMU_SOSC_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky PLL clock monitor reset flag + * + * This function gets the current Sticky PLL clock monitor reset flag. + * Indicates a reset has been caused by CMU PLL reset. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky PLL clock monitor reset flag + * - 0b : Reset not caused by CMU PLL reset + * - 1b : Reset caused by CMU PLL reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagCmuPll(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_CMU_PLL_SF_MASK) >> RCM_RST_SFLAG_CMU_PLL_SF_SHIFT); +} + +/*! \brief Sets the Sticky PLL clock monitor reset flag + * + * This function sets the Sticky PLL clock monitor reset flag. + * Indicates a reset has been caused by CMU PLL reset. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky PLL clock monitor reset flag + * - 0b : Reset not caused by CMU PLL reset + * - 1b : Reset caused by CMU PLL reset + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagCmuPll(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_CMU_PLL_SF_SHIFT)) & RCM_RST_SFLAG_CMU_PLL_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky PLL lock loss reset flag + * + * This function gets the current Sticky PLL lock loss reset flag. + * Indicates a reset has been caused by PLL loss lock reset. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky PLL lock loss reset flag + * - 0b : Reset not caused by PLL lock loss reset + * - 1b : Reset caused by PLL lock loss reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagPllLoss(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_PLL_LOSS_SF_MASK) >> RCM_RST_SFLAG_PLL_LOSS_SF_SHIFT); +} + +/*! \brief Sets the Sticky PLL lock loss reset flag + * + * This function sets the Sticky PLL lock loss reset flag. + * Indicates a reset has been caused by PLL loss lock reset. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky PLL lock loss reset flag + * - 0b : Reset not caused by PLL lock loss reset + * - 1b : Reset caused by PLL lock loss reset + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagPllLoss(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_PLL_LOSS_SF_SHIFT)) & RCM_RST_SFLAG_PLL_LOSS_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky MDMAP reset flag + * + * This function gets the current Sticky MDMAP reset flag. + * Indicates a reset has been caused by MDMAP system reset. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky MDMAP reset flag + * - 0b : Reset not caused by MDMAP system reset + * - 1b : Reset caused by MDMAP system reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagMdmap(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_MDMAP_RST_SF_MASK) >> RCM_RST_SFLAG_MDMAP_RST_SF_SHIFT); +} + +/*! \brief Sets the Sticky MDMAP reset flag + * + * This function sets the Sticky MDMAP reset flag. + * Indicates a reset has been caused by MDMAP system reset. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky MDMAP reset flag + * - 0b : Reset not caused by MDMAP system reset + * - 1b : Reset caused by MDMAP system reset + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagMdmap(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_MDMAP_RST_SF_SHIFT)) & RCM_RST_SFLAG_MDMAP_RST_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky External PIN reset flag + * + * This function gets the current Sticky External PIN reset flag. + * Indicates a reset has been caused by an active-low level on the external RESET (RESET_b) pin. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky External PIN reset flag + * - 0b : Reset not caused by external reset pin + * - 1b : Reset caused by external reset pin + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagPin(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_PIN_RST_SF_MASK) >> RCM_RST_SFLAG_PIN_RST_SF_SHIFT); +} + +/*! \brief Sets the Sticky External PIN reset flag + * + * This function sets the Sticky External PIN reset flag. + * Indicates a reset has been caused by an active-low level on the external RESET (RESET_b) pin. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky External PIN reset flag + * - 0b : Reset not caused by external reset pin + * - 1b : Reset caused by external reset pin + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagPin(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_PIN_RST_SF_SHIFT)) & RCM_RST_SFLAG_PIN_RST_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky Core Lockup reset flag + * + * This function gets the current Sticky Core Lockup reset flag. + * Indicates a reset has been caused by the Arm core indication of a LOCKUP event. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky Core Lockup reset flag + * - 0b : Reset not caused by core LOCKUP event + * - 1b : Reset caused by core LOCKUP event + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagLockup(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_LOCKUP_RST_SF_MASK) >> RCM_RST_SFLAG_LOCKUP_RST_SF_SHIFT); +} + +/*! \brief Sets the Sticky Core Lockup reset flag + * + * This function sets the Sticky Core Lockup reset flag. + * Indicates a reset has been caused by the Arm core indication of a LOCKUP event. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky Core Lockup reset flag + * - 0b : Reset not caused by core LOCKUP event + * - 1b : Reset caused by core LOCKUP event + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagLockup(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_LOCKUP_RST_SF_SHIFT)) & RCM_RST_SFLAG_LOCKUP_RST_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky CPU Software reset flag + * + * This function gets the current Sticky CPU Software reset flag. + * Indicates a reset has been caused by software setting of SYSRESETREQ bit in Application Interrupt + * and Reset Control Register in the Arm core. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky CPU Software reset flag + * - 0b : Reset not caused by software setting of SYSRESETREQ bit + * - 1b : Reset caused by software setting of SYSRESETREQ bit + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagSys(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_SYS_RST_SF_MASK) >> RCM_RST_SFLAG_SYS_RST_SF_SHIFT); +} + +/*! \brief Sets the Sticky CPU Software reset flag + * + * This function sets the Sticky CPU Software reset flag. + * Indicates a reset has been caused by software setting of SYSRESETREQ bit in Application Interrupt + * and Reset Control Register in the Arm core. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky CPU Software reset flag + * - 0b : Reset not caused by software setting of SYSRESETREQ bit + * - 1b : Reset caused by software setting of SYSRESETREQ bit + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagSys(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_SYS_RST_SF_SHIFT)) & RCM_RST_SFLAG_SYS_RST_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky Watchdog reset flag + * + * This function gets the current Sticky Watchdog reset flag. + * Indicates a reset has been caused by the watchdog timer timing out. + * This reset source can be blocked by disabling the watchdog. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky Watchdog reset flag + * - 0b : Reset not caused by watchdog timeout + * - 1b : Reset caused by watchdog timeout + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagWdg(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_WDG_RST_SF_MASK) >> RCM_RST_SFLAG_WDG_RST_SF_SHIFT); +} + +/*! \brief Sets the Sticky Watchdog reset flag + * + * This function sets the Sticky Watchdog reset flag. + * Indicates a reset has been caused by the watchdog timer timing out. + * This reset source can be blocked by disabling the watchdog. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky Watchdog reset flag + * - 0b : Reset not caused by watchdog timeout + * - 1b : Reset caused by watchdog timeout + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagWdg(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_WDG_RST_SF_SHIFT)) & RCM_RST_SFLAG_WDG_RST_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the lockup reset enable + * + * This function gets the current lockup reset enable. + * + * \param[in] obj : pointer to RCM register instance + * \return lockup reset enable + * - 0b : No reset or interrupt will be caused by LOCKUP. + * - 1b : Reset or interrupt will be caused by LOCKUP. + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlLockupEn(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_LOCKUP_EN_MASK) >> RCM_RST_CTRL_LOCKUP_EN_SHIFT); +} + +/*! \brief Sets the lockup reset enable + * + * This function sets the lockup reset enable. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of lockup reset enable + * - 0b : No reset or interrupt will be caused by LOCKUP. + * - 1b : Reset or interrupt will be caused by LOCKUP. + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlLockupEn(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_LOCKUP_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_LOCKUP_EN_SHIFT)) & RCM_RST_CTRL_LOCKUP_EN_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the PLL lock loss reset enable + * + * This function gets the current PLL lock loss reset enable. + * + * \param[in] obj : pointer to RCM register instance + * \return PLL lock loss reset enable + * - 0b : No reset or interrupt will be caused by PLL lock loss. + * - 1b : Reset or interrupt will be caused by PLL lock loss. + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlPllLossEn(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_PLL_LOSS_EN_MASK) >> RCM_RST_CTRL_PLL_LOSS_EN_SHIFT); +} + +/*! \brief Sets the PLL lock loss reset enable + * + * This function sets the PLL lock loss reset enable. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of PLL lock loss reset enable + * - 0b : No reset or interrupt will be caused by PLL lock loss. + * - 1b : Reset or interrupt will be caused by PLL lock loss. + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlPllLossEn(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_PLL_LOSS_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_PLL_LOSS_EN_SHIFT)) & RCM_RST_CTRL_PLL_LOSS_EN_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the SOSC clock monitor interrupt enable + * + * This function gets the current SOSC clock monitor interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \return SOSC clock monitor interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlCmuSoscIE(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_CMU_SOSC_IE_MASK) >> RCM_RST_CTRL_CMU_SOSC_IE_SHIFT); +} + +/*! \brief Sets the SOSC clock monitor interrupt enable + * + * This function sets the SOSC clock monitor interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of SOSC clock monitor interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlCmuSoscIE(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_CMU_SOSC_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_CMU_SOSC_IE_SHIFT)) & RCM_RST_CTRL_CMU_SOSC_IE_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the PLL clock monitor interrupt enable + * + * This function gets the current PLL clock monitor interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \return PLL clock monitor interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlCmuPllIE(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_CMU_PLL_IE_MASK) >> RCM_RST_CTRL_CMU_PLL_IE_SHIFT); +} + +/*! \brief Sets the PLL clock monitor interrupt enable + * + * This function sets the PLL clock monitor interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of PLL clock monitor interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlCmuPllIE(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_CMU_PLL_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_CMU_PLL_IE_SHIFT)) & RCM_RST_CTRL_CMU_PLL_IE_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the PLL loss reset interrupt enable + * + * This function gets the current PLL loss reset interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \return PLL loss reset interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlPllLossIE(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_PLL_LOSS_IE_MASK) >> RCM_RST_CTRL_PLL_LOSS_IE_SHIFT); +} + +/*! \brief Sets the PLL loss reset interrupt enable + * + * This function sets the PLL loss reset interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of PLL loss reset interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlPllLossIE(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_PLL_LOSS_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_PLL_LOSS_IE_SHIFT)) & RCM_RST_CTRL_PLL_LOSS_IE_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the MDMAP system reset interrupt enable + * + * This function gets the current MDMAP system reset interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \return MDMAP system reset interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlMdmapRstIE(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_MDMAP_RST_IE_MASK) >> RCM_RST_CTRL_MDMAP_RST_IE_SHIFT); +} + +/*! \brief Sets the MDMAP system reset interrupt enable + * + * This function sets the MDMAP system reset interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of MDMAP system reset interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlMdmapRstIE(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_MDMAP_RST_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_MDMAP_RST_IE_SHIFT)) & RCM_RST_CTRL_MDMAP_RST_IE_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the external reset pin interrupt enable + * + * This function gets the current external reset pin interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \return external reset pin interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlPinRstIE(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_PIN_RST_IE_MASK) >> RCM_RST_CTRL_PIN_RST_IE_SHIFT); +} + +/*! \brief Sets the external reset pin interrupt enable + * + * This function sets the external reset pin interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of external reset pin interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlPinRstIE(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_PIN_RST_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_PIN_RST_IE_SHIFT)) & RCM_RST_CTRL_PIN_RST_IE_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the CPU system reset interrupt enable + * + * This function gets the current CPU system reset interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \return CPU system reset interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlSysRstIE(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_SYS_RST_IE_MASK) >> RCM_RST_CTRL_SYS_RST_IE_SHIFT); +} + +/*! \brief Sets the CPU system reset interrupt enable + * + * This function sets the CPU system reset interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of CPU system reset interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlSysRstIE(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_SYS_RST_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_SYS_RST_IE_SHIFT)) & RCM_RST_CTRL_SYS_RST_IE_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the watchdog reset interrupt enable + * + * This function gets the current watchdog reset interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \return watchdog reset interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlWdgRstIE(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_WDG_RST_IE_MASK) >> RCM_RST_CTRL_WDG_RST_IE_SHIFT); +} + +/*! \brief Sets the watchdog reset interrupt enable + * + * This function sets the watchdog reset interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of watchdog reset interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlWdgRstIE(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_WDG_RST_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_WDG_RST_IE_SHIFT)) & RCM_RST_CTRL_WDG_RST_IE_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the Global Interrupt Enable + * + * This function gets the current Global Interrupt Enable. + * + * \note The individual interrupt-enable bits still need to be set to generate interrupts + * + * \param[in] obj : pointer to RCM register instance + * \return Global Interrupt Enable + * - 0b : All interrupt sources disabled. + * - 1b : All interrupt sources enabled. + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlGlobalIE(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_GLOBAL_IE_MASK) >> RCM_RST_CTRL_GLOBAL_IE_SHIFT); +} + +/*! \brief Sets the Global Interrupt Enable + * + * This function sets the Global Interrupt Enable. + * + * \note The individual interrupt-enable bits still need to be set to generate interrupts + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Global Interrupt Enable + * - 0b : All interrupt sources disabled. + * - 1b : All interrupt sources enabled. + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlGlobalIE(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_GLOBAL_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_GLOBAL_IE_SHIFT)) & RCM_RST_CTRL_GLOBAL_IE_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the Reset Delay Time + * + * This function gets the current Reset Delay Time. + * Configures the maximum reset delay time from when the interrupt is asserted and the system reset occurs. + * + * \param[in] obj : pointer to RCM register instance + * \return Reset Delay Time + * - 00b : 10 LPO cycles + * - 01b : 34 LPO cycles + * - 10b : 130 LPO cycles + * - 11b : 514 LPO cycles + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlRstDelay(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_RST_DELAY_MASK) >> RCM_RST_CTRL_RST_DELAY_SHIFT); +} + +/*! \brief Sets the Reset Delay Time + * + * This function sets the Reset Delay Time. + * Configures the maximum reset delay time from when the interrupt is asserted and the system reset occurs. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Reset Delay Time + * - 00b : 10 LPO cycles + * - 01b : 34 LPO cycles + * - 10b : 130 LPO cycles + * - 11b : 514 LPO cycles + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlRstDelay(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_RST_DELAY_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_RST_DELAY_SHIFT)) & RCM_RST_CTRL_RST_DELAY_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the external reset input digital filter length + * + * This function gets the current external reset input digital filter length. + * + * \param[in] obj : pointer to RCM register instance + * \return external reset input digital filter length + * - 00h : 1 + * - 01h : 2 + * - 02h : 3 + * ... + * - 1Fh : 32 + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetExtRstFltLen(const RcmRegType *obj) +{ + return ((obj->EXTRST & RCM_EXTRST_FLT_LEN_MASK) >> RCM_EXTRST_FLT_LEN_SHIFT); +} + +/*! \brief Sets the external reset input digital filter length + * + * This function sets the external reset input digital filter length. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of external reset input digital filter length + * - 00h : 1 + * - 01h : 2 + * - 02h : 3 + * ... + * - 1Fh : 32 + */ +__attribute__((always_inline)) static inline void RcmReg_SetExtRstFltLen(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTRST; + + tmp &= ~RCM_EXTRST_FLT_LEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_EXTRST_FLT_LEN_SHIFT)) & RCM_EXTRST_FLT_LEN_MASK); + obj->EXTRST = tmp; +} + +/*! \brief Gets the clock source of PIN Reset digital filter + * + * This function gets the current clock source of PIN Reset digital filter. + * This register should be changed after the clock is disabled at least 2 pre-changed clock cycles + * and 2 after-changed clock cycles. + * + * \param[in] obj : pointer to RCM register instance + * \return clock source of PIN Reset digital filter + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetExtRstFltCk(const RcmRegType *obj) +{ + return ((obj->EXTRST & RCM_EXTRST_FLT_CK_MASK) >> RCM_EXTRST_FLT_CK_SHIFT); +} + +/*! \brief Sets the clock source of PIN Reset digital filter + * + * This function sets the clock source of PIN Reset digital filter. + * This register should be changed after the clock is disabled at least 2 pre-changed clock cycles + * and 2 after-changed clock cycles. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of clock source of PIN Reset digital filter + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline void RcmReg_SetExtRstFltCk(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTRST; + + tmp &= ~RCM_EXTRST_FLT_CK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_EXTRST_FLT_CK_SHIFT)) & RCM_EXTRST_FLT_CK_MASK); + obj->EXTRST = tmp; +} + +/*! \brief Gets the external reset input digital filter enable + * + * This function gets the current external reset input digital filter enable. + * Reset by Chip Por only + * + * \param[in] obj : pointer to RCM register instance + * \return external reset input digital filter enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetExtRstFltEn(const RcmRegType *obj) +{ + return ((obj->EXTRST & RCM_EXTRST_FLT_EN_MASK) >> RCM_EXTRST_FLT_EN_SHIFT); +} + +/*! \brief Sets the external reset input digital filter enable + * + * This function sets the external reset input digital filter enable. + * Reset by Chip Por only + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of external reset input digital filter enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void RcmReg_SetExtRstFltEn(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTRST; + + tmp &= ~RCM_EXTRST_FLT_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_EXTRST_FLT_EN_SHIFT)) & RCM_EXTRST_FLT_EN_MASK); + obj->EXTRST = tmp; +} + +/*! \brief Sets the unlock key + * + * This function sets the unlock key. + * The RST/SCG/PCC registers in ALON power domain is locked by default. + * Before writing registers, write unlock key to this register. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of unlock key + * - 0x52434D4B : unlock + * - other : lock + */ +__attribute__((always_inline)) static inline void RcmReg_SetKey(RcmRegType *obj, uint32_t value) +{ + obj->KEY = value; +} + +/*! \brief Gets the RCM register lock flag + * + * This function gets the current RCM register lock flag. + * Registers in RCM is locked by default. Before writing registers in rcm, write unlock key. + * + * \param[in] obj : pointer to RCM register instance + * \return RCM register lock flag + * - 0b : unlock + * - 1b : lock + */ +__attribute__((always_inline)) static inline uint32_t RcmReg_GetLock(const RcmRegType *obj) +{ + return obj->LOCK; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _RCM_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/rtc_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/rtc_reg.h new file mode 100644 index 0000000..e7b26cc --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/rtc_reg.h @@ -0,0 +1,809 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _RTC_REG_H_ +#define _RTC_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the RTC (Real Time Clock) Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* TPR Bit Fields */ +#define RTC_TPR_TPR_MASK (0xFFFFu) +#define RTC_TPR_TPR_SHIFT (0u) +#define RTC_TPR_TPR_WIDTH (16u) + +/* CR Bit Fields */ +#define RTC_CR_CPE_MASK (0x1000000u) +#define RTC_CR_CPE_SHIFT (24u) +#define RTC_CR_CPE_WIDTH (1u) +#define RTC_CR_CLKO_MASK (0x200u) +#define RTC_CR_CLKO_SHIFT (9u) +#define RTC_CR_CLKO_WIDTH (1u) +#define RTC_CR_CPS_MASK (0x20u) +#define RTC_CR_CPS_SHIFT (5u) +#define RTC_CR_CPS_WIDTH (1u) +#define RTC_CR_UM_MASK (0x08u) +#define RTC_CR_UM_SHIFT (3u) +#define RTC_CR_UM_WIDTH (1u) +#define RTC_CR_SUP_MASK (0x04u) +#define RTC_CR_SUP_SHIFT (2u) +#define RTC_CR_SUP_WIDTH (1u) +#define RTC_CR_SWR_MASK (0x01u) +#define RTC_CR_SWR_SHIFT (0u) +#define RTC_CR_SWR_WIDTH (1u) + +/* SR Bit Fields */ +#define RTC_SR_TCE_MASK (0x10u) +#define RTC_SR_TCE_SHIFT (4u) +#define RTC_SR_TCE_WIDTH (1u) +#define RTC_SR_CSD_MASK (0x08u) +#define RTC_SR_CSD_SHIFT (3u) +#define RTC_SR_CSD_WIDTH (1u) +#define RTC_SR_TAF_MASK (0x04u) +#define RTC_SR_TAF_SHIFT (2u) +#define RTC_SR_TAF_WIDTH (1u) +#define RTC_SR_TOF_MASK (0x02u) +#define RTC_SR_TOF_SHIFT (1u) +#define RTC_SR_TOF_WIDTH (1u) +#define RTC_SR_TIF_MASK (0x01u) +#define RTC_SR_TIF_SHIFT (0u) +#define RTC_SR_TIF_WIDTH (1u) + +/* LR Bit Fields */ +#define RTC_LR_LRL_MASK (0x40u) +#define RTC_LR_LRL_SHIFT (6u) +#define RTC_LR_LRL_WIDTH (1u) +#define RTC_LR_SRL_MASK (0x20u) +#define RTC_LR_SRL_SHIFT (5u) +#define RTC_LR_SRL_WIDTH (1u) +#define RTC_LR_CRL_MASK (0x10u) +#define RTC_LR_CRL_SHIFT (4u) +#define RTC_LR_CRL_WIDTH (1u) + +/* IER Bit Fields */ +#define RTC_IER_TSIC_MASK (0x70000u) +#define RTC_IER_TSIC_SHIFT (16u) +#define RTC_IER_TSIC_WIDTH (3u) +#define RTC_IER_TSIE_MASK (0x10u) +#define RTC_IER_TSIE_SHIFT (4u) +#define RTC_IER_TSIE_WIDTH (1u) +#define RTC_IER_TAIE_MASK (0x04u) +#define RTC_IER_TAIE_SHIFT (2u) +#define RTC_IER_TAIE_WIDTH (1u) +#define RTC_IER_TIOE_MASK (0x02u) +#define RTC_IER_TIOE_SHIFT (1u) +#define RTC_IER_TIOE_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of RTC registers + */ +typedef struct _RtcRegType_ +{ + volatile uint32_t TSR; /*!< time second value register, offset: 0x0 */ + volatile uint32_t TPR; /*!< time prescaler value register, offset: 0x4 */ + volatile uint32_t TAR; /*!< time alarm value register, offset: 0x8 */ + uint32_t RESERVED; /*!< reserverd block, offset: 0xC */ + volatile uint32_t CR; /*!< control register, offset: 0x10 */ + volatile uint32_t SR; /*!< status register, offset: 0x14 */ + volatile uint32_t LR; /*!< lock register, offset: 0x18 */ + volatile uint32_t IER; /*!< interrupt config register, offset: 0x1C */ +} RtcRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the TSR value register + * + * This function gets the current TSR value register. + * When the time counter is enabled, the TSR is read only and increments once a second. + * The time counter will read as zero when SR[TOF] or SR[TIF] are set. + * When the time counter is disabled, the TSR can be read or written. + * Writing to the TSR when the time counter is disabled will clear the SR[TOF] and/or the SR[TIF]. + * Writing to TSR with zero is supported, but not recommended because TSR will read as zero when SR[TIF] or SR[TOF] + * are set (indicating the time is invalid) + * + * \param[in] obj : pointer to RTC register instance + * \return current TSR value + */ +__attribute__((always_inline)) static inline uint32_t RtcReg_GetTsr(const RtcRegType *obj) +{ + return obj->TSR; +} + +/*! \brief Sets the TSR value register + * + * This function sets the TSR value register. + * When the time counter is enabled, the TSR is read only and increments once a second. + * The time counter will read as zero when SR[TOF] or SR[TIF] are set. + * When the time counter is disabled, the TSR can be read or written. + * Writing to the TSR when the time counter is disabled will clear the SR[TOF] and/or the SR[TIF]. + * Writing to TSR with zero is supported, but not recommended because TSR will read as zero when SR[TIF] or SR[TOF] + * are set (indicating the time is invalid) + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of TSR register + */ +__attribute__((always_inline)) static inline void RtcReg_SetTsr(RtcRegType *obj, uint32_t value) +{ + obj->TSR = value; +} + +/*! \brief Gets the TPR value register + * + * This function gets the current TPR value register. + * When the time counter is enabled, the TPR is read only and increments every 32.768 kHz clock cycle. + * The time counter will read as zero when SR[TOF] or SR[TIF] are set. + * When the time counter is disabled, the TPR can be read or written. + * The TSR[TSR] increments when bit 14 of the TPR transitions from a logic one to a logic zero + * + * \param[in] obj : pointer to RTC register instance + * \return TPR value register + */ +__attribute__((always_inline)) static inline uint16_t RtcReg_GetTprTpr(const RtcRegType *obj) +{ + return ((obj->TPR & RTC_TPR_TPR_MASK) >> RTC_TPR_TPR_SHIFT); +} + +/*! \brief Sets the TPR value register + * + * This function sets the TPR value register. + * When the time counter is enabled, the TPR is read only and increments every 32.768 kHz clock cycle. + * The time counter will read as zero when SR[TOF] or SR[TIF] are set. + * When the time counter is disabled, the TPR can be read or written. + * The TSR[TSR] increments when bit 14 of the TPR transitions from a logic one to a logic zero + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of TPR value register + */ +__attribute__((always_inline)) static inline void RtcReg_SetTprTpr(RtcRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->TPR; + + tmp &= ~RTC_TPR_TPR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_TPR_TPR_SHIFT)) & RTC_TPR_TPR_MASK); + obj->TPR = tmp; +} + +/*! \brief Gets the TAR value register + * + * This function gets the current TAR value register. + * When the time counter is enabled, the SR[TAF] is set whenever the TAR[TAR] equals the TSR[TSR] and the TSR[TSR] increments. + * Writing to the TAR clears the SR[TAF] + * + * \param[in] obj : pointer to RTC register instance + * \return TAR value register + */ +__attribute__((always_inline)) static inline uint32_t RtcReg_GetTar(const RtcRegType *obj) +{ + return obj->TAR; +} + +/*! \brief Sets the TAR value register + * + * This function sets the TAR value register. + * When the time counter is enabled, the SR[TAF] is set whenever the TAR[TAR] equals the TSR[TSR] and the TSR[TSR] increments. + * Writing to the TAR clears the SR[TAF] + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of TAR value register + */ +__attribute__((always_inline)) static inline void RtcReg_SetTar(RtcRegType *obj, uint32_t value) +{ + obj->TAR = value; +} + +/*! \brief Gets the Clock Pin Enable + * + * This function gets the current Clock Pin Enable. + * + * \param[in] obj : pointer to RTC register instance + * \return Clock Pin Enable + * - 0b : The RTC_CLKOUT function is disabled. + * - 1b : Enable RTC_CLKOUT function. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetCrCpe(const RtcRegType *obj) +{ + return ((obj->CR & RTC_CR_CPE_MASK) >> RTC_CR_CPE_SHIFT); +} + +/*! \brief Sets the Clock Pin Enable + * + * This function sets the Clock Pin Enable. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Clock Pin Enable + * - 0b : The RTC_CLKOUT function is disabled. + * - 1b : Enable RTC_CLKOUT function. + */ +__attribute__((always_inline)) static inline void RtcReg_SetCrCpe(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR; + + tmp &= ~RTC_CR_CPE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_CR_CPE_SHIFT)) & RTC_CR_CPE_MASK); + obj->CR = tmp; +} + +/*! \brief Gets the Clock Output + * + * This function gets the current Clock Output. + * + * \param[in] obj : pointer to RTC register instance + * \return Clock Output + * - 0b : The 32K/32.768KHz clock is output to other peripherals. + * - 1b : The 32K/32.768KHz clock is not output to other peripherals. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetCrClkO(const RtcRegType *obj) +{ + return ((obj->CR & RTC_CR_CLKO_MASK) >> RTC_CR_CLKO_SHIFT); +} + +/*! \brief Sets the Clock Output + * + * This function sets the Clock Output. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Clock Output + * - 0b : The 32K/32.768KHz clock is output to other peripherals. + * - 1b : The 32K/32.768KHz clock is not output to other peripherals. + */ +__attribute__((always_inline)) static inline void RtcReg_SetCrClkO(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR; + + tmp &= ~RTC_CR_CLKO_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_CR_CLKO_SHIFT)) & RTC_CR_CLKO_MASK); + obj->CR = tmp; +} + +/*! \brief Gets the Clock Pin Select + * + * This function gets the current Clock Pin Select. + * + * \param[in] obj : pointer to RTC register instance + * \return Clock Pin Select + * - 0b : The prescaler output clock (as configured by TSIC) is output on RTC_CLKOUT. + * - 1b : The RTC 32.768 kHz/32kHz clock is output on RTC_CLKOUT, provided it is output to other peripherals. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetCrCps(const RtcRegType *obj) +{ + return ((obj->CR & RTC_CR_CPS_MASK) >> RTC_CR_CPS_SHIFT); +} + +/*! \brief Sets the Clock Pin Select + * + * This function sets the Clock Pin Select. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Clock Pin Select + * - 0b : The prescaler output clock (as configured by TSIC) is output on RTC_CLKOUT. + * - 1b : The RTC 32.768 kHz/32kHz clock is output on RTC_CLKOUT, provided it is output to other peripherals. + */ +__attribute__((always_inline)) static inline void RtcReg_SetCrCps(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR; + + tmp &= ~RTC_CR_CPS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_CR_CPS_SHIFT)) & RTC_CR_CPS_MASK); + obj->CR = tmp; +} + +/*! \brief Gets the Update Mode + * + * This function gets the current Update Mode. + * when UM=0 and LR[SRL]=0, SR[TCE] can't be written + * when UM=1 and LR[SRL]=0, SR[TCE] can only be written when SR[TCE]=0 or SR[TIF]=1 or SR[TOF]=1. + * (when LR[SRL]=1, CR[UM] has no effect on SR[TCE]. In other words, in this situation, TCE can be written at any time) + * + * \param[in] obj : pointer to RTC register instance + * \return Update Mode + * - 0b : SR[TCE] register cannot be written when locked. + * - 1b : SR[TCE] register can be written when locked under limited conditions. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetCrUm(const RtcRegType *obj) +{ + return ((obj->CR & RTC_CR_UM_MASK) >> RTC_CR_UM_SHIFT); +} + +/*! \brief Sets the Update Mode + * + * This function sets the Update Mode. + * when UM=0 and LR[SRL]=0, SR[TCE] can't be written + * when UM=1 and LR[SRL]=0, SR[TCE] can only be written when SR[TCE]=0 or SR[TIF]=1 or SR[TOF]=1. + * (when LR[SRL]=1, CR[UM] has no effect on SR[TCE]. In other words, in this situation, TCE can be written at any time) + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Update Mode + * - 0b : SR[TCE] register cannot be written when locked. + * - 1b : SR[TCE] register can be written when locked under limited conditions. + */ +__attribute__((always_inline)) static inline void RtcReg_SetCrUm(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR; + + tmp &= ~RTC_CR_UM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_CR_UM_SHIFT)) & RTC_CR_UM_MASK); + obj->CR = tmp; +} + +/*! \brief Gets the Supervisor Access + * + * This function gets the current Supervisor Access. + * + * \param[in] obj : pointer to RTC register instance + * \return Supervisor Access + * - 0b : Non-supervisor mode write accesses are not supported and generate a bus error. + * - 1b : Non-supervisor mode write accesses are supported. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetCrSup(const RtcRegType *obj) +{ + return ((obj->CR & RTC_CR_SUP_MASK) >> RTC_CR_SUP_SHIFT); +} + +/*! \brief Sets the Supervisor Access + * + * This function sets the Supervisor Access. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Supervisor Access + * - 0b : Non-supervisor mode write accesses are not supported and generate a bus error. + * - 1b : Non-supervisor mode write accesses are supported. + */ +__attribute__((always_inline)) static inline void RtcReg_SetCrSup(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR; + + tmp &= ~RTC_CR_SUP_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_CR_SUP_SHIFT)) & RTC_CR_SUP_MASK); + obj->CR = tmp; +} + +/*! \brief Gets the software reset + * + * This function gets the current software reset . + * + * \param[in] obj : pointer to RTC register instance + * \return software reset + * - 0b : no effect + * - 1b : reset all RTC registers except for the SWR bit. + * The SWR bit is cleared by POR and by software explicitly clearing it + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetCrSwr(const RtcRegType *obj) +{ + return ((obj->CR & RTC_CR_SWR_MASK) >> RTC_CR_SWR_SHIFT); +} + +/*! \brief Sets the software reset + * + * This function sets the software reset . + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of software reset + * - 0b : no effect + * - 1b : reset all RTC registers except for the SWR bit. + * The SWR bit is cleared by POR and by software explicitly clearing it + */ +__attribute__((always_inline)) static inline void RtcReg_SetCrSwr(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR; + + tmp &= ~RTC_CR_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_CR_SWR_SHIFT)) & RTC_CR_SWR_MASK); + obj->CR = tmp; +} + +/*! \brief Gets the Time Counter Enable + * + * This function gets the current Time Counter Enable. + * When time counter is disabled the TSR register and TPR register are writeable, but do not increment. + * When time counter is enabled the TSR register and TPR register are not writeable, but increment. + * + * \param[in] obj : pointer to RTC register instance + * \return Time Counter Enable + * - 0b : Time counter is disabled. + * - 1b : Time counter is enabled. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetSrTce(const RtcRegType *obj) +{ + return ((obj->SR & RTC_SR_TCE_MASK) >> RTC_SR_TCE_SHIFT); +} + +/*! \brief Sets the Time Counter Enable + * + * This function sets the Time Counter Enable. + * When time counter is disabled the TSR register and TPR register are writeable, but do not increment. + * When time counter is enabled the TSR register and TPR register are not writeable, but increment. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Time Counter Enable + * - 0b : Time counter is disabled. + * - 1b : Time counter is enabled. + */ +__attribute__((always_inline)) static inline void RtcReg_SetSrTce(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SR; + + tmp &= ~RTC_SR_TCE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_SR_TCE_SHIFT)) & RTC_SR_TCE_MASK); + obj->SR = tmp; +} + +/*! \brief Gets the Time New Config Sync Done Enable + * + * This function gets the current Time New Config Sync Done Enable. + * when new config done, software should set this bit, but return 0 when software read now. + * this bit would be 1 when the new config sync done. Its means software can enable RTC again. + * + * \param[in] obj : pointer to RTC register instance + * \return Time New Config Sync Done Enable + * - 0b : Synchronization of New Config is Ongoing, Re-enable RTC is not allowed. + * - 1b : Synchronization of New Config is Done, Re-enable RTC is allowed. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetSrCsd(const RtcRegType *obj) +{ + return ((obj->SR & RTC_SR_CSD_MASK) >> RTC_SR_CSD_SHIFT); +} + +/*! \brief Sets the Time New Config Sync Done Enable + * + * This function gets the current Time New Config Sync Done Enable. + * when new config done, software should set this bit, but return 0 when software read now. + * this bit would be 1 when the new config sync done. Its means software can enable RTC again. + * + * \param[in] obj : pointer to RTC register instance + * \return Time New Config Sync Done Enable + * - 0b : Synchronization of New Config is Ongoing, Re-enable RTC is not allowed. + * - 1b : Synchronization of New Config is Done, Re-enable RTC is allowed. + */ +__attribute__((always_inline)) static inline void RtcReg_SetSrCsd(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SR; + + tmp &= ~RTC_SR_CSD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_SR_CSD_SHIFT)) & RTC_SR_CSD_MASK); + obj->SR = tmp; +} + +/*! \brief Gets the Time Alarm Flag + * + * This function gets the current Time Alarm Flag. + * Time alarm flag is set when the TAR[TAR] equals the TSR[TSR] and the TSR[TSR] increments. + * This bit is cleared by writing the TAR register. + * + * \param[in] obj : pointer to RTC register instance + * \return Time Alarm Flag + * - 0b : Time alarm has not occurred. + * - 1b : Time alarm has occurred. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetSrTaf(const RtcRegType *obj) +{ + return ((obj->SR & RTC_SR_TAF_MASK) >> RTC_SR_TAF_SHIFT); +} + +/*! \brief Gets the Time Overflow Flag + * + * This function gets the current Time Overflow Flag. + * Time overflow flag is set when the time counter is enabled and overflows. + * This bit is cleared by writing the TSR register when the time counter is disabled. + * When this bit set, both counters keep incrementing so as TCE is set. + * + * \param[in] obj : pointer to RTC register instance + * \return Time Overflow Flag + * - 0b : Time overflow has not occurred. + * - 1b : Time overflow has occurred and time counter is read as zero + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetSrTof(const RtcRegType *obj) +{ + return ((obj->SR & RTC_SR_TOF_MASK) >> RTC_SR_TOF_SHIFT); +} + +/*! \brief Gets the Time Invalid Flag + * + * This function gets the current Time Invalid Flag. + * The time invalid flag is set on POR or software reset. + * This bit is cleared by writing the TSR register when the time counter is disabled. + * When this bit set, both counters keep incrementing so as TCE is set. + * + * \param[in] obj : pointer to RTC register instance + * \return Time Invalid Flag + * - 0b : Time is valid. + * - 1b : Time is invalid and time counter is read as zero + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetSrTif(const RtcRegType *obj) +{ + return ((obj->SR & RTC_SR_TIF_MASK) >> RTC_SR_TIF_SHIFT); +} + +/*! \brief Gets the Lock Register Lock + * + * This function gets the current Lock Register Lock. + * After being cleared, this bit can be set only by POR or software reset. + * + * \param[in] obj : pointer to RTC register instance + * \return Lock Register Lock + * - 0b : Lock Register is locked and writes are ignored. + * - 1b : Lock Register is not locked and writes complete as normal. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetLrLrl(const RtcRegType *obj) +{ + return ((obj->LR & RTC_LR_LRL_MASK) >> RTC_LR_LRL_SHIFT); +} + +/*! \brief Sets the Lock Register Lock + * + * This function sets the Lock Register Lock. + * After being cleared, this bit can be set only by POR or software reset. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Lock Register Lock + * - 0b : Lock Register is locked and writes are ignored. + * - 1b : Lock Register is not locked and writes complete as normal. + */ +__attribute__((always_inline)) static inline void RtcReg_SetLrLrl(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LR; + + tmp &= ~RTC_LR_LRL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_LR_LRL_SHIFT)) & RTC_LR_LRL_MASK); + obj->LR = tmp; +} + +/*! \brief Gets the status Register Lock + * + * This function gets the current status Register Lock. + * After being cleared, this bit can be set only by POR or software reset. + * + * \param[in] obj : pointer to RTC register instance + * \return status Register Lock + * - 0b : Status Register is locked and writes are ignored. + * - 1b : Status Register is not locked and writes complete as normal + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetLrSrl(const RtcRegType *obj) +{ + return ((obj->LR & RTC_LR_SRL_MASK) >> RTC_LR_SRL_SHIFT); +} + +/*! \brief Sets the status Register Lock + * + * This function sets the status Register Lock. + * After being cleared, this bit can be set only by POR or software reset. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of status Register Lock + * - 0b : Status Register is locked and writes are ignored. + * - 1b : Status Register is not locked and writes complete as normal + */ +__attribute__((always_inline)) static inline void RtcReg_SetLrSrl(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LR; + + tmp &= ~RTC_LR_SRL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_LR_SRL_SHIFT)) & RTC_LR_SRL_MASK); + obj->LR = tmp; +} + +/*! \brief Gets the Control Register Lock + * + * This function gets the current Control Register Lock. + * After being cleared, this bit can only be set by POR. + * + * \param[in] obj : pointer to RTC register instance + * \return Control Register Lock + * - 0b : Control Register is locked and writes are ignored. + * - 1b : Control Register is not locked and writes complete as normal. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetLrCrl(const RtcRegType *obj) +{ + return ((obj->LR & RTC_LR_CRL_MASK) >> RTC_LR_CRL_SHIFT); +} + +/*! \brief Sets the Control Register Lock + * + * This function sets the Control Register Lock. + * After being cleared, this bit can only be set by POR. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Control Register Lock + * - 0b : Control Register is locked and writes are ignored. + * - 1b : Control Register is not locked and writes complete as normal. + */ +__attribute__((always_inline)) static inline void RtcReg_SetLrCrl(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LR; + + tmp &= ~RTC_LR_CRL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_LR_CRL_SHIFT)) & RTC_LR_CRL_MASK); + obj->LR = tmp; +} + +/*! \brief Gets the Timer Seconds Interrupt Configuration + * + * This function gets the current Timer Seconds Interrupt Configuration. + * Configures the frequency of the RTC Seconds interrupt and the RTC_CLKOUT prescaler output. + * This field should only be altered when TSIE is clear. + * + * \param[in] obj : pointer to RTC register instance + * \return Timer Seconds Interrupt Configuration + * - 000b : 1 Hz. + * - 001b : 2 Hz. + * - 010b : 4 Hz. + * - 011b : 8 Hz. + * - 100b : 16 Hz. + * - 101b : 32 Hz. + * - 110b : 64 Hz. + * - 111b : 128 Hz + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetIerTsic(const RtcRegType *obj) +{ + return ((obj->IER & RTC_IER_TSIC_MASK) >> RTC_IER_TSIC_SHIFT); +} + +/*! \brief Sets the Timer Seconds Interrupt Configuration + * + * This function sets the Timer Seconds Interrupt Configuration. + * Configures the frequency of the RTC Seconds interrupt and the RTC_CLKOUT prescaler output. + * This field should only be altered when TSIE is clear. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Timer Seconds Interrupt Configuration + * - 000b : 1 Hz. + * - 001b : 2 Hz. + * - 010b : 4 Hz. + * - 011b : 8 Hz. + * - 100b : 16 Hz. + * - 101b : 32 Hz. + * - 110b : 64 Hz. + * - 111b : 128 Hz + */ +__attribute__((always_inline)) static inline void RtcReg_SetIerTsic(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IER; + + tmp &= ~RTC_IER_TSIC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_IER_TSIC_SHIFT)) & RTC_IER_TSIC_MASK); + obj->IER = tmp; +} + +/*! \brief Gets the Time Seconds Interrupt Enable + * + * This function gets the current Time Seconds Interrupt Enable. + * The seconds interrupt is an edge-sensitive interrupt with a dedicated interrupt vector. + * It is generated at least once a second and requires no software overhead (there is no corresponding status flag to clear). + * The frequency of the seconds interrupt is configured by TSIC. + * + * \param[in] obj : pointer to RTC register instance + * \return Time Seconds Interrupt Enable + * - 0b : Seconds interrupt is disabled. + * - 1b : Seconds interrupt is enabled. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetIerTsie(const RtcRegType *obj) +{ + return ((obj->IER & RTC_IER_TSIE_MASK) >> RTC_IER_TSIE_SHIFT); +} + +/*! \brief Sets the Time Seconds Interrupt Enable + * + * This function sets the Time Seconds Interrupt Enable. + * The seconds interrupt is an edge-sensitive interrupt with a dedicated interrupt vector. + * It is generated at least once a second and requires no software overhead (there is no corresponding status flag to clear). + * The frequency of the seconds interrupt is configured by TSIC. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Time Seconds Interrupt Enable + * - 0b : Seconds interrupt is disabled. + * - 1b : Seconds interrupt is enabled. + */ +__attribute__((always_inline)) static inline void RtcReg_SetIerTsie(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IER; + + tmp &= ~RTC_IER_TSIE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_IER_TSIE_SHIFT)) & RTC_IER_TSIE_MASK); + obj->IER = tmp; +} + +/*! \brief Gets the Time Alarm Interrupt Enable + * + * This function gets the current Time Alarm Interrupt Enable. + * + * \param[in] obj : pointer to RTC register instance + * \return Time Alarm Interrupt Enable + * - 0b : Time alarm flag does not generate an interrupt. + * - 1b : Time alarm flag does generate an interrupt. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetIerTaie(const RtcRegType *obj) +{ + return ((obj->IER & RTC_IER_TAIE_MASK) >> RTC_IER_TAIE_SHIFT); +} + +/*! \brief Sets the Time Alarm Interrupt Enable + * + * This function sets the Time Alarm Interrupt Enable. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Time Alarm Interrupt Enable + * - 0b : Time alarm flag does not generate an interrupt. + * - 1b : Time alarm flag does generate an interrupt. + */ +__attribute__((always_inline)) static inline void RtcReg_SetIerTaie(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IER; + + tmp &= ~RTC_IER_TAIE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_IER_TAIE_SHIFT)) & RTC_IER_TAIE_MASK); + obj->IER = tmp; +} + +/*! \brief Gets the Time Overflow Interrupt Enable + * + * This function gets the current Time Overflow Interrupt Enable. + * + * \param[in] obj : pointer to RTC register instance + * \return Time Overflow Interrupt Enable + * - 0b : Time overflow flag does not generate an interrupt. + * - 1b : Time overflow flag does generate an interrupt. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetIerTioe(const RtcRegType *obj) +{ + return ((obj->IER & RTC_IER_TIOE_MASK) >> RTC_IER_TIOE_SHIFT); +} + +/*! \brief Sets the Time Overflow Interrupt Enable + * + * This function sets the Time Overflow Interrupt Enable. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Time Overflow Interrupt Enable + * - 0b : Time overflow flag does not generate an interrupt. + * - 1b : Time overflow flag does generate an interrupt. + */ +__attribute__((always_inline)) static inline void RtcReg_SetIerTioe(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IER; + + tmp &= ~RTC_IER_TIOE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_IER_TIOE_SHIFT)) & RTC_IER_TIOE_MASK); + obj->IER = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _RTC_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/scg0_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/scg0_reg.h new file mode 100644 index 0000000..26dacc0 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/scg0_reg.h @@ -0,0 +1,638 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _SCG0_REG_H_ +#define _SCG0_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the SCG0 Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* TRIM Bit Fields */ +#define SCG0_TRIM_AUTO_GC_EN_MASK (0x100000u) +#define SCG0_TRIM_AUTO_GC_EN_SHIFT (20u) +#define SCG0_TRIM_AUTO_GC_EN_WIDTH (1u) + +/* OSC_CTRL Bit Fields */ +#define SCG0_OSC_CTRL_EN_EXT_CLK_MASK (0x10u) +#define SCG0_OSC_CTRL_EN_EXT_CLK_SHIFT (4u) +#define SCG0_OSC_CTRL_EN_EXT_CLK_WIDTH (1u) +#define SCG0_OSC_CTRL_RANGE_MASK (0x0Cu) +#define SCG0_OSC_CTRL_RANGE_SHIFT (2u) +#define SCG0_OSC_CTRL_RANGE_WIDTH (2u) +#define SCG0_OSC_CTRL_HGO_MASK (0x02u) +#define SCG0_OSC_CTRL_HGO_SHIFT (1u) +#define SCG0_OSC_CTRL_HGO_WIDTH (1u) +#define SCG0_OSC_CTRL_EN_SOSC_MASK (0x01u) +#define SCG0_OSC_CTRL_EN_SOSC_SHIFT (0u) +#define SCG0_OSC_CTRL_EN_SOSC_WIDTH (1u) + +/* PLL_CTRL0 Bit Fields */ +#define SCG0_PLL_CTRL0_PLL_VCO_DIV_MASK (0x200000u) +#define SCG0_PLL_CTRL0_PLL_VCO_DIV_SHIFT (21u) +#define SCG0_PLL_CTRL0_PLL_VCO_DIV_WIDTH (1u) +#define SCG0_PLL_CTRL0_PLL_POSDIV_MASK (0x3800u) +#define SCG0_PLL_CTRL0_PLL_POSDIV_SHIFT (11u) +#define SCG0_PLL_CTRL0_PLL_POSDIV_WIDTH (3u) +#define SCG0_PLL_CTRL0_PLL_FDKSEL_MASK (0x400u) +#define SCG0_PLL_CTRL0_PLL_FDKSEL_SHIFT (10u) +#define SCG0_PLL_CTRL0_PLL_FDKSEL_WIDTH (1u) +#define SCG0_PLL_CTRL0_PLL_PREDIV_MASK (0x300u) +#define SCG0_PLL_CTRL0_PLL_PREDIV_SHIFT (8u) +#define SCG0_PLL_CTRL0_PLL_PREDIV_WIDTH (2u) +#define SCG0_PLL_CTRL0_PLL_M_MASK (0xFEu) +#define SCG0_PLL_CTRL0_PLL_M_SHIFT (1u) +#define SCG0_PLL_CTRL0_PLL_M_WIDTH (7u) +#define SCG0_PLL_CTRL0_PLL_EN_MASK (0x01u) +#define SCG0_PLL_CTRL0_PLL_EN_SHIFT (0u) +#define SCG0_PLL_CTRL0_PLL_EN_WIDTH (1u) + +/* PLL_CTRL1 Bit Fields */ +#define SCG0_PLL_CTRL1_PLL_CLKIN_SEL_MASK (0x10u) +#define SCG0_PLL_CTRL1_PLL_CLKIN_SEL_SHIFT (4u) +#define SCG0_PLL_CTRL1_PLL_CLKIN_SEL_WIDTH (1u) + +/* STATUS Bit Fields */ +#define SCG0_STATUS_SCG0_LOCK_MASK (0x08u) +#define SCG0_STATUS_SCG0_LOCK_SHIFT (3u) +#define SCG0_STATUS_SCG0_LOCK_WIDTH (1u) +#define SCG0_STATUS_SOSC_RDY_MASK (0x04u) +#define SCG0_STATUS_SOSC_RDY_SHIFT (2u) +#define SCG0_STATUS_SOSC_RDY_WIDTH (1u) +#define SCG0_STATUS_SIRC_8M_RDY_MASK (0x02u) +#define SCG0_STATUS_SIRC_8M_RDY_SHIFT (1u) +#define SCG0_STATUS_SIRC_8M_RDY_WIDTH (1u) +#define SCG0_STATUS_PLL_LOCK_MASK (0x01u) +#define SCG0_STATUS_PLL_LOCK_SHIFT (0u) +#define SCG0_STATUS_PLL_LOCK_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of SCG0 registers + */ +typedef struct _Scg0RegType_ +{ + volatile uint32_t TRIM; /*!< Trimming code register, offset: 0x0 */ + uint32_t RESERVED0[2]; /*!< Reserverd block, offset: 0x4 */ + volatile uint32_t OSC_CTRL; /*!< oscillator control register, offset: 0xC */ + uint32_t RESERVED1[1]; /*!< Reserverd block, offset: 0x10 */ + volatile uint32_t PLL_CTRL0; /*!< phase lock loop control0 register, offset: 0x14 */ + volatile uint32_t PLL_CTRL1; /*!< MISC phase lock loop control1 register, offset: 0x18 */ + uint32_t RESERVED2[1]; /*!< Reserverd block, offset: 0x1C */ + volatile uint32_t STATUS; /*!< status register, offset: 0x20 */ + uint32_t RESERVED3[15]; /*!< Reserverd block, offset: 0x24 */ + volatile uint32_t KEY; /*!< key register, offset: 0x60 */ +} Scg0RegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the EEE auto garbage collection enable + * + * This function gets the current EEE auto garbage collection enable. + * + * \param[in] obj : pointer to SCG0 register instance + * \return EEE auto garbage collection enable + * - 1 : enable auto eee garbage collection; + * - 0 : disable auto eee garbage collection; + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetTrimAutoGcEn(const Scg0RegType *obj) +{ + return ((obj->TRIM & SCG0_TRIM_AUTO_GC_EN_MASK) >> SCG0_TRIM_AUTO_GC_EN_SHIFT); +} + +/*! \brief Sets the EEE auto garbage collection enable + * + * This function sets the EEE auto garbage collection enable. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of EEE auto garbage collection enable + * - 1 : enable auto eee garbage collection; + * - 0 : disable auto eee garbage collection; + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetTrimAutoGcEn(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->TRIM; + + tmp &= ~SCG0_TRIM_AUTO_GC_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_TRIM_AUTO_GC_EN_SHIFT)) & SCG0_TRIM_AUTO_GC_EN_MASK); + obj->TRIM = tmp; +} + +/*! \brief Gets the External clock input through XIN pin enable + * + * This function gets the current External clock input through XIN pin enable. + * Enable external clock input through XIN pin. When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \return External clock input through XIN pin enable + * - 0b : disable. + * - 1b : enable. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetOscCtrlEnExtClk(const Scg0RegType *obj) +{ + return ((obj->OSC_CTRL & SCG0_OSC_CTRL_EN_EXT_CLK_MASK) >> SCG0_OSC_CTRL_EN_EXT_CLK_SHIFT); +} + +/*! \brief Sets the External clock input through XIN pin enable + * + * This function sets the External clock input through XIN pin enable. + * Enable external clock input through XIN pin. When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of External clock input through XIN pin enable + * - 0b : disable. + * - 1b : enable. + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetOscCtrlEnExtClk(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OSC_CTRL; + + tmp &= ~SCG0_OSC_CTRL_EN_EXT_CLK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_OSC_CTRL_EN_EXT_CLK_SHIFT)) & SCG0_OSC_CTRL_EN_EXT_CLK_MASK); + obj->OSC_CTRL = tmp; +} + +/*! \brief Gets the SOSC frequency range + * + * This function gets the current SOSC frequency range. + * SOSC frequency range select, When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \return SOSC frequency range + * - 00b : Low frequency range selected for the crystal oscillator(4M); + * - 01b : Medium frequency range selected for the crytstal oscillator(4M~8M) + * - 10b : Medium frequency range selected for the crytstal oscillator(8M~24M) + * - 11b : High frequency range selected for the crystal oscillator(24M~40M) + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetOscCtrlRange(const Scg0RegType *obj) +{ + return ((obj->OSC_CTRL & SCG0_OSC_CTRL_RANGE_MASK) >> SCG0_OSC_CTRL_RANGE_SHIFT); +} + +/*! \brief Sets the SOSC frequency range + * + * This function sets the SOSC frequency range. + * SOSC frequency range select, When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of SOSC frequency range + * - 00b : Low frequency range selected for the crystal oscillator(4M); + * - 01b : Medium frequency range selected for the crytstal oscillator(4M~8M) + * - 10b : Medium frequency range selected for the crytstal oscillator(8M~24M) + * - 11b : High frequency range selected for the crystal oscillator(24M~40M) + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetOscCtrlRange(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OSC_CTRL; + + tmp &= ~SCG0_OSC_CTRL_RANGE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_OSC_CTRL_RANGE_SHIFT)) & SCG0_OSC_CTRL_RANGE_MASK); + obj->OSC_CTRL = tmp; +} + +/*! \brief Gets the High gain oscillator + * + * This function gets the current High gain oscillator. + * High gain oscillator control, When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \return High gain oscillator + * - 0b : Low power mode for SOSC(OSC output amplitude limited) + * - 1b : High gain mode for SOSC. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetOscCtrlHgo(const Scg0RegType *obj) +{ + return ((obj->OSC_CTRL & SCG0_OSC_CTRL_HGO_MASK) >> SCG0_OSC_CTRL_HGO_SHIFT); +} + +/*! \brief Sets the High gain oscillator + * + * This function sets the High gain oscillator. + * High gain oscillator control, When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of High gain oscillator + * - 0b : Low power mode for SOSC(OSC output amplitude limited) + * - 1b : High gain mode for SOSC. + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetOscCtrlHgo(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OSC_CTRL; + + tmp &= ~SCG0_OSC_CTRL_HGO_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_OSC_CTRL_HGO_SHIFT)) & SCG0_OSC_CTRL_HGO_MASK); + obj->OSC_CTRL = tmp; +} + +/*! \brief Gets the System oscillator (crystal osc) enable + * + * This function gets the current System oscillator (crystal osc) enable. + * System oscillator (crystal osc) enable control, When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \return System oscillator (crystal osc) enable + * - 0b : SOSC disable. + * - 1b : SOSC enable. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetOscCtrlEnSosc(const Scg0RegType *obj) +{ + return ((obj->OSC_CTRL & SCG0_OSC_CTRL_EN_SOSC_MASK) >> SCG0_OSC_CTRL_EN_SOSC_SHIFT); +} + +/*! \brief Sets the System oscillator (crystal osc) enable + * + * This function sets the System oscillator (crystal osc) enable. + * System oscillator (crystal osc) enable control, When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of System oscillator (crystal osc) enable + * - 0b : SOSC disable. + * - 1b : SOSC enable. + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetOscCtrlEnSosc(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OSC_CTRL; + + tmp &= ~SCG0_OSC_CTRL_EN_SOSC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_OSC_CTRL_EN_SOSC_SHIFT)) & SCG0_OSC_CTRL_EN_SOSC_MASK); + obj->OSC_CTRL = tmp; +} + +/*! \brief Gets the PLL ICO DIV2 Setting + * + * This function gets the current PLL ICO DIV2 Setting. + * 1 stand for div2, When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \return PLL ICO DIV2 Setting + * - 0b : not divider. + * - 1b : divider 2. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetPllCtrl0PllVcoDiv(const Scg0RegType *obj) +{ + return ((obj->PLL_CTRL0 & SCG0_PLL_CTRL0_PLL_VCO_DIV_MASK) >> SCG0_PLL_CTRL0_PLL_VCO_DIV_SHIFT); +} + +/*! \brief Sets the PLL ICO DIV2 Setting + * + * This function sets the PLL ICO DIV2 Setting. + * 1 stand for div2, When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of PLL ICO DIV2 Setting + * - 0b : not divider. + * - 1b : divider 2. + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetPllCtrl0PllVcoDiv(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_CTRL0; + + tmp &= ~SCG0_PLL_CTRL0_PLL_VCO_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_PLL_CTRL0_PLL_VCO_DIV_SHIFT)) & SCG0_PLL_CTRL0_PLL_VCO_DIV_MASK); + obj->PLL_CTRL0 = tmp; +} + +/*! \brief Gets the PLL post-divide + * + * This function gets the current PLL post-divide. + * When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \return PLL post-divide + * - 000b : 8 + * - 001b : 1 + * - 010b : 2 + * - 011b : 3 + * . + * . + * . + * - 111b : 7 + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetPllCtrl0PllPosDiv(const Scg0RegType *obj) +{ + return ((obj->PLL_CTRL0 & SCG0_PLL_CTRL0_PLL_POSDIV_MASK) >> SCG0_PLL_CTRL0_PLL_POSDIV_SHIFT); +} + +/*! \brief Sets the PLL post-divide + * + * This function sets the PLL post-divide. + * When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of PLL post-divide + * - 000b : 8 + * - 001b : 1 + * - 010b : 2 + * - 011b : 3 + * . + * . + * . + * - 111b : 7 + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetPllCtrl0PllPosDiv(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_CTRL0; + + tmp &= ~SCG0_PLL_CTRL0_PLL_POSDIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_PLL_CTRL0_PLL_POSDIV_SHIFT)) & SCG0_PLL_CTRL0_PLL_POSDIV_MASK); + obj->PLL_CTRL0 = tmp; +} + +/*! \brief Gets the PLL Feedback clock divider pre-scaler + * + * This function gets the current PLL Feedback clock divider pre-scaler. + * When write-lock disabled, this register can be written. + * + * \param[in] obj : pointer to SCG0 register instance + * \return PLL Feedback clock divider pre-scaler + * - 0b : 1. + * - 1b : 2. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetPllCtrl0PllFdkSel(const Scg0RegType *obj) +{ + return ((obj->PLL_CTRL0 & SCG0_PLL_CTRL0_PLL_FDKSEL_MASK) >> SCG0_PLL_CTRL0_PLL_FDKSEL_SHIFT); +} + +/*! \brief Sets the PLL Feedback clock divider pre-scaler + * + * This function sets the PLL Feedback clock divider pre-scaler. + * When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of PLL Feedback clock divider pre-scaler + * - 0b : 1. + * - 1b : 2. + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetPllCtrl0PllFdkSel(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_CTRL0; + + tmp &= ~SCG0_PLL_CTRL0_PLL_FDKSEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_PLL_CTRL0_PLL_FDKSEL_SHIFT)) & SCG0_PLL_CTRL0_PLL_FDKSEL_MASK); + obj->PLL_CTRL0 = tmp; +} + +/*! \brief Gets the PLL pre-divider setting + * + * This function gets the current PLL pre-divider setting. + * When write-lock disabled, this register can be written. + * + * \param[in] obj : pointer to SCG0 register instance + * \return PLL pre-divider setting + * - 00b : 1. + * - 01b : 2. + * - 10b : 4. + * - 11b : 8. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetPllCtrl0PllPreDiv(const Scg0RegType *obj) +{ + return ((obj->PLL_CTRL0 & SCG0_PLL_CTRL0_PLL_PREDIV_MASK) >> SCG0_PLL_CTRL0_PLL_PREDIV_SHIFT); +} + +/*! \brief Sets the PLL pre-divider setting + * + * This function sets the PLL pre-divider setting. + * When write-lock disabled, this register can be written. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of PLL pre-divider setting + * - 00b : 1. + * - 01b : 2. + * - 10b : 4. + * - 11b : 8. + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetPllCtrl0PllPreDiv(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_CTRL0; + + tmp &= ~SCG0_PLL_CTRL0_PLL_PREDIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_PLL_CTRL0_PLL_PREDIV_SHIFT)) & SCG0_PLL_CTRL0_PLL_PREDIV_MASK); + obj->PLL_CTRL0 = tmp; +} + +/*! \brief Gets the PLL feedback divider setting + * + * This function gets the current PLL feedback divider setting. + * When write-lock disabled, this register can be written. + * + * \param[in] obj : pointer to SCG0 register instance + * \return PLL feedback divider setting + * - 0000001b : 1. + * - 0000010b : 2. + * . + * . + * . + * - 1111111b : 127. + * - 0000000b : 128. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetPllCtrl0PllM(const Scg0RegType *obj) +{ + return ((obj->PLL_CTRL0 & SCG0_PLL_CTRL0_PLL_M_MASK) >> SCG0_PLL_CTRL0_PLL_M_SHIFT); +} + +/*! \brief Sets the PLL feedback divider setting + * + * This function sets the PLL feedback divider setting. + * When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of PLL feedback divider setting + * - 0000001b : 1. + * - 0000010b : 2. + * . + * . + * . + * - 1111111b : 127. + * - 0000000b : 128. + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetPllCtrl0PllM(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_CTRL0; + + tmp &= ~SCG0_PLL_CTRL0_PLL_M_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_PLL_CTRL0_PLL_M_SHIFT)) & SCG0_PLL_CTRL0_PLL_M_MASK); + obj->PLL_CTRL0 = tmp; +} + +/*! \brief Gets the PLL enable + * + * This function gets the current PLL enable. + * When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \return PLL enable + * - 0 : disable. + * - 1 : enable. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetPllCtrl0PllEn(const Scg0RegType *obj) +{ + return ((obj->PLL_CTRL0 & SCG0_PLL_CTRL0_PLL_EN_MASK) >> SCG0_PLL_CTRL0_PLL_EN_SHIFT); +} + +/*! \brief Sets the PLL enable + * + * This function sets the PLL enable. + * When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of PLL enable + * - 0 : disable. + * - 1 : enable. + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetPllCtrl0PllEn(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_CTRL0; + + tmp &= ~SCG0_PLL_CTRL0_PLL_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_PLL_CTRL0_PLL_EN_SHIFT)) & SCG0_PLL_CTRL0_PLL_EN_MASK); + obj->PLL_CTRL0 = tmp; +} + +/*! \brief Gets the PLL input clock source select + * + * This function gets the current PLL input clock source select. + * When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \return PLL input clock source select + * - 0 : SIRC. + * - 1 : SOSC. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetPllCtrl1PllClkinSel(const Scg0RegType *obj) +{ + return ((obj->PLL_CTRL1 & SCG0_PLL_CTRL1_PLL_CLKIN_SEL_MASK) >> SCG0_PLL_CTRL1_PLL_CLKIN_SEL_SHIFT); +} + +/*! \brief Sets the PLL input clock source select + * + * This function sets the PLL input clock source select. + * When write-lock disabled, this register can be written. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of PLL input clock source select + * - 0 : SIRC. + * - 1 : SOSC. + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetPllCtrl1PllClkinSel(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_CTRL1; + + tmp &= ~SCG0_PLL_CTRL1_PLL_CLKIN_SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_PLL_CTRL1_PLL_CLKIN_SEL_SHIFT)) & SCG0_PLL_CTRL1_PLL_CLKIN_SEL_MASK); + obj->PLL_CTRL1 = tmp; +} + +/*! \brief Gets the scg0 lock enable status + * + * This function gets the current scg0 lock enable status. + * + * \param[in] obj : pointer to SCG0 register instance + * \return scg0 lock enable status + * - 0b : disalbe. + * - 1b : enable. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetStatusKeyLock(const Scg0RegType *obj) +{ + return ((obj->STATUS & SCG0_STATUS_SCG0_LOCK_MASK) >> SCG0_STATUS_SCG0_LOCK_SHIFT); +} + +/*! \brief Gets the Sytem oscillator clock ready flag + * + * This function gets the current Sytem oscillator clock ready flag. + * if use external, this flag is not used + * + * \param[in] obj : pointer to SCG0 register instance + * \return Sytem oscillator clock ready flag + * - 1b : SOSC ready. + * - 0b : SOSC not ready. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetStatusSoscRdy(const Scg0RegType *obj) +{ + return ((obj->STATUS & SCG0_STATUS_SOSC_RDY_MASK) >> SCG0_STATUS_SOSC_RDY_SHIFT); +} + +/*! \brief Gets the SIRC clock ready flag + * + * This function gets the current SIRC clock ready flag. + * + * \param[in] obj : pointer to SCG0 register instance + * \return SIRC clock ready flag + * - 1b : ready; + * - 0b : not ready + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetStatusSircRdy(const Scg0RegType *obj) +{ + return ((obj->STATUS & SCG0_STATUS_SIRC_8M_RDY_MASK) >> SCG0_STATUS_SIRC_8M_RDY_SHIFT); +} + +/*! \brief Gets the PLL lock state + * + * This function gets the current PLL lock state. + * + * \param[in] obj : pointer to SCG0 register instance + * \return PLL lock state + * - 1b : Lock state; + * - 0b : Not lock state + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetStatusPllLock(const Scg0RegType *obj) +{ + return ((obj->STATUS & SCG0_STATUS_PLL_LOCK_MASK) >> SCG0_STATUS_PLL_LOCK_SHIFT); +} + +/*! \brief Sets the SCG0 public write key register + * + * This function sets the SCG0 public write key register. + * SCG0 public write hit key, the initial confirm key is 0x1996_2020, + * when cpu write data is 0x19962020. SCG0 function lock is invalid, + * CPU can write the SCG0 function register. + * When cpu write data is not equal 0x1996_2020, SCG0 function lock is valid, + * CPU can not write the SCG0 function register + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of SCG0 public write key register + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetKey(Scg0RegType *obj, uint32_t value) +{ + obj->KEY = value; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _SCG0_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/scg1_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/scg1_reg.h new file mode 100644 index 0000000..7cc3e78 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/scg1_reg.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _SCG1_REG_H_ +#define _SCG1_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the SCG1 Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* CKSRC Bit Fields */ +#define SCG1_CKSRC_SYS_DIV_MASK (0x0Fu) +#define SCG1_CKSRC_SYS_DIV_SHIFT (0u) +#define SCG1_CKSRC_SYS_DIV_WIDTH (4u) + +/* CPU_MODE Bit Fields */ +#define SCG1_CPU_MODE_RET_MASK (0x01u) +#define SCG1_CPU_MODE_RET_SHIFT (0u) +#define SCG1_CPU_MODE_RET_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of SCG1 registers + */ +typedef struct _Scg1RegType_ +{ + volatile uint32_t CKSRC; /*!< clock source selection register, offset: 0x0 */ + volatile uint32_t CPU_MODE; /*!< CPU mode register, offset: 0x4 */ +} Scg1RegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the system clock divide control + * + * This function gets the current system clock divide control. + * rstn_apor domain + * + * \param[in] obj : pointer to SCG1 register instance + * \return system clock divide control + * - 0h : divide by 1 + * - 1h : divide by 2 + * - 2h : divide by 3 + * - 3h : divide by 4 + * . + * . + * . + * - Fh : divide by 16 + */ +__attribute__((always_inline)) static inline uint8_t Scg1Reg_GetCkSrcSysDiv(const Scg1RegType *obj) +{ + return ((obj->CKSRC & SCG1_CKSRC_SYS_DIV_MASK) >> SCG1_CKSRC_SYS_DIV_SHIFT); +} + +/*! \brief Sets the system clock divide control + * + * This function sets the system clock divide control. + * rstn_apor domain + * + * \param[in] obj : pointer to SCG1 register instance + * \param[in] value : the value of system clock divide control + * - 0h : divide by 1 + * - 1h : divide by 2 + * - 2h : divide by 3 + * - 3h : divide by 4 + * . + * . + * . + * - Fh : divide by 16 + */ +__attribute__((always_inline)) static inline void Scg1Reg_SetCkSrcSysDiv(Scg1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CKSRC; + + tmp &= ~SCG1_CKSRC_SYS_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG1_CKSRC_SYS_DIV_SHIFT)) & SCG1_CKSRC_SYS_DIV_MASK); + obj->CKSRC = tmp; +} + +/*! \brief Gets the cpu core work clock selection + * + * This function gets the current cpu core work clock selection. + * rstn_apor domain + * + * \param[in] obj : pointer to SCG1 register instance + * \return cpu core work clock selection + * - 0b : cpu core clock always on, delay cpu reset release; + * - 1b : cpu core clock gate enable, cpu reset early; + */ +__attribute__((always_inline)) static inline uint8_t Scg1Reg_GetCpuModeRet(const Scg1RegType *obj) +{ + return ((obj->CPU_MODE & SCG1_CPU_MODE_RET_MASK) >> SCG1_CPU_MODE_RET_SHIFT); +} + +/*! \brief Sets the cpu core work clock selection + * + * This function sets the cpu core work clock selection. + * rstn_apor domain + * + * \param[in] obj : pointer to SCG1 register instance + * \param[in] value : the value of cpu core work clock selection + * - 0b : cpu core clock always on, delay cpu reset release; + * - 1b : cpu core clock gate enable, cpu reset early; + */ +__attribute__((always_inline)) static inline void Scg1Reg_SetCpuModeRet(Scg1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CPU_MODE; + + tmp &= ~SCG1_CPU_MODE_RET_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG1_CPU_MODE_RET_SHIFT)) & SCG1_CPU_MODE_RET_MASK); + obj->CPU_MODE = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _SCG1_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/scg2_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/scg2_reg.h new file mode 100644 index 0000000..121077c --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/scg2_reg.h @@ -0,0 +1,880 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _SCG2_REG_H_ +#define _SCG2_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the SCG2 Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* CSR Bit Fields */ +#define SCG2_CSR_SYS_ST_MASK (0x3000000u) +#define SCG2_CSR_SYS_ST_SHIFT (24u) +#define SCG2_CSR_SYS_ST_WIDTH (2u) +#define SCG2_CSR_SRC_SYS_MASK (0x30000u) +#define SCG2_CSR_SRC_SYS_SHIFT (16u) +#define SCG2_CSR_SRC_SYS_WIDTH (2u) +#define SCG2_CSR_DIV_AIPS_MASK (0xF00u) +#define SCG2_CSR_DIV_AIPS_SHIFT (8u) +#define SCG2_CSR_DIV_AIPS_WIDTH (4u) + +/* CLKOUT Bit Fields */ +#define SCG2_CLKOUT_SRC0_MASK (0x380000u) +#define SCG2_CLKOUT_SRC0_SHIFT (19u) +#define SCG2_CLKOUT_SRC0_WIDTH (3u) +#define SCG2_CLKOUT_SRC1_MASK (0x70000u) +#define SCG2_CLKOUT_SRC1_SHIFT (16u) +#define SCG2_CLKOUT_SRC1_WIDTH (3u) +#define SCG2_CLKOUT_DIV_MASK (0x700u) +#define SCG2_CLKOUT_DIV_SHIFT (8u) +#define SCG2_CLKOUT_DIV_WIDTH (3u) +#define SCG2_CLKOUT_EN_MASK (0x10u) +#define SCG2_CLKOUT_EN_SHIFT (4u) +#define SCG2_CLKOUT_EN_WIDTH (1u) + +/* SIRC_MFT Bit Fields */ +#define SCG2_SIRC_MFT_DIV_MASK (0x700u) +#define SCG2_SIRC_MFT_DIV_SHIFT (8u) +#define SCG2_SIRC_MFT_DIV_WIDTH (3u) +#define SCG2_SIRC_MFT_EN_MASK (0x10u) +#define SCG2_SIRC_MFT_EN_SHIFT (4u) +#define SCG2_SIRC_MFT_EN_WIDTH (1u) + +/* SIRC_CFG Bit Fields */ +#define SCG2_SIRC_CFG_DIV_MASK (0x700u) +#define SCG2_SIRC_CFG_DIV_SHIFT (8u) +#define SCG2_SIRC_CFG_DIV_WIDTH (3u) +#define SCG2_SIRC_CFG_EN_MASK (0x10u) +#define SCG2_SIRC_CFG_EN_SHIFT (4u) +#define SCG2_SIRC_CFG_EN_WIDTH (1u) + +/* SOSC_MFT Bit Fields */ +#define SCG2_SOSC_MFT_DIV_MASK (0x700u) +#define SCG2_SOSC_MFT_DIV_SHIFT (8u) +#define SCG2_SOSC_MFT_DIV_WIDTH (3u) +#define SCG2_SOSC_MFT_EN_MASK (0x10u) +#define SCG2_SOSC_MFT_EN_SHIFT (4u) +#define SCG2_SOSC_MFT_EN_WIDTH (1u) + +/* SOSC_CFG Bit Fields */ +#define SCG2_SOSC_CFG_DIV_MASK (0x700u) +#define SCG2_SOSC_CFG_DIV_SHIFT (8u) +#define SCG2_SOSC_CFG_DIV_WIDTH (3u) +#define SCG2_SOSC_CFG_EN_MASK (0x10u) +#define SCG2_SOSC_CFG_EN_SHIFT (4u) +#define SCG2_SOSC_CFG_EN_WIDTH (1u) + +/* PLL_MFT Bit Fields */ +#define SCG2_PLL_MFT_DIV_MASK (0x700u) +#define SCG2_PLL_MFT_DIV_SHIFT (8u) +#define SCG2_PLL_MFT_DIV_WIDTH (3u) +#define SCG2_PLL_MFT_EN_MASK (0x10u) +#define SCG2_PLL_MFT_EN_SHIFT (4u) +#define SCG2_PLL_MFT_EN_WIDTH (1u) + +/* PLL_CFG Bit Fields */ +#define SCG2_PLL_CFG_DIV_MASK (0x700u) +#define SCG2_PLL_CFG_DIV_SHIFT (8u) +#define SCG2_PLL_CFG_DIV_WIDTH (3u) +#define SCG2_PLL_CFG_EN_MASK (0x10u) +#define SCG2_PLL_CFG_EN_SHIFT (4u) +#define SCG2_PLL_CFG_EN_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of SCG2 registers + */ +typedef struct _Scg2RegType_ +{ + volatile uint32_t CSR; /*!< SYSTEM clock config register, offset: 0x0 */ + volatile uint32_t CLKOUT; /*!< system clock out control register, offset: 0x4 */ + uint32_t RESERVED0[2]; /*!< Reserved register, offset: 0x8 */ + volatile uint32_t SIRC_MFT; /*!< SIRC_MFT clock div configuration register, offset: 0x10 */ + volatile uint32_t SIRC_CFG; /*!< SIRC_DIV clock div configuration register, offset: 0x14 */ + volatile uint32_t SOSC_MFT; /*!< SOSC_MFT clock div configuration register, offset: 0x18 */ + volatile uint32_t SOSC_CFG; /*!< SOSC_DIV clock div configuration register, offset: 0x1C */ + volatile uint32_t PLL_MFT; /*!< PLL_MFT clock div configuration register, offset: 0x20 */ + volatile uint32_t PLL_CFG; /*!< PLL clock div configuration register, offset: 0x24 */ +} Scg2RegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the system clock(clk_sys) source status + * + * This function gets the current system clock(clk_sys) source status. + * + * \param[in] obj : pointer to SCG2 register instance + * \return system clock(clk_sys) source status + * - 0h : clk_sirc + * - 1h : clk_sosc + * - 2h : clk_pll + * - 3h : clk_sirc + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetCsrSysSt(const Scg2RegType *obj) +{ + return ((obj->CSR & SCG2_CSR_SYS_ST_MASK) >> SCG2_CSR_SYS_ST_SHIFT); +} + +/*! \brief Gets the System Clock(clk_sys) source select + * + * This function gets the current System Clock(clk_sys) source select. + * + * \param[in] obj : pointer to SCG2 register instance + * \return System Clock(clk_sys) source select + * - 0h : clk_sirc + * - 1h : clk_sosc + * - 2h : clk_pll + * - 3h : clk_sirc + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetCsrSrcSys(const Scg2RegType *obj) +{ + return ((obj->CSR & SCG2_CSR_SRC_SYS_MASK) >> SCG2_CSR_SRC_SYS_SHIFT); +} + +/*! \brief Sets the System Clock(clk_sys) source select + * + * This function sets the System Clock(clk_sys) source select. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of System Clock(clk_sys) source select + * - 0h : clk_sirc + * - 1h : clk_sosc + * - 2h : clk_pll + * - 3h : clk_sirc + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetCsrSrcSys(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CSR; + + tmp &= ~SCG2_CSR_SRC_SYS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_CSR_SRC_SYS_SHIFT)) & SCG2_CSR_SRC_SYS_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the clk_apb(APB bus Clock):Divide Ratio + * + * This function gets the current clk_apb(APB bus Clock):Divide Ratio. + * The source clock is clk_core. + * + * \param[in] obj : pointer to SCG2 register instance + * \return clk_apb(APB bus Clock):Divide Ratio + * - 0000 : Divide-by-1 + * - 0001 : Divide-by-2 + * - 0010 : Divide-by-3 + * - 0011 : Divide-by-4 + * - 0100 : Divide-by-5 + * - 0101 : Divide-by-6 + * - 0110 : Divide-by-7 + * - 0111 : Divide-by-8 + * - 1000 : Divide-by-9 + * - 1001 : Divide-by-10 + * - 1010 : Divide-by-11 + * - 1011 : Divide-by-12 + * - 1100 : Divide-by-13 + * - 1101 : Divide-by-14 + * - 1110 : Divide-by-15 + * - 1111 : Divide-by-16 + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetCsrDivAips(const Scg2RegType *obj) +{ + return ((obj->CSR & SCG2_CSR_DIV_AIPS_MASK) >> SCG2_CSR_DIV_AIPS_SHIFT); +} + +/*! \brief Sets the clk_apb(APB bus Clock):Divide Ratio + * + * This function sets the clk_apb(APB bus Clock):Divide Ratio. + * The source clock is clk_core. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of clk_apb(APB bus Clock):Divide Ratio + * - 0000 : Divide-by-1 + * - 0001 : Divide-by-2 + * - 0010 : Divide-by-3 + * - 0011 : Divide-by-4 + * - 0100 : Divide-by-5 + * - 0101 : Divide-by-6 + * - 0110 : Divide-by-7 + * - 0111 : Divide-by-8 + * - 1000 : Divide-by-9 + * - 1001 : Divide-by-10 + * - 1010 : Divide-by-11 + * - 1011 : Divide-by-12 + * - 1100 : Divide-by-13 + * - 1101 : Divide-by-14 + * - 1110 : Divide-by-15 + * - 1111 : Divide-by-16 + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetCsrDivAips(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CSR; + + tmp &= ~SCG2_CSR_DIV_AIPS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_CSR_DIV_AIPS_SHIFT)) & SCG2_CSR_DIV_AIPS_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the scg clock out + * + * This function gets the current scg clock out. + * + * \param[in] obj : pointer to SCG2 register instance + * \return scg clock out + * - 0b : clk_cnt_fls + * - 1b : clk_sosc + * - 2h : clk_sirc + * - 3h : clk_pll + * - 4h : clk_core + * - 5h : clk_apb + * - 6h : clk_sosc_div + * - 7h : clk_sirc_div + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetClkOutSrc0(const Scg2RegType *obj) +{ + return ((obj->CLKOUT & SCG2_CLKOUT_SRC0_MASK) >> SCG2_CLKOUT_SRC0_SHIFT); +} + +/*! \brief Sets the scg clock out + * + * This function sets the scg clock out. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of scg clock out + * - 0b : clk_cnt_fls + * - 1b : clk_sosc + * - 2h : clk_sirc + * - 3h : clk_pll + * - 4h : clk_core + * - 5h : clk_apb + * - 6h : clk_sosc_div + * - 7h : clk_sirc_div + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetClkOutSrc0(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CLKOUT; + + tmp &= ~SCG2_CLKOUT_SRC0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_CLKOUT_SRC0_SHIFT)) & SCG2_CLKOUT_SRC0_MASK); + obj->CLKOUT = tmp; +} + +/*! \brief Gets the clock out(to PAD) source + * + * This function gets the current clock out(to PAD) source. + * + * \param[in] obj : pointer to SCG2 register instance + * \return clock out(to PAD) source + * - 0b : scg_out + * - 1h : clk_pll_div + * - 2h : clk_lpo128 + * - 3h : clk_lpo32 + * - 4h : clk_lpo1 + * - 5h : clk_rtc_cnt + * - 6h : clk_sirc + * - 7h : clk_sirc + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetClkOutSrc1(const Scg2RegType *obj) +{ + return ((obj->CLKOUT & SCG2_CLKOUT_SRC1_MASK) >> SCG2_CLKOUT_SRC1_SHIFT); +} + +/*! \brief Sets the clock out(to PAD) source + * + * This function sets the clock out(to PAD) source. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of clock out(to PAD) source + * - 0b : scg_out + * - 1h : clk_pll_div2 + * - 2h : clk_lpo128 + * - 3h : clk_lpo32 + * - 4h : clk_lpo1 + * - 5h : clk_rtc_cnt + * - 6h : clk_sirc + * - 7h : clk_sirc + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetClkOutSrc1(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CLKOUT; + + tmp &= ~SCG2_CLKOUT_SRC1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_CLKOUT_SRC1_SHIFT)) & SCG2_CLKOUT_SRC1_MASK); + obj->CLKOUT = tmp; +} + +/*! \brief Gets the clock out divide ratio + * + * This function gets the current clock out divide ratio. + * + * \note The max frequency is 24M, so this bit should be configured properly. + * + * \param[in] obj : pointer to SCG2 register instance + * \return clock out divide ratio + * - 0b : 1 + * - 1b : 2 + * - 2h : 3 + * - 3h : 4 + * - 4h : 5 + * - 5h : 6 + * - 6h : 7 + * - 7h : 8 + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetClkOutDiv(const Scg2RegType *obj) +{ + return ((obj->CLKOUT & SCG2_CLKOUT_DIV_MASK) >> SCG2_CLKOUT_DIV_SHIFT); +} + +/*! \brief Sets the clock out divide ratio + * + * This function sets the clock out divide ratio. + * + * \note The max frequency is 24M, so this bit should be configured properly. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of clock out divide ratio + * - 0b : 1 + * - 1b : 2 + * - 2h : 3 + * - 3h : 4 + * - 4h : 5 + * - 5h : 6 + * - 6h : 7 + * - 7h : 8 + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetClkOutDiv(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CLKOUT; + + tmp &= ~SCG2_CLKOUT_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_CLKOUT_DIV_SHIFT)) & SCG2_CLKOUT_DIV_MASK); + obj->CLKOUT = tmp; +} + +/*! \brief Gets the clock out enable + * + * This function gets the current clock out enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \return clock out enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetClkOutEn(const Scg2RegType *obj) +{ + return ((obj->CLKOUT & SCG2_CLKOUT_EN_MASK) >> SCG2_CLKOUT_EN_SHIFT); +} + +/*! \brief Sets the clock out enable + * + * This function sets the clock out enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of clock out enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetClkOutEn(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CLKOUT; + + tmp &= ~SCG2_CLKOUT_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_CLKOUT_EN_SHIFT)) & SCG2_CLKOUT_EN_MASK); + obj->CLKOUT = tmp; +} + +/*! \brief Gets the SIRC_DIV_MFT clock diviation + * + * This function gets the current SIRC_DIV_MFT clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \return SIRC_DIV_MFT clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : / + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetSircMftDiv(const Scg2RegType *obj) +{ + return ((obj->SIRC_MFT & SCG2_SIRC_MFT_DIV_MASK) >> SCG2_SIRC_MFT_DIV_SHIFT); +} + +/*! \brief Sets the SIRC_DIV_MFT clock diviation + * + * This function sets the SIRC_DIV_MFT clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of SIRC_DIV_MFT clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : / + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetSircMftDiv(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SIRC_MFT; + + tmp &= ~SCG2_SIRC_MFT_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_SIRC_MFT_DIV_SHIFT)) & SCG2_SIRC_MFT_DIV_MASK); + obj->SIRC_MFT = tmp; +} + +/*! \brief Gets the clk_sirc_div_mft clock enable + * + * This function gets the current clk_sirc_div_mft clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \return clk_sirc_div_mft clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetSircMftEn(const Scg2RegType *obj) +{ + return ((obj->SIRC_MFT & SCG2_SIRC_MFT_EN_MASK) >> SCG2_SIRC_MFT_EN_SHIFT); +} + +/*! \brief Sets the clk_sirc_div_mft clock enable + * + * This function sets the clk_sirc_div_mft clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of clk_sirc_div_mft clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetSircMftEn(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SIRC_MFT; + + tmp &= ~SCG2_SIRC_MFT_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_SIRC_MFT_EN_SHIFT)) & SCG2_SIRC_MFT_EN_MASK); + obj->SIRC_MFT = tmp; +} + +/*! \brief Gets the SIRC_DIV clock diviation + * + * This function gets the current SIRC_DIV clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \return SIRC_DIV clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : / + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetSircCfgDiv(const Scg2RegType *obj) +{ + return ((obj->SIRC_CFG & SCG2_SIRC_CFG_DIV_MASK) >> SCG2_SIRC_CFG_DIV_SHIFT); +} + +/*! \brief Sets the SIRC_DIV clock diviation + * + * This function sets the SIRC_DIV clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of SIRC_DIV clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : / + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetSircCfgDiv(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SIRC_CFG; + + tmp &= ~SCG2_SIRC_CFG_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_SIRC_CFG_DIV_SHIFT)) & SCG2_SIRC_CFG_DIV_MASK); + obj->SIRC_CFG = tmp; +} + +/*! \brief Gets the clk_sirc_div clock enable + * + * This function gets the current clk_sirc_div clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \return clk_sirc_div clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetSircCfgEn(const Scg2RegType *obj) +{ + return ((obj->SIRC_CFG & SCG2_SIRC_CFG_EN_MASK) >> SCG2_SIRC_CFG_EN_SHIFT); +} + +/*! \brief Sets the clk_sirc_div clock enable + * + * This function sets the clk_sirc_div clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of clk_sirc_div clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetSircCfgEn(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SIRC_CFG; + + tmp &= ~SCG2_SIRC_CFG_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_SIRC_CFG_EN_SHIFT)) & SCG2_SIRC_CFG_EN_MASK); + obj->SIRC_CFG = tmp; +} + +/*! \brief Gets the SOSC_DIV_MFT clock diviation + * + * This function gets the current SOSC_DIV_MFT clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \return SOSC_DIV_MFT clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : / + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetSoscMftDiv(const Scg2RegType *obj) +{ + return ((obj->SOSC_MFT & SCG2_SOSC_MFT_DIV_MASK) >> SCG2_SOSC_MFT_DIV_SHIFT); +} + +/*! \brief Sets the SOSC_DIV_MFT clock diviation + * + * This function sets the SOSC_DIV_MFT clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of SOSC_DIV_MFT clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : / + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetSoscMftDiv(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SOSC_MFT; + + tmp &= ~SCG2_SOSC_MFT_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_SOSC_MFT_DIV_SHIFT)) & SCG2_SOSC_MFT_DIV_MASK); + obj->SOSC_MFT = tmp; +} + +/*! \brief Gets the clk_sosc_div_mft clock enable + * + * This function gets the current clk_sosc_div_mft clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \return clk_sosc_div_mft clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetSoscMftEn(const Scg2RegType *obj) +{ + return ((obj->SOSC_MFT & SCG2_SOSC_MFT_EN_MASK) >> SCG2_SOSC_MFT_EN_SHIFT); +} + +/*! \brief Sets the clk_sosc_div_mft clock enable + * + * This function sets the clk_sosc_div_mft clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of clk_sosc_div_mft clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetSoscMftEn(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SOSC_MFT; + + tmp &= ~SCG2_SOSC_MFT_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_SOSC_MFT_EN_SHIFT)) & SCG2_SOSC_MFT_EN_MASK); + obj->SOSC_MFT = tmp; +} + +/*! \brief Gets the SOSC_DIV clock diviation + * + * This function gets the current SOSC_DIV clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \return SOSC_DIV clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : / + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetSoscCfgDiv(const Scg2RegType *obj) +{ + return ((obj->SOSC_CFG & SCG2_SOSC_CFG_DIV_MASK) >> SCG2_SOSC_CFG_DIV_SHIFT); +} + +/*! \brief Sets the SOSC_DIV clock diviation + * + * This function sets the SOSC_DIV clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of SOSC_DIV clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : / + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetSoscCfgDiv(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SOSC_CFG; + + tmp &= ~SCG2_SOSC_CFG_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_SOSC_CFG_DIV_SHIFT)) & SCG2_SOSC_CFG_DIV_MASK); + obj->SOSC_CFG = tmp; +} + +/*! \brief Gets the clk_sosc_div clock enable + * + * This function gets the current clk_sosc_div clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \return clk_sosc_div clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetSoscCfgEn(const Scg2RegType *obj) +{ + return ((obj->SOSC_CFG & SCG2_SOSC_CFG_EN_MASK) >> SCG2_SOSC_CFG_EN_SHIFT); +} + +/*! \brief Sets the clk_sosc_div clock enable + * + * This function sets the clk_sosc_div clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of clk_sosc_div clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetSoscCfgEn(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SOSC_CFG; + + tmp &= ~SCG2_SOSC_CFG_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_SOSC_CFG_EN_SHIFT)) & SCG2_SOSC_CFG_EN_MASK); + obj->SOSC_CFG = tmp; +} + +/*! \brief Gets the PLL_DIV_MFT clock diviation + * + * This function gets the current PLL_DIV_MFT clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \return PLL_DIV_MFT clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : /(128) + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetPllMftDiv(const Scg2RegType *obj) +{ + return ((obj->PLL_MFT & SCG2_PLL_MFT_DIV_MASK) >> SCG2_PLL_MFT_DIV_SHIFT); +} + +/*! \brief Sets the PLL_DIV_MFT clock diviation + * + * This function sets the PLL_DIV_MFT clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of PLL_DIV_MFT clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : /(128) + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetPllMftDiv(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_MFT; + + tmp &= ~SCG2_PLL_MFT_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_PLL_MFT_DIV_SHIFT)) & SCG2_PLL_MFT_DIV_MASK); + obj->PLL_MFT = tmp; +} + +/*! \brief Gets the clk_pll_div_mft clock enable + * + * This function gets the current clk_pll_div_mft clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \return clk_pll_div_mft clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetPllMftEn(const Scg2RegType *obj) +{ + return ((obj->PLL_MFT & SCG2_PLL_MFT_EN_MASK) >> SCG2_PLL_MFT_EN_SHIFT); +} + +/*! \brief Sets the clk_pll_div_mft clock enable + * + * This function sets the clk_pll_div_mft clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of clk_pll_div_mft clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetPllMftEn(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_MFT; + + tmp &= ~SCG2_PLL_MFT_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_PLL_MFT_EN_SHIFT)) & SCG2_PLL_MFT_EN_MASK); + obj->PLL_MFT = tmp; +} + +/*! \brief Gets the PLL_DIV clock diviation + * + * This function gets the current PLL_DIV clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \return PLL_DIV clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : /(128) + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetPllCfgDiv(const Scg2RegType *obj) +{ + return ((obj->PLL_CFG & SCG2_PLL_CFG_DIV_MASK) >> SCG2_PLL_CFG_DIV_SHIFT); +} + +/*! \brief Sets the PLL_DIV clock diviation + * + * This function sets the PLL_DIV clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of PLL_DIV clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : /(128) + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetPllCfgDiv(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_CFG; + + tmp &= ~SCG2_PLL_CFG_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_PLL_CFG_DIV_SHIFT)) & SCG2_PLL_CFG_DIV_MASK); + obj->PLL_CFG = tmp; +} + +/*! \brief Gets the clk_pll_div clock enable + * + * This function gets the current clk_pll_div clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \return clk_pll_div clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetPllCfgEn(const Scg2RegType *obj) +{ + return ((obj->PLL_CFG & SCG2_PLL_CFG_EN_MASK) >> SCG2_PLL_CFG_EN_SHIFT); +} + +/*! \brief Sets the clk_pll_div clock enable + * + * This function sets the clk_pll_div clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of clk_pll_div clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetPllCfgEn(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_CFG; + + tmp &= ~SCG2_PLL_CFG_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_PLL_CFG_EN_SHIFT)) & SCG2_PLL_CFG_EN_MASK); + obj->PLL_CFG = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _SCG2_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/sim_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/sim_reg.h new file mode 100644 index 0000000..1e099ee --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/sim_reg.h @@ -0,0 +1,1410 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _SIM_REG_H_ +#define _SIM_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the SIM (System Integration Module) Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* CHIP Bit Fields */ +#define SIM_CHIP_SRAM_INIT_ST_MASK (0x20u) +#define SIM_CHIP_SRAM_INIT_ST_SHIFT (5u) +#define SIM_CHIP_SRAM_INIT_ST_WIDTH (1u) +#define SIM_CHIP_SRAM_INIT_MASK (0x08u) +#define SIM_CHIP_SRAM_INIT_SHIFT (3u) +#define SIM_CHIP_SRAM_INIT_WIDTH (1u) +#define SIM_CHIP_SRAM_RETEN_MASK (0x02u) +#define SIM_CHIP_SRAM_RETEN_SHIFT (1u) +#define SIM_CHIP_SRAM_RETEN_WIDTH (1u) + +/* PWM_CTRL0 Bit Fields */ +#define SIM_PWM_CTRL0_PWM_FUNC3_MASK (0xF000000u) +#define SIM_PWM_CTRL0_PWM_FUNC3_SHIFT (24u) +#define SIM_PWM_CTRL0_PWM_FUNC3_WIDTH (4u) +#define SIM_PWM_CTRL0_PWM_FUNC2_MASK (0xF0000u) +#define SIM_PWM_CTRL0_PWM_FUNC2_SHIFT (16u) +#define SIM_PWM_CTRL0_PWM_FUNC2_WIDTH (4u) +#define SIM_PWM_CTRL0_PWM_FUNC1_MASK (0xF00u) +#define SIM_PWM_CTRL0_PWM_FUNC1_SHIFT (8u) +#define SIM_PWM_CTRL0_PWM_FUNC1_WIDTH (4u) +#define SIM_PWM_CTRL0_PWM_FUNC0_MASK (0x0Fu) +#define SIM_PWM_CTRL0_PWM_FUNC0_SHIFT (0u) +#define SIM_PWM_CTRL0_PWM_FUNC0_WIDTH (4u) + +/* PWM_CTRL1 Bit Fields */ +#define SIM_PWM_CTRL1_PWM_FUNC5_MASK (0xF00u) +#define SIM_PWM_CTRL1_PWM_FUNC5_SHIFT (8u) +#define SIM_PWM_CTRL1_PWM_FUNC5_WIDTH (4u) +#define SIM_PWM_CTRL1_PWM_FUNC4_MASK (0x0Fu) +#define SIM_PWM_CTRL1_PWM_FUNC4_SHIFT (0u) +#define SIM_PWM_CTRL1_PWM_FUNC4_WIDTH (4u) + +/* ADC Bit Fields */ +#define SIM_ADC_TRG_SRC_MASK (0x20u) +#define SIM_ADC_TRG_SRC_SHIFT (5u) +#define SIM_ADC_TRG_SRC_WIDTH (1u) +#define SIM_ADC_PRETRG_SW_SRC_MASK (0x1Cu) +#define SIM_ADC_PRETRG_SW_SRC_SHIFT (2u) +#define SIM_ADC_PRETRG_SW_SRC_WIDTH (3u) +#define SIM_ADC_PRETRG_SRC_MASK (0x03u) +#define SIM_ADC_PRETRG_SRC_SHIFT (0u) +#define SIM_ADC_PRETRG_SRC_WIDTH (2u) + +/* I2S Bit Fields */ +#define SIM_I2S_SLV_DMA_IRQ_MASK (0x04u) +#define SIM_I2S_SLV_DMA_IRQ_SHIFT (2u) +#define SIM_I2S_SLV_DMA_IRQ_WIDTH (1u) +#define SIM_I2S_MST_DMA_IRQ_MASK (0x02u) +#define SIM_I2S_MST_DMA_IRQ_SHIFT (1u) +#define SIM_I2S_MST_DMA_IRQ_WIDTH (1u) +#define SIM_I2S_MODE_MASK (0x01u) +#define SIM_I2S_MODE_SHIFT (0u) +#define SIM_I2S_MODE_WIDTH (1u) + +/* MFT_CTRL0 Bit Fields */ +#define SIM_MFT_CTRL0_MFT1_FLT_SEL_MASK (0x700000u) +#define SIM_MFT_CTRL0_MFT1_FLT_SEL_SHIFT (20u) +#define SIM_MFT_CTRL0_MFT1_FLT_SEL_WIDTH (3u) +#define SIM_MFT_CTRL0_MFT0_FLT_SEL_MASK (0x70000u) +#define SIM_MFT_CTRL0_MFT0_FLT_SEL_SHIFT (16u) +#define SIM_MFT_CTRL0_MFT0_FLT_SEL_WIDTH (3u) +#define SIM_MFT_CTRL0_GLDOK_MASK (0x01u) +#define SIM_MFT_CTRL0_GLDOK_SHIFT (0u) +#define SIM_MFT_CTRL0_GLDOK_WIDTH (1u) + +/* MFT_CTRL1 Bit Fields */ +#define SIM_MFT_CTRL1_MFT1SYNCBIT_MASK (0x2000000u) +#define SIM_MFT_CTRL1_MFT1SYNCBIT_SHIFT (25u) +#define SIM_MFT_CTRL1_MFT1SYNCBIT_WIDTH (1u) +#define SIM_MFT_CTRL1_MFT0SYNCBIT_MASK (0x1000000u) +#define SIM_MFT_CTRL1_MFT0SYNCBIT_SHIFT (24u) +#define SIM_MFT_CTRL1_MFT0SYNCBIT_WIDTH (1u) +#define SIM_MFT_CTRL1_MFT1CH0SEL_MASK (0x80000u) +#define SIM_MFT_CTRL1_MFT1CH0SEL_SHIFT (19u) +#define SIM_MFT_CTRL1_MFT1CH0SEL_WIDTH (1u) +#define SIM_MFT_CTRL1_MFT0_OUTSEL_MASK (0xFF00u) +#define SIM_MFT_CTRL1_MFT0_OUTSEL_SHIFT (8u) +#define SIM_MFT_CTRL1_MFT0_OUTSEL_WIDTH (8u) + +/* FLASH Bit Fields */ +#define SIM_FLASH_EEERST_MASK (0x800u) +#define SIM_FLASH_EEERST_SHIFT (11u) +#define SIM_FLASH_EEERST_WIDTH (1u) +#define SIM_FLASH_EEEVLD_MASK (0x400u) +#define SIM_FLASH_EEEVLD_SHIFT (10u) +#define SIM_FLASH_EEEVLD_WIDTH (1u) +#define SIM_FLASH_LOAD_DONE_MASK (0x200u) +#define SIM_FLASH_LOAD_DONE_SHIFT (9u) +#define SIM_FLASH_LOAD_DONE_WIDTH (1u) +#define SIM_FLASH_VIRGIN_FLAG_MASK (0x100u) +#define SIM_FLASH_VIRGIN_FLAG_SHIFT (8u) +#define SIM_FLASH_VIRGIN_FLAG_WIDTH (1u) +#define SIM_FLASH_DFLS_FLUSH_EN_MASK (0x08u) +#define SIM_FLASH_DFLS_FLUSH_EN_SHIFT (3u) +#define SIM_FLASH_DFLS_FLUSH_EN_WIDTH (1u) +#define SIM_FLASH_PFLS_FLUSH_EN_MASK (0x04u) +#define SIM_FLASH_PFLS_FLUSH_EN_SHIFT (2u) +#define SIM_FLASH_PFLS_FLUSH_EN_WIDTH (1u) +#define SIM_FLASH_DFLS_PFB_EN_MASK (0x02u) +#define SIM_FLASH_DFLS_PFB_EN_SHIFT (1u) +#define SIM_FLASH_DFLS_PFB_EN_WIDTH (1u) +#define SIM_FLASH_PFLS_PFB_EN_MASK (0x01u) +#define SIM_FLASH_PFLS_PFB_EN_SHIFT (0u) +#define SIM_FLASH_PFLS_PFB_EN_WIDTH (1u) + +/* UDIDH Bit Fields */ +#define SIM_UDIDH_H_MASK (0xFFFFFFFFu) +#define SIM_UDIDH_H_SHIFT (0u) +#define SIM_UDIDH_H_WIDTH (32u) + +/* UDIDMH Bit Fields */ +#define SIM_UDIDMH_MH_MASK (0xFFFFFFFFu) +#define SIM_UDIDMH_MH_SHIFT (0u) +#define SIM_UDIDMH_MH_WIDTH (32u) + +/* UDIDML Bit Fields */ +#define SIM_UDIDML_ML_MASK (0xFFFFFFFFu) +#define SIM_UDIDML_ML_SHIFT (0u) +#define SIM_UDIDML_ML_WIDTH (32u) + +/* UDIDL Bit Fields */ +#define SIM_UDIDL_L_MASK (0xFFFFFFFFu) +#define SIM_UDIDL_L_SHIFT (0u) +#define SIM_UDIDL_L_WIDTH (32u) + +/* SDID Bit Fields */ +#define SIM_SDID_ID_MASK (0xFFFFFFFFu) +#define SIM_SDID_ID_SHIFT (0u) +#define SIM_SDID_ID_WIDTH (32u) + +/* SW_TRG Bit Fields */ +#define SIM_SW_TRG_SW_TRG_MASK (0x01u) +#define SIM_SW_TRG_SW_TRG_SHIFT (0u) +#define SIM_SW_TRG_SW_TRG_WIDTH (1u) + +/* CAN Bit Fields */ +#define SIM_CAN_WAK_INT_MASK (0x40000u) +#define SIM_CAN_WAK_INT_SHIFT (18u) +#define SIM_CAN_WAK_INT_WIDTH (1u) +#define SIM_CAN_SLF_WAK_MASK (0x20000u) +#define SIM_CAN_SLF_WAK_SHIFT (17u) +#define SIM_CAN_SLF_WAK_WIDTH (1u) +#define SIM_CAN_LPM_ACK_MASK (0x10000u) +#define SIM_CAN_LPM_ACK_SHIFT (16u) +#define SIM_CAN_LPM_ACK_WIDTH (1u) +#define SIM_CAN_IPG_STOP_MASK (0x08u) +#define SIM_CAN_IPG_STOP_SHIFT (3u) +#define SIM_CAN_IPG_STOP_WIDTH (1u) +#define SIM_CAN_SOFT_RESET_MASK (0x04u) +#define SIM_CAN_SOFT_RESET_SHIFT (2u) +#define SIM_CAN_SOFT_RESET_WIDTH (1u) +#define SIM_CAN_IPG_DOZE_MASK (0x02u) +#define SIM_CAN_IPG_DOZE_SHIFT (1u) +#define SIM_CAN_IPG_DOZE_WIDTH (1u) +#define SIM_CAN_WKUP_SRC_SEL_MASK (0x01u) +#define SIM_CAN_WKUP_SRC_SEL_SHIFT (0u) +#define SIM_CAN_WKUP_SRC_SEL_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of SIM registers + */ +typedef struct _SimRegType_ +{ + uint32_t RESERVED0[1]; /*!< Reserverd block, offset: 0x00 */ + volatile uint32_t CHIP; /*!< system chip register, offset: 0x04 */ + uint32_t RESERVED1[2]; /*!< Reserverd block, offset: 0x08 */ + volatile uint32_t PWM_CTRL0; /*!< system PWM register 0, offset: 0x10 */ + volatile uint32_t PWM_CTRL1; /*!< system PWM register 1, offset: 0x14 */ + volatile uint32_t ADC; /*!< system ADC register, offset: 0x18 */ + uint32_t RESERVED2[1]; /*!< Reserverd block, offset: 0x1C */ + volatile uint32_t I2S; /*!< system I2S register, offset: 0x20 */ + volatile uint32_t MFT_CTRL0; /*!< system MFT register 0, offset: 0x24 */ + volatile uint32_t MFT_CTRL1; /*!< system MFT register 1, offset: 0x28 */ + volatile uint32_t FLASH; /*!< system flash controller register, offset: 0x2C */ + const volatile uint32_t UDIDH; /*!< system UD ID high register, offset: 0x30 */ + const volatile uint32_t UDIDMH; /*!< system UD ID medium high register, offset: 0x34 */ + const volatile uint32_t UDIDML; /*!< system UD ID medium low register, offset: 0x38 */ + const volatile uint32_t UDIDL; /*!< system UD ID low register, offset: 0x3C */ + const volatile uint32_t SDID; /*!< system SDID high register, offset: 0x40 */ + volatile uint32_t SW_TRG; /*!< system software trigger register, offset: 0x44 */ + volatile uint32_t CAN; /*!< system CAN configure register, offset: 0x48 */ +} SimRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the SRAM initialization status + * + * This function gets the current SRAM initialization status. + * + * \param[in] obj : pointer to SIM register instance + * \return SRAM initialization status + * - 0b : SRAM initialization is in progress + * - 1b : SRAM initialization is done or not started + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetChipSRamInitSt(const SimRegType *obj) +{ + return ((obj->CHIP & SIM_CHIP_SRAM_INIT_ST_MASK) >> SIM_CHIP_SRAM_INIT_ST_SHIFT); +} + +/*! \brief Sets the SRAM initial command + * + * This function sets the SRAM initial command. + * SRAM initialization start trigger. Invalid when SRAM_RETEN is 0 + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of SRAM initial command + * - 0b : not start SRAM initialization + * - 1b : start SRAM initialization + */ +__attribute__((always_inline)) static inline void SimReg_SetChipSRamInit(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CHIP; + + tmp &= ~SIM_CHIP_SRAM_INIT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_CHIP_SRAM_INIT_SHIFT)) & SIM_CHIP_SRAM_INIT_MASK); + obj->CHIP = tmp; +} + +/*! \brief Gets the SRAM retention + * + * This function gets the current SRAM retention. + * It is reseted by power up and standby exit only. + * + * \note If this bit is set to 0 and system reset happens, program heap operation might malfunction. + * Use this bit with caution. + * + * \param[in] obj : pointer to SIM register instance + * \return SRAM retention + * - 0b : memory contents are retained across resets. + * - 1b : No memory contents retention. + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetChipSRamReten(const SimRegType *obj) +{ + return ((obj->CHIP & SIM_CHIP_SRAM_RETEN_MASK) >> SIM_CHIP_SRAM_RETEN_SHIFT); +} + +/*! \brief Sets the SRAM retention + * + * This function sets the SRAM retention. + * It is reseted by power up and standby exit only. + * + * \note If this bit is set to 0 and system reset happens, program heap operation might malfunction. + * Use this bit with caution. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of SRAM retention + * - 0b : memory contents are retained across resets. + * - 1b : No memory contents retention. + */ +__attribute__((always_inline)) static inline void SimReg_SetChipSRamReten(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CHIP; + + tmp &= ~SIM_CHIP_SRAM_RETEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_CHIP_SRAM_RETEN_SHIFT)) & SIM_CHIP_SRAM_RETEN_MASK); + obj->CHIP = tmp; +} + +/*! \brief Gets the PWM3 output channel select + * + * This function gets the current PWM3 output channel select. + * channel details are same with SIM_PWM_CTRL0[PWM_FUNC0] + * + * \param[in] obj : pointer to SIM register instance + * \return PWM3 output channel select + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetPwmCtrl0PwmFunc3(const SimRegType *obj) +{ + return ((obj->PWM_CTRL0 & SIM_PWM_CTRL0_PWM_FUNC3_MASK) >> SIM_PWM_CTRL0_PWM_FUNC3_SHIFT); +} + +/*! \brief Sets the PWM3 output channel select + * + * This function sets the PWM3 output channel select. + * channel details are same with SIM_PWM_CTRL0[PWM_FUNC0] + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of PWM3 output channel select + */ +__attribute__((always_inline)) static inline void SimReg_SetPwmCtrl0PwmFunc3(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWM_CTRL0; + + tmp &= ~SIM_PWM_CTRL0_PWM_FUNC3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_PWM_CTRL0_PWM_FUNC3_SHIFT)) & SIM_PWM_CTRL0_PWM_FUNC3_MASK); + obj->PWM_CTRL0 = tmp; +} + +/*! \brief Gets the PWM2 output channel select + * + * This function gets the current PWM2 output channel select. + * channel details are same with SIM_PWM_CTRL0[PWM_FUNC0 + * + * \param[in] obj : pointer to SIM register instance + * \return PWM2 output channel select + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetPwmCtrl0PwmFunc2(const SimRegType *obj) +{ + return ((obj->PWM_CTRL0 & SIM_PWM_CTRL0_PWM_FUNC2_MASK) >> SIM_PWM_CTRL0_PWM_FUNC2_SHIFT); +} + +/*! \brief Sets the PWM2 output channel select + * + * This function sets the PWM2 output channel select. + * channel details are same with SIM_PWM_CTRL0[PWM_FUNC0] + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of PWM2 output channel select + */ +__attribute__((always_inline)) static inline void SimReg_SetPwmCtrl0PwmFunc2(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWM_CTRL0; + + tmp &= ~SIM_PWM_CTRL0_PWM_FUNC2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_PWM_CTRL0_PWM_FUNC2_SHIFT)) & SIM_PWM_CTRL0_PWM_FUNC2_MASK); + obj->PWM_CTRL0 = tmp; +} + +/*! \brief Gets the PWM1 output channel select + * + * This function gets the current PWM1 output channel select. + * channel details are same with SIM_PWM_CTRL0[PWM_FUNC0] + * + * \param[in] obj : pointer to SIM register instance + * \return PWM1 output channel select + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetPwmCtrl0PwmFunc1(const SimRegType *obj) +{ + return ((obj->PWM_CTRL0 & SIM_PWM_CTRL0_PWM_FUNC1_MASK) >> SIM_PWM_CTRL0_PWM_FUNC1_SHIFT); +} + +/*! \brief Sets the PWM1 output channel select + * + * This function sets the PWM1 output channel select. + * channel details are same with SIM_PWM_CTRL0[PWM_FUNC0] + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of PWM1 output channel select + */ +__attribute__((always_inline)) static inline void SimReg_SetPwmCtrl0PwmFunc1(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWM_CTRL0; + + tmp &= ~SIM_PWM_CTRL0_PWM_FUNC1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_PWM_CTRL0_PWM_FUNC1_SHIFT)) & SIM_PWM_CTRL0_PWM_FUNC1_MASK); + obj->PWM_CTRL0 = tmp; +} + +/*! \brief Gets the PWM0 output channel select + * + * This function gets the current PWM0 output channel select. + * + * \param[in] obj : pointer to SIM register instance + * \return PWM0 output channel select + * - 0d : PWM0[0] + * - 1d : PWM0[1] + * - 2d : PWM0[2] + * - 3d : PWM0[3] + * - 4d : PWM0[4] + * - 5d : PWM0[5] + * - 6d : PWM1[0] + * - 7d : PWM1[1] + * - 8d : PWM1[2] + * - 9d : PWM1[3] + * - 10d : PWM1[4] + * - 11d : PWM1[5] + * - others : reserved + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetPwmCtrl0PwmFunc0(const SimRegType *obj) +{ + return ((obj->PWM_CTRL0 & SIM_PWM_CTRL0_PWM_FUNC0_MASK) >> SIM_PWM_CTRL0_PWM_FUNC0_SHIFT); +} + +/*! \brief Sets the PWM0 output channel select + * + * This function sets the PWM0 output channel select. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of PWM0 output channel select + * - 0d : PWM0[0] + * - 1d : PWM0[1] + * - 2d : PWM0[2] + * - 3d : PWM0[3] + * - 4d : PWM0[4] + * - 5d : PWM0[5] + * - 6d : PWM1[0] + * - 7d : PWM1[1] + * - 8d : PWM1[2] + * - 9d : PWM1[3] + * - 10d : PWM1[4] + * - 11d : PWM1[5] + * - others : reserved + */ +__attribute__((always_inline)) static inline void SimReg_SetPwmCtrl0PwmFunc0(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWM_CTRL0; + + tmp &= ~SIM_PWM_CTRL0_PWM_FUNC0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_PWM_CTRL0_PWM_FUNC0_SHIFT)) & SIM_PWM_CTRL0_PWM_FUNC0_MASK); + obj->PWM_CTRL0 = tmp; +} + +/*! \brief Gets the PWM5 output channel select + * + * This function gets the current PWM5 output channel select. + * channel details are same with SIM_PWM_CTRL0[PWM_FUNC0] + * + * \param[in] obj : pointer to SIM register instance + * \return PWM5 output channel select + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetPwmCtrl1PwmFunc5(const SimRegType *obj) +{ + return ((obj->PWM_CTRL1 & SIM_PWM_CTRL1_PWM_FUNC5_MASK) >> SIM_PWM_CTRL1_PWM_FUNC5_SHIFT); +} + +/*! \brief Sets the PWM5 output channel select + * + * This function sets the PWM5 output channel select. + * channel details are same with SIM_PWM_CTRL0[PWM_FUNC0] + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of PWM5 output channel select + */ +__attribute__((always_inline)) static inline void SimReg_SetPwmCtrl1PwmFunc5(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWM_CTRL1; + + tmp &= ~SIM_PWM_CTRL1_PWM_FUNC5_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_PWM_CTRL1_PWM_FUNC5_SHIFT)) & SIM_PWM_CTRL1_PWM_FUNC5_MASK); + obj->PWM_CTRL1 = tmp; +} + +/*! \brief Gets the PWM4 output channel select + * + * This function gets the current PWM4 output channel select. + * channel details are same with SIM_PWM_CTRL0[PWM_FUNC0] + * + * \param[in] obj : pointer to SIM register instance + * \return PWM4 output channel select + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetPwmCtrl1PwmFunc4(const SimRegType *obj) +{ + return ((obj->PWM_CTRL1 & SIM_PWM_CTRL1_PWM_FUNC4_MASK) >> SIM_PWM_CTRL1_PWM_FUNC4_SHIFT); +} + +/*! \brief Sets the PWM4 output channel select + * + * This function sets the PWM4 output channel select. + * channel details are same with SIM_PWM_CTRL0[PWM_FUNC0] + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of PWM4 output channel select + */ +__attribute__((always_inline)) static inline void SimReg_SetPwmCtrl1PwmFunc4(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWM_CTRL1; + + tmp &= ~SIM_PWM_CTRL1_PWM_FUNC4_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_PWM_CTRL1_PWM_FUNC4_SHIFT)) & SIM_PWM_CTRL1_PWM_FUNC4_MASK); + obj->PWM_CTRL1 = tmp; +} + +/*! \brief Gets the ADC trigger source + * + * This function gets the current ADC trigger source. + * + * \param[in] obj : pointer to SIM register instance + * \return ADC trigger source + * - 0b : PDB trigger out + * - 1b : TRGMUX output + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetAdcTrgSrc(const SimRegType *obj) +{ + return ((obj->ADC & SIM_ADC_TRG_SRC_MASK) >> SIM_ADC_TRG_SRC_SHIFT); +} + +/*! \brief Sets the ADC trigger source + * + * This function sets the ADC trigger source. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of ADC trigger source + * - 0b : PDB trigger out + * - 1b : TRGMUX output + */ +__attribute__((always_inline)) static inline void SimReg_SetAdcTrgSrc(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~SIM_ADC_TRG_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_ADC_TRG_SRC_SHIFT)) & SIM_ADC_TRG_SRC_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the ADC software pre trigger source + * + * This function gets the current ADC software pre trigger source. + * + * \param[in] obj : pointer to SIM register instance + * \return ADC software pre trigger source + * - 100b : pretrigger 0 + * - 101b : pretrigger 1 + * - 110b : pretrigger 2 + * - 111b : pretrigger 3 + * - others : reserved + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetAdcPreTrgSwSrc(const SimRegType *obj) +{ + return ((obj->ADC & SIM_ADC_PRETRG_SW_SRC_MASK) >> SIM_ADC_PRETRG_SW_SRC_SHIFT); +} + +/*! \brief Sets the ADC software pre trigger source + * + * This function sets the ADC software pre trigger source. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of ADC software pre trigger source + * - 100b : pretrigger 0 + * - 101b : pretrigger 1 + * - 110b : pretrigger 2 + * - 111b : pretrigger 3 + * - others : reserved + */ +__attribute__((always_inline)) static inline void SimReg_SetAdcPreTrgSwSrc(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~SIM_ADC_PRETRG_SW_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_ADC_PRETRG_SW_SRC_SHIFT)) & SIM_ADC_PRETRG_SW_SRC_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the ADC pre trigger source + * + * This function gets the current ADC pre trigger source. + * + * \param[in] obj : pointer to SIM register instance + * \return ADC pre trigger source + * - 00b : PDB trigger out + * - 01b : TRGMUX output + * - 10b : software configure PRETRG1_SW_SRC + * - 11b : no hardware trigger + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetAdcPreTrgSrc(const SimRegType *obj) +{ + return ((obj->ADC & SIM_ADC_PRETRG_SRC_MASK) >> SIM_ADC_PRETRG_SRC_SHIFT); +} + +/*! \brief Sets the ADC pre trigger source + * + * This function sets the ADC pre trigger source. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of ADC pre trigger source + * - 00b : PDB trigger out + * - 01b : TRGMUX output + * - 10b : software configure PRETRG1_SW_SRC + * - 11b : no hardware trigger + */ +__attribute__((always_inline)) static inline void SimReg_SetAdcPreTrgSrc(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~SIM_ADC_PRETRG_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_ADC_PRETRG_SRC_SHIFT)) & SIM_ADC_PRETRG_SRC_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the I2S Slave dma or interrupt mode + * + * This function gets the current I2S Slave dma or interrupt mode. + * + * \param[in] obj : pointer to SIM register instance + * \return I2S Slave dma or interrupt mode + * - 0b : interrupt + * - 1b : dma + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetI2sSlvDmaIrq(const SimRegType *obj) +{ + return ((obj->I2S & SIM_I2S_SLV_DMA_IRQ_MASK) >> SIM_I2S_SLV_DMA_IRQ_SHIFT); +} + +/*! \brief Sets the I2S Slave dma or interrupt mode + * + * This function sets the I2S Slave dma or interrupt mode. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of I2S Slave dma or interrupt mode + * - 0b : interrupt + * - 1b : dma + */ +__attribute__((always_inline)) static inline void SimReg_SetI2sSlvDmaIrq(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2S; + + tmp &= ~SIM_I2S_SLV_DMA_IRQ_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_I2S_SLV_DMA_IRQ_SHIFT)) & SIM_I2S_SLV_DMA_IRQ_MASK); + obj->I2S = tmp; +} + +/*! \brief Gets the I2S Master dma or interrupt mode + * + * This function gets the current I2S Master dma or interrupt mode. + * + * \param[in] obj : pointer to SIM register instance + * \return I2S Master dma or interrupt mode + * - 0b : interrupt + * - 1b : dma + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetI2sMstDmaIrq(const SimRegType *obj) +{ + return ((obj->I2S & SIM_I2S_MST_DMA_IRQ_MASK) >> SIM_I2S_MST_DMA_IRQ_SHIFT); +} + +/*! \brief Sets the I2S Master dma or interrupt mode + * + * This function sets the I2S Master dma or interrupt mode. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of I2S Master dma or interrupt mode + * - 0b : interrupt + * - 1b : dma + */ +__attribute__((always_inline)) static inline void SimReg_SetI2sMstDmaIrq(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2S; + + tmp &= ~SIM_I2S_MST_DMA_IRQ_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_I2S_MST_DMA_IRQ_SHIFT)) & SIM_I2S_MST_DMA_IRQ_MASK); + obj->I2S = tmp; +} + +/*! \brief Gets the I2S mode + * + * This function gets the current I2S mode. + * + * \param[in] obj : pointer to SIM register instance + * \return I2S mode + * - 0b : slave + * - 1b : master + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetI2sMode(const SimRegType *obj) +{ + return ((obj->I2S & SIM_I2S_MODE_MASK) >> SIM_I2S_MODE_SHIFT); +} + +/*! \brief Sets the I2S mode + * + * This function sets the I2S mode. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of I2S mode + * - 0b : slave + * - 1b : master + */ +__attribute__((always_inline)) static inline void SimReg_SetI2sMode(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2S; + + tmp &= ~SIM_I2S_MODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_I2S_MODE_SHIFT)) & SIM_I2S_MODE_MASK); + obj->I2S = tmp; +} + +/*! \brief Gets the MFT1 Fault X Select + * + * This function gets the current MFT1 Fault X Select. + * Selects the source of the MFT1 fault. + * Every bit means one fault input, respectively. + * If there is no pin assigned to the specific FAULT signal, logic zero is used as input source. + * + * \param[in] obj : pointer to SIM register instance + * \return MFT1 Fault X Select + * - 0b : MFT1_FLTx pin + * - 1b : TRGMUX_MFT1 out + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetMftCtrl0Mft1FltSel(const SimRegType *obj) +{ + return ((obj->MFT_CTRL0 & SIM_MFT_CTRL0_MFT1_FLT_SEL_MASK) >> SIM_MFT_CTRL0_MFT1_FLT_SEL_SHIFT); +} + +/*! \brief Sets the MFT1 Fault X Select + * + * This function sets the MFT1 Fault X Select. + * Selects the source of the MFT1 fault. + * Every bit means one fault input, respectively. + * If there is no pin assigned to the specific FAULT signal, logic zero is used as input source. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of MFT1 Fault X Select + * - 0b : MFT1_FLTx pin + * - 1b : TRGMUX_MFT1 out + */ +__attribute__((always_inline)) static inline void SimReg_SetMftCtrl0Mft1FltSel(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT_CTRL0; + + tmp &= ~SIM_MFT_CTRL0_MFT1_FLT_SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_MFT_CTRL0_MFT1_FLT_SEL_SHIFT)) & SIM_MFT_CTRL0_MFT1_FLT_SEL_MASK); + obj->MFT_CTRL0 = tmp; +} + +/*! \brief Gets the MFT0 Fault X Select + * + * This function gets the current MFT0 Fault X Select. + * Selects the source of the MFT0 fault. + * Every bit means one fault input, respectively. + * If there is no pin assigned to the specific FAULT signal, logic zero is used as input source. + * + * \param[in] obj : pointer to SIM register instance + * \return MFT0 Fault X Select + * - 0b : MFT0_FLTx pin + * - 1b : TRGMUX_MFT0 out + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetMftCtrl0Mft0FltSel(const SimRegType *obj) +{ + return ((obj->MFT_CTRL0 & SIM_MFT_CTRL0_MFT0_FLT_SEL_MASK) >> SIM_MFT_CTRL0_MFT0_FLT_SEL_SHIFT); +} + +/*! \brief Sets the MFT0 Fault X Select + * + * This function sets the MFT0 Fault X Select. + * Selects the source of the MFT0 fault. + * Every bit means one fault input, respectively. + * If there is no pin assigned to the specific FAULT signal, logic zero is used as input source. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of MFT0 Fault X Select + * - 0b : MFT0_FLTx pin + * - 1b : TRGMUX_MFT0 out + */ +__attribute__((always_inline)) static inline void SimReg_SetMftCtrl0Mft0FltSel(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT_CTRL0; + + tmp &= ~SIM_MFT_CTRL0_MFT0_FLT_SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_MFT_CTRL0_MFT0_FLT_SEL_SHIFT)) & SIM_MFT_CTRL0_MFT0_FLT_SEL_MASK); + obj->MFT_CTRL0 = tmp; +} + +/*! \brief Gets the MFT global load enable + * + * This function gets the current MFT global load enable. + * This bit is not self-clearing. + * For subsequent reload operations, it should be cleared and then set. + * + * \param[in] obj : pointer to SIM register instance + * \return MFT global load enable + * - 0b : MFT Global load mechanism disabled. + * - 1b : MFT Global load mechanism enabled + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetMftCtrl0GldOk(const SimRegType *obj) +{ + return ((obj->MFT_CTRL0 & SIM_MFT_CTRL0_GLDOK_MASK) >> SIM_MFT_CTRL0_GLDOK_SHIFT); +} + +/*! \brief Sets the MFT global load enable + * + * This function sets the MFT global load enable. + * This bit is not self-clearing. + * For subsequent reload operations, it should be cleared and then set. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of MFT global load enable + * - 0b : MFT Global load mechanism disabled. + * - 1b : MFT Global load mechanism enabled + */ +__attribute__((always_inline)) static inline void SimReg_SetMftCtrl0GldOk(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT_CTRL0; + + tmp &= ~SIM_MFT_CTRL0_GLDOK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_MFT_CTRL0_GLDOK_SHIFT)) & SIM_MFT_CTRL0_GLDOK_MASK); + obj->MFT_CTRL0 = tmp; +} + +/*! \brief Gets the MFT1 Sync Bit + * + * This function gets the current MFT1 Sync Bit. + * This is used as a synchronization trigger source for MFT + * + * \param[in] obj : pointer to SIM register instance + * \return MFT1 Sync Bit + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetMftCtrl1Mft1SyncBit(const SimRegType *obj) +{ + return ((obj->MFT_CTRL1 & SIM_MFT_CTRL1_MFT1SYNCBIT_MASK) >> SIM_MFT_CTRL1_MFT1SYNCBIT_SHIFT); +} + +/*! \brief Sets the MFT1 Sync Bit + * + * This function sets the MFT1 Sync Bit. + * This is used as a synchronization trigger source for MFT + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of MFT1 Sync Bit + */ +__attribute__((always_inline)) static inline void SimReg_SetMftCtrl1Mft1SyncBit(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT_CTRL1; + + tmp &= ~SIM_MFT_CTRL1_MFT1SYNCBIT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_MFT_CTRL1_MFT1SYNCBIT_SHIFT)) & SIM_MFT_CTRL1_MFT1SYNCBIT_MASK); + obj->MFT_CTRL1 = tmp; +} + +/*! \brief Gets the MFT0 Sync Bit + * + * This function gets the current MFT0 Sync Bit. + * This is used as a synchronization trigger source for MFT + * + * \param[in] obj : pointer to SIM register instance + * \return MFT0 Sync Bit + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetMftCtrl1Mft0SyncBit(const SimRegType *obj) +{ + return ((obj->MFT_CTRL1 & SIM_MFT_CTRL1_MFT0SYNCBIT_MASK) >> SIM_MFT_CTRL1_MFT0SYNCBIT_SHIFT); +} + +/*! \brief Sets the MFT0 Sync Bit + * + * This function sets the MFT0 Sync Bit. + * This is used as a synchronization trigger source for MFT + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of MFT0 Sync Bit + */ +__attribute__((always_inline)) static inline void SimReg_SetMftCtrl1Mft0SyncBit(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT_CTRL1; + + tmp &= ~SIM_MFT_CTRL1_MFT0SYNCBIT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_MFT_CTRL1_MFT0SYNCBIT_SHIFT)) & SIM_MFT_CTRL1_MFT0SYNCBIT_MASK); + obj->MFT_CTRL1 = tmp; +} + +/*! \brief Gets the MFT1 CH0 Select + * + * This function gets the current MFT1 CH0 Select. + * Selects MFT1 Channel0's input + * + * \param[in] obj : pointer to SIM register instance + * \return MFT1 CH0 Select + * - 0b : MFT1_CH0 input from PAD + * - 1b : CMP0 output + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetMftCtrl1Mft1Ch0Sel(const SimRegType *obj) +{ + return ((obj->MFT_CTRL1 & SIM_MFT_CTRL1_MFT1CH0SEL_MASK) >> SIM_MFT_CTRL1_MFT1CH0SEL_SHIFT); +} + +/*! \brief Sets the MFT1 CH0 Select + * + * This function sets the MFT1 CH0 Select. + * Selects MFT1 Channel0's input + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of MFT1 CH0 Select + * - 0b : MFT1_CH0 input from PAD + * - 1b : CMP0 output + */ +__attribute__((always_inline)) static inline void SimReg_SetMftCtrl1Mft1Ch0Sel(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT_CTRL1; + + tmp &= ~SIM_MFT_CTRL1_MFT1CH0SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_MFT_CTRL1_MFT1CH0SEL_SHIFT)) & SIM_MFT_CTRL1_MFT1CH0SEL_MASK); + obj->MFT_CTRL1 = tmp; +} + +/*! \brief Gets the MFT0 channel modulation select with MFT1_CH1 + * + * This function gets the current MFT0 channel modulation select with MFT1_CH1. + * Bits 7 to 0 of this field are for channel 7 to 0, respectively. For each channel, + * + * \param[in] obj : pointer to SIM register instance + * \return MFT0 channel modulation select with MFT1_CH1 + * - 0b : No modulation with MFT1_CH1 + * - 1b : Modulation with MFT1_CH1 + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetMftCtrl1Mft0OutSel(const SimRegType *obj) +{ + return ((obj->MFT_CTRL1 & SIM_MFT_CTRL1_MFT0_OUTSEL_MASK) >> SIM_MFT_CTRL1_MFT0_OUTSEL_SHIFT); +} + +/*! \brief Sets the MFT0 channel modulation select with MFT1_CH1 + * + * This function sets the MFT0 channel modulation select with MFT1_CH1. + * Bits 7 to 0 of this field are for channel 7 to 0, respectively. For each channel, + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of MFT0 channel modulation select with MFT1_CH1 + * - 0b : No modulation with MFT1_CH1 + * - 1b : Modulation with MFT1_CH1 + */ +__attribute__((always_inline)) static inline void SimReg_SetMftCtrl1Mft0OutSel(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT_CTRL1; + + tmp &= ~SIM_MFT_CTRL1_MFT0_OUTSEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_MFT_CTRL1_MFT0_OUTSEL_SHIFT)) & SIM_MFT_CTRL1_MFT0_OUTSEL_MASK); + obj->MFT_CTRL1 = tmp; +} + +/*! \brief Gets the flash eee restore config status + * + * This function gets the current Flash eee restore config status. + * Indicates the restore settings of emulated eeprom + * + * \param[in] obj : pointer to SIM register instance + * \return flash eee restore config status. + * - 0b : emulated eeprom is configured as not restore after reset + * - 1b : emulated eeprom is configured as restore after reset + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetFlashEeeRst(const SimRegType *obj) +{ + return ((obj->FLASH & SIM_FLASH_EEERST_MASK) >> SIM_FLASH_EEERST_SHIFT); +} + +/*! \brief Gets the flash eee valid + * + * This function gets the current flash eee valid. + * emulated eeprom is valid + * + * \param[in] obj : pointer to SIM register instance + * \return Flash eee Valid + * - 0b : invalid + * - 1b : valid + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetFlashEeeVld(const SimRegType *obj) +{ + return ((obj->FLASH & SIM_FLASH_EEEVLD_MASK) >> SIM_FLASH_EEEVLD_SHIFT); +} + +/*! \brief Gets the flash load is done + * + * This function gets the current flash load is done. + * + * \param[in] obj : pointer to SIM register instance + * \return flash load is done + * - 0b : during load progress + * - 1b : load done + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetFlashLoadDone(const SimRegType *obj) +{ + return ((obj->FLASH & SIM_FLASH_LOAD_DONE_MASK) >> SIM_FLASH_LOAD_DONE_SHIFT); +} + +/*! \brief Gets the flash is blank + * + * This function gets the current flash is blank. + * + * \param[in] obj : pointer to SIM register instance + * \return flash is blank + * - 0b : flash is not blank + * - 1b : flash is blank + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetFlashVirginFlag(const SimRegType *obj) +{ + return ((obj->FLASH & SIM_FLASH_VIRGIN_FLAG_MASK) >> SIM_FLASH_VIRGIN_FLAG_SHIFT); +} + +/*! \brief Gets the dflash prefetch buffer flush + * + * This function gets the current dflash prefetch buffer flush. + * + * \param[in] obj : pointer to SIM register instance + * \return dflash prefetch buffer flush + * - 0b : do not flush dflash prefetch buffer; + * - 1b : flush dflash prefetch buffer; + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetFlashDFlsFlushEn(const SimRegType *obj) +{ + return ((obj->FLASH & SIM_FLASH_DFLS_FLUSH_EN_MASK) >> SIM_FLASH_DFLS_FLUSH_EN_SHIFT); +} + +/*! \brief Sets the dflash prefetch buffer flush + * + * This function sets the dflash prefetch buffer flush. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of dflash prefetch buffer flush + * - 0b : do not flush dflash prefetch buffer; + * - 1b : flush dflash prefetch buffer; + */ +__attribute__((always_inline)) static inline void SimReg_SetFlashDFlsFlushEn(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLASH; + + tmp &= ~SIM_FLASH_DFLS_FLUSH_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_FLASH_DFLS_FLUSH_EN_SHIFT)) & SIM_FLASH_DFLS_FLUSH_EN_MASK); + obj->FLASH = tmp; +} + +/*! \brief Gets the pflash prefetch buffer flush + * + * This function gets the current pflash prefetch buffer flush. + * + * \param[in] obj : pointer to SIM register instance + * \return pflash prefetch buffer flush + * - 0b : do not flush pflash prefetch buffer; + * - 1b : flush pflash prefetch buffer; + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetFlashPFlsFlushEn(const SimRegType *obj) +{ + return ((obj->FLASH & SIM_FLASH_PFLS_FLUSH_EN_MASK) >> SIM_FLASH_PFLS_FLUSH_EN_SHIFT); +} + +/*! \brief Sets the pflash prefetch buffer flush + * + * This function sets the pflash prefetch buffer flush. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of pflash prefetch buffer flush + * - 0b : do not flush pflash prefetch buffer; + * - 1b : flush pflash prefetch buffer; + */ +__attribute__((always_inline)) static inline void SimReg_SetFlashPFlsFlushEn(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLASH; + + tmp &= ~SIM_FLASH_PFLS_FLUSH_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_FLASH_PFLS_FLUSH_EN_SHIFT)) & SIM_FLASH_PFLS_FLUSH_EN_MASK); + obj->FLASH = tmp; +} + +/*! \brief Gets the dflash prefetch enable + * + * This function gets the current dflash prefetch enable. + * + * \param[in] obj : pointer to SIM register instance + * \return dflash prefetch enable + * - 0b : disable dflash prefetch; + * - 1b : enable dflash prefetch; + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetFlashDFlsPfbEn(const SimRegType *obj) +{ + return ((obj->FLASH & SIM_FLASH_DFLS_PFB_EN_MASK) >> SIM_FLASH_DFLS_PFB_EN_SHIFT); +} + +/*! \brief Sets the dflash prefetch enable + * + * This function sets the dflash prefetch enable. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of dflash prefetch enable + * - 0b : disable dflash prefetch; + * - 1b : enable dflash prefetch; + */ +__attribute__((always_inline)) static inline void SimReg_SetFlashDFlsPfbEn(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLASH; + + tmp &= ~SIM_FLASH_DFLS_PFB_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_FLASH_DFLS_PFB_EN_SHIFT)) & SIM_FLASH_DFLS_PFB_EN_MASK); + obj->FLASH = tmp; +} + +/*! \brief Gets the pflash prefetch enable + * + * This function gets the current pflash prefetch enable. + * + * \param[in] obj : pointer to SIM register instance + * \return pflash prefetch enable + * - 0b : disable pflash prefetch; + * - 1b : enable pflash prefetch; + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetFlashPFlsPfbEn(const SimRegType *obj) +{ + return ((obj->FLASH & SIM_FLASH_PFLS_PFB_EN_MASK) >> SIM_FLASH_PFLS_PFB_EN_SHIFT); +} + +/*! \brief Sets the pflash prefetch enable + * + * This function sets the pflash prefetch enable. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of pflash prefetch enable + * - 0b : disable pflash prefetch; + * - 1b : enable pflash prefetch; + */ +__attribute__((always_inline)) static inline void SimReg_SetFlashPFlsPfbEn(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLASH; + + tmp &= ~SIM_FLASH_PFLS_PFB_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_FLASH_PFLS_PFB_EN_SHIFT)) & SIM_FLASH_PFLS_PFB_EN_MASK); + obj->FLASH = tmp; +} + +/*! \brief Gets the Unique Identification[127:96] + * + * This function gets the current Unique Identification[127:96]. + * + * \param[in] obj : pointer to SIM register instance + * \return Unique Identification[127:96] + */ +__attribute__((always_inline)) static inline uint32_t SimReg_GetUdidH(const SimRegType *obj) +{ + return ((obj->UDIDH & SIM_UDIDH_H_MASK) >> SIM_UDIDH_H_SHIFT); +} + +/*! \brief Gets the Unique Identification[95:64] + * + * This function gets the current Unique Identification[95:64]. + * + * \param[in] obj : pointer to SIM register instance + * \return Unique Identification[95:64] + */ +__attribute__((always_inline)) static inline uint32_t SimReg_GetUdidMH(const SimRegType *obj) +{ + return ((obj->UDIDMH & SIM_UDIDMH_MH_MASK) >> SIM_UDIDMH_MH_SHIFT); +} + +/*! \brief Gets the Unique Identification[63:32] + * + * This function gets the current Unique Identification[63:32]. + * + * \param[in] obj : pointer to SIM register instance + * \return Unique Identification[63:32] + */ +__attribute__((always_inline)) static inline uint32_t SimReg_GetUdidML(const SimRegType *obj) +{ + return ((obj->UDIDML & SIM_UDIDML_ML_MASK) >> SIM_UDIDML_ML_SHIFT); +} + +/*! \brief Gets the Unique Identification[31:0] + * + * This function gets the current Unique Identification[31:0]. + * + * \param[in] obj : pointer to SIM register instance + * \return Unique Identification[31:0] + */ +__attribute__((always_inline)) static inline uint32_t SimReg_GetUdidL(const SimRegType *obj) +{ + return ((obj->UDIDL & SIM_UDIDL_L_MASK) >> SIM_UDIDL_L_SHIFT); +} + +/*! \brief Gets the System Device Identification + * + * This function gets the current System Device Identification. + * + * \param[in] obj : pointer to SIM register instance + * \return System Device Identification + */ +__attribute__((always_inline)) static inline uint32_t SimReg_GetSdId(const SimRegType *obj) +{ + return ((obj->SDID & SIM_SDID_ID_MASK) >> SIM_SDID_ID_SHIFT); +} + +/*! \brief Gets the Software trigger to TRGMUX + * + * This function gets the current Software trigger to TRGMUX. + * Writing to this bit generates software trigger to peripheral + * + * \param[in] obj : pointer to SIM register instance + * \return Software trigger to TRGMUX + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetSwTrg(const SimRegType *obj) +{ + return ((obj->SW_TRG & SIM_SW_TRG_SW_TRG_MASK) >> SIM_SW_TRG_SW_TRG_SHIFT); +} + +/*! \brief Sets the Software trigger to TRGMUX + * + * This function sets the Software trigger to TRGMUX. + * Writing to this bit generates software trigger to peripheral + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of Software trigger to TRGMUX + */ +__attribute__((always_inline)) static inline void SimReg_SetSwTrg(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SW_TRG; + + tmp &= ~SIM_SW_TRG_SW_TRG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_SW_TRG_SW_TRG_SHIFT)) & SIM_SW_TRG_SW_TRG_MASK); + obj->SW_TRG = tmp; +} + +/*! \brief Gets the unmasked wake up interrupt flag + * + * This function gets the current unmasked wake up interrupt flag. + * + * \param[in] obj : pointer to SIM register instance + * \return unmasked wake up interrupt flag + * - 0b : there haven't wake up interrupt. + * - 1b : wake up interrrupt. + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetCanWakInt(const SimRegType *obj) +{ + return ((obj->CAN & SIM_CAN_WAK_INT_MASK) >> SIM_CAN_WAK_INT_SHIFT); +} + +/*! \brief Gets the FlexCAN self wakeup enable + * + * This function gets the current FlexCAN self wakeup enable. + * Indicates that the FlexCAN self wake up mechanism is enabled. + * + * \param[in] obj : pointer to SIM register instance + * \return FlexCAN self wakeup enable + * - 0b : the self wake up mechanism is not enabled. + * - 1b : the self wake up mechanism enabled. + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetCanSlfWak(const SimRegType *obj) +{ + return ((obj->CAN & SIM_CAN_SLF_WAK_MASK) >> SIM_CAN_SLF_WAK_SHIFT); +} + +/*! \brief Gets the FlexCAN low power mode flag + * + * This function gets the current FlexCAN low power mode flag. + * Indicates that the FlexCAN is in either Doze mode or stop mode. + * + * \param[in] obj : pointer to SIM register instance + * \return FlexCAN low power mode flag + * - 0b : the state is normal work mode. + * - 1b : the state is in low power mode. + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetCanLpmAck(const SimRegType *obj) +{ + return ((obj->CAN & SIM_CAN_LPM_ACK_MASK) >> SIM_CAN_LPM_ACK_SHIFT); +} + +/*! \brief Gets the CAN stop mode request + * + * This function gets the current CAN stop mode request. + * high active. + * + * \param[in] obj : pointer to SIM register instance + * \return CAN stop mode request + * - 0b : not request. + * - 1b : stop mode request. + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetCanIpgStop(const SimRegType *obj) +{ + return ((obj->CAN & SIM_CAN_IPG_STOP_MASK) >> SIM_CAN_IPG_STOP_SHIFT); +} + +/*! \brief Sets the CAN stop mode request + * + * This function sets the CAN stop mode request. + * high active. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of CAN stop mode request + * - 0b : not request. + * - 1b : stop mode request. + */ +__attribute__((always_inline)) static inline void SimReg_SetCanIpgStop(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CAN; + + tmp &= ~SIM_CAN_IPG_STOP_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_CAN_IPG_STOP_SHIFT)) & SIM_CAN_IPG_STOP_MASK); + obj->CAN = tmp; +} + +/*! \brief Gets the CAN soft reset + * + * This function gets the current CAN soft reset. + * high active. + * + * \param[in] obj : pointer to SIM register instance + * \return CAN soft reset + * - 0b : not reset. + * - 1b : reset. + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetCanSoftReset(const SimRegType *obj) +{ + return ((obj->CAN & SIM_CAN_SOFT_RESET_MASK) >> SIM_CAN_SOFT_RESET_SHIFT); +} + +/*! \brief Sets the CAN soft reset + * + * This function sets the CAN soft reset. + * high active. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of CAN soft reset + * - 0b : not reset. + * - 1b : reset. + */ +__attribute__((always_inline)) static inline void SimReg_SetCanSoftReset(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CAN; + + tmp &= ~SIM_CAN_SOFT_RESET_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_CAN_SOFT_RESET_SHIFT)) & SIM_CAN_SOFT_RESET_MASK); + obj->CAN = tmp; +} + +/*! \brief Gets the CAN doze mode request + * + * This function gets the current CAN doze mode request. + * high active. + * + * \param[in] obj : pointer to SIM register instance + * \return CAN doze mode request + * - 0b : not request. + * - 1b : doze request. + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetCanIpgDoze(const SimRegType *obj) +{ + return ((obj->CAN & SIM_CAN_IPG_DOZE_MASK) >> SIM_CAN_IPG_DOZE_SHIFT); +} + +/*! \brief Sets the CAN doze mode request + * + * This function sets the CAN doze mode request. + * high active. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of CAN doze mode request + * - 0b : not request. + * - 1b : doze request. + */ +__attribute__((always_inline)) static inline void SimReg_SetCanIpgDoze(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CAN; + + tmp &= ~SIM_CAN_IPG_DOZE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_CAN_IPG_DOZE_SHIFT)) & SIM_CAN_IPG_DOZE_MASK); + obj->CAN = tmp; +} + +/*! \brief Gets the CAN wake up function select signal + * + * This function gets the current CAN wake up function select signal . + * + * \param[in] obj : pointer to SIM register instance + * \return CAN wake up function select signal + * - 1b : support stop and doze mode. + * - 0b : select not support stop and doze mode. + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetCanWkupSrcSel(const SimRegType *obj) +{ + return ((obj->CAN & SIM_CAN_WKUP_SRC_SEL_MASK) >> SIM_CAN_WKUP_SRC_SEL_SHIFT); +} + +/*! \brief Sets the CAN wake up function select signal + * + * This function sets the CAN wake up function select signal . + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of CAN wake up function select signal + * - 1b : support stop and doze mode. + * - 0b : select not support stop and doze mode. + */ +__attribute__((always_inline)) static inline void SimReg_SetCanWkupSrcSel(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CAN; + + tmp &= ~SIM_CAN_WKUP_SRC_SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_CAN_WKUP_SRC_SEL_SHIFT)) & SIM_CAN_WKUP_SRC_SEL_MASK); + obj->CAN = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _SIM_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/spi_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/spi_reg.h new file mode 100644 index 0000000..e864bde --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/spi_reg.h @@ -0,0 +1,1708 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _SPI_REG_H_ +#define _SPI_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of SPI module + */ + +/****************************************************************************** + * the includes + *****************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * the defines + *****************************************************************************/ + +/* PARAM Bit fields */ +#define SPI_PARAM_TX_FIFO_DEPTH_MASK (0x000000FFul) +#define SPI_PARAM_TX_FIFO_DEPTH_SHIFT (0u) +#define SPI_PARAM_TX_FIFO_DEPTH_WIDTH (8u) + +#define SPI_PARAM_RX_FIFO_DEPTH_MASK (0x0000FF00ul) +#define SPI_PARAM_RX_FIFO_DEPTH_SHIFT (8u) +#define SPI_PARAM_RX_FIFO_DEPTH_WIDTH (8u) + +/* CR Bit fields */ +#define SPI_CR_EN_MASK (0x00000001ul) +#define SPI_CR_EN_SHIFT (0u) +#define SPI_CR_EN_WIDTH (1u) + +#define SPI_CR_RESET_MASK (0x00000002ul) +#define SPI_CR_RESET_SHIFT (1u) +#define SPI_CR_RESET_WIDTH (1u) + +#define SPI_CR_DOZE_EN_MASK (0x00000004ul) +#define SPI_CR_DOZE_EN_SHIFT (2u) +#define SPI_CR_DOZE_EN_WIDTH (1u) + +#define SPI_CR_DBG_EN_MASK (0x00000008ul) +#define SPI_CR_DBG_EN_SHIFT (3u) +#define SPI_CR_DBG_EN_WIDTH (1u) + +#define SPI_CR_RESET_TXFIFO_MASK (0x00000100ul) +#define SPI_CR_RESET_TXFIFO_SHIFT (8u) +#define SPI_CR_RESET_TXFIFO_WIDTH (1u) + +#define SPI_CR_RESET_RXFIFO_MASK (0x00000200ul) +#define SPI_CR_RESET_RXFIFO_SHIFT (9u) +#define SPI_CR_RESET_RXFIFO_WIDTH (1u) + +/* SR Bit fields */ +#define SPI_SR_TX_DATA_FLAG_MASK (0x00000001ul) +#define SPI_SR_TX_DATA_FLAG_SHIFT (0u) +#define SPI_SR_TX_DATA_FLAG_WIDTH (1u) + +#define SPI_SR_RX_DATA_FLAG_MASK (0x00000002ul) +#define SPI_SR_RX_DATA_FLAG_SHIFT (1u) +#define SPI_SR_RX_DATA_FLAG_WIDTH (1u) + +#define SPI_SR_RX_WORD_DONE_FLAG_MASK (0x00000100ul) +#define SPI_SR_RX_WORD_DONE_FLAG_SHIFT (8u) +#define SPI_SR_RX_WORD_DONE_FLAG_WIDTH (1u) + +#define SPI_SR_FRAME_DONE_FLAG_MASK (0x00000200ul) +#define SPI_SR_FRAME_DONE_FLAG_SHIFT (9u) +#define SPI_SR_FRAME_DONE_FLAG_WIDTH (1u) + +#define SPI_SR_XFR_DONE_FLAG_MASK (0x00000400ul) +#define SPI_SR_XFR_DONE_FLAG_SHIFT (10u) +#define SPI_SR_XFR_DONE_FLAG_WIDTH (1u) + +#define SPI_SR_TX_UF_FLAG_MASK (0x00000800ul) +#define SPI_SR_TX_UF_FLAG_SHIFT (11u) +#define SPI_SR_TX_UF_FLAG_WIDTH (1u) + +#define SPI_SR_RX_OF_FLAG_MASK (0x00001000ul) +#define SPI_SR_RX_OF_FLAG_SHIFT (12u) +#define SPI_SR_RX_OF_FLAG_WIDTH (1u) + +#define SPI_SR_BUSY_FLAG_MASK (0x01000000ul) +#define SPI_SR_BUSY_FLAG_SHIFT (24u) +#define SPI_SR_BUSY_FLAG_WIDTH (1u) + +/* IER Bit fields */ +#define SPI_IER_TX_DATA_IE_MASK (0x00000001ul) +#define SPI_IER_TX_DATA_IE_SHIFT (0u) +#define SPI_IER_TX_DATA_IE_WIDTH (1u) + +#define SPI_IER_RX_DATA_IE_MASK (0x00000002ul) +#define SPI_IER_RX_DATA_IE_SHIFT (1u) +#define SPI_IER_RX_DATA_IE_WIDTH (1u) + +#define SPI_IER_RX_WORD_DONE_IE_MASK (0x00000100ul) +#define SPI_IER_RX_WORD_DONE_IE_SHIFT (8u) +#define SPI_IER_RX_WORD_DONE_IE_WIDTH (1u) + +#define SPI_IER_FRAME_DONE_IE_MASK (0x00000200ul) +#define SPI_IER_FRAME_DONE_IE_SHIFT (9u) +#define SPI_IER_FRAME_DONE_IE_WIDTH (1u) + +#define SPI_IER_MST_TRANSFER_DONE_IE_MASK (0x00000400ul) +#define SPI_IER_MST_TRANSFER_DONE_IE_SHIFT (10u) +#define SPI_IER_MST_TRANSFER_DONE_IE_WIDTH (1u) + +#define SPI_IER_TX_UF_IE_MASK (0x00000800ul) +#define SPI_IER_TX_UF_IE_SHIFT (11u) +#define SPI_IER_TX_UF_IE_WIDTH (1u) + +#define SPI_IER_RX_OF_IE_MASK (0x00001000ul) +#define SPI_IER_RX_OF_IE_SHIFT (12u) +#define SPI_IER_RX_OF_IE_WIDTH (1u) + +#define SPI_IER_ALL_ISR_IE_MASK (0x00001FFFul) +#define SPI_IER_ALL_ISR_IE_SHIFT (0u) +#define SPI_IER_ALL_ISR_IE_WIDTH (13u) + +/* DER Bit fields */ +#define SPI_DER_DMA_TX_EN_MASK (0x00000001ul) +#define SPI_DER_DMA_TX_EN_SHIFT (0u) +#define SPI_DER_DMA_TX_EN_WIDTH (1u) + +#define SPI_DER_DMA_RX_EN_MASK (0x00000002ul) +#define SPI_DER_DMA_RX_EN_SHIFT (1u) +#define SPI_DER_DMA_RX_EN_WIDTH (1u) + +/* CFGR0 Bit fields */ +#define SPI_CFGR0_CIRCULAR_FIFO_EN_MASK (0x00000100ul) +#define SPI_CFGR0_CIRCULAR_FIFO_EN_SHIFT (8u) +#define SPI_CFGR0_CIRCULAR_FIFO_EN_WIDTH (1u) + +/* CFGR1 Bit fields */ +#define SPI_CFGR1_MASTER_EN_MASK (0x00000001ul) +#define SPI_CFGR1_MASTER_EN_SHIFT (0u) +#define SPI_CFGR1_MASTER_EN_WIDTH (1u) + +#define SPI_CFGR1_AUTO_PCS_MASK (0x00000004ul) +#define SPI_CFGR1_AUTO_PCS_SHIFT (2u) +#define SPI_CFGR1_AUTO_PCS_WIDTH (1u) + +#define SPI_CFGR1_NO_STALL_MASK (0x00000008ul) +#define SPI_CFGR1_NO_STALL_SHIFT (3u) +#define SPI_CFGR1_NO_STALL_WIDTH (1u) + +#define SPI_CFGR1_MST_SCK_DLY_MASK (0x00000070ul) +#define SPI_CFGR1_MST_SCK_DLY_SHIFT (4u) +#define SPI_CFGR1_MST_SCK_DLY_WIDTH (3u) + +#define SPI_CFGR1_PCS_POL_MASK (0x00000F00ul) +#define SPI_CFGR1_PCS_POL_SHIFT (8u) +#define SPI_CFGR1_PCS_POL_WIDTH (4u) + +#define SPI_CFGR1_PIN_CFG_MASK (0x03000000ul) +#define SPI_CFGR1_PIN_CFG_SHIFT (24u) +#define SPI_CFGR1_PIN_CFG_WIDTH (2u) + +#define SPI_CFGR1_OUT_CFG_MASK (0x04000000ul) +#define SPI_CFGR1_OUT_CFG_SHIFT (26u) +#define SPI_CFGR1_OUT_CFG_WIDTH (1u) + +/* CCR Bit fields */ +#define SPI_CCR_SCK_DIV_MASK (0x000000FFul) +#define SPI_CCR_SCK_DIV_SHIFT (0u) +#define SPI_CCR_SCK_DIV_WIDTH (8u) + +#define SPI_CCR_DBT_MASK (0x0000FF00ul) +#define SPI_CCR_DBT_SHIFT (8u) +#define SPI_CCR_DBT_WIDTH (8u) + +#define SPI_CCR_PCS_SCK_MASK (0x00FF0000ul) +#define SPI_CCR_PCS_SCK_SHIFT (16u) +#define SPI_CCR_PCS_SCK_WIDTH (8u) + +#define SPI_CCR_SCK_PCS_MASK (0xFF000000ul) +#define SPI_CCR_SCK_PCS_SHIFT (24u) +#define SPI_CCR_SCK_PCS_WIDTH (8u) + +/* FCR Bit fields */ +#define SPI_FCR_TX_FIFO_WATER_MASK (0x0000001Ful) +#define SPI_FCR_TX_FIFO_WATER_SHIFT (0u) +#define SPI_FCR_TX_FIFO_WATER_WIDTH (5u) + +#define SPI_FCR_RX_FIFO_WATER_MASK (0x001F0000ul) +#define SPI_FCR_RX_FIFO_WATER_SHIFT (16u) +#define SPI_FCR_RX_FIFO_WATER_WIDTH (5u) + +/* FSR Bit fields */ +#define SPI_FSR_TX_FIFO_CNT_MASK (0x0000001Ful) +#define SPI_FSR_TX_FIFO_CNT_SHIFT (0u) +#define SPI_FSR_TX_FIFO_CNT_WIDTH (5u) + +#define SPI_FSR_RX_FIFO_CNT_MASK (0x001F0000ul) +#define SPI_FSR_RX_FIFO_CNT_SHIFT (16u) +#define SPI_FSR_RX_FIFO_CNT_WIDTH (5u) + +/* TCR Bit fields */ +#define SPI_TCR_FRAME_SIZE_MASK (0x00000FFFul) +#define SPI_TCR_FRAME_SIZE_SHIFT (0u) +#define SPI_TCR_FRAME_SIZE_WIDTH (12u) + +#define SPI_TCR_TRANSFER_WIDTH_MASK (0x00030000ul) +#define SPI_TCR_TRANSFER_WIDTH_SHIFT (16u) +#define SPI_TCR_TRANSFER_WIDTH_WIDTH (2u) + +#define SPI_TCR_TX_MASK_MASK (0x00040000ul) +#define SPI_TCR_TX_MASK_SHIFT (18u) +#define SPI_TCR_TX_MASK_WIDTH (1u) + +#define SPI_TCR_RX_MASK_MASK (0x00080000ul) +#define SPI_TCR_RX_MASK_SHIFT (19u) +#define SPI_TCR_RX_MASK_WIDTH (1u) + +#define SPI_TCR_CONTINUE_CMD_MASK (0x00100000ul) +#define SPI_TCR_CONTINUE_CMD_SHIFT (20u) +#define SPI_TCR_CONTINUE_CMD_WIDTH (1u) + +#define SPI_TCR_CONTINUE_TRANSFER_MASK (0x00200000ul) +#define SPI_TCR_CONTINUE_TRANSFER_SHIFT (21u) +#define SPI_TCR_CONTINUE_TRANSFER_WIDTH (1u) + +#define SPI_TCR_BYTE_SWAP_MASK (0x00400000ul) +#define SPI_TCR_BYTE_SWAP_SHIFT (22u) +#define SPI_TCR_BYTE_SWAP_WIDTH (1u) + +#define SPI_TCR_LSB_FIRST_MASK (0x00800000ul) +#define SPI_TCR_LSB_FIRST_SHIFT (23u) +#define SPI_TCR_LSB_FIRST_WIDTH (1u) + +#define SPI_TCR_PCS_SEL_MASK (0x03000000ul) +#define SPI_TCR_PCS_SEL_SHIFT (24u) +#define SPI_TCR_PCS_SEL_WIDTH (2u) + +#define SPI_TCR_PRESCALER_MASK (0x38000000ul) +#define SPI_TCR_PRESCALER_SHIFT (27u) +#define SPI_TCR_PRESCALER_WIDTH (3u) + +#define SPI_TCR_CPHA_MASK (0x40000000ul) +#define SPI_TCR_CPHA_SHIFT (30u) +#define SPI_TCR_CPHA_WIDTH (1u) + +#define SPI_TCR_CPOL_MASK (0x80000000ul) +#define SPI_TCR_CPOL_SHIFT (31u) +#define SPI_TCR_CPOL_WIDTH (1u) + +/* TDR Bit fields */ +#define SPI_TDR_DATA_MASK (0xFFFFFFFFul) +#define SPI_TDR_DATA_SHIFT (0u) +#define SPI_TDR_DATA_WIDTH (32u) + +/* RSR Bit fields */ +#define SPI_RSR_SOF_MASK (0x00000001ul) +#define SPI_RSR_SOF_SHIFT (0u) +#define SPI_RSR_SOF_WIDTH (1u) + +#define SPI_RSR_RX_FIFO_EMPTY_MASK (0x00000002ul) +#define SPI_RSR_RX_FIFO_EMPTY_SHIFT (1u) +#define SPI_RSR_RX_FIFO_EMPTY_WIDTH (1u) + +/* RDR Bit fields */ +#define SPI_RDR_DATA_MASK (0xFFFFFFFFul) +#define SPI_RDR_DATA_SHIFT (0u) +#define SPI_RDR_DATA_WIDTH (32u) + +/****************************************************************************** + * the typedefs + *****************************************************************************/ + +/*! \brief the definition of spi register */ +typedef struct _SpiRegType_ +{ + volatile uint32_t VERID; /*!< SPI Version ID Register, offset: 0x00 */ + volatile uint32_t PARAM; /*!< SPI Parameters Register, offset: 0x04 */ + uint32_t RES1[2]; /*!< SPI Res, offset: 0x08 */ + volatile uint32_t CR; /*!< SPI Control Register, offset: 0x10 */ + volatile uint32_t SR; /*!< SPI Status Register, offset: 0x14 */ + volatile uint32_t IER; /*!< SPI Interrupt Enable Register, offset: 0x18 */ + volatile uint32_t DER; /*!< SPI DMA control Register, offset: 0x1C */ + volatile uint32_t CFGR0; /*!< SPI Configuration 0 Register, offset: 0x20 */ + volatile uint32_t CFGR1; /*!< SPI Configuration 1 Register, offset: 0x24 */ + uint32_t RES2[6]; /*!< SPI Res, offset: 0x28 */ + volatile uint32_t CCR; /*!< SPI Clock Configuration Register, offset: 0x40 */ + uint32_t RES3[5]; /*!< SPI Res Register, offset: 0x44 */ + volatile uint32_t FCR; /*!< SPI FIFO Control Register, offset: 0x58 */ + volatile uint32_t FSR; /*!< SPI FIFO Status Register, offset: 0x5C */ + volatile uint32_t TCR; /*!< SPI Transmit Control Register, offset: 0x60 */ + volatile uint32_t TDR; /*!< SPI Transmit Data Register, offset: 0x64 */ + uint32_t RES4[2]; /*!< SPI Res Register, offset: 0x68 */ + volatile uint32_t RSR; /*!< SPI Receive Status Register, offset: 0x70 */ + volatile uint32_t RDR; /*!< SPI Receive Data Register, offset: 0x74 */ +} SpiRegType; + +/****************************************************************************** + * the globals + *****************************************************************************/ + +/****************************************************************************** + * the function prototypes + *****************************************************************************/ + +/*! \brief Get the tx fifo depth size that the hardware supports + * + * this function get the tx fifo depth how many the hardware supported + * + * \param[in] obj : base address for the SPI instance + * \return: uint8_t : Real depth = 2^(TX_FIFO_DEPTH) + * 0h:1 + * 1h:2 + * 2h:4 + * 3h:8 + * 4h:16 + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetTxFifoDepth(SpiRegType *obj) +{ + uint8_t tRtn = 0; + uint8_t tFifoDepth[5] = {1, 2, 4, 8, 16}; + + tRtn = (((obj->PARAM & SPI_PARAM_TX_FIFO_DEPTH_MASK) >> SPI_PARAM_TX_FIFO_DEPTH_SHIFT) & 0xFF); + tRtn = tRtn < 4 ? tRtn : 4; + + return tFifoDepth[tRtn]; +} + +/*! \brief Get the rx fifo depth size that the hardware supports + * + * this function get the rx fifo depth how many the hardware supported + * + * \param[in] obj : base address for the SPI instance + * \return: uint8_t : Real depth = 2^(RX_FIFO_DEPTH) + * 0h:1 + * 1h:2 + * 2h:4 + * 3h:8 + * 4h:16 + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetRxFifoDepth(const SpiRegType *obj) +{ + uint8_t tRtn = 0; + uint8_t tFifoDepth[5] = {1, 2, 4, 8, 16}; + + tRtn = (((obj->PARAM & SPI_PARAM_RX_FIFO_DEPTH_MASK) >> SPI_PARAM_RX_FIFO_DEPTH_SHIFT) & 0xFF); + tRtn = tRtn < 4 ? tRtn : 4; + + return tFifoDepth[tRtn]; +} + +/*! \brief spi module enable + * + * this function enable the module + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable : enable or disable module + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_EnableModule(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->CR; + + if(enable == true) + { + obj->CR = ((1ul << SPI_CR_EN_SHIFT) | ((~SPI_CR_EN_MASK) & tRegValue)); + } + else + { + obj->CR = ((0ul << SPI_CR_EN_SHIFT) | ((~SPI_CR_EN_MASK) & tRegValue)); + } +} + +/*! \brief module software reset + * + * Reset all internal logic and registers, except the Control Register. + * RST remains set until cleared by software. + * + * \param[in] obj: base address for the SPI instance + * \param[in] reset: enable or disable reset module + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_ResetModule(SpiRegType *obj, bool reset) +{ + uint32_t tRegValue = obj->CR; + + if(reset == true) + { + obj->CR = ((1ul << SPI_CR_RESET_SHIFT) | ((~SPI_CR_RESET_MASK) & tRegValue)); + } + else + { + obj->CR = ((0ul << SPI_CR_RESET_SHIFT) | ((~SPI_CR_RESET_MASK) & tRegValue)); + } +} + +/*! \brief STOP/DEBUG Mode Enable + * + * Enables or disables the SPI module in STOP and DEBUG mode. + * This bit should be updated only when the SPI module is disabled. + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: enable or disable doze mode + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_EnableDozeMode(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->CR; + + if(enable == true) + { + obj->CR = ((1ul << SPI_CR_DOZE_EN_SHIFT) | ((~SPI_CR_DOZE_EN_MASK) & tRegValue)); + } + else + { + obj->CR = ((0ul << SPI_CR_DOZE_EN_SHIFT) | ((~SPI_CR_DOZE_EN_MASK) & tRegValue)); + } +} + +/*! \brief Debug Enable + * + * Enables or disables the SPI module in debug mode. + * Debug Enable bit should be updated only when the SPI module is disabled. + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: enable or disable debug mode + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_EnableDebugMode(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->CR; + + if(enable == true) + { + obj->CR = ((1ul << SPI_CR_DBG_EN_SHIFT) | ((~SPI_CR_DBG_EN_MASK) & tRegValue)); + } + else + { + obj->CR = ((0ul << SPI_CR_DBG_EN_SHIFT) | ((~SPI_CR_DBG_EN_MASK) & tRegValue)); + } +} + +/*! \brief Reset Transmit FIFO + * + * the bit is WO + * + * \param[in] obj: base address for the SPI instance + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_ResetTxFIFO(SpiRegType *obj) +{ + uint32_t tRegValue = obj->CR; + + obj->CR = ((1ul << SPI_CR_RESET_TXFIFO_SHIFT) | ((~SPI_CR_RESET_TXFIFO_MASK) & tRegValue)); +} + +/*! \brief Reset Receive FIFO + * + * the bit is WO + * + * \param[in] obj: base address for the SPI instance + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_ResetRxFIFO(SpiRegType *obj) +{ + uint32_t tRegValue = obj->CR; + + obj->CR = ((1ul << SPI_CR_RESET_RXFIFO_SHIFT) | ((~SPI_CR_RESET_RXFIFO_MASK) & tRegValue)); +} + +/*! \brief Transmit Data Flag + * + * The Transmit Data Flag is set whenever the number of words in the transmit FIFO is equal or less than FCR[TXWATER] + * (FIFO Control Register) + * + * \param[in] obj: base address for the SPI instance + * \return: uint8_t + * 0b - Transmit data not requested + * 1b - Transmit data is requested + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetTxDataFlag(const SpiRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = ((obj->SR & SPI_SR_TX_DATA_FLAG_MASK) >> SPI_SR_TX_DATA_FLAG_SHIFT) & 0xFF; + + return tRtn; +} + +/*! \brief Receive Data Flag + * + * The Receive Data Flag is set whenever the number of words in the receive FIFO is greater than + * FCR[RXWATER] (FIFO Control Register) + * + * \param[in] obj: base address for the SPI instance + * \return: uint8_t + * 0b - Receive Data is not ready + * 1b - Receive data is ready + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetRxDataFlag(const SpiRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->SR & SPI_SR_RX_DATA_FLAG_MASK) >> SPI_SR_RX_DATA_FLAG_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Get Receive Word Complete Flag + * + * The Word Complete Flag will set when the last bit of a received word is sampled. + * + * \param[in] obj: base address for the SPI instance + * \return: uint8_t + * 0b : Transfer of a received word has not yet completed + * 1b : Transfer of a received word has completed + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetRxWordDoneFlag(const SpiRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->SR & SPI_SR_RX_WORD_DONE_FLAG_MASK) >> SPI_SR_RX_WORD_DONE_FLAG_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Clear Receive Word Complete Flag + * + * this flag is clear by write one to the referenced bit + * + * \param[in] obj: base address for the SPI instance + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_ClearRxWordDoneFlag(SpiRegType *obj) +{ + obj->SR |= SPI_SR_RX_WORD_DONE_FLAG_MASK; +} + +/*! \brief Get Frame Complete Flag + * + * The Frame Complete Flag will set at the end of each frame transfer. + * + * \param[in] obj: base address for the SPI instance + * \return: uint8_t + * 0b : Frame transfer has not completed + * 1b : Frame transfer has completed + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetFrameDoneFlag(const SpiRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->SR & SPI_SR_FRAME_DONE_FLAG_MASK) >> SPI_SR_FRAME_DONE_FLAG_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Clear Frame Complete Flag + * + * this flag is clear by write one to the referenced bit + * + * \param[in] obj: base address for the SPI instance + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_ClearFrameDoneFlag(SpiRegType *obj) +{ + obj->SR |= SPI_SR_FRAME_DONE_FLAG_MASK; +} + +/*! \brief Get Master Transfer Complete Flag + * + * In master mode when the SPI returns to idle state,when the PCS negates, + the Transfer Complete Flag will set. + * + * \param[in] obj: base address for the SPI instance + * \return: uint8_t + * 0b : All transfers have not completed + * 1b : All transfers have completed + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetMasterTransferDoneFlag(const SpiRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->SR & SPI_SR_XFR_DONE_FLAG_MASK) >> SPI_SR_XFR_DONE_FLAG_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Clear Master Transfer Complete Flag + * + * this flag is clear by write one to the referenced bit + * + * \param[in] obj: base address for the SPI instance + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_ClearMasterTransferDoneFlag(SpiRegType *obj) +{ + obj->SR |= SPI_SR_XFR_DONE_FLAG_MASK; +} + +/*! \brief Get Transmit FIFO underflow Flag + * + * The Transmit Error Flag will set when the Transmit FIFO under runs + * + * \param[in] obj: base address for the SPI instance + * \return: uint8_t + * 0b : Transmit FIFO underrun has not occurred + * 1b : Transmit FIFO underrun has occurred + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetTxUnderFlowFlag(const SpiRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->SR & SPI_SR_TX_UF_FLAG_MASK) >> SPI_SR_TX_UF_FLAG_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Clear Transmit FIFO underflow Flag + * + * this flag is clear by write one to the referenced bit + * + * \param[in] obj: base address for the SPI instance + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_ClearTxUnderFlowFlag(SpiRegType *obj) +{ + obj->SR |= SPI_SR_TX_UF_FLAG_MASK; +} + +/*! \brief Get RX FIFO overflow flag + * + * The Receive Error Flag will set when the Receiver FIFO overflows. When the Receive Error Flag is set + * + * \param[in] obj: base address for the SPI instance + * \return: uint8_t + * 0b : Receive FIFO has not overflowed + * 1b : Receive FIFO has overflowed + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetRxOverFlowFlag(const SpiRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->SR & SPI_SR_RX_OF_FLAG_MASK) >> SPI_SR_RX_OF_FLAG_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Clear RX FIFO overflow flag + * + * this flag is clear by write one to the referenced bit + * + * \param[in] obj: base address for the SPI instance + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_ClearRxOverFlowFlag(SpiRegType *obj) +{ + obj->SR |= SPI_SR_RX_OF_FLAG_MASK; +} + +/*! \brief Module Busy Flag + * + * this function get the current status about the module + * + * \param[in] obj: base address for the SPI instance + * \return: uint8_t + * 0b : SPI is idle + * 1b : SPI is busy + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetBusyFlag(const SpiRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->SR & SPI_SR_BUSY_FLAG_MASK) >> SPI_SR_BUSY_FLAG_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief RX FIFO overflow interrupt enable or disable + * + * this function enable the rx overflow interrupt request if the condition is matched + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: RX FIFO overflow interrupt enable + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetRxOverflowIsr(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->IER; + + if(enable == true) + { + obj->IER = ((1ul << SPI_IER_RX_OF_IE_SHIFT) | ((~SPI_IER_RX_OF_IE_MASK) & tRegValue)); + } + else + { + obj->IER = ((0ul << SPI_IER_RX_OF_IE_SHIFT) | ((~SPI_IER_RX_OF_IE_MASK) & tRegValue)); + } +} + +/*! \brief Transmit FIFO underflow interrupt enable or disable + * + * this function enable the tx underflow interrupt request if the condition is matched + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: Transmit FIFO underflow interrupt enable + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetTxUnderflowIsr(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->IER; + + if(enable == true) + { + obj->IER = ((1ul << SPI_IER_TX_UF_IE_SHIFT) | ((~SPI_IER_TX_UF_IE_MASK) & tRegValue)); + } + else + { + obj->IER = ((0ul << SPI_IER_TX_UF_IE_SHIFT) | ((~SPI_IER_TX_UF_IE_MASK) & tRegValue)); + } +} + +/*! \brief Master Transfer Complete interrupt enable or disable + * + * this function enable the tx transfer done interrupt request if the condition is matched + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: Master Transfer Complete interrupt enable + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetTxTransferDoneIsr(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->IER; + + if(enable == true) + { + obj->IER = ((1ul << SPI_IER_MST_TRANSFER_DONE_IE_SHIFT) | ((~SPI_IER_MST_TRANSFER_DONE_IE_MASK) & tRegValue)); + } + else + { + obj->IER = ((0ul << SPI_IER_MST_TRANSFER_DONE_IE_SHIFT) | ((~SPI_IER_MST_TRANSFER_DONE_IE_MASK) & tRegValue)); + } +} + +/*! \brief Master Transfer Complete interrupt enable or disable + * + * this function enable the frame done interrupt request if the condition is matched + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: Frame Complete interrupt enable + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetFrameDoneIsr(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->IER; + + if(enable == true) + { + obj->IER = ((1ul << SPI_IER_FRAME_DONE_IE_SHIFT) | ((~SPI_IER_FRAME_DONE_IE_MASK) & tRegValue)); + } + else + { + obj->IER = ((0ul << SPI_IER_FRAME_DONE_IE_SHIFT) | ((~SPI_IER_FRAME_DONE_IE_MASK) & tRegValue)); + } +} + +/*! \brief Receive Word Complete interrupt enable or disable + * + * this function enable the rx word done interrupt request if the condition is matched + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: Receive Word Complete interrupt enable + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetRxWordDoneIsr(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->IER; + + if(enable == true) + { + obj->IER = ((1ul << SPI_IER_RX_WORD_DONE_IE_SHIFT) | ((~SPI_IER_RX_WORD_DONE_IE_MASK) & tRegValue)); + } + else + { + obj->IER = ((0ul << SPI_IER_RX_WORD_DONE_IE_SHIFT) | ((~SPI_IER_RX_WORD_DONE_IE_MASK) & tRegValue)); + } +} + +/*! \brief Receive Data interrupt enable + * + * this function enable the rx data interrupt request if the condition is matched + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: Receive Data interrupt enable + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetRxDataIsr(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->IER; + + if(enable == true) + { + obj->IER = ((1ul << SPI_IER_RX_DATA_IE_SHIFT) | ((~SPI_IER_RX_DATA_IE_MASK) & tRegValue)); + } + else + { + obj->IER = ((0ul << SPI_IER_RX_DATA_IE_SHIFT) | ((~SPI_IER_RX_DATA_IE_MASK) & tRegValue)); + } +} + +/*! \brief Transmit Data interrupt enable or disable + * + * this function enable the tx data interrupt request if the condition is matched + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: Transmit Data interrupt enable + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetTxDataIsr(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->IER; + + if(enable == true) + { + obj->IER = ((1ul << SPI_IER_TX_DATA_IE_SHIFT) | ((~SPI_IER_TX_DATA_IE_MASK) & tRegValue)); + } + else + { + obj->IER = ((0ul << SPI_IER_TX_DATA_IE_SHIFT) | ((~SPI_IER_TX_DATA_IE_MASK) & tRegValue)); + } +} + +/*! \brief Enable the interrupt request with combination + * + * this function enable the interrupt request with the intMask + * + * \param[in] obj :: base address for the SPI instance + * \param[in] intMask : which interrupt request to be operated + * example : SPI_IER_RX_DATA_IE_MASK | SPI_IER_TX_DATA_IE_MASK + * \param[in] enable : enable or disable + * \return void + */ +__attribute__((always_inline)) static inline void SpiReg_EnableIntReq(SpiRegType *obj, uint32_t intMask, bool enable) +{ + uint32_t tRegValue = obj->IER; + + if(enable == true) + { + obj->IER = (intMask | ((~intMask) & tRegValue)); + } + else + { + obj->IER = ((~intMask) & tRegValue); + } +} + +/*! \brief Get the interrupt request is enabled or not + * + * this function enable the interrupt request with the intMask + * + * \param[in] obj :: base address for the SPI instance + * \param[in] intMask : which interrupt request to be operated + * \return bool + * true: the interrupt is enabled + * false: the interrupt is disabled + */ +__attribute__((always_inline)) static inline bool SpiReg_GetIntReqEnableState(const SpiRegType *obj, uint32_t intMask) +{ + bool tRtn = false; + + if((obj->IER & intMask) == intMask) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief receive dma enable or disable + * + * this function enable the rx with dma method + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: receive dma enable + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetRxDMA(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->DER; + + if(enable == true) + { + obj->DER = ((1ul << SPI_DER_DMA_RX_EN_SHIFT) | ((~SPI_DER_DMA_RX_EN_MASK) & tRegValue)); + } + else + { + obj->DER = ((0ul << SPI_DER_DMA_RX_EN_SHIFT) | ((~SPI_DER_DMA_RX_EN_MASK) & tRegValue)); + } +} + +/*! \brief transmit dma enable or disable + * + * this function enable the tx with dma method + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: transmit dma enable + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetTxDMA(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->DER; + + if(enable == true) + { + obj->DER = ((1ul << SPI_DER_DMA_TX_EN_SHIFT) | ((~SPI_DER_DMA_TX_EN_MASK) & tRegValue)); + } + else + { + obj->DER = ((0ul << SPI_DER_DMA_TX_EN_SHIFT) | ((~SPI_DER_DMA_TX_EN_MASK) & tRegValue)); + } +} + +/*! \brief Set Clock Polarity + * + * The Clock Polarity field is only updated when PCS negated. + * + * \param[in] obj : base address for the SPI instance + * \param[in] clockPolarity : + * 0b : The inactive state value of SCK is low + * 1b : The inactive state value of SCK is high + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetClockPolarity(SpiRegType *obj, uint8_t clockPolarity) +{ + uint32_t tmp = obj->TCR; + + tmp &= ~SPI_TCR_CPOL_MASK; + tmp |= (((uint32_t)(((uint32_t)(clockPolarity)) << SPI_TCR_CPOL_SHIFT)) & SPI_TCR_CPOL_MASK); + obj->TCR = tmp; +} + +/*! \brief Set Clock Phase + * + * The Clock Phase field is only updated when PCS negated. + * + * \param[in] obj : base address for the SPI instance + * \param[in] clockPhase : + * 0b : Data is captured on the leading edge of SCK and changed on the following edge of SCK + * 1b : Data is changed on the leading edge of SCK and captured on the following edge of SCK + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetClockPhase(SpiRegType *obj, uint8_t clockPhase) +{ + uint32_t tmp = obj->TCR; + + tmp &= ~SPI_TCR_CPHA_MASK; + tmp |= (((uint32_t)(((uint32_t)(clockPhase)) << SPI_TCR_CPHA_SHIFT)) & SPI_TCR_CPHA_MASK); + obj->TCR = tmp; +} + +/*! \brief Set Prescaler Value + * + * For all SPI bus transfers, the Prescaler value applied to the clock configuration register. The Prescaler Value field is only updated when PCS negated. + * + * \param[in] obj : base address for the SPI instance + * \param[in] prescaler : + * 000b : Divide by 1 + * 001b : Divide by 2 + * 010b : Divide by 4 + * 011b : Divide by 8 + * 100b : Divide by 16 + * 101b : Divide by 32 + * 110b : Divide by 64 + * 111b : Divide by 128 + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetPrescaler(SpiRegType *obj, uint8_t prescaler) +{ + uint32_t tmp = obj->TCR; + + tmp &= ~SPI_TCR_PRESCALER_MASK; + tmp |= (((uint32_t)(((uint32_t)(prescaler)) << SPI_TCR_PRESCALER_SHIFT)) & SPI_TCR_PRESCALER_MASK); + obj->TCR = tmp; +} + +/*! \brief Select Peripheral Chip + * + * Configures the peripheral chip select used for the transfer. The Peripheral Chip Select field is only updated when PCS negated. + * + * \param[in] obj : base address for the SPI instance + * \param[in] pcsSelection : + * 00b : Transfer using SPI_PCS[0] + * 01b : Transfer using SPI_PCS[1] + * 10b : Transfer using SPI_PCS[2] + * 11b : Transfer using SPI_PCS[3] + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetPcsSelection(SpiRegType *obj, uint8_t pcsSelection) +{ + uint32_t tmp = obj->TCR; + + tmp &= ~SPI_TCR_PCS_SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(pcsSelection)) << SPI_TCR_PCS_SEL_SHIFT)) & SPI_TCR_PCS_SEL_MASK); + obj->TCR = tmp; +} + +/*! \brief Set data transfer bit direction + * + * Note: + * + * \param[in] obj : base address for the SPI instance + * \param[in] lsbFirst : + * 0b:Data is transferred MSB first + * 1b:Data is transferred LSB first + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetLowBitFirstTransfer(SpiRegType *obj, uint8_t lsbFirst) +{ + uint32_t tmp = obj->TCR; + + tmp &= ~SPI_TCR_LSB_FIRST_MASK; + tmp |= (((uint32_t)(((uint32_t)(lsbFirst)) << SPI_TCR_LSB_FIRST_SHIFT)) & SPI_TCR_LSB_FIRST_MASK); + obj->TCR = tmp; +} + +/*! \brief Get data transfer bit direction + * + * + * + * \param[in] obj: base address for the SPI instance + * \return: transfer bit direction + * 0b:Data is transferred MSB first + * 1b:Data is transferred LSB first + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetTransferDataBitLsbState(const SpiRegType *obj) +{ + uint8_t tRtn = 0; + + if((obj->TCR & SPI_TCR_LSB_FIRST_MASK) != 0u) + { + tRtn = 1; + } + + return tRtn; +} + +/*! \brief Set Byte Swap + * + * Byte swap will swap the contents of [31:24] with [7:0] and [23:16] with [15:8] for each transmit data word read from + * the FIFO and for each received data word stored to the FIFO + * + * \param[in] obj : base address for the SPI instance + * \param[in] enable : + * 0b:Byte swap is disabled + * 1b:Byte swap is enabled + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetByteSwap(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->TCR; + + if(enable == true) + { + obj->TCR = ((1ul << SPI_TCR_BYTE_SWAP_SHIFT) | ((~SPI_TCR_BYTE_SWAP_MASK) & tRegValue)); + } + else + { + obj->TCR = ((0ul << SPI_TCR_BYTE_SWAP_SHIFT) | ((~SPI_TCR_BYTE_SWAP_MASK) & tRegValue)); + } +} + +/*! \brief Set Continuous Transfer + * + * In master mode, continuous transfer will keep the PCS asserted at the end of the frame size, + * until a command word is received that starts a new frame. + * In slave mode, when continuous transfer is enabled, the SPI will only transmit the first FRAMESZ bits; + * after which the SPI will transmit received data (assuming a 32-bit shift register) until the next PCS negation. + * + * \param[in] obj : base address for the SPI instance + * \param[in] enable : + * 0b:Continuous transfer is disabled + * 1b:Continuous transfer is enabled + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetContinuousTransfer(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->TCR; + + if(enable == true) + { + obj->TCR = ((1ul << SPI_TCR_CONTINUE_TRANSFER_SHIFT) | ((~SPI_TCR_CONTINUE_TRANSFER_MASK) & tRegValue)); + } + else + { + obj->TCR = ((0ul << SPI_TCR_CONTINUE_TRANSFER_SHIFT) | ((~SPI_TCR_CONTINUE_TRANSFER_MASK) & tRegValue)); + } +} + +/*! \brief Set Continuing Command + * + * In master mode, the Continuing Command bit allows the command word to be changed within a transfer. + * 1. in continuous transfer + * The initial command word must enable continuous transfer (CONT=1), + * the continuing command must set this bit (CONTC=1), + * the continuing command word must be loaded on a frame size boundary. + * 2. in non-continuous transfer + * the continuing command must set this bit (CONTC=1), + * the continuing command word must be loaded on a frame size boundary. + * + * \param[in] obj : base address for the SPI instance + * \param[in] cmd : + * 0b:Command word for start of new transfer + * 1b:Command word for continuing transfer + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetContinuousCmd(SpiRegType *obj, uint8_t cmd) +{ + uint32_t tmp = obj->TCR; + + tmp &= ~SPI_TCR_CONTINUE_CMD_MASK; + tmp |= (((uint32_t)(((uint32_t)(cmd)) << SPI_TCR_CONTINUE_CMD_SHIFT)) & SPI_TCR_CONTINUE_CMD_MASK); + obj->TCR = tmp; +} + +/*! \brief Set Receive Data Mask + * + * When set, receive data is masked (receive data is not stored in receive FIFO). + * + * \param[in] obj : base address for the SPI instance + * \param[in] enableMask : + * 0b:Normal transfer + * 1b:Receive data is masked + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetRxDataMask(SpiRegType *obj, bool enableMask) +{ + uint32_t tRegValue = obj->TCR; + + if(enableMask == true) + { + obj->TCR = ((1ul << SPI_TCR_RX_MASK_SHIFT) | ((~SPI_TCR_RX_MASK_MASK) & tRegValue)); + } + else + { + obj->TCR = ((0ul << SPI_TCR_RX_MASK_SHIFT) | ((~SPI_TCR_RX_MASK_MASK) & tRegValue)); + } +} + +/*! \brief Set Transmit Data Mask + * + * When set, transmit data is masked (no data is loaded from transmit FIFO and output pin is tristated). + * In master mode, the Transmit Data Mask bit will initiate a new transfer + * which cannot be aborted by another command word; TXMSK bit will be cleared by hardware at the end of the transfer. + * + * \param[in] obj : base address for the SPI instance + * \param[in] enableMask : + * 0b:Normal transfer + * 1b:Mask transmit data + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetTxDataMask(SpiRegType *obj, bool enableMask) +{ + uint32_t tRegValue = obj->TCR; + + if(enableMask == true) + { + obj->TCR = ((1ul << SPI_TCR_TX_MASK_SHIFT) | ((~SPI_TCR_TX_MASK_MASK) & tRegValue)); + } + else + { + obj->TCR = ((0ul << SPI_TCR_TX_MASK_SHIFT) | ((~SPI_TCR_TX_MASK_MASK) & tRegValue)); + } +} + +/*! \brief Set Transfer data Width + * + * Configures between serial (1-bit) or parallel transfers. For half-duplex parallel transfers, either Receive Data Mask (RXMSK) or Transmit Data Mask (TXMSK) must be set. + * + * \param[in] obj : base address for the SPI instance + * \param[in] transferWidth : + * 00b:1 bit transfer + * 01b:2 bit transfer + * 10b:Reserved + * 11b:Reserved + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetTransferWidth(SpiRegType *obj, uint8_t transferWidth) +{ + uint32_t tmp = obj->TCR; + + tmp &= ~SPI_TCR_TRANSFER_WIDTH_MASK; + tmp |= (((uint32_t)(((uint32_t)(transferWidth)) << SPI_TCR_TRANSFER_WIDTH_SHIFT)) & SPI_TCR_TRANSFER_WIDTH_MASK); + obj->TCR = tmp; +} + +/*! \brief Set Frame Size + * + * The minimum frame size is 8 bits, The minimum word size is 2 bits; a frame size of 33 bits (or similar) is not supported. + * If the frame size is larger than 32 bits, then the frame is divided into multiple words of 32-bits; + * each word is loaded from the transmit FIFO and stored in the receive FIFO separately. + * If the size of the frame is not divisible by 32, then the last load of the transmit FIFO and store of the receive FIFO will contain the remainder bits. + * For example, a 72-bit transfer will consist of 3 words: the 1st and 2nd words are 32 bits, and the 3rd word is 8 bits. + * + * \param[in] obj : base address for the SPI instance + * \param[in] frameSize :Configures the frame size in number of bits equal to (FRAMESZ + 1) + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetFrameSize(SpiRegType *obj, uint16_t frameSize) +{ + uint32_t tmp = obj->TCR; + + tmp &= ~SPI_TCR_FRAME_SIZE_MASK; + tmp |= (((uint32_t)(((uint32_t)(frameSize)) << SPI_TCR_FRAME_SIZE_SHIFT)) & SPI_TCR_FRAME_SIZE_MASK); + obj->TCR = tmp; +} + +/*! \brief Get Frame Size + * + * \param[in] obj : base address for the SPI instance + * \return : Return the frame size in number of bits equal to (FRAMESZ + 1) + */ +__attribute__((always_inline)) static inline uint16_t SpiReg_GetFrameSize(const SpiRegType *obj) +{ + uint16_t tRtn = 0; + + tRtn = ((obj->TCR & SPI_TCR_FRAME_SIZE_MASK) >> SPI_TCR_FRAME_SIZE_SHIFT); + return tRtn; +} + +/*! \brief Transmit Command config + * + * this function config the clock polarity, clock phase prescaler value and transfer mode .... + * + * \param[in] obj: base address for the SPI instance + * \param[in] tcr: Transmit Command + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetTcr(SpiRegType *obj, uint32_t tcr) +{ + obj->TCR = tcr; +} + +/*! \brief Get Transmit Command config + * + * this function config get the clock polarity, clock phase prescaler value and transfer mode .... + * + * \param[in] obj: base address for the SPI instance + * \return: Transmit Command + */ +__attribute__((always_inline)) static inline uint32_t SpiReg_GetTcr(const SpiRegType *obj) +{ + return obj->TCR; +} + +/*! \brief Circular FIFO Enable or disable + * + * this function enable the tx circular fifo mode + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: + * 0b : disabled + * 1b : enabled + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetCircularFIFO(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->CFGR0; + + if(enable == true) + { + obj->CFGR0 = ((1ul << SPI_CFGR0_CIRCULAR_FIFO_EN_SHIFT) | ((~SPI_CFGR0_CIRCULAR_FIFO_EN_MASK) & tRegValue)); + } + else + { + obj->CFGR0 = ((0ul << SPI_CFGR0_CIRCULAR_FIFO_EN_SHIFT) | ((~SPI_CFGR0_CIRCULAR_FIFO_EN_MASK) & tRegValue)); + } +} + +/*! \brief Output Configuration + * + * Configures if the output data is tristate between accesses (SPI_PCS is negated). If performing half- + * duplex transfers, this bit must be set. + * + * \param[in] obj: base address for the SPI instance + * \param[in] enableTristate + * false : Output data retains last value when PCS is negated + * true : Output data is tristate when PCS is negated + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetOutCfg(SpiRegType *obj, bool enableTristate) +{ + uint32_t tRegValue = obj->CFGR1; + + if(enableTristate == true) + { + obj->CFGR1 = ((1ul << SPI_CFGR1_OUT_CFG_SHIFT) | ((~SPI_CFGR1_OUT_CFG_MASK) & tRegValue)); + } + else + { + obj->CFGR1 = ((0ul << SPI_CFGR1_OUT_CFG_SHIFT) | ((~SPI_CFGR1_OUT_CFG_MASK) & tRegValue)); + } +} + +/*! \brief Pin Configuration + * + * Configures which pins are used for input and output data during serial transfers. + * + * \param[in] obj: base address for the SPI instance + * \param[in] pin_cfg + * 00b : SIN is used for input data and SOUT is used for output data + * 01b : SIN is used for both input and output data, only half-duplex serial transfers are supported + * 10b : SOUT is used for both input and output data, only half-duplex serial transfers are supported + * 11b : SOUT is used for input data and SIN is used for output data + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetPinCfg(SpiRegType *obj, uint8_t pin_cfg) +{ + uint32_t tmp = obj->CFGR1; + + tmp &= ~SPI_CFGR1_PIN_CFG_MASK; + tmp |= (((uint32_t)(((uint32_t)(pin_cfg)) << SPI_CFGR1_PIN_CFG_SHIFT)) & SPI_CFGR1_PIN_CFG_MASK); + obj->CFGR1 = tmp; +} + +/*! \brief Peripheral Chip Select Polarity + * + * Configures the polarity of each Peripheral Chip Select pin. Each PCS_POL bit position corresponds to a PCS[n] pin. + * + * \param[in] obj: base address for the SPI instance + * \param[in] polarity + * 0b: the PCS[n] pin is active low. + * 1b: the PCS[n] pin is active high. + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetPcsPolarity(SpiRegType *obj, uint8_t polarity) +{ + uint32_t tmp = obj->CFGR1; + + tmp &= ~SPI_CFGR1_PCS_POL_MASK; + tmp |= (((uint32_t)(((uint32_t)(polarity)) << SPI_CFGR1_PCS_POL_SHIFT)) & SPI_CFGR1_PCS_POL_MASK); + obj->CFGR1 = tmp; +} + +/*! \brief Set master sck delay + * + * this function set the sck delay ticks + * + * \param[in] obj: base address for the SPI instance + * \param[in] delaytick: delay tick + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetMstSckDelay(SpiRegType *obj, uint8_t delaytick) +{ + uint32_t tmp = obj->CFGR1; + + tmp &= ~SPI_CFGR1_MST_SCK_DLY_MASK; + tmp |= (((uint32_t)(((uint32_t)(delaytick)) << SPI_CFGR1_MST_SCK_DLY_SHIFT)) & SPI_CFGR1_MST_SCK_DLY_MASK); + obj->CFGR1 = tmp; +} + +/*! \brief Master mode No Stall enable or disable + * + * In master mode, the SPI will stall transfers when the transmit FIFO is empty, + * ensuring that no transmit FIFO underrun can occur. Setting the No Stall bit will disable this functionality. + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable + * 0b : Transfers will stall when the transmit FIFO is empty + * 1b : Transfers will not stall, allowing transmit FIFO underruns to occur + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetNoStallMode(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->CFGR1; + + if(enable == true) + { + obj->CFGR1 = ((1ul << SPI_CFGR1_NO_STALL_SHIFT) | ((~SPI_CFGR1_NO_STALL_MASK) & tRegValue)); + } + else + { + obj->CFGR1 = ((0ul << SPI_CFGR1_NO_STALL_SHIFT) | ((~SPI_CFGR1_NO_STALL_MASK) & tRegValue)); + } +} + +/*! \brief Automatic PCS enable or disable in slave mode + * + * The module normally requires the PCS to negate between frames. Setting this bit will cause the module to generate an internal PCS signal + * at the end of each transfer word when the Clock Phase bit TCR[CPHA] = 1. + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: Automatic PCS in slave mode + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetAutoCS(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->CFGR1; + + if(enable == true) + { + obj->CFGR1 = ((1ul << SPI_CFGR1_AUTO_PCS_SHIFT) | ((~SPI_CFGR1_AUTO_PCS_MASK) & tRegValue)); + } + else + { + obj->CFGR1 = ((0ul << SPI_CFGR1_AUTO_PCS_SHIFT) | ((~SPI_CFGR1_AUTO_PCS_MASK) & tRegValue)); + } +} + +/*! \brief Configures the module in master or slave mode + * + * this function set the node word mode in master or slave + * + * \param[in] obj: base address for the SPI instance + * \param[in] ismaster: + * false:as slave + * true: as master + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetNodeMode(SpiRegType *obj, bool ismaster) +{ + uint32_t tRegValue = obj->CFGR1; + + if(ismaster == true) + { + obj->CFGR1 = ((1ul << SPI_CFGR1_MASTER_EN_SHIFT) | ((~SPI_CFGR1_MASTER_EN_MASK) & tRegValue)); + } + else + { + obj->CFGR1 = ((0ul << SPI_CFGR1_MASTER_EN_SHIFT) | ((~SPI_CFGR1_MASTER_EN_MASK) & tRegValue)); + } +} + +/*! \brief Get the module in master or slave mode + * + * + * + * \param[in] obj : base address for the SPI instance + * \return bool + * false: is slave node + * true: is master node + */ +__attribute__((always_inline)) static inline bool SpiReg_GetNodeMasterState(const SpiRegType *obj) +{ + bool tRtn = false; + + if((obj->CFGR1 & SPI_CFGR1_MASTER_EN_MASK) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief configures the delay from the last SCK edge to the PCS negation + * + * The delay is equal to (SCKPCS + 1) cycles of the SPI functional clock divided by the Prescaler Value TCR[PRESCALE] configuration. + * The minimum delay is 1 cycle. + * + * \param[in] obj: base address for the SPI instance + * \param[in] delaytick: SCK-to-PCS Delay + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetDelaySckToPcs(SpiRegType *obj, uint8_t delaytick) +{ + uint32_t tmp = obj->CCR; + + tmp &= ~SPI_CCR_SCK_PCS_MASK; + tmp |= (((uint32_t)(((uint32_t)(delaytick)) << SPI_CCR_SCK_PCS_SHIFT)) & SPI_CCR_SCK_PCS_MASK); + obj->CCR = tmp; +} + +/*! \brief configures the delay from the PCS assertion to the first SCK edge. + * + * The delay is equal to (PCSSCK + 1) cycles of the SPI functional clock divided by the Prescaler Value TCR[PRESCALE] configuration + * The minimum delay is 1 cycle. + * + * \param[in] obj: base address for the SPI instance + * \param[in] delaytick: PCS-to-SCK Delay + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetDelayPcsToSck(SpiRegType *obj, uint8_t delaytick) +{ + uint32_t tmp = obj->CCR; + + tmp &= ~SPI_CCR_PCS_SCK_MASK; + tmp |= (((uint32_t)(((uint32_t)(delaytick)) << SPI_CCR_PCS_SCK_SHIFT)) & SPI_CCR_PCS_SCK_MASK); + obj->CCR = tmp; +} + +/*! \brief Configures the delay from the PCS negation to the next PCS assertion. + * + * The delay is equal to (DBT + 2) cycles of the SPI functional clock divided by the Prescaler. + * The minimum delay is 2 cycles. + * + * \param[in] obj: base address for the SPI instance + * \param[in] delaytick: Delay Between Transfers + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetDelayDBT(SpiRegType *obj, uint8_t delaytick) +{ + uint32_t tmp = obj->CCR; + + tmp &= ~SPI_CCR_DBT_MASK; + tmp |= (((uint32_t)(((uint32_t)(delaytick)) << SPI_CCR_DBT_SHIFT)) & SPI_CCR_DBT_MASK); + obj->CCR = tmp; +} + +/*! \brief the SCK Divider configures the divide ratio of the SCK pin + * + * The SCK period is equal to (SCKDIV+2) cycles of the SPI functional clock divided by the Prescaler Value TCR[PRESCALE] configuration. + * The minimum SCK period is 2 cycles. + * + * \param[in] obj: base address for the SPI instance + * \param[in] sckdiv: SCK Divider + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetSckDiv(SpiRegType *obj, uint8_t sckdiv) +{ + uint32_t tmp = obj->CCR; + + tmp &= ~SPI_CCR_SCK_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(sckdiv)) << SPI_CCR_SCK_DIV_SHIFT)) & SPI_CCR_SCK_DIV_MASK); + obj->CCR = tmp; +} + +/*! \brief Transmit FIFO water mark + * + * The Transmit Data Flag is set whenever the number of words in the transmit FIFO is equal or less than TX_WATER + * + * \param[in] obj: base address for the SPI instance + * \param[in] txWaterMark: Transmit FIFO water mark + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetTxFifoWaterMark(SpiRegType *obj, uint8_t txWaterMark) +{ + uint32_t tmp = obj->FCR; + + tmp &= ~SPI_FCR_TX_FIFO_WATER_MASK; + tmp |= (((uint32_t)(((uint32_t)(txWaterMark)) << SPI_FCR_TX_FIFO_WATER_SHIFT)) & SPI_FCR_TX_FIFO_WATER_MASK); + obj->FCR = tmp; +} + +/*! \brief Get Tx FIFO water mark + * + * this function get the tx fifo water mark + * + * \param[in] obj: base address for the SPI instance + * \return: return tx fifo water mark value + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetTxFifoWaterMark(const SpiRegType *obj) +{ + uint8_t tTxWaterMark = 0; + + tTxWaterMark = ((obj->FCR & SPI_FCR_TX_FIFO_WATER_MASK) >> SPI_FCR_TX_FIFO_WATER_SHIFT); + + return tTxWaterMark; +} + +/*! \brief Receive FIFO Watermark + * + * The Receive Data Flag is set whenever the number of words in the receive FIFO is greater than RX_WATER + * + * \param[in] obj: base address for the SPI instance + * \param[in] rxWaterMark: Receive FIFO Watermark + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetRxFifoWaterMark(SpiRegType *obj, uint8_t rxWaterMark) +{ + uint32_t tmp = obj->FCR; + + tmp &= ~SPI_FCR_RX_FIFO_WATER_MASK; + tmp |= (((uint32_t)(((uint32_t)(rxWaterMark)) << SPI_FCR_RX_FIFO_WATER_SHIFT)) & SPI_FCR_RX_FIFO_WATER_MASK); + obj->FCR = tmp; +} + +/*! \brief Get Rx FIFO water mark + * + * this function get the rx fifo water mark + * + * \param[in] obj: base address for the SPI instance + * \return: return rx fifo water mark value + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetRxFifoWaterMark(const SpiRegType *obj) +{ + uint8_t tRxWaterMark = 0; + + tRxWaterMark = ((obj->FCR & SPI_FCR_RX_FIFO_WATER_MASK) >> SPI_FCR_RX_FIFO_WATER_SHIFT); + + return tRxWaterMark; +} + +/*! \brief Transmit FIFO Count + * + * Returns the number of words currently stored in the transmit FIFO. + * + * \param[in] obj: base address for the SPI instance + * \return: uint8_t: return tx fifo counter value + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetTxFifoCounter(const SpiRegType *obj) +{ + uint8_t tTxFifoCnt = 0; + + tTxFifoCnt = ((obj->FSR & SPI_FSR_TX_FIFO_CNT_MASK) >> SPI_FSR_TX_FIFO_CNT_SHIFT); + + return tTxFifoCnt; +} + +/*! \brief Receive FIFO Count + * + * Returns the number of words currently stored in the receive FIFO. + * + * \param[in] obj: base address for the SPI instance + * \return: return received rx fifo counter value + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetRxFifoCounter(const SpiRegType *obj) +{ + uint8_t tRxFifoCnt = 0; + + tRxFifoCnt = ((obj->FSR & SPI_FSR_RX_FIFO_CNT_MASK) >> SPI_FSR_RX_FIFO_CNT_SHIFT); + + return tRxFifoCnt; +} + +/*! \brief Set TX FIFO data + * + * this function is write data to hardware fifo + * + * \param[in] obj: base address for the SPI instance + * \param[in] dat: TX FIFO data + */ +__attribute__((always_inline)) static inline void SpiReg_SetTxFifoData(SpiRegType *obj, uint32_t dat) +{ + obj->TDR = dat; +} + +/*! \brief Get RX FIFO data + * + * this function read out the received data from hardware fifo + * + * \param[in] obj: base address for the SPI instance + * \return: RX FIFO data + */ +__attribute__((always_inline)) static inline uint32_t SpiReg_GetRxFiFoData(const SpiRegType *obj) +{ + return obj->RDR; +} + +/*! \brief RX FIFO Empty status + * + * this function get the current rx fifo status + * + * \param[in] obj: base address for the SPI instance + * \return: RX FIFO Empty status + * false:RX FIFO is not empty + * true:RX FIFO is empty + */ +__attribute__((always_inline)) static inline bool SpiReg_GetRxFifoEmptyState(const SpiRegType *obj) +{ + bool tRtn = false; + + if(((obj->RSR & SPI_RSR_RX_FIFO_EMPTY_MASK) >> SPI_RSR_RX_FIFO_EMPTY_SHIFT) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief Indicates that this is the first data word received after PCS assertion. + * + * this function get the current received data that is the first time to received + * + * \param[in] obj: base address for the SPI instance + * \return: the first data word received + * false:The first word after PCS assertion is read by software or has no data after PCS assertion. + * true:receive the first word after PCS assertion + */ +__attribute__((always_inline)) static inline bool SpiReg_GetStartOfFrameIndicate(const SpiRegType *obj) +{ + bool tRtn = false; + + if(((obj->RSR & SPI_RSR_SOF_MASK) >> SPI_RSR_SOF_SHIFT) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _SPI_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/trgmux_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/trgmux_reg.h new file mode 100644 index 0000000..129749b --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/trgmux_reg.h @@ -0,0 +1,1351 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _TRGMUX_REG_H_ +#define _TRGMUX_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the TRGMUX Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* DMAMUX0 Bit Fields */ +#define TRGMUX_DMAMUX0_LK_MASK (0x80000000u) +#define TRGMUX_DMAMUX0_LK_SHIFT (31u) +#define TRGMUX_DMAMUX0_LK_WIDTH (1u) +#define TRGMUX_DMAMUX0_SEL3_MASK (0x7F000000u) +#define TRGMUX_DMAMUX0_SEL3_SHIFT (24u) +#define TRGMUX_DMAMUX0_SEL3_WIDTH (7u) +#define TRGMUX_DMAMUX0_SEL2_MASK (0x7F0000u) +#define TRGMUX_DMAMUX0_SEL2_SHIFT (16u) +#define TRGMUX_DMAMUX0_SEL2_WIDTH (7u) +#define TRGMUX_DMAMUX0_SEL1_MASK (0x7F00u) +#define TRGMUX_DMAMUX0_SEL1_SHIFT (8u) +#define TRGMUX_DMAMUX0_SEL1_WIDTH (7u) +#define TRGMUX_DMAMUX0_SEL0_MASK (0x7Fu) +#define TRGMUX_DMAMUX0_SEL0_SHIFT (0u) +#define TRGMUX_DMAMUX0_SEL0_WIDTH (7u) + +/* EXTOUT0 Bit Fields */ +#define TRGMUX_EXTOUT0_LK_MASK (0x80000000u) +#define TRGMUX_EXTOUT0_LK_SHIFT (31u) +#define TRGMUX_EXTOUT0_LK_WIDTH (1u) +#define TRGMUX_EXTOUT0_SEL3_MASK (0x7F000000u) +#define TRGMUX_EXTOUT0_SEL3_SHIFT (24u) +#define TRGMUX_EXTOUT0_SEL3_WIDTH (7u) +#define TRGMUX_EXTOUT0_SEL2_MASK (0x7F0000u) +#define TRGMUX_EXTOUT0_SEL2_SHIFT (16u) +#define TRGMUX_EXTOUT0_SEL2_WIDTH (7u) +#define TRGMUX_EXTOUT0_SEL1_MASK (0x7F00u) +#define TRGMUX_EXTOUT0_SEL1_SHIFT (8u) +#define TRGMUX_EXTOUT0_SEL1_WIDTH (7u) +#define TRGMUX_EXTOUT0_SEL0_MASK (0x7Fu) +#define TRGMUX_EXTOUT0_SEL0_SHIFT (0u) +#define TRGMUX_EXTOUT0_SEL0_WIDTH (7u) + +/* ADC Bit Fields */ +#define TRGMUX_ADC_LK_MASK (0x80000000u) +#define TRGMUX_ADC_LK_SHIFT (31u) +#define TRGMUX_ADC_LK_WIDTH (1u) +#define TRGMUX_ADC_SEL3_MASK (0x7F000000u) +#define TRGMUX_ADC_SEL3_SHIFT (24u) +#define TRGMUX_ADC_SEL3_WIDTH (7u) +#define TRGMUX_ADC_SEL2_MASK (0x7F0000u) +#define TRGMUX_ADC_SEL2_SHIFT (16u) +#define TRGMUX_ADC_SEL2_WIDTH (7u) +#define TRGMUX_ADC_SEL1_MASK (0x7F00u) +#define TRGMUX_ADC_SEL1_SHIFT (8u) +#define TRGMUX_ADC_SEL1_WIDTH (7u) +#define TRGMUX_ADC_SEL0_MASK (0x7Fu) +#define TRGMUX_ADC_SEL0_SHIFT (0u) +#define TRGMUX_ADC_SEL0_WIDTH (7u) + +/* CMP Bit Fields */ +#define TRGMUX_CMP_LK_MASK (0x80000000u) +#define TRGMUX_CMP_LK_SHIFT (31u) +#define TRGMUX_CMP_LK_WIDTH (1u) +#define TRGMUX_CMP_SEL0_MASK (0x7Fu) +#define TRGMUX_CMP_SEL0_SHIFT (0u) +#define TRGMUX_CMP_SEL0_WIDTH (7u) + +/* MFT0 Bit Fields */ +#define TRGMUX_MFT0_LK_MASK (0x80000000u) +#define TRGMUX_MFT0_LK_SHIFT (31u) +#define TRGMUX_MFT0_LK_WIDTH (1u) +#define TRGMUX_MFT0_SEL3_MASK (0x7F000000u) +#define TRGMUX_MFT0_SEL3_SHIFT (24u) +#define TRGMUX_MFT0_SEL3_WIDTH (7u) +#define TRGMUX_MFT0_SEL2_MASK (0x7F0000u) +#define TRGMUX_MFT0_SEL2_SHIFT (16u) +#define TRGMUX_MFT0_SEL2_WIDTH (7u) +#define TRGMUX_MFT0_SEL1_MASK (0x7F00u) +#define TRGMUX_MFT0_SEL1_SHIFT (8u) +#define TRGMUX_MFT0_SEL1_WIDTH (7u) +#define TRGMUX_MFT0_SEL0_MASK (0x7Fu) +#define TRGMUX_MFT0_SEL0_SHIFT (0u) +#define TRGMUX_MFT0_SEL0_WIDTH (7u) + +/* MFT1 Bit Fields */ +#define TRGMUX_MFT1_LK_MASK (0x80000000u) +#define TRGMUX_MFT1_LK_SHIFT (31u) +#define TRGMUX_MFT1_LK_WIDTH (1u) +#define TRGMUX_MFT1_SEL3_MASK (0x7F000000u) +#define TRGMUX_MFT1_SEL3_SHIFT (24u) +#define TRGMUX_MFT1_SEL3_WIDTH (7u) +#define TRGMUX_MFT1_SEL2_MASK (0x7F0000u) +#define TRGMUX_MFT1_SEL2_SHIFT (16u) +#define TRGMUX_MFT1_SEL2_WIDTH (7u) +#define TRGMUX_MFT1_SEL1_MASK (0x7F00u) +#define TRGMUX_MFT1_SEL1_SHIFT (8u) +#define TRGMUX_MFT1_SEL1_WIDTH (7u) +#define TRGMUX_MFT1_SEL0_MASK (0x7Fu) +#define TRGMUX_MFT1_SEL0_SHIFT (0u) +#define TRGMUX_MFT1_SEL0_WIDTH (7u) + +/* PDB Bit Fields */ +#define TRGMUX_PDB_LK_MASK (0x80000000u) +#define TRGMUX_PDB_LK_SHIFT (31u) +#define TRGMUX_PDB_LK_WIDTH (1u) +#define TRGMUX_PDB_SEL0_MASK (0x7Fu) +#define TRGMUX_PDB_SEL0_SHIFT (0u) +#define TRGMUX_PDB_SEL0_WIDTH (7u) + +/* LPIT Bit Fields */ +#define TRGMUX_LPIT_LK_MASK (0x80000000u) +#define TRGMUX_LPIT_LK_SHIFT (31u) +#define TRGMUX_LPIT_LK_WIDTH (1u) +#define TRGMUX_LPIT_SEL3_MASK (0x7F000000u) +#define TRGMUX_LPIT_SEL3_SHIFT (24u) +#define TRGMUX_LPIT_SEL3_WIDTH (7u) +#define TRGMUX_LPIT_SEL2_MASK (0x7F0000u) +#define TRGMUX_LPIT_SEL2_SHIFT (16u) +#define TRGMUX_LPIT_SEL2_WIDTH (7u) +#define TRGMUX_LPIT_SEL1_MASK (0x7F00u) +#define TRGMUX_LPIT_SEL1_SHIFT (8u) +#define TRGMUX_LPIT_SEL1_WIDTH (7u) +#define TRGMUX_LPIT_SEL0_MASK (0x7Fu) +#define TRGMUX_LPIT_SEL0_SHIFT (0u) +#define TRGMUX_LPIT_SEL0_WIDTH (7u) + +/* LPTMR Bit Fields */ +#define TRGMUX_LPTMR_LK_MASK (0x80000000u) +#define TRGMUX_LPTMR_LK_SHIFT (31u) +#define TRGMUX_LPTMR_LK_WIDTH (1u) +#define TRGMUX_LPTMR_SEL0_MASK (0x7Fu) +#define TRGMUX_LPTMR_SEL0_SHIFT (0u) +#define TRGMUX_LPTMR_SEL0_WIDTH (7u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of TRGMUX registers + */ +typedef struct _TrgMuxRegType_ +{ + volatile uint32_t DMAMUX0; /*!< TRGMUX DMAMUX0 register, offset: 0x0 */ + volatile uint32_t EXTOUT0; /*!< TRGMUX EXTOUT0 register, offset: 0x4 */ + uint32_t RESERVED0[1]; /*!< Reserverd block, offset: 0x08 */ + volatile uint32_t ADC; /*!< TRGMUX ADC register, offset: 0x0C */ + uint32_t RESERVED1[1]; /*!< Reserverd block, offset: 0x10 */ + volatile uint32_t CMP; /*!< TRGMUX CMP register, offset: 0x014 */ + volatile uint32_t MFT0; /*!< TRGMUX MFT0 register, offset: 0x18 */ + volatile uint32_t MFT1; /*!< TRGMUX MFT1 register, offset: 0x1C */ + uint32_t RESERVED2[2]; /*!< Reserverd block, offset: 0x20 */ + volatile uint32_t PDB; /*!< TRGMUX PDB register, offset: 0x28 */ + uint32_t RESERVED3[1]; /*!< Reserverd block, offset: 0x2C */ + volatile uint32_t LPIT; /*!< TRGMUX LPIT register, offset: 0x30 */ + volatile uint32_t LPTMR; /*!< TRGMUX LPTMR register, offset: 0x34 */ +} TrgMuxRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the TRGMUX DMAMUX0 register lock + * + * This function gets the current TRGMUX DMAMUX0 register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \return TRGMUX DMAMUX0 register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetDmaMux0Lk(const TrgMuxRegType *obj) +{ + return ((obj->DMAMUX0 & TRGMUX_DMAMUX0_LK_MASK) >> TRGMUX_DMAMUX0_LK_SHIFT); +} + +/*! \brief Sets the TRGMUX DMAMUX0 register lock + * + * This function sets the TRGMUX DMAMUX0 register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of TRGMUX DMAMUX0 register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetDmaMux0Lk(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DMAMUX0; + + tmp &= ~TRGMUX_DMAMUX0_LK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_DMAMUX0_LK_SHIFT)) & TRGMUX_DMAMUX0_LK_MASK); + obj->DMAMUX0 = tmp; +} + +/*! \brief Gets the Selected source for output 3 of this module + * + * This function gets the current Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetDmaMux0Sel3(const TrgMuxRegType *obj) +{ + return ((obj->DMAMUX0 & TRGMUX_DMAMUX0_SEL3_MASK) >> TRGMUX_DMAMUX0_SEL3_SHIFT); +} + +/*! \brief Sets the Selected source for output 3 of this module + * + * This function sets the Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetDmaMux0Sel3(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DMAMUX0; + + tmp &= ~TRGMUX_DMAMUX0_SEL3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_DMAMUX0_SEL3_SHIFT)) & TRGMUX_DMAMUX0_SEL3_MASK); + obj->DMAMUX0 = tmp; +} + +/*! \brief Gets the Selected source for output 2 of this module + * + * This function gets the current Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetDmaMux0Sel2(const TrgMuxRegType *obj) +{ + return ((obj->DMAMUX0 & TRGMUX_DMAMUX0_SEL2_MASK) >> TRGMUX_DMAMUX0_SEL2_SHIFT); +} + +/*! \brief Sets the Selected source for output 2 of this module + * + * This function sets the Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetDmaMux0Sel2(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DMAMUX0; + + tmp &= ~TRGMUX_DMAMUX0_SEL2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_DMAMUX0_SEL2_SHIFT)) & TRGMUX_DMAMUX0_SEL2_MASK); + obj->DMAMUX0 = tmp; +} + +/*! \brief Gets the Selected source for output 1 of this module + * + * This function gets the current Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetDmaMux0Sel1(const TrgMuxRegType *obj) +{ + return ((obj->DMAMUX0 & TRGMUX_DMAMUX0_SEL1_MASK) >> TRGMUX_DMAMUX0_SEL1_SHIFT); +} + +/*! \brief Sets the Selected source for output 1 of this module + * + * This function sets the Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetDmaMux0Sel1(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DMAMUX0; + + tmp &= ~TRGMUX_DMAMUX0_SEL1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_DMAMUX0_SEL1_SHIFT)) & TRGMUX_DMAMUX0_SEL1_MASK); + obj->DMAMUX0 = tmp; +} + +/*! \brief Gets the Selected source for output 0 of this module + * + * This function gets the current Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetDmaMux0Sel0(const TrgMuxRegType *obj) +{ + return ((obj->DMAMUX0 & TRGMUX_DMAMUX0_SEL0_MASK) >> TRGMUX_DMAMUX0_SEL0_SHIFT); +} + +/*! \brief Sets the Selected source for output 0 of this module + * + * This function sets the Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetDmaMux0Sel0(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DMAMUX0; + + tmp &= ~TRGMUX_DMAMUX0_SEL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_DMAMUX0_SEL0_SHIFT)) & TRGMUX_DMAMUX0_SEL0_MASK); + obj->DMAMUX0 = tmp; +} + +/*! \brief Gets the TRGMUX EXTOUT0 register lock + * + * This function gets the current TRGMUX EXTOUT0 register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \return TRGMUX EXTOUT0 register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetExtOut0Lk(const TrgMuxRegType *obj) +{ + return ((obj->EXTOUT0 & TRGMUX_EXTOUT0_LK_MASK) >> TRGMUX_EXTOUT0_LK_SHIFT); +} + +/*! \brief Sets the TRGMUX EXTOUT0 register lock + * + * This function sets the TRGMUX EXTOUT0 register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of TRGMUX EXTOUT0 register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetExtOut0Lk(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTOUT0; + + tmp &= ~TRGMUX_EXTOUT0_LK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_EXTOUT0_LK_SHIFT)) & TRGMUX_EXTOUT0_LK_MASK); + obj->EXTOUT0 = tmp; +} + +/*! \brief Gets the Selected source for output 3 of this module + * + * This function gets the current Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetExtOut0Sel3(const TrgMuxRegType *obj) +{ + return ((obj->EXTOUT0 & TRGMUX_EXTOUT0_SEL3_MASK) >> TRGMUX_EXTOUT0_SEL3_SHIFT); +} + +/*! \brief Sets the Selected source for output 3 of this module + * + * This function sets the Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetExtOut0Sel3(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTOUT0; + + tmp &= ~TRGMUX_EXTOUT0_SEL3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_EXTOUT0_SEL3_SHIFT)) & TRGMUX_EXTOUT0_SEL3_MASK); + obj->EXTOUT0 = tmp; +} + +/*! \brief Gets the Selected source for output 2 of this module + * + * This function gets the current Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetExtOut0Sel2(const TrgMuxRegType *obj) +{ + return ((obj->EXTOUT0 & TRGMUX_EXTOUT0_SEL2_MASK) >> TRGMUX_EXTOUT0_SEL2_SHIFT); +} + +/*! \brief Sets the Selected source for output 2 of this module + * + * This function sets the Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetExtOut0Sel2(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTOUT0; + + tmp &= ~TRGMUX_EXTOUT0_SEL2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_EXTOUT0_SEL2_SHIFT)) & TRGMUX_EXTOUT0_SEL2_MASK); + obj->EXTOUT0 = tmp; +} + +/*! \brief Gets the Selected source for output 1 of this module + * + * This function gets the current Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetExtOut0Sel1(const TrgMuxRegType *obj) +{ + return ((obj->EXTOUT0 & TRGMUX_EXTOUT0_SEL1_MASK) >> TRGMUX_EXTOUT0_SEL1_SHIFT); +} + +/*! \brief Sets the Selected source for output 1 of this module + * + * This function sets the Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetExtOut0Sel1(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTOUT0; + + tmp &= ~TRGMUX_EXTOUT0_SEL1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_EXTOUT0_SEL1_SHIFT)) & TRGMUX_EXTOUT0_SEL1_MASK); + obj->EXTOUT0 = tmp; +} + +/*! \brief Gets the Selected source for output 0 of this module + * + * This function gets the current Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetExtOut0Sel0(const TrgMuxRegType *obj) +{ + return ((obj->EXTOUT0 & TRGMUX_EXTOUT0_SEL0_MASK) >> TRGMUX_EXTOUT0_SEL0_SHIFT); +} + +/*! \brief Sets the Selected source for output 0 of this module + * + * This function sets the Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetExtOut0Sel0(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTOUT0; + + tmp &= ~TRGMUX_EXTOUT0_SEL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_EXTOUT0_SEL0_SHIFT)) & TRGMUX_EXTOUT0_SEL0_MASK); + obj->EXTOUT0 = tmp; +} + +/*! \brief Gets the TRGMUX ADC register lock + * + * This function gets the current TRGMUX ADC register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \return TRGMUX ADC register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetAdcLk(const TrgMuxRegType *obj) +{ + return ((obj->ADC & TRGMUX_ADC_LK_MASK) >> TRGMUX_ADC_LK_SHIFT); +} + +/*! \brief Sets the TRGMUX ADC register lock + * + * This function sets the TRGMUX ADC register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of TRGMUX ADC register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetAdcLk(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~TRGMUX_ADC_LK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_ADC_LK_SHIFT)) & TRGMUX_ADC_LK_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the Selected source for output 3 of this module + * + * This function gets the current Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetAdcSel3(const TrgMuxRegType *obj) +{ + return ((obj->ADC & TRGMUX_ADC_SEL3_MASK) >> TRGMUX_ADC_SEL3_SHIFT); +} + +/*! \brief Sets the Selected source for output 3 of this module + * + * This function sets the Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetAdcSel3(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~TRGMUX_ADC_SEL3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_ADC_SEL3_SHIFT)) & TRGMUX_ADC_SEL3_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the Selected source for output 2 of this module + * + * This function gets the current Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetAdcSel2(const TrgMuxRegType *obj) +{ + return ((obj->ADC & TRGMUX_ADC_SEL2_MASK) >> TRGMUX_ADC_SEL2_SHIFT); +} + +/*! \brief Sets the Selected source for output 2 of this module + * + * This function sets the Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetAdcSel2(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~TRGMUX_ADC_SEL2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_ADC_SEL2_SHIFT)) & TRGMUX_ADC_SEL2_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the Selected source for output 1 of this module + * + * This function gets the current Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetAdcSel1(const TrgMuxRegType *obj) +{ + return ((obj->ADC & TRGMUX_ADC_SEL1_MASK) >> TRGMUX_ADC_SEL1_SHIFT); +} + +/*! \brief Sets the Selected source for output 1 of this module + * + * This function sets the Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetAdcSel1(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~TRGMUX_ADC_SEL1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_ADC_SEL1_SHIFT)) & TRGMUX_ADC_SEL1_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the Selected source for output 0 of this module + * + * This function gets the current Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetAdcSel0(const TrgMuxRegType *obj) +{ + return ((obj->ADC & TRGMUX_ADC_SEL0_MASK) >> TRGMUX_ADC_SEL0_SHIFT); +} + +/*! \brief Sets the Selected source for output 0 of this module + * + * This function sets the Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetAdcSel0(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~TRGMUX_ADC_SEL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_ADC_SEL0_SHIFT)) & TRGMUX_ADC_SEL0_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the TRGMUX CMP register lock + * + * This function gets the current TRGMUX CMP register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \return TRGMUX CMP register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetCmpLk(const TrgMuxRegType *obj) +{ + return ((obj->CMP & TRGMUX_CMP_LK_MASK) >> TRGMUX_CMP_LK_SHIFT); +} + +/*! \brief Sets the TRGMUX CMP register lock + * + * This function sets the TRGMUX CMP register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of TRGMUX CMP register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetCmpLk(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CMP; + + tmp &= ~TRGMUX_CMP_LK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_CMP_LK_SHIFT)) & TRGMUX_CMP_LK_MASK); + obj->CMP = tmp; +} + +/*! \brief Gets the Selected source for output 0 of this module + * + * This function gets the current Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetCmpSel0(const TrgMuxRegType *obj) +{ + return ((obj->CMP & TRGMUX_CMP_SEL0_MASK) >> TRGMUX_CMP_SEL0_SHIFT); +} + +/*! \brief Sets the Selected source for output 0 of this module + * + * This function sets the Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetCmpSel0(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CMP; + + tmp &= ~TRGMUX_CMP_SEL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_CMP_SEL0_SHIFT)) & TRGMUX_CMP_SEL0_MASK); + obj->CMP = tmp; +} + +/*! \brief Gets the TRGMUX MFT0 register lock + * + * This function gets the current TRGMUX MFT0 register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \return TRGMUX MFT0 register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetMft0Lk(const TrgMuxRegType *obj) +{ + return ((obj->MFT0 & TRGMUX_MFT0_LK_MASK) >> TRGMUX_MFT0_LK_SHIFT); +} + +/*! \brief Sets the TRGMUX MFT0 register lock + * + * This function sets the TRGMUX MFT0 register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of TRGMUX MFT0 register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetMft0Lk(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT0; + + tmp &= ~TRGMUX_MFT0_LK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_MFT0_LK_SHIFT)) & TRGMUX_MFT0_LK_MASK); + obj->MFT0 = tmp; +} + +/*! \brief Gets the Selected source for output 3 of this module + * + * This function gets the current Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetMft0Sel3(const TrgMuxRegType *obj) +{ + return ((obj->MFT0 & TRGMUX_MFT0_SEL3_MASK) >> TRGMUX_MFT0_SEL3_SHIFT); +} + +/*! \brief Sets the Selected source for output 3 of this module + * + * This function sets the Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetMft0Sel3(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT0; + + tmp &= ~TRGMUX_MFT0_SEL3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_MFT0_SEL3_SHIFT)) & TRGMUX_MFT0_SEL3_MASK); + obj->MFT0 = tmp; +} + +/*! \brief Gets the Selected source for output 2 of this module + * + * This function gets the current Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetMft0Sel2(const TrgMuxRegType *obj) +{ + return ((obj->MFT0 & TRGMUX_MFT0_SEL2_MASK) >> TRGMUX_MFT0_SEL2_SHIFT); +} + +/*! \brief Sets the Selected source for output 2 of this module + * + * This function sets the Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetMft0Sel2(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT0; + + tmp &= ~TRGMUX_MFT0_SEL2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_MFT0_SEL2_SHIFT)) & TRGMUX_MFT0_SEL2_MASK); + obj->MFT0 = tmp; +} + +/*! \brief Gets the Selected source for output 1 of this module + * + * This function gets the current Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetMft0Sel1(const TrgMuxRegType *obj) +{ + return ((obj->MFT0 & TRGMUX_MFT0_SEL1_MASK) >> TRGMUX_MFT0_SEL1_SHIFT); +} + +/*! \brief Sets the Selected source for output 1 of this module + * + * This function sets the Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetMft0Sel1(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT0; + + tmp &= ~TRGMUX_MFT0_SEL1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_MFT0_SEL1_SHIFT)) & TRGMUX_MFT0_SEL1_MASK); + obj->MFT0 = tmp; +} + +/*! \brief Gets the Selected source for output 0 of this module + * + * This function gets the current Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetMft0Sel0(const TrgMuxRegType *obj) +{ + return ((obj->MFT0 & TRGMUX_MFT0_SEL0_MASK) >> TRGMUX_MFT0_SEL0_SHIFT); +} + +/*! \brief Sets the Selected source for output 0 of this module + * + * This function sets the Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetMft0Sel0(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT0; + + tmp &= ~TRGMUX_MFT0_SEL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_MFT0_SEL0_SHIFT)) & TRGMUX_MFT0_SEL0_MASK); + obj->MFT0 = tmp; +} + +/*! \brief Gets the TRGMUX MFT1 register lock + * + * This function gets the current TRGMUX MFT1 register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \return TRGMUX MFT1 register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetMft1Lk(const TrgMuxRegType *obj) +{ + return ((obj->MFT1 & TRGMUX_MFT1_LK_MASK) >> TRGMUX_MFT1_LK_SHIFT); +} + +/*! \brief Sets the TRGMUX MFT1 register lock + * + * This function sets the TRGMUX MFT1 register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of TRGMUX MFT1 register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetMft1Lk(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT1; + + tmp &= ~TRGMUX_MFT1_LK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_MFT1_LK_SHIFT)) & TRGMUX_MFT1_LK_MASK); + obj->MFT1 = tmp; +} + +/*! \brief Gets the Selected source for output 3 of this module + * + * This function gets the current Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetMft1Sel3(const TrgMuxRegType *obj) +{ + return ((obj->MFT1 & TRGMUX_MFT1_SEL3_MASK) >> TRGMUX_MFT1_SEL3_SHIFT); +} + +/*! \brief Sets the Selected source for output 3 of this module + * + * This function sets the Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetMft1Sel3(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT1; + + tmp &= ~TRGMUX_MFT1_SEL3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_MFT1_SEL3_SHIFT)) & TRGMUX_MFT1_SEL3_MASK); + obj->MFT1 = tmp; +} + +/*! \brief Gets the Selected source for output 2 of this module + * + * This function gets the current Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetMft1Sel2(const TrgMuxRegType *obj) +{ + return ((obj->MFT1 & TRGMUX_MFT1_SEL2_MASK) >> TRGMUX_MFT1_SEL2_SHIFT); +} + +/*! \brief Sets the Selected source for output 2 of this module + * + * This function sets the Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetMft1Sel2(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT1; + + tmp &= ~TRGMUX_MFT1_SEL2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_MFT1_SEL2_SHIFT)) & TRGMUX_MFT1_SEL2_MASK); + obj->MFT1 = tmp; +} + +/*! \brief Gets the Selected source for output 1 of this module + * + * This function gets the current Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetMft1Sel1(const TrgMuxRegType *obj) +{ + return ((obj->MFT1 & TRGMUX_MFT1_SEL1_MASK) >> TRGMUX_MFT1_SEL1_SHIFT); +} + +/*! \brief Sets the Selected source for output 1 of this module + * + * This function sets the Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetMft1Sel1(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT1; + + tmp &= ~TRGMUX_MFT1_SEL1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_MFT1_SEL1_SHIFT)) & TRGMUX_MFT1_SEL1_MASK); + obj->MFT1 = tmp; +} + +/*! \brief Gets the Selected source for output 0 of this module + * + * This function gets the current Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetMft1Sel0(const TrgMuxRegType *obj) +{ + return ((obj->MFT1 & TRGMUX_MFT1_SEL0_MASK) >> TRGMUX_MFT1_SEL0_SHIFT); +} + +/*! \brief Sets the Selected source for output 0 of this module + * + * This function sets the Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetMft1Sel0(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT1; + + tmp &= ~TRGMUX_MFT1_SEL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_MFT1_SEL0_SHIFT)) & TRGMUX_MFT1_SEL0_MASK); + obj->MFT1 = tmp; +} + +/*! \brief Gets the TRGMUX PDB register lock + * + * This function gets the current TRGMUX PDB register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \return TRGMUX PDB register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetPdbLk(const TrgMuxRegType *obj) +{ + return ((obj->PDB & TRGMUX_PDB_LK_MASK) >> TRGMUX_PDB_LK_SHIFT); +} + +/*! \brief Sets the TRGMUX PDB register lock + * + * This function sets the TRGMUX PDB register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of TRGMUX PDB register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetPdbLk(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PDB; + + tmp &= ~TRGMUX_PDB_LK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_PDB_LK_SHIFT)) & TRGMUX_PDB_LK_MASK); + obj->PDB = tmp; +} + +/*! \brief Gets the Selected source for output 0 of this module + * + * This function gets the current Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetPdbSel0(const TrgMuxRegType *obj) +{ + return ((obj->PDB & TRGMUX_PDB_SEL0_MASK) >> TRGMUX_PDB_SEL0_SHIFT); +} + +/*! \brief Sets the Selected source for output 0 of this module + * + * This function sets the Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetPdbSel0(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PDB; + + tmp &= ~TRGMUX_PDB_SEL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_PDB_SEL0_SHIFT)) & TRGMUX_PDB_SEL0_MASK); + obj->PDB = tmp; +} + +/*! \brief Gets the TRGMUX LPIT register lock + * + * This function gets the current TRGMUX LPIT register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \return TRGMUX LPIT register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetLpitLk(const TrgMuxRegType *obj) +{ + return ((obj->LPIT & TRGMUX_LPIT_LK_MASK) >> TRGMUX_LPIT_LK_SHIFT); +} + +/*! \brief Sets the TRGMUX LPIT register lock + * + * This function sets the TRGMUX LPIT register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of TRGMUX LPIT register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetLpitLk(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPIT; + + tmp &= ~TRGMUX_LPIT_LK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_LPIT_LK_SHIFT)) & TRGMUX_LPIT_LK_MASK); + obj->LPIT = tmp; +} + +/*! \brief Gets the Selected source for output 3 of this module + * + * This function gets the current Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetLpitSel3(const TrgMuxRegType *obj) +{ + return ((obj->LPIT & TRGMUX_LPIT_SEL3_MASK) >> TRGMUX_LPIT_SEL3_SHIFT); +} + +/*! \brief Sets the Selected source for output 3 of this module + * + * This function sets the Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetLpitSel3(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPIT; + + tmp &= ~TRGMUX_LPIT_SEL3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_LPIT_SEL3_SHIFT)) & TRGMUX_LPIT_SEL3_MASK); + obj->LPIT = tmp; +} + +/*! \brief Gets the Selected source for output 2 of this module + * + * This function gets the current Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetLpitSel2(const TrgMuxRegType *obj) +{ + return ((obj->LPIT & TRGMUX_LPIT_SEL2_MASK) >> TRGMUX_LPIT_SEL2_SHIFT); +} + +/*! \brief Sets the Selected source for output 2 of this module + * + * This function sets the Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetLpitSel2(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPIT; + + tmp &= ~TRGMUX_LPIT_SEL2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_LPIT_SEL2_SHIFT)) & TRGMUX_LPIT_SEL2_MASK); + obj->LPIT = tmp; +} + +/*! \brief Gets the Selected source for output 1 of this module + * + * This function gets the current Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetLpitSel1(const TrgMuxRegType *obj) +{ + return ((obj->LPIT & TRGMUX_LPIT_SEL1_MASK) >> TRGMUX_LPIT_SEL1_SHIFT); +} + +/*! \brief Sets the Selected source for output 1 of this module + * + * This function sets the Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetLpitSel1(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPIT; + + tmp &= ~TRGMUX_LPIT_SEL1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_LPIT_SEL1_SHIFT)) & TRGMUX_LPIT_SEL1_MASK); + obj->LPIT = tmp; +} + +/*! \brief Gets the Selected source for output 0 of this module + * + * This function gets the current Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetLpitSel0(const TrgMuxRegType *obj) +{ + return ((obj->LPIT & TRGMUX_LPIT_SEL0_MASK) >> TRGMUX_LPIT_SEL0_SHIFT); +} + +/*! \brief Sets the Selected source for output 0 of this module + * + * This function sets the Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetLpitSel0(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPIT; + + tmp &= ~TRGMUX_LPIT_SEL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_LPIT_SEL0_SHIFT)) & TRGMUX_LPIT_SEL0_MASK); + obj->LPIT = tmp; +} + +/*! \brief Gets the TRGMUX LPTMR register lock + * + * This function gets the current TRGMUX LPTMR register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \return TRGMUX LPTMR register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetLptmrLk(const TrgMuxRegType *obj) +{ + return ((obj->LPTMR & TRGMUX_LPTMR_LK_MASK) >> TRGMUX_LPTMR_LK_SHIFT); +} + +/*! \brief Sets the TRGMUX LPTMR register lock + * + * This function sets the TRGMUX LPTMR register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of TRGMUX LPTMR register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetLptmrLk(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPTMR; + + tmp &= ~TRGMUX_LPTMR_LK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_LPTMR_LK_SHIFT)) & TRGMUX_LPTMR_LK_MASK); + obj->LPTMR = tmp; +} + +/*! \brief Gets the Selected source for output 0 of this module + * + * This function gets the current Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetLptmrSel0(const TrgMuxRegType *obj) +{ + return ((obj->LPTMR & TRGMUX_LPTMR_SEL0_MASK) >> TRGMUX_LPTMR_SEL0_SHIFT); +} + +/*! \brief Sets the Selected source for output 0 of this module + * + * This function sets the Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetLptmrSel0(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPTMR; + + tmp &= ~TRGMUX_LPTMR_SEL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_LPTMR_SEL0_SHIFT)) & TRGMUX_LPTMR_SEL0_MASK); + obj->LPTMR = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _TRGMUX_REG_H_ */ diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/uart_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/uart_reg.h new file mode 100644 index 0000000..b6e46a8 --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/uart_reg.h @@ -0,0 +1,2398 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UART_REG_H_ +#define _UART_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of UART module + */ + +/****************************************************************************** + * the includes + *****************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * the defines + *****************************************************************************/ + +/* CR1 Bit fields */ +#define UART_CR1_UE_MASK (0x00000001ul) +#define UART_CR1_UE_SHIFT (0u) +#define UART_CR1_UE_WIDTH (1u) + +#define UART_CR1_RE_MASK (0x00000004ul) +#define UART_CR1_RE_SHIFT (2u) +#define UART_CR1_RE_WIDTH (1u) + +#define UART_CR1_TE_MASK (0x00000008ul) +#define UART_CR1_TE_SHIFT (3u) +#define UART_CR1_TE_WIDTH (1u) + +#define UART_CR1_IDLEIE_MASK (0x00000010ul) +#define UART_CR1_IDLEIE_SHIFT (4u) +#define UART_CR1_IDLEIE_WIDTH (1u) + +#define UART_CR1_RDRFIE_MASK (0x00000020ul) +#define UART_CR1_RDRFIE_SHIFT (5u) +#define UART_CR1_RDRFIE_WIDTH (1u) + +#define UART_CR1_TCIE_MASK (0x00000040ul) +#define UART_CR1_TCIE_SHIFT (6u) +#define UART_CR1_TCIE_WIDTH (1u) + +#define UART_CR1_TDREIE_MASK (0x00000080ul) +#define UART_CR1_TDREIE_SHIFT (7u) +#define UART_CR1_TDREIE_WIDTH (1u) + +#define UART_CR1_PEIE_MASK (0x00000100ul) +#define UART_CR1_PEIE_SHIFT (8u) +#define UART_CR1_PEIE_WIDTH (1u) + +#define UART_CR1_PS_MASK (0x00000200ul) +#define UART_CR1_PS_SHIFT (9u) +#define UART_CR1_PS_WIDTH (1u) + +#define UART_CR1_PCE_MASK (0x00000400ul) +#define UART_CR1_PCE_SHIFT (10u) +#define UART_CR1_PCE_WIDTH (1u) + +#define UART_CR1_WAKE_MASK (0x00000800ul) +#define UART_CR1_WAKE_IDLE_LINE (0x00000000ul) +#define UART_CR1_WAKE_ADDR_MARK (0x00000800ul) +#define UART_CR1_WAKE_SHIFT (11u) +#define UART_CR1_WAKE_WIDTH (1u) + +#define UART_CR1_M_MASK (0x00001000ul) +#define UART_CR1_M_8BITS (0x00000000ul) +#define UART_CR1_M_9BITS (0x00001000ul) +#define UART_CR1_M_SHIFT (12u) +#define UART_CR1_M_WIDTH (1u) + +#define UART_CR1_MME_MASK (0x00002000ul) +#define UART_CR1_MME_SHIFT (13u) +#define UART_CR1_MME_WIDTH (1u) + +#define UART_CR1_SBRKDIE_MASK (0x00004000ul) +#define UART_CR1_SBRKDIE_SHIFT (14u) +#define UART_CR1_SBRKDIE_WIDTH (1u) + +#define UART_CR1_OVER8_MASK (0x00008000ul) +#define UART_CR1_OVER8_SHIFT (15u) +#define UART_CR1_OVER8_WIDTH (1u) + +#define UART_CR1_DEDT_MASK (0x001F0000ul) +#define UART_CR1_DEDT_SHIFT (16u) +#define UART_CR1_DEDT_WIDTH (5u) + +#define UART_CR1_DEAT_MASK (0x01F00000ul) +#define UART_CR1_DEAT_SHIFT (21u) +#define UART_CR1_DEAT_WIDTH (5u) + +#define UART_CR1_RTOIE_MASK (0x04000000ul) +#define UART_CR1_RTOIE_SHIFT (26u) +#define UART_CR1_RTOIE_WIDTH (1u) + +/* CR2 Bit fields */ +#define UART_CR2_SBRK_LEN_MASK (0x00000003ul) +#define UART_CR2_SBRK_LEN_13BITS (0x00000000ul) +#define UART_CR2_SBRK_LEN_14BITS (0x00000001ul) +#define UART_CR2_SBRK_LEN_15BITS (0x00000002ul) +#define UART_CR2_SBRK_LEN_SHIFT (0u) +#define UART_CR2_SBRK_LEN_WIDTH (2u) + +#define UART_CR2_SDEL_LEN_MASK (0x00000004ul) +#define UART_CR2_SDEL_LEN_1BITS (0x00000000ul) +#define UART_CR2_SDEL_LEN_2BITS (0x00000004ul) +#define UART_CR2_SDEL_LEN_SHIFT (2u) +#define UART_CR2_SDEL_LEN_WIDTH (1u) + +#define UART_CR2_ADDM_MASK (0x00000010ul) +#define UART_CR2_ADDM_4BITS (0x00000000ul) +#define UART_CR2_ADDM_7BITS (0x00000010ul) +#define UART_CR2_ADDM_SHIFT (4u) +#define UART_CR2_ADDM_WIDTH (1u) + +#define UART_CR2_LBDL_MASK (0x00000060ul) +#define UART_CR2_LBDL_11BITS (0x00000000ul) +#define UART_CR2_LBDL_12BITS (0x00000020ul) +#define UART_CR2_LBDL_13BITS (0x00000040ul) +#define UART_CR2_LBDL_SHIFT (5u) +#define UART_CR2_LBDL_WIDTH (2u) + +#define UART_CR2_LBDTIE_MASK (0x00000080ul) +#define UART_CR2_LBDTIE_SHIFT (7u) +#define UART_CR2_LBDTIE_WIDTH (1u) + +#define UART_CR2_IDLECFG_MASK (0x00000700ul) +#define UART_CR2_IDLECFG_1DILE_CHAR (0x00000000ul) +#define UART_CR2_IDLECFG_2DILE_CHAR (0x00000100ul) +#define UART_CR2_IDLECFG_4DILE_CHAR (0x00000200ul) +#define UART_CR2_IDLECFG_8DILE_CHAR (0x00000300ul) +#define UART_CR2_IDLECFG_16DILE_CHAR (0x00000400ul) +#define UART_CR2_IDLECFG_32DILE_CHAR (0x00000500ul) +#define UART_CR2_IDLECFG_64DILE_CHAR (0x00000600ul) +#define UART_CR2_IDLECFG_128DILE_CHAR (0x00000700ul) +#define UART_CR2_IDLECFG_SHIFT (8u) +#define UART_CR2_IDLECFG_WIDTH (3u) + +#define UART_CR2_STOP_MASK (0x00002000ul) +#define UART_CR2_STOP_SHIFT (13u) +#define UART_CR2_STOP_WIDTH (1u) + +#define UART_CR2_LINEN_MASK (0x00004000ul) +#define UART_CR2_LINEN_SHIFT (14u) +#define UART_CR2_LINEN_WIDTH (1u) + +#define UART_CR2_RXINV_MASK (0x00010000ul) +#define UART_CR2_RXINV_SHIFT (16u) +#define UART_CR2_RXINV_WIDTH (1u) + +#define UART_CR2_TXINV_MASK (0x00020000ul) +#define UART_CR2_TXINV_SHIFT (17u) +#define UART_CR2_TXINV_WIDTH (1u) + +#define UART_CR2_DATAINV_MASK (0x00040000ul) +#define UART_CR2_DATAINV_SHIFT (18u) +#define UART_CR2_DATAINV_WIDTH (1u) + +#define UART_CR2_MSBFIRST_MASK (0x00080000ul) +#define UART_CR2_MSBFIRST_SHIFT (19u) +#define UART_CR2_MSBFIRST_WIDTH (1u) + +#define UART_CR2_ABREN_MASK (0x00100000ul) +#define UART_CR2_ABREN_SHIFT (20u) +#define UART_CR2_ABREN_WIDTH (1u) + +#define UART_CR2_ABRMOD_MASK (0x00600000ul) +#define UART_CR2_ABRMOD_SHIFT (21u) +#define UART_CR2_ABRMOD_WIDTH (2u) + +#define UART_CR2_RTOEN_MASK (0x00800000ul) +#define UART_CR2_RTOEN_SHIFT (23u) +#define UART_CR2_RTOEN_WIDTH (1u) + +#define UART_CR2_ADD_MASK (0xFF000000ul) +#define UART_CR2_ADD_SHIFT (24u) +#define UART_CR2_ADD_WIDTH (8u) + +/* CR3 Bit fields */ +#define UART_CR3_EIE_MASK (0x00000001uL) +#define UART_CR3_EIE_SHIFT (0u) +#define UART_CR3_EIE_WIDTH (1u) + +#define UART_CR3_LOOPS_MASK (0x00000004uL) +#define UART_CR3_LOOPS_SHIFT (2u) +#define UART_CR3_LOOPS_WIDTH (1u) + +#define UART_CR3_HDSEL_MASK (0x00000008uL) +#define UART_CR3_HDSEL_SHIFT (3u) +#define UART_CR3_HDSEL_WIDTH (1u) + +#define UART_CR3_DMAR_MASK (0x00000040ul) +#define UART_CR3_DMAR_SHIFT (6u) +#define UART_CR3_DMAR_WIDTH (1u) + +#define UART_CR3_DMAT_MASK (0x00000080ul) +#define UART_CR3_DMAT_SHIFT (7u) +#define UART_CR3_DMAT_WIDTH (1u) + +#define UART_CR3_RTSE_MASK (0x00000100ul) +#define UART_CR3_RTSE_SHIFT (8u) +#define UART_CR3_RTSE_WIDTH (1u) + +#define UART_CR3_CTSE_MASK (0x00000200ul) +#define UART_CR3_CTSE_SHIFT (9u) +#define UART_CR3_CTSE_WIDTH (1u) + +#define UART_CR3_CTSIE_MASK (0x00000400ul) +#define UART_CR3_CTSIE_SHIFT (10u) +#define UART_CR3_CTSIE_WIDTH (1u) + +#define UART_CR3_ONEBIT_MASK (0x00000800ul) +#define UART_CR3_ONEBIT_SHIFT (11u) +#define UART_CR3_ONEBIT_WIDTH (1u) + +#define UART_CR3_DEM_MASK (0x00004000ul) +#define UART_CR3_DEM_SHIFT (14u) +#define UART_CR3_DEM_WIDTH (1u) + +#define UART_CR3_DEP_MASK (0x00008000ul) +#define UART_CR3_DEP_SHIFT (15u) +#define UART_CR3_DEP_WIDTH (1u) + +/* BRR Bit fields */ +#define UART_BRR_BRR_MASK (0x00FFFFFFul) +#define UART_BRR_BRR_SHIFT (0u) +#define UART_BRR_BRR_WIDTH (24u) + +/* RTOR Bit fields */ +#define UART_RTOR_RTO_MASK (0x00FFFFFFul) +#define UART_RTOR_RTO_SHIFT (0u) +#define UART_RTOR_RTO_WIDTH (24u) + +/* RQR Bit fields */ +#define UART_RQR_ABRRQ_MASK (0x00000001ul) +#define UART_RQR_ABRRQ_SHIFT (0u) +#define UART_RQR_ABRRQ_WIDTH (1u) + +#define UART_RQR_SBRKRQ_MASK (0x00000002ul) +#define UART_RQR_SBRKRQ_SHIFT (1u) +#define UART_RQR_SBRKRQ_WIDTH (1u) + +#define UART_RQR_MMRQ_MASK (0x00000004ul) +#define UART_RQR_MMRQ_SHIFT (2u) +#define UART_RQR_MMRQ_WIDTH (1u) + +/* ISR Bit fields */ +#define UART_ISR_PE_MASK (0x00000001ul) +#define UART_ISR_PE_SHIFT (0u) +#define UART_ISR_PE_WIDTH (1u) + +#define UART_ISR_FE_MASK (0x00000002ul) +#define UART_ISR_FE_SHIFT (1u) +#define UART_ISR_FE_WIDTH (1u) + +#define UART_ISR_NF_MASK (0x00000004ul) +#define UART_ISR_NF_SHIFT (2u) +#define UART_ISR_NF_WIDTH (1u) + +#define UART_ISR_ORE_MASK (0x00000008ul) +#define UART_ISR_ORE_SHIFT (3u) +#define UART_ISR_ORE_WIDTH (1u) + +#define UART_ISR_IDLE_MASK (0x00000010ul) +#define UART_ISR_IDLE_SHIFT (4u) +#define UART_ISR_IDLE_WIDTH (1u) + +#define UART_ISR_RDRF_MASK (0x00000020ul) +#define UART_ISR_RDRF_SHIFT (5u) +#define UART_ISR_RDRF_WIDTH (1u) + +#define UART_ISR_TC_MASK (0x00000040ul) +#define UART_ISR_TC_SHIFT (6u) +#define UART_ISR_TC_WIDTH (1u) + +#define UART_ISR_TDRE_MASK (0x00000080ul) +#define UART_ISR_TDRE_SHIFT (7u) +#define UART_ISR_TDRE_WIDTH (1u) + +#define UART_ISR_LBDT_DONE_MASK (0x00000100ul) +#define UART_ISR_LBDT_DONE_SHIFT (8u) +#define UART_ISR_LBDT_DONE_WIDTH (1u) + +#define UART_ISR_CTSIF_MASK (0x00000200ul) +#define UART_ISR_CTSIF_SHIFT (9u) +#define UART_ISR_CTSIF_WIDTH (1u) + +#define UART_ISR_CTS_MASK (0x00000400ul) +#define UART_ISR_CTS_SHIFT (10u) +#define UART_ISR_CTS_WIDTH (1u) + +#define UART_ISR_RTOF_MASK (0x00000800ul) +#define UART_ISR_RTOF_SHIFT (11u) +#define UART_ISR_RTOF_WIDTH (1u) + +#define UART_ISR_ABRE_MASK (0x00004000ul) +#define UART_ISR_ABRE_SHIFT (14u) +#define UART_ISR_ABRE_WIDTH (1u) + +#define UART_ISR_ABRF_MASK (0x00008000ul) +#define UART_ISR_ABRF_SHIFT (15u) +#define UART_ISR_ABRF_WIDTH (1u) + +#define UART_ISR_BUSY_MASK (0x00010000ul) +#define UART_ISR_BUSY_SHIFT (16u) +#define UART_ISR_BUSY_WIDTH (1u) + +#define UART_ISR_LBDT_FAIL_MASK (0x00020000ul) +#define UART_ISR_LBDT_FAIL_SHIFT (17u) +#define UART_ISR_LBDT_FAIL_WIDTH (1u) + +#define UART_ISR_SBRKD_MASK (0x00040000ul) +#define UART_ISR_SBRKD_SHIFT (18u) +#define UART_ISR_SBRKD_WIDTH (1u) + +#define UART_ISR_RWU_MASK (0x00080000ul) +#define UART_ISR_RWU_SHIFT (19u) +#define UART_ISR_RWU_WIDTH (1u) + +/* ICR Bit fields */ +#define UART_ICR_PECF_MASK (0x00000001ul) +#define UART_ICR_PECF_SHIFT (0u) +#define UART_ICR_PECF_WIDTH (1u) + +#define UART_ICR_FECF_MASK (0x00000002ul) +#define UART_ICR_FECF_SHIFT (1u) +#define UART_ICR_FECF_WIDTH (1u) + +#define UART_ICR_NCF_MASK (0x00000004ul) +#define UART_ICR_NCF_SHIFT (2u) +#define UART_ICR_NCF_WIDTH (1u) + +#define UART_ICR_ORECF_MASK (0x00000008ul) +#define UART_ICR_ORECF_SHIFT (3u) +#define UART_ICR_ORECF_WIDTH (1u) + +#define UART_ICR_IDLECF_MASK (0x00000010ul) +#define UART_ICR_IDLECF_SHIFT (4u) +#define UART_ICR_IDLECF_WIDTH (1u) + +#define UART_ICR_TCCF_MASK (0x00000040ul) +#define UART_ICR_TCCF_SHIFT (6u) +#define UART_ICR_TCCF_WIDTH (1u) + +#define UART_ICR_LBDTCF_MASK (0x00000100ul) +#define UART_ICR_LBDTCF_SHIFT (8u) +#define UART_ICR_LBDTCF_WIDTH (1u) + +#define UART_ICR_CTSCF_MASK (0x00000200ul) +#define UART_ICR_CTSCF_SHIFT (9u) +#define UART_ICR_CTSCF_WIDTH (1u) + +#define UART_ICR_RTOCF_MASK (0x00000800ul) +#define UART_ICR_RTOCF_SHIFT (11u) +#define UART_ICR_RTOCF_WIDTH (1u) + +#define UART_ICR_SBRKDCF_MASK (0x00040000ul) +#define UART_ICR_SBRKDCF_SHIFT (18u) +#define UART_ICR_SBRKDCF_WIDTH (1u) + +/* RDR Bit fields */ +#define UART_RDR_RDR_MASK (0x000001FFul) +#define UART_RDR_RDR_SHIFT (0u) +#define UART_RDR_RDR_WIDTH (9u) + +#define UART_RDR_FE_MASK (0x00002000ul) +#define UART_RDR_FE_SHIFT (13u) +#define UART_RDR_FE_WIDTH (1u) + +#define UART_RDR_PE_MASK (0x00004000ul) +#define UART_RDR_PE_SHIFT (14u) +#define UART_RDR_PE_WIDTH (1u) + +#define UART_RDR_NF_MASK (0x00008000ul) +#define UART_RDR_NF_SHIFT (15u) +#define UART_RDR_NF_WIDTH (1u) + +#define UART_RDR_ERR_MASK (0x0000E000ul) +#define UART_RDR_ERR_SHIFT (13u) +#define UART_RDR_ERR_WIDTH (3u) + +/* TDR Bit fields */ +#define UART_TDR_TDR_MASK (0x000001FFul) +#define UART_TDR_TDR_SHIFT (0u) +#define UART_TDR_TDR_WIDTH (9u) + +/* FIFO Bit fields */ +#define UART_FIFO_RXUFE_MASK (0x00000100ul) +#define UART_FIFO_RXUFE_SHIFT (8u) +#define UART_FIFO_RXUFE_WIDTH (1u) + +#define UART_FIFO_TXOFE_MASK (0x00000200ul) +#define UART_FIFO_TXOFE_SHIFT (9u) +#define UART_FIFO_TXOFE_WIDTH (1u) + +#define UART_FIFO_RXFLUSH_MASK (0x00004000ul) +#define UART_FIFO_RXFLUSH_SHIFT (14u) +#define UART_FIFO_RXFLUSH_WIDTH (1u) + +#define UART_FIFO_TXFLUSH_MASK (0x00008000ul) +#define UART_FIFO_TXFLUSH_SHIFT (15u) +#define UART_FIFO_TXFLUSH_WIDTH (1u) + +#define UART_FIFO_RXUF_MASK (0x00010000ul) +#define UART_FIFO_RXUF_SHIFT (16u) +#define UART_FIFO_RXUF_WIDTH (1u) + +#define UART_FIFO_TXOF_MASK (0x00020000ul) +#define UART_FIFO_TXOF_SHIFT (17u) +#define UART_FIFO_TXOF_WIDTH (1u) + +#define UART_FIFO_RXEMPT_MASK (0x00400000ul) +#define UART_FIFO_RXEMPT_SHIFT (22u) +#define UART_FIFO_RXEMPT_WIDTH (1u) + +#define UART_FIFO_TXEMPT_MASK (0x00800000ul) +#define UART_FIFO_TXEMPT_SHIFT (23u) +#define UART_FIFO_TXEMPT_WIDTH (1u) + +/* WATER Bit fields */ +#define UART_WATER_TXWATER_MASK (0x00000003ul) +#define UART_WATER_TXWATER_SHIFT (0u) +#define UART_WATER_TXWATER_WIDTH (2u) + +#define UART_WATER_TXCOUNT_MASK (0x00000700ul) +#define UART_WATER_TXCOUNT_SHIFT (8u) +#define UART_WATER_TXCOUNT_WIDTH (3u) +#define UART_WATER_RXWATER_MASK (0x00030000ul) +#define UART_WATER_RXWATER_SHIFT (16u) +#define UART_WATER_RXWATER_WIDTH (2u) + +#define UART_WATER_RXCOUNT_MASK (0x07000000ul) +#define UART_WATER_RXCOUNT_SHIFT (24u) +#define UART_WATER_RXCOUNT_WIDTH (3u) + +/****************************************************************************** + * the typedefs + *****************************************************************************/ + +/*! \brief The definition of UART registers */ +typedef struct _UartRegType_ +{ + volatile uint32_t CR1; /*!< UART Control Register 1, offset: 0x0 */ + volatile uint32_t CR2; /*!< UART Control Register 2, offset: 0x4 */ + volatile uint32_t CR3; /*!< UART Control Register 3, offset: 0x8 */ + volatile uint32_t BRR; /*!< UART Baud Rate Register, offset: 0xC */ + uint32_t RES; + volatile uint32_t RTOR; /*!< UART Receiver timeout Value Register, offset: 0x14 */ + volatile uint32_t RQR; /*!< UART Request Register, offset: 0x18 */ + volatile const uint32_t ISR; /*!< UART Status Register, offset: 0x1C */ + volatile uint32_t ICR; /*!< UART Interrupt Clear Register, offset: 0x20 */ + volatile uint32_t RDR; /*!< UART Receive data Register, offset: 0x24 */ + volatile uint32_t TDR; /*!< UART Transmit data Register, offset: 0x28 */ + volatile uint32_t FIFO; /*!< UART FIFO Register, offset: 0x2C */ + volatile uint32_t WATER; /*!< UART Watermark Register, offset: 0x30 */ +} UartRegType; + +/****************************************************************************** + * the globals + ******************************************************************************/ + +/****************************************************************************** + * the function prototypes + ******************************************************************************/ + +/*! \brief Receiver timeout interrupt enable or disable + * + * this function enable the rx timeout interrupt features + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable : + * 0: Interrupt is inhibited + * 1: An UART interrupt is generated when the RTOF bit is set in the ISR register. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetRxTimeoutIsr(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR1; + + if(enable == true) + { + obj->CR1 = ((1ul << UART_CR1_RTOIE_SHIFT) | ((~UART_CR1_RTOIE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_RTOIE_SHIFT) | ((~UART_CR1_RTOIE_MASK) & tmp)); + } +} + +/*! \brief Get the RxTimeoutIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetRxTimeoutIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->CR1 & UART_CR1_RTOIE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief Driver Enable assertion time + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] deat :This 5-bit value defines the time between the activation of the DE (Driver Enable) signal and the beginning of the start bit + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetDEAT(UartRegType *obj, uint8_t deat) +{ + uint32_t tmp = obj->CR1; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR1_DEAT_MASK; + tmp |= (((uint32_t)(((uint32_t)(deat)) << UART_CR1_DEAT_SHIFT)) & UART_CR1_DEAT_MASK); + obj->CR1 = tmp; +} + +/*! \brief Driver Enable de-assertion time + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] dedt: This 5-bit value defines the time between the end of the last stop bit, + * in a transmitted message, and the de-activation of the DE (Driver Enable) signal + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetDEDT(UartRegType *obj, uint8_t dedt) +{ + uint32_t tmp = obj->CR1; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR1_DEDT_MASK; + tmp |= (((uint32_t)(((uint32_t)(dedt)) << UART_CR1_DEDT_SHIFT)) & UART_CR1_DEDT_MASK); + obj->CR1 = tmp; +} + +/*! \brief Oversampling mode + * + * This bit can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] samplingBy8BitModeEn: + * 0: Oversampling by 16 + * 1: Oversampling by 8 + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetOverSamplingMode(UartRegType *obj, bool samplingBy8BitModeEn) +{ + uint32_t tmp = obj->CR1; + + if(samplingBy8BitModeEn == true) + { + obj->CR1 = ((1ul << UART_CR1_OVER8_SHIFT) | ((~UART_CR1_OVER8_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_OVER8_SHIFT) | ((~UART_CR1_OVER8_MASK) & tmp)); + } +} + +/*! \brief SBRKD interrupt enable + * + * this function enable the break tx completed interrupt request if finished tx break signal + * + * \param[in] obj : pointer to UART driver instance + * \param[in] txBreakOkIsr: + * 0: Interrupt is inhibited + * 1: A UART interrupt is generated whenever SBRKD=1 in the ISR register + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetBreakTxCompletedIsr(UartRegType *obj, bool txBreakOkIsr) +{ + uint32_t tmp = obj->CR1; + + if(txBreakOkIsr == true) + { + obj->CR1 = ((1ul << UART_CR1_SBRKDIE_SHIFT) | ((~UART_CR1_SBRKDIE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_SBRKDIE_SHIFT) | ((~UART_CR1_SBRKDIE_MASK) & tmp)); + } +} + +/*! \brief Get the BreakTxCompletedIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetBreakTxCompletedIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->CR1 & UART_CR1_SBRKDIE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief Mute mode enable + * + * This bit activates the mute mode function of the UART. when set, the UART can switch between the active and mute modes, + * as defined by the WAKE bit. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] muteEn: + * 0: Receiver in active mode permanently + * 1: Receiver can switch between mute mode and active mode. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetMuteMode(UartRegType *obj, bool muteEn) +{ + uint32_t tmp = obj->CR1; + + if(muteEn == true) + { + obj->CR1 = ((1ul << UART_CR1_MME_SHIFT) | ((~UART_CR1_MME_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_MME_SHIFT) | ((~UART_CR1_MME_MASK) & tmp)); + } +} + +/*! \brief Get the mute + * + * this function get the mute mode is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * 0: Receiver in active mode permanently + * 1: Receiver can switch between mute mode and active mode. + */ +__attribute__((always_inline)) static inline bool UartReg_GetMuteIsActive(const UartRegType *obj) +{ + bool tRtn = false; + + if((obj->CR1 & UART_CR1_MME_MASK) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief Set Word length + * + * this function set the frame bits formate + * + * \param[in] obj : pointer to UART driver instance + * \param[in] wordLen: + * 0: 1 Start bit, 8 data bits, n stop bits + * 1: 1 Start bit, 9 data bits, n stop bits + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetWordLength(UartRegType *obj, uint8_t wordLen) +{ + uint32_t tmp = obj->CR1; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR1_M_MASK; + tmp |= (((uint32_t)(((uint32_t)(wordLen)) << UART_CR1_M_SHIFT)) & UART_CR1_M_MASK); + obj->CR1 = tmp; +} + +/*! \brief Set Receiver wakeup method + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] wkpMethod: + * 0: Idle line + * 1: Address mark + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetWakeupMethod(UartRegType *obj, uint8_t wkpMethod) +{ + uint32_t tmp = obj->CR1; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR1_WAKE_MASK; + tmp |= (((uint32_t)(((uint32_t)(wkpMethod)) << UART_CR1_WAKE_SHIFT)) & UART_CR1_WAKE_MASK); + obj->CR1 = tmp; +} + +/*! \brief Get wake up source + * + * this function get the address to wakeup + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * 0: Idle line + * 1: Address mark + */ +__attribute__((always_inline)) static inline bool UartReg_GetWakeUpByAddress(const UartRegType *obj) +{ + bool tRtn = false; + + if((obj->CR1 & UART_CR1_WAKE_MASK) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief selects the hardware parity control + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] parityCtrlEn: enable or disable + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetParityControlEnable(UartRegType *obj, bool parityCtrlEn) +{ + uint32_t tmp = obj->CR1; + + if(parityCtrlEn == true) + { + obj->CR1 = ((1ul << UART_CR1_PCE_SHIFT) | ((~UART_CR1_PCE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_PCE_SHIFT) | ((~UART_CR1_PCE_MASK) & tmp)); + } +} + +/*! \brief This bit selects the odd or even parity when the parity generation/detection is enabled (PCE bit set). + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] paritySelection: + * 0: Even parity + * 1: Odd parity + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SelectParity(UartRegType *obj, uint8_t paritySelection) +{ + uint32_t tmp = obj->CR1; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR1_PS_MASK; + tmp |= (((uint32_t)(((uint32_t)(paritySelection)) << UART_CR1_PS_SHIFT)) & UART_CR1_PS_MASK); + obj->CR1 = tmp; +} + +/*! \brief Set Parity error interrupt enable or disable + * + * this function set the Parity error interrupt enable or disable + * + * \param[in] obj : pointer to UART driver instance + * \param[in] parityErrIsrEn: + * 0: Interrupt is inhibited + * 1: A UART interrupt is generated whenever PE=1 in the ISR register + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetParityErrIsr(UartRegType *obj, bool parityErrIsrEn) +{ + uint32_t tmp = obj->CR1; + + if(parityErrIsrEn == true) + { + obj->CR1 = ((1ul << UART_CR1_PEIE_SHIFT) | ((~UART_CR1_PEIE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_PEIE_SHIFT) | ((~UART_CR1_PEIE_MASK) & tmp)); + } +} + +/*! \brief Get the ParityErrIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetParityErrIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->CR1 & UART_CR1_PEIE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief Set tx buffer empty interrupt enable or disable + * + * this function set the tx buffer empty interrupt request when condition is matched + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Interrupt is inhibited + * 1: A UART interrupt is generated whenever TDRE=1 in the ISR register + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetTxBufferEmptyIsr(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR1; + + if(enable == true) + { + obj->CR1 = ((1ul << UART_CR1_TDREIE_SHIFT) | ((~UART_CR1_TDREIE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_TDREIE_SHIFT) | ((~UART_CR1_TDREIE_MASK) & tmp)); + } +} + +/*! \brief Get the TxBufferEmptyIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetTxBufferEmptyIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->CR1 & UART_CR1_TDREIE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief Set Transmission complete interrupt enable or disable + * + * This bit is set and cleared by software. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Interrupt is inhibited + * 1: A UART interrupt is generated whenever TC=1 in the ISR register + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetTxCompletedIsr(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR1; + + if(enable == true) + { + obj->CR1 = ((1ul << UART_CR1_TCIE_SHIFT) | ((~UART_CR1_TCIE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_TCIE_SHIFT) | ((~UART_CR1_TCIE_MASK) & tmp)); + } +} + +/*! \brief Get the TxCompletedIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetTxCompletedIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->CR1 & UART_CR1_TCIE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief Set rx buffer full interrupt enable or disable + * + * this function set the rx buffer full interrupt request when condition is matched + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Interrupt is inhibited + * 1: A UART interrupt is generated when RDRF=1 in the ISR register + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetRxBufferFullIsr(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR1; + + if(enable == true) + { + obj->CR1 = ((1ul << UART_CR1_RDRFIE_SHIFT) | ((~UART_CR1_RDRFIE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_RDRFIE_SHIFT) | ((~UART_CR1_RDRFIE_MASK) & tmp)); + } +} + +/*! \brief Get the RxBufferFullIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetRxBufferFullIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->CR1 & UART_CR1_RDRFIE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief Set IDLE interrupt enable or disable + * + * this function set the idle interrupt request when condition is matched + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Interrupt is inhibited + * 1: A UART interrupt is generated whenever IDLE=1 in the ISR register + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetIdleIsr(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR1; + + if(enable == true) + { + obj->CR1 = ((1ul << UART_CR1_IDLEIE_SHIFT) | ((~UART_CR1_IDLEIE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_IDLEIE_SHIFT) | ((~UART_CR1_IDLEIE_MASK) & tmp)); + } +} + +/*! \brief Get the IdleIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetIdleIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->CR1 & UART_CR1_IDLEIE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief Set Transmitter enable or disable + * + * this function enable the transmitter feature + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Transmitter is disabled + * 1: Transmitter is enabled + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetTransmitterEnable(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR1; + + if(enable == true) + { + obj->CR1 = ((1ul << UART_CR1_TE_SHIFT) | ((~UART_CR1_TE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_TE_SHIFT) | ((~UART_CR1_TE_MASK) & tmp)); + } +} + +/*! \brief Set Receiver enable or disable + * + * this function enable the receive feature + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Receiver is disabled + * 1: Receiver is enabled and begins searching for a start bit + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetReceiverEnable(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR1; + + if(enable == true) + { + obj->CR1 = ((1ul << UART_CR1_RE_SHIFT) | ((~UART_CR1_RE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_RE_SHIFT) | ((~UART_CR1_RE_MASK) & tmp)); + } +} + +/*! \brief UART module enable + * + * In order to go into low-power mode without generating errors on the line, the TE bit must be reset before and + * the software must wait for the TC bit in the ISR to be set before resetting the UE bit. + * The DMA requests are also reset when UE = 0 so the DMA channel must be disabled before resetting the UE bit. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: UART prescaler and outputs disabled, low-power mode + * 1: UART enabled + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableModule(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR1; + + if(enable == true) + { + obj->CR1 = ((1ul << UART_CR1_UE_SHIFT) | ((~UART_CR1_UE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_UE_SHIFT) | ((~UART_CR1_UE_MASK) & tmp)); + } +} + +/*! \brief Get UART module enable state + * + * This function get the enable state of LPTMR. + * When UE is clear, the UART is disabled. + * When UE is set, the UART is enabled. + * + * \param[in] obj : pointer to UART driver instance + * \return the state of the UART + * - 0 : UART is disabled. + * - 1 : UART is enabled. + */ +__attribute__((always_inline)) static inline uint8_t UartReg_GetEnable(const UartRegType *obj) +{ + return ((obj->CR1 & UART_CR1_UE_MASK) >> UART_CR1_UE_SHIFT); +} + +/*! \brief Set Address of the UART node + * + * This bit field can only be written when reception is disabled (RE = 0) or the UART is disabled (UE=0) + * + * \param[in] obj : pointer to UART driver instance + * \param[in] address: This bit-field gives the address of the UART node or a character code to be recognized. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetNodeAddress(UartRegType *obj, uint8_t address) +{ + uint32_t tmp = obj->CR2; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR2_ADD_MASK; + tmp |= (((uint32_t)(((uint32_t)(address)) << UART_CR2_ADD_SHIFT)) & UART_CR2_ADD_MASK); + obj->CR2 = tmp; +} + +/*! \brief Receiver timeout enable + * + * When this feature is enabled, the RTOF flag in the ISR register is set if the RX line is idle (no reception) + * for the duration programmed in the RTOR (receiver timeout register). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Receiver timeout feature disabled. + * 1: Receiver timeout feature enabled. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableRxTimeoutFeature(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR2; + + if(enable == true) + { + obj->CR2 = ((1ul << UART_CR2_RTOEN_SHIFT) | ((~UART_CR2_RTOEN_MASK) & tmp)); + } + else + { + obj->CR2 = ((0ul << UART_CR2_RTOEN_SHIFT) | ((~UART_CR2_RTOEN_MASK) & tmp)); + } +} + +/*! \brief Get RxTimeout feature enable or disable + * + * this function get the config of rx timeout feature tha is enable or disable + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * 0: Receiver timeout feature disabled. + * 1: Receiver timeout feature enabled. + */ +__attribute__((always_inline)) static inline bool UartReg_GetRxTimeoutFeatureEnable(const UartRegType *obj) +{ + bool tRtn = false; + + if((obj->CR2 & UART_CR2_RTOEN_MASK) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief Auto baud rate mode + * + * This bit field can only be written when ABREN = 0 or the UART is disabled (UE=0). + * If DATAINV=1 and/or MSBFIRST=1 the patterns must be the same on the line, for example 0xAA for MSBFIRST) + * + * \param[in] obj : pointer to UART driver instance + * \param[in] autoMode: + * 00: Measurement of the start bit is used to detect the baud rate. + * 01: Falling edge to falling edge measurement. (the received frame must start with a single bit = 1 -> Frame = Start10xxxxxx) + * 10: 0x7F frame detection. + * 11: 0x55 frame detection + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetAutoBaudrateMode(UartRegType *obj, uint8_t autoMode) +{ + uint32_t tmp = obj->CR2; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR2_ABRMOD_MASK; + tmp |= (((uint32_t)(((uint32_t)(autoMode)) << UART_CR2_ABRMOD_SHIFT)) & UART_CR2_ABRMOD_MASK); + obj->CR2 = tmp; +} + +/*! \brief Auto baud rate mode + * + * This bit field can only be written when ABREN = 0 or the UART is disabled (UE=0). + * If DATAINV=1 and/or MSBFIRST=1 the patterns must be the same on the line, for example 0xAA for MSBFIRST) + * + * \param[in] obj : pointer to UART driver instance + * \return: uint8_t + * 00: Measurement of the start bit is used to detect the baud rate. + * 01: Falling edge to falling edge measurement. (the received frame must start with a single bit = 1 -> Frame = Start10xxxxxx) + * 10: 0x7F frame detection. + * 11: 0x55 frame detection + */ +__attribute__((always_inline)) static inline uint8_t UartReg_GetAutoBaudrateMode(const UartRegType *obj) +{ + uint8_t tRtn = 0; + uint32_t tmp = obj->CR2; + + tRtn = ((tmp & UART_CR2_ABRMOD_MASK) >> UART_CR2_ABRMOD_SHIFT) & 0xFF; + + return tRtn; +} + +/*! \brief Set Auto baud rate enable or disable + * + * this function enable auto baudrate features + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Auto baud rate detection is disabled. + * 1: Auto baud rate detection is enabled. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableAutoBaudrateFeature(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR2; + + if(enable == true) + { + obj->CR2 = ((1ul << UART_CR2_ABREN_SHIFT) | ((~UART_CR2_ABREN_MASK) & tmp)); + } + else + { + obj->CR2 = ((0ul << UART_CR2_ABREN_SHIFT) | ((~UART_CR2_ABREN_MASK) & tmp)); + } +} + +/*! \brief Most significant bit first + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] mbsFirst: + * 0: data is transmitted/received with data bit 0 first, following the start bit. + * 1: data is transmitted/received with the MSB (bit 7/8/9) first, following the start bit. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetFirstBitShift(UartRegType *obj, uint8_t mbsFirst) +{ + uint32_t tmp = obj->CR2; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR2_MSBFIRST_MASK; + tmp |= (((uint32_t)(((uint32_t)(mbsFirst)) << UART_CR2_MSBFIRST_SHIFT)) & UART_CR2_MSBFIRST_MASK); + obj->CR2 = tmp; +} + +/*! \brief Binary data inversion + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Logical data from the data register are send/received in positive/direct logic. (1=H, 0=L) + * 1: Logical data from the data register are send/received in negative/inverse logic. (1=L, 0=H). The parity bit is also inverted. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableDataInverteFeature(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR2; + + if(enable == true) + { + obj->CR2 = ((1ul << UART_CR2_DATAINV_SHIFT) | ((~UART_CR2_DATAINV_MASK) & tmp)); + } + else + { + obj->CR2 = ((0ul << UART_CR2_DATAINV_SHIFT) | ((~UART_CR2_DATAINV_MASK) & tmp)); + } +} + +/*! \brief TX pin active level inversion + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: TX pin signal works using the standard logic levels (VDD =1/idle, Gnd=0/mark) + * 1: TX pin signal values are inverted. (VDD =0/mark, Gnd=1/idle). This allows the use of an external inverter on the TX line. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableTxInverteFeature(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR2; + + if(enable == true) + { + obj->CR2 = ((1ul << UART_CR2_TXINV_SHIFT) | ((~UART_CR2_TXINV_MASK) & tmp)); + } + else + { + obj->CR2 = ((0ul << UART_CR2_TXINV_SHIFT) | ((~UART_CR2_TXINV_MASK) & tmp)); + } +} + +/*! \brief RX pin active level inversion + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: RX pin signal works using the standard logic levels (VDD =1/idle, Gnd=0/mark) + * 1: RX pin signal values are inverted. (VDD =0/mark, Gnd=1/idle). This allows the use of an external inverter on the RX line. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableRxInverteFeature(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR2; + + if(enable == true) + { + obj->CR2 = ((1ul << UART_CR2_RXINV_SHIFT) | ((~UART_CR2_RXINV_MASK) & tmp)); + } + else + { + obj->CR2 = ((0ul << UART_CR2_RXINV_SHIFT) | ((~UART_CR2_RXINV_MASK) & tmp)); + } +} + +/*! \brief LIN feature enable or disable + * + * this function is used only in lin mode + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: LIN break detect disabled + * 1: LIN break detect enabled + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableLineBreakDetectFeature(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR2; + + if(enable == true) + { + obj->CR2 = ((1ul << UART_CR2_LINEN_SHIFT) | ((~UART_CR2_LINEN_MASK) & tmp)); + } + else + { + obj->CR2 = ((0ul << UART_CR2_LINEN_SHIFT) | ((~UART_CR2_LINEN_MASK) & tmp)); + } +} + +/*! \brief Get break synect detected enable status + * + * this function get the lin break detected features tha is enable or disbale + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * 0: LIN break detect disabled + * 1: LIN break detect enabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetLinBreakDetecteEnable(const UartRegType *obj) +{ + bool tRtn = false; + + if((obj->CR2 & UART_CR2_LINEN_MASK) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief These bits are used for programming the stop bits. + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] stopBitsNum: + * 0: 1 stop bit + * 1: 2 stop bits + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetStopBitNums(UartRegType *obj, uint8_t stopBitsNum) +{ + uint32_t tmp = obj->CR2; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR2_STOP_MASK; + tmp |= (((uint32_t)(((uint32_t)(stopBitsNum)) << UART_CR2_STOP_SHIFT)) & UART_CR2_STOP_MASK); + obj->CR2 = tmp; +} + +/*! \brief Configures the number of idle characters that must be received before the IDLE flag is set. + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] idleCfg: + * 000b : 1 idle character + * 001b : 2 idle characters + * 010b : 4 idle characters + * 011b : 8 idle characters + * 100b : 16 idle characters + * 101b : 32 idle characters + * 110b : 64 idle characters + * 111b : 128 idle characters + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetIdleConfig(UartRegType *obj, uint8_t idleCfg) +{ + uint32_t tmp = obj->CR2; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR2_IDLECFG_MASK; + tmp |= (((uint32_t)(((uint32_t)(idleCfg)) << UART_CR2_IDLECFG_SHIFT)) & UART_CR2_IDLECFG_MASK); + obj->CR2 = tmp; +} + +/*! \brief LIN break detection done interrupt enable + * + * this function set lin break signal detected to trigger one interrupt request + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Interrupt is inhibited + * 1: An interrupt is generated whenever LBDT_DONE=1 in the ISR register + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetLinBreakDetectedIsr(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR2; + + if(enable == true) + { + obj->CR2 = ((1ul << UART_CR2_LBDTIE_SHIFT) | ((~UART_CR2_LBDTIE_MASK) & tmp)); + } + else + { + obj->CR2 = ((0ul << UART_CR2_LBDTIE_SHIFT) | ((~UART_CR2_LBDTIE_MASK) & tmp)); + } +} + +/*! \brief Get the LinBreakDetectedIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetLinBreakDetectedIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->CR2 & UART_CR2_LBDTIE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief LIN synch break detect length + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] breakLen: + * 00: 11bit + * 01: 12bit + * 10: 13bit + * 11: 11bit + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetLinSyncBreakDetectLen(UartRegType *obj, uint8_t breakLen) +{ + uint32_t tmp = obj->CR2; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR2_LBDL_MASK; + tmp |= (((uint32_t)(((uint32_t)(breakLen)) << UART_CR2_LBDL_SHIFT)) & UART_CR2_LBDL_MASK); + obj->CR2 = tmp; +} + +/*! \brief This bit is for selection between 4-bit address detection or 7-bit address detection. + * + * This bit can only be written when the UART is disabled (UE=0) + * + * \param[in] obj : pointer to UART driver instance + * \param[in] addressSelection: + * 0: 4-bit address detection + * 1: 7-bit address detection (in 8-bit data mode) + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetAddreDetectMode(UartRegType *obj, uint8_t addressSelection) +{ + uint32_t tmp = obj->CR2; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR2_ADDM_MASK; + tmp |= (((uint32_t)(((uint32_t)(addressSelection)) << UART_CR2_ADDM_SHIFT)) & UART_CR2_ADDM_MASK); + obj->CR2 = tmp; +} + +/*! \brief Config Transmiting LIN Delimitor Width + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] delimitorWidth: + * 0 : 1 bit + * 1 : 2 bits + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetLinDelimitorWidth(UartRegType *obj, uint8_t delimitorWidth) +{ + uint32_t tmp = obj->CR2; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR2_SDEL_LEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(delimitorWidth)) << UART_CR2_SDEL_LEN_SHIFT)) & UART_CR2_SDEL_LEN_MASK); + obj->CR2 = tmp; +} + +/*! \brief Config Transmiting synch break Width + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] syncBreakLen: + * 00b : 13 bits + * 01b : 14 bits + * 10b : 15 bits + * 11b : 13 bits + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetTxLinSyncBreakWidth(UartRegType *obj, uint8_t syncBreakLen) +{ + uint32_t tmp = obj->CR2; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR2_SBRK_LEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(syncBreakLen)) << UART_CR2_SBRK_LEN_SHIFT)) & UART_CR2_SBRK_LEN_MASK); + obj->CR2 = tmp; +} + +/*! \brief Driver enable polarity selection + * + * This bit can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] deInActiveIsLowEn: + * 0: DE signal is active high. + * 1: DE signal is active low. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetDriverPolarity(UartRegType *obj, bool deInActiveIsLowEn) +{ + uint32_t tmp = obj->CR3; + + if(deInActiveIsLowEn == true) + { + obj->CR3 = ((1ul << UART_CR3_DEP_SHIFT) | ((~UART_CR3_DEP_MASK) & tmp)); + } + else + { + obj->CR3 = ((0ul << UART_CR3_DEP_SHIFT) | ((~UART_CR3_DEP_MASK) & tmp)); + } +} + +/*! \brief This bit allows the user to activate the external transceiver control, through the DE signal + * + * This bit can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: DE function is disabled. + * 1: DE function is enabled. The DE signal is output on the RTS pin. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetDriverEnableMode(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR3; + + if(enable == true) + { + obj->CR3 = ((1ul << UART_CR3_DEM_SHIFT) | ((~UART_CR3_DEM_MASK) & tmp)); + } + else + { + obj->CR3 = ((0ul << UART_CR3_DEM_SHIFT) | ((~UART_CR3_DEM_MASK) & tmp)); + } +} + +/*! \brief This bit allows the user to select the sample method + * + * This bit can only be written when the UART is disabled (UE=0). ONEBIT feature applies only to data bits, It does not apply to Start bit. + * When the one sample bit method is selected the noise detection flag (NF) is disabled. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] sampleBitMethod: + * 0: Three sample bit method + * 1: One sample bit method + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetSampleBitMethod(UartRegType *obj, uint8_t sampleBitMethod) +{ + uint32_t tmp = obj->CR3; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR3_ONEBIT_MASK; + tmp |= (((uint32_t)(((uint32_t)(sampleBitMethod)) << UART_CR3_ONEBIT_SHIFT)) & UART_CR3_ONEBIT_MASK); + obj->CR3 = tmp; +} + +/*! \brief CTS interrupt enable + * + * this function set the cts interrupt request, but only in rs232 mode + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Interrupt is inhibited + * 1: An interrupt is generated whenever CTSIF=1 in the ISR register + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetCtsIsr(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR3; + + if(enable == true) + { + obj->CR3 = ((1ul << UART_CR3_CTSIE_SHIFT) | ((~UART_CR3_CTSIE_MASK) & tmp)); + } + else + { + obj->CR3 = ((0ul << UART_CR3_CTSIE_SHIFT) | ((~UART_CR3_CTSIE_MASK) & tmp)); + } +} + +/*! \brief Get the CtsIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetCtsIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->CR3 & UART_CR3_CTSIE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief CTS enable + * + * This bit can only be written when the UART is disabled (UE=0) + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: CTS hardware flow control disabled + * 1: CTS mode enabled, data is only transmitted when the CTS input + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableCts(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR3; + + if(enable == true) + { + obj->CR3 = ((1ul << UART_CR3_CTSE_SHIFT) | ((~UART_CR3_CTSE_MASK) & tmp)); + } + else + { + obj->CR3 = ((0ul << UART_CR3_CTSE_SHIFT) | ((~UART_CR3_CTSE_MASK) & tmp)); + } +} + +/*! \brief RTS enable or disable + * + * This bit can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: RTS hardware flow control disabled + * 1: RTS output enabled, data is only requested when there is space in the receive buffer + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableRts(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR3; + + if(enable == true) + { + obj->CR3 = ((1ul << UART_CR3_RTSE_SHIFT) | ((~UART_CR3_RTSE_MASK) & tmp)); + } + else + { + obj->CR3 = ((0ul << UART_CR3_RTSE_SHIFT) | ((~UART_CR3_RTSE_MASK) & tmp)); + } +} + +/*! \brief DMA enable transmitter + * + * this function set the tx data used DMA mode + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: DMA mode is disabled for transmission + * 1: DMA mode is enabled for transmission + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableTxDMA(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR3; + + if(enable == true) + { + obj->CR3 = ((1ul << UART_CR3_DMAT_SHIFT) | ((~UART_CR3_DMAT_MASK) & tmp)); + } + else + { + obj->CR3 = ((0ul << UART_CR3_DMAT_SHIFT) | ((~UART_CR3_DMAT_MASK) & tmp)); + } +} + +/*! \brief DMA enable receiver + * + * This function set the received data used DMA + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: DMA mode is disabled for reception + * 1: DMA mode is enabled for reception + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableRxDMA(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR3; + + if(enable == true) + { + obj->CR3 = ((1ul << UART_CR3_DMAR_SHIFT) | ((~UART_CR3_DMAR_MASK) & tmp)); + } + else + { + obj->CR3 = ((0ul << UART_CR3_DMAR_SHIFT) | ((~UART_CR3_DMAR_MASK) & tmp)); + } +} + +/*! \brief Half-duplex selection + * + * This bit can only be written when the UART is disabled (UE=0). If LOOPS and HDSEL are both 1, HDSEL is invalid. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Half duplex mode is not selected + * 1: Half duplex mode is selected + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetHalfDuplex(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR3; + + if(enable == true) + { + obj->CR3 = ((1ul << UART_CR3_HDSEL_SHIFT) | ((~UART_CR3_HDSEL_MASK) & tmp)); + } + else + { + obj->CR3 = ((0ul << UART_CR3_HDSEL_SHIFT) | ((~UART_CR3_HDSEL_MASK) & tmp)); + } +} + +/*! \brief Loop Mode Selec + * + * This bit can only be written when the UART is disabled (UE=0). If LOOPS and HDSEL are both 1, HDSEL is invalid. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Normal operation - RXD and TXD use separate pins. + * 1: Loop mode mode where transmitter outputs are internally connected to receiver input. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetLoopsMode(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR3; + + if(enable == true) + { + obj->CR3 = ((1ul << UART_CR3_LOOPS_SHIFT) | ((~UART_CR3_LOOPS_MASK) & tmp)); + } + else + { + obj->CR3 = ((0ul << UART_CR3_LOOPS_SHIFT) | ((~UART_CR3_LOOPS_MASK) & tmp)); + } +} + +/*! \brief Error Interrupt Enable + * + * Error Interrupt Enable bit is required to enable interrupt generation in case of a framing error, + * overrun error or noise flag (FE=1 or ORE=1 or NF=1 in the ISR register). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Interrupt is inhibited + * 1: An interrupt is generated when FE=1 or ORE=1 or NF=1 in the ISR register. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetErrIsr(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR3; + + if(enable == true) + { + obj->CR3 = ((1ul << UART_CR3_EIE_SHIFT) | ((~UART_CR3_EIE_MASK) & tmp)); + } + else + { + obj->CR3 = ((0ul << UART_CR3_EIE_SHIFT) | ((~UART_CR3_EIE_MASK) & tmp)); + } +} + +/*! \brief Get the Error Interrupt enable status + * + * Readout the current Error Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetErrIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->CR3 & UART_CR3_EIE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief Send break done clear flag + * + * Writing 1 to this bit clears the SBRKD flag in the ISR register. + * + * \param[in] obj : pointer to UART driver instance + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_ClearTxBreakDoneFlag(UartRegType *obj) +{ + obj->ICR |= UART_ICR_SBRKDCF_MASK; + /* Read back to avoid problem */ + (void)obj->ICR; +} + +/*! \brief Receiver timeout clear flag + * + * Writing 1 to this bit clears the RTOF flag in the ISR register. + * + * \param[in] obj : pointer to UART driver instance + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_ClearRxTimeoutFlag(UartRegType *obj) +{ + obj->ICR |= UART_ICR_RTOCF_MASK; + /* Read back to avoid problem */ + (void)obj->ICR; +} + +/*! \brief CTS clear flag + * + * Writing 1 to this bit clears the CTSIF flag in the ISR register. + * + * \param[in] obj : pointer to UART driver instance + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_ClearCtsFlag(UartRegType *obj) +{ + obj->ICR |= UART_ICR_CTSCF_MASK; + /* Read back to avoid problem */ + (void)obj->ICR; +} + +/*! \brief LIN break detection result (LBDT_DONE and LBDT_FAIL) clear flag + * + * Writing 1 to this bit clears the LBDT_DONE and LBDT_FAIL flag in the ISR register. + * + * \param[in] obj : pointer to UART driver instance + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_ClearLinBreakDetectedResultFlag(UartRegType *obj) +{ + obj->ICR |= UART_ICR_LBDTCF_MASK; + /* Read back to avoid problem */ + (void)obj->ICR; +} + +/*! \brief Transmission complete clear flag + * + * Writing 1 to this bit clears the TC flag in the ISR register. + * + * \param[in] obj : pointer to UART driver instance + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_ClearTxCompletedFlag(UartRegType *obj) +{ + obj->ICR |= UART_ICR_TCCF_MASK; + /* Read back to avoid problem */ + (void)obj->ICR; +} + +/*! \brief Idle line detected clear flag + * + * Writing 1 to this bit clears the IDLE flag in the ISR register. + * + * \param[in] obj : pointer to UART driver instance + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_ClearIdlelineDetectedFlag(UartRegType *obj) +{ + obj->ICR |= UART_ICR_IDLECF_MASK; + /* Read back to avoid problem */ + (void)obj->ICR; +} + +/*! \brief Overrun error clear flag + * + * Writing 1 to this bit clears the ORE flag in the ISR register. + * + * \param[in] obj : pointer to UART driver instance + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_ClearOverRunnErrFlag(UartRegType *obj) +{ + obj->ICR |= UART_ICR_ORECF_MASK; + /* Read back to avoid problem */ + (void)obj->ICR; +} + +/*! \brief Noise detected clear flag + * + * Writing 1 to this bit clears the NE flag in the ISR register. + * + * \param[in] obj : pointer to UART driver instance + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_ClearNoiseDetectedFlag(UartRegType *obj) +{ + obj->ICR |= UART_ICR_NCF_MASK; + /* Read back to avoid problem */ + (void)obj->ICR; +} + +/*! \brief Framing error clear flag + * + * Writing 1 to this bit clears the FE flag in the ISR register. + * + * \param[in] obj : pointer to UART driver instance + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_ClearFrameErrFlag(UartRegType *obj) +{ + obj->ICR |= UART_ICR_FECF_MASK; + /* Read back to avoid problem */ + (void)obj->ICR; +} + +/*! \brief Parity error clear flag + * + * Writing 1 to this bit clears the PE flag in the ISR register. + * + * \param[in] obj : pointer to UART driver instance + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_ClearParityErrFlag(UartRegType *obj) +{ + obj->ICR |= UART_ICR_PECF_MASK; + /* Read back to avoid problem */ + (void)obj->ICR; +} + +/*! \brief Baud Rate Regiter + * + * This register can only be written when the UART is disabled (UE=0), + * It may be automatically updated by hardware in auto baud rate detection mode. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] brr: + * BRR[15:4] = UARTDIV[15:4] + * When OVER8 = 0, BRR[3:0] = UARTDIV[3:0]. + * When OVER8 = 1: BRR[2:0] = UARTDIV[3:0] shifted 1 bit to the right. BRR[3] must be kept cleared. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetBaudRate(UartRegType *obj, uint16_t brr) +{ + uint32_t tmp = obj->BRR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_BRR_BRR_MASK; + tmp |= (((uint32_t)(((uint32_t)(brr)) << UART_BRR_BRR_SHIFT)) & UART_BRR_BRR_MASK); + obj->BRR = tmp; +} + +/*! \brief This bit-field gives the Receiver timeout value in terms of number of bit duration. + * + * This value must only be programmed once per received character. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] timeout: Receiver timeout value + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetRxTimeout(UartRegType *obj, uint32_t timeout) +{ + uint32_t tmp = obj->RTOR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_RTOR_RTO_MASK; + tmp |= (((uint32_t)(((uint32_t)(timeout)) << UART_RTOR_RTO_SHIFT)) & UART_RTOR_RTO_MASK); + obj->RTOR = tmp; +} + +/*! \brief Mute mode request + * + * Writing 1 to this bit puts the UART in mute mode and sets the RWU flag. + * + * \param[in] obj : pointer to UART driver instance + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_ReqMuteMode(UartRegType *obj) +{ + uint32_t tmp = obj->RQR; + + obj->RQR = ((1ul << UART_RQR_MMRQ_SHIFT) | ((~UART_RQR_MMRQ_MASK) & tmp)); +} + +/*! \brief Send break request + * + * In the case the application needs to send the break character following all previously inserted data, + * including the ones not yet transmitted, the software should wait for the TXEMPT flag assertion before setting the SBRKRQ bit. + * + * \param[in] obj : pointer to UART driver instance + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_ReqTxBreak(UartRegType *obj) +{ + uint32_t tmp = obj->RQR; + + obj->RQR = ((1ul << UART_RQR_SBRKRQ_SHIFT) | ((~UART_RQR_SBRKRQ_MASK) & tmp)); +} + +/*! \brief Auto baud rate request + * + * Writing 1 to this bit resets the ABRF flag in the ISR and request an automatic baud rate measurement on the next received data frame. + * + * \param[in] obj : pointer to UART driver instance + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_ReqAutoBaudRate(UartRegType *obj) +{ + uint32_t tmp = obj->RQR; + + obj->RQR = ((1ul << UART_RQR_ABRRQ_SHIFT) | ((~UART_RQR_ABRRQ_MASK) & tmp)); +} + +/*! \brief Transmit data + * + * Note: Contains the data character to be transmitted. When transmitting with the parity enabled (PCE bit set to 1 in the CR1 register), + * the value written in the MSB (bit 7 or bit 8 depending on the data length) has no effect because it is replaced by the parity + * + * \param[in] obj : pointer to UART driver instance + * \param[in] txData : the tx data value + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_TxData(UartRegType *obj, uint16_t txData) +{ + uint32_t tmp = obj->TDR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_TDR_TDR_MASK; + tmp |= (((uint32_t)(((uint32_t)(txData)) << UART_TDR_TDR_SHIFT)) & UART_TDR_TDR_MASK); + obj->TDR = tmp; +} + +/*! \brief Transmit Buffer/FIFO Empty + * + * this function get the current tx buffer is empty or not + * + * \param[in] obj : pointer to UART driver instance + * \return: uint8_t + * 0b : Transmit buffer is not empty. + * 1b : Transmit buffer is empty. + */ +__attribute__((always_inline)) static inline uint8_t UartReg_GetTxBufferIsEmpty(const UartRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->FIFO & UART_FIFO_TXEMPT_MASK) >> UART_FIFO_TXEMPT_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Receive Buffer/FIFO Empty + * + * this function get the current rx buffer is empty or not + * + * \param[in] obj : pointer to UART driver instance + * \return: uint8_t + * 0b : Receive buffer is not empty. + * 1b : Receive buffer is empty. + */ +__attribute__((always_inline)) static inline uint8_t UartReg_GetRxBufferIsEmpty(const UartRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->FIFO & UART_FIFO_RXEMPT_MASK) >> UART_FIFO_RXEMPT_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Get Transmitter Buffer Overflow Flag + * + * Indicates that more data has been written to the transmit buffer than it can hold. This field asserts regardless of the value of TXOFE. However, + * an interrupt is issued to the host only if TXOFE is set. + * + * \param[in] obj : pointer to UART driver instance + * \return: uint8_t + * 0b : No transmit buffer overflow has occurred since the last time the flag was cleared. + * 1b : At least one transmit buffer overflow has occurred since the last time the flag was cleared. + */ +__attribute__((always_inline)) static inline uint8_t UartReg_GetTxOverflowFlag(const UartRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->FIFO & UART_FIFO_TXOF_MASK) >> UART_FIFO_TXOF_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Clear Transmitter Buffer Overflow Flag + * + * This flag is cleared by writing a 1. + * + * \param[in] obj : pointer to UART driver instance + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_ClearTxOverflowFlag(UartRegType *obj) +{ + obj->FIFO |= UART_FIFO_TXOF_MASK; + /* Read back to avoid problem */ + (void)obj->FIFO; +} + +/*! \brief Get Receiver Buffer Underflow Flag + * + * This flag is cleared by writing a 1. + * + * \param[in] obj : pointer to UART driver instance + * \return: uint8_t + * 0b : No receive buffer underflow has occurred since the last time the flag was cleared. + * 1b : At least one receive buffer underflow has occurred since the last time the flag was cleared. + */ +__attribute__((always_inline)) static inline uint8_t UartReg_GetRxUnderflowFlag(const UartRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->FIFO & UART_FIFO_RXUF_MASK) >> UART_FIFO_RXUF_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Clear Receiver Buffer Underflow Flag + * + * Indicates that more data has been read from the receive buffer than was present. This field asserts regardless of the value of RXUFE. However, + * an interrupt is issued to the host only if RXUFE is setThis flag is cleared by writing a 1. + * + * \param[in] obj : pointer to UART driver instance + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_ClearRxUnderflowFlag(UartRegType *obj) +{ + obj->FIFO |= UART_FIFO_RXUF_MASK; + /* Read back to avoid problem */ + (void)obj->FIFO; +} + +/*! \brief Transmit FIFO/Buffer Flush + * + * Set and cleared by software. When using this bit, it is recommended this bit is high for at least three clock cycles. + * + * \param[in] obj : pointer to UART driver instance + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_FlushTxFifo(UartRegType *obj) +{ + uint32_t tmp = obj->FIFO; + + obj->FIFO = ((1ul << UART_FIFO_TXFLUSH_SHIFT) | ((~UART_FIFO_TXFLUSH_MASK) & tmp)); + + __asm volatile("nop"); + __asm volatile("nop"); + __asm volatile("nop"); + __asm volatile("nop"); + + obj->FIFO = ((0ul << UART_FIFO_TXFLUSH_SHIFT) | ((~UART_FIFO_TXFLUSH_MASK) & tmp)); +} + +/*! \brief Receiver FIFO/Buffer Flush + * + * Set and cleared by software. When using this bit, it is recommended this bit is high for at least three clock cycles. + * + * \param[in] obj : pointer to UART driver instance + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_FlushRxFifo(UartRegType *obj) +{ + uint32_t tmp = obj->FIFO; + + obj->FIFO = ((1ul << UART_FIFO_RXFLUSH_SHIFT) | ((~UART_FIFO_RXFLUSH_MASK) & tmp)); + + __asm volatile("nop"); + __asm volatile("nop"); + __asm volatile("nop"); + __asm volatile("nop"); + + obj->FIFO = ((0ul << UART_FIFO_RXFLUSH_SHIFT) | ((~UART_FIFO_RXFLUSH_MASK) & tmp)); +} + +/*! \brief Transmit FIFO Overflow Interrupt Enable + * + * When this field is set, the TXOF flag generates an interrupt to the host. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0b : TXOF flag does not generate an interrupt to the host. + * 1b : TXOF flag generates an interrupt to the host. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetTxOverflowIsr(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->FIFO; + + if(enable == true) + { + obj->FIFO = ((1ul << UART_FIFO_TXOFE_SHIFT) | ((~UART_FIFO_TXOFE_MASK) & tmp)); + } + else + { + obj->FIFO = ((0ul << UART_FIFO_TXOFE_SHIFT) | ((~UART_FIFO_TXOFE_MASK) & tmp)); + } +} + +/*! \brief Get the TxOverflowIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetTxOverflowIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->FIFO & UART_FIFO_TXOFE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief Receive FIFO Underflow Interrupt Enable + * + * When this field is set, the RXUF flag generates an interrupt to the host. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0b : No receive buffer underflow has occurred since the last time the flag was cleared. + * 1b : At least one receive buffer underflow has occurred since the last time the flag was cleared. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetRxUnderflowIsr(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->FIFO; + + if(enable == true) + { + obj->FIFO = ((1ul << UART_FIFO_RXUFE_SHIFT) | ((~UART_FIFO_RXUFE_MASK) & tmp)); + } + else + { + obj->FIFO = ((0ul << UART_FIFO_RXUFE_SHIFT) | ((~UART_FIFO_RXUFE_MASK) & tmp)); + } +} + +/*! \brief Get the RxUnderflowIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetRxUnderflowIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->FIFO & UART_FIFO_RXUFE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief The value in this register indicates the number of datawords that are in the receive FIFO/buffer + * + * If a dataword is being received, that is, in the receive shift register, it is not included in the count. + * This value may be used to calculate how much room is left in the receive FIFO/buffer. + * + * \param[in] obj : pointer to UART driver instance + * \return: Receive Counter + */ +__attribute__((always_inline)) static inline uint8_t UartReg_GetRxCounter(const UartRegType *obj) +{ + uint8_t tRxCnt = 0; + + tRxCnt = (((obj->WATER & UART_WATER_RXCOUNT_MASK) >> UART_WATER_RXCOUNT_SHIFT) & 0xFF); + + return tRxCnt; +} + +/*! \brief When the number of datawords in the receive FIFO/buffer is greater than the value in this register field, + * an interrupt or a DMA request is generated. + * + * These 2 bits can only be written when the UART is disabled (UE=0) + * + * \param[in] obj : pointer to UART driver instance + * \param[in] rxWater: Receive Watermark + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetRxWater(UartRegType *obj, uint8_t rxWater) +{ + uint32_t tmp = obj->WATER; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_WATER_RXWATER_MASK; + tmp |= (((uint32_t)(((uint32_t)(rxWater)) << UART_WATER_RXWATER_SHIFT)) & UART_WATER_RXWATER_MASK); + obj->WATER = tmp; +} + +/*! \brief The value in this register indicates the number of datawords that are in the receive FIFO/buffer + * + * If a dataword is being transmitted, that is, in the transmit shift register, it is not included in the count. + * This value may be used to calculate how much room is left in the transmit FIFO/buffer. + * + * \param[in] obj : pointer to UART driver instance + * \return: Transmit Counter + */ +__attribute__((always_inline)) static inline uint8_t UartReg_GetTxCounter(const UartRegType *obj) +{ + uint8_t tTxCnt = 0; + + tTxCnt = (((obj->WATER & UART_WATER_TXCOUNT_MASK) >> UART_WATER_TXCOUNT_SHIFT) & 0xFF); + + return tTxCnt; +} + +/*! \brief When the number of datawords in the transmit FIFO/buffer is equal to or less than the value in this register field, + * an interrupt or a DMA request is generated. + * + * These 2 bits can only be written when the UART is disabled (UE=0) + * + * \param[in] obj : pointer to UART driver instance + * \param[in] txWater: Transmit Watermark + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetTxWater(UartRegType *obj, uint8_t txWater) +{ + uint32_t tmp = obj->WATER; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_WATER_TXWATER_MASK; + tmp |= (((uint32_t)(((uint32_t)(txWater)) << UART_WATER_TXWATER_SHIFT)) & UART_WATER_TXWATER_MASK); + obj->WATER = tmp; +} + +/*! \brief Get Tx water mark + * + * This function get the theshold value to compared with tx counter + * + * \param[in] obj : pointer to UART driver instance + * \return: Transmit Watermark + */ +__attribute__((always_inline)) static inline uint8_t UartReg_GetTxWaterMark(const UartRegType *obj) +{ + uint8_t tTxWaterMark = 0; + + tTxWaterMark = (((obj->WATER & UART_WATER_TXWATER_MASK) >> UART_WATER_TXWATER_SHIFT) & 0xFF); + + return tTxWaterMark; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UART_REG_H_ */ \ No newline at end of file diff --git a/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/wdg_reg.h b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/wdg_reg.h new file mode 100644 index 0000000..94894da --- /dev/null +++ b/cva_asw_m0118/SDK/platform/devices/CVM011x/reg/wdg_reg.h @@ -0,0 +1,687 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _WDG_REG_H_ +#define _WDG_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the WDG (Watch Dog) Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* CS Bit Fields */ +#define WDG_CS_CLK_MASK (0x70000u) +#define WDG_CS_CLK_SHIFT (16u) +#define WDG_CS_CLK_WIDTH (3u) +#define WDG_CS_WIN_MASK (0x8000u) +#define WDG_CS_WIN_SHIFT (15u) +#define WDG_CS_WIN_WIDTH (1u) +#define WDG_CS_FLG_MASK (0x4000u) +#define WDG_CS_FLG_SHIFT (14u) +#define WDG_CS_FLG_WIDTH (1u) +#define WDG_CS_PRES_MASK (0x1000u) +#define WDG_CS_PRES_SHIFT (12u) +#define WDG_CS_PRES_WIDTH (1u) +#define WDG_CS_ULK_MASK (0x800u) +#define WDG_CS_ULK_SHIFT (11u) +#define WDG_CS_ULK_WIDTH (1u) +#define WDG_CS_RCS_MASK (0x400u) +#define WDG_CS_RCS_SHIFT (10u) +#define WDG_CS_RCS_WIDTH (1u) +#define WDG_CS_CSD_MASK (0x200u) +#define WDG_CS_CSD_SHIFT (9) +#define WDG_CS_CSD_WIDTH (1) +#define WDG_CS_EN_MASK (0x80u) +#define WDG_CS_EN_SHIFT (7u) +#define WDG_CS_EN_WIDTH (1u) +#define WDG_CS_INTR_MASK (0x40u) +#define WDG_CS_INTR_SHIFT (6u) +#define WDG_CS_INTR_WIDTH (1u) +#define WDG_CS_UPDATE_MASK (0x20u) +#define WDG_CS_UPDATE_SHIFT (5u) +#define WDG_CS_UPDATE_WIDTH (1u) +#define WDG_CS_TST_MASK (0x18u) +#define WDG_CS_TST_SHIFT (3u) +#define WDG_CS_TST_WIDTH (2u) +#define WDG_CS_DEBUG_MASK (0x02u) +#define WDG_CS_DEBUG_SHIFT (1u) +#define WDG_CS_DEBUG_WIDTH (1u) +#define WDG_CS_STOP_MASK (0x01u) +#define WDG_CS_STOP_SHIFT (0u) +#define WDG_CS_STOP_WIDTH (1u) + +/* CNT Bit Fields */ +#define WDG_CNT_HIGH_MASK (0xFF00u) +#define WDG_CNT_HIGH_SHIFT (8u) +#define WDG_CNT_HIGH_WIDTH (8u) +#define WDG_CNT_LOW_MASK (0xFFu) +#define WDG_CNT_LOW_SHIFT (0u) +#define WDG_CNT_LOW_WIDTH (8u) + +/* TOVAL Bit Fields */ +#define WDG_TOVAL_HIGH_MASK (0xFF00u) +#define WDG_TOVAL_HIGH_SHIFT (8u) +#define WDG_TOVAL_HIGH_WIDTH (8u) +#define WDG_TOVAL_LOW_MASK (0xFFu) +#define WDG_TOVAL_LOW_SHIFT (0u) +#define WDG_TOVAL_LOW_WIDTH (8u) + +/* WIN Bit Fields */ +#define WDG_WIN_HIGH_MASK (0xFF00u) +#define WDG_WIN_HIGH_SHIFT (8u) +#define WDG_WIN_HIGH_WIDTH (8u) +#define WDG_WIN_LOW_MASK (0xFFu) +#define WDG_WIN_LOW_SHIFT (0u) +#define WDG_WIN_LOW_WIDTH (8u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of WDG registers + */ +typedef struct _WdgRegType_ +{ + volatile uint32_t CS; /*!< control register, offset: 0x00 */ + volatile uint32_t CNT; /*!< counter set register, offset: 0x04 */ + volatile uint32_t TOVAL; /*!< timeout value register, offset: 0x08 */ + volatile uint32_t WIN; /*!< window value register, offset: 0x0C */ +} WdgRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the WDG CS value. + * + * the function gets the WDG CS value. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to CS current value + * + */ +__attribute__((always_inline)) static inline uint32_t WdgReg_GetCsVal(const WdgRegType *obj) +{ + return obj->CS; +} + +/*! \brief Sets the WDG CS unlock key + * + * The WDG CS registers is locked by default. + * Before writing registers, write unlock key to this register or refresh this register. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : pointer to the value + */ +__attribute__((always_inline)) static inline void WdgReg_SetCsVal(WdgRegType *obj, uint32_t value) +{ + obj->CS = value; +} + +/*! \brief Gets the WDG input clock source + * + * This function gets the WDG input clock source + * + * \param[in] obj : pointer to WDG register instance + * \return indicate the clock source that feeds the watchdog counter + * - 000b : BUS clock as source; + * - 001b : LPO_CLK_128 clock as source; + * - 010b : SOSC clock as source; + * - 011b : SIRC clock as source; + * - 100b : LPO_CLK_32 clock as source; + * - 101b : LPO_CLK_1 clock as source; + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_GetClockSource(const WdgRegType *obj) +{ + return ((obj->CS & WDG_CS_CLK_MASK) >> WDG_CS_CLK_SHIFT); +} + +/*! \brief Sets the WDG input clock source + * + * This function sets the WDG input clock source + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : the value of WDG input clock source + * - 000b : BUS clock as source; + * - 001b : LPO_CLK_128 clock as source; + * - 010b : SOSC clock as source; + * - 011b : SIRC clock as source; + * - 100b : LPO_CLK_32 clock as source; + * - 101b : LPO_CLK_1 clock as source; + */ +__attribute__((always_inline)) static inline void WdgReg_SetClockSource(WdgRegType *obj, uint8_t value) +{ + uint32_t csTmp = obj->CS; + + csTmp &= ~(WDG_CS_CLK_MASK); + csTmp |= (((uint32_t)(((uint32_t)(value)) << WDG_CS_CLK_SHIFT)) & WDG_CS_CLK_MASK); + obj->CS = csTmp; +} + +/*! \brief Verifies if the WDG windouw mode is enabled. + * + * This function verifies if the WDG windouw mode is enabled. + * + * \param[in] obj : pointer to WDG register instance + * \return Verifies if the WDG windouw mode is enabled + * - 000b : window mode is disabled; + * - 001b : window mode is enabled; + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_IsEnabledWinMode(const WdgRegType *obj) +{ + return ((obj->CS & WDG_CS_WIN_MASK) >> WDG_CS_WIN_SHIFT); +} + +/*! \brief Enable/disable the WDG windouw mode. + * + * This function enable/disable the WDG windouw mode. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : Enable/disable + * - 000b : disable; + * - 001b : enable; + */ +__attribute__((always_inline)) static inline void WdgReg_EnableWinMode(WdgRegType *obj, uint8_t value) +{ + uint32_t csTmp = obj->CS; + + csTmp &= ~(WDG_CS_WIN_MASK); + csTmp |= (((uint32_t)(((uint32_t)(value)) << WDG_CS_WIN_SHIFT)) & WDG_CS_WIN_MASK); + obj->CS = csTmp; +} + +/*! \brief Gets the WDG interrupt flag. + * + * This function gets the WDG interript flag. + * + * \param[in] obj : pointer to WDG register instance + * \return the WDG interrupt flag + * - 000b : disable; + * - 001b : enable; + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_GetInterruptFlag(WdgRegType *obj) +{ + return ((obj->CS & WDG_CS_FLG_MASK) >> WDG_CS_FLG_SHIFT); +} + +/*! \brief Sets the WDG interrupt flag. + * + * This bit is an interrupt indicator when INT is set in control and status register 1. Write 1 to clear it. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : pointer to clear value + * - 000b: No occurred. + * - 001b: clear interrupt flag + */ +__attribute__((always_inline)) static inline void WdgReg_ClearInterruptFlag(WdgRegType *obj, uint16_t value) +{ + uint32_t csTmp = obj->CS; + + csTmp &= ~(WDG_CS_FLG_MASK); + csTmp |= (((uint32_t)(((uint32_t)(value)) << WDG_CS_FLG_SHIFT)) & WDG_CS_FLG_MASK); + obj->CS = csTmp; +} + +/*! \brief Verifies if the WDG prescaler is enabled. + * + * This bit is an interrupt indicator when INT is set in control and status register 1. Write 1 to clear it. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to prescaler status + * - 000b: No occurred. + * - 001b: clear interrupt flag + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_IsEnabledPrescaler(const WdgRegType *obj) +{ + return ((obj->CS & WDG_CS_PRES_MASK) >> WDG_CS_PRES_SHIFT); +} + +/*! \brief Enable/disable the WDG prescaler. + * + * This function enable/disable the WDG prescaler. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : Enable/disable + * - 000b : disable; + * - 001b : enable; + */ +__attribute__((always_inline)) static inline void WdgReg_EnablePrescaler(WdgRegType *obj, uint8_t value) +{ + uint32_t csTmp = obj->CS; + + csTmp &= ~(WDG_CS_PRES_MASK); + csTmp |= (((uint32_t)(((uint32_t)(value)) << WDG_CS_PRES_SHIFT)) & WDG_CS_PRES_MASK); + obj->CS = csTmp; +} + +/*! \brief Verifies if the WDG prescaler is unlocked. + * + * this read-only bit indicates whether WDOG is unlocked or not. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to unlock status + * - 000b: WDG is locked. + * - 001b: WDG is unlocked. + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_IsUnlocked(WdgRegType *obj) +{ + return ((uint8_t)((obj->CS & WDG_CS_ULK_MASK) >> WDG_CS_ULK_SHIFT)); +} + +/*! \brief Verifies if the WDG configuration is successful. + * + * this read-only bit indicates whether the configuration is successful or not. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to configuration status + * - 000b: configuring WDG. + * - 001b: configuration is successful. + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_IsSuccessConfig(WdgRegType *obj) +{ + return ((uint8_t)((obj->CS & WDG_CS_RCS_MASK) >> WDG_CS_RCS_SHIFT)); +} + +/*! \brief Verifies if the synchronization of the WDG new configuration is done + * + * this flag indicate the synchronization of new configuration is done, next unlock seq is allowed if required + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to configuration status + * - 000b: synchronization is ongoing, next unlock seq is not allowed. + * - 001b: synchronization is done, next unlock seq is allowed if required. + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_IsDoneConfigSync(WdgRegType *obj) +{ + return ((uint8_t)((obj->CS & WDG_CS_CSD_MASK) >> WDG_CS_CSD_SHIFT)); +} + +/*! \brief Verifies if the WDG is enabled. + * + * Verifies if the WDG is enabled. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to enable status + * - 000b: watchdog disabled. + * - 001b: watchdog enabled. + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_IsEnabled(const WdgRegType *obj) +{ + return ((obj->CS & WDG_CS_EN_MASK) >> WDG_CS_EN_SHIFT); +} + +/*! \brief Enable/Disable the WDG . + * + * the function enable/disable the WDG . + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : pointer to WDG enable value + * - 000b: watchdog disable. + * - 001b: watchdog enable. + */ +__attribute__((always_inline)) static inline void WdgReg_Enable(WdgRegType *obj, uint8_t value) +{ + uint32_t csTmp = obj->CS; + + csTmp &= ~(WDG_CS_EN_MASK); + csTmp |= (((uint32_t)(((uint32_t)(value)) << WDG_CS_EN_SHIFT)) & WDG_CS_EN_MASK); + obj->CS = csTmp; +} + +/*! \brief Verifies if the WDG interrupt is enabled.. + * + * the function verifies if the WDG interrupt is enabled . + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to enable status + * - 000b: disabled. + * - 001b: enabled. + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_IsEnabledInterrupt(const WdgRegType *obj) +{ + return ((obj->CS & WDG_CS_INTR_MASK) >> WDG_CS_INTR_SHIFT); +} + +/*! \brief Enable/Disable the WDG interrupt. + * + * the function enable/disable the WDG interrupt. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : pointer to WDG enable value + * - 000b: disable. + * - 001b: enable. + */ +__attribute__((always_inline)) static inline void WdgReg_EnableInterrupt(WdgRegType *obj, uint8_t value) +{ + uint32_t csTmp = obj->CS; + + csTmp &= ~(WDG_CS_INTR_MASK); + csTmp |= (((uint32_t)(((uint32_t)(value)) << WDG_CS_INTR_SHIFT)) & WDG_CS_INTR_MASK); + obj->CS = csTmp; +} + +/*! \brief Verifies if allow update register. + * + * the function verifies if allow update register. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to allow status + * - 000b: updates not allowed. + * - 001b: update allowed. + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_IsEnabledUpdate(const WdgRegType *obj) +{ + return ((obj->CS & WDG_CS_UPDATE_MASK) >> WDG_CS_UPDATE_SHIFT); +} + +/*! \brief Enable/Disable the WDG update register. + * + * the function enable/disable the WDG update register. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : pointer to WDG enable value + * - 000b: disable. + * - 001b: enable. + */ +__attribute__((always_inline)) static inline void WdgReg_EnableUpdate(WdgRegType *obj, uint8_t value) +{ + uint32_t csTmp = obj->CS; + + csTmp &= ~(WDG_CS_UPDATE_MASK); + csTmp |= (((uint32_t)(((uint32_t)(value)) << WDG_CS_UPDATE_SHIFT)) & WDG_CS_UPDATE_MASK); + obj->CS = csTmp; +} + +/*! \brief Verifies if test mode is enabled. + * + * the function TST is cleared (0:0) on POR only. + * Any other reset does not affect the value of this field. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to status + * - 000b: watchdog test mode disable + * - 001b: watchdog user mode enable. (watchdog test mode disabled) + * - 010b: watchdog test mode enabled, only the low byte is used. + * - 011b: watchdog test mode enabled, only the high byte is used. + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_GetTestModeStatus(const WdgRegType *obj) +{ + return ((obj->CS & WDG_CS_TST_MASK) >> WDG_CS_TST_SHIFT); +} + +/*! \brief Enable/Disable the WDG test mode. + * + * the function enable/disable the WDG test mode. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : pointer to WDG enable value + * - 000b: watchdog test mode disable + * - 001b: watchdog user mode enable. (watchdog test mode disabled) + * - 010b: watchdog test mode enabled, only the low byte is used. + * - 011b: watchdog test mode enabled, only the high byte is used. + */ +__attribute__((always_inline)) static inline void WdgReg_SetTestMode(WdgRegType *obj, uint8_t value) +{ + uint32_t csTmp = obj->CS; + + csTmp &= ~(WDG_CS_TST_MASK); + csTmp |= (((uint32_t)(((uint32_t)(value)) << WDG_CS_TST_SHIFT)) & WDG_CS_TST_MASK); + obj->CS = csTmp; +} + +/*! \brief Verifies if enable debug mode. + * + * the function verifies if enable the WDG in debug mode. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to allow status + * - 000b: watchdog disable in chip stop mode. + * - 001b: watchdog enabled in chip stop mode + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_IsEnabledDebugMode(const WdgRegType *obj) +{ + return ((obj->CS & WDG_CS_DEBUG_MASK) >> WDG_CS_DEBUG_SHIFT); +} + +/*! \brief Enable/Disable the WDG in debug mode. + * + * the function enable/disable the WDG in debug mode. + * the reg is write-once bit. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : pointer to WDG enable value + * - 000b: watchdog disable in chip stop mode. + * - 001b: watchdog enabled in chip stop mode. + */ +__attribute__((always_inline)) static inline void WdgReg_EnableDebugMode(WdgRegType *obj, uint8_t value) +{ + uint32_t csTmp = obj->CS; + + csTmp &= ~(WDG_CS_DEBUG_MASK); + csTmp |= (((uint32_t)(((uint32_t)(value)) << WDG_CS_DEBUG_SHIFT)) & WDG_CS_DEBUG_MASK); + obj->CS = csTmp; +} + +/*! \brief Verifies if the WDG stop mode. + * + * the function verifies if the watchdog is eabled to operate in stop mode. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to status + * - 000b: disabled. + * - 001b: enabled. + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_IsEnabledStopMode(WdgRegType *obj) +{ + return ((obj->CS & WDG_CS_STOP_MASK) >> WDG_CS_STOP_SHIFT); +} + +/*! \brief Enable/Disable the WDG stop mode. + * + * the function enable/disable the WDG stop mode. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : pointer to WDG enable value + * - 000b: disable. + * - 001b: enable. + */ +__attribute__((always_inline)) static inline void WdgReg_EnableStopMode(WdgRegType *obj, uint8_t value) +{ + uint32_t csTmp = obj->CS; + + csTmp &= ~(WDG_CS_STOP_MASK); + csTmp |= (((uint32_t)(((uint32_t)(value)) << WDG_CS_STOP_SHIFT)) & WDG_CS_STOP_MASK); + obj->CS = csTmp; +} + +/*! \brief Gets the WDG CNT value. + * + * the function gets the WDG CNT value. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to CNT current value + * + */ +__attribute__((always_inline)) static inline uint32_t WdgReg_GetCntVal(const WdgRegType *obj) +{ + return obj->CNT; +} + +/*! \brief Sets the WDG CNT unlock key + * + * The WDG CNT registers is locked by default. + * Before writing registers, write unlock key to this register or refresh this register. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : CNT value + */ +__attribute__((always_inline)) static inline void WdgReg_SetCntVal(WdgRegType *obj, uint32_t value) +{ + obj->CNT = value; +} + +/*! \brief Gets the WDG CNT high 8 bits value . + * + * the function gets he WDG CNT high 8 bits value. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to CNT current high 8 bits value + * + */ +__attribute__((always_inline)) static inline uint32_t WdgReg_GetCntValHighBits(WdgRegType *obj) +{ + return ((obj->CNT & WDG_CNT_HIGH_MASK) >> WDG_CNT_HIGH_SHIFT); +} + +/*! \brief Gets the WDG CNT low 8 bits value . + * + * the function gets he WDG CNT low 8 bits value. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to CNT current low 8 bits value + * + */ +__attribute__((always_inline)) static inline uint32_t WdgReg_GetCntValLowBits(WdgRegType *obj) +{ + return ((obj->CNT & WDG_CNT_LOW_MASK) >> WDG_CNT_LOW_SHIFT); +} + +/*! \brief Gets the WDG Timeout configuration value. + * + * the function gets the WDG Timeout configuration value. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to TOVAL current value + * + */ +__attribute__((always_inline)) static inline uint32_t WdgReg_GetToval(const WdgRegType *obj) +{ + return obj->TOVAL; +} + +/*! \brief Sets the WDG Timeout Configuration value + * + * The WDG TOVAL registers is locked by default. + * Before writing registers, write unlock key to CNT register. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : pointer to configuration value + */ +__attribute__((always_inline)) static inline void WdgReg_SetToval(WdgRegType *obj, uint32_t value) +{ + obj->TOVAL = value; +} + +/*! \brief Gets the WDG Timeout high 8 bits value . + * + * the function gets he WDG Timeout high8 bits value. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to current Timeout high 8 bits value + * + */ +__attribute__((always_inline)) static inline uint32_t WdgReg_GetTovalHighBits(WdgRegType *obj) +{ + return ((obj->TOVAL & WDG_TOVAL_HIGH_MASK) >> WDG_TOVAL_HIGH_SHIFT); +} + +/*! \brief Gets the WDG Timeout low 8 bits value . + * + * the function gets he WDG Timeout low 8 bits value. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to Timeout current low 8 bits value + * + */ +__attribute__((always_inline)) static inline uint32_t WdgReg_GetTovalLowBits(WdgRegType *obj) +{ + return ((obj->TOVAL & WDG_TOVAL_LOW_MASK) >> WDG_TOVAL_LOW_SHIFT); +} + +/*! \brief Gets the WDG window configuration value. + * + * the function gets the WDG window configuration value. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to TOVAL current value + * + */ +__attribute__((always_inline)) static inline uint32_t WdgReg_GetWinVal(const WdgRegType *obj) +{ + return obj->WIN; +} + +/*! \brief Sets the WDG window Configuration value + * + * The WDG WIN registers is locked by default. + * Before writing registers, write unlock key to CNT register. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : pointer to configuration value + */ +__attribute__((always_inline)) static inline void WdgReg_SetWinVal(WdgRegType *obj, uint32_t value) +{ + obj->WIN = value; +} + +/*! \brief Gets the WDG window high 8 bits value . + * + * the function gets he WDG window high8 bits value. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to current window high 8 bits value + * + */ +__attribute__((always_inline)) static inline uint32_t WdgReg_GetWinValHighBits(WdgRegType *obj) +{ + return ((obj->WIN & WDG_WIN_HIGH_MASK) >> WDG_WIN_HIGH_SHIFT); +} + +/*! \brief Gets the WDG window low 8 bits value . + * + * the function gets he WDG window low 8 bits value. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to window current low 8 bits value + * + */ +__attribute__((always_inline)) static inline uint32_t WdgReg_GetWinValLowBits(WdgRegType *obj) +{ + return ((obj->WIN & WDG_WIN_LOW_MASK) >> WDG_WIN_LOW_SHIFT); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _WDG_REG_H_ */ diff --git a/cva_asw_m0118/bat_complier_object/InfoWindow2.dll b/cva_asw_m0118/bat_complier_object/InfoWindow2.dll new file mode 100644 index 0000000..5683215 Binary files /dev/null and b/cva_asw_m0118/bat_complier_object/InfoWindow2.dll differ diff --git a/cva_asw_m0118/bat_complier_object/convert_hex.bat b/cva_asw_m0118/bat_complier_object/convert_hex.bat new file mode 100644 index 0000000..6274df5 --- /dev/null +++ b/cva_asw_m0118/bat_complier_object/convert_hex.bat @@ -0,0 +1,5 @@ +@echo off +set curdir=%~dp0 +cd /d %curdir% +convert_hex ..\Debug_FLASH\Exe\cva_asw_m0118.srec /FA /FR:0x10000-0x37FFB /FP:FF /CS9:@0x37FFC /XS:32 -o cva_asw_m0118_iar.s19 +convert_hex cva_asw_m0118_iar.s19 /XI:32 -o cva_asw_m0118_iar.hex \ No newline at end of file diff --git a/cva_asw_m0118/bat_complier_object/convert_hex.exe b/cva_asw_m0118/bat_complier_object/convert_hex.exe new file mode 100644 index 0000000..f59e15d Binary files /dev/null and b/cva_asw_m0118/bat_complier_object/convert_hex.exe differ diff --git a/cva_asw_m0118/bat_complier_object/cva_asw_m0118_iar.hex b/cva_asw_m0118/bat_complier_object/cva_asw_m0118_iar.hex new file mode 100644 index 0000000..5346918 --- /dev/null +++ b/cva_asw_m0118/bat_complier_object/cva_asw_m0118_iar.hex @@ -0,0 +1,5124 @@ +:020000021000EC +:20000000F05F00200D980100332D01002B42010000000000000000000000000000000000FC +:200020000000000000000000000000007B4201000000000000000000674301000D560100F3 +:20004000D09A0100D09A0100D09A0100D09A0100D09A0100D09A0100D09A0100D09A010048 +:20006000D09A01002F560100D09A0100D09A0100D09A0100D09A0100D09A0100D09A01000D +:20008000D09A0100D09A0100D09A0100D09A0100D09A0100D09A0100D09A0100D09A010008 +:2000A000F7710100D09A0100D09A0100D09A0100D09A0100D09A0100D09A0100D09A0100EA +:2000C000DDCCBBAA31333A33353A33320000000044656320313220323032340000000000F6 +:2000E0005357303130315F32303234313231310000000000000000000000000000000000A8 +:2001000000B583680122DB681340DBB2002B0AD083681B6A9B081A40D2B2002A03D0C069DD +:200120000860012000E0002000BD70B500231C008568EE68012296430122E4B21440344352 +:20014000EC600978002943D0C169224CA14201D11D0012E0C169BA4CA14201D215000CE053 +:20016000C169B84CA14201D2022506E0C169B64CA14201D2032500E004252900C9B20429AA +:2001800001D1002025E08168CC680C26B443EDB2AE000C2535402543CD608168CC68102548 +:2001A000AC43DBB21B0110252B402343CB6011008368DC680125AC43C9B211402143D960B8 +:2001C0008168096A8B0811001940C9B20029F7D0012070BD00093D0000B58268126A530851 +:2001E0001A00D207D20FD2B2002A03D080690860012000E0002000BD7CB504000D00002019 +:20020000A16801264A6931001140C9B200295BD0A1680A6A31001140C9B2002954D0A168DA +:2002200089690A0931001140C9B2002902D0012905D009E069462000FFF762FF04E0694620 +:200240002000FFF7C9FFFFE7C0B2002801D100203BE03100A0684069000A8007800FC0B2BF +:20026000002805D0022807D004D3032806D007E0310005E0022103E0042101E00821FFE790 +:20028000A0684069400843065B0EDBB2002B01D18023FFE7A0684069C00A4207520FD2B2F7 +:2002A000002A01D10822FFE7A0684069800A34000440E4B2641C00985843604351434900B6 +:2002C00002F0DFFC28603000C0B276BDF1B500242000009A9268556901239D430123C0B21E +:2002E00018402843506118004A78002A02D0012A0DD019E02600009A9568AA691027BA43AF +:20030000F6B2360110273E401643AE610DE01E00009A9568AA691027BA43F6B236011027E2 +:200320003E401643AE6100E020000200D2B2002A01D1002081E0CA68012A01D126000FE090 +:20034000CA68022A01D11E000AE0CA68042A01D1022605E0CA68082A01D1032600E0FF26C2 +:200360003200D2B2FF2A01D1002066E0009A92685769BD4D3D40F6B23702C026B6003E4090 +:200380002E4356614A88002A18D04A88812A15DA4A88802A01D1220000E04A88009DAD6811 +:2003A0006E69FE27BE43D2B25700FE223A4032436A610A69002A03D100203EE000203CE0A0 +:2003C0000A69092AF8D20A69082A00D00C69009A92685669A54D3540E4B2E602E024A401E2 +:2003E00034402C4354618A68012A02D08A68022A24D18D686D1E009A926856699C4C344034 +:20040000EDB2AD028026F6003540254355610978002911D01900009A926854690125AC4355 +:20042000C9B2194021435161009989680A6A19001140C9B20029F7D0C0B2F2BD0020FCE7DB +:2004400001127A0001366E01015A6202F8B504000E0000270020009060690125C0690109F2 +:2004600028000840C0B2002817D069462000FFF747FE07003800C0B200280ED06069C069D8 +:20048000000A4007400F85402900412904D2009802F0F7FB306000E000273800C0B2F2BD22 +:2004A000FCB500226B461A7016004569EF691023DB431F401024F6B2360126403E43EE6119 +:2004C0008D88012D01D115001EE08D88022D01D1012519E08D88042D01D1022514E08D8877 +:2004E000082D01D103250FE08D88102D01D104250AE08D88202D01D1052505E08D88402DE2 +:2005000001D1062500E007252E00F6B2072E14D06E4635704569EF699A4E3E400196019FE7 +:20052000BC466E4636783702E026F6003E4067463E43EE6101256E4635700978002901D02D +:200540000122FFE74069C1690B40D2B211010C401C43C46168460078F6BDF8B504000E0076 +:20056000002700200090606901258069010928000840C0B2002817D069462000FFF7C0FD4F +:2005800007003800C0B200280ED060698069000A4007400F85402900412904D2009802F09A +:2005A00070FB306000E000273800C0B2F2BDFCB500226B461A7016004569AF691023DB43A5 +:2005C0001F401024F6B2360126403E43AE618D88012D01D115001EE08D88022D01D101254F +:2005E00019E08D88042D01D1022514E08D88082D01D103250FE08D88102D01D104250AE065 +:200600008D88202D01D1052505E08D88402D01D1062500E007252E00F6B2072E14D06E4669 +:2006200035704569AF69574E3E400196019FBC466E4636783702E026F6003E4067463E43B0 +:20064000AE6101256E4635700978002901D00122FFE7406981690B40D2B211010C401C4369 +:20066000846168460078F6BDFFFCFFFFFFC7FFFFFFFBFFFFF8B504000E0000270020009071 +:20068000606901254069010928000840C0B2002817D069462000FFF79FFD07003800C0B2B5 +:2006A00000280ED060694069000A4007400F85402900412904D2009802F0E3FA306000E01D +:2006C00000273800C0B2F2BDFCB500226B461A70160045696F691023DB431F401024F6B264 +:2006E000360126403E436E618D88012D01D115001EE08D88022D01D1012519E08D88042D6A +:2007000001D1022514E08D88082D01D103250FE08D88102D01D104250AE08D88202D01D14E +:20072000052505E08D88402D01D1062500E007252E00F6B2072E14D06E46357045696F6951 +:20074000104E3E400196019FBC466E4636783702E026F6003E4067463E436E6101256E4698 +:2007600035700978002901D00122FFE7406941690B40D2B211010C401C43446168460078A6 +:20078000F6BD0000FFF8FFFFF8B504000E0000270020009060690125006901092800084049 +:2007A000C0B2002817D069462000FFF715FD07003800C0B200280ED060690069000A4007A7 +:2007C000400F85402900412904D2009802F059FA306000E000273800C0B2F2BDFCB50022FC +:2007E0006B461A70160045692F691023DB431F401024F6B2360126403E432E618D88012DE6 +:2008000001D115001EE08D88022D01D1012519E08D88042D01D1022514E08D88082D01D16F +:2008200003250FE08D88102D01D104250AE08D88202D01D1052505E08D88402D01D10625A8 +:2008400000E007252E00F6B2072E14D06E46357045692F69974E3E400196019FBC466E46AE +:2008600036783702E026F6003E4067463E432E6101256E4635700978002901D00122FFE757 +:20088000406901690B40D2B211010C401C43046168460078F6BDF8B504000E000027002075 +:2008A000009060690125406A010928000840C0B2002817D069462000FFF79EFC0700380076 +:2008C000C0B200280ED06069406A000A4007400F85402900412904D2009802F0D2F930607A +:2008E00000E000273800C0B2F2BDFCB500226B461A70160045696F6A1023DB431F40102409 +:20090000F6B2360126403E436E628D88012D01D115001EE08D88022D01D1012519E08D88CF +:20092000042D01D1022514E08D88082D01D103250FE08D88102D01D104250AE08D88202DCD +:2009400001D1052505E08D88402D01D1062500E007252E00F6B2072E14D06E463570456935 +:200960006F6A544E3E400196019FBC466E4636783702E026F6003E4067463E436E6201250C +:200980006E4635700978002901D00122FFE74069416A0B40D2B211010C401C434462684646 +:2009A0000078F6BDF8B504000E0000270020009060690125006A010928000840C0B2002809 +:2009C00017D069462000FFF717FC07003800C0B200280ED06069006A000A4007400F854009 +:2009E0002900412904D2009802F04BF9306000E000273800C0B2F2BDFCB500226B461A70C2 +:200A0000160045692F6A1023DB431F401024F6B2360126403E432E628D88012D01D1150015 +:200A20001EE08D88022D01D1012519E08D88042D01D1022514E08D88082D01D103250FE01D +:200A40008D88102D01D104250AE08D88202D01D1052505E08D88402D01D1062500E0072591 +:200A60002E00F6B2072E14D06E46357045692F6A104E3E400196019FBC466E463678370237 +:200A8000E026F6003E4067463E432E6201256E4635700978002901D00122FFE74069016A07 +:200AA0000B40D2B211010C401C43046268460078F6BD0000FFF8FFFF80B50A00002143696A +:200AC0001B681B0E9B079B0FDBB2002B05D0022B0DD007D3032B0FD013E01100FFF77CFB2F +:200AE00001000EE01100FFF70BFB010009E01100FFF782FB010004E01100FFF76DFB010037 +:200B0000FFE70800C0B202BD30B54A78012A01D100210AE04A78002A01D1012105E0497881 +:200B2000022901D1022100E0FF210A00D2B2FF2A01D1002016E00A0043691C688B4D25407F +:200B4000D2B21404C022920222402A431A6042691268120E9207920F0B00D2B2DBB29A42C3 +:200B6000F5D1012030BD7CB504000D00002069462000FFF7A1FF06003000C0B2002801D138 +:200B800000200BE0E06800680107090F0098C9B2491C02F076F828603000C0B276BD00B590 +:200BA0008A88002A0FD08A88112A0CDA8988491EC06802680F239A43C9B20907090F1143D7 +:200BC0000160012000E0002000BD7CB504000D00002069462000FFF7C6FF06003000C0B242 +:200BE000002801D100200CE060690068000A0107090F0098C9B2491C02F043F82860300037 +:200C0000C0B276BD00B58A88002A11D08A88112A0EDA8988491E40690268554B1340C9B22F +:200C20000A02F0210901114019430160012000E0002000BDF8B504000D00002637002069FD +:200C4000C8214058000C8007800FC0B2002805D002280FD008D3032812D017E069462000CB +:200C6000FFF7BAFA070011E069462000FFF748FA07000BE069462000FFF7BEFA070005E070 +:200C800069462000FFF7A8FA0700FFE73800C0B2002801D1002019E02069C821405801092F +:200CA0000800C007C00FC0B200280CD02069C8214058000A0107090F0098C9B2491C01F083 +:200CC000E0FF286000E037003800C0B2F2BD30B54A78012A01D100220AE04A78002A01D1CF +:200CE000012205E04A78022A01D1022200E0FF221300DBB2FF2B01D1002036E08B88002BF7 +:200D000032D08B88112B2FDA0369C8241C59174D2540D2B21404C022920222402A43C82416 +:200D20001A518B885B1E0269C8241459104D2540DBB21C02F0231B0123402B43C82413513B +:200D40000978002901D0012100E000210069C822825810239A43C9B2090110231940114353 +:200D6000C8228150012000E0002030BDFFFFFCFFFFF0FFFFF8B504000D006069406801098B +:200D80000800C007C00FC0B2002801D100209BE0002007000090606907264068000C3040DD +:200DA000C0B2002843D160694068C00C3040C0B200280BD0022815D00ED304281ED017D36F +:200DC000062827D020D307282AD02FE069462000FFF730FF070066E069462000FFF790F934 +:200DE000070060E069462000FFF7F6F907005AE069462000FFF700FA070054E069462000EE +:200E0000FFF7B1FE07004EE069462000FFF7DDFE070048E069462000FFF718FB070042E028 +:200E200069462000FFF726FC07003CE03BE060694068000C3040C0B201280AD033D30328FA +:200E400013D00CD305281CD015D3072825D01ED329E069462000FFF71EFD070023E0694618 +:200E6000200000F0EFF907001DE06946200000F0C5F9070017E06946200000F09BF90700A1 +:200E800011E06946200000F0ABFC07000BE069462000FFF7A1F9070005E069462000FFF7F9 +:200EA0009BF90700FFE73800C0B201280AD160694068000A064031000098C9B2491C01F0A8 +:200EC000E0FE28603800C0B2F2BDF2B5012319000024260045696A681027BA43F6B2360192 +:200EE00010273E4016436E60009A5278002A39D0012A50D0022A67D0032A00D1AFE0052A15 +:200F000000D1C5E0072A00D1DBE00A2A75D00B2A00D18BE00C2A0CD00F2A00D1F8E0102A86 +:200F200000D1E8E0112A00D1D8E01A2A00D1FCE008E12600426957689A4D3D40F6B23704A3 +:200F4000E026F6023E402E435660260042695768954D3D40F6B2F704E026B6033E402E43AE +:200F60005660F0E02600426957688E4D3D40F6B23704E026F6023E402E4356601E004269B4 +:200F80005768894D3D40F6B2F704E026B6033E402E435660D7E0260042695768814D3D40A6 +:200FA000F6B23704E026F6023E402E4356600226426957687C4D3D40F6B2F704E026B60371 +:200FC0003E402E435660BEE0260042695768754D3D40F6B23704E026F6023E402E43566079 +:200FE000032642695768704D3D40F6B2F704E026B6033E402E435660A5E026004269576808 +:20100000684D3D40F6B23704E026F6023E402E435660042642695768634D3D40F6B2F704B4 +:20102000E026B6033E402E4356608CE02600426957685C4D3D40F6B23704E026F6023E40CB +:201040002E435660052642695768574D3D40F6B2F704E026B6033E402E43566073E0260033 +:20106000426957684F4D3D40F6B23704E026F6023E402E4356600626426957684A4D3D40BD +:20108000F6B2F704E026B6033E402E4356605AE0260042695768434D3D40F6B23704E02689 +:2010A000F6023E402E4356600726426957683E4D3D40F6B2F704E026B6033E402E435660ED +:2010C00041E01E0042695768364D3D40F6B23704E026F6023E402E43566034E002264269FA +:2010E0005768304D3D40F6B23704E026F6023E402E43566027E0032642695768294D3D4024 +:20110000F6B23704E026F6023E402E4356601AE0042642695768234D3D40F6B23704E026E5 +:20112000F6023E402E4356600DE00526426957681C4D3D40F6B23704E026F6023E402E43DA +:20114000566000E021000A00D2B2002A17D0009A9288002A12D0009A9288092A0EDA009A10 +:201160009688761E426957686D4D3D40F6B23702E026F6003E402E43566000E02100009AFF +:201180001278002A00D12300406942681024A243DBB21B0110242340134343600800C0B288 +:2011A000F2BD0000FFFFF8FFFFFFC7FF006A08600120704700B54068806C02091000C007F2 +:2011C000C00FC0B2002804D0FA2080000860012000E0002000BD00B50978002901D00121A0 +:2011E00000E000214068826C10239A43C9B209011023194011438164012000BD00B54068C3 +:20120000406C02091000C007C00FC0B2002804D0FA20C0010860012000E0002000BD00B52D +:201220000978002901D0012100E000214068426C10239A43C9B209011023194011434164A0 +:20124000012000BDFA20400208600120704710B50200002054680123646824091C40E4B262 +:20126000002C01D1002015E054686468240C1C40E4B2002C03D11000FFF775FC09E0546895 +:201280006468240C2340DBB2012B02D1100000F009F9C0B210BDF3B5002211001600436886 +:2012A0005F681024E44327401025F6B236012E403E435E60019B5B780A2B0DD116004368A1 +:2012C0005F6818493940F6B2360480277F023E400E435E60012112E0019B5B78182B0ED131 +:2012E000012143685F680F4E3E400096009EC9B2090480277F023940314359600121019B37 +:201300001B78002B01D00122FFE7406843681C40D2B212011540254345600800C0B2F6BD60 +:20132000FFF8FFFFFFFFFEFF10B50A00002143689B681C092300DB07DB0FDBB2002B03D080 +:201340001100FFF742FC01000800C0B210BD00B50978002901D0012100E00021406882681B +:2013600010239A43C9B209011023194011438160012000BD10B50A0000214368DB681C0936 +:201380002300DB07DB0FDBB2002B03D01100FFF71CFC01000800C0B210BD00B5097800290D +:2013A00001D0012100E000214068C26810239A43C9B20901102319401143C160012000BDF3 +:2013C00010B50A00002143681B691C092300DB07DB0FDBB2002B03D01100FFF7F6FB010056 +:2013E0000800C0B210BD00B50978002901D0012100E000214068026910239A43C9B20901AB +:201400001023194011430161012000BD10B50A00002143685B691C092300DB07DB0FDBB2AC +:20142000002B03D01100FFF7D0FB01000800C0B210BD00B50978002901D0012100E0002141 +:201440004068426910239A43C9B209011023194011434161012000BD10B50A0000214368A9 +:201460009B691C092300DB07DB0FDBB2002B03D01100FFF7AAFB01000800C0B210BD00B520 +:201480000978002901D0012100E000214068826910239A43C9B209011023194011438161C4 +:2014A000012000BDF8B504000D000020070000906068C06901090800C007C00FC0B20028A6 +:2014C00001D1002054E060680726C069000C3040C0B200280BD0022815D00ED304281ED0CD +:2014E00017D3062827D020D307282AD02FE069462000FFF7BFF8070029E069462000FEF762 +:20150000A5FF070023E069462000FFF7C4F907001DE069462000FFF795FE070017E0694692 +:201520002000FFF747FE070011E069462000FFF765FE07000BE069462000FFF737FE07003D +:2015400005E069462000FFF795F80700FFE73800C0B200280AD06068C069000A0640310049 +:20156000C9B2491C009801F08CFB28603800C0B2F2BDF2B501231900002426004568EA696C +:201580001027BA43F6B2360110273E401643EE61009A5278032A19D0052A0AD0072A22D035 +:2015A0000E2A54D00F2A38D0102A43D0112A27D05AE026004268D769CC4D3D40F6B237044C +:2015C000E026F6023E402E43D6614EE01E004268D769C64D3D40F6B23704E026F6023E40C2 +:2015E0002E43D66141E002264268D769BF4D3D40F6B23704E026F6023E402E43D66134E06C +:2016000003264268D769B94D3D40F6B23704E026F6023E402E43D66127E004264268D76912 +:20162000B24D3D40F6B23704E026F6023E402E43D6611AE005264268D769AC4D3D40F6B2FA +:201640003704E026F6023E402E43D6610DE006264268D769A54D3D40F6B23704E026F602D8 +:201660003E402E43D66100E02100009A9288002A12D0009A9288092A0EDA009A9688761E68 +:201680004268D769BA4D3D40F6B23702E026F6003E402E43D66100E02100009A1278002A8A +:2016A00000D123004068C2691024A243DBB21B01102423401343C3610800C0B2F2BD10B5A2 +:2016C0000200002054680123246A24091C40E4B2002C01D100201FE05468246A240CA40719 +:2016E000A40FE4B2002C05D0022C0BD006D3032C0CD010E01000FEF7BDFF0CE01000FFF710 +:20170000CAF808E01000FEF7A1FE04E0FA20400208601800FFE7C0B210BDF3B501210A00C2 +:201720006B461A70002216004468256A10239D431023F6B236011E402E432662019C647806 +:20174000032C20D0052C04D0072C0FD0112C27D033E016004468276AC54D3D40F6B2370447 +:20176000C026B6023E402E43266228E00E004468276ABF4D3D40F6B23704C026B6023E4079 +:201780002E4326621BE002264468276AB84D3D40F6B23704C026B6023E402E4326620EE088 +:2017A00003264468276AB24D3D40F6B23704C026B6023E402E43266201E06C462270019C8D +:2017C0002478002C00D111004068026A1024A243C9B209010B401343036268460078F6BDCE +:2017E00010B50200002053689B6A1C092300DB07DB0FDBB2002B01D100201EE053689B6AC6 +:201800001B0C9B079B0FDBB2002B05D0022B0BD006D3032B0CD00FE01000FFF7EFFC0BE012 +:201820001000FFF7C3FC07E01000FFF7C3FC03E01000FFF7BFFCFFE7C0B210BDF3B50022A4 +:201840001100160043689F6A1024E44327401025F6B236012E403E439E62019B5B78102B3E +:201860000DD1160041688F6A814B3B40F6B23704C026B6023E401E438E62012124E0019B79 +:201880005B780E2B0FD1012143689F6A784E3E400096009EC9B20F04C02189023940314327 +:2018A0009962012110E0019B5B780F2B0CD1022641688F6A6E4B3B40F6B23704C026B60216 +:2018C0003E401E438E620121019B1B78002B01D00122FFE74068836A1C40D2B21201154006 +:2018E000254385620800C0B2F6BD0000FFFFF8FF10B50200002054680123246B240C1C4095 +:20190000E4B2002C03D11000FFF75FF909E05468246B240C2340DBB2012B02D11000FFF77A +:2019200091FCC0B210BD10B50200002318004C780B2C0BD151680A6B8D4C1440DBB21A04FC +:2019400080235B021A4022430A630EE0497811290BD101215268136B854C1C40C9B2090487 +:2019600080235B02194021431163C0B210BD0000FFF8FFFF10B50200002054680123646B6C +:20198000240C1C40E4B2002C03D11000FFF71DF909E05468646B240C2340DBB2012B02D176 +:2019A0001000FFF74FFCC0B210BD10B50200002318004C780B2C0BD151684A6B6C4C144044 +:2019C000DBB21A0480235B021A4022434A630EE0497811290BD101215268536B644C1C4085 +:2019E000C9B2090480235B02194021435163C0B210BD10B50200002054680123A46B240CA9 +:201A00001C40E4B2002C03D11000FFF7DEF809E05468A46B240C2340DBB2012B02D1100015 +:201A2000FFF710FCC0B210BD10B50200002318004C780B2C0BD151688A6B4D4C1440DBB264 +:201A40001A0480235B021A4022438A630EE0497811290BD101215268936B454C1C40C9B2B5 +:201A6000090480235B02194021439163C0B210BDFFFFFCFF10B50200002054680123E46B5A +:201A8000240C1C40E4B2002C03D11000FFF79DF809E05468E46B240C2340DBB2012B02D176 +:201AA0001000FFF7CFFBC0B210BD10B50200002318004C780B2C0BD15168CA6B2C4C144084 +:201AC000DBB21A0480235B021A402243CA630EE0497811290BD101215268D36B244C1C40C4 +:201AE000C9B2090480235B0219402143D163C0B210BD10B50200002054680123246C240CA7 +:201B00001C40E4B2002C03D11000FFF75EF809E05468246C240C2340DBB2012B02D1100013 +:201B2000FFF790FBC0B210BD10B50200002318004C780B2C0BD151680A6C0D4C1440DBB2A3 +:201B40001A0480235B021A4022430A640EE0497811290BD101215268136C054C1C40C9B2F2 +:201B6000090480235B02194021431164C0B210BDFFFFFEFF10B50200002014680123E46819 +:201B800024091C40E4B2002C03D11000FFF71DF80AE01268D26812091A40D2B2012A03D175 +:201BA000FA20400208601800C0B210BD10B50200002318004C780B2C0BD11068C16810225E +:201BC0009143DBB21A0110231A400A43C26001200EE0497811290BD1012001001268D368D0 +:201BE0001024A343C9B20901102421401943D160C0B210BD80B50269126813091A00D207BC +:201C0000D20FD2B2002A01D1002001E0FEF7ABFF02BD00B50978002901D0012100E00021B1 +:201C20000069026810239A43C9B209011023194011430160012000BD80B5026952681309A7 +:201C40001A00D207D20FD2B2002A01D1002001E0FEF7BBFF02BD00B50978002901D001216F +:201C600000E000210069426810239A43C9B209011023194011434160012000BD80B50269BC +:201C8000126913091A00D207D20FD2B2002A01D1002001E0FEF799FF02BD00B509780029AD +:201CA00001D0012100E000210069026910239A43C9B209011023194011430161012000BDA7 +:201CC00080B50269526913091A00D207D20FD2B2002A01D1002001E0FEF777FF02BD00B559 +:201CE0000978002901D0012100E000210069426910239A43C9B2090110231940114341611B +:201D0000012000BD80B50269926913091A00D207D20FD2B2002A01D1002001E0FEF723FFC2 +:201D200002BD00B50978002901D0012100E000210069826910239A43C9B20901102319401C +:201D400011438161012000BD80B50269D26913091A00D207D20FD2B2002A01D1002001E023 +:201D6000FEF733FF02BD00B50978002901D0012100E000210069C26910239A43C9B2090101 +:201D8000102319401143C161012000BDF8B504000E0020690125006A010928000840C0B29F +:201DA000002801D1002035E02800002700972069006A000C8007800FC0B2002805D0022860 +:201DC0000FD008D3032812D017E069462000FEF703FA070011E069462000FEF791F9070037 +:201DE0000BE069462000FEF707FA070005E069462000FEF7F1F90700FFE72069006A000AAF +:201E00008007800F85402900009800F03AFF30603800C0B2F2BDFCB500231A001F00066998 +:201E2000356A1024A5431024FFB23F0127402F4337624D78012D01D11D000AE04D78002D92 +:201E400001D1012505E04D78022D01D1022500E0FF252E00F6B2FF2E0BD00269176AA24EFA +:201E60003E40EDB22F04C025AD023D403543156201221500EDB2002D2CD08D88012D01D1FD +:201E80001D000FE08D88022D01D101250AE08D88042D01D1022505E08D88082D01D10325A8 +:201EA00000E0FF252E00F6B2FF2E12D06E46357005692F6A8D4E3E400196019FBC466E4693 +:201EC00036783702C026B6003E4067463E432E6200E01A000978002901D00123FFE700695B +:201EE000016A1025A943DBB21B011C400C4304621000C0B2F6BD80B50269926A13091A0095 +:201F0000D207D20FD2B2002A01D1002001E0FEF75CFE02BD00B50978002901D0012100E046 +:201F200000210069826A10239A43C9B209011023194011438162012000BD80B50369012231 +:201F40001B6B1B091340DBB2002B01D100201BE00269126B120C9207920FD2B2002A05D01C +:201F6000022A09D005D3032A09D00BE0FEF782FB09E0FEF76BFA06E0FEF78DFC03E0FEF7A2 +:201F800079FB00E00020C0B202BDF2B500221100160003691F6B1024E44327401025F6B217 +:201FA00036012E403E431E63009B5B78052B01D113000CE0009B5B78032B01D1012306E093 +:201FC000009B5B78072B01D1022300E0FF231E00F6B2FF2E0BD001690F6B434E3E40DBB21A +:201FE0001F04C0239B023B4033430B630121009B1B78002B01D00122FFE70069036B1C4057 +:20200000D2B212011540254305630800C0B2F2BD80B5036901225B6B1B091340DBB2002B22 +:2020200001D100201BE00269526B120C9207920FD2B2002A05D0022A09D005D3032A09D0CD +:202040000BE0FEF717FB09E0FEF700FA06E0FEF722FC03E0FEF70EFB00E00020C0B202BDAB +:20206000F2B500221100160003695F6B1024E44327401025F6B236012E403E435E63009B19 +:202080005B78052B01D113000CE0009B5B78032B01D1012306E0009B5B78072B01D102235D +:2020A00000E0FF231E00F6B2FF2E0BD001694F6B0D4E3E40DBB21F04C0239B023B40334332 +:2020C0004B630121009B1B78002B01D00122FFE70069436B1C40D2B212011540254345638E +:2020E0000800C0B2F2BD0000FFFFFCFFFFFCFFFF80B5036901221B6C1B091340DBB2002B4B +:2021000001D100201BE00269126C120C9207920FD2B2002A05D0022A09D005D3032A09D02B +:202120000BE0FEF7A7FA09E0FEF790F906E0FEF7B2FB03E0FEF79EFA00E00020C0B202BD8E +:20214000F2B500221100160003691F6C1024E44327401025F6B236012E403E431E64009BB6 +:202160005B78052B01D113000CE0009B5B78032B01D1012306E0009B5B78072B01D102237C +:2021800000E0FF231E00F6B2FF2E0BD001690F6CAD4E3E40DBB21F04C0239B023B403343F0 +:2021A0000B640121009B1B78002B01D00122FFE70069036C1C40D2B212011540254305646A +:2021C0000800C0B2F2BD80B5036901225B6C1B091340DBB2002B01D100201BE00269526C06 +:2021E000120C9207920FD2B2002A05D0022A09D005D3032A09D00BE0FEF73CFA09E0FEF72D +:2022000025F906E0FEF747FB03E0FEF733FA00E00020C0B202BDF2B50022110016000369F1 +:202220005F6C1024E44327401025F6B236012E403E435E64009B5B78052B01D113000CE0DD +:20224000009B5B78032B01D1012306E0009B5B78072B01D1022300E0FF231E00F6B2FF2E7A +:202260000BD001694F6C784E3E40DBB21F04C0239B023B4033434B640121009B1B78002BCF +:2022800001D00122FFE70069436C1C40D2B212011540254345640800C0B2F2BD80B5036929 +:2022A00001229B6C1B091340DBB2002B01D100201BE00269926C120C9207920FD2B2002A69 +:2022C00005D0022A09D005D3032A09D00BE0FEF7D1F909E0FEF7BAF806E0FEF7DCFA03E078 +:2022E000FEF7C8F900E00020C0B202BDF2B500221100160003699F6C1024E4432740102599 +:20230000F6B236012E403E439E64009B5B78052B01D113000CE0009B5B78032B01D10123EC +:2023200006E0009B5B78072B01D1022300E0FF231E00F6B2FF2E0BD001698F6C974E3E4088 +:20234000DBB21F04C0239B023B4033438B640121009B1B78002B01D00122FFE70069836CC0 +:202360001C40D2B212011540254385640800C0B2F2BD80B5036901221B6E1B091340DBB24A +:20238000002B01D100201BE00269126E120C9207920FD2B2002A05D0022A09D005D3032A55 +:2023A00009D00BE0FEF766F909E0FEF74FF806E0FEF771FA03E0FEF75DF900E00020C0B2FA +:2023C00002BDF2B500221100160003691F6E1024E44327401025F6B236012E403E431E660C +:2023E000009B5B78052B01D113000CE0009B5B78032B01D1012306E0009B5B78072B01D184 +:20240000022300E0FF231E00F6B2FF2E0BD001690F6E624E3E40DBB21F04C0239B023B4007 +:2024200033430B660121009B1B78002B01D00122FFE70069036E1C40D2B2120115402543D6 +:2024400005660800C0B2F2BDFFFFFCFF7CB505000C0029690120496E0A0901001140C9B263 +:20246000002901D1002037E0002600962869406E000C8007800FC0B2002805D002280FD095 +:2024800008D3032812D017E069462800FDF7A4FE060011E069462800FDF732FE06000BE00D +:2024A00069462800FDF7A8FE060005E069462800FDF792FE0600FFE72869406E000A8106A9 +:2024C000890EC9B2491C022900D20221009800F0D8FB20603000C0B276BDF3B501000022EA +:2024E000100016000C69656E10239D431023F6B236011E402E436666019C6478012C01D136 +:2025000014000CE0019C6478002C01D1012406E0019C6478022C01D1022400E0FF24250072 +:20252000EDB2FF2D0BD00869466E1C4D3540E4B22604C024A40234402C43446601200400F6 +:20254000E4B2002C18D0019CA488A41E3F2C12D2019CA5886D1E0C69666E0096009F104EC6 +:202560003E400096009EEDB22F02FC25AD013D403543656600E01000019C2478002C01D024 +:202580000122FFE709694C6E1025AC43D2B21201134023434B66C0B2F6BD0000FFFFFCFFC3 +:2025A000FFC0FFFF0020704700B50978002901D0012100E000210069826E10239A43C9B250 +:2025C00009011023194011438166012000BD80B50269D26E13091A00D207D20FD2B2002ACE +:2025E00001D1002001E0FEF7F0FA02BD00B50978002901D0012100E000210069C26E10234B +:202600009A43C9B20901102319401143C166012000BD80B50269126F13091A00D207D20F62 +:20262000D2B2002A01D1002001E0FEF7CEFA02BD00B50978002901D0012100E000210069E1 +:20264000026F10239A43C9B209011023194011430167012000BD80B502698023D2581309C5 +:202660001A00D207D20FD2B2002A01D1002001E0FEF779FA02BD00B50978002901D001218C +:2026800000E0002100698022825810239A43C9B2090110231940114380228150012000BD8E +:2026A00080B502698423D25813091A00D207D20FD2B2002A01D1002001E0FEF754FA02BD36 +:2026C00000B50978002901D0012100E0002100698422825810239A43C9B20901102319409D +:2026E000114384228150012000BD80B502699423D25813091A00D207D20FD2B2002A01D140 +:20270000002001E0FDF7FCFC02BD00B50978002901D0012100E0002100699422825810238E +:202720009A43C9B2090110231940114394228150012000BD80B502699C23D25813091A0033 +:20274000D207D20FD2B2002A01D1002001E0FDF753FD02BD00B50978002901D0012100E009 +:20276000002100699C22825810239A43C9B209011023194011439C228150012000BD406AAB +:20278000086001207047806A086001207047C06A08600120704780B501220269A023D258B5 +:2027A000120C5207520FD2B2002A0BD0022A0FD00BD3042A12D00ED3062A15D011D3072AB4 +:2027C00012D014E0FFF7DBFF12E0FFF7DCFF0FE0FFF7DDFF0CE0FDF7D7FF09E0FDF7BDFE81 +:2027E00006E0FEF7DFF803E0FDF7CEFF00E00020C0B202BD10B50200012318004978042961 +:2028000045D0062934D0082950D0372904D0382911D039291DD058E000231169A0228A58E1 +:20282000BA4C1440DBB21B04E022D2021A402243A023CA504AE01169A0228A58B34C144085 +:20284000DBB21B04E022D2021A402243A023CA503CE002231169A0228A58AC4C1440DBB222 +:202860001B04E022D2021A402243A023CA502DE003231169A0228A58A44C1440DBB21B0486 +:20288000E022D2021A402243A023CA501EE004231169A0228A589D4C1440DBB21B04E02298 +:2028A000D2021A402243A023CA500FE005231169A0228A58954C1440DBB21B04E022D202BC +:2028C0001A402243A023CA5000E00020C0B210BD80B501220269A423D258120C5207520F91 +:2028E000D2B2002A0BD0022A0FD00BD3042A12D00ED3062A15D011D3072A12D014E0FFF77F +:202900003EFF12E0FFF73FFF0FE0FFF740FF0CE0FDF73AFF09E0FDF720FE06E0FEF742F807 +:2029200003E0FDF731FF00E00020C0B202BD10B50200012318004978042945D0062934D026 +:20294000082950D0372904D0382911D039291DD058E000231169A4228A586C4C1440DBB24B +:202960001B04E022D2021A402243A423CA504AE01169A4228A58654C1440DBB21B04E022C3 +:20298000D2021A402243A423CA503CE002231169A4228A585D4C1440DBB21B04E022D202E1 +:2029A0001A402243A423CA502DE003231169A4228A58564C1440DBB21B04E022D2021A4050 +:2029C0002243A423CA501EE004231169A4228A584E4C1440DBB21B04E022D2021A4022433B +:2029E000A423CA500FE005231169A4228A58474C1440DBB21B04E022D2021A402243A423CE +:202A0000CA5000E00020C0B210BD10B501231A000269C0241259120C1340DBB2002B02D0A5 +:202A2000012B03D005E0FEF7E9FB03E0FEF7BEFB00E00020C0B210BD10B502000123180006 +:202A400049780E2910D010291CD100231169C0228A587A4C1440DBB21A0480235B021A40F8 +:202A60002243C023CA500EE01169C0228A58734C1440DBB21A0480235B021A402243C02368 +:202A8000CA5000E00020C0B210BD10B501231A000269C4241259120C1340DBB2002B02D021 +:202AA000012B03D005E0FEF7A9FB03E0FEF77EFB00E00020C0B210BD10B502000123180006 +:202AC00049780E2910D010291CD100231169C4228A585A4C1440DBB21A0480235B021A4094 +:202AE0002243C423CA500EE01169C4228A58534C1440DBB21A0480235B021A402243C423FC +:202B0000CA5000E00020C0B210BD0000FFFFF8FF80B50269CC23D25813091A00D207D20FBE +:202B2000D2B2002A01D1002001E0FEF71CF802BD00B50978002901D0012100E00021006990 +:202B4000CC22825810239A43C9B20901102319401143CC228150012000BDF0B5059D069EB0 +:202B6000079F089C016042608360C56006614761216881616168C161A168016200210A0004 +:202B80000AE00A00D2B29200A218D2680B00DBB29B00C3185A62491C0A00D2B2032AF0D38A +:202BA000F0BD38B503000C0011002000C0B23F2801DB00200DE00020214A2500EDB2ED003D +:202BC0005559002D04D01800E4B2E300D2589047C0B232BDF8B50B0015001900C9B23F298A +:202BE00001DB002029E000242100154A1E00F6B2F60096197668002E1DD029000500114841 +:202C00006F688026B8511048AE6830660F482F688026B8512800DBB2DB00D2185268904782 +:202C2000010020006A688023D0502000AA6810662868802284500800C0B2F2BDFFFFFEFF0C +:202C4000E488010052455355202096194B4D4352F446002804D4494200F013F840426047C3 +:202C60004042002905D45FD000F00BF8404249426047494200F005F84942604703460B43B9 +:202C8000E6D40022030A8B420BD203098B4219D243088B422ED2411A00D201465241104668 +:202CA0007047FF2209023FD012068B4205D3121209028B4201D31212090203098B4219D3A1 +:202CC00000E0090AC3098B4201D3CB01C01A524183098B4201D38B01C01A524143098B421C +:202CE00001D34B01C01A524103098B4201D30B01C01A5241C3088B4201D3CB00C01A52417D +:202D000083088B4201D38B00C01A524143088B4201D34B00C01A5241884200D3401A524161 +:202D2000CFD201461046704708B500F001F808BD7047FEE700B501000020C9B2002905D048 +:202D4000022907D004D3032906D006E0102004E0182002E0282000E04820C0B200BD70B5A0 +:202D60000E0001680C0080340025290029000068C9B2002919D0022909D00FD303291BD1B2 +:202D8000C02109014058400E8507AD0F14E0C02109014058800D8507AD0F0DE0C0210901F6 +:202DA0004058C00C8507AD0F06E0C02109014058000C8507AD0FFFE72800C0B2FFF7BAFF7B +:202DC0000100C9B2890830002A00D2B2002A05D1C9B280B241438800201832E02A00D2B257 +:202DE000012A0ED1C9B2020092B251430D0080B21521FFF743FF4000290008188000201886 +:202E00001FE0EDB2022D0ED1C9B2020092B251430D0080B20C21FFF731FFC0002900081816 +:202E2000800020180DE0C9B2020092B251430D0080B20721FFF722FF400029000818800011 +:202E4000201870BD00B5010000200A00D2B2002A082A0ED9093A0ED0521E0ED0521E0ED0A9 +:202E6000521E0ED0521E0ED0521E0ED0521E0ED00FE008000DE00C200BE0102009E01420D2 +:202E800007E0182005E0202003E0302001E04020FFE7C0B200BD80B500231A0089B2FFF7C2 +:202EA0005EFF0068000C0007000FC0B2FFF7CAFFC0B202BD00B50023D2B2002A0CD00268FD +:202EC000C023DB03134303604268520F5207C900C908114341600BE00268B14B134003607E +:202EE0004268B04B13408A04AF4911401943416000BD0268AD4B134003600268C9B209043F +:202F0000F0231B030B4013430360704700B502685200520802600268A54B13400360C9B20D +:202F2000002909D00168802212060A43026001688022D2050A43026000BD00B50A00D2B22C +:202F4000002A06D101689B4A0A400260016801600BE0C9B2012908D10168964A0A4002604E +:202F600001688022D2040A43026000BD10B50168803100221300140003E0A300CB181A60F9 +:202F8000641C037EDB019C42F7D310BD10B48A4982688023D15001214268136D2024A34324 +:202FA000C9B249012024214019431165002180688022815010BC704710B47F4982688023BD +:202FC000D15001214268136D1024A343C9B209011024214019431165002180688022815002 +:202FE00010BC7047F0B4049C059D069E079F3F780776016042608360C46005614661F0BC27 +:20300000704710B500210A008160016141618161C160C16141628162C1620162012202705E +:203020000A00C2700A0002710022D24342638263C26302640B00442403550B0045240355F4 +:203040000B00C82403550823462403550B0005E01C00E4B2A4000419A2645B1C1C00E4B2A2 +:20306000202CF5DB0A0042700A0082700A003023C2540A00C923C2540A00CA23C2540A00E6 +:20308000CB23C2540A00D523C2540A00D423C2540A00D623C2540A00D723C2540A00CC23D1 +:2030A000C254D022815010BD30B500210A0003681C683F4D2540D2B292078024E40522406E +:2030C0002A431A60026813683C4C1C40C9B2090780235B05194021431160016809680A0E92 +:2030E0001100C907C90FC9B20029F6D130BD38B50400206801250068000D2840C0B20028A9 +:2031000013D0002021680A6852005208C0B2C0071043086002E02000FFF74EFF20680068DC +:20312000000D2840C0B20028F5D1280021680A68234B1340C0B2400680229204104018433B +:20314000086020680068400E2840C0B20028F8D1280021680A68164B1340C0B2800780228C +:20316000D205104018430860280021680A68134B1340C0B20007802252051040184308600C +:2031800020680068000E2840C0B20028F8D020680068C00E2840C0B20028F1D031BD0000F8 +:2031A000FFFF9FFFFFFF03E00000FC1FFFFFF0FFFFFFFFBFFFFFFFF052455355FFFFFFEFB6 +:2031C000FFFFFFFDF0B593B007000C0015002900C9B289B23800FFF7C2FD0600227A6168AE +:2031E0003000FFF767FEA17A3000FFF782FEE17A3000FFF78BFE617A3000FFF79EFE207B41 +:20320000002805D0684605706946380000F0A8FD607A012807D120693968EDB2AA00891823 +:2032200088221201885013B0F0BD0000F8B504000E00002500202000FFF7A8FE0127390068 +:203240002068026852005208C9B2C9071143016020680068010D38000840C0B20028F7D0F1 +:20326000327821684B686D481840D2B2520380239B011A4002434A602000FFF738FF3A0073 +:2032800021680B6866481840D2B2D20580231B041A4002430A603A0021684B6B614818408C +:2032A000D2B2120780235B051A4002434A632000FFF75CFE3020305CFFF73CFD010008009E +:2032C000C0B2002807D080208000C9B2FFF7D9FC0500207E4543206801687F229143EDB2E7 +:2032E0006A06520E0A430260380021680A6D52005208C0B2C007104308654B49B06843186B +:203300002068056D494A2A409BB25D05484B2B4013430365F06843182068056D454A2A40A5 +:203320001D04F8235B032B4013430365306943182068056D404A2A409BB29D02FC231B02C0 +:203340002B4013430365706943182068056D3B4A2A409BB25D01F8239B002B40134303659D +:20336000B06943182068026D1F25AA439BB2DB06DB0E13430365F078002861D03B00226856 +:203380001568D7482840DBB25B078025AD052B4003431360337922681568D2482840DBB2FD +:2033A000DB0380252D022B4003431360306C226890644420335C20680568CB4A2A40DBB229 +:2033C0001D02C0239B002B40134303604520335C2068456BC54A2A40DBB21D06F0231B05A4 +:2033E0002B4013434363C820305C012840D1002210004623F35CC0B2984239D21000C0B2F5 +:2034000080003018836C15002068EDB2AD004519882000012B50521CEAE700BFFFDFFFFFB0 +:20342000FFFF7FFFFFFFFFEFFFFF0000FFFF1F800000E07FFFFFE0FFFF03FFFF1FFCFFFF34 +:20344000002322681568A6482840DBB25B078025AD052B4003431360002322681568A1486F +:203460002840DBB2DB0380252D022B40034313607078002800D16CE1737822681568CE484B +:203480002840DBB2DB0280252D012B40034313603A002068C0231B01C3585B005B08D2B245 +:2034A000D2071A43C0231B01C250F06943182268C2481558C24828409BB21D05C14B2B40B8 +:2034C0000343BE481350306A43182268BB481558BD4828401D04E023DB022B400343B74830 +:2034E0001350736A2268B5481558B84828409BB29D02F823DB012B400343B0481350B06A27 +:2035000042182068AD4BC358E025AB4392B25501E0222A401A43A94BC250F06A411820681F +:20352000A64A825807239A4389B24907490F1143A24A81503020315C00232068C022120149 +:203540008258DBB2002B1FD0022B0BD013D3032B23D1C44B1340C9B24906C022D2040A40AC +:203560001A431AE0C04B1340C9B28905C02212040A401A4311E0BD4B1340C9B2C904C02278 +:2035800052030A401A4308E0B94B1340C9B20904C02292020A401A43FFE7C02109014250E8 +:2035A0003020315C3B002068C02212018258DBB2002B1FD0022B0BD013D3032B23D1A94BF1 +:2035C0001340C9B24906C022D2040A401A431AE0A54B1340C9B28905C02212040A401A438A +:2035E00011E0A24B1340C9B2C904C02252030A401A4308E09E4B1340C9B20904C022920252 +:203600000A401A43FFE7C021090142503020315C02232068C02212018258DBB2002B1FD0A0 +:20362000022B0BD013D3032B23D18E4B1340C9B24906C022D2040A401A431AE08A4B134003 +:20364000C9B28905C02212040A401A4311E0874B1340C9B2C904C02252030A401A4308E09E +:20366000834B1340C9B20904C02292020A401A43FFE7C021090142503020315C0323206896 +:20368000C02212018258DBB2002B1FD0022B0BD013D3032B2CD1734B1340C9B24906C022DE +:2036A000D2040A401A4323E06F4B1340C9B28905C02212040A401A431AE06C4B1340C9B256 +:2036C000C904C02252030A401A4311E0684B1340C9B20904C02292020A401A4308E000BFFC +:2036E000FFFFFFDFFF7FFFFFFFFCFFFFFFFFFFF0C02109014250CA20325C2068C021090124 +:203700004358AA491940D2B2D20380231B021A400A43C02109014250CB20325C2068C021A3 +:2037200009014358A2491940D2B21302F82252011A400A43C02109014250B2782068436B16 +:203740009C491940D2B2120380235B011A400A434263706B21680861B06B21684861F06BD2 +:2037600021688861C820325C2068036892491940D2B2120480235B021A400A430260C920AE +:20378000305C002824D00022206803688B491940D2B2520480239B021A400A4302603A00E2 +:2037A0002068436883491940D2B2120380235B011A400A43426023E0FFF7FFFF040C0000C9 +:2037C000FFFF0FC00000F03FFFFFF8FFFF83FFFF3A002068036879491940D2B252048023B3 +:2037E0009B021A400A43026000222068436871491940D2B2120380235B011A400A434260DA +:20380000D420305C002835D03A00206803686C491940D2B292058023DB031A400A4302601B +:203820003A002068036867491940D2B292068023DB041A400A4302603A00206803686249D3 +:203840001940D2B292048023DB021A400A430260380061698A6C01239A43C0B20740174360 +:203860008F6434E0FFFFFFF9FFFF3FFFFFFFE7FFFFFFFCFF00210B002268156850482840FF +:20388000DBB29B058025ED032B40034313600B00226815684B482840DBB29B068025ED0471 +:2038A0002B40034313600B002268156846482840DBB29B048025ED022B400343136060692F +:2038C000826C01239A43C9B20F4017438764D520305C21680A68374B1340C0B20003802282 +:2038E0005201104018430860D620305C21684A682E4B1340C0B2C003802212021040184343 +:203900004860D720305C21684A68304B1340C0B280038022D201104018434860002723E08C +:203920002A00D2B2D02030583900C9B21423594341182000FFF746FC6D1C2A0092B2D02042 +:2039400030583900C9B214235943435AD020305884463900C9B21420414360464018408847 +:2039600018188242DCDB7F1C3800CC21715CC0B2884208D20020D02030583900C9B2142277 +:203980005143455AD9E7200000F06EF92000FFF78BFB002021680A680D4B1340C0B2C00524 +:2039A00080221204104018430860F1BDFF7FFFFFFFE0FFFFFFEFFFFFFFFFFEFFFFFFFDFF54 +:2039C000FFFFBFFFFFFFFFFBFFFFFBFFFFBFFFFFFFFF7FFF80B5097889B2FFF7C0F90168FA +:2039E000C02212050A43026001BDF8B506000C00217889B23000FFF7B2F905000835217822 +:203A000089B23000FFF747FA00210A000A001BE01600F6B23340032B15D12B681600F6B23E +:203A2000A619367A1E432E602D1D0CE01600F6B21E40022EECD12B681600F6B2A619367A29 +:203A400036021E432E60521C1300DBB283421BD203231E00324209D129602B681600F6B213 +:203A6000A619367A36061E432E60ECE71600F6B21E40012EDAD12B681600F6B2A619367A23 +:203A800036041E432E60DEE7F1BDF8B506000C00217889B23000FFF762F905002868000CD5 +:203AA0000007000FFFF7CEF9482160542868400D0100C907C90F281DC9B2002904D001686A +:203AC000C900C908616004E00168890C4905490D6160051D217889B23000FFF7DCF9002132 +:203AE0000A0012E02A680B00DBB2E3181A722D1D0AE00B00DBB21A40022AF3D12A68120A55 +:203B00000B00DBB2E3181A72491C0A000300D2B2DBB29A4216D203221300194206D12A6843 +:203B2000120E0B00DBB2E3181A72EDE70B00DBB21340012BDDD12A68120C0B00DBB2E3186A +:203B40001A72E1E730688068F1BD30B500231A000A78D506ED0E01242200AA400D78402D46 +:203B600011DB0221006800290AD0022904D005D3032907D1026705E0426703E0C26201E011 +:203B80000263FFE723E00978202910DB0068002C0AD0022C04D005D3032C07D1026705E085 +:203BA000426703E0C26201E00263FFE70FE00068002B0AD0022B04D005D3032B07D1026785 +:203BC00005E0426703E0C26201E00263FFE730BD30B5002213000B78DD06ED0E0124230074 +:203BE000AB400D78402D12DB0221006800290AD0022904D005D3032907D1026F05E0426F8B +:203C000003E0C26A01E0026BFFE71A4026E00978202911DB0068002C0AD0022C04D005D303 +:203C2000032C07D1026F05E0426F03E0C26A01E0026BFFE71A4011E01100006800290AD06C +:203C4000022904D005D3032907D1026F05E0426F03E0C26A01E0026BFFE71A40002A01D0EA +:203C6000012000E0002030BD10B5017E032937D10021C9430A0002240368002C0AD0022CC2 +:203C800004D005D3032C07D11A6705E05A6703E0DA6201E01A63FFE70A0001240368002C21 +:203CA0000AD0022C04D005D3032C07D11A6705E05A6703E0DA6201E01A63FFE70022006835 +:203CC000002A0AD0022A04D005D3032A07D1016705E0416703E0C16201E00163FFE73EE0BF +:203CE000017E022925D10021C9430A0001240368002C0AD0022C04D005D3032C07D11A67F5 +:203D000005E05A6703E0DA6201E01A63FFE700220068002A0AD0022A04D005D3032A07D12F +:203D2000016705E0416703E0C16201E00163FFE715E0017E012912D10021C9430022006825 +:203D4000002A0AD0022A04D005D3032A07D1016705E0416703E0C16201E00163FFE710BD8F +:203D600030B500231A000A78D506ED0E01242200AA400D78402D19DB02210068002910D01E +:203D8000022906D009D303290FD1816E0A4382660BE0C16E0A43C26607E0416A0A43426204 +:203DA00003E0816A0A438262FFE733E00978202918DB0068002C10D0022C06D009D3032CCB +:203DC0000FD1816E0A4382660BE0C16E0A43C26607E0416A0A43426203E0816A0A438262CE +:203DE000FFE717E00068002B10D0022B06D009D3032B0FD1816E0A4382660BE0C16E0A43FB +:203E0000C26607E0416A0A43426203E0816A0A438262FFE730BDF9B58FB00D00179900205B +:203E200001200490012003900820009003230293022414240C94784C0B94FA24A4050A94E0 +:203E4000C9B2002909D1754909915E2608931F217118491C0791069008E07049099126268A +:203E6000089307217118491C079106900192019800F0DEF8059001240D952EE0280000F0EF +:203E8000E7F80100380000F0EEF80700019800F0CFF80100380000F070F98021090400F0AD +:203EA000C5F939D8019800F0C3F80100380000F064F901000798A8420EDB059800F0B6F9BA +:203EC0000AD80494009505910C98A84204DB08000B9900F0BFF927D3641C0998A04223DB81 +:203EE0000D9800F0A5F80500200000F0B1F80100280000F0B8F80700019800F099F80100E7 +:203F0000380000F0B0F800F0B9F90500002D02D006988542B2DA07E0019800F089F8390010 +:203F200000F02BF90100C5E710A80488200080B200F07EF80A9900F0BEF905000098B042EB +:203F400000DA009E0CE0380000F082F8290000F081F904D20296380000F07AF80500761E27 +:203F60000898864216DB3000401C2D4948430099FEF784FE210089B2411A012903DB21006B +:203F800089B2471A02E0210089B20F1A210089B28842D8DA00980299401A401E0190214C5D +:203FA0000125169E1DE0310089B20F1A0CE01C4868430099FEF762FE310089B2411A0129BB +:203FC000F1DB310089B2471A380000F041F8210000F040F904D20395380000F039F80400D2 +:203FE0006D1C0198A842E2DA0F9C04982060029800F0CAF90CA20CCA00F0D0F900F090FA2E +:20400000A0600298A168401AE060019820610398606011B0F0BD0000CDCCCC3DFF030000DC +:204020001027000000401C46333333333333E33F9D2102000AD002D4491E9218FCD5C90533 +:20404000100A1206524100D3012A4841704700009D210200EED55242F446FFF7EBFF012209 +:20406000D2071043604730B405004D400122D20715404B180418240E25D01B0E2CD0FF2CB0 +:2040800031D0FF2B34D0E41A000209021043114343084808D10D1B1A02D2641EDB181B1815 +:2040A000DB18834200D31B1A4941F9D37F3423DDFF2C05DAE40548086041284330BC704745 +:2040C000FF20C005F9E728001B0E03D0FF2BF5D14902F3D0D043F1E7FF2C01D14002F9D106 +:2040E000FF20C005E9E74002F4D1FF2BF8D1F1E728004902E2D0EDE70B0200202442DCD101 +:204100005B129B1CD9D9D805D7E70122D20703004B402ED4431A01D2C01AC91830B44B1870 +:204120000418240E1B0E22D0FF2C20D0E31A182B1DDC09021143C40D641E000210439446E1 +:204140001925ED1A0A00AA40D940451801D36D08A41CE405D209280A2D062A436546AA417B +:20416000604103181B0EFF2B01D3C00DC00530BC7047514006E05140CCE70122D20703006D +:204180004B40F8D4431A03D2C01AC9185040514030B44B18090211430418240E1B0E40D08D +:2041A000FF2C3AD025009D410BD31ED8C50D4002401A0BD3ED050100400AC9059141684121 +:2041C000D5E7C50D40024918401AD0D001214008491C0018FCD58C4204D36D1A000AED05D4 +:2041E0004019C4E7E8051040C1E7182DBFDCAC1C0D00E140E5414D40012D4941C40D0002C2 +:204200001043451A01D46D199543641EE405280A2D069541604130BC7047FF2BA7D1D84312 +:20422000A5E72442A3D10020A1E7FEE70CB4012212060318DA4207D84B18DA4204D802001D +:204240000A43921802D281420CBC7047FCD088420CBC70470CB4012212060318DA4207D82B +:204260004B18DA4204D802000A43921802D288420CBC7047FCD08142FAE7FEE70122D2077C +:204280000118090E7F3910D449421F310FD4001805D2C0011043C84000D5D0437047C00129 +:2042A0001043C84005D440427047002070470042F3D51000704730B405004D400122D20777 +:2042C00015404B180418240E2ED01B0E32D0FF2C34D0FF2B3AD0E41800020902104311439C +:2042E000000A090A9446C2B24A43000AC3B24B43000A4843110A5B181A43D2B2190A091871 +:2043000001D44918641E080A7F3C23DBFE2C08DAE40509061143634699416041284330BC47 +:204320007047FF20C005F9E728001B0EFF2BF6D1D043F4E72800FF2CF1D1F9E74002F7D1D3 +:20434000FF2B01D14902F3D1E005E7E7D8054902E4D0EDE743020020641CDFD15B129B1C36 +:20436000DCD9D805DAE7FEE7010042221201D21E004207D002D4521E0018FCD5C10A400545 +:2043800012058918704700000100EED54042F446FFF7EBFF0122D20711436047F0B50E00A4 +:2043A0005E400125ED072E40B446AE0ADF184C18F44208D2F7420ED2640D01D07F0D12D1F0 +:2043C00000206146F0BD05D1F74201D87F0D05D10020C143F0BDFBD1640DF9D00020C14324 +:2043E000490549088FE0E419C902DB0229432B43DB0A460DC00231438E4630B487B295B28A +:204400007D432E0CADB2140C7C43A419260C240425439CB27C43A419190C7943270CC91925 +:20442000A4B20F043C43090C000C97B247432E0CBE193543ADB2170C4743360CBF19A6B299 +:20444000BF193E043543240C3E0C36199FB24743BF19BCB23E0C89191F0C47437F183E0466 +:204460003443390C704680B297B247432E0CBE193543ADB2170C4743360CBF19A6B2BF19E6 +:204480003E043543240C3E0C36199FB24743BF19BCB23E0C89191F0C47437F183E04344387 +:2044A000390C77463F0C90B278432E0C80190604ADB22E43050CA0B22D18120C7A43501919 +:2044C000020C80B2240CA4189AB27A43121914042043120C89181B0C7B43C91830BCEF0A97 +:2044E000394203D1B61940414941641E6F12BF0DE41B0BDBFF19BC4211DA24050027420844 +:20450000AE417841614166463143F0BD641C05D1401C6141CF0201D34908F4E750E75DE7E4 +:204520004A1812D2400DC90208430121C9070843520D40210901521A521C06D452421F3232 +:2045400001D4D0407047C017704700207047704700B50100C9B2802900DB7F20C0B200BD20 +:2045600000B50100C9B2F139092901D2012004E00100C9B2802900DB0020C0B200BDFEB5D4 +:204580000400002528006E463F2030703078F0270F430740377072701800C0B2FFF7D8FFDF +:2045A000B070207800280FD0032003E00100C9B27554401C0100C9B20829F7DB082269463D +:2045C000E068A36D984704E003226946E068A36D984740B2FEBD7CB50300002001000100B2 +:2045E00069460F220A700A78DC8AF025254315400D70020008E01C691500EDB2645D150031 +:20460000EDB24D196C70521C1400E4B2DD8AA4B2AC42F0D31A78002A15D0020006E0140096 +:20462000E4B2DD8A64190C196070521C1400E4B20725DE8AAD1BAC42F1DB08226946D868C4 +:204640009B6D984706E0DA8A521CD2B26946D8689B6D984740B276BD1CB5040068461F2179 +:2046600001700178E28A92B2120AF02313430B400370E18A417000210A00D2B2C9B208E02F +:2046800022690B00DBB2D25C0B00DBB2C3189A70491C0A00D2B2062AF2DB08226946E0683B +:2046A000A36D9847010049B2002904D1218B891D21830121A17640B216BDFEB50400002541 +:2046C0002800C0B268462F2101700178A27EF02313430B400370E18A228B8E1A310089B2E5 +:2046E000082900DB07262900C9B20AE02269238B0F00FFB2DB19D25C0B00DBB2C3185A709B +:20470000491C0A00D2B2330092B29BB29A42EDD3217800291AD02900C9B22900C9B207E06B +:204720000A00D2B233009BB2D21882185570491C0A00D2B207233700BFB2DB1B9A42EFDBC1 +:2047400008226946E068A36D984706E03200521CD2B26946E068A36D9847010049B2002934 +:2047600009D1218B89192183A17E491CA176A17E102900DBA57640B2FEBD70B5030000208F +:2047800004000F240D782600354205D0D2B2521E0D782540AA4208DA586D002802D099489F +:2047A000596D88470620C04315E00A78144042229C5208E00200D2B28A185278DC6B0500F8 +:2047C000EDB26255401C0200D2B242241C5B92B2A242EFD3002070BD38B503000020040079 +:2047E000D2B2082A08D0586D002802D08648596D88470620C04339E00A781202F0242401F8 +:2048000014404A78A2181400A4B2082C08DA586D002802D07D48596D88470620C04325E001 +:2048200040241C5B1500ADB2AC4208D2586D002802D07748596D88470220C04316E04224CD +:204840001A5308E00200D2B28A189278DC6B0500EDB26255401C0200D2B2062AF2DB06202A +:2048600044215852012046215854002032BDF8B50300002528004620185C0C782407240F2D +:20488000A04202D00320C0433EE04220185A44241C5B041B200080B2082800DB0724D2B242 +:2048A000521E200080B2824208DA586D002802D05848596D88470620C04325E02A000BE059 +:2048C000D86B1600F6B24427DF5BF6191700FFB2CF197F788755521C1000C0B2260080B258 +:2048E000B6B2B042ECD34420185A0019442158524620185C401C462158544620185C102846 +:2049000001DB46201D540020F2BD80B50100D2B2032A08DA486D002802D03F48496D884791 +:204920000620C04300E0002002BD80B513009BB20A00C16800F001F802BDF8B50400002549 +:204940002800002C02D10020C04359E0A08A190089B2884208D2606D002802D0C048616D15 +:2049600088470220C0434BE03420205C012808D1606D002802D0BB48616D88470120C043BB +:204980003EE0E38228002083280007E00100C9B2515C26690700FFB2F155401C0100C9B22C +:2049A0001E0089B2B6B2B142F0D3E08A082804DA2000FFF710FE060020E02000FFF74CFE7E +:2049C0000600300040B2002818D12800A0832800A0772800E077E06D80472200203203C248 +:2049E000083AE06D80470022643051412200283203C2083A2563012034216054300040B2C2 +:204A0000F2BD0000DC990100089A0100D49801000C990100349A0100549A0100FEB5140036 +:204A20001A001300DBB29B1E072B00D317E100252B00DBB22B00DBB2029408E0029C1E0037 +:204A4000F6B2A45D6E461F00FFB2F4555B1C1C001600E4B2F6B2B442F0D32B00DBB207E0A1 +:204A60006C461E00F6B21700FFB2F619A5555B1C1C00E4B208261700FFB2F61BB442EFDBFD +:204A80006F4604000E003878C0B20009002806D0022858D01BD3032800D19DE0DFE051203D +:204AA000205C012804D10520C0435021605401E050202554D2B269462000FFF75EFE40B2CE +:204AC000002803D1A663022051216054C7E05120205C012804D10520C0435021605401E0C9 +:204AE00050202554D2B269462000FFF775FE01000222D24349B291420CD10720C043502191 +:204B00006054512025540023002202212000FFF736FDA4E040B2002814D1A6630120512127 +:204B2000605460784721605401234720225C00212000FFF724FDE06D804700226430514110 +:204B4000A064E1648BE05120205C012804D00520C0435021605482E0A06B864200D07EE007 +:204B6000D2B269462000FFF782FE0321C94302000B0052B29A4204D15020215451202554AB +:204B80006DE040B2002826D1E06D8047002264305141A064E1644420205A4221615A88424C +:204BA00003D302205121605415E06078002812D04720205C401E472160544720205C002898 +:204BC00009D160784721605401234720225C00212000FFF7D4FC42E03420205C01283ED1CD +:204BE000D2B269462000FFF790FE40B2002835D1E06D80470022643051412200283203C221 +:204C0000083A0F2039780140022906D10720C043206302203421605420E03978014001293B +:204C20000CD1E07F401CE077E07F022816DB0620C04320630220342160540FE03978014251 +:204C40000CD17878002802D18048A08301E07878A083B878FFF784FCA077E577FFE7F7BDFA +:204C6000449901007899010070B5002425005125455D022D02D00420C04325E0856B8668B3 +:204C8000B54201D1012500E025000D704221415A1D000E00ADB2B6B2B54200D219002300AE +:204CA00007E0C56B1E00B6B2AD5D1E00B6B295555B1C1D000E00ADB2B6B2B542F1D3049A1B +:204CC000118051214454002070BD70B402000B0018781070587850705868506098689060BB +:204CE000D868D06018691061988A908200242000D08220001083200090762000908320005C +:204D000090772000D077002000211500203503C5083D1500283503C5083D146325003426F8 +:204D200095559D69D5639D8B40269553250042269553250044269553250046269555250049 +:204D4000472695559064D16420005021505451201454186A5065586A9065986AD06570BC74 +:204D6000704738B504003420205C012856D1374DA08BA84202D0A08B00283DD0A07F002859 +:204D80000ED0A07F002837D0E06D8047220020320CCA121A8B41002B2EDC01DB002A2BD259 +:204DA0002000FFF78AFC40B2002822D1A08BA84202D0A08B4019A083E06D804700226430F2 +:204DC00051412200283203C2083AE06D804702000B00A07F0021801859412200203203C2F2 +:204DE000083A208BE18A884206D300203421605402E0022034216054E06D804722002832F2 +:204E00000CCA121A8B41002B08DC01DB002A05D20120C04320630220342160545120205C19 +:204E2000012811D1E06D8047A26CE36C121A8B41002B09DC01DB002A06D20220C04350217A +:204E4000605400205121605431BD0000FFFF000000B5BFF34F8F054805490860BFF34F8F94 +:204E600000BFFDE701604260836070470400FA050CED00E038B504002F48A2688023D050E1 +:204E8000C9B200295AD0022900D17FE06AD3042900D1A3E000D28DE0062900D1C6E000D274 +:204EA000B0E0082900D1E9E000D2D3E00A2900D10CE100D2F6E00C2900D12FE100D219E197 +:204EC0000E2900D152E100D23CE1102900D175E100D25FE1122900D198E100D282E114293F +:204EE00000D1BBE100D2A5E1162900D1DEE100D2C8E1182900D101E200D2EBE11A2900D1FC +:204F000024E200D20EE21C2900D147E200D231E21E2900D172E200D258E2202900D19DE294 +:204F200000D283E2222900D1C8E200D2AEE2232900D1DBE2DDE200BF524553550120010059 +:204F4000A26853680125AB43C9B20140194351600021A26853680125AB43C9B20840184397 +:204F60005060C6E201200100A26893680125AB43C9B20140194391600021A2689368012549 +:204F8000AB43C9B2084018439060B2E201200100A268D3680125AB43C9B201401943D160BD +:204FA0000021A268D3680125AB43C9B208401843D0609EE201200100A26813690125AB43ED +:204FC000C9B20140194311610021A26813690125AB43C9B20840184310618AE2012001006F +:204FE000A26853690125AB43C9B20140194351610021A26853690125AB43C9B208401843F4 +:20500000506176E201200100A26893690125AB43C9B20140194391610021A26893690125F4 +:20502000AB43C9B208401843906162E201200100A268D3690125AB43C9B201401943D16169 +:205040000021A268D3690125AB43C9B208401843D0614EE201200100A268136A0125AB4399 +:20506000C9B20140194311620021A268136A0125AB43C9B20840184310623AE2012001001B +:20508000A268D36A0125AB43C9B201401943D1620021A268D36A0125AB43C9B208401843D0 +:2050A000D06226E201200100626813680125AB43C9B2014019431160002162681368012526 +:2050C000AB43C9B208401843106012E201200100626853680125AB43C9B2014019435160DC +:2050E0000021626853680125AB43C9B2084018435060FEE101200100626813690125AB43CD +:20510000C9B20140194311610021626813690125AB43C9B2084018431061EAE1012001000E +:20512000626853690125AB43C9B20140194351610021626853690125AB43C9B20840184332 +:205140005061D6E101200100626893690125AB43C9B20140194391610021626893690125D4 +:20516000AB43C9B2084018439061C2E1012001006268D3690125AB43C9B201401943D16109 +:2051800000216268D3690125AB43C9B208401843D061AEE1012001006268136A0125AB4379 +:2051A000C9B201401943116200216268136A0125AB43C9B20840184310629AE101200100BB +:2051C0006268936A0125AB43C9B201401943916200216268936A0125AB43C9B208401843CF +:2051E000906286E1012001006268136B0125AB43C9B201401943116300216268136B0125BD +:20520000AB43C9B208401843106372E1012001006268536B0125AB43C9B201401943516332 +:2052200000216268536B0125AB43C9B20840184350635EE1012001006268136C0125AB4322 +:20524000C9B201401943116400216268136C0125AB43C9B20840184310644AE10120010064 +:205260006268536C0125AB43C9B201401943516400216268536C0125AB43C9B208401843E8 +:20528000506436E1012001006268936C0125AB43C9B201401943916400216268936C012527 +:2052A000AB43C9B208401843906422E1012001006268136D0125AB43C9B2014019431165DD +:2052C00000216268136D0125AB43C9B20840184310650EE1012001006268136E0125AB434C +:2052E000C9B201401943116600216268136E0125AB43C9B2084018431066FAE0012001000F +:205300006268536E0125AB43C9B201401943516600216268536E0125AB43C9B20840184341 +:205320005066E6E0012001006268936E0125AB43C9B201401943916600216268936E0125CF +:20534000AB43C9B2084018439066D2E0012001006268D36E0125AB43C9B201401943D16609 +:2053600000216268D36E0125AB43C9B208401843D066BEE0012001006268136F0125AB4379 +:20538000C9B201401943116700216268136F0125AB43C9B2084018431067AAE001200100BB +:2053A00062688023D3580125AB43C9B2014019438023D150002162688023D3580125AB4398 +:2053C000C9B2084018438021505092E00120010062688423D3580125AB43C9B20140194312 +:2053E0008423D150002162688423D3580125AB43C9B208401843842150507AE00120010035 +:2054000062689023D3580125AB43C9B2014019439023D150002162689023D3580125AB4307 +:20542000C9B2084018439021505062E00120010062689C23D3580125AB43C9B201401943B9 +:205440009C23D150002162689C23D3580125AB43C9B2084018439C2150504AE001200100BC +:2054600062689423D3580125AB43C9B2014019439423D150002162689423D3580125AB439B +:20548000C9B2084018439421505032E0012001006268C823D3580125AB43C9B20140194359 +:2054A000C823D15000216268C823D3580125AB43C9B208401843C82150501AE00120010008 +:2054C0006268CC23D3580125AB43C9B201401943CC23D15000216268CC23D3580125AB4393 +:2054E000C9B208401843CC21505002E0FFF7B0FCFFE70020A1688022885031BDF0B502005F +:2055000052B2002A16D41822AA4B040064B2A408A4001C59FF25C6001640B540AC438901B7 +:20552000C9B2C5002A409140214340B28008800019501BE00F25A04B1824020052B22A4063 +:20554000083A92089200060076B23540083DAD08AD005D59FF26C7002740BE40B54389010A +:20556000C9B2C0000440A14029439950F0BD80B5411E80225204914201D301200EE0401E29 +:205580008E49086003210020C043FFF7B7FF00208B4908600720BD490860002002BD00B554 +:2055A000017A00290FD0417A00290CD101684268914208D20168491C0160016842689142D2 +:2055C00001D10121417200BD10B5040084204001201803C80022401C514184225201A218F3 +:2055E00003C2083AAA482018FFF7D9FFA9482018FFF7D5FFA8482018FFF7D1FF10BDA7480F +:20560000A74908607047A74803C8704780B5A6480168491C0160A34A03CA083A0023401C3D +:20562000594103C2083AA148FFF7CEFF01BDF8B594B000200020694608704CE001A92868A1 +:20564000FEF783FA42E001AE684600783070984D01A92868FEF7BCFA002837D0D0202058E0 +:2056600069460978142251434018407A0128E5D101A92868FEF769FA01A92868FEF705FA7F +:205680004820325C01A8010008318A4C98204001251828784C2358432018071D380000F0F7 +:2056A00043FA029829784C225143605028784C214843201844214822B25C42542878401C81 +:2056C00028702878202801D30020287068460078401C69460870784C68460078CC21615C81 +:2056E0008842B0D315B0F0BD70B5010000242000704B724A9D18982252019A5C2E78B242B8 +:2057000011D04C2228784C26704318180E000100300000F009FA2878401C28702878202897 +:2057200000D32C700120C0B270BDF0B593B000242300DBB22500EDB2E4B200E0641C5E4D19 +:205740002600CC27EF5DF6B2BE420CD2D026AE59B4462700FFB2142677436646F619766802 +:20576000B042EBD123002800D0306C4605681E00F6B214277E43AD5B257048256255006826 +:20578000DBB214246343C01840680190D2B2684604000834200000F0C7F9454C6946206883 +:2057A000FEF723F969462068FEF714F9002013B0F0BD000000E400E01CED00E014E000E08E +:2057C00018E000E0FEB500240294394FAF4E3000803038603500D83501220521280000F0E4 +:2057E00013FA01220521280000F04EFA01220521280000F056FA3500D03505220021280098 +:2058000000F002FA05220121280000F0FDF92A4D2800FDF7F6FB0820CC2168549C48D0211B +:205820006850012001002970210069702100A9702100E97030216C54C821685402AA0B21B9 +:2058400030000830FDF7ADF9687801280BD101200190FA20C00000908E4B8F4A02992800D0 +:205860001C30FEF7D8FA002001908C480090894B8B4A029928000830FEF7CDFA29003868D7 +:20588000FDF7D4FC092000F03DFAF7BD10E000E0901000009C100000A810000055AAAA556E +:2058A000F06300200020002048320020082000203C500020603C0020644F00200113000004 +:2058C000F0B59BB000F014FA704800F021FA754800F082FB00F098FC7349002000F09CFE03 +:2058E000724900200090724C009A200000F09EFED821002000906F4C009A200000F096FE97 +:20590000012603AC30002070022060703000A080694D03AA07212800FDF75CF930002070F3 +:20592000A68003AA13212800FDF754F903AA14212800FDF74FF903AA15212800FDF74AF96F +:2059400003AA16212800FDF745F903AA17212800FDF740F9FFF736FF584C01220321200099 +:2059600000F052F901220321200000F08DF902220321200000F0E9F801220321200000F07F +:2059800090F94F4E01220B21300000F03DF901220B21300000F078F902220B21300000F0EC +:2059A000D4F801220B21300000F07BF901220521200000F029F901220521200000F064F907 +:2059C00002220521200000F0C0F800220521200000F067F93B4E3C49300000F04FFE3B4CFB +:2059E000220009212800FDF7DCF82068FA218900FDF747F9FFF7BBFD354800F083F900F084 +:205A000069F914E008210025009501AF009A380000F00CFE2560082201A92E48FFF785FE89 +:205A20002D49002000F0F8FD300000F0F2FE2B4C20680028FBD07078022805D1FFF7DFFD2F +:205A400023212748FFF716FA2068401E2060254C2068401C206024480168491C016008A807 +:205A6000FFF742FE0128DFD108982049884203D008981F498842C5D108A84421435C021D36 +:205A8000089930001830FEF7C9FFC9E7C4300020F49601004C1D000080841E00C409000089 +:205AA00020A10700443200209C9A010004130000603C0020644F0020CC300020A43100209A +:205AC0008C310020082000204000002054320020FFFF000022020000B49A01004832002090 +:205AE000D43100204C3200205032002032070000DF07000070B4103A03D378C9103A78C01B +:205B0000FBD2530701D318C918C001D508C908C0D20704D30B880380891C801C002A01D55B +:205B20000B78037070BC70478B0701D18307E1D0124205D00B78491C0370401C521EF9D1D3 +:205B400070470000016042607047F0B51300122959D20200DBB2002B03D0022B38D01CD305 +:205B600051E000231E000C001568A00028580227B843F6B2760002273E400643A0002E50BA +:205B800010688A0082580124A243DBB21C00E407E40F14438900445035E001231E000C00C1 +:205BA0001568A00028580227B843F6B2760002273E400643A0002E50002012688C00145965 +:205BC0000125AC43C0B203402343880013501AE000250800136884001C590226B443EDB251 +:205BE0006D0002263540254380001D500120030012688C0014590125AC43DBB21840204352 +:205C000089005050FFE7F0BDF0B51300DBB2002B1BD10B0004689D0066591A4D3540D2B239 +:205C20001602E022D20032402A439B00E250012200688B00C3580424A343D2B2920004244F +:205C400022401A43890042501AE000260C000568A300EB580427BB43F6B2B60004273E40BB +:205C60001E43A300EE5000688B00C358054C1C40D2B21302E022D2001A40224389004250E0 +:205C8000F0BD0000FFF8FFFF10B443685B6901248C40A343D2B28A401A434068426110BC96 +:205CA000704710B443681B6801248C40A343D2B28A401A434068026010BC704700B5010076 +:205CC00049B2002905D40121C006C00E81400B48016000BD00B50A480168012906DB0168FB +:205CE000491E01600068012800DA62B600BD000072B603480168491C0160704700E100E082 +:205D0000C030002080B540B2FFF7D8FF01BD0000F0B58BB004007D4D2A007D49200000F013 +:205D2000E9FD7C480590069000200790089009900A90794E794F05A8039002977848019053 +:205D4000784800903300784A784920000830FCF704FF77492000383000F0D0FD754920000C +:205D60003C3000F0CDFD74492000403000F0C8FD72492000443000F0C5FD714A7149200065 +:205D8000483000F0C1FD70492000543000F0C0FD6E492000583000F0BDFD6D4920005C3068 +:205DA00000F0BAFD32006B492000603000F0B6FD02206946087404A80390029501970096B2 +:205DC000594B574A644920008030FDF70BF9634920009C3000F09AFE2A0061492000A03025 +:205DE00000F0A2FE2A005F492000A83000F09FFE5D492000B03000F09DFE5C492000B430E2 +:205E000000F09AFE5A492000B83000F097FE59492000BC3000F092FE57492000C03000F0FC +:205E20008FFE56492000C43000F08CFE544A55492000C830FFF786FE534A54492000D03080 +:205E4000FFF780FE524A53492000D830FFF77AFE514A52492000E030FFF774FE504A5149FE +:205E60002000E830FFF76EFE00962E4B3A004E492000F03000F068FE2A004C498020400073 +:205E8000201800F0A7FE2A00494984204000201800F0A0FE244B224A244988204000201867 +:205EA000FEF7E0FF43498E204000201800F0BEFE4149B2204000201800F0C2FE3F49B420D0 +:205EC0004000201800F0BCFE2A003D49B6204000201801F08FF83B49BA204000201801F063 +:205EE0008DF83949BC204000201801F087F83749BE204000201801F081F83549C0204000F9 +:205F0000201800F067F80BB0F0BD00BF00F005400040024000127A0000E0064000E806403C +:205F200000F8064000E4064000F0064000F0074000400740003000400040004000C0004015 +:205F4000001002400080004000900140008001400050004000000240008003400060064062 +:205F600000200740003007400070074000500740000003400010034000D0004000600240AD +:205F8000005003400000064040500340001006408050034000200640C050034000300640BD +:205FA000005103400040064000D0074000800540009005400080074000C0024000D002403B +:205FC00000E0054000A0064000B0064000C0064000A007400160704700B502680121126800 +:205FE00052090A40D2B2012A19D10D4A03685A600268126880239A4303681A60094A0368E0 +:206000009A6002681268D20A0A40D2B2002AF8D102681268520A0A40D2B2002AF8D000BD48 +:2060200020C528D9FFFF000010B5494C0320206160614848A0614849E1618021C90021626C +:206040000021A1626162E1622066444860661020A0662167E166616741A1E01D00F0F2FFB1 +:206060004049200000F0EEFF2020A07110BDF8B584B004000D00160000200190E7682069EB +:20608000874202D2C01B401E03E0A168C91B0818401EA168C91B884201D3A068C01BB0427C +:2060A00001D2009000E000966068C0190099039129000290039A0298FFF736FD02980198EB +:2060C00000994018019000982D180098361A00983F18A068874200D10027E760002ECED1AD +:2060E000019805B0F0BDF8B504000F001500E668A068801B0090009885420AD260688019B3 +:206100002A00390007003800FFF70EFD7019E06010E0009A6068861939003000FFF704FDC2 +:2061200000982D1A66682A00009839183000FFF7FBFCE560F1BD00B50169C2688A4204D3A3 +:206140008068401E801A401801E0881A401E00BD40500020A89A0100E8500020E8540020C2 +:2061600052545400C49A0100F8B516000F002549182250430818050018356869002803D07B +:2061800002281DD00ED322E02800FFF7D4FFB04201D2002405E03400320039002800FFF789 +:2061A000A2FF15E02800FFF7C6FFB04201D2040000E03400220039002800FFF794FF07E096 +:2061C000320039002800FFF752FF040000E000242000F2BD70B504000D00160009480078F9 +:2061E000002801D1FFF720FF320029002000EFF31084012383F31088FFF7B6FF84F31088B3 +:2062000070BD00004050002080B5FFF70DFF01BD10B50400A26863681000401C834206D304 +:2062200020688154521CA260E068401CE060A068616888420DD1A26821682069FFF7CAFF59 +:20624000A168884203D00020C043E06001E00020A06010BDF7B582B005001F0003980124A5 +:20626000012603E00499FCF70CFD761C04998842F8D2BE4200D23E0001950A9D0B98C00701 +:206280001BD4002D19D00B98800705D5002F03D130206946087002E0202069460870002D05 +:2062A0000BD0AE4209D26D1E684601780198FFF7AFFF0198C0680028F1D50198C0680028B1 +:2062C00039D402E07F1E04984443022FFAD203982100FCF7D6FC04998842F4D203982100A8 +:2062E000FCF7CFFC0100039A08006043101A03901248415C0198FFF78BFF0198C0680028E1 +:2063000007D420000499FCF7BCFC0400002CE5D1FFE70B98C0070ED5002D0CD0002D0AD011 +:20632000AE4208D26D1E20210198FFF771FF0198C0680028F2D505B0F0BD00008C9A01008F +:20634000F1B584B00E001D00002E01D5704200E030000124039203E00399FCF78FFC641C3B +:2063600003998842F8DA02950298844200D2029C0A9D0B9F002D04D0002E01D4780700D5D5 +:206380006D1EB80702D50298002810D0F8070ED4002D0CD0002D0AD0AC4208D26D1E2021B5 +:2063A0000498FFF735FF0498C0680028F2D50498C068002834D4002E06D5704206002D2161 +:2063C0000498FFF725FF05E0780703D52B210498FFF71EFF0498C068002821D4B807800FA1 +:2063E000022811D1029800280ED1002D0CD0002D0AD0AC4208D26D1E30210498FFF708FFA3 +:206400000498C0680028F2D50498C068002807D401970095029B039A31000498FFF71AFFBF +:2064200005B0F0BDF1B598B00C00160007A802904020039000270497189806900597217879 +:20644000641C0800C0B2002808D00800C0B2252800D0C7E038000122110000E0CAE0237873 +:20646000DBB2232B13D02B2B0CD02D2B02D0302B03D011E01043641C0FE0030002201843A1 +:20648000641C0AE0030004201843641C05E0030008201843641C00E039000029DFD13A0079 +:2064A00005E0641C0A235A43C9B25218303A21780B00DBB2303B0A2BF3D33B002178C9B278 +:2064C0002E290DD1641C05E0641C0A256B43C9B25B18303B21780D00EDB2303D0A2DF3D3BD +:2064E000217801E0641C21780D00EDB26C2DF9D00D00EDB2682DF5D0C9B225296BD0582970 +:2065000034D063290AD0642914D0702952D073293AD075291CD0782928D061E030683060B3 +:20652000306801683068001D3060C9B202A8FFF76FFE55E0316831603168096835682D1D3D +:206540003560019000920A2202A8FFF7F9FE47E0316831603168096835682D1D3560019058 +:2065600000920A2202A8FFF775FE39E0316831603168096835682D1D35600190009210222C +:2065800002A8FFF767FE2BE030683060306805683068001D306029786D1C0800C0B20028AD +:2065A00007D0C9B202A8FFF733FE05980028F2D5FFE715E030683060306801683068001D73 +:2065C000306000200190082000900823102202A8FFF740FE04E0252102A8FFF719FEFFE7C0 +:2065E000641C03E0C9B202A8FFF712FE0598002800D424E7059801280BDB0498002804D025 +:20660000049A07A91898FFF7E5FD0598049940180590059819B0F0BD0CB480B502AA009237 +:206620006A46FFF7FFFE019904B008471206130A1A43130C1A4300BF094205D0830705D0CE +:206640000270401C491EF9D1704700001300103906D330B41400150010393CC0FCD230BC43 +:20666000490700D30CC000D504C0890002D30280801C002900D502707047000010B5040026 +:20668000200000F08DF80548A0600548E0600F206060044820610620A08210BD949701008E +:2066A000AC990100C801002080B5080000F028FD01BD40780870704780B5080000F029FD61 +:2066C00001BD80B5080000F0FFFC01BD80B5080000F0F2FC01BD80B5080000F0FDFC01BD59 +:2066E0000021016041600A000272417270470022026041600121017242727047407A7047F9 +:20670000FEB505000E001400082100226F463800FFF78CFF2000C0B2782805D06F48295AA5 +:206720006F482818FFF7E3FF7920285C002814D02000C0B211280FD02000C0B212280BD010 +:206740002000C0B2312807D02000C0B27E2803D02000C0B27F2800D10AE068467F210170B9 +:20676000467084700322694628001830FEF7DDF8F7BD10B50022130000E0521C13009BB205 +:206780004468A3420AD283681400A4B2E4001B5D0C00E4B2A342F0D1012000E0002010BDA5 +:2067A00070B505000C00210028001830FEF78DFA0120687000263000A870300078216854AA +:2067C0000020002184225201AA1803C2083AA08D44496852E08D44496852208E3F4968529E +:2067E00042482818FFF77CFF41482818FFF778FF3B482818FFF774FF3000300004E0310087 +:206800002A187B23D154401C802149018842F6D370BD7CB50400002528006946888028000B +:206820002800280020001830FEF79BFA01A8009080235B0122007B322100793120001830DC +:20684000FEF712FA40B2002839D17B20265C3100C9B22000FFF78DFF00282AD02B0000E07B +:206860005B1C606883422AD2A068D900405C3100C9B28842F4D1A068D90040188078002807 +:2068800006D07C20205CC0B2C0097821605402E028007821605418007A216054684682880C +:2068A00021007B312000A668DB00F3185B68984705E011223100C9B22000FFF721FF08480B +:2068C0002018FFF71BFF012806D101206070A57003482018FFF704FF73BD00008C10000022 +:2068E000A8100000881000008A100000901000009C10000001604260704700000160704790 +:206900000160704701607047416082607047000001607047016070470160704738B50400D4 +:20692000216062600025A560E0208002E060802040052061802000026061200000F0C8F88F +:206940002076E561207E002800D06561200000F001F831BD30B401221300046800210D0054 +:20696000DBB25B0002252B402360130004680D00DBB21B0110252B402360130004680D0036 +:20698000DBB25B0120252B402360130004680D00DBB29B0140252B402360130004680D0047 +:2069A000DBB2DB0008252B4023600068D2B2910004221140016030BC704730B50100002353 +:2069C0001800012214000D68E4B2E301802423402B600B681B68DB091340DBB2002BF8D03A +:2069E0000B681B685B091340DBB2002B0CD10B681B681B091340DBB2002B05D10968096878 +:206A00001140C9B2002900D01000C0B230BDF6B583B001000024200022006A46127C402A55 +:206A200000DB01200293029A002A00D1012000910100C9B2002935D1009800680125006843 +:206A4000C10928000840C0B2002801D1022029E00098FFF77FFF08232100009802682000EB +:206A6000FF2001900E00F6B29619367F019FBE43DBB2019F1F403743C9B251180F7769468C +:206A8000097C009A126823002B00DBB2D3181B7F8343C9B208401843EDB2511908770098F9 +:206AA000FFF78BFF0100C9B200290ED121000AE00A00D21D009B1B682500D2B29A18127FC4 +:206AC000029B5A54491C0829F2D3C0B205B0F0BD3EB5050008220021684600F03BFB002005 +:206AE0000400FF20694608706B46002200212800FFF78DFFC0B2002804D168460078800792 +:206B000000D401242000C0B23EBD0000016000210168CA6E01239A43CA660068016C0A00BC +:206B2000D207D20F006C7047016042607047016042607047016070470160704701607047BC +:206B4000016070470160704710B4019C016042608360C46010BC704702692F4B1340C9B264 +:206B60000A06F0210905114019430161704702692A4B1340C9B20A04F0210903114019439A +:206B8000016170470269264B1340C9B20A02F0210901114019430161704702690F239A43CB +:206BA000C9B20907090F11430161704742691C4B1340C9B20A02F02109011140194341616F +:206BC000704742690F239A43C9B20907090F11434161704738B5050029606A60002408E0A3 +:206BE0001048210089B2425C0C21280000F006F8641C200080B20628F2D331BD80B5130005 +:206C0000DBB2062B06DAC9B24068074BD2B292009A58904701BD0000FFFFFFF0FFFFF0FFEA +:206C2000FFF0FFFFBC9A0100749A0100016000210171417128228154382281547047000056 +:206C4000016001680A6980235B0013430B6101680A6980239B0013430B61012101680A695D +:206C6000022313430B6100BF00BF00BF002100680161704730B50200002318001C00491EA9 +:206C800017D0491E1CD0FE3922D080256D00491B26D08025AD00491B2AD08025ED00491B7F +:206CA0002ED080252D01491B32D07B4D491B37D03EE0116849690C00E407E40FE4B237E08A +:206CC0001168496949080C00E407E40FE4B22FE011684969090A0C00E407E40FE4B227E0E4 +:206CE00011684969490A0C00E407E40FE4B21FE011684969890A0C00E407E40FE4B217E062 +:206D000011684969C90A0C00E407E40FE4B20FE011684969090B0C00E407E40FE4B207E060 +:206D200011684969090E0C00E407E40FE4B2FFE7002C00D00120C0B230BD0000FEB582B04A +:206D4000070001240026300038683200C06DC006C00E1022101AC0B26A46928980B2904281 +:206D600000D292E0684601700196350030003868006E0190002101A800F003F9012101A894 +:206D800000F0F1F8002101A800F014F9002101A800F002F968460078C100491E89B201A86C +:206DA00000F01EF9019839680866300013E039684B6F0A99020092B292008B500AE06946B7 +:206DC00009780229F3D139684B6F0A99020092B252008B52401C01006A46928989B291429A +:206DE00047D23A683100012153690A001A40D2B2002A04D16D1C294A9542F2D334006A4666 +:206E00001278012A06D1049A03009BB2D25C3B685A6612E06A461278022A07D1049A030096 +:206E20009BB25B00D25A3B685A6606E0049A03009BB29B00D2583B685A6635003B68320015 +:206E40001B6F5B080B40002B00D00A00D2B2002A04D06D1C114A9542F0D334006946097891 +:206E60000129ACD13968496F0A9A03009BB2D154B0E7002101A800F084F8002101A800F072 +:206E800072F801983968086600E034002000C0B205B0F0BD0000000000F0FF00E9030000FD +:206EA00010B502000B00002108005B1E14D05B1E1CD0FE3B23D0802464001B1B29D080240E +:206EC000A4001B1B2FD08024E4001B1B35D0802424011B1B3BD044E001231C001268080026 +:206EE00091692140A14200D118003AE002231268080091691940994200D1012031E08023D6 +:206F00005B001268080091691940994200D1012027E080239B00126808009169194099427F +:206F200000D101201DE08023DB001268080091691940994200D1012013E080231B01126816 +:206F4000080091691940994200D1012009E080235B011268080091691940994200D101207F +:206F6000FFE7C0B210BD00B50268C9B2012904D1802189031143016002E01549114001607F +:206F800000BD0268134B1340C9B2090580225203114019430160704700B50268C9B2012910 +:206FA00004D1802109031143016002E00A491140016000BD00B50268C9B2012904D18021BC +:206FC000C9021143016002E004491140016000BDFFFFDFFFFFFFEFFFFFFFF7FFFFFFFBFFDF +:206FE0000268120B120389B20905090D1143016070470000016042607047000001600168A6 +:20700000CA6A80231B021343CB6200BF00BF00BF00BF0A4B1340CB620168CA6A8023DB010C +:207020001343CB6200BF00BF00BF00BF044B1340CB6200210068016070470000FF7FFFFFE5 +:20704000FFBFFFFF31B48B0707D00B780370002B20D0401C491C8B07F7D1164CE501830728 +:2070600022D104C9131B93432B4205D104C004C9131B93432B42F9D0FF231A42027009D075 +:20708000120A1A42427005D0120A1A42827001D0120AC27031BC70470270120A4270120A68 +:2070A0008270120AC270001D04C9131B93432B42F2D0E1E70101010110B504001022224941 +:2070C0002000FEF731FD10BD10B50400C02104222000FEF729FD10BD70B504000C221B4D09 +:2070E0002900103126003000FEF71EFD0822291D25000C352800FEF717FD2020E07270BDFA +:2071000010B50400C0200822011D2000FEF70CFD10BD10B50400C020082201002831200046 +:20712000FEF702FD10BD80B50020009003230622C021012000F01FF801BD80B523210448CF +:20714000FDF798FE01BD0000E0000100C0000100D431002010B5040008001100020020001C +:20716000FFF764FA200010BD80B500214006400E00F030F802BDF1B582B00C0017001D00F5 +:20718000089E6846007AFFF7EFFF002E00D03080A0432900C9B2B9400143C9B26846027A26 +:2071A00080201043C0B200F015F86846007A69460870EDB2BD40684685706846007AFFF7C1 +:2071C000D3FF0440684680784440684644700098FEBD00001CB50E4B187059700D4C009452 +:2071E000022201210C48FFF7A9FD207800026178084380B216BD10B5074C02212000FFF745 +:2072000039FD012803D102212000FFF749FE10BDF85400200455002028320020002202600B +:207220004160012101724272704770B504000E0015003448215A34482018FFF7EFFF78203A +:20724000205C012806D02A00310092B220001830FDF76BFB70BDFEB505000E001400082122 +:2072600000226F463800FFF7E1F92000C0B2782805D02448295A24482818FFF7CFFF792030 +:20728000285C002814D02000C0B211280FD02000C0B212280BD02000C0B2312807D020002B +:2072A000C0B27E2803D02000C0B27F2800D10AE068467F210170467084700322694628008A +:2072C0001830FDF732FBF7BD7CB56C46AE4D2E682660DBB2042B14D3069C0B0004210D0015 +:2072E000258014008078DBB2834204D100222000FFF79CF905E068460A0001002000FEF736 +:2073000013FC73BD8C100000A810000001207047F8B584B006000C00150000200821002091 +:20732000009002AF009A3800FFF780F900206946C880002000202800B1687A22B25CD200B7 +:207340008918497880B289B2884205D2132227213000FFF780FF14E17078012805D122227B +:2073600027213000FFF777FF0BE184204001301803C8FA22D2000023994208DC01DB9042C7 +:2073800005D2372227213000FFF765FFF9E0200041784906490E6A46117167216A461172A6 +:2073A0006946097902AA517069460979C90776D500273800754908703C0000E0641C200092 +:2073C000C0B2042833DA724D684600792100C9B20901695C8842F1D12000C0B20001281852 +:2073E00080782100C9B209016918497888421ED28420400130180CC808382000C0B200011F +:207400002818083003C8121A8B41624800218B4208DC01DB824205D2362227213000FFF778 +:207420001AFFAEE02000C0B2000128184770E4B2042C05DB312227213000FFF70CFFA0E029 +:20744000062301A8801C0090DBB202A8821C684601793000FFF738FF6846C088002818D0CE +:207460006846C288921C92B202A93000FFF7DDFE68460079454908706846C088464908803C +:207480006846C28802A8811C444C2000FEF74CFB77E0312227213000FFF7DDFE71E03B4CF6 +:2074A000694609792278521C914205D0242227213000FFF7D0FE64E0AD1EADB20095831CC7 +:2074C0003548028835492078FFF720FFC0B2012821D1022202A93000FFF7A7FE0020010032 +:2074E000217069460979491EB17001000A00D2B2042A46DA264A6B461B790C00E4B22401E9 +:20750000145DA34205D103000C00E4B2240112195370491CEAE7352227213000FFF79BFEF3 +:2075200000232AE01A4A20781900C9B20901515C884221D11800C0B2000110184078401C54 +:207540001900C9B20901511848701800C0B20001101880781900C9B209015118497888422F +:207560000AD284204001301803C81D00EDB22D015219083203C2083A5B1C1800C0B2042874 +:20758000D0DB05B0F0BD0000CC9A01006B55002000000020102700006855002010550020DE +:2075A000002202604160012101724272704770B504000E0015002548215A25482018FFF7D7 +:2075C000EFFF7820205C012806D02A00310092B220001830FDF7A9F970BDFEB505000E001A +:2075E0001400082100226F463800FFF71FF82000C0B2782805D01548295A15482818FFF7B8 +:20760000CFFF7920285C002814D02000C0B211280FD02000C0B212280BD02000C0B2312837 +:2076200007D02000C0B27E2803D02000C0B27F2800D10AE068467F210170467084700322E6 +:20764000694628001830FDF770F9F7BD8C100000A810000000B50028FFD000BD00B5002860 +:20766000FFD000BD00B50028FFD000BD00B50028FFD000BD00B50028FFD000BD00B5002866 +:20768000FFD000BD00B50028FFD000BD00B50028FFD000BD00B50028FFD000BDF3B5FFB0CC +:2076A00086B0060014000025039528002800280028000320694608708020800001902A00F8 +:2076C00005AF01993800FEF7B1FF2800694608812000B1687A22B25CD2008918497880B2D6 +:2076E00089B2884205D2132231213000FFF775FFE5E0869841784906490E6A4651708178E1 +:207700000902C2788918241F6A4694806A469288002A01D0001D03902C0000E0641C20005B +:207720006A461278C0B2904229D266482200D2B214235A43825A0B009BB29A42EED17178F0 +:207740002200D2B214235A4382189278914222D12100C9B2142251434118C97800290ED03E +:207760002100C9B2142251434018C078B178884205D0332231213000FFF72FFF9FE02000B1 +:2077800069460978C0B288420BD3312231213000FFF723FF93E0222231213000FFF71DFF67 +:2077A0008DE08020800004902A0005AF04993800FEF73CFF68464078012804D066D30328FE +:2077C0004CD027D362E03F4D02A8009080239B0005AA68468188039884462700FFB2142076 +:2077E0004743E81987686046B8470120E4B214214C43291908716846008904284CDB6846FC +:20780000007D712848D16846028905A93000FFF7CEFE54E02B482100C9B2142251434018FB +:207820000079002819D002A8009080239B0005AA6846818803980190224884462700FFB2A8 +:20784000142047436046C019C7680198B8471D48E4B214214C4300190571CCE7194D20009D +:20786000C0B2142148432818007900280DD002A8009080239B0005AA684681880398E4B209 +:2078800014277C432C192469A047B4E7122231213000FFF7A2FE12E068460089032809D120 +:2078A00005A801787F2905D1827831213000FFF794FE04E0242231213000FFF78EFE7FB0C3 +:2078C00008B0F0BD8C010020002202604160012101724272704770B504000E001500AE482F +:2078E000215AAE482018FFF7EFFF7820205C012806D02A00310092B220001830FDF715F8E0 +:2079000070BDFEB505000E001400082100226F463800FEF78BFE2000C0B2782805D09E48BD +:20792000295A9E482818FFF7CFFF7920285C002814D02000C0B211280FD02000C0B212283B +:207940000BD02000C0B2312807D02000C0B27E2803D02000C0B27F2800D10AE068467F213D +:207960000170467084700322694628001830FCF7DCFFF7BDF6B5FFB082B005000020002055 +:207980000026002000200027802189000020009001AC009A2000FEF749FE82A80088A9681A +:2079A0007A22AA5CD2008918497889B2884205D2132222212800FFF7A4FFEAE082A8008860 +:2079C000401EC00705D5132222212800FFF799FFDFE082A80088400880B2002805D113225C +:2079E00022212800FFF78DFFD3E0622001A9320092B28854761C01206946088079E03000F6 +:207A000080B22969220092B214235343C91889894018801C6249884200DB9FE02869210007 +:207A200089B214224A4380188078052800D19BE068782969220092B214235343C918C97878 +:207A4000884200D290E02869210089B214224A4380188289D2B22869210089B214234B4391 +:207A6000C018816828002F69BC462700BFB214237B436746FB181B699847012701A88199E8 +:207A80006A461288895C320092B28154761C81996A46128889184978320092B28154761C37 +:207AA000684646802869210089B214224A43801882892869210089B214234B43C01881688C +:207AC00001A86B465B88C6183000FEF72DF8684640882969A4B214226243891889894618F7 +:207AE0003800C0B2002845D068460088801C694608806846008882A9098888423AD28198B5 +:207B000069460988405C000281996A4612888918497808430024270000E0641C2100AA8A76 +:207B200089B29142DCD22969220092B214235343C95A020092B29142EFD1A87829692200F4 +:207B400092B214235343C9180979884200D156E7332222212800FFF7D4FE1AE014222221DE +:207B60002800FFF7CEFE14E0222222212800FFF7C8FE0EE0FFB2002F06D0320092B201A9F8 +:207B80002800FFF7A8FE04E0312222212800FFF7B8FE7FB004B0F0BD8C100000A8100000EF +:207BA00001020000002202604160012101724272704770B504000E0015009548215A95481C +:207BC0002018FFF7EFFF7820205C012806D02A00310092B220001830FCF7A7FE70BDFEB5F7 +:207BE00005000E001400082100226F463800FEF71DFD2000C0B2782805D08548295A8548F3 +:207C00002818FFF7CFFF7920285C002814D02000C0B211280FD02000C0B212280BD02000C6 +:207C2000C0B2312807D02000C0B27E2803D02000C0B27F2800D10AE068467F21017046702E +:207C400084700322694628001830FCF76EFEF7BD7047704770477047F6B5FFB082B004006D +:207C60000D00002630003000300002206946087080218900320001AF3800FEF7D7FC82A8C2 +:207C80000088A1687A22A25CD2008918497889B2884205D213222F212000FFF7A0FFB3E0DC +:207CA0006078012805D122222F212000FFF797FFAAE028004178090282788918C2786B46B1 +:207CC0005A70350000E06D1C2A006B461B78D2B29A4220D2504A2B00DBB214277B43D35A04 +:207CE0000F00BFB2BB42EED12900C9B2142359435118897800290ED02900C9B214235943E9 +:207D000051188978A278914205D033222F212000FFF765FF78E029006A461278C9B291420F +:207D200005D331222F212000FFF759FF6CE001A96F220A7042784A7082788A70C278CA707D +:207D400069464978002902D003291BD057E032482900C9B2142251434118CE722900C9B245 +:207D6000142251434118096900290AD0EDB214214D43401900698047042201A92000FFF798 +:207D800018FF41E0244E82A909882A00D2B214235A43B218127A121D914205DA22222F2130 +:207DA0002000FFF71CFF2FE001212A00D2B214235A43B218D1722900C9B2142251437118DB +:207DC0000A7A011D2800C0B214235843301847683800FDF7A9FE2800C0B214214843301829 +:207DE000C06800280AD0EDB2142045437019C0688047042201A92000FFF7DBFE04E0312290 +:207E00002F212000FFF7EBFE7FB004B0F0BD00008C100000A81000006401002001000500A4 +:207E2000000000000000000000000000030005000000000000000000000000001100050024 +:207E40000000000000000000000000006300050000000000000000000000000001000000B9 +:207E600032070000DF070000B20700005832002000020000583400200808000000000000C2 +:207E80002B570100075601003200F401881300001A62040050000000000000001B630400ED +:207EA00050000000000000001603F00050000000000000001703F0005000000000000000BF +:207EC0008873C00050000000000000000100C10050000000000000000101C1005000000072 +:207EE000000000000121C10050000000000000000127C10050000000000000000128C1002C +:207F000050000000000000000129C10050000000000000000131C100500000000000000093 +:207F20000041C10050000000000000000151C10050000000000000000063C1005000000018 +:207F4000000000000069C10050000000000000000181C10050000000000000000136C2001B +:207F600050000000000000000064C10050000000000000000067C1005000000000000000C4 +:207F800092F000001855002002000000517C0100537C010020F000001A5500200200000091 +:207FA000557C0100577C010000FF030100000000557601005D7601006576010001FF030198 +:207FC000000000006D760100757601007D76010002FF030100000000857601008D760100D8 +:207FE0009576010086F10601000000002855002001000000B366010087F1060100000000C0 +:208000002955002008000000B966010080F10601000000003155002008000000A966010064 +:2080200093F10601000000003955002004000000C366010095F10601000000003D5500209A +:2080400010000000CD66010091F10601000000004D55002018000000D766010088490870F2 +:20806000704730B5010089B2142927DA0021854A0B000400A4B20C256543541923710300B8 +:208080009BB20C245C4313191B1D1C78102525431D7003009BB20C245C4313191B1D1C788B +:2080A000402525431D7003009BB20C245C431319D98080B20C234343D018017230BD30B5AE +:2080C000010000221000100010000DE06D4B1400A4B20C2565435B191B795B065B0EDBB206 +:2080E0000B4200D0401C521C13009BB2142BEDDB80B230BDF2B50100002318001800180000 +:2081000023E01E00B6B20C277743EE59360C0700BFB2CE55401C1E00B6B20C277743EE59AF +:20812000360A0700BFB2CE55401C1E00B6B20C277743ED590600B6B28D55401C6406640EC7 +:208140000500ADB24C55401C5B1C1C00A4B2142C11DA4C4D1C00A4B20C266643AC19247962 +:208160002600F6B21642EFD06E4636880700BFB23F1DBE42C5DA80B2F2BDF0B5020000238A +:2081800018001800180023E01E00B6B20C277743EE59360C0700BFB2D655401C1E00B6B213 +:2081A0000C277743EE59360A0700BFB2D655401C1E00B6B20C277743ED590600B6B295553B +:2081C000401C6406640E0500ADB25455401C5B1C1C00A4B2142C0DDA2A4D1C00A4B20C26D3 +:2081E0006643AC1924790E00B6B20700BFB23F1DBE42C9DA80B2F0BD10B500242100224933 +:20820000401A04D09D3817D02F382CD035E00EE01C48210089B20C224A43805880214903CE +:20822000884203D2200080B2FFF71BFF641C200080B21428ECDB20E010E01248210089B2C2 +:208240000C224A438058114940188021C903884203D2200080B2FFF704FF641C200080B2B0 +:208260001428EADB09E004E0200080B2FFF7F9FE641C200080B21428F6DB10BD0000000045 +:208280006A5500207400002033FFFF000000C0FF002202604160012101724272704770B531 +:2082A00004000E0015002548215A25482018FFF7EFFF7820205C012806D02A00310092B274 +:2082C00020001830FCF731FB70BDFEB505000E001400082100226F463800FEF7A7F9200023 +:2082E000C0B2782805D01548295A15482818FFF7CFFF7920285C002814D02000C0B2112862 +:208300000FD02000C0B212280BD02000C0B2312807D02000C0B27E2803D02000C0B27F28D1 +:2083200000D10AE068467F210170467084700322694628001830FCF7F8FAF7BD8C100000A0 +:20834000A81000008020704710B5010000200200012200E0521C1300DBB2052B08DA0423DC +:208360009B1ADB000C00DC40002CF3D00520801AC0B210BDF8B584B004001300002210002E +:2083800015001500160016001600160016006778012F05D1222234212000FFF796FF8EE0AE +:2083A0009C46A7687A23E35CDB00FB185B786746BFB29BB29F4205D2132234212000FFF76C +:2083C00084FF7CE00191019989780907090F6B46197001998978C9B209096B4659706946DE +:2083E000097800290BD069460978052907D269464978002903D069464978052905D331228C +:2084000034212000FFF761FF59E0110007E00002019B0F00FFB2DB19DB78C018491C0B0073 +:208420006F463F78DBB2BB42F1D30AE02902019B6D462D781700FFB2ED195B19DB78CD18FF +:20844000521C11006B465B78C9B29942EED3002D05D1222234212000FFF737FF2FE000F01B +:2084600087F8280000F087F8012000F08AF8FFF769FF05002800FFF767FF02A974223300F8 +:208480009BB2CA54761C320003011600B6B28B55521C012308E0C61AF7002E00FE40170077 +:2084A000BFB2CE55521C5B1C06001F00F6B2FFB2BE42F0D292B202A92000FFF7F0FE05B05B +:2084C000F0BD0000002202604160012101724272704770B504000E0015007948215A794881 +:2084E0002018FFF7EFFF7820205C012806D02A00310092B220001830FCF717FA70BDFEB562 +:2085000005000E001400082100226F463800FEF78DF82000C0B2782805D06948295A694896 +:208520002818FFF7CFFF7920285C002814D02000C0B211280FD02000C0B212280BD020009D +:20854000C0B2312807D02000C0B27E2803D02000C0B27F2800D10AE068467F210170467005 +:2085600084700322694628001830FCF7DEF9F7BD55490860704755490860704753480068C8 +:2085800070475349087000200100524A11700100514A11705149086070474D480078704738 +:2085A0004E4800687047F0B5FFB082B004000E00150000221000694608808021890001AF16 +:2085C0003800FEF733F86078012805D1222236212000FFF794FF6EE028000100A2687A230A +:2085E000E35CDB00D218527889B292B2914205D2132236212000FFF782FF5CE03449097827 +:20860000012902D002294BD050E0334972780A70304B0A781D78AA420BD00A781D786D1C0F +:20862000EDB2AA4205D0732236212000FFF767FF41E001AA76256F463F88D5556D462D88FD +:208640006D1C77782E00B6B297556D1C2A000D781E78B54205D192B201A92000FFF739FF49 +:2086600029E01E4D194E3768BC462F680600B6B2BE19B61E6746B74205D271223621200047 +:20868000FFF73DFF17E02E6880B2801E301828600878187092B201A92000FFF71AFF0AE06C +:2086A000312236212000FFF72AFF04E0242236212000FFF724FF7FB002B0F0BD0000000089 +:2086C0008C100000A81000001C550020205500206D5500206F5500206E55002024550020DE +:2086E000002202604160012101724272704770B504000E0015007848215A78482018FFF7E0 +:20870000EFFF7820205C012806D02A00310092B220001830FCF709F970BDFEB505000E0069 +:208720001400082100226F463800FDF77FFF2000C0B2782805D06848295A68482818FFF75B +:20874000CFFF7920285C002814D02000C0B211280FD02000C0B212280BD02000C0B23128E6 +:2087600007D02000C0B27E2803D02000C0B27F2800D10AE068467F21017046708470032295 +:20878000694628001830FCF7D0F8F7BDF2B582B0040015000821002632006F463800FDF7F7 +:2087A00045FF3000A0687A21615CC90040184078ADB280B2854205D2132228212000FFF749 +:2087C000ACFF86E06078012805D1222228212000FFF7A3FF7DE0029841784906490E80781E +:2087E0006A46682313705170C9B2002905D0022936D01BD303294DD066E00100C9B201292D +:2088000006D00100C9B2022902D0C0B2032807D133480670022269462000FFF768FF04E06F +:20882000312228212000FFF778FF52E00100C9B2012906D00100C9B2022902D0C0B203284B +:2088400008D1012026490870022269462000FFF74EFF04E0312228212000FFF75EFF38E0F6 +:208860000100C9B2012906D00100C9B2022902D0C0B2032808D102201949087002226946BE +:208880002000FFF734FF04E0312228212000FFF744FF1EE00100C9B2012906D00100C9B2C0 +:2088A000022902D0C0B2032808D103200C490870022269462000FFF71AFF04E031222821D3 +:2088C0002000FFF72AFF04E0122228212000FFF724FFF7BD000000008C100000A8100000B7 +:2088E0006C550020010101002B010100D901010000000000F9010100CD0201004D0401006F +:20890000A10401005B050100AF05010075060100C906010089070100DD0701009708010039 +:20892000EB080100A5090100F9090100B90A0100090B0100670B01009F0B0100CB0B0100C3 +:20894000050C0100350C0100CF0C0100750D0100CB0E0100AD11010000000000B511010004 +:20896000D7110100FD1101001F12010045120100000000004F12010097120100291301002C +:208980004F130100751301009B130100C1130100E71301000D140100331401005914010094 +:2089A0007F140100A514010073150100BF1601001B170100E11701003D180100F11801007E +:2089C0002719010075190100AB190100F3190100291A0100751A0100AB1A0100F31A01004D +:2089E000291B0100751B0100AD1B0100F51B0100131C0100391C0100571C01007D1C010033 +:208A00009B1C0100C11C0100DF1C0100051D0100231D0100491D0100671D01008D1D0100C9 +:208A2000171E0100F71E0100151F01003B1F01008B1F01001120010061200100F1200100E9 +:208A400041210100C7210100172201009D220100ED22010073230100C32301004D240100D0 +:208A6000DB240100A5250100A9250100CF250100ED25010013260100312601005726010044 +:208A800077260100A1260100C1260100EB2601000B27010035270100552701007F270100C2 +:208AA0000000000087270100000000008F2701000000000097270100F5270100D12801007A +:208AC0002F2901000B2A0100392A01008B2A0100B92A0100112B0100312B010000220260EB +:208AE0004160012101724272704770B504000E0015002548215A25482018FFF7EFFF782080 +:208B0000205C012806D02A00310092B220001830FBF70BFF70BDFEB505000E0014000821A7 +:208B200000226F463800FDF781FD2000C0B2782805D01548295A15482818FFF7CFFF7920D3 +:208B4000285C002814D02000C0B211280FD02000C0B212280BD02000C0B2312807D0200052 +:208B6000C0B27E2803D02000C0B27F2800D10AE068467F21017046708470032269462800B1 +:208B80001830FBF7D2FEF7BD8C100000A8100000F2B582B004001500002630003000082122 +:208BA00032006F463800FDF741FD2800A1687A22A25CD2008918497880B289B2884205D257 +:208BC00013222E212000FFF7A6FF7BE0029841780902827811436A466E231370437853700D +:208BE0008378937000E0761C3200A38A92B29A4263D2226933009BB214275F43D25B0B0031 +:208C00009BB29A42EFD12169320092B214235343C918097900290FD0A178226933009BB20F +:208C200014275F43D2191279914205D0332222212000FFF770FF45E0ADB2E91E22693300D3 +:208C40009BB214255D4352199289914205D013222E212000FFF75FFF34E02169320092B2B4 +:208C600014235343C9188978032909D06178226933009BB214255D435219D278914205D224 +:208C800022222E212000FFF746FF1BE02169320092B214235343C9188A89C11C2069B6B25C +:208CA00014237343C01885682800FCF73DFF032269462000FFF719FF04E031222E21200003 +:208CC000FFF729FFF7BD0000002202604160012101724272704770B504000E0015002548E4 +:208CE000215A25482018FFF7EFFF7820205C012806D02A00310092B220001830FBF715FE51 +:208D000070BDFEB505000E001400082100226F463800FDF78BFC2000C0B2782805D0154835 +:208D2000295A15482818FFF7CFFF7920285C002814D02000C0B211280FD02000C0B21228B0 +:208D40000BD02000C0B2312807D02000C0B27E2803D02000C0B27F2800D10AE068467F2129 +:208D60000170467084700322694628001830FBF7DCFDF7BD8C100000A8100000F8B5FFB065 +:208D800081B005000C00170000221000100010001000802189006E463000FDF747FC38009B +:208DA000A9687A22AA5CD2008918497880B289B2884205D2132219212800FFF7A2FF5EE052 +:208DC00020007F26417831406C46592222706170C9B2012904D002291DD00A2934D049E023 +:208DE000BFB2032F05D0132219212800FFF789FF45E08078C0B2FFF762F9A6700121E1707D +:208E0000010089B2090A21716071062269462800FFF761FF33E0BFB2032F05D01322192151 +:208E20002800FFF76EFF2AE08278A670D2B2FF21FE31E01CFFF75EF9C01C020092B26946A0 +:208E40002800FFF748FF1AE0BFB2022F05D0132219212800FFF755FF11E0FF21FE31E01C1F +:208E6000FFF78BF9C01C020092B269462800FFF732FF04E0122219212800FFF742FF7FB078 +:208E800002B0F0BD002202604160012101724272704770B504000E0015005748215A574849 +:208EA0002018FFF7EFFF7820205C012806D02A00310092B220001830FBF737FD70BDFEB576 +:208EC00005000E001400082100226F463800FDF7ADFB2000C0B2782805D04748295A4748EF +:208EE0002818FFF7CFFF7920285C002814D02000C0B211280FD02000C0B212280BD02000D4 +:208F0000C0B2312807D02000C0B27E2803D02000C0B27F2800D10AE068467F21017046703B +:208F200084700322694628001830FBF7FEFCF7BDF2B582B0040015000821002632006F4631 +:208F40003800FDF773FBA0687A21615CC90040184078ADB280B2854205D01322102120008B +:208F6000FFF7ADFF47E0029840784006400E694650220A704870224AA25A92B2120A8A702D +:208F80001F4AA25ACA701F4AA25A92B2120A0A711C4AA25A4A710100C9B2012906D025D361 +:208FA00003290BD012D3042918D01FE0A6706070062269462000FFF76CFF1CE0A670607091 +:208FC000062269462000FFF764FF14E0A6706070062269462000FFF75CFF0CE0A67060704D +:208FE000062269462000FFF754FF04E0122210212000FFF764FFF7BD8C100000A810000067 +:20900000881000008A100000002202604160012101724272704770B504000E001500254840 +:20902000215A25482018FFF7EFFF7820205C012806D02A00310092B220001830FBF775FCAF +:2090400070BDFEB505000E001400082100226F463800FDF7EBFA2000C0B2782805D0154894 +:20906000295A15482818FFF7CFFF7920285C002814D02000C0B211280FD02000C0B212286D +:209080000BD02000C0B2312807D02000C0B27E2803D02000C0B27F2800D10AE068467F21E6 +:2090A0000170467084700322694628001830FBF73CFCF7BD8C100000A8100000FEB5040068 +:2090C00016000022150008216F463800FDF7AEFA6078012805D1222237212000FFF7B1FF58 +:2090E0003EE0A0687A21615CC90040184078B6B280B2864205D2132237212000FFF7A1FF9D +:209100002EE0772069462A0092B288546D1CFFF744FA012802D0022814D019E0FFF740FAC2 +:209120000600FFF72BFA864205D0132237212000FFF787FF11E02A0092B269462000FFF724 +:209140006AFF0AE0312237212000FFF77AFF04E0242237212000FFF774FF0020FFF711FA56 +:20916000F7BD0000002202604160012101724272704770B504000E0015002548215A254875 +:209180002018FFF7EFFF7820205C012806D02A00310092B220001830FBF7C7FB70BDFEB505 +:2091A00005000E001400082100226F463800FDF73DFA2000C0B2782805D01548295A1548E1 +:2091C0002818FFF7CFFF7920285C002814D02000C0B211280FD02000C0B212280BD02000F1 +:2091E000C0B2312807D02000C0B27E2803D02000C0B27F2800D10AE068467F210170467059 +:2092000084700322694628001830FBF78EFBF7BD8C100000A8100000FEB504000D001600B9 +:20922000082100226F463800FDF700FAA0687A21615CC90040184078B6B280B2864205D296 +:20924000132285212000FFF7AAFF2CE06078012805D1222285212000FFF7A1FF23E068780E +:209260004006400E6946C5220A704870C0B2012802D0022809D011E00120FEF7EFFE02220A +:2092800069462000FFF775FF0DE00020FEF7E6FE022269462000FFF76CFF04E0122285219D +:2092A0002000FFF77CFFF7BD002202604160012101724272704770B504000E00150025488B +:2092C000215A25482018FFF7EFFF7820205C012806D02A00310092B220001830FBF725FB5E +:2092E00070BDFEB505000E001400082100226F463800FDF79BF92000C0B2782805D0154843 +:20930000295A15482818FFF7CFFF7920285C002814D02000C0B211280FD02000C0B21228CA +:209320000BD02000C0B2312807D02000C0B27E2803D02000C0B27F2800D10AE068467F2143 +:209340000170467084700322694628001830FBF7ECFAF7BD8C100000A8100000FEB5040017 +:209360000D001600082100226F463800FDF75EF9FF20A1687A22A25CD20089184978B6B2E9 +:2093800089B28E4205D0132211212000FFF7A9FF2AE069784906490E6A46512313705170CF +:2093A0009070C9B2012904D019D303290FD008D315E0032269462000FFF77DFFFDF7B3FE62 +:2093C00012E0032269462000FFF775FF0CE0032269462000FFF76FFFFDF7AFFE04E0122240 +:2093E00011212000FFF77DFFF7BD0000002202604160012101724272704770B504000E0099 +:2094000015004448215A44482018FFF7EFFF7820205C012806D02A00310092B2200018306E +:20942000FBF783FA70BDFEB505000E001400082100226F463800FDF7F9F82000C0B2782867 +:2094400005D03448295A34482818FFF7CFFF7920285C002814D02000C0B211280FD02000C5 +:20946000C0B212280BD02000C0B2312807D02000C0B27E2803D02000C0B27F2800D10AE0A4 +:2094800068467F210170467084700322694628001830FBF74AFAF7BDFEB504000D0016005B +:2094A0000022029208216F463800FDF7BFF8A0687A21615CC90040184078B6B280B286429A +:2094C00005D0132214212000FFF7ADFF20E00299687800040843A97809020143E8780843A6 +:2094E00054216A46117001000C4A891A03D09D3901D02F3907D1FEF77FFE012269462000AE +:20950000FFF77BFF04E0312214212000FFF78BFFF7BD00008C100000A810000033FFFF0096 +:20952000002202604160012101724272704770B504000E0015002548215A25482018FFF737 +:20954000EFFF7820205C012806D02A00310092B220001830FBF7E9F970BDFEB505000E003C +:209560001400082100226F463800FDF75FF82000C0B2782805D01548295A15482818FFF7DA +:20958000CFFF7920285C002814D02000C0B211280FD02000C0B212280BD02000C0B2312898 +:2095A00007D02000C0B27E2803D02000C0B27F2800D10AE068467F21017046708470032247 +:2095C000694628001830FBF7B0F9F7BD8C100000A8100000FEB504000D00160008210022A4 +:2095E0006F463800FDF722F8A0687A21615CC90040184078B6B280B2864205D013223E216C +:209600002000FFF7AAFF15E068784006400E0100C9B2002909D169467E220A7048700222FE +:2096200069462000FFF783FF04E012223E212000FFF793FFF7BD0000FFB51F481F49204A23 +:209640000392204A204B214C0294214C214D0195214D224E224F009703E00F780770401C09 +:20966000491C039F8F42F8D10298984207D018781070521C5B1CF7E700202070641C019862 +:20968000A042F9D10098B04204D030782870761C6D1CF7E7002006E0124982008958124A67 +:2096A0008300D150401C114989088842F4D30E480F490860FFBD00BF000000201C7E0100E2 +:2096C0005C80010040020020D49A0100D49A01000020002070550020000000000000000048 +:2096E0000000000000000100000001000000000008ED00E000000100320700000001080050 +:2097000001000000FFFFFFFF01000100DF0700000001080001000000FFFFFFFF020001005B +:20972000440400000001080001000000FFFFFFFF0300010055050000000108000100000073 +:20974000FFFFFFFF05000100B20700000000080000000000FFFFFFFF060001001101000031 +:209760000000080000000000FFFFFFFF07000100220200000000080000000000FFFFFFFFB5 +:20978000000000000000000000000000000000000000000010020100318F010011020100E1 +:2097A0005D9301002702010011730100280301008D8701003E020100D59501008502010094 +:2097C0001992010022030000757901002E040000918B010014040000999401001903010017 +:2097E0007D8D01002F030000597C0100310401009D760100340500007583010036020000A2 +:20980000A785010037010000BD90010072B60021002200230024002500260027B846B94674 +:20982000BA46BB46BC460C490C4A521A013A05DD0020042308601944043AFBDA08488546B7 +:20984000084880470848804762B600F00FF88047FCF736F8FEE7000000000020FF6300205C +:20986000F05F00204F450100399601000548014603B4684680F3098800BF00BF00BF00BF1B +:2098800000F002F8A5EDF5FE00F00DF8002801D000BF00BF00BF00BF002000BF00BFFCF7DE +:2098A0000FF800F002F80120704780B500F002F801BD00000746384600F002F8FBE700006B +:2098C00080B500BF00BF024A11001820ABBEFBE7260002004669727374206672616D65207A +:2098E00073686F756C64206E6F7420757365206D756C7469706C65206672616D652074723E +:20990000616E736D697373696F6E2E004D756C74692D6672616D6520726573706F6E736503 +:2099200020746F6F206C6172676520666F7220726563656976696E67206275666665722E7F +:20994000000000004D6573736167652073697A6520746F6F206C617267652E205365742030 +:2099600061206C61726765722073656E64206275666665720A00000041626F727420707281 +:209980006576696F7573206D6573736167652C207472616E736D697373696F6E20696E209A +:2099A00070726F67726573732E0A00000000000000000000000000000000000000000000FA +:2099C0000000000000000000000000000000000000000000000000000000000053696E67F6 +:2099E0006C652D6672616D65206C656E67746820746F6F20736D616C6C206F7220746F6F9E +:209A0000206C617267652E004669727374206672616D652073686F756C64206265203820AC +:209A2000627974657320696E206C656E6774682E00000000436F6E73656375746976652090 +:209A40006672616D6520746F6F2073686F72742E00000000466C6F7720636F6E74726F6C52 +:209A6000206672616D6520746F6F2073686F72742E0000009B6B0100856B01006F6B0100F8 +:209A8000596B0100C36B0100AD6B01003031323334353637383941424344454661707020B6 +:209AA00073746172740A00005465726D696E616C00000000746573740A0000000001020362 +:209AC0000405000053454747455200000102030400000000FFFFFFFFFFFFFFFFFFFFFFFFC2 +:209AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +:209B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +:209B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +:209B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:209B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:209B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:209BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:209BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +:209BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +:209C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:209C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:209C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +:209C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +:209C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +:209CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +:209CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +:209CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:209D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:209D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:209D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:209D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:209D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:209DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:209DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +:209DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +:209E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:209E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:209E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:209E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:209E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:209EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:209EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:209EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:209F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:209F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:209F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:209F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:209F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:209FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:209FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +:209FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:20A00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:20A02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:20A04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:20A06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:20A08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:20A0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:20A0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:20A0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:20A10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +:20A12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +:20A14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +:20A16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +:20A18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +:20A1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +:20A1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +:20A1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +:20A20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +:20A22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +:20A24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +:20A26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +:20A28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +:20A2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +:20A2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +:20A2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +:20A30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +:20A32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +:20A34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +:20A36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +:20A38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +:20A3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:20A3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +:20A3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +:20A40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +:20A42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +:20A44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +:20A46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +:20A48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +:20A4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +:20A4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:20A4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:20A50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +:20A52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +:20A54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +:20A56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +:20A58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +:20A5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +:20A5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +:20A5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +:20A60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +:20A62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +:20A64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +:20A66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +:20A68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +:20A6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +:20A6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +:20A6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +:20A70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +:20A72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +:20A74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +:20A76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +:20A78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +:20A7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +:20A7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +:20A7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +:20A80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +:20A82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +:20A84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +:20A86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +:20A88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +:20A8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +:20A8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +:20A8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +:20A90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:20A92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:20A94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:20A96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:20A98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:20A9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +:20A9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:20A9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:20AA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +:20AA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +:20AA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +:20AA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +:20AA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +:20AAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +:20AAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +:20AAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +:20AB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +:20AB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +:20AB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +:20AB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +:20AB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +:20ABA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:20ABC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +:20ABE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +:20AC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:20AC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:20AC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +:20AC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +:20AC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +:20ACA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +:20ACC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:20ACE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:20AD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:20AD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:20AD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:20AD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:20AD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:20ADA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +:20ADC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +:20ADE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +:20AE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:20AE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:20AE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:20AE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:20AE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:20AEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:20AEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:20AEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:20AF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:20AF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:20AF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +:20AF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:20AF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:20AFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:20AFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:20AFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:20B00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:20B02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:20B04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:20B06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:20B08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:20B0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:20B0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:20B0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:20B10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +:20B12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +:20B14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +:20B16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +:20B18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +:20B1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +:20B1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +:20B1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +:20B20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +:20B22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:20B24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +:20B26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +:20B28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +:20B2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +:20B2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +:20B2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:20B30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:20B32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:20B34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:20B36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:20B38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:20B3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:20B3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:20B3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:20B40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +:20B42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +:20B44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +:20B46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +:20B48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +:20B4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +:20B4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:20B4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:20B50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +:20B52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +:20B54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +:20B56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +:20B58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +:20B5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +:20B5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +:20B5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +:20B60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +:20B62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +:20B64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +:20B66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +:20B68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +:20B6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +:20B6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +:20B6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +:20B70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +:20B72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +:20B74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +:20B76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +:20B78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +:20B7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +:20B7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +:20B7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +:20B80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +:20B82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +:20B84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +:20B86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +:20B88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +:20B8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:20B8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +:20B8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +:20B90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:20B92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:20B94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:20B96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:20B98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +:20B9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +:20B9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:20B9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:20BA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +:20BA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +:20BA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +:20BA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +:20BA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +:20BAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +:20BAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +:20BAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +:20BB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +:20BB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:20BB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:20BB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:20BB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:20BBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +:20BBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +:20BBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +:20BC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:20BC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +:20BC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +:20BC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +:20BC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +:20BCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +:20BCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:20BCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:20BD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:20BD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:20BD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:20BD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:20BD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:20BDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +:20BDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +:20BDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:20BE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:20BE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:20BE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:20BE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:20BE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:20BEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:20BEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:20BEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:20BF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:20BF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:20BF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:20BF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:20BF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:20BFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +:20BFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:20BFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:20C00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:20C02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:20C04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:20C06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:20C08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:20C0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:20C0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:20C0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:20C10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +:20C12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +:20C14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +:20C16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +:20C18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +:20C1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +:20C1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +:20C1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +:20C20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +:20C22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +:20C24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +:20C26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +:20C28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +:20C2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +:20C2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +:20C2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +:20C30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +:20C32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +:20C34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +:20C36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +:20C38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:20C3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +:20C3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +:20C3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +:20C40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +:20C42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +:20C44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +:20C46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +:20C48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +:20C4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:20C4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:20C4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +:20C50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +:20C52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +:20C54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +:20C56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +:20C58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +:20C5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +:20C5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +:20C5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +:20C60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +:20C62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +:20C64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +:20C66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +:20C68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +:20C6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +:20C6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +:20C6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +:20C70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +:20C72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +:20C74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +:20C76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +:20C78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +:20C7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +:20C7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +:20C7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +:20C80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +:20C82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +:20C84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +:20C86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +:20C88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +:20C8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +:20C8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +:20C8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +:20C90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:20C92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:20C94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:20C96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:20C98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +:20C9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:20C9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:20C9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:20CA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +:20CA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +:20CA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +:20CA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +:20CA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +:20CAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +:20CAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +:20CAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +:20CB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +:20CB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +:20CB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +:20CB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +:20CB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:20CBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +:20CBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +:20CBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +:20CC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:20CC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +:20CC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +:20CC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +:20CC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +:20CCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:20CCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:20CCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:20CD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:20CD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:20CD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:20CD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:20CD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +:20CDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +:20CDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +:20CDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:20CE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:20CE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:20CE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:20CE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:20CE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:20CEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:20CEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:20CEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:20CF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:20CF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +:20CF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:20CF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:20CF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:20CFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:20CFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:20CFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:20D00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:20D02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:20D04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:20D06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:20D08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:20D0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:20D0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:20D0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:20D10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +:20D12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +:20D14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +:20D16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +:20D18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +:20D1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +:20D1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +:20D1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +:20D20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:20D22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +:20D24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +:20D26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +:20D28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +:20D2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +:20D2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:20D2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +:20D30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:20D32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:20D34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:20D36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:20D38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:20D3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:20D3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:20D3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:20D40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +:20D42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +:20D44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +:20D46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +:20D48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +:20D4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:20D4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:20D4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +:20D50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +:20D52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +:20D54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +:20D56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +:20D58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +:20D5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +:20D5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +:20D5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +:20D60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +:20D62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +:20D64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +:20D66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +:20D68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +:20D6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +:20D6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +:20D6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +:20D70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +:20D72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +:20D74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +:20D76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +:20D78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +:20D7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +:20D7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +:20D7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +:20D80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +:20D82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +:20D84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +:20D86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +:20D88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:20D8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +:20D8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +:20D8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +:20D90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:20D92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:20D94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:20D96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +:20D98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +:20D9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:20D9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:20D9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:20DA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +:20DA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +:20DA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +:20DA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +:20DA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +:20DAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +:20DAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +:20DAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +:20DB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:20DB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:20DB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:20DB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:20DB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +:20DBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +:20DBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +:20DBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +:20DC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +:20DC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +:20DC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +:20DC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +:20DC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +:20DCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:20DCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:20DCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:20DD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:20DD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:20DD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:20DD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:20DD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +:20DDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +:20DDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:20DDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:20DE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:20DE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:20DE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:20DE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:20DE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:20DEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:20DEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:20DEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:20DF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:20DF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:20DF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:20DF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:20DF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +:20DFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:20DFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:20DFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:20E00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:20E02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:20E04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:20E06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:20E08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:20E0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:20E0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:20E0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:20E10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +:20E12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +:20E14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +:20E16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +:20E18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +:20E1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +:20E1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +:20E1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +:20E20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +:20E22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +:20E24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +:20E26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +:20E28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +:20E2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +:20E2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +:20E2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +:20E30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +:20E32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +:20E34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +:20E36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:20E38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +:20E3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +:20E3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +:20E3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +:20E40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +:20E42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +:20E44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +:20E46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +:20E48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:20E4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:20E4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +:20E4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +:20E50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +:20E52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +:20E54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +:20E56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +:20E58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +:20E5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +:20E5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +:20E5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +:20E60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +:20E62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +:20E64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +:20E66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +:20E68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +:20E6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +:20E6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +:20E6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +:20E70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +:20E72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +:20E74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +:20E76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +:20E78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +:20E7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +:20E7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +:20E7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +:20E80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +:20E82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +:20E84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +:20E86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +:20E88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +:20E8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +:20E8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +:20E8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +:20E90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:20E92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:20E94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:20E96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +:20E98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:20E9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:20E9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:20E9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:20EA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +:20EA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +:20EA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +:20EA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +:20EA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +:20EAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +:20EAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +:20EAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +:20EB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +:20EB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +:20EB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +:20EB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:20EB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +:20EBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +:20EBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +:20EBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +:20EC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +:20EC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +:20EC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +:20EC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +:20EC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:20ECA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:20ECC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:20ECE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:20ED0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:20ED2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:20ED4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:20ED6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +:20ED8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +:20EDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +:20EDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:20EDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:20EE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:20EE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:20EE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:20EE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:20EE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:20EEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:20EEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:20EEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:20EF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +:20EF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:20EF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:20EF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:20EF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:20EFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:20EFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:20EFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:20F00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:20F02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:20F04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:20F06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:20F08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:20F0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:20F0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:20F0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:20F10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +:20F12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +:20F14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +:20F16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +:20F18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +:20F1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +:20F1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +:20F1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +:20F20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +:20F22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +:20F24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +:20F26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +:20F28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +:20F2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:20F2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +:20F2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:20F30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:20F32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:20F34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:20F36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:20F38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:20F3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:20F3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:20F3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:20F40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +:20F42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +:20F44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +:20F46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +:20F48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:20F4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:20F4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +:20F4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +:20F50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +:20F52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +:20F54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +:20F56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +:20F58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +:20F5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +:20F5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +:20F5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +:20F60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +:20F62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +:20F64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +:20F66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +:20F68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +:20F6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +:20F6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +:20F6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +:20F70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +:20F72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +:20F74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +:20F76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +:20F78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +:20F7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +:20F7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +:20F7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +:20F80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +:20F82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +:20F84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +:20F86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:20F88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +:20F8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +:20F8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +:20F8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +:20F90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:20F92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:20F94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +:20F96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +:20F98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:20F9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:20F9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:20F9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:20FA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +:20FA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +:20FA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +:20FA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +:20FA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +:20FAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +:20FAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +:20FAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +:20FB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:20FB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:20FB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:20FB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +:20FB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +:20FBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +:20FBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +:20FBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:20FC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +:20FC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +:20FC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +:20FC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +:20FC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:20FCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:20FCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:20FCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +:20FD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:20FD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:20FD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:20FD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +:20FD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +:20FDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:20FDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:20FDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:20FE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:20FE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:20FE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:20FE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:20FE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:20FEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:20FEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:20FEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:20FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:20FF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:20FF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:20FF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +:20FF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:20FFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:20FFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:20FFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:020000022000DC +:20000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:20002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:20004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:20006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:20008000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:2000A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:2000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:2000E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:20010000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +:20012000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +:20014000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +:20016000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +:20018000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +:2001A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +:2001C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +:2001E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +:20020000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +:20022000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +:20024000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +:20026000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +:20028000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +:2002A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +:2002C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +:2002E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +:20030000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +:20032000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +:20034000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:20036000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +:20038000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +:2003A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +:2003C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +:2003E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +:20040000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +:20042000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +:20044000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +:20046000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:20048000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:2004A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +:2004C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +:2004E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +:20050000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +:20052000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +:20054000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +:20056000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +:20058000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +:2005A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +:2005C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +:2005E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +:20060000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +:20062000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +:20064000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +:20066000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +:20068000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +:2006A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +:2006C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +:2006E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +:20070000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +:20072000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +:20074000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +:20076000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +:20078000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +:2007A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +:2007C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +:2007E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +:20080000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +:20082000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +:20084000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +:20086000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +:20088000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +:2008A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +:2008C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +:2008E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +:20090000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:20092000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:20094000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +:20096000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:20098000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:2009A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:2009C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:2009E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:200A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +:200A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +:200A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +:200A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +:200A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +:200AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +:200AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +:200AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +:200B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +:200B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +:200B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:200B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +:200B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +:200BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +:200BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +:200BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +:200C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +:200C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +:200C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +:200C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:200C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:200CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:200CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:200CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +:200D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:200D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:200D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +:200D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +:200D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +:200DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:200DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:200DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:200E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:200E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:200E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:200E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:200E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:200EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:200EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:200EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:200F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:200F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:200F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:200F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:200F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:200FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:200FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:200FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +:20100000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:20102000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:20104000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:20106000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:20108000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:2010A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:2010C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:2010E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:20110000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +:20112000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +:20114000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +:20116000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +:20118000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +:2011A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +:2011C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +:2011E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +:20120000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +:20122000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +:20124000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +:20126000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +:20128000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:2012A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +:2012C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:2012E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +:20130000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:20132000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:20134000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:20136000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:20138000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:2013A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:2013C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:2013E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:20140000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +:20142000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +:20144000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +:20146000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:20148000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:2014A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +:2014C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +:2014E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +:20150000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +:20152000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +:20154000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +:20156000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +:20158000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +:2015A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +:2015C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +:2015E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +:20160000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +:20162000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +:20164000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +:20166000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +:20168000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +:2016A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +:2016C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +:2016E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +:20170000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +:20172000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +:20174000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +:20176000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +:20178000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +:2017A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +:2017C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +:2017E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +:20180000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +:20182000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +:20184000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:20186000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +:20188000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +:2018A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +:2018C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +:2018E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +:20190000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:20192000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +:20194000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +:20196000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:20198000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:2019A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:2019C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:2019E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:201A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +:201A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +:201A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +:201A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +:201A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +:201AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +:201AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +:201AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +:201B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:201B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:201B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +:201B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +:201B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +:201BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +:201BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:201BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:201C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +:201C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +:201C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +:201C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:201C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:201CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:201CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +:201CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +:201D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:201D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:201D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +:201D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +:201D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:201DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:201DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:201DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:201E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:201E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:201E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:201E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:201E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:201EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:201EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:201EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:201F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:201F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:201F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +:201F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:201F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:201FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:201FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:201FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:20200000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:20202000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:20204000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:20206000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:20208000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:2020A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:2020C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:2020E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:20210000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +:20212000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +:20214000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +:20216000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +:20218000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +:2021A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +:2021C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +:2021E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +:20220000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +:20222000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +:20224000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +:20226000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +:20228000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +:2022A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +:2022C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +:2022E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +:20230000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +:20232000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:20234000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +:20236000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +:20238000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +:2023A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +:2023C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +:2023E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +:20240000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +:20242000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +:20244000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:20246000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:20248000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +:2024A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +:2024C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +:2024E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +:20250000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +:20252000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +:20254000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +:20256000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +:20258000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +:2025A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +:2025C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +:2025E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +:20260000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +:20262000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +:20264000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +:20266000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +:20268000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +:2026A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +:2026C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +:2026E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +:20270000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +:20272000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +:20274000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +:20276000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +:20278000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +:2027A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +:2027C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +:2027E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +:20280000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +:20282000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +:20284000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +:20286000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +:20288000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +:2028A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +:2028C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +:2028E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +:20290000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:20292000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +:20294000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:20296000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:20298000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:2029A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:2029C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:2029E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:202A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +:202A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +:202A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +:202A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +:202A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +:202AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +:202AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +:202AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +:202B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +:202B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:202B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +:202B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +:202B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +:202BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +:202BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +:202BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +:202C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +:202C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +:202C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:202C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:202C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:202CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:202CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +:202CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +:202D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:202D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +:202D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +:202D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +:202D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:202DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:202DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:202DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:202E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:202E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:202E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:202E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:202E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:202EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:202EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:202EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:202F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:202F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:202F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:202F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:202F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:202FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:202FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +:202FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:20300000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:20302000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:20304000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:20306000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:20308000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:2030A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:2030C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:2030E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:20310000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +:20312000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +:20314000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +:20316000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +:20318000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +:2031A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +:2031C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +:2031E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +:20320000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +:20322000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +:20324000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +:20326000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:20328000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +:2032A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:2032C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +:2032E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +:20330000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:20332000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:20334000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:20336000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:20338000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:2033A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:2033C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:2033E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:20340000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +:20342000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +:20344000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:20346000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:20348000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +:2034A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +:2034C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +:2034E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +:20350000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +:20352000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +:20354000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +:20356000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +:20358000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +:2035A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +:2035C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +:2035E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +:20360000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +:20362000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +:20364000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +:20366000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +:20368000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +:2036A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +:2036C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +:2036E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +:20370000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +:20372000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +:20374000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +:20376000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +:20378000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +:2037A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +:2037C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +:2037E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +:20380000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +:20382000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:20384000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +:20386000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +:20388000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +:2038A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +:2038C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +:2038E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +:20390000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +:20392000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +:20394000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:20396000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:20398000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:2039A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:2039C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:2039E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:203A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +:203A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +:203A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +:203A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +:203A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +:203AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +:203AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +:203AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +:203B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:203B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +:203B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +:203B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +:203B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +:203BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:203BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:203BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:203C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +:203C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +:203C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:203C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:203C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:203CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +:203CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +:203CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +:203D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:203D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +:203D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +:203D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:203D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:203DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:203DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:203DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:203E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:203E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:203E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:203E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:203E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:203EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:203EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:203EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:203F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:203F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +:203F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:203F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:203F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:203FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:203FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:203FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:20400000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:20402000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:20404000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:20406000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:20408000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:2040A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:2040C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:2040E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:20410000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +:20412000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +:20414000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +:20416000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +:20418000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +:2041A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +:2041C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +:2041E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +:20420000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +:20422000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +:20424000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +:20426000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +:20428000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +:2042A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +:2042C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +:2042E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +:20430000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:20432000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +:20434000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +:20436000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +:20438000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +:2043A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +:2043C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +:2043E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +:20440000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +:20442000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:20444000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:20446000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +:20448000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +:2044A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +:2044C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +:2044E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +:20450000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +:20452000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +:20454000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +:20456000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +:20458000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +:2045A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +:2045C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +:2045E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +:20460000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +:20462000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +:20464000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +:20466000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +:20468000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +:2046A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +:2046C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +:2046E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +:20470000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +:20472000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +:20474000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +:20476000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +:20478000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +:2047A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +:2047C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +:2047E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +:20480000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +:20482000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +:20484000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +:20486000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +:20488000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +:2048A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +:2048C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +:2048E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +:20490000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +:20492000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:20494000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:20496000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:20498000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:2049A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:2049C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:2049E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:204A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +:204A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +:204A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +:204A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +:204A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +:204AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +:204AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +:204AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +:204B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:204B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +:204B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +:204B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +:204B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +:204BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +:204BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +:204BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +:204C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +:204C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:204C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:204C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:204C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:204CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +:204CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +:204CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +:204D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +:204D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +:204D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +:204D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:204D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:204DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:204DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:204DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:204E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:204E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:204E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:204E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:204E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:204EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:204EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:204EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:204F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:204F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:204F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:204F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:204F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:204FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +:204FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:204FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:20500000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:20502000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:20504000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:20506000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:20508000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:2050A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:2050C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:2050E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:20510000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +:20512000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +:20514000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +:20516000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +:20518000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +:2051A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +:2051C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +:2051E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +:20520000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +:20522000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +:20524000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:20526000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +:20528000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:2052A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +:2052C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +:2052E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +:20530000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:20532000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:20534000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:20536000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:20538000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:2053A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:2053C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:2053E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:20540000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +:20542000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:20544000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:20546000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +:20548000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +:2054A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +:2054C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +:2054E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +:20550000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +:20552000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +:20554000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +:20556000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +:20558000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +:2055A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +:2055C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +:2055E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +:20560000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +:20562000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +:20564000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +:20566000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +:20568000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +:2056A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +:2056C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +:2056E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +:20570000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +:20572000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +:20574000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +:20576000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +:20578000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +:2057A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +:2057C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +:2057E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +:20580000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:20582000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +:20584000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +:20586000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +:20588000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +:2058A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +:2058C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +:2058E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +:20590000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +:20592000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:20594000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:20596000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:20598000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:2059A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:2059C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:2059E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +:205A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +:205A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +:205A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +:205A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +:205A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +:205AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +:205AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +:205AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +:205B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +:205B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +:205B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +:205B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +:205B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:205BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:205BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:205BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:205C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +:205C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:205C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:205C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:205C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +:205CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +:205CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +:205CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +:205D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +:205D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +:205D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:205D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:205D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:205DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:205DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:205DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:205E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:205E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:205E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:205E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:205E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:205EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:205EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:205EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:205F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +:205F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:205F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:205F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:205F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:205FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:205FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:205FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:20600000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:20602000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:20604000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:20606000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:20608000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:2060A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:2060C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:2060E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:20610000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +:20612000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +:20614000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +:20616000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +:20618000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +:2061A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +:2061C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +:2061E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +:20620000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +:20622000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +:20624000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +:20626000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +:20628000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +:2062A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +:2062C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +:2062E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +:20630000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +:20632000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +:20634000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +:20636000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +:20638000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +:2063A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +:2063C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +:2063E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:20640000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:20642000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:20644000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +:20646000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +:20648000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +:2064A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +:2064C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +:2064E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +:20650000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +:20652000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +:20654000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +:20656000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +:20658000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +:2065A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +:2065C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +:2065E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +:20660000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +:20662000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +:20664000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +:20666000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +:20668000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +:2066A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +:2066C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +:2066E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +:20670000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +:20672000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +:20674000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +:20676000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +:20678000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +:2067A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +:2067C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +:2067E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +:20680000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +:20682000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +:20684000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +:20686000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +:20688000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +:2068A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +:2068C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +:2068E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +:20690000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:20692000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:20694000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:20696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:20698000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:2069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:2069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:2069E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +:206A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +:206A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +:206A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +:206A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +:206A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +:206AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +:206AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +:206AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +:206B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +:206B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +:206B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +:206B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +:206B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +:206BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +:206BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +:206BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:206C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:206C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:206C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:206C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:206C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +:206CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +:206CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +:206CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +:206D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +:206D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +:206D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:206D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:206D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:206DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:206DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:206DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +:206E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:206E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:206E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:206E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:206E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:206EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:206EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:206EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:206F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:206F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:206F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:206F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:206F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +:206FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:206FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:206FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:20700000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:20702000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:20704000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:20706000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:20708000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:2070A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:2070C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:2070E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:20710000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +:20712000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +:20714000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +:20716000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +:20718000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +:2071A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +:2071C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +:2071E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +:20720000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +:20722000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:20724000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +:20726000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:20728000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +:2072A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +:2072C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +:2072E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +:20730000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:20732000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:20734000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:20736000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:20738000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:2073A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:2073C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:2073E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:20740000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:20742000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:20744000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +:20746000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +:20748000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +:2074A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +:2074C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +:2074E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +:20750000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +:20752000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +:20754000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +:20756000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +:20758000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +:2075A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +:2075C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +:2075E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +:20760000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +:20762000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +:20764000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +:20766000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +:20768000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +:2076A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +:2076C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +:2076E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +:20770000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +:20772000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +:20774000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +:20776000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +:20778000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +:2077A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +:2077C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +:2077E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +:20780000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +:20782000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +:20784000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +:20786000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +:20788000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +:2078A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +:2078C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +:2078E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:20790000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:20792000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:20794000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:20796000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:20798000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:2079A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:2079C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +:2079E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +:207A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +:207A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +:207A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +:207A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +:207A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +:207AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +:207AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +:207AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +:207B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +:207B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +:207B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +:207B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:207B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:207BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:207BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:207BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +:207C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:207C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:207C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:207C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +:207C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +:207CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +:207CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +:207CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +:207D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +:207D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:207D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:207D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:207D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:207DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:207DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:207DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +:207E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:207E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:207E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:207E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:207E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:207EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:207EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:207EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:207F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:207F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:207F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:207F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:207F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:207FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:207FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:207FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +:20800000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:20802000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:20804000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:20806000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:20808000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:2080A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:2080C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:2080E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:20810000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +:20812000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +:20814000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +:20816000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +:20818000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +:2081A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +:2081C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +:2081E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +:20820000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +:20822000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +:20824000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +:20826000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +:20828000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +:2082A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +:2082C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +:2082E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +:20830000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +:20832000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +:20834000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +:20836000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +:20838000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +:2083A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +:2083C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:2083E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +:20840000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:20842000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +:20844000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +:20846000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +:20848000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +:2084A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +:2084C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +:2084E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:20850000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +:20852000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +:20854000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +:20856000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +:20858000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +:2085A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +:2085C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +:2085E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +:20860000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +:20862000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +:20864000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +:20866000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +:20868000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +:2086A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +:2086C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +:2086E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +:20870000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +:20872000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +:20874000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +:20876000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +:20878000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +:2087A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +:2087C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +:2087E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +:20880000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +:20882000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +:20884000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +:20886000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +:20888000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +:2088A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +:2088C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +:2088E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +:20890000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:20892000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:20894000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:20896000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:20898000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:2089A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:2089C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +:2089E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:208A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +:208A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +:208A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +:208A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +:208A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +:208AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +:208AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +:208AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +:208B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +:208B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +:208B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +:208B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +:208B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +:208BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +:208BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:208BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +:208C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:208C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:208C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:208C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +:208C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +:208CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +:208CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +:208CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:208D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +:208D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:208D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:208D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:208D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:208DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:208DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +:208DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +:208E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:208E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:208E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:208E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:208E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:208EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:208EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:208EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:208F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:208F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:208F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:208F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +:208F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:208FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:208FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:208FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:20900000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:20902000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:20904000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:20906000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:20908000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:2090A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:2090C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:2090E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:20910000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +:20912000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +:20914000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +:20916000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +:20918000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +:2091A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +:2091C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +:2091E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +:20920000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:20922000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +:20924000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:20926000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +:20928000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +:2092A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +:2092C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +:2092E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +:20930000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:20932000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:20934000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:20936000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:20938000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:2093A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:2093C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:2093E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:20940000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:20942000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +:20944000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +:20946000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +:20948000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +:2094A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +:2094C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +:2094E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:20950000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +:20952000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +:20954000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +:20956000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +:20958000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +:2095A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +:2095C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +:2095E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +:20960000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +:20962000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +:20964000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +:20966000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +:20968000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +:2096A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +:2096C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +:2096E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +:20970000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +:20972000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +:20974000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +:20976000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +:20978000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +:2097A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +:2097C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +:2097E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +:20980000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +:20982000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +:20984000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +:20986000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +:20988000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +:2098A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +:2098C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:2098E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +:20990000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:20992000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:20994000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:20996000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:20998000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:2099A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +:2099C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +:2099E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:209A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +:209A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +:209A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +:209A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +:209A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +:209AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +:209AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +:209AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +:209B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +:209B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +:209B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:209B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:209B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:209BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:209BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +:209BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +:209C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:209C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:209C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +:209C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +:209C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +:209CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +:209CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +:209CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:209D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:209D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:209D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:209D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:209D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:209DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:209DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +:209DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +:209E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:209E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:209E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:209E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:209E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:209EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:209EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:209EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:209F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:209F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:209F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:209F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:209F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:209FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:209FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +:209FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:20A00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:20A02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:20A04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:20A06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:20A08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:20A0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:20A0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:20A0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:20A10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +:20A12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +:20A14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +:20A16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +:20A18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +:20A1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +:20A1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +:20A1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +:20A20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +:20A22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +:20A24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +:20A26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +:20A28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +:20A2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +:20A2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +:20A2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +:20A30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +:20A32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +:20A34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +:20A36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +:20A38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +:20A3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:20A3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +:20A3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +:20A40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +:20A42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +:20A44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +:20A46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +:20A48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +:20A4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +:20A4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:20A4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:20A50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +:20A52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +:20A54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +:20A56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +:20A58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +:20A5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +:20A5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +:20A5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +:20A60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +:20A62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +:20A64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +:20A66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +:20A68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +:20A6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +:20A6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +:20A6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +:20A70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +:20A72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +:20A74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +:20A76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +:20A78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +:20A7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +:20A7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +:20A7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +:20A80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +:20A82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +:20A84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +:20A86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +:20A88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +:20A8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +:20A8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +:20A8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +:20A90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:20A92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:20A94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:20A96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:20A98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:20A9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +:20A9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:20A9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:20AA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +:20AA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +:20AA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +:20AA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +:20AA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +:20AAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +:20AAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +:20AAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +:20AB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +:20AB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +:20AB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +:20AB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +:20AB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +:20ABA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:20ABC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +:20ABE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +:20AC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:20AC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:20AC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +:20AC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +:20AC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +:20ACA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +:20ACC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:20ACE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:20AD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:20AD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:20AD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:20AD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:20AD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:20ADA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +:20ADC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +:20ADE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +:20AE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:20AE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:20AE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:20AE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:20AE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:20AEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:20AEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:20AEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:20AF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:20AF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:20AF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +:20AF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:20AF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:20AFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:20AFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:20AFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:20B00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:20B02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:20B04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:20B06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:20B08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:20B0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:20B0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:20B0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:20B10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +:20B12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +:20B14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +:20B16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +:20B18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +:20B1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +:20B1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +:20B1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +:20B20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +:20B22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:20B24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +:20B26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +:20B28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +:20B2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +:20B2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +:20B2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:20B30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:20B32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:20B34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:20B36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:20B38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:20B3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:20B3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:20B3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:20B40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +:20B42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +:20B44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +:20B46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +:20B48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +:20B4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +:20B4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:20B4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:20B50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +:20B52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +:20B54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +:20B56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +:20B58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +:20B5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +:20B5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +:20B5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +:20B60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +:20B62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +:20B64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +:20B66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +:20B68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +:20B6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +:20B6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +:20B6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +:20B70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +:20B72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +:20B74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +:20B76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +:20B78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +:20B7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +:20B7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +:20B7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +:20B80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +:20B82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +:20B84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +:20B86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +:20B88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +:20B8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:20B8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +:20B8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +:20B90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:20B92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:20B94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:20B96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:20B98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +:20B9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +:20B9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:20B9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:20BA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +:20BA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +:20BA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +:20BA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +:20BA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +:20BAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +:20BAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +:20BAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +:20BB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +:20BB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:20BB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:20BB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:20BB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:20BBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +:20BBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +:20BBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +:20BC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:20BC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +:20BC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +:20BC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +:20BC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +:20BCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +:20BCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:20BCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:20BD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:20BD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:20BD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:20BD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:20BD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:20BDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +:20BDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +:20BDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:20BE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:20BE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:20BE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:20BE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:20BE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:20BEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:20BEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:20BEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:20BF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:20BF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:20BF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:20BF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:20BF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:20BFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +:20BFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:20BFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:20C00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:20C02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:20C04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:20C06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:20C08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:20C0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:20C0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:20C0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:20C10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +:20C12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +:20C14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +:20C16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +:20C18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +:20C1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +:20C1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +:20C1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +:20C20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +:20C22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +:20C24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +:20C26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +:20C28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +:20C2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +:20C2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +:20C2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +:20C30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +:20C32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +:20C34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +:20C36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +:20C38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:20C3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +:20C3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +:20C3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +:20C40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +:20C42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +:20C44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +:20C46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +:20C48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +:20C4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:20C4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:20C4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +:20C50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +:20C52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +:20C54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +:20C56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +:20C58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +:20C5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +:20C5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +:20C5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +:20C60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +:20C62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +:20C64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +:20C66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +:20C68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +:20C6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +:20C6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +:20C6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +:20C70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +:20C72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +:20C74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +:20C76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +:20C78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +:20C7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +:20C7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +:20C7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +:20C80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +:20C82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +:20C84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +:20C86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +:20C88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +:20C8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +:20C8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +:20C8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +:20C90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:20C92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:20C94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:20C96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:20C98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +:20C9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:20C9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:20C9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:20CA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +:20CA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +:20CA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +:20CA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +:20CA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +:20CAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +:20CAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +:20CAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +:20CB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +:20CB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +:20CB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +:20CB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +:20CB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:20CBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +:20CBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +:20CBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +:20CC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:20CC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +:20CC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +:20CC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +:20CC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +:20CCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:20CCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:20CCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:20CD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:20CD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:20CD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:20CD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:20CD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +:20CDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +:20CDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +:20CDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:20CE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:20CE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:20CE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:20CE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:20CE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:20CEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:20CEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:20CEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:20CF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:20CF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +:20CF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:20CF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:20CF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:20CFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:20CFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:20CFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:20D00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:20D02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:20D04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:20D06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:20D08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:20D0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:20D0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:20D0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:20D10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +:20D12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +:20D14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +:20D16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +:20D18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +:20D1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +:20D1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +:20D1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +:20D20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:20D22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +:20D24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +:20D26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +:20D28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +:20D2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +:20D2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:20D2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +:20D30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:20D32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:20D34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:20D36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:20D38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:20D3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:20D3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:20D3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:20D40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +:20D42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +:20D44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +:20D46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +:20D48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +:20D4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:20D4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:20D4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +:20D50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +:20D52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +:20D54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +:20D56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +:20D58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +:20D5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +:20D5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +:20D5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +:20D60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +:20D62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +:20D64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +:20D66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +:20D68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +:20D6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +:20D6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +:20D6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +:20D70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +:20D72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +:20D74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +:20D76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +:20D78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +:20D7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +:20D7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +:20D7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +:20D80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +:20D82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +:20D84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +:20D86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +:20D88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:20D8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +:20D8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +:20D8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +:20D90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:20D92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:20D94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:20D96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +:20D98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +:20D9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:20D9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:20D9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:20DA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +:20DA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +:20DA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +:20DA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +:20DA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +:20DAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +:20DAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +:20DAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +:20DB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:20DB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:20DB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:20DB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:20DB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +:20DBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +:20DBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +:20DBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +:20DC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +:20DC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +:20DC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +:20DC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +:20DC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +:20DCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:20DCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:20DCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:20DD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:20DD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:20DD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:20DD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:20DD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +:20DDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +:20DDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:20DDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:20DE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:20DE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:20DE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:20DE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:20DE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:20DEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:20DEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:20DEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:20DF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:20DF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:20DF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:20DF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:20DF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +:20DFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:20DFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:20DFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:20E00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:20E02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:20E04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:20E06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:20E08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:20E0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:20E0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:20E0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:20E10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +:20E12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +:20E14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +:20E16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +:20E18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +:20E1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +:20E1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +:20E1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +:20E20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +:20E22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +:20E24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +:20E26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +:20E28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +:20E2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +:20E2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +:20E2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +:20E30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +:20E32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +:20E34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +:20E36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:20E38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +:20E3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +:20E3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +:20E3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +:20E40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +:20E42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +:20E44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +:20E46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +:20E48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:20E4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:20E4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +:20E4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +:20E50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +:20E52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +:20E54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +:20E56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +:20E58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +:20E5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +:20E5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +:20E5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +:20E60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +:20E62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +:20E64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +:20E66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +:20E68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +:20E6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +:20E6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +:20E6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +:20E70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +:20E72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +:20E74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +:20E76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +:20E78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +:20E7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +:20E7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +:20E7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +:20E80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +:20E82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +:20E84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +:20E86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +:20E88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +:20E8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +:20E8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +:20E8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +:20E90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:20E92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:20E94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:20E96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +:20E98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:20E9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:20E9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:20E9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:20EA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +:20EA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +:20EA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +:20EA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +:20EA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +:20EAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +:20EAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +:20EAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +:20EB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +:20EB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +:20EB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +:20EB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:20EB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +:20EBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +:20EBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +:20EBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +:20EC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +:20EC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +:20EC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +:20EC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +:20EC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:20ECA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:20ECC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:20ECE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:20ED0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:20ED2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:20ED4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:20ED6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +:20ED8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +:20EDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +:20EDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:20EDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:20EE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:20EE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:20EE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:20EE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:20EE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:20EEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:20EEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:20EEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:20EF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +:20EF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:20EF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:20EF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:20EF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:20EFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:20EFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:20EFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:20F00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:20F02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:20F04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:20F06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:20F08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:20F0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:20F0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:20F0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:20F10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +:20F12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +:20F14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +:20F16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +:20F18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +:20F1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +:20F1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +:20F1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +:20F20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +:20F22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +:20F24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +:20F26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +:20F28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +:20F2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:20F2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +:20F2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:20F30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:20F32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:20F34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:20F36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:20F38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:20F3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:20F3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:20F3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:20F40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +:20F42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +:20F44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +:20F46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +:20F48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:20F4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:20F4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +:20F4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +:20F50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +:20F52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +:20F54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +:20F56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +:20F58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +:20F5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +:20F5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +:20F5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +:20F60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +:20F62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +:20F64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +:20F66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +:20F68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +:20F6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +:20F6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +:20F6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +:20F70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +:20F72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +:20F74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +:20F76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +:20F78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +:20F7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +:20F7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +:20F7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +:20F80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +:20F82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +:20F84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +:20F86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:20F88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +:20F8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +:20F8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +:20F8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +:20F90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:20F92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:20F94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +:20F96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +:20F98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:20F9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:20F9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:20F9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:20FA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +:20FA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +:20FA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +:20FA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +:20FA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +:20FAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +:20FAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +:20FAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +:20FB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:20FB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:20FB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:20FB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +:20FB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +:20FBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +:20FBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +:20FBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:20FC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +:20FC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +:20FC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +:20FC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +:20FC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:20FCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:20FCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:20FCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +:20FD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:20FD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:20FD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:20FD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +:20FD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +:20FDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:20FDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:20FDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:20FE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:20FE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:20FE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:20FE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:20FE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:20FEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:20FEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:20FEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:20FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:20FF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:20FF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:20FF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +:20FF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:20FFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:20FFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:20FFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:020000023000CC +:20000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:20002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:20004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:20006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:20008000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:2000A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:2000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:2000E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:20010000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +:20012000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +:20014000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +:20016000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +:20018000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +:2001A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +:2001C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +:2001E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +:20020000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +:20022000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +:20024000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +:20026000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +:20028000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +:2002A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +:2002C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +:2002E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +:20030000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +:20032000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +:20034000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:20036000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +:20038000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +:2003A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +:2003C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +:2003E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +:20040000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +:20042000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +:20044000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +:20046000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:20048000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:2004A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +:2004C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +:2004E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +:20050000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +:20052000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +:20054000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +:20056000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +:20058000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +:2005A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +:2005C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +:2005E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +:20060000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +:20062000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +:20064000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +:20066000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +:20068000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +:2006A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +:2006C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +:2006E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +:20070000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +:20072000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +:20074000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +:20076000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +:20078000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +:2007A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +:2007C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +:2007E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +:20080000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +:20082000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +:20084000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +:20086000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +:20088000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +:2008A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +:2008C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +:2008E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +:20090000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:20092000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:20094000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +:20096000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:20098000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:2009A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:2009C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:2009E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:200A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +:200A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +:200A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +:200A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +:200A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +:200AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +:200AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +:200AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +:200B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +:200B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +:200B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:200B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +:200B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +:200BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +:200BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +:200BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +:200C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +:200C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +:200C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +:200C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:200C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:200CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:200CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:200CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +:200D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:200D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:200D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +:200D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +:200D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +:200DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:200DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:200DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:200E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:200E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:200E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:200E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:200E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:200EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:200EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:200EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:200F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:200F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:200F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:200F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:200F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:200FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:200FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:200FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +:20100000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:20102000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:20104000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:20106000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:20108000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:2010A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:2010C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:2010E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:20110000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +:20112000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +:20114000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +:20116000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +:20118000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +:2011A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +:2011C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +:2011E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +:20120000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +:20122000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +:20124000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +:20126000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +:20128000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:2012A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +:2012C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:2012E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +:20130000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:20132000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:20134000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:20136000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:20138000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:2013A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:2013C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:2013E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:20140000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +:20142000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +:20144000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +:20146000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:20148000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:2014A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +:2014C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +:2014E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +:20150000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +:20152000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +:20154000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +:20156000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +:20158000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +:2015A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +:2015C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +:2015E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +:20160000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +:20162000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +:20164000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +:20166000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +:20168000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +:2016A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +:2016C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +:2016E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +:20170000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +:20172000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +:20174000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +:20176000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +:20178000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +:2017A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +:2017C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +:2017E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +:20180000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +:20182000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +:20184000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:20186000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +:20188000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +:2018A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +:2018C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +:2018E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +:20190000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:20192000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +:20194000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +:20196000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:20198000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:2019A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:2019C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:2019E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:201A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +:201A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +:201A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +:201A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +:201A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +:201AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +:201AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +:201AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +:201B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:201B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:201B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +:201B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +:201B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +:201BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +:201BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:201BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:201C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +:201C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +:201C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +:201C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:201C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:201CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:201CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +:201CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +:201D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:201D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:201D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +:201D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +:201D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:201DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:201DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:201DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:201E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:201E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:201E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:201E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:201E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:201EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:201EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:201EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:201F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:201F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:201F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +:201F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:201F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:201FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:201FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:201FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:20200000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:20202000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:20204000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:20206000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:20208000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:2020A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:2020C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:2020E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:20210000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +:20212000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +:20214000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +:20216000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +:20218000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +:2021A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +:2021C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +:2021E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +:20220000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +:20222000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +:20224000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +:20226000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +:20228000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +:2022A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +:2022C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +:2022E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +:20230000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +:20232000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:20234000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +:20236000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +:20238000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +:2023A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +:2023C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +:2023E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +:20240000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +:20242000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +:20244000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:20246000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:20248000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +:2024A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +:2024C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +:2024E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +:20250000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +:20252000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +:20254000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +:20256000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +:20258000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +:2025A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +:2025C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +:2025E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +:20260000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +:20262000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +:20264000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +:20266000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +:20268000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +:2026A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +:2026C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +:2026E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +:20270000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +:20272000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +:20274000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +:20276000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +:20278000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +:2027A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +:2027C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +:2027E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +:20280000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +:20282000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +:20284000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +:20286000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +:20288000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +:2028A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +:2028C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +:2028E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +:20290000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:20292000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +:20294000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:20296000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:20298000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:2029A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:2029C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:2029E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:202A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +:202A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +:202A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +:202A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +:202A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +:202AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +:202AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +:202AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +:202B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +:202B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:202B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +:202B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +:202B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +:202BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +:202BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +:202BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +:202C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +:202C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +:202C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:202C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:202C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:202CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:202CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +:202CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +:202D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:202D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +:202D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +:202D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +:202D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:202DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:202DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:202DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:202E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:202E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:202E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:202E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:202E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:202EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:202EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:202EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:202F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:202F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:202F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:202F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:202F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:202FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:202FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +:202FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:20300000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:20302000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:20304000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:20306000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:20308000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:2030A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:2030C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:2030E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:20310000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +:20312000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +:20314000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +:20316000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +:20318000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +:2031A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +:2031C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +:2031E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +:20320000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +:20322000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +:20324000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +:20326000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:20328000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +:2032A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:2032C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +:2032E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +:20330000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:20332000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:20334000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:20336000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:20338000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:2033A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:2033C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:2033E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:20340000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +:20342000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +:20344000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:20346000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:20348000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +:2034A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +:2034C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +:2034E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +:20350000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +:20352000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +:20354000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +:20356000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +:20358000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +:2035A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +:2035C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +:2035E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +:20360000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +:20362000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +:20364000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +:20366000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +:20368000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +:2036A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +:2036C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +:2036E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +:20370000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +:20372000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +:20374000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +:20376000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +:20378000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +:2037A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +:2037C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +:2037E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +:20380000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +:20382000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:20384000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +:20386000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +:20388000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +:2038A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +:2038C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +:2038E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +:20390000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +:20392000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +:20394000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:20396000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:20398000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:2039A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:2039C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:2039E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:203A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +:203A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +:203A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +:203A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +:203A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +:203AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +:203AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +:203AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +:203B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:203B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +:203B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +:203B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +:203B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +:203BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:203BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:203BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:203C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +:203C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +:203C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:203C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:203C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:203CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +:203CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +:203CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +:203D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:203D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +:203D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +:203D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:203D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:203DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:203DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:203DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:203E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:203E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:203E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:203E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:203E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:203EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:203EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:203EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:203F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:203F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +:203F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:203F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:203F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:203FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:203FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:203FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:20400000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:20402000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:20404000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:20406000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:20408000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:2040A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:2040C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:2040E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:20410000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +:20412000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +:20414000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +:20416000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +:20418000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +:2041A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +:2041C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +:2041E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +:20420000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +:20422000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +:20424000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +:20426000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +:20428000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +:2042A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +:2042C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +:2042E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +:20430000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:20432000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +:20434000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +:20436000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +:20438000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +:2043A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +:2043C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +:2043E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +:20440000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +:20442000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:20444000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:20446000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +:20448000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +:2044A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +:2044C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +:2044E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +:20450000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +:20452000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +:20454000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +:20456000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +:20458000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +:2045A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +:2045C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +:2045E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +:20460000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +:20462000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +:20464000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +:20466000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +:20468000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +:2046A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +:2046C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +:2046E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +:20470000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +:20472000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +:20474000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +:20476000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +:20478000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +:2047A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +:2047C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +:2047E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +:20480000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +:20482000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +:20484000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +:20486000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +:20488000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +:2048A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +:2048C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +:2048E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +:20490000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +:20492000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:20494000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:20496000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:20498000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:2049A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:2049C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:2049E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:204A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +:204A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +:204A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +:204A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +:204A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +:204AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +:204AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +:204AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +:204B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:204B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +:204B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +:204B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +:204B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +:204BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +:204BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +:204BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +:204C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +:204C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:204C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:204C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:204C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:204CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +:204CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +:204CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +:204D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +:204D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +:204D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +:204D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:204D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:204DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:204DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:204DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:204E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:204E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:204E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:204E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:204E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:204EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:204EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:204EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:204F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:204F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:204F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:204F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:204F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:204FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +:204FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:204FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:20500000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:20502000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:20504000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:20506000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:20508000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:2050A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:2050C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:2050E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:20510000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +:20512000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +:20514000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +:20516000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +:20518000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +:2051A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +:2051C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +:2051E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +:20520000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +:20522000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +:20524000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:20526000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +:20528000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:2052A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +:2052C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +:2052E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +:20530000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:20532000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:20534000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:20536000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:20538000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:2053A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:2053C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:2053E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:20540000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +:20542000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:20544000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:20546000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +:20548000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +:2054A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +:2054C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +:2054E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +:20550000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +:20552000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +:20554000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +:20556000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +:20558000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +:2055A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +:2055C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +:2055E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +:20560000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +:20562000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +:20564000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +:20566000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +:20568000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +:2056A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +:2056C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +:2056E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +:20570000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +:20572000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +:20574000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +:20576000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +:20578000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +:2057A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +:2057C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +:2057E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +:20580000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:20582000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +:20584000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +:20586000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +:20588000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +:2058A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +:2058C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +:2058E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +:20590000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +:20592000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:20594000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:20596000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:20598000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:2059A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:2059C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:2059E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +:205A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +:205A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +:205A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +:205A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +:205A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +:205AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +:205AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +:205AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +:205B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +:205B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +:205B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +:205B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +:205B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:205BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:205BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:205BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:205C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +:205C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:205C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:205C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:205C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +:205CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +:205CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +:205CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +:205D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +:205D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +:205D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:205D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:205D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:205DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:205DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:205DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:205E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:205E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:205E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:205E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:205E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:205EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:205EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:205EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:205F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +:205F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:205F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:205F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:205F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:205FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:205FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:205FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:20600000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:20602000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:20604000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:20606000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:20608000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:2060A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:2060C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:2060E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:20610000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +:20612000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +:20614000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +:20616000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +:20618000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +:2061A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +:2061C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +:2061E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +:20620000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +:20622000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +:20624000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +:20626000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +:20628000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +:2062A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +:2062C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +:2062E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +:20630000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +:20632000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +:20634000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +:20636000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +:20638000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +:2063A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +:2063C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +:2063E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:20640000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:20642000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:20644000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +:20646000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +:20648000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +:2064A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +:2064C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +:2064E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +:20650000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +:20652000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +:20654000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +:20656000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +:20658000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +:2065A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +:2065C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +:2065E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +:20660000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +:20662000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +:20664000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +:20666000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +:20668000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +:2066A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +:2066C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +:2066E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +:20670000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +:20672000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +:20674000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +:20676000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +:20678000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +:2067A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +:2067C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +:2067E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +:20680000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +:20682000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +:20684000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +:20686000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +:20688000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +:2068A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +:2068C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +:2068E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +:20690000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:20692000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:20694000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:20696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:20698000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:2069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:2069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:2069E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +:206A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +:206A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +:206A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +:206A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +:206A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +:206AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +:206AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +:206AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +:206B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +:206B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +:206B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +:206B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +:206B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +:206BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +:206BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +:206BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:206C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:206C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:206C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:206C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:206C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +:206CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +:206CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +:206CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +:206D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +:206D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +:206D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:206D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:206D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:206DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:206DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:206DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +:206E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:206E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:206E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:206E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:206E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:206EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:206EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:206EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:206F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:206F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:206F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:206F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:206F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +:206FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:206FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:206FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:20700000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:20702000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:20704000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:20706000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:20708000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:2070A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:2070C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:2070E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:20710000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +:20712000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +:20714000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +:20716000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +:20718000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +:2071A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +:2071C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +:2071E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +:20720000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +:20722000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:20724000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +:20726000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:20728000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +:2072A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +:2072C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +:2072E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +:20730000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:20732000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:20734000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:20736000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:20738000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:2073A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:2073C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:2073E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:20740000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:20742000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:20744000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +:20746000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +:20748000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +:2074A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +:2074C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +:2074E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +:20750000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +:20752000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +:20754000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +:20756000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +:20758000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +:2075A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +:2075C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +:2075E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +:20760000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +:20762000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +:20764000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +:20766000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +:20768000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +:2076A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +:2076C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +:2076E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +:20770000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +:20772000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +:20774000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +:20776000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +:20778000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +:2077A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +:2077C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +:2077E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +:20780000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +:20782000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +:20784000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +:20786000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +:20788000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +:2078A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +:2078C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +:2078E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:20790000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:20792000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:20794000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:20796000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:20798000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:2079A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:2079C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +:2079E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +:207A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +:207A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +:207A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +:207A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +:207A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +:207AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +:207AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +:207AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +:207B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +:207B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +:207B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +:207B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:207B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:207BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:207BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:207BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +:207C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:207C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:207C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:207C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +:207C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +:207CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +:207CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +:207CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +:207D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +:207D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:207D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:207D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:207D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:207DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:207DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:207DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +:207E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:207E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:207E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:207E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:207E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:207EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:207EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:207EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:207F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:207F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:207F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:207F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:207F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:207FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:207FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:207FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D631B3D75 +:00000001FF diff --git a/cva_asw_m0118/bat_complier_object/cva_asw_m0118_iar.s19 b/cva_asw_m0118/bat_complier_object/cva_asw_m0118_iar.s19 new file mode 100644 index 0000000..c3236f2 --- /dev/null +++ b/cva_asw_m0118/bat_complier_object/cva_asw_m0118_iar.s19 @@ -0,0 +1,5121 @@ +S224010000F05F00200D980100332D01002B42010000000000000000000000000000000000F6 +S2240100200000000000000000000000007B4201000000000000000000674301000D560100ED +S224010040D09A0100D09A0100D09A0100D09A0100D09A0100D09A0100D09A0100D09A010042 +S224010060D09A01002F560100D09A0100D09A0100D09A0100D09A0100D09A0100D09A010007 +S224010080D09A0100D09A0100D09A0100D09A0100D09A0100D09A0100D09A0100D09A010002 +S2240100A0F7710100D09A0100D09A0100D09A0100D09A0100D09A0100D09A0100D09A0100E4 +S2240100C0DDCCBBAA31333A33353A33320000000044656320313220323032340000000000F0 +S2240100E05357303130315F32303234313231310000000000000000000000000000000000A2 +S22401010000B583680122DB681340DBB2002B0AD083681B6A9B081A40D2B2002A03D0C069D7 +S2240101200860012000E0002000BD70B500231C008568EE68012296430122E4B2144034434C +S224010140EC600978002943D0C169224CA14201D11D0012E0C169BA4CA14201D215000CE04D +S224010160C169B84CA14201D2022506E0C169B64CA14201D2032500E004252900C9B20429A4 +S22401018001D1002025E08168CC680C26B443EDB2AE000C2535402543CD608168CC68102542 +S2240101A0AC43DBB21B0110252B402343CB6011008368DC680125AC43C9B211402143D960B2 +S2240101C08168096A8B0811001940C9B20029F7D0012070BD00093D0000B58268126A53084B +S2240101E01A00D207D20FD2B2002A03D080690860012000E0002000BD7CB504000D00002013 +S224010200A16801264A6931001140C9B200295BD0A1680A6A31001140C9B2002954D0A168D4 +S22401022089690A0931001140C9B2002902D0012905D009E069462000FFF762FF04E069461A +S2240102402000FFF7C9FFFFE7C0B2002801D100203BE03100A0684069000A8007800FC0B2B9 +S224010260002805D0022807D004D3032806D007E0310005E0022103E0042101E00821FFE78A +S224010280A0684069400843065B0EDBB2002B01D18023FFE7A0684069C00A4207520FD2B2F1 +S2240102A0002A01D10822FFE7A0684069800A34000440E4B2641C00985843604351434900B0 +S2240102C002F0DFFC28603000C0B276BDF1B500242000009A9268556901239D430123C0B218 +S2240102E018402843506118004A78002A02D0012A0DD019E02600009A9568AA691027BA43A9 +S224010300F6B2360110273E401643AE610DE01E00009A9568AA691027BA43F6B236011027DC +S2240103203E401643AE6100E020000200D2B2002A01D1002081E0CA68012A01D126000FE08A +S224010340CA68022A01D11E000AE0CA68042A01D1022605E0CA68082A01D1032600E0FF26BC +S2240103603200D2B2FF2A01D1002066E0009A92685769BD4D3D40F6B23702C026B6003E408A +S2240103802E4356614A88002A18D04A88812A15DA4A88802A01D1220000E04A88009DAD680B +S2240103A06E69FE27BE43D2B25700FE223A4032436A610A69002A03D100203EE000203CE09A +S2240103C00A69092AF8D20A69082A00D00C69009A92685669A54D3540E4B2E602E024A401DC +S2240103E034402C4354618A68012A02D08A68022A24D18D686D1E009A926856699C4C34402E +S224010400EDB2AD028026F6003540254355610978002911D01900009A926854690125AC434F +S224010420C9B2194021435161009989680A6A19001140C9B20029F7D0C0B2F2BD0020FCE7D5 +S22401044001127A0001366E01015A6202F8B504000E0000270020009060690125C0690109EC +S22401046028000840C0B2002817D069462000FFF747FE07003800C0B200280ED06069C069D2 +S224010480000A4007400F85402900412904D2009802F0F7FB306000E000273800C0B2F2BD1C +S2240104A0FCB500226B461A7016004569EF691023DB431F401024F6B2360126403E43EE6113 +S2240104C08D88012D01D115001EE08D88022D01D1012519E08D88042D01D1022514E08D8871 +S2240104E0082D01D103250FE08D88102D01D104250AE08D88202D01D1052505E08D88402DDC +S22401050001D1062500E007252E00F6B2072E14D06E4635704569EF699A4E3E400196019FE1 +S224010520BC466E4636783702E026F6003E4067463E43EE6101256E4635700978002901D027 +S2240105400122FFE74069C1690B40D2B211010C401C43C46168460078F6BDF8B504000E0070 +S224010560002700200090606901258069010928000840C0B2002817D069462000FFF7C0FD49 +S22401058007003800C0B200280ED060698069000A4007400F85402900412904D2009802F094 +S2240105A070FB306000E000273800C0B2F2BDFCB500226B461A7016004569AF691023DB439F +S2240105C01F401024F6B2360126403E43AE618D88012D01D115001EE08D88022D01D1012549 +S2240105E019E08D88042D01D1022514E08D88082D01D103250FE08D88102D01D104250AE05F +S2240106008D88202D01D1052505E08D88402D01D1062500E007252E00F6B2072E14D06E4663 +S22401062035704569AF69574E3E400196019FBC466E4636783702E026F6003E4067463E43AA +S224010640AE6101256E4635700978002901D00122FFE7406981690B40D2B211010C401C4363 +S224010660846168460078F6BDFFFCFFFFFFC7FFFFFFFBFFFFF8B504000E000027002000906B +S224010680606901254069010928000840C0B2002817D069462000FFF79FFD07003800C0B2AF +S2240106A000280ED060694069000A4007400F85402900412904D2009802F0E3FA306000E017 +S2240106C000273800C0B2F2BDFCB500226B461A70160045696F691023DB431F401024F6B25E +S2240106E0360126403E436E618D88012D01D115001EE08D88022D01D1012519E08D88042D64 +S22401070001D1022514E08D88082D01D103250FE08D88102D01D104250AE08D88202D01D148 +S224010720052505E08D88402D01D1062500E007252E00F6B2072E14D06E46357045696F694B +S224010740104E3E400196019FBC466E4636783702E026F6003E4067463E436E6101256E4692 +S22401076035700978002901D00122FFE7406941690B40D2B211010C401C43446168460078A0 +S224010780F6BD0000FFF8FFFFF8B504000E0000270020009060690125006901092800084043 +S2240107A0C0B2002817D069462000FFF715FD07003800C0B200280ED060690069000A4007A1 +S2240107C0400F85402900412904D2009802F059FA306000E000273800C0B2F2BDFCB50022F6 +S2240107E06B461A70160045692F691023DB431F401024F6B2360126403E432E618D88012DE0 +S22401080001D115001EE08D88022D01D1012519E08D88042D01D1022514E08D88082D01D169 +S22401082003250FE08D88102D01D104250AE08D88202D01D1052505E08D88402D01D10625A2 +S22401084000E007252E00F6B2072E14D06E46357045692F69974E3E400196019FBC466E46A8 +S22401086036783702E026F6003E4067463E432E6101256E4635700978002901D00122FFE751 +S224010880406901690B40D2B211010C401C43046168460078F6BDF8B504000E00002700206F +S2240108A0009060690125406A010928000840C0B2002817D069462000FFF79EFC0700380070 +S2240108C0C0B200280ED06069406A000A4007400F85402900412904D2009802F0D2F9306074 +S2240108E000E000273800C0B2F2BDFCB500226B461A70160045696F6A1023DB431F40102403 +S224010900F6B2360126403E436E628D88012D01D115001EE08D88022D01D1012519E08D88C9 +S224010920042D01D1022514E08D88082D01D103250FE08D88102D01D104250AE08D88202DC7 +S22401094001D1052505E08D88402D01D1062500E007252E00F6B2072E14D06E46357045692F +S2240109606F6A544E3E400196019FBC466E4636783702E026F6003E4067463E436E62012506 +S2240109806E4635700978002901D00122FFE74069416A0B40D2B211010C401C434462684640 +S2240109A00078F6BDF8B504000E0000270020009060690125006A010928000840C0B2002803 +S2240109C017D069462000FFF717FC07003800C0B200280ED06069006A000A4007400F854003 +S2240109E02900412904D2009802F04BF9306000E000273800C0B2F2BDFCB500226B461A70BC +S224010A00160045692F6A1023DB431F401024F6B2360126403E432E628D88012D01D115000F +S224010A201EE08D88022D01D1012519E08D88042D01D1022514E08D88082D01D103250FE017 +S224010A408D88102D01D104250AE08D88202D01D1052505E08D88402D01D1062500E007258B +S224010A602E00F6B2072E14D06E46357045692F6A104E3E400196019FBC466E463678370231 +S224010A80E026F6003E4067463E432E6201256E4635700978002901D00122FFE74069016A01 +S224010AA00B40D2B211010C401C43046268460078F6BD0000FFF8FFFF80B50A000021436964 +S224010AC01B681B0E9B079B0FDBB2002B05D0022B0DD007D3032B0FD013E01100FFF77CFB29 +S224010AE001000EE01100FFF70BFB010009E01100FFF782FB010004E01100FFF76DFB010031 +S224010B00FFE70800C0B202BD30B54A78012A01D100210AE04A78002A01D1012105E049787B +S224010B20022901D1022100E0FF210A00D2B2FF2A01D1002016E00A0043691C688B4D254079 +S224010B40D2B21404C022920222402A431A6042691268120E9207920F0B00D2B2DBB29A42BD +S224010B60F5D1012030BD7CB504000D00002069462000FFF7A1FF06003000C0B2002801D132 +S224010B8000200BE0E06800680107090F0098C9B2491C02F076F828603000C0B276BD00B58A +S224010BA08A88002A0FD08A88112A0CDA8988491EC06802680F239A43C9B20907090F1143D1 +S224010BC00160012000E0002000BD7CB504000D00002069462000FFF7C6FF06003000C0B23C +S224010BE0002801D100200CE060690068000A0107090F0098C9B2491C02F043F82860300031 +S224010C00C0B276BD00B58A88002A11D08A88112A0EDA8988491E40690268554B1340C9B229 +S224010C200A02F0210901114019430160012000E0002000BDF8B504000D00002637002069F7 +S224010C40C8214058000C8007800FC0B2002805D002280FD008D3032812D017E069462000C5 +S224010C60FFF7BAFA070011E069462000FFF748FA07000BE069462000FFF7BEFA070005E06A +S224010C8069462000FFF7A8FA0700FFE73800C0B2002801D1002019E02069C8214058010929 +S224010CA00800C007C00FC0B200280CD02069C8214058000A0107090F0098C9B2491C01F07D +S224010CC0E0FF286000E037003800C0B2F2BD30B54A78012A01D100220AE04A78002A01D1C9 +S224010CE0012205E04A78022A01D1022200E0FF221300DBB2FF2B01D1002036E08B88002BF1 +S224010D0032D08B88112B2FDA0369C8241C59174D2540D2B21404C022920222402A43C82410 +S224010D201A518B885B1E0269C8241459104D2540DBB21C02F0231B0123402B43C824135135 +S224010D400978002901D0012100E000210069C822825810239A43C9B209011023194011434D +S224010D60C8228150012000E0002030BDFFFFFCFFFFF0FFFFF8B504000D0060694068010985 +S224010D800800C007C00FC0B2002801D100209BE0002007000090606907264068000C3040D7 +S224010DA0C0B2002843D160694068C00C3040C0B200280BD0022815D00ED304281ED017D369 +S224010DC0062827D020D307282AD02FE069462000FFF730FF070066E069462000FFF790F92E +S224010DE0070060E069462000FFF7F6F907005AE069462000FFF700FA070054E069462000E8 +S224010E00FFF7B1FE07004EE069462000FFF7DDFE070048E069462000FFF718FB070042E022 +S224010E2069462000FFF726FC07003CE03BE060694068000C3040C0B201280AD033D30328F4 +S224010E4013D00CD305281CD015D3072825D01ED329E069462000FFF71EFD070023E0694612 +S224010E60200000F0EFF907001DE06946200000F0C5F9070017E06946200000F09BF907009B +S224010E8011E06946200000F0ABFC07000BE069462000FFF7A1F9070005E069462000FFF7F3 +S224010EA09BF90700FFE73800C0B201280AD160694068000A064031000098C9B2491C01F0A2 +S224010EC0E0FE28603800C0B2F2BDF2B5012319000024260045696A681027BA43F6B236018C +S224010EE010273E4016436E60009A5278002A39D0012A50D0022A67D0032A00D1AFE0052A0F +S224010F0000D1C5E0072A00D1DBE00A2A75D00B2A00D18BE00C2A0CD00F2A00D1F8E0102A80 +S224010F2000D1E8E0112A00D1D8E01A2A00D1FCE008E12600426957689A4D3D40F6B237049D +S224010F40E026F6023E402E435660260042695768954D3D40F6B2F704E026B6033E402E43A8 +S224010F605660F0E02600426957688E4D3D40F6B23704E026F6023E402E4356601E004269AE +S224010F805768894D3D40F6B2F704E026B6033E402E435660D7E0260042695768814D3D40A0 +S224010FA0F6B23704E026F6023E402E4356600226426957687C4D3D40F6B2F704E026B6036B +S224010FC03E402E435660BEE0260042695768754D3D40F6B23704E026F6023E402E43566073 +S224010FE0032642695768704D3D40F6B2F704E026B6033E402E435660A5E026004269576802 +S224011000684D3D40F6B23704E026F6023E402E435660042642695768634D3D40F6B2F704AE +S224011020E026B6033E402E4356608CE02600426957685C4D3D40F6B23704E026F6023E40C5 +S2240110402E435660052642695768574D3D40F6B2F704E026B6033E402E43566073E026002D +S224011060426957684F4D3D40F6B23704E026F6023E402E4356600626426957684A4D3D40B7 +S224011080F6B2F704E026B6033E402E4356605AE0260042695768434D3D40F6B23704E02683 +S2240110A0F6023E402E4356600726426957683E4D3D40F6B2F704E026B6033E402E435660E7 +S2240110C041E01E0042695768364D3D40F6B23704E026F6023E402E43566034E002264269F4 +S2240110E05768304D3D40F6B23704E026F6023E402E43566027E0032642695768294D3D401E +S224011100F6B23704E026F6023E402E4356601AE0042642695768234D3D40F6B23704E026DF +S224011120F6023E402E4356600DE00526426957681C4D3D40F6B23704E026F6023E402E43D4 +S224011140566000E021000A00D2B2002A17D0009A9288002A12D0009A9288092A0EDA009A0A +S2240111609688761E426957686D4D3D40F6B23702E026F6003E402E43566000E02100009AF9 +S2240111801278002A00D12300406942681024A243DBB21B0110242340134343600800C0B282 +S2240111A0F2BD0000FFFFF8FFFFFFC7FF006A08600120704700B54068806C02091000C007EC +S2240111C0C00FC0B2002804D0FA2080000860012000E0002000BD00B50978002901D001219A +S2240111E000E000214068826C10239A43C9B209011023194011438164012000BD00B54068BD +S224011200406C02091000C007C00FC0B2002804D0FA20C0010860012000E0002000BD00B527 +S2240112200978002901D0012100E000214068426C10239A43C9B2090110231940114341649A +S224011240012000BDFA20400208600120704710B50200002054680123646824091C40E4B25C +S224011260002C01D1002015E054686468240C1C40E4B2002C03D11000FFF775FC09E054688F +S2240112806468240C2340DBB2012B02D1100000F009F9C0B210BDF3B5002211001600436880 +S2240112A05F681024E44327401025F6B236012E403E435E60019B5B780A2B0DD1160043689B +S2240112C05F6818493940F6B2360480277F023E400E435E60012112E0019B5B78182B0ED12B +S2240112E0012143685F680F4E3E400096009EC9B2090480277F023940314359600121019B31 +S2240113001B78002B01D00122FFE7406843681C40D2B212011540254345600800C0B2F6BD5A +S224011320FFF8FFFFFFFFFEFF10B50A00002143689B681C092300DB07DB0FDBB2002B03D07A +S2240113401100FFF742FC01000800C0B210BD00B50978002901D0012100E000214068826815 +S22401136010239A43C9B209011023194011438160012000BD10B50A0000214368DB681C0930 +S2240113802300DB07DB0FDBB2002B03D01100FFF71CFC01000800C0B210BD00B50978002907 +S2240113A001D0012100E000214068C26810239A43C9B20901102319401143C160012000BDED +S2240113C010B50A00002143681B691C092300DB07DB0FDBB2002B03D01100FFF7F6FB010050 +S2240113E00800C0B210BD00B50978002901D0012100E000214068026910239A43C9B20901A5 +S2240114001023194011430161012000BD10B50A00002143685B691C092300DB07DB0FDBB2A6 +S224011420002B03D01100FFF7D0FB01000800C0B210BD00B50978002901D0012100E000213B +S2240114404068426910239A43C9B209011023194011434161012000BD10B50A0000214368A3 +S2240114609B691C092300DB07DB0FDBB2002B03D01100FFF7AAFB01000800C0B210BD00B51A +S2240114800978002901D0012100E000214068826910239A43C9B209011023194011438161BE +S2240114A0012000BDF8B504000D000020070000906068C06901090800C007C00FC0B20028A0 +S2240114C001D1002054E060680726C069000C3040C0B200280BD0022815D00ED304281ED0C7 +S2240114E017D3062827D020D307282AD02FE069462000FFF7BFF8070029E069462000FEF75C +S224011500A5FF070023E069462000FFF7C4F907001DE069462000FFF795FE070017E069468C +S2240115202000FFF747FE070011E069462000FFF765FE07000BE069462000FFF737FE070037 +S22401154005E069462000FFF795F80700FFE73800C0B200280AD06068C069000A0640310043 +S224011560C9B2491C009801F08CFB28603800C0B2F2BDF2B501231900002426004568EA6966 +S2240115801027BA43F6B2360110273E401643EE61009A5278032A19D0052A0AD0072A22D02F +S2240115A00E2A54D00F2A38D0102A43D0112A27D05AE026004268D769CC4D3D40F6B2370446 +S2240115C0E026F6023E402E43D6614EE01E004268D769C64D3D40F6B23704E026F6023E40BC +S2240115E02E43D66141E002264268D769BF4D3D40F6B23704E026F6023E402E43D66134E066 +S22401160003264268D769B94D3D40F6B23704E026F6023E402E43D66127E004264268D7690C +S224011620B24D3D40F6B23704E026F6023E402E43D6611AE005264268D769AC4D3D40F6B2F4 +S2240116403704E026F6023E402E43D6610DE006264268D769A54D3D40F6B23704E026F602D2 +S2240116603E402E43D66100E02100009A9288002A12D0009A9288092A0EDA009A9688761E62 +S2240116804268D769BA4D3D40F6B23702E026F6003E402E43D66100E02100009A1278002A84 +S2240116A000D123004068C2691024A243DBB21B01102423401343C3610800C0B2F2BD10B59C +S2240116C00200002054680123246A24091C40E4B2002C01D100201FE05468246A240CA40713 +S2240116E0A40FE4B2002C05D0022C0BD006D3032C0CD010E01000FEF7BDFF0CE01000FFF70A +S224011700CAF808E01000FEF7A1FE04E0FA20400208601800FFE7C0B210BDF3B501210A00BC +S2240117206B461A70002216004468256A10239D431023F6B236011E402E432662019C647800 +S224011740032C20D0052C04D0072C0FD0112C27D033E016004468276AC54D3D40F6B2370441 +S224011760C026B6023E402E43266228E00E004468276ABF4D3D40F6B23704C026B6023E4073 +S2240117802E4326621BE002264468276AB84D3D40F6B23704C026B6023E402E4326620EE082 +S2240117A003264468276AB24D3D40F6B23704C026B6023E402E43266201E06C462270019C87 +S2240117C02478002C00D111004068026A1024A243C9B209010B401343036268460078F6BDC8 +S2240117E010B50200002053689B6A1C092300DB07DB0FDBB2002B01D100201EE053689B6AC0 +S2240118001B0C9B079B0FDBB2002B05D0022B0BD006D3032B0CD00FE01000FFF7EFFC0BE00C +S2240118201000FFF7C3FC07E01000FFF7C3FC03E01000FFF7BFFCFFE7C0B210BDF3B500229E +S2240118401100160043689F6A1024E44327401025F6B236012E403E439E62019B5B78102B38 +S2240118600DD1160041688F6A814B3B40F6B23704C026B6023E401E438E62012124E0019B73 +S2240118805B780E2B0FD1012143689F6A784E3E400096009EC9B20F04C02189023940314321 +S2240118A09962012110E0019B5B780F2B0CD1022641688F6A6E4B3B40F6B23704C026B60210 +S2240118C03E401E438E620121019B1B78002B01D00122FFE74068836A1C40D2B21201154000 +S2240118E0254385620800C0B2F6BD0000FFFFF8FF10B50200002054680123246B240C1C408F +S224011900E4B2002C03D11000FFF75FF909E05468246B240C2340DBB2012B02D11000FFF774 +S22401192091FCC0B210BD10B50200002318004C780B2C0BD151680A6B8D4C1440DBB21A04F6 +S22401194080235B021A4022430A630EE0497811290BD101215268136B854C1C40C9B2090481 +S22401196080235B02194021431163C0B210BD0000FFF8FFFF10B50200002054680123646B66 +S224011980240C1C40E4B2002C03D11000FFF71DF909E05468646B240C2340DBB2012B02D170 +S2240119A01000FFF74FFCC0B210BD10B50200002318004C780B2C0BD151684A6B6C4C14403E +S2240119C0DBB21A0480235B021A4022434A630EE0497811290BD101215268536B644C1C407F +S2240119E0C9B2090480235B02194021435163C0B210BD10B50200002054680123A46B240CA3 +S224011A001C40E4B2002C03D11000FFF7DEF809E05468A46B240C2340DBB2012B02D110000F +S224011A20FFF710FCC0B210BD10B50200002318004C780B2C0BD151688A6B4D4C1440DBB25E +S224011A401A0480235B021A4022438A630EE0497811290BD101215268936B454C1C40C9B2AF +S224011A60090480235B02194021439163C0B210BDFFFFFCFF10B50200002054680123E46B54 +S224011A80240C1C40E4B2002C03D11000FFF79DF809E05468E46B240C2340DBB2012B02D170 +S224011AA01000FFF7CFFBC0B210BD10B50200002318004C780B2C0BD15168CA6B2C4C14407E +S224011AC0DBB21A0480235B021A402243CA630EE0497811290BD101215268D36B244C1C40BE +S224011AE0C9B2090480235B0219402143D163C0B210BD10B50200002054680123246C240CA1 +S224011B001C40E4B2002C03D11000FFF75EF809E05468246C240C2340DBB2012B02D110000D +S224011B20FFF790FBC0B210BD10B50200002318004C780B2C0BD151680A6C0D4C1440DBB29D +S224011B401A0480235B021A4022430A640EE0497811290BD101215268136C054C1C40C9B2EC +S224011B60090480235B02194021431164C0B210BDFFFFFEFF10B50200002014680123E46813 +S224011B8024091C40E4B2002C03D11000FFF71DF80AE01268D26812091A40D2B2012A03D16F +S224011BA0FA20400208601800C0B210BD10B50200002318004C780B2C0BD11068C168102258 +S224011BC09143DBB21A0110231A400A43C26001200EE0497811290BD1012001001268D368CA +S224011BE01024A343C9B20901102421401943D160C0B210BD80B50269126813091A00D207B6 +S224011C00D20FD2B2002A01D1002001E0FEF7ABFF02BD00B50978002901D0012100E00021AB +S224011C200069026810239A43C9B209011023194011430160012000BD80B5026952681309A1 +S224011C401A00D207D20FD2B2002A01D1002001E0FEF7BBFF02BD00B50978002901D0012169 +S224011C6000E000210069426810239A43C9B209011023194011434160012000BD80B50269B6 +S224011C80126913091A00D207D20FD2B2002A01D1002001E0FEF799FF02BD00B509780029A7 +S224011CA001D0012100E000210069026910239A43C9B209011023194011430161012000BDA1 +S224011CC080B50269526913091A00D207D20FD2B2002A01D1002001E0FEF777FF02BD00B553 +S224011CE00978002901D0012100E000210069426910239A43C9B20901102319401143416115 +S224011D00012000BD80B50269926913091A00D207D20FD2B2002A01D1002001E0FEF723FFBC +S224011D2002BD00B50978002901D0012100E000210069826910239A43C9B209011023194016 +S224011D4011438161012000BD80B50269D26913091A00D207D20FD2B2002A01D1002001E01D +S224011D60FEF733FF02BD00B50978002901D0012100E000210069C26910239A43C9B20901FB +S224011D80102319401143C161012000BDF8B504000E0020690125006A010928000840C0B299 +S224011DA0002801D1002035E02800002700972069006A000C8007800FC0B2002805D002285A +S224011DC00FD008D3032812D017E069462000FEF703FA070011E069462000FEF791F9070031 +S224011DE00BE069462000FEF707FA070005E069462000FEF7F1F90700FFE72069006A000AA9 +S224011E008007800F85402900009800F03AFF30603800C0B2F2BDFCB500231A001F00066992 +S224011E20356A1024A5431024FFB23F0127402F4337624D78012D01D11D000AE04D78002D8C +S224011E4001D1012505E04D78022D01D1022500E0FF252E00F6B2FF2E0BD00269176AA24EF4 +S224011E603E40EDB22F04C025AD023D403543156201221500EDB2002D2CD08D88012D01D1F7 +S224011E801D000FE08D88022D01D101250AE08D88042D01D1022505E08D88082D01D10325A2 +S224011EA000E0FF252E00F6B2FF2E12D06E46357005692F6A8D4E3E400196019FBC466E468D +S224011EC036783702C026B6003E4067463E432E6200E01A000978002901D00123FFE7006955 +S224011EE0016A1025A943DBB21B011C400C4304621000C0B2F6BD80B50269926A13091A008F +S224011F00D207D20FD2B2002A01D1002001E0FEF75CFE02BD00B50978002901D0012100E040 +S224011F2000210069826A10239A43C9B209011023194011438162012000BD80B5036901222B +S224011F401B6B1B091340DBB2002B01D100201BE00269126B120C9207920FD2B2002A05D016 +S224011F60022A09D005D3032A09D00BE0FEF782FB09E0FEF76BFA06E0FEF78DFC03E0FEF79C +S224011F8079FB00E00020C0B202BDF2B500221100160003691F6B1024E44327401025F6B211 +S224011FA036012E403E431E63009B5B78052B01D113000CE0009B5B78032B01D1012306E08D +S224011FC0009B5B78072B01D1022300E0FF231E00F6B2FF2E0BD001690F6B434E3E40DBB214 +S224011FE01F04C0239B023B4033430B630121009B1B78002B01D00122FFE70069036B1C4051 +S224012000D2B212011540254305630800C0B2F2BD80B5036901225B6B1B091340DBB2002B1C +S22401202001D100201BE00269526B120C9207920FD2B2002A05D0022A09D005D3032A09D0C7 +S2240120400BE0FEF717FB09E0FEF700FA06E0FEF722FC03E0FEF70EFB00E00020C0B202BDA5 +S224012060F2B500221100160003695F6B1024E44327401025F6B236012E403E435E63009B13 +S2240120805B78052B01D113000CE0009B5B78032B01D1012306E0009B5B78072B01D1022357 +S2240120A000E0FF231E00F6B2FF2E0BD001694F6B0D4E3E40DBB21F04C0239B023B4033432C +S2240120C04B630121009B1B78002B01D00122FFE70069436B1C40D2B2120115402543456388 +S2240120E00800C0B2F2BD0000FFFFFCFFFFFCFFFF80B5036901221B6C1B091340DBB2002B45 +S22401210001D100201BE00269126C120C9207920FD2B2002A05D0022A09D005D3032A09D025 +S2240121200BE0FEF7A7FA09E0FEF790F906E0FEF7B2FB03E0FEF79EFA00E00020C0B202BD88 +S224012140F2B500221100160003691F6C1024E44327401025F6B236012E403E431E64009BB0 +S2240121605B78052B01D113000CE0009B5B78032B01D1012306E0009B5B78072B01D1022376 +S22401218000E0FF231E00F6B2FF2E0BD001690F6CAD4E3E40DBB21F04C0239B023B403343EA +S2240121A00B640121009B1B78002B01D00122FFE70069036C1C40D2B2120115402543056464 +S2240121C00800C0B2F2BD80B5036901225B6C1B091340DBB2002B01D100201BE00269526C00 +S2240121E0120C9207920FD2B2002A05D0022A09D005D3032A09D00BE0FEF73CFA09E0FEF727 +S22401220025F906E0FEF747FB03E0FEF733FA00E00020C0B202BDF2B50022110016000369EB +S2240122205F6C1024E44327401025F6B236012E403E435E64009B5B78052B01D113000CE0D7 +S224012240009B5B78032B01D1012306E0009B5B78072B01D1022300E0FF231E00F6B2FF2E74 +S2240122600BD001694F6C784E3E40DBB21F04C0239B023B4033434B640121009B1B78002BC9 +S22401228001D00122FFE70069436C1C40D2B212011540254345640800C0B2F2BD80B5036923 +S2240122A001229B6C1B091340DBB2002B01D100201BE00269926C120C9207920FD2B2002A63 +S2240122C005D0022A09D005D3032A09D00BE0FEF7D1F909E0FEF7BAF806E0FEF7DCFA03E072 +S2240122E0FEF7C8F900E00020C0B202BDF2B500221100160003699F6C1024E4432740102593 +S224012300F6B236012E403E439E64009B5B78052B01D113000CE0009B5B78032B01D10123E6 +S22401232006E0009B5B78072B01D1022300E0FF231E00F6B2FF2E0BD001698F6C974E3E4082 +S224012340DBB21F04C0239B023B4033438B640121009B1B78002B01D00122FFE70069836CBA +S2240123601C40D2B212011540254385640800C0B2F2BD80B5036901221B6E1B091340DBB244 +S224012380002B01D100201BE00269126E120C9207920FD2B2002A05D0022A09D005D3032A4F +S2240123A009D00BE0FEF766F909E0FEF74FF806E0FEF771FA03E0FEF75DF900E00020C0B2F4 +S2240123C002BDF2B500221100160003691F6E1024E44327401025F6B236012E403E431E6606 +S2240123E0009B5B78052B01D113000CE0009B5B78032B01D1012306E0009B5B78072B01D17E +S224012400022300E0FF231E00F6B2FF2E0BD001690F6E624E3E40DBB21F04C0239B023B4001 +S22401242033430B660121009B1B78002B01D00122FFE70069036E1C40D2B2120115402543D0 +S22401244005660800C0B2F2BDFFFFFCFF7CB505000C0029690120496E0A0901001140C9B25D +S224012460002901D1002037E0002600962869406E000C8007800FC0B2002805D002280FD08F +S22401248008D3032812D017E069462800FDF7A4FE060011E069462800FDF732FE06000BE007 +S2240124A069462800FDF7A8FE060005E069462800FDF792FE0600FFE72869406E000A8106A3 +S2240124C0890EC9B2491C022900D20221009800F0D8FB20603000C0B276BDF3B501000022E4 +S2240124E0100016000C69656E10239D431023F6B236011E402E436666019C6478012C01D130 +S22401250014000CE0019C6478002C01D1012406E0019C6478022C01D1022400E0FF2425006C +S224012520EDB2FF2D0BD00869466E1C4D3540E4B22604C024A40234402C43446601200400F0 +S224012540E4B2002C18D0019CA488A41E3F2C12D2019CA5886D1E0C69666E0096009F104EC0 +S2240125603E400096009EEDB22F02FC25AD013D403543656600E01000019C2478002C01D01E +S2240125800122FFE709694C6E1025AC43D2B21201134023434B66C0B2F6BD0000FFFFFCFFBD +S2240125A0FFC0FFFF0020704700B50978002901D0012100E000210069826E10239A43C9B24A +S2240125C009011023194011438166012000BD80B50269D26E13091A00D207D20FD2B2002AC8 +S2240125E001D1002001E0FEF7F0FA02BD00B50978002901D0012100E000210069C26E102345 +S2240126009A43C9B20901102319401143C166012000BD80B50269126F13091A00D207D20F5C +S224012620D2B2002A01D1002001E0FEF7CEFA02BD00B50978002901D0012100E000210069DB +S224012640026F10239A43C9B209011023194011430167012000BD80B502698023D2581309BF +S2240126601A00D207D20FD2B2002A01D1002001E0FEF779FA02BD00B50978002901D0012186 +S22401268000E0002100698022825810239A43C9B2090110231940114380228150012000BD88 +S2240126A080B502698423D25813091A00D207D20FD2B2002A01D1002001E0FEF754FA02BD30 +S2240126C000B50978002901D0012100E0002100698422825810239A43C9B209011023194097 +S2240126E0114384228150012000BD80B502699423D25813091A00D207D20FD2B2002A01D13A +S224012700002001E0FDF7FCFC02BD00B50978002901D0012100E00021006994228258102388 +S2240127209A43C9B2090110231940114394228150012000BD80B502699C23D25813091A002D +S224012740D207D20FD2B2002A01D1002001E0FDF753FD02BD00B50978002901D0012100E003 +S224012760002100699C22825810239A43C9B209011023194011439C228150012000BD406AA5 +S224012780086001207047806A086001207047C06A08600120704780B501220269A023D258AF +S2240127A0120C5207520FD2B2002A0BD0022A0FD00BD3042A12D00ED3062A15D011D3072AAE +S2240127C012D014E0FFF7DBFF12E0FFF7DCFF0FE0FFF7DDFF0CE0FDF7D7FF09E0FDF7BDFE7B +S2240127E006E0FEF7DFF803E0FDF7CEFF00E00020C0B202BD10B5020001231800497804295B +S22401280045D0062934D0082950D0372904D0382911D039291DD058E000231169A0228A58DB +S224012820BA4C1440DBB21B04E022D2021A402243A023CA504AE01169A0228A58B34C14407F +S224012840DBB21B04E022D2021A402243A023CA503CE002231169A0228A58AC4C1440DBB21C +S2240128601B04E022D2021A402243A023CA502DE003231169A0228A58A44C1440DBB21B0480 +S224012880E022D2021A402243A023CA501EE004231169A0228A589D4C1440DBB21B04E02292 +S2240128A0D2021A402243A023CA500FE005231169A0228A58954C1440DBB21B04E022D202B6 +S2240128C01A402243A023CA5000E00020C0B210BD80B501220269A423D258120C5207520F8B +S2240128E0D2B2002A0BD0022A0FD00BD3042A12D00ED3062A15D011D3072A12D014E0FFF779 +S2240129003EFF12E0FFF73FFF0FE0FFF740FF0CE0FDF73AFF09E0FDF720FE06E0FEF742F801 +S22401292003E0FDF731FF00E00020C0B202BD10B50200012318004978042945D0062934D020 +S224012940082950D0372904D0382911D039291DD058E000231169A4228A586C4C1440DBB245 +S2240129601B04E022D2021A402243A423CA504AE01169A4228A58654C1440DBB21B04E022BD +S224012980D2021A402243A423CA503CE002231169A4228A585D4C1440DBB21B04E022D202DB +S2240129A01A402243A423CA502DE003231169A4228A58564C1440DBB21B04E022D2021A404A +S2240129C02243A423CA501EE004231169A4228A584E4C1440DBB21B04E022D2021A40224335 +S2240129E0A423CA500FE005231169A4228A58474C1440DBB21B04E022D2021A402243A423C8 +S224012A00CA5000E00020C0B210BD10B501231A000269C0241259120C1340DBB2002B02D09F +S224012A20012B03D005E0FEF7E9FB03E0FEF7BEFB00E00020C0B210BD10B502000123180000 +S224012A4049780E2910D010291CD100231169C0228A587A4C1440DBB21A0480235B021A40F2 +S224012A602243C023CA500EE01169C0228A58734C1440DBB21A0480235B021A402243C02362 +S224012A80CA5000E00020C0B210BD10B501231A000269C4241259120C1340DBB2002B02D01B +S224012AA0012B03D005E0FEF7A9FB03E0FEF77EFB00E00020C0B210BD10B502000123180000 +S224012AC049780E2910D010291CD100231169C4228A585A4C1440DBB21A0480235B021A408E +S224012AE02243C423CA500EE01169C4228A58534C1440DBB21A0480235B021A402243C423F6 +S224012B00CA5000E00020C0B210BD0000FFFFF8FF80B50269CC23D25813091A00D207D20FB8 +S224012B20D2B2002A01D1002001E0FEF71CF802BD00B50978002901D0012100E0002100698A +S224012B40CC22825810239A43C9B20901102319401143CC228150012000BDF0B5059D069EAA +S224012B60079F089C016042608360C56006614761216881616168C161A168016200210A00FE +S224012B800AE00A00D2B29200A218D2680B00DBB29B00C3185A62491C0A00D2B2032AF0D384 +S224012BA0F0BD38B503000C0011002000C0B23F2801DB00200DE00020214A2500EDB2ED0037 +S224012BC05559002D04D01800E4B2E300D2589047C0B232BDF8B50B0015001900C9B23F2984 +S224012BE001DB002029E000242100154A1E00F6B2F60096197668002E1DD02900050011483B +S224012C006F688026B8511048AE6830660F482F688026B8512800DBB2DB00D218526890477C +S224012C20010020006A688023D0502000AA6810662868802284500800C0B2F2BDFFFFFEFF06 +S224012C40E488010052455355202096194B4D4352F446002804D4494200F013F840426047BD +S224012C604042002905D45FD000F00BF8404249426047494200F005F84942604703460B43B3 +S224012C80E6D40022030A8B420BD203098B4219D243088B422ED2411A00D201465241104662 +S224012CA07047FF2209023FD012068B4205D3121209028B4201D31212090203098B4219D39B +S224012CC000E0090AC3098B4201D3CB01C01A524183098B4201D38B01C01A524143098B4216 +S224012CE001D34B01C01A524103098B4201D30B01C01A5241C3088B4201D3CB00C01A524177 +S224012D0083088B4201D38B00C01A524143088B4201D34B00C01A5241884200D3401A52415B +S224012D20CFD201461046704708B500F001F808BD7047FEE700B501000020C9B2002905D042 +S224012D40022907D004D3032906D006E0102004E0182002E0282000E04820C0B200BD70B59A +S224012D600E0001680C0080340025290029000068C9B2002919D0022909D00FD303291BD1AC +S224012D80C02109014058400E8507AD0F14E0C02109014058800D8507AD0F0DE0C0210901F0 +S224012DA04058C00C8507AD0F06E0C02109014058000C8507AD0FFFE72800C0B2FFF7BAFF75 +S224012DC00100C9B2890830002A00D2B2002A05D1C9B280B241438800201832E02A00D2B251 +S224012DE0012A0ED1C9B2020092B251430D0080B21521FFF743FF4000290008188000201880 +S224012E001FE0EDB2022D0ED1C9B2020092B251430D0080B20C21FFF731FFC0002900081810 +S224012E20800020180DE0C9B2020092B251430D0080B20721FFF722FF40002900081880000B +S224012E40201870BD00B5010000200A00D2B2002A082A0ED9093A0ED0521E0ED0521E0ED0A3 +S224012E60521E0ED0521E0ED0521E0ED0521E0ED00FE008000DE00C200BE0102009E01420CC +S224012E8007E0182005E0202003E0302001E04020FFE7C0B200BD80B500231A0089B2FFF7BC +S224012EA05EFF0068000C0007000FC0B2FFF7CAFFC0B202BD00B50023D2B2002A0CD00268F7 +S224012EC0C023DB03134303604268520F5207C900C908114341600BE00268B14B1340036078 +S224012EE04268B04B13408A04AF4911401943416000BD0268AD4B134003600268C9B2090439 +S224012F00F0231B030B4013430360704700B502685200520802600268A54B13400360C9B207 +S224012F20002909D00168802212060A43026001688022D2050A43026000BD00B50A00D2B226 +S224012F40002A06D101689B4A0A400260016801600BE0C9B2012908D10168964A0A40026048 +S224012F6001688022D2040A43026000BD10B50168803100221300140003E0A300CB181A60F3 +S224012F80641C037EDB019C42F7D310BD10B48A4982688023D15001214268136D2024A3431E +S224012FA0C9B249012024214019431165002180688022815010BC704710B47F4982688023B7 +S224012FC0D15001214268136D1024A343C9B2090110242140194311650021806880228150FC +S224012FE010BC7047F0B4049C059D069E079F3F780776016042608360C46005614661F0BC21 +S224013000704710B500210A008160016141618161C160C16141628162C16201620122027058 +S2240130200A00C2700A0002710022D24342638263C26302640B00442403550B0045240355EE +S2240130400B00C82403550823462403550B0005E01C00E4B2A4000419A2645B1C1C00E4B29C +S224013060202CF5DB0A0042700A0082700A003023C2540A00C923C2540A00CA23C2540A00E0 +S224013080CB23C2540A00D523C2540A00D423C2540A00D623C2540A00D723C2540A00CC23CB +S2240130A0C254D022815010BD30B500210A0003681C683F4D2540D2B292078024E405224068 +S2240130C02A431A60026813683C4C1C40C9B2090780235B05194021431160016809680A0E8C +S2240130E01100C907C90FC9B20029F6D130BD38B50400206801250068000D2840C0B20028A3 +S22401310013D0002021680A6852005208C0B2C0071043086002E02000FFF74EFF20680068D6 +S224013120000D2840C0B20028F5D1280021680A68234B1340C0B24006802292041040184335 +S224013140086020680068400E2840C0B20028F8D1280021680A68164B1340C0B28007802286 +S224013160D205104018430860280021680A68134B1340C0B200078022520510401843086006 +S22401318020680068000E2840C0B20028F8D020680068C00E2840C0B20028F1D031BD0000F2 +S2240131A0FFFF9FFFFFFF03E00000FC1FFFFFF0FFFFFFFFBFFFFFFFF052455355FFFFFFEFB0 +S2240131C0FFFFFFFDF0B593B007000C0015002900C9B289B23800FFF7C2FD0600227A6168A8 +S2240131E03000FFF767FEA17A3000FFF782FEE17A3000FFF78BFE617A3000FFF79EFE207B3B +S224013200002805D0684605706946380000F0A8FD607A012807D120693968EDB2AA0089181D +S22401322088221201885013B0F0BD0000F8B504000E00002500202000FFF7A8FE0127390062 +S2240132402068026852005208C9B2C9071143016020680068010D38000840C0B20028F7D0EB +S224013260327821684B686D481840D2B2520380239B011A4002434A602000FFF738FF3A006D +S22401328021680B6866481840D2B2D20580231B041A4002430A603A0021684B6B6148184086 +S2240132A0D2B2120780235B051A4002434A632000FFF75CFE3020305CFFF73CFD0100080098 +S2240132C0C0B2002807D080208000C9B2FFF7D9FC0500207E4543206801687F229143EDB2E1 +S2240132E06A06520E0A430260380021680A6D52005208C0B2C007104308654B49B068431865 +S2240133002068056D494A2A409BB25D05484B2B4013430365F06843182068056D454A2A409F +S2240133201D04F8235B032B4013430365306943182068056D404A2A409BB29D02FC231B02BA +S2240133402B4013430365706943182068056D3B4A2A409BB25D01F8239B002B401343036597 +S224013360B06943182068026D1F25AA439BB2DB06DB0E13430365F078002861D03B00226850 +S2240133801568D7482840DBB25B078025AD052B4003431360337922681568D2482840DBB2F7 +S2240133A0DB0380252D022B4003431360306C226890644420335C20680568CB4A2A40DBB223 +S2240133C01D02C0239B002B40134303604520335C2068456BC54A2A40DBB21D06F0231B059E +S2240133E02B4013434363C820305C012840D1002210004623F35CC0B2984239D21000C0B2EF +S22401340080003018836C15002068EDB2AD004519882000012B50521CEAE700BFFFDFFFFFAA +S224013420FFFF7FFFFFFFFFEFFFFF0000FFFF1F800000E07FFFFFE0FFFF03FFFF1FFCFFFF2E +S224013440002322681568A6482840DBB25B078025AD052B4003431360002322681568A14869 +S2240134602840DBB2DB0380252D022B40034313607078002800D16CE1737822681568CE4845 +S2240134802840DBB2DB0280252D012B40034313603A002068C0231B01C3585B005B08D2B23F +S2240134A0D2071A43C0231B01C250F06943182268C2481558C24828409BB21D05C14B2B40B2 +S2240134C00343BE481350306A43182268BB481558BD4828401D04E023DB022B400343B7482A +S2240134E01350736A2268B5481558B84828409BB29D02F823DB012B400343B0481350B06A21 +S22401350042182068AD4BC358E025AB4392B25501E0222A401A43A94BC250F06A4118206819 +S224013520A64A825807239A4389B24907490F1143A24A81503020315C00232068C022120143 +S2240135408258DBB2002B1FD0022B0BD013D3032B23D1C44B1340C9B24906C022D2040A40A6 +S2240135601A431AE0C04B1340C9B28905C02212040A401A4311E0BD4B1340C9B2C904C02272 +S22401358052030A401A4308E0B94B1340C9B20904C02292020A401A43FFE7C02109014250E2 +S2240135A03020315C3B002068C02212018258DBB2002B1FD0022B0BD013D3032B23D1A94BEB +S2240135C01340C9B24906C022D2040A401A431AE0A54B1340C9B28905C02212040A401A4384 +S2240135E011E0A24B1340C9B2C904C02252030A401A4308E09E4B1340C9B20904C02292024C +S2240136000A401A43FFE7C021090142503020315C02232068C02212018258DBB2002B1FD09A +S224013620022B0BD013D3032B23D18E4B1340C9B24906C022D2040A401A431AE08A4B1340FD +S224013640C9B28905C02212040A401A4311E0874B1340C9B2C904C02252030A401A4308E098 +S224013660834B1340C9B20904C02292020A401A43FFE7C021090142503020315C0323206890 +S224013680C02212018258DBB2002B1FD0022B0BD013D3032B2CD1734B1340C9B24906C022D8 +S2240136A0D2040A401A4323E06F4B1340C9B28905C02212040A401A431AE06C4B1340C9B250 +S2240136C0C904C02252030A401A4311E0684B1340C9B20904C02292020A401A4308E000BFF6 +S2240136E0FFFFFFDFFF7FFFFFFFFCFFFFFFFFFFF0C02109014250CA20325C2068C02109011E +S2240137004358AA491940D2B2D20380231B021A400A43C02109014250CB20325C2068C0219D +S22401372009014358A2491940D2B21302F82252011A400A43C02109014250B2782068436B10 +S2240137409C491940D2B2120380235B011A400A434263706B21680861B06B21684861F06BCC +S22401376021688861C820325C2068036892491940D2B2120480235B021A400A430260C920A8 +S224013780305C002824D00022206803688B491940D2B2520480239B021A400A4302603A00DC +S2240137A02068436883491940D2B2120380235B011A400A43426023E0FFF7FFFF040C0000C3 +S2240137C0FFFF0FC00000F03FFFFFF8FFFF83FFFF3A002068036879491940D2B252048023AD +S2240137E09B021A400A43026000222068436871491940D2B2120380235B011A400A434260D4 +S224013800D420305C002835D03A00206803686C491940D2B292058023DB031A400A43026015 +S2240138203A002068036867491940D2B292068023DB041A400A4302603A00206803686249CD +S2240138401940D2B292048023DB021A400A430260380061698A6C01239A43C0B2074017435A +S2240138608F6434E0FFFFFFF9FFFF3FFFFFFFE7FFFFFFFCFF00210B002268156850482840F9 +S224013880DBB29B058025ED032B40034313600B00226815684B482840DBB29B068025ED046B +S2240138A02B40034313600B002268156846482840DBB29B048025ED022B4003431360606929 +S2240138C0826C01239A43C9B20F4017438764D520305C21680A68374B1340C0B2000380227C +S2240138E05201104018430860D620305C21684A682E4B1340C0B2C00380221202104018433D +S2240139004860D720305C21684A68304B1340C0B280038022D201104018434860002723E086 +S2240139202A00D2B2D02030583900C9B21423594341182000FFF746FC6D1C2A0092B2D0203C +S22401394030583900C9B214235943435AD020305884463900C9B21420414360464018408841 +S22401396018188242DCDB7F1C3800CC21715CC0B2884208D20020D02030583900C9B2142271 +S2240139805143455AD9E7200000F06EF92000FFF78BFB002021680A680D4B1340C0B2C0051E +S2240139A080221204104018430860F1BDFF7FFFFFFFE0FFFFFFEFFFFFFFFFFEFFFFFFFDFF4E +S2240139C0FFFFBFFFFFFFFFFBFFFFFBFFFFBFFFFFFFFF7FFF80B5097889B2FFF7C0F90168F4 +S2240139E0C02212050A43026001BDF8B506000C00217889B23000FFF7B2F90500083521781C +S224013A0089B23000FFF747FA00210A000A001BE01600F6B23340032B15D12B681600F6B238 +S224013A20A619367A1E432E602D1D0CE01600F6B21E40022EECD12B681600F6B2A619367A23 +S224013A4036021E432E60521C1300DBB283421BD203231E00324209D129602B681600F6B20D +S224013A60A619367A36061E432E60ECE71600F6B21E40012EDAD12B681600F6B2A619367A1D +S224013A8036041E432E60DEE7F1BDF8B506000C00217889B23000FFF762F905002868000CCF +S224013AA00007000FFFF7CEF9482160542868400D0100C907C90F281DC9B2002904D0016864 +S224013AC0C900C908616004E00168890C4905490D6160051D217889B23000FFF7DCF900212C +S224013AE00A0012E02A680B00DBB2E3181A722D1D0AE00B00DBB21A40022AF3D12A68120A4F +S224013B000B00DBB2E3181A72491C0A000300D2B2DBB29A4216D203221300194206D12A683D +S224013B20120E0B00DBB2E3181A72EDE70B00DBB21340012BDDD12A68120C0B00DBB2E31864 +S224013B401A72E1E730688068F1BD30B500231A000A78D506ED0E01242200AA400D78402D40 +S224013B6011DB0221006800290AD0022904D005D3032907D1026705E0426703E0C26201E00B +S224013B800263FFE723E00978202910DB0068002C0AD0022C04D005D3032C07D1026705E07F +S224013BA0426703E0C26201E00263FFE70FE00068002B0AD0022B04D005D3032B07D102677F +S224013BC005E0426703E0C26201E00263FFE730BD30B5002213000B78DD06ED0E012423006E +S224013BE0AB400D78402D12DB0221006800290AD0022904D005D3032907D1026F05E0426F85 +S224013C0003E0C26A01E0026BFFE71A4026E00978202911DB0068002C0AD0022C04D005D3FD +S224013C20032C07D1026F05E0426F03E0C26A01E0026BFFE71A4011E01100006800290AD066 +S224013C40022904D005D3032907D1026F05E0426F03E0C26A01E0026BFFE71A40002A01D0E4 +S224013C60012000E0002030BD10B5017E032937D10021C9430A0002240368002C0AD0022CBC +S224013C8004D005D3032C07D11A6705E05A6703E0DA6201E01A63FFE70A0001240368002C1B +S224013CA00AD0022C04D005D3032C07D11A6705E05A6703E0DA6201E01A63FFE7002200682F +S224013CC0002A0AD0022A04D005D3032A07D1016705E0416703E0C16201E00163FFE73EE0B9 +S224013CE0017E022925D10021C9430A0001240368002C0AD0022C04D005D3032C07D11A67EF +S224013D0005E05A6703E0DA6201E01A63FFE700220068002A0AD0022A04D005D3032A07D129 +S224013D20016705E0416703E0C16201E00163FFE715E0017E012912D10021C943002200681F +S224013D40002A0AD0022A04D005D3032A07D1016705E0416703E0C16201E00163FFE710BD89 +S224013D6030B500231A000A78D506ED0E01242200AA400D78402D19DB02210068002910D018 +S224013D80022906D009D303290FD1816E0A4382660BE0C16E0A43C26607E0416A0A434262FE +S224013DA003E0816A0A438262FFE733E00978202918DB0068002C10D0022C06D009D3032CC5 +S224013DC00FD1816E0A4382660BE0C16E0A43C26607E0416A0A43426203E0816A0A438262C8 +S224013DE0FFE717E00068002B10D0022B06D009D3032B0FD1816E0A4382660BE0C16E0A43F5 +S224013E00C26607E0416A0A43426203E0816A0A438262FFE730BDF9B58FB00D001799002055 +S224013E2001200490012003900820009003230293022414240C94784C0B94FA24A4050A94DA +S224013E40C9B2002909D1754909915E2608931F217118491C0791069008E070490991262684 +S224013E60089307217118491C079106900192019800F0DEF8059001240D952EE0280000F0E9 +S224013E80E7F80100380000F0EEF80700019800F0CFF80100380000F070F98021090400F0A7 +S224013EA0C5F939D8019800F0C3F80100380000F064F901000798A8420EDB059800F0B6F9B4 +S224013EC00AD80494009505910C98A84204DB08000B9900F0BFF927D3641C0998A04223DB7B +S224013EE00D9800F0A5F80500200000F0B1F80100280000F0B8F80700019800F099F80100E1 +S224013F00380000F0B0F800F0B9F90500002D02D006988542B2DA07E0019800F089F839000A +S224013F2000F02BF90100C5E710A80488200080B200F07EF80A9900F0BEF905000098B042E5 +S224013F4000DA009E0CE0380000F082F8290000F081F904D20296380000F07AF80500761E21 +S224013F600898864216DB3000401C2D4948430099FEF784FE210089B2411A012903DB210065 +S224013F8089B2471A02E0210089B20F1A210089B28842D8DA00980299401A401E0190214C57 +S224013FA00125169E1DE0310089B20F1A0CE01C4868430099FEF762FE310089B2411A0129B5 +S224013FC0F1DB310089B2471A380000F041F8210000F040F904D20395380000F039F80400CC +S224013FE06D1C0198A842E2DA0F9C04982060029800F0CAF90CA20CCA00F0D0F900F090FA28 +S224014000A0600298A168401AE060019820610398606011B0F0BD0000CDCCCC3DFF030000D6 +S2240140201027000000401C46333333333333E33F9D2102000AD002D4491E9218FCD5C9052D +S224014040100A1206524100D3012A4841704700009D210200EED55242F446FFF7EBFF012203 +S224014060D2071043604730B405004D400122D20715404B180418240E25D01B0E2CD0FF2CAA +S22401408031D0FF2B34D0E41A000209021043114343084808D10D1B1A02D2641EDB181B180F +S2240140A0DB18834200D31B1A4941F9D37F3423DDFF2C05DAE40548086041284330BC70473F +S2240140C0FF20C005F9E728001B0E03D0FF2BF5D14902F3D0D043F1E7FF2C01D14002F9D100 +S2240140E0FF20C005E9E74002F4D1FF2BF8D1F1E728004902E2D0EDE70B0200202442DCD1FB +S2240141005B129B1CD9D9D805D7E70122D20703004B402ED4431A01D2C01AC91830B44B186A +S2240141200418240E1B0E22D0FF2C20D0E31A182B1DDC09021143C40D641E000210439446DB +S2240141401925ED1A0A00AA40D940451801D36D08A41CE405D209280A2D062A436546AA4175 +S224014160604103181B0EFF2B01D3C00DC00530BC7047514006E05140CCE70122D207030067 +S2240141804B40F8D4431A03D2C01AC9185040514030B44B18090211430418240E1B0E40D087 +S2240141A0FF2C3AD025009D410BD31ED8C50D4002401A0BD3ED050100400AC905914168411B +S2240141C0D5E7C50D40024918401AD0D001214008491C0018FCD58C4204D36D1A000AED05CE +S2240141E04019C4E7E8051040C1E7182DBFDCAC1C0D00E140E5414D40012D4941C40D0002BC +S2240142001043451A01D46D199543641EE405280A2D069541604130BC7047FF2BA7D1D8430C +S224014220A5E72442A3D10020A1E7FEE70CB4012212060318DA4207D84B18DA4204D8020017 +S2240142400A43921802D281420CBC7047FCD088420CBC70470CB4012212060318DA4207D825 +S2240142604B18DA4204D802000A43921802D288420CBC7047FCD08142FAE7FEE70122D20776 +S2240142800118090E7F3910D449421F310FD4001805D2C0011043C84000D5D0437047C00123 +S2240142A01043C84005D440427047002070470042F3D51000704730B405004D400122D20771 +S2240142C015404B180418240E2ED01B0E32D0FF2C34D0FF2B3AD0E418000209021043114396 +S2240142E0000A090A9446C2B24A43000AC3B24B43000A4843110A5B181A43D2B2190A09186B +S22401430001D44918641E080A7F3C23DBFE2C08DAE40509061143634699416041284330BC41 +S2240143207047FF20C005F9E728001B0EFF2BF6D1D043F4E72800FF2CF1D1F9E74002F7D1CD +S224014340FF2B01D14902F3D1E005E7E7D8054902E4D0EDE743020020641CDFD15B129B1C30 +S224014360DCD9D805DAE7FEE7010042221201D21E004207D002D4521E0018FCD5C10A40053F +S22401438012058918704700000100EED54042F446FFF7EBFF0122D20711436047F0B50E009E +S2240143A05E400125ED072E40B446AE0ADF184C18F44208D2F7420ED2640D01D07F0D12D1EA +S2240143C000206146F0BD05D1F74201D87F0D05D10020C143F0BDFBD1640DF9D00020C1431E +S2240143E0490549088FE0E419C902DB0229432B43DB0A460DC00231438E4630B487B295B284 +S2240144007D432E0CADB2140C7C43A419260C240425439CB27C43A419190C7943270CC9191F +S224014420A4B20F043C43090C000C97B247432E0CBE193543ADB2170C4743360CBF19A6B293 +S224014440BF193E043543240C3E0C36199FB24743BF19BCB23E0C89191F0C47437F183E0460 +S2240144603443390C704680B297B247432E0CBE193543ADB2170C4743360CBF19A6B2BF19E0 +S2240144803E043543240C3E0C36199FB24743BF19BCB23E0C89191F0C47437F183E04344381 +S2240144A0390C77463F0C90B278432E0C80190604ADB22E43050CA0B22D18120C7A43501913 +S2240144C0020C80B2240CA4189AB27A43121914042043120C89181B0C7B43C91830BCEF0A91 +S2240144E0394203D1B61940414941641E6F12BF0DE41B0BDBFF19BC4211DA2405002742083E +S224014500AE417841614166463143F0BD641C05D1401C6141CF0201D34908F4E750E75DE7DE +S2240145204A1812D2400DC90208430121C9070843520D40210901521A521C06D452421F322C +S22401454001D4D0407047C017704700207047704700B50100C9B2802900DB7F20C0B200BD1A +S22401456000B50100C9B2F139092901D2012004E00100C9B2802900DB0020C0B200BDFEB5CE +S2240145800400002528006E463F2030703078F0270F430740377072701800C0B2FFF7D8FFD9 +S2240145A0B070207800280FD0032003E00100C9B27554401C0100C9B20829F7DB0822694637 +S2240145C0E068A36D984704E003226946E068A36D984740B2FEBD7CB50300002001000100AC +S2240145E069460F220A700A78DC8AF025254315400D70020008E01C691500EDB2645D15002B +S224014600EDB24D196C70521C1400E4B2DD8AA4B2AC42F0D31A78002A15D0020006E0140090 +S224014620E4B2DD8A64190C196070521C1400E4B20725DE8AAD1BAC42F1DB08226946D868BE +S2240146409B6D984706E0DA8A521CD2B26946D8689B6D984740B276BD1CB5040068461F2173 +S22401466001700178E28A92B2120AF02313430B400370E18A417000210A00D2B2C9B208E029 +S22401468022690B00DBB2D25C0B00DBB2C3189A70491C0A00D2B2062AF2DB08226946E06835 +S2240146A0A36D9847010049B2002904D1218B891D21830121A17640B216BDFEB5040000253B +S2240146C02800C0B268462F2101700178A27EF02313430B400370E18A228B8E1A310089B2DF +S2240146E0082900DB07262900C9B20AE02269238B0F00FFB2DB19D25C0B00DBB2C3185A7095 +S224014700491C0A00D2B2330092B29BB29A42EDD3217800291AD02900C9B22900C9B207E065 +S2240147200A00D2B233009BB2D21882185570491C0A00D2B207233700BFB2DB1B9A42EFDBBB +S22401474008226946E068A36D984706E03200521CD2B26946E068A36D9847010049B200292E +S22401476009D1218B89192183A17E491CA176A17E102900DBA57640B2FEBD70B50300002089 +S22401478004000F240D782600354205D0D2B2521E0D782540AA4208DA586D002802D0994899 +S2240147A0596D88470620C04315E00A78144042229C5208E00200D2B28A185278DC6B0500F2 +S2240147C0EDB26255401C0200D2B242241C5B92B2A242EFD3002070BD38B503000020040073 +S2240147E0D2B2082A08D0586D002802D08648596D88470620C04339E00A781202F0242401F2 +S22401480014404A78A2181400A4B2082C08DA586D002802D07D48596D88470620C04325E0FB +S22401482040241C5B1500ADB2AC4208D2586D002802D07748596D88470220C04316E04224C7 +S2240148401A5308E00200D2B28A189278DC6B0500EDB26255401C0200D2B2062AF2DB062024 +S22401486044215852012046215854002032BDF8B50300002528004620185C0C782407240F27 +S224014880A04202D00320C0433EE04220185A44241C5B041B200080B2082800DB0724D2B23C +S2240148A0521E200080B2824208DA586D002802D05848596D88470620C04325E02A000BE053 +S2240148C0D86B1600F6B24427DF5BF6191700FFB2CF197F788755521C1000C0B2260080B252 +S2240148E0B6B2B042ECD34420185A0019442158524620185C401C462158544620185C102840 +S22401490001DB46201D540020F2BD80B50100D2B2032A08DA486D002802D03F48496D88478B +S2240149200620C04300E0002002BD80B513009BB20A00C16800F001F802BDF8B50400002543 +S2240149402800002C02D10020C04359E0A08A190089B2884208D2606D002802D0C048616D0F +S22401496088470220C0434BE03420205C012808D1606D002802D0BB48616D88470120C043B5 +S2240149803EE0E38228002083280007E00100C9B2515C26690700FFB2F155401C0100C9B226 +S2240149A01E0089B2B6B2B142F0D3E08A082804DA2000FFF710FE060020E02000FFF74CFE78 +S2240149C00600300040B2002818D12800A0832800A0772800E077E06D80472200203203C242 +S2240149E0083AE06D80470022643051412200283203C2083A2563012034216054300040B2BC +S224014A00F2BD0000DC990100089A0100D49801000C990100349A0100549A0100FEB5140030 +S224014A201A001300DBB29B1E072B00D317E100252B00DBB22B00DBB2029408E0029C1E0031 +S224014A40F6B2A45D6E461F00FFB2F4555B1C1C001600E4B2F6B2B442F0D32B00DBB207E09B +S224014A606C461E00F6B21700FFB2F619A5555B1C1C00E4B208261700FFB2F61BB442EFDBF7 +S224014A806F4604000E003878C0B20009002806D0022858D01BD3032800D19DE0DFE0512037 +S224014AA0205C012804D10520C0435021605401E050202554D2B269462000FFF75EFE40B2C8 +S224014AC0002803D1A663022051216054C7E05120205C012804D10520C0435021605401E0C3 +S224014AE050202554D2B269462000FFF775FE01000222D24349B291420CD10720C04350218B +S224014B006054512025540023002202212000FFF736FDA4E040B2002814D1A6630120512121 +S224014B20605460784721605401234720225C00212000FFF724FDE06D80470022643051410A +S224014B40A064E1648BE05120205C012804D00520C0435021605482E0A06B864200D07EE001 +S224014B60D2B269462000FFF782FE0321C94302000B0052B29A4204D15020215451202554A5 +S224014B806DE040B2002826D1E06D8047002264305141A064E1644420205A4221615A884246 +S224014BA003D302205121605415E06078002812D04720205C401E472160544720205C002892 +S224014BC009D160784721605401234720225C00212000FFF7D4FC42E03420205C01283ED1C7 +S224014BE0D2B269462000FFF790FE40B2002835D1E06D80470022643051412200283203C21B +S224014C00083A0F2039780140022906D10720C043206302203421605420E039780140012935 +S224014C200CD1E07F401CE077E07F022816DB0620C04320630220342160540FE0397801424B +S224014C400CD17878002802D18048A08301E07878A083B878FFF784FCA077E577FFE7F7BDF4 +S224014C60449901007899010070B5002425005125455D022D02D00420C04325E0856B8668AD +S224014C80B54201D1012500E025000D704221415A1D000E00ADB2B6B2B54200D219002300A8 +S224014CA007E0C56B1E00B6B2AD5D1E00B6B295555B1C1D000E00ADB2B6B2B542F1D3049A15 +S224014CC0118051214454002070BD70B402000B0018781070587850705868506098689060B5 +S224014CE0D868D06018691061988A908200242000D082200010832000907620009083200056 +S224014D0090772000D077002000211500203503C5083D1500283503C5083D146325003426F2 +S224014D2095559D69D5639D8B40269553250042269553250044269553250046269555250043 +S224014D40472695559064D16420005021505451201454186A5065586A9065986AD06570BC6E +S224014D60704738B504003420205C012856D1374DA08BA84202D0A08B00283DD0A07F002853 +S224014D800ED0A07F002837D0E06D8047220020320CCA121A8B41002B2EDC01DB002A2BD253 +S224014DA02000FFF78AFC40B2002822D1A08BA84202D0A08B4019A083E06D804700226430EC +S224014DC051412200283203C2083AE06D804702000B00A07F0021801859412200203203C2EC +S224014DE0083A208BE18A884206D300203421605402E0022034216054E06D804722002832EC +S224014E000CCA121A8B41002B08DC01DB002A05D20120C04320630220342160545120205C13 +S224014E20012811D1E06D8047A26CE36C121A8B41002B09DC01DB002A06D20220C043502174 +S224014E40605400205121605431BD0000FFFF000000B5BFF34F8F054805490860BFF34F8F8E +S224014E6000BFFDE701604260836070470400FA050CED00E038B504002F48A2688023D050DB +S224014E80C9B200295AD0022900D17FE06AD3042900D1A3E000D28DE0062900D1C6E000D26E +S224014EA0B0E0082900D1E9E000D2D3E00A2900D10CE100D2F6E00C2900D12FE100D219E191 +S224014EC00E2900D152E100D23CE1102900D175E100D25FE1122900D198E100D282E1142939 +S224014EE000D1BBE100D2A5E1162900D1DEE100D2C8E1182900D101E200D2EBE11A2900D1F6 +S224014F0024E200D20EE21C2900D147E200D231E21E2900D172E200D258E2202900D19DE28E +S224014F2000D283E2222900D1C8E200D2AEE2232900D1DBE2DDE200BF524553550120010053 +S224014F40A26853680125AB43C9B20140194351600021A26853680125AB43C9B20840184391 +S224014F605060C6E201200100A26893680125AB43C9B20140194391600021A2689368012543 +S224014F80AB43C9B2084018439060B2E201200100A268D3680125AB43C9B201401943D160B7 +S224014FA00021A268D3680125AB43C9B208401843D0609EE201200100A26813690125AB43E7 +S224014FC0C9B20140194311610021A26813690125AB43C9B20840184310618AE20120010069 +S224014FE0A26853690125AB43C9B20140194351610021A26853690125AB43C9B208401843EE +S224015000506176E201200100A26893690125AB43C9B20140194391610021A26893690125EE +S224015020AB43C9B208401843906162E201200100A268D3690125AB43C9B201401943D16163 +S2240150400021A268D3690125AB43C9B208401843D0614EE201200100A268136A0125AB4393 +S224015060C9B20140194311620021A268136A0125AB43C9B20840184310623AE20120010015 +S224015080A268D36A0125AB43C9B201401943D1620021A268D36A0125AB43C9B208401843CA +S2240150A0D06226E201200100626813680125AB43C9B2014019431160002162681368012520 +S2240150C0AB43C9B208401843106012E201200100626853680125AB43C9B2014019435160D6 +S2240150E00021626853680125AB43C9B2084018435060FEE101200100626813690125AB43C7 +S224015100C9B20140194311610021626813690125AB43C9B2084018431061EAE10120010008 +S224015120626853690125AB43C9B20140194351610021626853690125AB43C9B2084018432C +S2240151405061D6E101200100626893690125AB43C9B20140194391610021626893690125CE +S224015160AB43C9B2084018439061C2E1012001006268D3690125AB43C9B201401943D16103 +S22401518000216268D3690125AB43C9B208401843D061AEE1012001006268136A0125AB4373 +S2240151A0C9B201401943116200216268136A0125AB43C9B20840184310629AE101200100B5 +S2240151C06268936A0125AB43C9B201401943916200216268936A0125AB43C9B208401843C9 +S2240151E0906286E1012001006268136B0125AB43C9B201401943116300216268136B0125B7 +S224015200AB43C9B208401843106372E1012001006268536B0125AB43C9B20140194351632C +S22401522000216268536B0125AB43C9B20840184350635EE1012001006268136C0125AB431C +S224015240C9B201401943116400216268136C0125AB43C9B20840184310644AE1012001005E +S2240152606268536C0125AB43C9B201401943516400216268536C0125AB43C9B208401843E2 +S224015280506436E1012001006268936C0125AB43C9B201401943916400216268936C012521 +S2240152A0AB43C9B208401843906422E1012001006268136D0125AB43C9B2014019431165D7 +S2240152C000216268136D0125AB43C9B20840184310650EE1012001006268136E0125AB4346 +S2240152E0C9B201401943116600216268136E0125AB43C9B2084018431066FAE00120010009 +S2240153006268536E0125AB43C9B201401943516600216268536E0125AB43C9B2084018433B +S2240153205066E6E0012001006268936E0125AB43C9B201401943916600216268936E0125C9 +S224015340AB43C9B2084018439066D2E0012001006268D36E0125AB43C9B201401943D16603 +S22401536000216268D36E0125AB43C9B208401843D066BEE0012001006268136F0125AB4373 +S224015380C9B201401943116700216268136F0125AB43C9B2084018431067AAE001200100B5 +S2240153A062688023D3580125AB43C9B2014019438023D150002162688023D3580125AB4392 +S2240153C0C9B2084018438021505092E00120010062688423D3580125AB43C9B2014019430C +S2240153E08423D150002162688423D3580125AB43C9B208401843842150507AE0012001002F +S22401540062689023D3580125AB43C9B2014019439023D150002162689023D3580125AB4301 +S224015420C9B2084018439021505062E00120010062689C23D3580125AB43C9B201401943B3 +S2240154409C23D150002162689C23D3580125AB43C9B2084018439C2150504AE001200100B6 +S22401546062689423D3580125AB43C9B2014019439423D150002162689423D3580125AB4395 +S224015480C9B2084018439421505032E0012001006268C823D3580125AB43C9B20140194353 +S2240154A0C823D15000216268C823D3580125AB43C9B208401843C82150501AE00120010002 +S2240154C06268CC23D3580125AB43C9B201401943CC23D15000216268CC23D3580125AB438D +S2240154E0C9B208401843CC21505002E0FFF7B0FCFFE70020A1688022885031BDF0B5020059 +S22401550052B2002A16D41822AA4B040064B2A408A4001C59FF25C6001640B540AC438901B1 +S224015520C9B2C5002A409140214340B28008800019501BE00F25A04B1824020052B22A405D +S224015540083A92089200060076B23540083DAD08AD005D59FF26C7002740BE40B543890104 +S224015560C9B2C0000440A14029439950F0BD80B5411E80225204914201D301200EE0401E23 +S2240155808E49086003210020C043FFF7B7FF00208B4908600720BD490860002002BD00B54E +S2240155A0017A00290FD0417A00290CD101684268914208D20168491C0160016842689142CC +S2240155C001D10121417200BD10B5040084204001201803C80022401C514184225201A218ED +S2240155E003C2083AAA482018FFF7D9FFA9482018FFF7D5FFA8482018FFF7D1FF10BDA74809 +S224015600A74908607047A74803C8704780B5A6480168491C0160A34A03CA083A0023401C37 +S224015620594103C2083AA148FFF7CEFF01BDF8B594B000200020694608704CE001A928689B +S224015640FEF783FA42E001AE684600783070984D01A92868FEF7BCFA002837D0D0202058DA +S22401566069460978142251434018407A0128E5D101A92868FEF769FA01A92868FEF705FA79 +S2240156804820325C01A8010008318A4C98204001251828784C2358432018071D380000F0F1 +S2240156A043FA029829784C225143605028784C214843201844214822B25C42542878401C7B +S2240156C028702878202801D30020287068460078401C69460870784C68460078CC21615C7B +S2240156E08842B0D315B0F0BD70B5010000242000704B724A9D18982252019A5C2E78B242B2 +S22401570011D04C2228784C26704318180E000100300000F009FA2878401C28702878202891 +S22401572000D32C700120C0B270BDF0B593B000242300DBB22500EDB2E4B200E0641C5E4D13 +S2240157402600CC27EF5DF6B2BE420CD2D026AE59B4462700FFB2142677436646F6197668FC +S224015760B042EBD123002800D0306C4605681E00F6B214277E43AD5B257048256255006820 +S224015780DBB214246343C01840680190D2B2684604000834200000F0C7F9454C694620687D +S2240157A0FEF723F969462068FEF714F9002013B0F0BD000000E400E01CED00E014E000E088 +S2240157C018E000E0FEB500240294394FAF4E3000803038603500D83501220521280000F0DE +S2240157E013FA01220521280000F04EFA01220521280000F056FA3500D03505220021280092 +S22401580000F002FA05220121280000F0FDF92A4D2800FDF7F6FB0820CC2168549C48D02115 +S2240158206850012001002970210069702100A9702100E97030216C54C821685402AA0B21B3 +S22401584030000830FDF7ADF9687801280BD101200190FA20C00000908E4B8F4A02992800CA +S2240158601C30FEF7D8FA002001908C480090894B8B4A029928000830FEF7CDFA29003868D1 +S224015880FDF7D4FC092000F03DFAF7BD10E000E0901000009C100000A810000055AAAA5568 +S2240158A0F06300200020002048320020082000203C500020603C0020644F002001130000FE +S2240158C0F0B59BB000F014FA704800F021FA754800F082FB00F098FC7349002000F09CFEFD +S2240158E0724900200090724C009A200000F09EFED821002000906F4C009A200000F096FE91 +S224015900012603AC30002070022060703000A080694D03AA07212800FDF75CF930002070ED +S224015920A68003AA13212800FDF754F903AA14212800FDF74FF903AA15212800FDF74AF969 +S22401594003AA16212800FDF745F903AA17212800FDF740F9FFF736FF584C01220321200093 +S22401596000F052F901220321200000F08DF902220321200000F0E9F801220321200000F079 +S22401598090F94F4E01220B21300000F03DF901220B21300000F078F902220B21300000F0E6 +S2240159A0D4F801220B21300000F07BF901220521200000F029F901220521200000F064F901 +S2240159C002220521200000F0C0F800220521200000F067F93B4E3C49300000F04FFE3B4CF5 +S2240159E0220009212800FDF7DCF82068FA218900FDF747F9FFF7BBFD354800F083F900F07E +S224015A0069F914E008210025009501AF009A380000F00CFE2560082201A92E48FFF785FE83 +S224015A202D49002000F0F8FD300000F0F2FE2B4C20680028FBD07078022805D1FFF7DFFD29 +S224015A4023212748FFF716FA2068401E2060254C2068401C206024480168491C016008A801 +S224015A60FFF742FE0128DFD108982049884203D008981F498842C5D108A84421435C021D30 +S224015A80089930001830FEF7C9FFC9E7C4300020F49601004C1D000080841E00C409000083 +S224015AA020A10700443200209C9A010004130000603C0020644F0020CC300020A431002094 +S224015AC08C310020082000204000002054320020FFFF000022020000B49A0100483200208A +S224015AE0D43100204C3200205032002032070000DF07000070B4103A03D378C9103A78C015 +S224015B00FBD2530701D318C918C001D508C908C0D20704D30B880380891C801C002A01D555 +S224015B200B78037070BC70478B0701D18307E1D0124205D00B78491C0370401C521EF9D1CD +S224015B4070470000016042607047F0B51300122959D20200DBB2002B03D0022B38D01CD3FF +S224015B6051E000231E000C001568A00028580227B843F6B2760002273E400643A0002E50B4 +S224015B8010688A0082580124A243DBB21C00E407E40F14438900445035E001231E000C00BB +S224015BA01568A00028580227B843F6B2760002273E400643A0002E50002012688C0014595F +S224015BC00125AC43C0B203402343880013501AE000250800136884001C590226B443EDB24B +S224015BE06D0002263540254380001D500120030012688C0014590125AC43DBB2184020434C +S224015C0089005050FFE7F0BDF0B51300DBB2002B1BD10B0004689D0066591A4D3540D2B233 +S224015C201602E022D20032402A439B00E250012200688B00C3580424A343D2B29200042449 +S224015C4022401A43890042501AE000260C000568A300EB580427BB43F6B2B60004273E40B5 +S224015C601E43A300EE5000688B00C358054C1C40D2B21302E022D2001A40224389004250DA +S224015C80F0BD0000FFF8FFFF10B443685B6901248C40A343D2B28A401A434068426110BC90 +S224015CA0704710B443681B6801248C40A343D2B28A401A434068026010BC704700B5010070 +S224015CC049B2002905D40121C006C00E81400B48016000BD00B50A480168012906DB0168F5 +S224015CE0491E01600068012800DA62B600BD000072B603480168491C0160704700E100E07C +S224015D00C030002080B540B2FFF7D8FF01BD0000F0B58BB004007D4D2A007D49200000F00D +S224015D20E9FD7C480590069000200790089009900A90794E794F05A803900297784801904D +S224015D40784800903300784A784920000830FCF704FF77492000383000F0D0FD7549200006 +S224015D603C3000F0CDFD74492000403000F0C8FD72492000443000F0C5FD714A714920005F +S224015D80483000F0C1FD70492000543000F0C0FD6E492000583000F0BDFD6D4920005C3062 +S224015DA000F0BAFD32006B492000603000F0B6FD02206946087404A80390029501970096AC +S224015DC0594B574A644920008030FDF70BF9634920009C3000F09AFE2A0061492000A0301F +S224015DE000F0A2FE2A005F492000A83000F09FFE5D492000B03000F09DFE5C492000B430DC +S224015E0000F09AFE5A492000B83000F097FE59492000BC3000F092FE57492000C03000F0F6 +S224015E208FFE56492000C43000F08CFE544A55492000C830FFF786FE534A54492000D0307A +S224015E40FFF780FE524A53492000D830FFF77AFE514A52492000E030FFF774FE504A5149F8 +S224015E602000E830FFF76EFE00962E4B3A004E492000F03000F068FE2A004C49802040006D +S224015E80201800F0A7FE2A00494984204000201800F0A0FE244B224A244988204000201861 +S224015EA0FEF7E0FF43498E204000201800F0BEFE4149B2204000201800F0C2FE3F49B420CA +S224015EC04000201800F0BCFE2A003D49B6204000201801F08FF83B49BA204000201801F05D +S224015EE08DF83949BC204000201801F087F83749BE204000201801F081F83549C0204000F3 +S224015F00201800F067F80BB0F0BD00BF00F005400040024000127A0000E0064000E8064036 +S224015F2000F8064000E4064000F0064000F0074000400740003000400040004000C000400F +S224015F4000100240008000400090014000800140005000400000024000800340006006405C +S224015F6000200740003007400070074000500740000003400010034000D0004000600240A7 +S224015F80005003400000064040500340001006408050034000200640C050034000300640B7 +S224015FA0005103400040064000D0074000800540009005400080074000C0024000D0024035 +S224015FC000E0054000A0064000B0064000C0064000A007400160704700B5026801211268FA +S224015FE052090A40D2B2012A19D10D4A03685A600268126880239A4303681A60094A0368DA +S2240160009A6002681268D20A0A40D2B2002AF8D102681268520A0A40D2B2002AF8D000BD42 +S22401602020C528D9FFFF000010B5494C0320206160614848A0614849E1618021C900216266 +S2240160400021A1626162E1622066444860661020A0662167E166616741A1E01D00F0F2FFAB +S2240160604049200000F0EEFF2020A07110BDF8B584B004000D00160000200190E7682069E5 +S224016080874202D2C01B401E03E0A168C91B0818401EA168C91B884201D3A068C01BB04276 +S2240160A001D2009000E000966068C0190099039129000290039A0298FFF736FD02980198E5 +S2240160C000994018019000982D180098361A00983F18A068874200D10027E760002ECED1A7 +S2240160E0019805B0F0BDF8B504000F001500E668A068801B0090009885420AD260688019AD +S2240161002A00390007003800FFF70EFD7019E06010E0009A6068861939003000FFF704FDBC +S22401612000982D1A66682A00009839183000FFF7FBFCE560F1BD00B50169C2688A4204D39D +S2240161408068401E801A401801E0881A401E00BD40500020A89A0100E8500020E8540020BC +S22401616052545400C49A0100F8B516000F002549182250430818050018356869002803D075 +S22401618002281DD00ED322E02800FFF7D4FFB04201D2002405E03400320039002800FFF783 +S2240161A0A2FF15E02800FFF7C6FFB04201D2040000E03400220039002800FFF794FF07E090 +S2240161C0320039002800FFF752FF040000E000242000F2BD70B504000D00160009480078F3 +S2240161E0002801D1FFF720FF320029002000EFF31084012383F31088FFF7B6FF84F31088AD +S22401620070BD00004050002080B5FFF70DFF01BD10B50400A26863681000401C834206D3FE +S22401622020688154521CA260E068401CE060A068616888420DD1A26821682069FFF7CAFF53 +S224016240A168884203D00020C043E06001E00020A06010BDF7B582B005001F00039801249F +S224016260012603E00499FCF70CFD761C04998842F8D2BE4200D23E0001950A9D0B98C007FB +S2240162801BD4002D19D00B98800705D5002F03D130206946087002E0202069460870002DFF +S2240162A00BD0AE4209D26D1E684601780198FFF7AFFF0198C0680028F1D50198C0680028AB +S2240162C039D402E07F1E04984443022FFAD203982100FCF7D6FC04998842F4D203982100A2 +S2240162E0FCF7CFFC0100039A08006043101A03901248415C0198FFF78BFF0198C0680028DB +S22401630007D420000499FCF7BCFC0400002CE5D1FFE70B98C0070ED5002D0CD0002D0AD00B +S224016320AE4208D26D1E20210198FFF771FF0198C0680028F2D505B0F0BD00008C9A010089 +S224016340F1B584B00E001D00002E01D5704200E030000124039203E00399FCF78FFC641C35 +S22401636003998842F8DA02950298844200D2029C0A9D0B9F002D04D0002E01D4780700D5CF +S2240163806D1EB80702D50298002810D0F8070ED4002D0CD0002D0AD0AC4208D26D1E2021AF +S2240163A00498FFF735FF0498C0680028F2D50498C068002834D4002E06D5704206002D215B +S2240163C00498FFF725FF05E0780703D52B210498FFF71EFF0498C068002821D4B807800F9B +S2240163E0022811D1029800280ED1002D0CD0002D0AD0AC4208D26D1E30210498FFF708FF9D +S2240164000498C0680028F2D50498C068002807D401970095029B039A31000498FFF71AFFB9 +S22401642005B0F0BDF1B598B00C00160007A802904020039000270497189806900597217873 +S224016440641C0800C0B2002808D00800C0B2252800D0C7E038000122110000E0CAE023786D +S224016460DBB2232B13D02B2B0CD02D2B02D0302B03D011E01043641C0FE00300022018439B +S224016480641C0AE0030004201843641C05E0030008201843641C00E039000029DFD13A0073 +S2240164A005E0641C0A235A43C9B25218303A21780B00DBB2303B0A2BF3D33B002178C9B272 +S2240164C02E290DD1641C05E0641C0A256B43C9B25B18303B21780D00EDB2303D0A2DF3D3B7 +S2240164E0217801E0641C21780D00EDB26C2DF9D00D00EDB2682DF5D0C9B225296BD058296A +S22401650034D063290AD0642914D0702952D073293AD075291CD0782928D061E030683060AD +S224016520306801683068001D3060C9B202A8FFF76FFE55E0316831603168096835682D1D37 +S2240165403560019000920A2202A8FFF7F9FE47E0316831603168096835682D1D3560019052 +S22401656000920A2202A8FFF775FE39E0316831603168096835682D1D356001900092102226 +S22401658002A8FFF767FE2BE030683060306805683068001D306029786D1C0800C0B20028A7 +S2240165A007D0C9B202A8FFF733FE05980028F2D5FFE715E030683060306801683068001D6D +S2240165C0306000200190082000900823102202A8FFF740FE04E0252102A8FFF719FEFFE7BA +S2240165E0641C03E0C9B202A8FFF712FE0598002800D424E7059801280BDB0498002804D01F +S224016600049A07A91898FFF7E5FD0598049940180590059819B0F0BD0CB480B502AA009231 +S2240166206A46FFF7FFFE019904B008471206130A1A43130C1A4300BF094205D0830705D0C8 +S2240166400270401C491EF9D1704700001300103906D330B41400150010393CC0FCD230BC3D +S224016660490700D30CC000D504C0890002D30280801C002900D502707047000010B5040020 +S224016680200000F08DF80548A0600548E0600F206060044820610620A08210BD9497010088 +S2240166A0AC990100C801002080B5080000F028FD01BD40780870704780B5080000F029FD5B +S2240166C001BD80B5080000F0FFFC01BD80B5080000F0F2FC01BD80B5080000F0FDFC01BD53 +S2240166E00021016041600A000272417270470022026041600121017242727047407A7047F3 +S224016700FEB505000E001400082100226F463800FFF78CFF2000C0B2782805D06F48295A9F +S2240167206F482818FFF7E3FF7920285C002814D02000C0B211280FD02000C0B212280BD00A +S2240167402000C0B2312807D02000C0B27E2803D02000C0B27F2800D10AE068467F210170B3 +S224016760467084700322694628001830FEF7DDF8F7BD10B50022130000E0521C13009BB2FF +S2240167804468A3420AD283681400A4B2E4001B5D0C00E4B2A342F0D1012000E0002010BD9F +S2240167A070B505000C00210028001830FEF78DFA0120687000263000A870300078216854A4 +S2240167C00020002184225201AA1803C2083AA08D44496852E08D44496852208E3F49685298 +S2240167E042482818FFF77CFF41482818FFF778FF3B482818FFF774FF3000300004E0310081 +S2240168002A187B23D154401C802149018842F6D370BD7CB504000025280069468880280005 +S2240168202800280020001830FEF79BFA01A8009080235B0122007B322100793120001830D6 +S224016840FEF712FA40B2002839D17B20265C3100C9B22000FFF78DFF00282AD02B0000E075 +S2240168605B1C606883422AD2A068D900405C3100C9B28842F4D1A068D90040188078002801 +S22401688006D07C20205CC0B2C0097821605402E028007821605418007A2160546846828806 +S2240168A021007B312000A668DB00F3185B68984705E011223100C9B22000FFF721FF084805 +S2240168C02018FFF71BFF012806D101206070A57003482018FFF704FF73BD00008C1000001C +S2240168E0A8100000881000008A100000901000009C1000000160426070470000016070478A +S2240169000160704701607047416082607047000001607047016070470160704738B50400CE +S224016920216062600025A560E0208002E060802040052061802000026061200000F0C8F889 +S2240169402076E561207E002800D06561200000F001F831BD30B401221300046800210D004E +S224016960DBB25B0002252B402360130004680D00DBB21B0110252B402360130004680D0030 +S224016980DBB25B0120252B402360130004680D00DBB29B0140252B402360130004680D0041 +S2240169A0DBB2DB0008252B4023600068D2B2910004221140016030BC704730B5010000234D +S2240169C01800012214000D68E4B2E301802423402B600B681B68DB091340DBB2002BF8D034 +S2240169E00B681B685B091340DBB2002B0CD10B681B681B091340DBB2002B05D10968096872 +S224016A001140C9B2002900D01000C0B230BDF6B583B001000024200022006A46127C402A4F +S224016A2000DB01200293029A002A00D1012000910100C9B2002935D100980068012500683D +S224016A40C10928000840C0B2002801D1022029E00098FFF77FFF08232100009802682000E5 +S224016A60FF2001900E00F6B29619367F019FBE43DBB2019F1F403743C9B251180F77694686 +S224016A80097C009A126823002B00DBB2D3181B7F8343C9B208401843EDB2511908770098F3 +S224016AA0FFF78BFF0100C9B200290ED121000AE00A00D21D009B1B682500D2B29A18127FBE +S224016AC0029B5A54491C0829F2D3C0B205B0F0BD3EB5050008220021684600F03BFB0020FF +S224016AE00400FF20694608706B46002200212800FFF78DFFC0B2002804D16846007880078C +S224016B0000D401242000C0B23EBD0000016000210168CA6E01239A43CA660068016C0A00B6 +S224016B20D207D20F006C7047016042607047016042607047016070470160704701607047B6 +S224016B40016070470160704710B4019C016042608360C46010BC704702692F4B1340C9B25E +S224016B600A06F0210905114019430161704702692A4B1340C9B20A04F02109031140194394 +S224016B80016170470269264B1340C9B20A02F0210901114019430161704702690F239A43C5 +S224016BA0C9B20907090F11430161704742691C4B1340C9B20A02F021090111401943416169 +S224016BC0704742690F239A43C9B20907090F11434161704738B5050029606A60002408E09D +S224016BE01048210089B2425C0C21280000F006F8641C200080B20628F2D331BD80B51300FF +S224016C00DBB2062B06DAC9B24068074BD2B292009A58904701BD0000FFFFFFF0FFFFF0FFE4 +S224016C20FFF0FFFFBC9A0100749A0100016000210171417128228154382281547047000050 +S224016C40016001680A6980235B0013430B6101680A6980239B0013430B61012101680A6957 +S224016C60022313430B6100BF00BF00BF002100680161704730B50200002318001C00491EA3 +S224016C8017D0491E1CD0FE3922D080256D00491B26D08025AD00491B2AD08025ED00491B79 +S224016CA02ED080252D01491B32D07B4D491B37D03EE0116849690C00E407E40FE4B237E084 +S224016CC01168496949080C00E407E40FE4B22FE011684969090A0C00E407E40FE4B227E0DE +S224016CE011684969490A0C00E407E40FE4B21FE011684969890A0C00E407E40FE4B217E05C +S224016D0011684969C90A0C00E407E40FE4B20FE011684969090B0C00E407E40FE4B207E05A +S224016D2011684969090E0C00E407E40FE4B2FFE7002C00D00120C0B230BD0000FEB582B044 +S224016D40070001240026300038683200C06DC006C00E1022101AC0B26A46928980B290427B +S224016D6000D292E0684601700196350030003868006E0190002101A800F003F9012101A88E +S224016D8000F0F1F8002101A800F014F9002101A800F002F968460078C100491E89B201A866 +S224016DA000F01EF9019839680866300013E039684B6F0A99020092B292008B500AE06946B1 +S224016DC009780229F3D139684B6F0A99020092B252008B52401C01006A46928989B2914294 +S224016DE047D23A683100012153690A001A40D2B2002A04D16D1C294A9542F2D334006A4660 +S224016E001278012A06D1049A03009BB2D25C3B685A6612E06A461278022A07D1049A030090 +S224016E209BB25B00D25A3B685A6606E0049A03009BB29B00D2583B685A6635003B6832000F +S224016E401B6F5B080B40002B00D00A00D2B2002A04D06D1C114A9542F0D33400694609788B +S224016E600129ACD13968496F0A9A03009BB2D154B0E7002101A800F084F8002101A800F06C +S224016E8072F801983968086600E034002000C0B205B0F0BD0000000000F0FF00E9030000F7 +S224016EA010B502000B00002108005B1E14D05B1E1CD0FE3B23D0802464001B1B29D0802408 +S224016EC0A4001B1B2FD08024E4001B1B35D0802424011B1B3BD044E001231C001268080020 +S224016EE091692140A14200D118003AE002231268080091691940994200D1012031E08023D0 +S224016F005B001268080091691940994200D1012027E080239B001268080091691940994279 +S224016F2000D101201DE08023DB001268080091691940994200D1012013E080231B01126810 +S224016F40080091691940994200D1012009E080235B011268080091691940994200D1012079 +S224016F60FFE7C0B210BD00B50268C9B2012904D1802189031143016002E015491140016079 +S224016F8000BD0268134B1340C9B2090580225203114019430160704700B50268C9B201290A +S224016FA004D1802109031143016002E00A491140016000BD00B50268C9B2012904D18021B6 +S224016FC0C9021143016002E004491140016000BDFFFFDFFFFFFFEFFFFFFFF7FFFFFFFBFFD9 +S224016FE00268120B120389B20905090D1143016070470000016042607047000001600168A0 +S224017000CA6A80231B021343CB6200BF00BF00BF00BF0A4B1340CB620168CA6A8023DB0106 +S2240170201343CB6200BF00BF00BF00BF044B1340CB6200210068016070470000FF7FFFFFDF +S224017040FFBFFFFF31B48B0707D00B780370002B20D0401C491C8B07F7D1164CE501830722 +S22401706022D104C9131B93432B4205D104C004C9131B93432B42F9D0FF231A42027009D06F +S224017080120A1A42427005D0120A1A42827001D0120AC27031BC70470270120A4270120A62 +S2240170A08270120AC270001D04C9131B93432B42F2D0E1E70101010110B50400102222493B +S2240170C02000FEF731FD10BD10B50400C02104222000FEF729FD10BD70B504000C221B4D03 +S2240170E02900103126003000FEF71EFD0822291D25000C352800FEF717FD2020E07270BDF4 +S22401710010B50400C0200822011D2000FEF70CFD10BD10B50400C020082201002831200040 +S224017120FEF702FD10BD80B50020009003230622C021012000F01FF801BD80B523210448C9 +S224017140FDF798FE01BD0000E0000100C0000100D431002010B50400080011000200200016 +S224017160FFF764FA200010BD80B500214006400E00F030F802BDF1B582B00C0017001D00EF +S224017180089E6846007AFFF7EFFF002E00D03080A0432900C9B2B9400143C9B26846027A20 +S2240171A080201043C0B200F015F86846007A69460870EDB2BD40684685706846007AFFF7BB +S2240171C0D3FF0440684680784440684644700098FEBD00001CB50E4B187059700D4C00944C +S2240171E0022201210C48FFF7A9FD207800026178084380B216BD10B5074C02212000FFF73F +S22401720039FD012803D102212000FFF749FE10BDF854002004550020283200200022026005 +S2240172204160012101724272704770B504000E0015003448215A34482018FFF7EFFF782034 +S224017240205C012806D02A00310092B220001830FDF76BFB70BDFEB505000E00140008211C +S22401726000226F463800FFF7E1F92000C0B2782805D02448295A24482818FFF7CFFF79202A +S224017280285C002814D02000C0B211280FD02000C0B212280BD02000C0B2312807D0200025 +S2240172A0C0B27E2803D02000C0B27F2800D10AE068467F2101704670847003226946280084 +S2240172C01830FDF732FBF7BD7CB56C46AE4D2E682660DBB2042B14D3069C0B0004210D000F +S2240172E0258014008078DBB2834204D100222000FFF79CF905E068460A0001002000FEF730 +S22401730013FC73BD8C100000A810000001207047F8B584B006000C0015000020082100208B +S224017320009002AF009A3800FFF780F900206946C880002000202800B1687A22B25CD200B1 +S2240173408918497880B289B2884205D2132227213000FFF780FF14E17078012805D1222275 +S22401736027213000FFF777FF0BE184204001301803C8FA22D2000023994208DC01DB9042C1 +S22401738005D2372227213000FFF765FFF9E0200041784906490E6A46117167216A461172A0 +S2240173A06946097902AA517069460979C90776D500273800754908703C0000E0641C20008C +S2240173C0C0B2042833DA724D684600792100C9B20901695C8842F1D12000C0B2000128184C +S2240173E080782100C9B209016918497888421ED28420400130180CC808382000C0B2000119 +S2240174002818083003C8121A8B41624800218B4208DC01DB824205D2362227213000FFF772 +S2240174201AFFAEE02000C0B2000128184770E4B2042C05DB312227213000FFF70CFFA0E023 +S224017440062301A8801C0090DBB202A8821C684601793000FFF738FF6846C088002818D0C8 +S2240174606846C288921C92B202A93000FFF7DDFE68460079454908706846C0884649088036 +S2240174806846C28802A8811C444C2000FEF74CFB77E0312227213000FFF7DDFE71E03B4CF0 +S2240174A0694609792278521C914205D0242227213000FFF7D0FE64E0AD1EADB20095831CC1 +S2240174C03548028835492078FFF720FFC0B2012821D1022202A93000FFF7A7FE002001002C +S2240174E0217069460979491EB17001000A00D2B2042A46DA264A6B461B790C00E4B22401E3 +S224017500145DA34205D103000C00E4B2240112195370491CEAE7352227213000FFF79BFEED +S22401752000232AE01A4A20781900C9B20901515C884221D11800C0B2000110184078401C4E +S2240175401900C9B20901511848701800C0B20001101880781900C9B2090151184978884229 +S2240175600AD284204001301803C81D00EDB22D015219083203C2083A5B1C1800C0B204286E +S224017580D0DB05B0F0BD0000CC9A01006B55002000000020102700006855002010550020D8 +S2240175A0002202604160012101724272704770B504000E0015002548215A25482018FFF7D1 +S2240175C0EFFF7820205C012806D02A00310092B220001830FDF7A9F970BDFEB505000E0014 +S2240175E01400082100226F463800FFF71FF82000C0B2782805D01548295A15482818FFF7B2 +S224017600CFFF7920285C002814D02000C0B211280FD02000C0B212280BD02000C0B2312831 +S22401762007D02000C0B27E2803D02000C0B27F2800D10AE068467F210170467084700322E0 +S224017640694628001830FDF770F9F7BD8C100000A810000000B50028FFD000BD00B500285A +S224017660FFD000BD00B50028FFD000BD00B50028FFD000BD00B50028FFD000BD00B5002860 +S224017680FFD000BD00B50028FFD000BD00B50028FFD000BD00B50028FFD000BDF3B5FFB0C6 +S2240176A086B0060014000025039528002800280028000320694608708020800001902A00F2 +S2240176C005AF01993800FEF7B1FF2800694608812000B1687A22B25CD2008918497880B2D0 +S2240176E089B2884205D2132231213000FFF775FFE5E0869841784906490E6A4651708178DB +S2240177000902C2788918241F6A4694806A469288002A01D0001D03902C0000E0641C200055 +S2240177206A461278C0B2904229D266482200D2B214235A43825A0B009BB29A42EED17178EA +S2240177402200D2B214235A4382189278914222D12100C9B2142251434118C97800290ED038 +S2240177602100C9B2142251434018C078B178884205D0332231213000FFF72FFF9FE02000AB +S22401778069460978C0B288420BD3312231213000FFF723FF93E0222231213000FFF71DFF61 +S2240177A08DE08020800004902A0005AF04993800FEF73CFF68464078012804D066D30328F8 +S2240177C04CD027D362E03F4D02A8009080239B0005AA68468188039884462700FFB2142070 +S2240177E04743E81987686046B8470120E4B214214C43291908716846008904284CDB6846F6 +S224017800007D712848D16846028905A93000FFF7CEFE54E02B482100C9B2142251434018F5 +S2240178200079002819D002A8009080239B0005AA6846818803980190224884462700FFB2A2 +S224017840142047436046C019C7680198B8471D48E4B214214C4300190571CCE7194D200097 +S224017860C0B2142148432818007900280DD002A8009080239B0005AA684681880398E4B203 +S22401788014277C432C192469A047B4E7122231213000FFF7A2FE12E068460089032809D11A +S2240178A005A801787F2905D1827831213000FFF794FE04E0242231213000FFF78EFE7FB0BD +S2240178C008B0F0BD8C010020002202604160012101724272704770B504000E001500AE4829 +S2240178E0215AAE482018FFF7EFFF7820205C012806D02A00310092B220001830FDF715F8DA +S22401790070BDFEB505000E001400082100226F463800FEF78BFE2000C0B2782805D09E48B7 +S224017920295A9E482818FFF7CFFF7920285C002814D02000C0B211280FD02000C0B2122835 +S2240179400BD02000C0B2312807D02000C0B27E2803D02000C0B27F2800D10AE068467F2137 +S2240179600170467084700322694628001830FCF7DCFFF7BDF6B5FFB082B00500002000204F +S2240179800026002000200027802189000020009001AC009A2000FEF749FE82A80088A96814 +S2240179A07A22AA5CD2008918497889B2884205D2132222212800FFF7A4FFEAE082A800885A +S2240179C0401EC00705D5132222212800FFF799FFDFE082A80088400880B2002805D1132256 +S2240179E022212800FFF78DFFD3E0622001A9320092B28854761C01206946088079E03000F0 +S224017A0080B22969220092B214235343C91889894018801C6249884200DB9FE02869210001 +S224017A2089B214224A4380188078052800D19BE068782969220092B214235343C918C97872 +S224017A40884200D290E02869210089B214224A4380188289D2B22869210089B214234B438B +S224017A60C018816828002F69BC462700BFB214237B436746FB181B699847012701A88199E2 +S224017A806A461288895C320092B28154761C81996A46128889184978320092B28154761C31 +S224017AA0684646802869210089B214224A43801882892869210089B214234B43C018816886 +S224017AC001A86B465B88C6183000FEF72DF8684640882969A4B214226243891889894618F1 +S224017AE03800C0B2002845D068460088801C694608806846008882A9098888423AD28198AF +S224017B0069460988405C000281996A4612888918497808430024270000E0641C2100AA8A70 +S224017B2089B29142DCD22969220092B214235343C95A020092B29142EFD1A87829692200EE +S224017B4092B214235343C9180979884200D156E7332222212800FFF7D4FE1AE014222221D8 +S224017B602800FFF7CEFE14E0222222212800FFF7C8FE0EE0FFB2002F06D0320092B201A9F2 +S224017B802800FFF7A8FE04E0312222212800FFF7B8FE7FB004B0F0BD8C100000A8100000E9 +S224017BA001020000002202604160012101724272704770B504000E0015009548215A954816 +S224017BC02018FFF7EFFF7820205C012806D02A00310092B220001830FCF7A7FE70BDFEB5F1 +S224017BE005000E001400082100226F463800FEF71DFD2000C0B2782805D08548295A8548ED +S224017C002818FFF7CFFF7920285C002814D02000C0B211280FD02000C0B212280BD02000C0 +S224017C20C0B2312807D02000C0B27E2803D02000C0B27F2800D10AE068467F210170467028 +S224017C4084700322694628001830FCF76EFEF7BD7047704770477047F6B5FFB082B0040067 +S224017C600D00002630003000300002206946087080218900320001AF3800FEF7D7FC82A8BC +S224017C800088A1687A22A25CD2008918497889B2884205D213222F212000FFF7A0FFB3E0D6 +S224017CA06078012805D122222F212000FFF797FFAAE028004178090282788918C2786B46AB +S224017CC05A70350000E06D1C2A006B461B78D2B29A4220D2504A2B00DBB214277B43D35AFE +S224017CE00F00BFB2BB42EED12900C9B2142359435118897800290ED02900C9B214235943E3 +S224017D0051188978A278914205D033222F212000FFF765FF78E029006A461278C9B2914209 +S224017D2005D331222F212000FFF759FF6CE001A96F220A7042784A7082788A70C278CA7077 +S224017D4069464978002902D003291BD057E032482900C9B2142251434118CE722900C9B23F +S224017D60142251434118096900290AD0EDB214214D43401900698047042201A92000FFF792 +S224017D8018FF41E0244E82A909882A00D2B214235A43B218127A121D914205DA22222F212A +S224017DA02000FFF71CFF2FE001212A00D2B214235A43B218D1722900C9B2142251437118D5 +S224017DC00A7A011D2800C0B214235843301847683800FDF7A9FE2800C0B214214843301823 +S224017DE0C06800280AD0EDB2142045437019C0688047042201A92000FFF7DBFE04E031228A +S224017E002F212000FFF7EBFE7FB004B0F0BD00008C100000A810000064010020010005009E +S224017E2000000000000000000000000003000500000000000000000000000000110005001E +S224017E400000000000000000000000006300050000000000000000000000000001000000B3 +S224017E6032070000DF070000B20700005832002000020000583400200808000000000000BC +S224017E802B570100075601003200F401881300001A62040050000000000000001B630400E7 +S224017EA050000000000000001603F00050000000000000001703F0005000000000000000B9 +S224017EC08873C00050000000000000000100C10050000000000000000101C100500000006C +S224017EE0000000000121C10050000000000000000127C10050000000000000000128C10026 +S224017F0050000000000000000129C10050000000000000000131C10050000000000000008D +S224017F200041C10050000000000000000151C10050000000000000000063C1005000000012 +S224017F40000000000069C10050000000000000000181C10050000000000000000136C20015 +S224017F6050000000000000000064C10050000000000000000067C1005000000000000000BE +S224017F8092F000001855002002000000517C0100537C010020F000001A550020020000008B +S224017FA0557C0100577C010000FF030100000000557601005D7601006576010001FF030192 +S224017FC0000000006D760100757601007D76010002FF030100000000857601008D760100D2 +S224017FE09576010086F10601000000002855002001000000B366010087F1060100000000BA +S2240180002955002008000000B966010080F10601000000003155002008000000A96601005E +S22401802093F10601000000003955002004000000C366010095F10601000000003D55002094 +S22401804010000000CD66010091F10601000000004D55002018000000D766010088490870EC +S224018060704730B5010089B2142927DA0021854A0B000400A4B20C256543541923710300B2 +S2240180809BB20C245C4313191B1D1C78102525431D7003009BB20C245C4313191B1D1C7885 +S2240180A0402525431D7003009BB20C245C431319D98080B20C234343D018017230BD30B5A8 +S2240180C0010000221000100010000DE06D4B1400A4B20C2565435B191B795B065B0EDBB200 +S2240180E00B4200D0401C521C13009BB2142BEDDB80B230BDF2B501000023180018001800FA +S22401810023E01E00B6B20C277743EE59360C0700BFB2CE55401C1E00B6B20C277743EE59A9 +S224018120360A0700BFB2CE55401C1E00B6B20C277743ED590600B6B28D55401C6406640EC1 +S2240181400500ADB24C55401C5B1C1C00A4B2142C11DA4C4D1C00A4B20C266643AC1924795C +S2240181602600F6B21642EFD06E4636880700BFB23F1DBE42C5DA80B2F2BDF0B50200002384 +S22401818018001800180023E01E00B6B20C277743EE59360C0700BFB2D655401C1E00B6B20D +S2240181A00C277743EE59360A0700BFB2D655401C1E00B6B20C277743ED590600B6B2955535 +S2240181C0401C6406640E0500ADB25455401C5B1C1C00A4B2142C0DDA2A4D1C00A4B20C26CD +S2240181E06643AC1924790E00B6B20700BFB23F1DBE42C9DA80B2F0BD10B50024210022492D +S224018200401A04D09D3817D02F382CD035E00EE01C48210089B20C224A43805880214903C8 +S224018220884203D2200080B2FFF71BFF641C200080B21428ECDB20E010E01248210089B2BC +S2240182400C224A438058114940188021C903884203D2200080B2FFF704FF641C200080B2AA +S2240182601428EADB09E004E0200080B2FFF7F9FE641C200080B21428F6DB10BD000000003F +S2240182806A5500207400002033FFFF000000C0FF002202604160012101724272704770B52B +S2240182A004000E0015002548215A25482018FFF7EFFF7820205C012806D02A00310092B26E +S2240182C020001830FCF731FB70BDFEB505000E001400082100226F463800FEF7A7F920001D +S2240182E0C0B2782805D01548295A15482818FFF7CFFF7920285C002814D02000C0B211285C +S2240183000FD02000C0B212280BD02000C0B2312807D02000C0B27E2803D02000C0B27F28CB +S22401832000D10AE068467F210170467084700322694628001830FCF7F8FAF7BD8C1000009A +S224018340A81000008020704710B5010000200200012200E0521C1300DBB2052B08DA0423D6 +S2240183609B1ADB000C00DC40002CF3D00520801AC0B210BDF8B584B0040013000022100028 +S22401838015001500160016001600160016006778012F05D1222234212000FFF796FF8EE0A8 +S2240183A09C46A7687A23E35CDB00FB185B786746BFB29BB29F4205D2132234212000FFF766 +S2240183C084FF7CE00191019989780907090F6B46197001998978C9B209096B4659706946D8 +S2240183E0097800290BD069460978052907D269464978002903D069464978052905D3312286 +S22401840034212000FFF761FF59E0110007E00002019B0F00FFB2DB19DB78C018491C0B006D +S2240184206F463F78DBB2BB42F1D30AE02902019B6D462D781700FFB2ED195B19DB78CD18F9 +S224018440521C11006B465B78C9B29942EED3002D05D1222234212000FFF737FF2FE000F015 +S22401846087F8280000F087F8012000F08AF8FFF769FF05002800FFF767FF02A974223300F2 +S2240184809BB2CA54761C320003011600B6B28B55521C012308E0C61AF7002E00FE40170071 +S2240184A0BFB2CE55521C5B1C06001F00F6B2FFB2BE42F0D292B202A92000FFF7F0FE05B055 +S2240184C0F0BD0000002202604160012101724272704770B504000E0015007948215A79487B +S2240184E02018FFF7EFFF7820205C012806D02A00310092B220001830FCF717FA70BDFEB55C +S22401850005000E001400082100226F463800FEF78DF82000C0B2782805D06948295A694890 +S2240185202818FFF7CFFF7920285C002814D02000C0B211280FD02000C0B212280BD0200097 +S224018540C0B2312807D02000C0B27E2803D02000C0B27F2800D10AE068467F2101704670FF +S22401856084700322694628001830FCF7DEF9F7BD55490860704755490860704753480068C2 +S22401858070475349087000200100524A11700100514A11705149086070474D480078704732 +S2240185A04E4800687047F0B5FFB082B004000E00150000221000694608808021890001AF10 +S2240185C03800FEF733F86078012805D1222236212000FFF794FF6EE028000100A2687A2304 +S2240185E0E35CDB00D218527889B292B2914205D2132236212000FFF782FF5CE03449097821 +S224018600012902D002294BD050E0334972780A70304B0A781D78AA420BD00A781D786D1C09 +S224018620EDB2AA4205D0732236212000FFF767FF41E001AA76256F463F88D5556D462D88F7 +S2240186406D1C77782E00B6B297556D1C2A000D781E78B54205D192B201A92000FFF739FF43 +S22401866029E01E4D194E3768BC462F680600B6B2BE19B61E6746B74205D271223621200041 +S224018680FFF73DFF17E02E6880B2801E301828600878187092B201A92000FFF71AFF0AE066 +S2240186A0312236212000FFF72AFF04E0242236212000FFF724FF7FB002B0F0BD0000000083 +S2240186C08C100000A81000001C550020205500206D5500206F5500206E55002024550020D8 +S2240186E0002202604160012101724272704770B504000E0015007848215A78482018FFF7DA +S224018700EFFF7820205C012806D02A00310092B220001830FCF709F970BDFEB505000E0063 +S2240187201400082100226F463800FDF77FFF2000C0B2782805D06848295A68482818FFF755 +S224018740CFFF7920285C002814D02000C0B211280FD02000C0B212280BD02000C0B23128E0 +S22401876007D02000C0B27E2803D02000C0B27F2800D10AE068467F2101704670847003228F +S224018780694628001830FCF7D0F8F7BDF2B582B0040015000821002632006F463800FDF7F1 +S2240187A045FF3000A0687A21615CC90040184078ADB280B2854205D2132228212000FFF743 +S2240187C0ACFF86E06078012805D1222228212000FFF7A3FF7DE0029841784906490E807818 +S2240187E06A46682313705170C9B2002905D0022936D01BD303294DD066E00100C9B2012927 +S22401880006D00100C9B2022902D0C0B2032807D133480670022269462000FFF768FF04E069 +S224018820312228212000FFF778FF52E00100C9B2012906D00100C9B2022902D0C0B2032845 +S22401884008D1012026490870022269462000FFF74EFF04E0312228212000FFF75EFF38E0F0 +S2240188600100C9B2012906D00100C9B2022902D0C0B2032808D102201949087002226946B8 +S2240188802000FFF734FF04E0312228212000FFF744FF1EE00100C9B2012906D00100C9B2BA +S2240188A0022902D0C0B2032808D103200C490870022269462000FFF71AFF04E031222821CD +S2240188C02000FFF72AFF04E0122228212000FFF724FFF7BD000000008C100000A8100000B1 +S2240188E06C550020010101002B010100D901010000000000F9010100CD0201004D04010069 +S224018900A10401005B050100AF05010075060100C906010089070100DD0701009708010033 +S224018920EB080100A5090100F9090100B90A0100090B0100670B01009F0B0100CB0B0100BD +S224018940050C0100350C0100CF0C0100750D0100CB0E0100AD11010000000000B5110100FE +S224018960D7110100FD1101001F12010045120100000000004F120100971201002913010026 +S2240189804F130100751301009B130100C1130100E71301000D14010033140100591401008E +S2240189A07F140100A514010073150100BF1601001B170100E11701003D180100F118010078 +S2240189C02719010075190100AB190100F3190100291A0100751A0100AB1A0100F31A010047 +S2240189E0291B0100751B0100AD1B0100F51B0100131C0100391C0100571C01007D1C01002D +S224018A009B1C0100C11C0100DF1C0100051D0100231D0100491D0100671D01008D1D0100C3 +S224018A20171E0100F71E0100151F01003B1F01008B1F01001120010061200100F1200100E3 +S224018A4041210100C7210100172201009D220100ED22010073230100C32301004D240100CA +S224018A60DB240100A5250100A9250100CF250100ED2501001326010031260100572601003E +S224018A8077260100A1260100C1260100EB2601000B27010035270100552701007F270100BC +S224018AA00000000087270100000000008F2701000000000097270100F5270100D128010074 +S224018AC02F2901000B2A0100392A01008B2A0100B92A0100112B0100312B010000220260E5 +S224018AE04160012101724272704770B504000E0015002548215A25482018FFF7EFFF78207A +S224018B00205C012806D02A00310092B220001830FBF70BFF70BDFEB505000E0014000821A1 +S224018B2000226F463800FDF781FD2000C0B2782805D01548295A15482818FFF7CFFF7920CD +S224018B40285C002814D02000C0B211280FD02000C0B212280BD02000C0B2312807D020004C +S224018B60C0B27E2803D02000C0B27F2800D10AE068467F21017046708470032269462800AB +S224018B801830FBF7D2FEF7BD8C100000A8100000F2B582B00400150000263000300008211C +S224018BA032006F463800FDF741FD2800A1687A22A25CD2008918497880B289B2884205D251 +S224018BC013222E212000FFF7A6FF7BE0029841780902827811436A466E2313704378537007 +S224018BE08378937000E0761C3200A38A92B29A4263D2226933009BB214275F43D25B0B002B +S224018C009BB29A42EFD12169320092B214235343C918097900290FD0A178226933009BB209 +S224018C2014275F43D2191279914205D0332222212000FFF770FF45E0ADB2E91E22693300CD +S224018C409BB214255D4352199289914205D013222E212000FFF75FFF34E02169320092B2AE +S224018C6014235343C9188978032909D06178226933009BB214255D435219D278914205D21E +S224018C8022222E212000FFF746FF1BE02169320092B214235343C9188A89C11C2069B6B256 +S224018CA014237343C01885682800FCF73DFF032269462000FFF719FF04E031222E212000FD +S224018CC0FFF729FFF7BD0000002202604160012101724272704770B504000E0015002548DE +S224018CE0215A25482018FFF7EFFF7820205C012806D02A00310092B220001830FBF715FE4B +S224018D0070BDFEB505000E001400082100226F463800FDF78BFC2000C0B2782805D015482F +S224018D20295A15482818FFF7CFFF7920285C002814D02000C0B211280FD02000C0B21228AA +S224018D400BD02000C0B2312807D02000C0B27E2803D02000C0B27F2800D10AE068467F2123 +S224018D600170467084700322694628001830FBF7DCFDF7BD8C100000A8100000F8B5FFB05F +S224018D8081B005000C00170000221000100010001000802189006E463000FDF747FC380095 +S224018DA0A9687A22AA5CD2008918497880B289B2884205D2132219212800FFF7A2FF5EE04C +S224018DC020007F26417831406C46592222706170C9B2012904D002291DD00A2934D049E01D +S224018DE0BFB2032F05D0132219212800FFF789FF45E08078C0B2FFF762F9A6700121E17077 +S224018E00010089B2090A21716071062269462800FFF761FF33E0BFB2032F05D0132219214B +S224018E202800FFF76EFF2AE08278A670D2B2FF21FE31E01CFFF75EF9C01C020092B269469A +S224018E402800FFF748FF1AE0BFB2022F05D0132219212800FFF755FF11E0FF21FE31E01C19 +S224018E60FFF78BF9C01C020092B269462800FFF732FF04E0122219212800FFF742FF7FB072 +S224018E8002B0F0BD002202604160012101724272704770B504000E0015005748215A574843 +S224018EA02018FFF7EFFF7820205C012806D02A00310092B220001830FBF737FD70BDFEB570 +S224018EC005000E001400082100226F463800FDF7ADFB2000C0B2782805D04748295A4748E9 +S224018EE02818FFF7CFFF7920285C002814D02000C0B211280FD02000C0B212280BD02000CE +S224018F00C0B2312807D02000C0B27E2803D02000C0B27F2800D10AE068467F210170467035 +S224018F2084700322694628001830FBF7FEFCF7BDF2B582B0040015000821002632006F462B +S224018F403800FDF773FBA0687A21615CC90040184078ADB280B2854205D013221021200085 +S224018F60FFF7ADFF47E0029840784006400E694650220A704870224AA25A92B2120A8A7027 +S224018F801F4AA25ACA701F4AA25A92B2120A0A711C4AA25A4A710100C9B2012906D025D35B +S224018FA003290BD012D3042918D01FE0A6706070062269462000FFF76CFF1CE0A67060708B +S224018FC0062269462000FFF764FF14E0A6706070062269462000FFF75CFF0CE0A670607047 +S224018FE0062269462000FFF754FF04E0122210212000FFF764FFF7BD8C100000A810000061 +S224019000881000008A100000002202604160012101724272704770B504000E00150025483A +S224019020215A25482018FFF7EFFF7820205C012806D02A00310092B220001830FBF775FCA9 +S22401904070BDFEB505000E001400082100226F463800FDF7EBFA2000C0B2782805D015488E +S224019060295A15482818FFF7CFFF7920285C002814D02000C0B211280FD02000C0B2122867 +S2240190800BD02000C0B2312807D02000C0B27E2803D02000C0B27F2800D10AE068467F21E0 +S2240190A00170467084700322694628001830FBF73CFCF7BD8C100000A8100000FEB5040062 +S2240190C016000022150008216F463800FDF7AEFA6078012805D1222237212000FFF7B1FF52 +S2240190E03EE0A0687A21615CC90040184078B6B280B2864205D2132237212000FFF7A1FF97 +S2240191002EE0772069462A0092B288546D1CFFF744FA012802D0022814D019E0FFF740FABC +S2240191200600FFF72BFA864205D0132237212000FFF787FF11E02A0092B269462000FFF71E +S2240191406AFF0AE0312237212000FFF77AFF04E0242237212000FFF774FF0020FFF711FA50 +S224019160F7BD0000002202604160012101724272704770B504000E0015002548215A25486F +S2240191802018FFF7EFFF7820205C012806D02A00310092B220001830FBF7C7FB70BDFEB5FF +S2240191A005000E001400082100226F463800FDF73DFA2000C0B2782805D01548295A1548DB +S2240191C02818FFF7CFFF7920285C002814D02000C0B211280FD02000C0B212280BD02000EB +S2240191E0C0B2312807D02000C0B27E2803D02000C0B27F2800D10AE068467F210170467053 +S22401920084700322694628001830FBF78EFBF7BD8C100000A8100000FEB504000D001600B3 +S224019220082100226F463800FDF700FAA0687A21615CC90040184078B6B280B2864205D290 +S224019240132285212000FFF7AAFF2CE06078012805D1222285212000FFF7A1FF23E0687808 +S2240192604006400E6946C5220A704870C0B2012802D0022809D011E00120FEF7EFFE022204 +S22401928069462000FFF775FF0DE00020FEF7E6FE022269462000FFF76CFF04E01222852197 +S2240192A02000FFF77CFFF7BD002202604160012101724272704770B504000E001500254885 +S2240192C0215A25482018FFF7EFFF7820205C012806D02A00310092B220001830FBF725FB58 +S2240192E070BDFEB505000E001400082100226F463800FDF79BF92000C0B2782805D015483D +S224019300295A15482818FFF7CFFF7920285C002814D02000C0B211280FD02000C0B21228C4 +S2240193200BD02000C0B2312807D02000C0B27E2803D02000C0B27F2800D10AE068467F213D +S2240193400170467084700322694628001830FBF7ECFAF7BD8C100000A8100000FEB5040011 +S2240193600D001600082100226F463800FDF75EF9FF20A1687A22A25CD20089184978B6B2E3 +S22401938089B28E4205D0132211212000FFF7A9FF2AE069784906490E6A46512313705170C9 +S2240193A09070C9B2012904D019D303290FD008D315E0032269462000FFF77DFFFDF7B3FE5C +S2240193C012E0032269462000FFF775FF0CE0032269462000FFF76FFFFDF7AFFE04E012223A +S2240193E011212000FFF77DFFF7BD0000002202604160012101724272704770B504000E0093 +S22401940015004448215A44482018FFF7EFFF7820205C012806D02A00310092B22000183068 +S224019420FBF783FA70BDFEB505000E001400082100226F463800FDF7F9F82000C0B2782861 +S22401944005D03448295A34482818FFF7CFFF7920285C002814D02000C0B211280FD02000BF +S224019460C0B212280BD02000C0B2312807D02000C0B27E2803D02000C0B27F2800D10AE09E +S22401948068467F210170467084700322694628001830FBF74AFAF7BDFEB504000D00160055 +S2240194A00022029208216F463800FDF7BFF8A0687A21615CC90040184078B6B280B2864294 +S2240194C005D0132214212000FFF7ADFF20E00299687800040843A97809020143E8780843A0 +S2240194E054216A46117001000C4A891A03D09D3901D02F3907D1FEF77FFE012269462000A8 +S224019500FFF77BFF04E0312214212000FFF78BFFF7BD00008C100000A810000033FFFF0090 +S224019520002202604160012101724272704770B504000E0015002548215A25482018FFF731 +S224019540EFFF7820205C012806D02A00310092B220001830FBF7E9F970BDFEB505000E0036 +S2240195601400082100226F463800FDF75FF82000C0B2782805D01548295A15482818FFF7D4 +S224019580CFFF7920285C002814D02000C0B211280FD02000C0B212280BD02000C0B2312892 +S2240195A007D02000C0B27E2803D02000C0B27F2800D10AE068467F21017046708470032241 +S2240195C0694628001830FBF7B0F9F7BD8C100000A8100000FEB504000D001600082100229E +S2240195E06F463800FDF722F8A0687A21615CC90040184078B6B280B2864205D013223E2166 +S2240196002000FFF7AAFF15E068784006400E0100C9B2002909D169467E220A7048700222F8 +S22401962069462000FFF783FF04E012223E212000FFF793FFF7BD0000FFB51F481F49204A1D +S2240196400392204A204B214C0294214C214D0195214D224E224F009703E00F780770401C03 +S224019660491C039F8F42F8D10298984207D018781070521C5B1CF7E700202070641C01985C +S224019680A042F9D10098B04204D030782870761C6D1CF7E7002006E0124982008958124A61 +S2240196A08300D150401C114989088842F4D30E480F490860FFBD00BF000000201C7E0100DC +S2240196C05C80010040020020D49A0100D49A01000020002070550020000000000000000042 +S2240196E00000000000000100000001000000000008ED00E00000010032070000000108004A +S22401970001000000FFFFFFFF01000100DF0700000001080001000000FFFFFFFF0200010055 +S224019720440400000001080001000000FFFFFFFF030001005505000000010800010000006D +S224019740FFFFFFFF05000100B20700000000080000000000FFFFFFFF06000100110100002B +S2240197600000080000000000FFFFFFFF07000100220200000000080000000000FFFFFFFFAF +S224019780000000000000000000000000000000000000000010020100318F010011020100DB +S2240197A05D9301002702010011730100280301008D8701003E020100D5950100850201008E +S2240197C01992010022030000757901002E040000918B010014040000999401001903010011 +S2240197E07D8D01002F030000597C0100310401009D7601003405000075830100360200009C +S224019800A785010037010000BD90010072B60021002200230024002500260027B846B9466E +S224019820BA46BB46BC460C490C4A521A013A05DD0020042308601944043AFBDA08488546B1 +S224019840084880470848804762B600F00FF88047FCF736F8FEE7000000000020FF63002056 +S224019860F05F00204F450100399601000548014603B4684680F3098800BF00BF00BF00BF15 +S22401988000F002F8A5EDF5FE00F00DF8002801D000BF00BF00BF00BF002000BF00BFFCF7D8 +S2240198A00FF800F002F80120704780B500F002F801BD00000746384600F002F8FBE7000065 +S2240198C080B500BF00BF024A11001820ABBEFBE7260002004669727374206672616D652074 +S2240198E073686F756C64206E6F7420757365206D756C7469706C65206672616D6520747238 +S224019900616E736D697373696F6E2E004D756C74692D6672616D6520726573706F6E7365FD +S22401992020746F6F206C6172676520666F7220726563656976696E67206275666665722E79 +S224019940000000004D6573736167652073697A6520746F6F206C617267652E20536574202A +S22401996061206C61726765722073656E64206275666665720A00000041626F72742070727B +S2240199806576696F7573206D6573736167652C207472616E736D697373696F6E20696E2094 +S2240199A070726F67726573732E0A00000000000000000000000000000000000000000000F4 +S2240199C00000000000000000000000000000000000000000000000000000000053696E67F0 +S2240199E06C652D6672616D65206C656E67746820746F6F20736D616C6C206F7220746F6F98 +S224019A00206C617267652E004669727374206672616D652073686F756C64206265203820A6 +S224019A20627974657320696E206C656E6774682E00000000436F6E7365637574697665208A +S224019A406672616D6520746F6F2073686F72742E00000000466C6F7720636F6E74726F6C4C +S224019A60206672616D6520746F6F2073686F72742E0000009B6B0100856B01006F6B0100F2 +S224019A80596B0100C36B0100AD6B01003031323334353637383941424344454661707020B0 +S224019AA073746172740A00005465726D696E616C00000000746573740A000000000102035C +S224019AC00405000053454747455200000102030400000000FFFFFFFFFFFFFFFFFFFFFFFFBC +S224019AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S224019B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S224019B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S224019B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S224019B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S224019B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S224019BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S224019BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S224019BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S224019C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S224019C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S224019C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S224019C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S224019C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S224019CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S224019CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S224019CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S224019D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S224019D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S224019D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S224019D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S224019D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S224019DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S224019DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S224019DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S224019E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S224019E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S224019E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S224019E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S224019E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S224019EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S224019EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S224019EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S224019F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S224019F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S224019F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224019F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S224019F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S224019FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S224019FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S224019FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S22401A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S22401A020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S22401A040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S22401A060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S22401A080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S22401A0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S22401A0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S22401A0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S22401A100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S22401A120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S22401A140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S22401A160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S22401A180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S22401A1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S22401A1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S22401A1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S22401A200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S22401A220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S22401A240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S22401A260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S22401A280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S22401A2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S22401A2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S22401A2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S22401A300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S22401A320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S22401A340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S22401A360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S22401A380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S22401A3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S22401A3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S22401A3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S22401A400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S22401A420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S22401A440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S22401A460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S22401A480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S22401A4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S22401A4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S22401A4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S22401A500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S22401A520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S22401A540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S22401A560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S22401A580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S22401A5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S22401A5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S22401A5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S22401A600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S22401A620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S22401A640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S22401A660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S22401A680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S22401A6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S22401A6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S22401A6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S22401A700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S22401A720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S22401A740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S22401A760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S22401A780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S22401A7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S22401A7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S22401A7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S22401A800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S22401A820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S22401A840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S22401A860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S22401A880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S22401A8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S22401A8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S22401A8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S22401A900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S22401A920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S22401A940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S22401A960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S22401A980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S22401A9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S22401A9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S22401A9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S22401AA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S22401AA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S22401AA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S22401AA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S22401AA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S22401AAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S22401AAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S22401AAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S22401AB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S22401AB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S22401AB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S22401AB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S22401AB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S22401ABA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S22401ABC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S22401ABE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S22401AC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S22401AC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S22401AC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S22401AC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S22401AC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S22401ACA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S22401ACC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S22401ACE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S22401AD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S22401AD20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S22401AD40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S22401AD60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S22401AD80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S22401ADA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S22401ADC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S22401ADE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S22401AE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S22401AE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S22401AE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S22401AE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S22401AE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S22401AEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S22401AEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S22401AEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S22401AF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S22401AF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S22401AF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S22401AF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S22401AF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S22401AFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S22401AFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S22401AFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S22401B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S22401B020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S22401B040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S22401B060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S22401B080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S22401B0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S22401B0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S22401B0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S22401B100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S22401B120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S22401B140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S22401B160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S22401B180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S22401B1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S22401B1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S22401B1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S22401B200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S22401B220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S22401B240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S22401B260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S22401B280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S22401B2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S22401B2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S22401B2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S22401B300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S22401B320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S22401B340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S22401B360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S22401B380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S22401B3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S22401B3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S22401B3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S22401B400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S22401B420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S22401B440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S22401B460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S22401B480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S22401B4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S22401B4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S22401B4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S22401B500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S22401B520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S22401B540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S22401B560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S22401B580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S22401B5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S22401B5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S22401B5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S22401B600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S22401B620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S22401B640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S22401B660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S22401B680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S22401B6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S22401B6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S22401B6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S22401B700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S22401B720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S22401B740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S22401B760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S22401B780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S22401B7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S22401B7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S22401B7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S22401B800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S22401B820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S22401B840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S22401B860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S22401B880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S22401B8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S22401B8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S22401B8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S22401B900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S22401B920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S22401B940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S22401B960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S22401B980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S22401B9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S22401B9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S22401B9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S22401BA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S22401BA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S22401BA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S22401BA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S22401BA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S22401BAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S22401BAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S22401BAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S22401BB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S22401BB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S22401BB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S22401BB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S22401BB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S22401BBA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S22401BBC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S22401BBE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S22401BC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S22401BC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S22401BC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S22401BC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S22401BC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S22401BCA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S22401BCC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S22401BCE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S22401BD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S22401BD20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S22401BD40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S22401BD60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S22401BD80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S22401BDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S22401BDC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S22401BDE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S22401BE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S22401BE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S22401BE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S22401BE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S22401BE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S22401BEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S22401BEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S22401BEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S22401BF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S22401BF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S22401BF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S22401BF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S22401BF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S22401BFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S22401BFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S22401BFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S22401C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S22401C020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S22401C040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S22401C060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S22401C080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S22401C0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S22401C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S22401C0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S22401C100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S22401C120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S22401C140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S22401C160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S22401C180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S22401C1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S22401C1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S22401C1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S22401C200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S22401C220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S22401C240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S22401C260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S22401C280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S22401C2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S22401C2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S22401C2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S22401C300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S22401C320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S22401C340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S22401C360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S22401C380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S22401C3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S22401C3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S22401C3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S22401C400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S22401C420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S22401C440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S22401C460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S22401C480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S22401C4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S22401C4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S22401C4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S22401C500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S22401C520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S22401C540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S22401C560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S22401C580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S22401C5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S22401C5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S22401C5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S22401C600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S22401C620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S22401C640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S22401C660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S22401C680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S22401C6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S22401C6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S22401C6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S22401C700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S22401C720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S22401C740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S22401C760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S22401C780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S22401C7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S22401C7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S22401C7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S22401C800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S22401C820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S22401C840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S22401C860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S22401C880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S22401C8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S22401C8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S22401C8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S22401C900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S22401C920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S22401C940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S22401C960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S22401C980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S22401C9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S22401C9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S22401C9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S22401CA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S22401CA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S22401CA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S22401CA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S22401CA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S22401CAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S22401CAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S22401CAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S22401CB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S22401CB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S22401CB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S22401CB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S22401CB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S22401CBA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S22401CBC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S22401CBE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S22401CC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S22401CC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S22401CC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S22401CC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S22401CC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S22401CCA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S22401CCC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S22401CCE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S22401CD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S22401CD20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S22401CD40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S22401CD60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S22401CD80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S22401CDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S22401CDC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S22401CDE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S22401CE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S22401CE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S22401CE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S22401CE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S22401CE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S22401CEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S22401CEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S22401CEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S22401CF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S22401CF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S22401CF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S22401CF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S22401CF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S22401CFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S22401CFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S22401CFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S22401D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S22401D020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S22401D040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S22401D060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S22401D080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S22401D0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S22401D0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S22401D0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S22401D100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S22401D120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S22401D140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S22401D160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S22401D180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S22401D1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S22401D1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S22401D1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S22401D200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S22401D220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S22401D240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S22401D260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S22401D280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S22401D2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S22401D2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S22401D2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S22401D300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S22401D320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S22401D340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S22401D360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S22401D380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S22401D3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S22401D3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S22401D3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S22401D400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S22401D420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S22401D440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S22401D460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S22401D480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S22401D4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S22401D4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S22401D4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S22401D500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S22401D520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S22401D540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S22401D560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S22401D580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S22401D5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S22401D5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S22401D5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S22401D600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S22401D620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S22401D640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S22401D660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S22401D680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S22401D6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S22401D6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S22401D6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S22401D700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S22401D720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S22401D740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S22401D760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S22401D780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S22401D7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S22401D7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S22401D7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S22401D800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S22401D820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S22401D840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S22401D860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S22401D880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S22401D8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S22401D8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S22401D8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S22401D900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S22401D920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S22401D940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S22401D960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S22401D980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S22401D9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S22401D9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S22401D9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S22401DA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S22401DA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S22401DA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S22401DA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S22401DA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S22401DAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S22401DAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S22401DAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S22401DB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S22401DB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S22401DB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S22401DB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S22401DB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S22401DBA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S22401DBC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S22401DBE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S22401DC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S22401DC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S22401DC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S22401DC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S22401DC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S22401DCA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S22401DCC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S22401DCE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S22401DD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S22401DD20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S22401DD40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S22401DD60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S22401DD80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S22401DDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S22401DDC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S22401DDE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S22401DE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S22401DE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S22401DE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S22401DE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S22401DE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S22401DEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S22401DEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S22401DEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S22401DF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S22401DF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S22401DF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S22401DF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S22401DF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S22401DFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S22401DFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S22401DFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S22401E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S22401E020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S22401E040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S22401E060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S22401E080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S22401E0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S22401E0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S22401E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S22401E100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S22401E120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S22401E140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S22401E160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S22401E180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S22401E1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S22401E1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S22401E1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S22401E200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S22401E220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S22401E240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S22401E260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S22401E280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S22401E2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S22401E2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S22401E2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S22401E300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S22401E320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S22401E340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S22401E360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S22401E380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S22401E3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S22401E3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S22401E3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S22401E400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S22401E420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S22401E440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S22401E460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S22401E480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S22401E4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S22401E4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S22401E4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S22401E500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S22401E520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S22401E540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S22401E560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S22401E580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S22401E5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S22401E5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S22401E5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S22401E600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S22401E620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S22401E640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S22401E660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S22401E680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S22401E6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S22401E6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S22401E6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S22401E700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S22401E720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S22401E740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S22401E760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S22401E780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S22401E7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S22401E7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S22401E7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S22401E800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S22401E820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S22401E840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S22401E860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S22401E880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S22401E8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S22401E8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S22401E8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S22401E900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S22401E920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S22401E940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S22401E960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S22401E980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S22401E9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S22401E9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S22401E9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S22401EA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S22401EA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S22401EA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S22401EA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S22401EA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S22401EAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S22401EAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S22401EAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S22401EB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S22401EB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S22401EB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S22401EB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S22401EB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S22401EBA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S22401EBC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S22401EBE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S22401EC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S22401EC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S22401EC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S22401EC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S22401EC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S22401ECA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S22401ECC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S22401ECE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S22401ED00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S22401ED20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S22401ED40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S22401ED60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S22401ED80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S22401EDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S22401EDC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S22401EDE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S22401EE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S22401EE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S22401EE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S22401EE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S22401EE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S22401EEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S22401EEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S22401EEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S22401EF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S22401EF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S22401EF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S22401EF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S22401EF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S22401EFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S22401EFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S22401EFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S22401F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S22401F020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S22401F040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S22401F060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S22401F080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S22401F0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S22401F0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S22401F0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S22401F100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S22401F120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S22401F140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S22401F160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S22401F180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S22401F1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S22401F1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S22401F1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S22401F200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S22401F220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S22401F240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S22401F260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S22401F280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S22401F2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S22401F2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S22401F2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S22401F300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S22401F320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S22401F340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S22401F360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S22401F380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S22401F3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S22401F3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S22401F3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S22401F400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S22401F420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S22401F440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S22401F460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S22401F480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S22401F4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S22401F4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S22401F4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S22401F500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S22401F520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S22401F540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S22401F560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S22401F580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S22401F5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S22401F5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S22401F5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S22401F600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S22401F620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S22401F640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S22401F660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S22401F680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S22401F6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S22401F6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S22401F6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S22401F700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S22401F720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S22401F740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S22401F760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S22401F780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S22401F7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S22401F7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S22401F7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S22401F800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S22401F820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S22401F840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S22401F860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S22401F880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S22401F8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S22401F8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S22401F8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S22401F900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S22401F920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S22401F940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S22401F960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S22401F980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S22401F9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S22401F9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S22401F9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S22401FA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S22401FA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S22401FA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S22401FA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S22401FA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S22401FAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S22401FAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S22401FAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S22401FB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S22401FB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S22401FB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S22401FB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S22401FB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S22401FBA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S22401FBC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S22401FBE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S22401FC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S22401FC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S22401FC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S22401FC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S22401FC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S22401FCA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S22401FCC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S22401FCE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S22401FD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S22401FD20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S22401FD40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S22401FD60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S22401FD80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S22401FDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S22401FDC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S22401FDE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S22401FE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S22401FE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S22401FE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S22401FE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S22401FE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S22401FEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S22401FEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S22401FEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S22401FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S22401FF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S22401FF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S22401FF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S22401FF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S22401FFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S22401FFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S22401FFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224020000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S224020020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S224020040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S224020060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S224020080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S2240200A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S2240200C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S2240200E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S224020100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S224020120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S224020140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S224020160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S224020180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S2240201A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S2240201C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S2240201E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S224020200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S224020220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S224020240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S224020260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S224020280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S2240202A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S2240202C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S2240202E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S224020300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S224020320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S224020340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S224020360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S224020380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S2240203A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S2240203C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S2240203E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S224020400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S224020420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S224020440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S224020460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S224020480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S2240204A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S2240204C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S2240204E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S224020500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S224020520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S224020540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S224020560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S224020580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S2240205A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S2240205C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S2240205E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S224020600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S224020620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S224020640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S224020660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S224020680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S2240206A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S2240206C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S2240206E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S224020700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S224020720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S224020740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S224020760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S224020780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S2240207A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S2240207C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S2240207E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S224020800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S224020820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S224020840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S224020860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S224020880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S2240208A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S2240208C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S2240208E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S224020900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S224020920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S224020940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S224020960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S224020980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S2240209A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S2240209C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S2240209E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S224020A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S224020A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S224020A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S224020A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S224020A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S224020AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S224020AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S224020AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S224020B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S224020B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S224020B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S224020B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S224020B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S224020BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S224020BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S224020BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S224020C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S224020C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S224020C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S224020C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S224020C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S224020CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S224020CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S224020CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S224020D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S224020D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S224020D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S224020D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S224020D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S224020DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S224020DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S224020DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S224020E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S224020E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S224020E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S224020E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S224020E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S224020EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S224020EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S224020EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S224020F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S224020F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S224020F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S224020F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S224020F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S224020FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S224020FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S224020FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S224021000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S224021020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S224021040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S224021060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S224021080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S2240210A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S2240210C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S2240210E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S224021100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S224021120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S224021140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S224021160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S224021180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S2240211A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S2240211C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S2240211E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S224021200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S224021220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S224021240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S224021260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S224021280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S2240212A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S2240212C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S2240212E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S224021300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S224021320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S224021340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S224021360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S224021380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S2240213A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S2240213C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S2240213E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S224021400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S224021420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S224021440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S224021460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S224021480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S2240214A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S2240214C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S2240214E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S224021500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S224021520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S224021540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S224021560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S224021580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S2240215A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S2240215C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S2240215E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S224021600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S224021620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S224021640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S224021660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S224021680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S2240216A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S2240216C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S2240216E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S224021700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S224021720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S224021740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S224021760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S224021780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S2240217A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S2240217C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S2240217E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S224021800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S224021820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S224021840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S224021860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S224021880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S2240218A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S2240218C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S2240218E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S224021900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S224021920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S224021940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S224021960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S224021980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S2240219A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S2240219C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S2240219E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S224021A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S224021A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S224021A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S224021A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S224021A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S224021AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S224021AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S224021AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S224021B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S224021B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S224021B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S224021B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S224021B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S224021BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S224021BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S224021BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S224021C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S224021C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S224021C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S224021C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S224021C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S224021CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S224021CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S224021CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S224021D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S224021D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S224021D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S224021D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S224021D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S224021DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S224021DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S224021DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S224021E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S224021E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S224021E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S224021E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S224021E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S224021EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S224021EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224021EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S224021F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S224021F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S224021F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S224021F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S224021F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S224021FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S224021FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S224021FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S224022000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S224022020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S224022040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S224022060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S224022080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S2240220A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S2240220C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S2240220E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S224022100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S224022120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S224022140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S224022160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S224022180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S2240221A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S2240221C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S2240221E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S224022200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S224022220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S224022240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S224022260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S224022280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S2240222A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S2240222C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S2240222E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S224022300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S224022320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S224022340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S224022360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S224022380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S2240223A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S2240223C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S2240223E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S224022400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S224022420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S224022440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S224022460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S224022480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S2240224A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S2240224C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S2240224E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S224022500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S224022520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S224022540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S224022560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S224022580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S2240225A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S2240225C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S2240225E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S224022600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S224022620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S224022640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S224022660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S224022680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S2240226A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S2240226C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S2240226E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S224022700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S224022720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S224022740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S224022760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S224022780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S2240227A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S2240227C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S2240227E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S224022800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S224022820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S224022840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S224022860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S224022880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S2240228A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S2240228C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S2240228E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S224022900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S224022920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S224022940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S224022960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S224022980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S2240229A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S2240229C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S2240229E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S224022A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S224022A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S224022A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S224022A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S224022A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S224022AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S224022AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S224022AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S224022B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S224022B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S224022B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S224022B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S224022B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S224022BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S224022BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S224022BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S224022C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S224022C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S224022C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S224022C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S224022C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S224022CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S224022CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S224022CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S224022D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S224022D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S224022D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S224022D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S224022D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S224022DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S224022DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S224022DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S224022E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S224022E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S224022E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S224022E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S224022E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S224022EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S224022EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S224022EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S224022F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S224022F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S224022F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S224022F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S224022F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S224022FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S224022FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S224022FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S224023000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S224023020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S224023040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S224023060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S224023080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S2240230A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S2240230C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S2240230E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S224023100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S224023120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S224023140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S224023160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S224023180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S2240231A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S2240231C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S2240231E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S224023200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S224023220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S224023240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S224023260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S224023280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S2240232A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S2240232C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S2240232E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S224023300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S224023320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S224023340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S224023360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S224023380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S2240233A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S2240233C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S2240233E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S224023400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S224023420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S224023440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S224023460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S224023480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S2240234A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S2240234C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S2240234E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S224023500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S224023520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S224023540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S224023560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S224023580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S2240235A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S2240235C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S2240235E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S224023600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S224023620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S224023640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S224023660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S224023680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S2240236A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S2240236C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S2240236E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S224023700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S224023720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S224023740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S224023760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S224023780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S2240237A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S2240237C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S2240237E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S224023800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S224023820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S224023840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S224023860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S224023880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S2240238A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S2240238C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S2240238E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S224023900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S224023920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S224023940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S224023960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S224023980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S2240239A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S2240239C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S2240239E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S224023A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S224023A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S224023A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S224023A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S224023A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S224023AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S224023AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S224023AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S224023B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S224023B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S224023B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S224023B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S224023B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S224023BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S224023BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S224023BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S224023C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S224023C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S224023C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S224023C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S224023C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S224023CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S224023CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S224023CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S224023D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S224023D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S224023D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S224023D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S224023D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S224023DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S224023DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S224023DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S224023E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S224023E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S224023E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S224023E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S224023E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S224023EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224023EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S224023EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S224023F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S224023F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S224023F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S224023F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S224023F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S224023FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S224023FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S224023FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S224024000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S224024020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S224024040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S224024060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S224024080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S2240240A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S2240240C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S2240240E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S224024100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S224024120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S224024140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S224024160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S224024180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S2240241A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S2240241C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S2240241E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S224024200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S224024220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S224024240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S224024260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S224024280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S2240242A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S2240242C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S2240242E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S224024300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S224024320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S224024340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S224024360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S224024380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S2240243A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S2240243C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S2240243E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S224024400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S224024420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S224024440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S224024460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S224024480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S2240244A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S2240244C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S2240244E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S224024500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S224024520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S224024540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S224024560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S224024580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S2240245A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S2240245C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S2240245E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S224024600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S224024620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S224024640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S224024660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S224024680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S2240246A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S2240246C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S2240246E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S224024700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S224024720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S224024740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S224024760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S224024780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S2240247A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S2240247C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S2240247E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S224024800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S224024820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S224024840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S224024860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S224024880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S2240248A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S2240248C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S2240248E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S224024900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S224024920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S224024940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S224024960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S224024980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S2240249A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S2240249C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S2240249E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S224024A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S224024A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S224024A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S224024A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S224024A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S224024AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S224024AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S224024AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S224024B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S224024B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S224024B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S224024B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S224024B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S224024BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S224024BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S224024BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S224024C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S224024C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S224024C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S224024C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S224024C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S224024CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S224024CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S224024CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S224024D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S224024D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S224024D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S224024D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S224024D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S224024DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S224024DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S224024DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S224024E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S224024E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S224024E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S224024E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S224024E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S224024EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S224024EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S224024EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S224024F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S224024F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S224024F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S224024F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S224024F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S224024FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S224024FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S224024FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S224025000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S224025020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S224025040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S224025060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S224025080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S2240250A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S2240250C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S2240250E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S224025100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S224025120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S224025140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S224025160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S224025180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S2240251A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S2240251C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S2240251E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S224025200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S224025220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S224025240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S224025260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S224025280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S2240252A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S2240252C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S2240252E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S224025300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S224025320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S224025340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S224025360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S224025380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S2240253A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S2240253C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S2240253E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S224025400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S224025420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S224025440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S224025460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S224025480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S2240254A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S2240254C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S2240254E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S224025500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S224025520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S224025540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S224025560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S224025580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S2240255A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S2240255C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S2240255E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S224025600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S224025620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S224025640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S224025660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S224025680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S2240256A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S2240256C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S2240256E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S224025700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S224025720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S224025740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S224025760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S224025780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S2240257A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S2240257C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S2240257E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S224025800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S224025820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S224025840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S224025860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S224025880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S2240258A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S2240258C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S2240258E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S224025900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S224025920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S224025940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S224025960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S224025980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S2240259A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S2240259C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S2240259E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S224025A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S224025A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S224025A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S224025A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S224025A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S224025AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S224025AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S224025AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S224025B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S224025B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S224025B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S224025B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S224025B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S224025BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S224025BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S224025BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S224025C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S224025C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S224025C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S224025C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S224025C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S224025CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S224025CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S224025CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S224025D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S224025D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S224025D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S224025D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S224025D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S224025DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S224025DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S224025DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S224025E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S224025E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S224025E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S224025E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S224025E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224025EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S224025EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S224025EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S224025F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S224025F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S224025F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S224025F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S224025F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S224025FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S224025FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S224025FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S224026000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S224026020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S224026040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S224026060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S224026080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S2240260A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S2240260C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S2240260E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S224026100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S224026120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S224026140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S224026160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S224026180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S2240261A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S2240261C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S2240261E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S224026200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S224026220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S224026240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S224026260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S224026280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S2240262A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S2240262C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S2240262E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S224026300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S224026320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S224026340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S224026360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S224026380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S2240263A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S2240263C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S2240263E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S224026400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S224026420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S224026440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S224026460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S224026480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S2240264A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S2240264C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S2240264E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S224026500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S224026520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S224026540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S224026560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S224026580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S2240265A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S2240265C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S2240265E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S224026600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S224026620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S224026640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S224026660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S224026680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S2240266A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S2240266C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S2240266E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S224026700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S224026720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S224026740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S224026760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S224026780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S2240267A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S2240267C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S2240267E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S224026800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S224026820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S224026840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S224026860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S224026880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S2240268A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S2240268C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S2240268E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S224026900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S224026920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S224026940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S224026960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S224026980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S2240269A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S2240269C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S2240269E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S224026A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S224026A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S224026A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S224026A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S224026A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S224026AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S224026AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S224026AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S224026B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S224026B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S224026B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S224026B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S224026B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S224026BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S224026BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S224026BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S224026C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S224026C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S224026C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S224026C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S224026C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S224026CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S224026CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S224026CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S224026D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S224026D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S224026D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S224026D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S224026D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S224026DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S224026DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S224026DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S224026E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S224026E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S224026E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S224026E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S224026E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S224026EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S224026EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S224026EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S224026F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S224026F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S224026F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S224026F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S224026F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S224026FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S224026FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S224026FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S224027000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S224027020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S224027040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S224027060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S224027080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S2240270A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S2240270C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S2240270E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S224027100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S224027120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S224027140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S224027160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S224027180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S2240271A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S2240271C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S2240271E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S224027200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S224027220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S224027240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S224027260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S224027280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S2240272A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S2240272C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S2240272E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S224027300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S224027320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S224027340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S224027360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S224027380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S2240273A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S2240273C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S2240273E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S224027400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S224027420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S224027440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S224027460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S224027480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S2240274A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S2240274C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S2240274E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S224027500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S224027520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S224027540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S224027560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S224027580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S2240275A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S2240275C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S2240275E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S224027600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S224027620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S224027640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S224027660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S224027680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S2240276A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S2240276C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S2240276E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S224027700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S224027720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S224027740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S224027760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S224027780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S2240277A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S2240277C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S2240277E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S224027800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S224027820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S224027840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S224027860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S224027880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S2240278A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S2240278C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S2240278E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S224027900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S224027920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S224027940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S224027960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S224027980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S2240279A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S2240279C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S2240279E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S224027A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S224027A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S224027A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S224027A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S224027A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S224027AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S224027AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S224027AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S224027B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S224027B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S224027B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S224027B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S224027B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S224027BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S224027BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S224027BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S224027C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S224027C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S224027C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S224027C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S224027C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S224027CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S224027CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S224027CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S224027D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S224027D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S224027D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S224027D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S224027D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S224027DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S224027DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S224027DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S224027E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S224027E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S224027E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S224027E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224027E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S224027EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S224027EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S224027EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S224027F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S224027F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S224027F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S224027F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S224027F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S224027FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S224027FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S224027FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S224028000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S224028020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S224028040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S224028060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S224028080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S2240280A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S2240280C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S2240280E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S224028100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S224028120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S224028140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S224028160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S224028180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S2240281A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S2240281C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S2240281E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S224028200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S224028220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S224028240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S224028260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S224028280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S2240282A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S2240282C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S2240282E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S224028300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S224028320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S224028340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S224028360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S224028380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S2240283A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S2240283C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S2240283E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S224028400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S224028420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S224028440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S224028460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S224028480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S2240284A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S2240284C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S2240284E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S224028500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S224028520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S224028540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S224028560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S224028580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S2240285A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S2240285C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S2240285E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S224028600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S224028620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S224028640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S224028660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S224028680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S2240286A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S2240286C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S2240286E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S224028700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S224028720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S224028740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S224028760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S224028780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S2240287A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S2240287C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S2240287E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S224028800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S224028820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S224028840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S224028860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S224028880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S2240288A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S2240288C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S2240288E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S224028900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S224028920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S224028940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S224028960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S224028980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S2240289A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S2240289C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S2240289E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S224028A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S224028A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S224028A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S224028A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S224028A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S224028AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S224028AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S224028AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S224028B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S224028B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S224028B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S224028B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S224028B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S224028BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S224028BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S224028BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S224028C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S224028C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S224028C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S224028C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S224028C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S224028CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S224028CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S224028CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S224028D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S224028D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S224028D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S224028D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S224028D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S224028DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S224028DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S224028DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S224028E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S224028E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S224028E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S224028E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S224028E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S224028EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S224028EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S224028EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S224028F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S224028F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S224028F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S224028F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S224028F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S224028FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S224028FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S224028FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S224029000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S224029020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S224029040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S224029060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S224029080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S2240290A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S2240290C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S2240290E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S224029100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S224029120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S224029140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S224029160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S224029180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S2240291A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S2240291C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S2240291E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S224029200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S224029220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S224029240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S224029260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S224029280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S2240292A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S2240292C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S2240292E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S224029300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S224029320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S224029340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S224029360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S224029380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S2240293A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S2240293C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S2240293E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S224029400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S224029420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S224029440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S224029460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S224029480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S2240294A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S2240294C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S2240294E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S224029500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S224029520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S224029540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S224029560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S224029580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S2240295A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S2240295C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S2240295E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S224029600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S224029620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S224029640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S224029660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S224029680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S2240296A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S2240296C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S2240296E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S224029700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S224029720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S224029740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S224029760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S224029780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S2240297A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S2240297C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S2240297E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S224029800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S224029820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S224029840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S224029860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S224029880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S2240298A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S2240298C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S2240298E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S224029900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S224029920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S224029940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S224029960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S224029980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S2240299A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S2240299C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S2240299E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S224029A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S224029A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S224029A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S224029A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S224029A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S224029AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S224029AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S224029AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S224029B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S224029B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S224029B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S224029B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S224029B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S224029BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S224029BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S224029BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S224029C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S224029C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S224029C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S224029C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S224029C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S224029CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S224029CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S224029CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S224029D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S224029D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S224029D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S224029D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S224029D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S224029DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S224029DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S224029DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S224029E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S224029E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S224029E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224029E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S224029E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S224029EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S224029EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S224029EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S224029F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S224029F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S224029F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S224029F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S224029F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S224029FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S224029FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S224029FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S22402A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S22402A020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S22402A040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S22402A060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S22402A080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S22402A0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S22402A0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S22402A0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S22402A100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S22402A120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S22402A140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S22402A160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S22402A180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S22402A1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S22402A1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S22402A1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S22402A200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S22402A220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S22402A240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S22402A260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S22402A280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S22402A2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S22402A2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S22402A2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S22402A300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S22402A320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S22402A340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S22402A360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S22402A380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S22402A3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S22402A3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S22402A3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S22402A400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S22402A420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S22402A440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S22402A460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S22402A480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S22402A4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S22402A4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S22402A4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S22402A500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S22402A520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S22402A540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S22402A560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S22402A580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S22402A5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S22402A5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S22402A5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S22402A600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S22402A620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S22402A640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S22402A660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S22402A680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S22402A6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S22402A6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S22402A6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S22402A700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S22402A720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S22402A740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S22402A760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S22402A780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S22402A7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S22402A7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S22402A7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S22402A800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S22402A820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S22402A840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S22402A860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S22402A880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S22402A8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S22402A8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S22402A8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S22402A900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S22402A920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S22402A940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S22402A960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S22402A980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S22402A9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S22402A9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S22402A9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S22402AA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S22402AA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S22402AA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S22402AA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S22402AA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S22402AAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S22402AAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S22402AAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S22402AB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S22402AB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S22402AB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S22402AB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S22402AB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S22402ABA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S22402ABC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S22402ABE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S22402AC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S22402AC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S22402AC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S22402AC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S22402AC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S22402ACA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S22402ACC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S22402ACE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S22402AD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S22402AD20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S22402AD40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S22402AD60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S22402AD80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S22402ADA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S22402ADC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S22402ADE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S22402AE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S22402AE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S22402AE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S22402AE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S22402AE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S22402AEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S22402AEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S22402AEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S22402AF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S22402AF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S22402AF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S22402AF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S22402AF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S22402AFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S22402AFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S22402AFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S22402B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S22402B020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S22402B040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S22402B060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S22402B080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S22402B0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S22402B0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S22402B0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S22402B100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S22402B120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S22402B140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S22402B160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S22402B180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S22402B1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S22402B1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S22402B1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S22402B200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S22402B220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S22402B240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S22402B260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S22402B280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S22402B2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S22402B2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S22402B2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S22402B300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S22402B320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S22402B340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S22402B360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S22402B380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S22402B3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S22402B3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S22402B3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S22402B400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S22402B420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S22402B440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S22402B460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S22402B480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S22402B4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S22402B4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S22402B4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S22402B500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S22402B520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S22402B540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S22402B560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S22402B580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S22402B5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S22402B5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S22402B5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S22402B600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S22402B620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S22402B640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S22402B660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S22402B680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S22402B6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S22402B6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S22402B6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S22402B700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S22402B720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S22402B740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S22402B760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S22402B780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S22402B7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S22402B7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S22402B7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S22402B800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S22402B820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S22402B840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S22402B860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S22402B880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S22402B8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S22402B8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S22402B8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S22402B900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S22402B920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S22402B940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S22402B960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S22402B980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S22402B9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S22402B9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S22402B9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S22402BA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S22402BA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S22402BA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S22402BA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S22402BA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S22402BAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S22402BAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S22402BAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S22402BB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S22402BB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S22402BB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S22402BB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S22402BB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S22402BBA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S22402BBC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S22402BBE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S22402BC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S22402BC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S22402BC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S22402BC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S22402BC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S22402BCA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S22402BCC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S22402BCE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S22402BD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S22402BD20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S22402BD40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S22402BD60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S22402BD80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S22402BDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S22402BDC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S22402BDE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S22402BE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S22402BE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S22402BE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S22402BE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S22402BE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S22402BEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S22402BEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S22402BEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S22402BF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S22402BF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S22402BF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S22402BF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S22402BF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S22402BFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S22402BFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S22402BFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S22402C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S22402C020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S22402C040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S22402C060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S22402C080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S22402C0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S22402C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S22402C0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S22402C100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S22402C120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S22402C140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S22402C160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S22402C180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S22402C1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S22402C1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S22402C1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S22402C200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S22402C220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S22402C240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S22402C260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S22402C280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S22402C2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S22402C2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S22402C2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S22402C300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S22402C320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S22402C340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S22402C360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S22402C380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S22402C3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S22402C3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S22402C3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S22402C400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S22402C420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S22402C440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S22402C460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S22402C480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S22402C4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S22402C4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S22402C4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S22402C500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S22402C520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S22402C540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S22402C560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S22402C580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S22402C5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S22402C5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S22402C5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S22402C600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S22402C620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S22402C640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S22402C660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S22402C680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S22402C6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S22402C6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S22402C6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S22402C700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S22402C720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S22402C740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S22402C760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S22402C780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S22402C7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S22402C7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S22402C7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S22402C800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S22402C820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S22402C840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S22402C860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S22402C880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S22402C8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S22402C8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S22402C8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S22402C900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S22402C920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S22402C940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S22402C960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S22402C980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S22402C9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S22402C9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S22402C9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S22402CA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S22402CA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S22402CA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S22402CA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S22402CA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S22402CAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S22402CAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S22402CAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S22402CB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S22402CB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S22402CB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S22402CB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S22402CB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S22402CBA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S22402CBC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S22402CBE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S22402CC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S22402CC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S22402CC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S22402CC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S22402CC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S22402CCA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S22402CCC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S22402CCE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S22402CD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S22402CD20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S22402CD40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S22402CD60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S22402CD80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S22402CDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S22402CDC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S22402CDE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S22402CE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S22402CE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S22402CE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S22402CE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S22402CE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S22402CEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S22402CEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S22402CEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S22402CF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S22402CF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S22402CF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S22402CF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S22402CF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S22402CFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S22402CFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S22402CFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S22402D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S22402D020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S22402D040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S22402D060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S22402D080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S22402D0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S22402D0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S22402D0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S22402D100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S22402D120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S22402D140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S22402D160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S22402D180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S22402D1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S22402D1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S22402D1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S22402D200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S22402D220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S22402D240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S22402D260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S22402D280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S22402D2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S22402D2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S22402D2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S22402D300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S22402D320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S22402D340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S22402D360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S22402D380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S22402D3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S22402D3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S22402D3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S22402D400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S22402D420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S22402D440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S22402D460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S22402D480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S22402D4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S22402D4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S22402D4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S22402D500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S22402D520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S22402D540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S22402D560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S22402D580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S22402D5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S22402D5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S22402D5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S22402D600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S22402D620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S22402D640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S22402D660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S22402D680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S22402D6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S22402D6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S22402D6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S22402D700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S22402D720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S22402D740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S22402D760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S22402D780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S22402D7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S22402D7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S22402D7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S22402D800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S22402D820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S22402D840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S22402D860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S22402D880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S22402D8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S22402D8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S22402D8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S22402D900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S22402D920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S22402D940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S22402D960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S22402D980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S22402D9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S22402D9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S22402D9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S22402DA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S22402DA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S22402DA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S22402DA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S22402DA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S22402DAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S22402DAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S22402DAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S22402DB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S22402DB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S22402DB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S22402DB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S22402DB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S22402DBA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S22402DBC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S22402DBE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S22402DC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S22402DC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S22402DC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S22402DC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S22402DC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S22402DCA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S22402DCC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S22402DCE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S22402DD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S22402DD20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S22402DD40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S22402DD60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S22402DD80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S22402DDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S22402DDC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S22402DDE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S22402DE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S22402DE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S22402DE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S22402DE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S22402DE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S22402DEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S22402DEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S22402DEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S22402DF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S22402DF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S22402DF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S22402DF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S22402DF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S22402DFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S22402DFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S22402DFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S22402E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S22402E020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S22402E040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S22402E060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S22402E080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S22402E0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S22402E0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S22402E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S22402E100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S22402E120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S22402E140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S22402E160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S22402E180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S22402E1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S22402E1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S22402E1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S22402E200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S22402E220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S22402E240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S22402E260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S22402E280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S22402E2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S22402E2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S22402E2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S22402E300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S22402E320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S22402E340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S22402E360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S22402E380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S22402E3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S22402E3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S22402E3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S22402E400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S22402E420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S22402E440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S22402E460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S22402E480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S22402E4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S22402E4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S22402E4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S22402E500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S22402E520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S22402E540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S22402E560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S22402E580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S22402E5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S22402E5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S22402E5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S22402E600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S22402E620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S22402E640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S22402E660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S22402E680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S22402E6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S22402E6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S22402E6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S22402E700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S22402E720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S22402E740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S22402E760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S22402E780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S22402E7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S22402E7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S22402E7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S22402E800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S22402E820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S22402E840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S22402E860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S22402E880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S22402E8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S22402E8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S22402E8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S22402E900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S22402E920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S22402E940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S22402E960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S22402E980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S22402E9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S22402E9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S22402E9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S22402EA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S22402EA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S22402EA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S22402EA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S22402EA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S22402EAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S22402EAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S22402EAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S22402EB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S22402EB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S22402EB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S22402EB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S22402EB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S22402EBA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S22402EBC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S22402EBE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S22402EC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S22402EC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S22402EC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S22402EC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S22402EC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S22402ECA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S22402ECC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S22402ECE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S22402ED00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S22402ED20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S22402ED40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S22402ED60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S22402ED80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S22402EDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S22402EDC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S22402EDE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S22402EE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S22402EE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S22402EE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S22402EE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S22402EE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S22402EEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S22402EEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S22402EEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S22402EF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S22402EF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S22402EF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S22402EF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S22402EF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S22402EFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S22402EFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S22402EFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S22402F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S22402F020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S22402F040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S22402F060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S22402F080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S22402F0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S22402F0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S22402F0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S22402F100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S22402F120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S22402F140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S22402F160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S22402F180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S22402F1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S22402F1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S22402F1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S22402F200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S22402F220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S22402F240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S22402F260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S22402F280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S22402F2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S22402F2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S22402F2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S22402F300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S22402F320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S22402F340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S22402F360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S22402F380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S22402F3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S22402F3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S22402F3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S22402F400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S22402F420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S22402F440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S22402F460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S22402F480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S22402F4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S22402F4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S22402F4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S22402F500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S22402F520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S22402F540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S22402F560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S22402F580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S22402F5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S22402F5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S22402F5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S22402F600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S22402F620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S22402F640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S22402F660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S22402F680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S22402F6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S22402F6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S22402F6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S22402F700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S22402F720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S22402F740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S22402F760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S22402F780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S22402F7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S22402F7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S22402F7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S22402F800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S22402F820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S22402F840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S22402F860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S22402F880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S22402F8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S22402F8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S22402F8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S22402F900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S22402F920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S22402F940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S22402F960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S22402F980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S22402F9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S22402F9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S22402F9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S22402FA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S22402FA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S22402FA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S22402FA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S22402FA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S22402FAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S22402FAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S22402FAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S22402FB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S22402FB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S22402FB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S22402FB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S22402FB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S22402FBA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S22402FBC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S22402FBE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S22402FC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S22402FC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S22402FC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S22402FC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S22402FC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S22402FCA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S22402FCC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S22402FCE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S22402FD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S22402FD20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S22402FD40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S22402FD60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S22402FD80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S22402FDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S22402FDC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S22402FDE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S22402FE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S22402FE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S22402FE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S22402FE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S22402FE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S22402FEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S22402FEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S22402FEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S22402FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S22402FF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S22402FF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S22402FF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S22402FF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S22402FFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S22402FFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S22402FFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S224030000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S224030020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S224030040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S224030060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S224030080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S2240300A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S2240300C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S2240300E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S224030100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S224030120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S224030140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S224030160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S224030180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S2240301A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S2240301C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S2240301E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S224030200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S224030220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S224030240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S224030260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S224030280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S2240302A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S2240302C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S2240302E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S224030300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S224030320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S224030340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S224030360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S224030380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S2240303A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S2240303C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S2240303E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S224030400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S224030420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S224030440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S224030460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S224030480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S2240304A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S2240304C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S2240304E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S224030500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S224030520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S224030540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S224030560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S224030580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S2240305A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S2240305C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S2240305E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S224030600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S224030620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S224030640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S224030660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S224030680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S2240306A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S2240306C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S2240306E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S224030700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S224030720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S224030740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S224030760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S224030780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S2240307A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S2240307C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S2240307E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S224030800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S224030820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S224030840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S224030860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S224030880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S2240308A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S2240308C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S2240308E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S224030900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S224030920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S224030940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S224030960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S224030980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S2240309A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S2240309C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S2240309E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S224030A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S224030A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S224030A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S224030A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S224030A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S224030AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S224030AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S224030AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S224030B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S224030B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S224030B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S224030B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S224030B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S224030BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S224030BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S224030BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S224030C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S224030C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S224030C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S224030C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S224030C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S224030CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S224030CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S224030CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S224030D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S224030D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S224030D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S224030D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S224030D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S224030DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S224030DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S224030DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S224030E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S224030E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S224030E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S224030E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S224030E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S224030EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S224030EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S224030EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S224030F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S224030F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S224030F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S224030F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S224030F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S224030FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S224030FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S224030FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S224031000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S224031020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S224031040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S224031060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S224031080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S2240310A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S2240310C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S2240310E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S224031100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S224031120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S224031140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S224031160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S224031180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S2240311A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S2240311C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S2240311E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S224031200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S224031220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S224031240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S224031260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S224031280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S2240312A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S2240312C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S2240312E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S224031300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S224031320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S224031340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S224031360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S224031380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S2240313A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S2240313C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S2240313E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S224031400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S224031420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S224031440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S224031460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S224031480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S2240314A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S2240314C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S2240314E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S224031500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S224031520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S224031540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S224031560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S224031580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S2240315A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S2240315C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S2240315E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S224031600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S224031620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S224031640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S224031660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S224031680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S2240316A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S2240316C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S2240316E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S224031700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S224031720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S224031740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S224031760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S224031780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S2240317A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S2240317C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S2240317E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S224031800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S224031820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S224031840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S224031860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S224031880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S2240318A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S2240318C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S2240318E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S224031900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S224031920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S224031940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S224031960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S224031980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S2240319A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S2240319C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S2240319E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S224031A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S224031A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S224031A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S224031A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S224031A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S224031AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S224031AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S224031AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S224031B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S224031B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S224031B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S224031B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S224031B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S224031BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S224031BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S224031BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S224031C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S224031C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S224031C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S224031C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S224031C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S224031CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S224031CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S224031CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S224031D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S224031D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S224031D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S224031D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S224031D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S224031DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S224031DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224031DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S224031E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S224031E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S224031E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S224031E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S224031E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S224031EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S224031EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S224031EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S224031F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S224031F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S224031F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S224031F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S224031F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S224031FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S224031FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S224031FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S224032000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S224032020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S224032040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S224032060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S224032080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S2240320A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S2240320C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S2240320E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S224032100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S224032120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S224032140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S224032160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S224032180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S2240321A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S2240321C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S2240321E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S224032200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S224032220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S224032240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S224032260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S224032280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S2240322A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S2240322C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S2240322E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S224032300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S224032320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S224032340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S224032360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S224032380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S2240323A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S2240323C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S2240323E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S224032400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S224032420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S224032440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S224032460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S224032480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S2240324A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S2240324C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S2240324E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S224032500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S224032520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S224032540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S224032560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S224032580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S2240325A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S2240325C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S2240325E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S224032600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S224032620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S224032640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S224032660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S224032680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S2240326A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S2240326C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S2240326E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S224032700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S224032720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S224032740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S224032760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S224032780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S2240327A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S2240327C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S2240327E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S224032800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S224032820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S224032840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S224032860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S224032880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S2240328A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S2240328C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S2240328E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S224032900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S224032920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S224032940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S224032960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S224032980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S2240329A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S2240329C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S2240329E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S224032A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S224032A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S224032A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S224032A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S224032A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S224032AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S224032AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S224032AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S224032B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S224032B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S224032B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S224032B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S224032B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S224032BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S224032BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S224032BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S224032C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S224032C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S224032C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S224032C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S224032C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S224032CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S224032CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S224032CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S224032D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S224032D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S224032D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S224032D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S224032D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S224032DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S224032DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S224032DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S224032E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S224032E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S224032E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S224032E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S224032E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S224032EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S224032EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S224032EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S224032F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S224032F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S224032F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S224032F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S224032F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S224032FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S224032FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S224032FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S224033000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S224033020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S224033040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S224033060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S224033080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S2240330A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S2240330C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S2240330E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S224033100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S224033120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S224033140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S224033160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S224033180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S2240331A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S2240331C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S2240331E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S224033200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S224033220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S224033240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S224033260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S224033280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S2240332A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S2240332C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S2240332E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S224033300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S224033320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S224033340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S224033360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S224033380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S2240333A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S2240333C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S2240333E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S224033400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S224033420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S224033440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S224033460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S224033480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S2240334A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S2240334C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S2240334E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S224033500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S224033520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S224033540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S224033560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S224033580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S2240335A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S2240335C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S2240335E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S224033600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S224033620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S224033640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S224033660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S224033680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S2240336A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S2240336C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S2240336E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S224033700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S224033720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S224033740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S224033760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S224033780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S2240337A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S2240337C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S2240337E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S224033800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S224033820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S224033840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S224033860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S224033880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S2240338A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S2240338C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S2240338E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S224033900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S224033920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S224033940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S224033960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S224033980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S2240339A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S2240339C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S2240339E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S224033A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S224033A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S224033A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S224033A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S224033A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S224033AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S224033AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S224033AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S224033B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S224033B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S224033B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S224033B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S224033B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S224033BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S224033BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S224033BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S224033C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S224033C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S224033C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S224033C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S224033C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S224033CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S224033CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S224033CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S224033D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S224033D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S224033D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S224033D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S224033D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S224033DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224033DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S224033DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S224033E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S224033E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S224033E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S224033E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S224033E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S224033EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S224033EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S224033EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S224033F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S224033F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S224033F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S224033F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S224033F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S224033FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S224033FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S224033FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S224034000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S224034020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S224034040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S224034060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S224034080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S2240340A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S2240340C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S2240340E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S224034100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S224034120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S224034140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S224034160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S224034180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S2240341A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S2240341C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S2240341E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S224034200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S224034220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S224034240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S224034260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S224034280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S2240342A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S2240342C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S2240342E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S224034300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S224034320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S224034340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S224034360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S224034380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S2240343A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S2240343C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S2240343E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S224034400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S224034420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S224034440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S224034460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S224034480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S2240344A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S2240344C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S2240344E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S224034500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S224034520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S224034540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S224034560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S224034580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S2240345A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S2240345C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S2240345E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S224034600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S224034620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S224034640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S224034660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S224034680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S2240346A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S2240346C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S2240346E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S224034700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S224034720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S224034740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S224034760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S224034780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S2240347A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S2240347C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S2240347E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S224034800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S224034820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S224034840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S224034860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S224034880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S2240348A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S2240348C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S2240348E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S224034900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S224034920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S224034940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S224034960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S224034980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S2240349A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S2240349C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S2240349E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S224034A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S224034A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S224034A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S224034A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S224034A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S224034AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S224034AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S224034AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S224034B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S224034B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S224034B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S224034B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S224034B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S224034BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S224034BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S224034BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S224034C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S224034C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S224034C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S224034C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S224034C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S224034CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S224034CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S224034CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S224034D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S224034D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S224034D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S224034D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S224034D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S224034DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S224034DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S224034DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S224034E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S224034E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S224034E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S224034E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S224034E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S224034EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S224034EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S224034EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S224034F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S224034F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S224034F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S224034F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S224034F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S224034FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S224034FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S224034FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S224035000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S224035020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S224035040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S224035060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S224035080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S2240350A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S2240350C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S2240350E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S224035100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S224035120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S224035140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S224035160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S224035180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S2240351A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S2240351C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S2240351E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S224035200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S224035220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S224035240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S224035260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S224035280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S2240352A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S2240352C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S2240352E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S224035300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S224035320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S224035340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S224035360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S224035380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S2240353A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S2240353C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S2240353E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S224035400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S224035420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S224035440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S224035460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S224035480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S2240354A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S2240354C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S2240354E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S224035500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S224035520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S224035540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S224035560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S224035580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S2240355A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S2240355C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S2240355E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S224035600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S224035620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S224035640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S224035660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S224035680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S2240356A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S2240356C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S2240356E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S224035700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S224035720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S224035740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S224035760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S224035780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S2240357A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S2240357C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S2240357E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S224035800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S224035820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S224035840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S224035860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S224035880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S2240358A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S2240358C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S2240358E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S224035900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S224035920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S224035940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S224035960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S224035980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S2240359A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S2240359C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S2240359E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S224035A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S224035A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S224035A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S224035A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S224035A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S224035AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S224035AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S224035AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S224035B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S224035B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S224035B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S224035B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S224035B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S224035BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S224035BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S224035BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S224035C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S224035C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S224035C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S224035C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S224035C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S224035CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S224035CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S224035CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S224035D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S224035D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S224035D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S224035D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S224035D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224035DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S224035DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S224035DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S224035E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S224035E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S224035E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S224035E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S224035E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S224035EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S224035EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S224035EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S224035F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S224035F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S224035F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S224035F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S224035F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S224035FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S224035FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S224035FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S224036000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S224036020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S224036040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S224036060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S224036080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S2240360A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S2240360C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S2240360E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S224036100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S224036120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S224036140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S224036160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S224036180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S2240361A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S2240361C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S2240361E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S224036200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S224036220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S224036240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S224036260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S224036280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S2240362A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S2240362C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S2240362E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S224036300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S224036320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S224036340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S224036360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S224036380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S2240363A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S2240363C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S2240363E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S224036400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S224036420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S224036440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S224036460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S224036480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S2240364A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S2240364C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S2240364E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S224036500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S224036520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S224036540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S224036560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S224036580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S2240365A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S2240365C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S2240365E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S224036600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S224036620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S224036640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S224036660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S224036680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S2240366A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S2240366C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S2240366E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S224036700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S224036720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S224036740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S224036760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S224036780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S2240367A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S2240367C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S2240367E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S224036800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S224036820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S224036840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S224036860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S224036880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S2240368A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S2240368C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S2240368E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S224036900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S224036920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S224036940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S224036960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S224036980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S2240369A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S2240369C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S2240369E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S224036A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S224036A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S224036A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S224036A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S224036A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S224036AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S224036AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S224036AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S224036B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S224036B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S224036B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S224036B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S224036B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S224036BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S224036BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S224036BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S224036C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S224036C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S224036C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S224036C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S224036C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S224036CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S224036CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S224036CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S224036D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S224036D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S224036D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S224036D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S224036D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S224036DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S224036DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S224036DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S224036E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S224036E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S224036E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S224036E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S224036E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S224036EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S224036EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S224036EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S224036F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S224036F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S224036F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S224036F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S224036F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S224036FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S224036FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S224036FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S224037000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S224037020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S224037040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S224037060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S224037080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S2240370A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S2240370C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S2240370E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S224037100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S224037120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S224037140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S224037160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S224037180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S2240371A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S2240371C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S2240371E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S224037200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S224037220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S224037240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S224037260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S224037280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S2240372A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S2240372C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S2240372E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S224037300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S224037320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S224037340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S224037360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S224037380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S2240373A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S2240373C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S2240373E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S224037400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S224037420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S224037440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S224037460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S224037480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S2240374A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S2240374C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S2240374E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S224037500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S224037520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S224037540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S224037560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S224037580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S2240375A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S2240375C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S2240375E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S224037600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S224037620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S224037640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S224037660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S224037680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S2240376A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S2240376C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S2240376E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S224037700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S224037720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S224037740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S224037760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S224037780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S2240377A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S2240377C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S2240377E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S224037800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S224037820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S224037840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S224037860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S224037880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S2240378A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S2240378C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S2240378E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S224037900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S224037920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S224037940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S224037960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S224037980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S2240379A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S2240379C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S2240379E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S224037A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S224037A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S224037A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S224037A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S224037A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S224037AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S224037AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S224037AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S224037B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S224037B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S224037B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S224037B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S224037B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S224037BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S224037BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S224037BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S224037C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S224037C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S224037C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S224037C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S224037C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S224037CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S224037CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S224037CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S224037D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S224037D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S224037D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S224037D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224037D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S224037DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S224037DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S224037DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S224037E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S224037E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S224037E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S224037E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S224037E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S224037EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S224037EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S224037EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S224037F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S224037F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S224037F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S224037F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S224037F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S224037FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S224037FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S224037FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D631B3D6D +S804000001FA diff --git a/cva_asw_m0118/bat_complier_object/cva_asw_m0118_iar_1.s19 b/cva_asw_m0118/bat_complier_object/cva_asw_m0118_iar_1.s19 new file mode 100644 index 0000000..37d3c79 --- /dev/null +++ b/cva_asw_m0118/bat_complier_object/cva_asw_m0118_iar_1.s19 @@ -0,0 +1,5121 @@ +S224010000F05F0020DD890100348C0100348C01000000000000000000000000000000000082 +S224010020000000000000000000000000348C01000000000000000000348C01002D490100C1 +S224010040348C0100348C0100348C0100348C0100348C0100348C0100348C0100348C010092 +S224010060348C010051490100348C0100348C0100348C0100348C0100348C0100348C010098 +S224010080348C0100348C0100348C0100348C0100348C0100348C0100348C0100348C010052 +S2240100A0348C0100348C0100348C0100348C0100348C0100348C0100348C0100348C010032 +S2240100C0DDCCBBAA00B58268D2681300DB07DB0F002B0BD08268126A92081300DB07DB0F6F +S2240100E0002B03D0C0690860012000E0002000BD30B500228368DC680125AC43D2B21500A9 +S224010100ED07ED0F2543DD600978002945D0C169B84A914201D1002112E0C169B64A9142A4 +S22401012001D201210CE0C169B44A914201D2022106E0C169B24A914201D2032100E004210C +S224010140C9B2042901D1002028E08268D3680C24A343C9B28C000C2121401943D160002179 +S2240101608268D3681024A343C9B20901102421401943D16001218268D3680124A343C9B2C6 +S2240101800C00E407E40F1C43D4608168096A89080A00D207D20F002AF7D0012030BD00B577 +S2240101A08268126A52081300DB07DB0F002B03D080690860012000E0002000BD38B504007C +S2240101C00D000020A16849690A00D207D20F002A59D0A168096A0A00D207D20F002A52D08E +S2240101E0A168896909090A00D207D20F002A02D0012A05D009E069462000FFF763FF04E038 +S22401020069462000FFF7CBFFFFE7C0B2002801D1002039E00121A0684069000A8007800FCB +S224010220002805D0022807D004D3032806D007E0012105E0022103E0042101E00821FFE7D9 +S224010240A068406940084206520E002A01D18022FFE7A0684069C00A43075B0F002B01D147 +S2240102600823FFE7A0684069800A0400E407E40F641C00985043604359430222514302F0B6 +S224010280CCFB28600120C0B232BD70B5002283685C690125AC43D2B21500ED07ED0F25438A +S2240102A05D6101224B78002B02D0012B0CD017E0002583689C691026B443EDB22D01102653 +S2240102C0354025439D610CE0012583689C691026B443EDB22D011026354025439D6100E050 +S2240102E00022D2B2002A01D100207FE0CB68012B01D100250FE0CB68022B01D101250AE050 +S224010300CB68042B01D1022505E0CB68082B01D1032500E0FF25EDB2FF2D01D1002065E031 +S22401032083685E69B34C3440EDB22E02C025AD00354025435D614B88002B17D04B88812B32 +S22401034014DA4B88802B01D1002500E04D8883685C69FE26B443EDB26E00FE2535402543A7 +S2240103605D610B69002B03D100203FE000203DE00B69092BF8D20B69082B01D1002500E0DA +S2240103800D6983685E699C4C3440EDB2EE02E025AD01354025435D618B68012B02D08B6812 +S2240103A0022B24D18B685D1E83685E69934C3440EDB2AD028026F600354025435D6109789C +S2240103C0002911D0012183685C690125AC43C9B20D00ED07ED0F25435D618168096A0B0021 +S2240103E0DB07DB0F002BF8D01000C0B270BD0020FCE7000000093D0001127A0001366E010D +S224010400015A620270B582B005000C000026002000906869C06900090100C907C90F002904 +S22401042016D069462800FFF74DFE0600F6B2002E0ED06869C0690121000A4007400F814081 +S224010440412904D2009802F0E8FA206000E000263000C0B276BD70B5002200254369DC6932 +S2240104601026B443EDB22D01102635402543DD618B88012B01D100231EE08B88022B01D1E7 +S224010480012319E08B88042B01D1022314E08B88082B01D103230FE08B88102B01D1042398 +S2240104A00AE08B88202B01D1052305E08B88402B01D1062300E00723DBB2072B0BD0426947 +S2240104C0D4698D4D2540DBB21C02E023DB0023402B43D36101220978002901D0012100E06C +S2240104E000214069C3691024A343C9B20901102421401943C1611000C0B270BD70B582B048 +S22401050005000C000026002000906869806900090100C907C90F002916D069462800FFF7A6 +S224010520D1FD0600F6B2002E0ED0686980690121000A4007400F8140412904D2009802F026 +S2240105406CFA206000E000263000C0B276BD70B50022002543699C691026B443EDB22D01BD +S2240105601026354025439D618B88012B01D100231EE08B88022B01D1012319E08B88042BC1 +S22401058001D1022314E08B88082B01D103230FE08B88102B01D104230AE08B88202B01D1DC +S2240105A0052305E08B88402B01D1062300E00723DBB2072B0BD0426994694F4D2540DBB2D5 +S2240105C01C02E023DB0023402B43936101220978002901D0012100E00021406983691024CA +S2240105E0A343C9B2090110242140194381611000C0B270BDFFFCFFFFFFC7FFFFFFFBFFFF53 +S22401060070B582B005000C000026002000906869406900090100C907C90F002916D06946AC +S2240106202800FFF7BCFD0600F6B2002E0ED0686940690121000A4007400F8140412904D2E6 +S224010640009802F0EAF9206000E000263000C0B276BD70B50022002543695C691026B443C2 +S224010660EDB22D011026354025435D618B88012B01D100231EE08B88022B01D1012319E075 +S2240106808B88042B01D1022314E08B88082B01D103230FE08B88102B01D104230AE08B88B6 +S2240106A0202B01D1052305E08B88402B01D1062300E00723DBB2072B0BD0426954690E4D2A +S2240106C02540DBB21C02E023DB0023402B43536101220978002901D0012100E00021406937 +S2240106E043691024A343C9B2090110242140194341611000C0B270BDFFF8FFFF70B582B01B +S22401070005000C000026002000906869006900090100C907C90F002916D069462800FFF724 +S2240107203EFD0600F6B2002E0ED0686900690121000A4007400F8140412904D2009802F037 +S2240107406CF9206000E000263000C0B276BD70B50022002543691C691026B443EDB22D013C +S2240107601026354025431D618B88012B01D100231EE08B88022B01D1012319E08B88042B3F +S22401078001D1022314E08B88082B01D103230FE08B88102B01D104230AE08B88202B01D1DA +S2240107A0052305E08B88402B01D1062300E00723DBB2072B0BD042691469B44D2540DBB2EE +S2240107C01C02E023DB0023402B43136101220978002901D0012100E00021406903691024C8 +S2240107E0A343C9B2090110242140194301611000C0B270BD70B582B005000C0000260020D8 +S22401080000906869406A00090100C907C90F002916D069462800FFF7D1FC0600F6B2002E90 +S2240108200ED06869406A0121000A4007400F8140412904D2009802F0F0F8206000E000269E +S2240108403000C0B276BD70B50022002543695C6A1026B443EDB22D011026354025435D6213 +S2240108608B88012B01D100231EE08B88022B01D1012319E08B88042B01D1022314E08B88D1 +S224010880082B01D103230FE08B88102B01D104230AE08B88202B01D1052305E08B88402B4C +S2240108A001D1062300E00723DBB2072B0BD04269546A764D2540DBB21C02E023DB00234016 +S2240108C02B43536201220978002901D0012100E000214069436A1024A343C9B20901102405 +S2240108E02140194341621000C0B270BD70B582B005000C000026002000906869006A000961 +S2240109000100C907C90F002916D069462800FFF755FC0600F6B2002E0ED06869006A0121E4 +S224010920000A4007400F8140412904D2009802F074F8206000E000263000C0B276BD70B59A +S2240109400022002543691C6A1026B443EDB22D011026354025431D628B88012B01D1002358 +S2240109601EE08B88022B01D1012319E08B88042B01D1022314E08B88082B01D103230FE0EA +S2240109808B88102B01D104230AE08B88202B01D1052305E08B88402B01D1062300E0072360 +S2240109A0DBB2072B0BD04269146A384D2540DBB21C02E023DB0023402B4313620122097811 +S2240109C0002901D0012100E000214069036A1024A343C9B2090110242140194301621000DB +S2240109E0C0B270BD80B50A00002143691B681B0E9B079B0F002B05D0022B0DD007D3032B3C +S224010A000FD013E01100FFF7CAFB01000EE01100FFF758FB010009E01100FFF7CFFB01002D +S224010A2004E01100FFF7BBFB0100FFE70800C0B202BD30B54A78012A01D100210AE04A787E +S224010A40002A01D1012105E04978022901D1022100E0FF21C9B2FF2901D1002015E0426977 +S224010A601368894C1C400B00DBB21D04C0239B022B402343136042691268120E9207920FC8 +S224010A800B00DBB29A42F6D1012030BDFFF8FFFF70B582B004000D00002069462000FFF7C5 +S224010AA0A1FF0600F6B2002E01D100200AE0E068016800980907090F491C01F0AEFF2860DC +S224010AC03000C0B276BD00B58A88002A0FD08A88112A0CDA8988491EC06802680F239A431F +S224010AE0C9B20907090F11430160012000E0002000BD70B582B004000D0000206946200063 +S224010B00FFF7C6FF0600F6B2002E01D100200BE0606901680098090A0907090F491C01F000 +S224010B207CFF28603000C0B276BD00B58A88002A11D08A88112A0EDA8988491E4069026845 +S224010B40524B1340C9B20A02F0210901114019430160012000E0002000BD70B582B00400B6 +S224010B600D0000262069C8214058000C8007800F002805D002280FD008D3032812D017E02B +S224010B8069462000FFF70BFB060011E069462000FFF798FA06000BE069462000FFF70EFB77 +S224010BA0060005E069462000FFF7F9FA0600FFE7F6B2002E01D1002017E02069C8214058D7 +S224010BC000090100C907C90F00290BD02069C82141580098090A0907090F491C01F01DFF09 +S224010BE0286000E000263000C0B276BD30B54A78012A01D100220AE04A78002A01D10122FB +S224010C0005E04A78022A01D1022200E0FF22D2B2FF2A01D1002036E08B88002B32D08B88FC +S224010C20112B2FDA0369C8241C59174D2540D2B21404C022920222402A43C8241A518A8889 +S224010C40531E0269C8241459104D2540DBB21C02F0231B0123402B43C824135109780029F2 +S224010C6001D0012100E000210069C822825810239A43C9B20901102319401143C82281501D +S224010C80012000E0002030BDFFFFFCFFFFF0FFFF70B582B004000D00606940680009010077 +S224010CA0C907C90F002901D1002098E000260020009060694068000C4007400F002843D1CE +S224010CC060694068C00C4007400F00280BD0022815D00ED304281ED017D3062827D020D32C +S224010CE007282AD02FE069462000FFF736FF060066E069462000FFF7E5F9060060E06946D8 +S224010D002000FFF74CFA06005AE069462000FFF755FA060054E069462000FFF7B9FE060061 +S224010D204EE069462000FFF7E4FE060048E069462000FFF767FB060042E069462000FFF796 +S224010D405FFC06003CE03BE060694068000C4007400F01280AD033D3032813D00CD30528BF +S224010D601CD015D3072825D01ED329E069462000FFF740FD060023E06946200000F0E4F9D4 +S224010D8006001DE06946200000F0BBF9060017E06946200000F092F9060011E069462000CA +S224010DA000F08CFC06000BE069462000FFF7F7F9060005E069462000FFF7F1F90600FFE789 +S224010DC0F6B2012E09D1606941680098090A4907490F491C01F021FE28603000C0B276BDC5 +S224010DE070B50122002543695C681026B443EDB22D011026354025435D604B78002B39D04F +S224010E00012B50D0022B67D0032B00D1AFE0052B00D1C5E0072B00D1DBE00A2B75D00B2B7A +S224010E2000D18BE00C2B0CD00F2B00D1F8E0102B00D1E8E0112B00D1D8E01A2B00D1FCE0EF +S224010E4008E1002543695E68984C3440EDB22E04E025ED02354025435D60002543695E68BE +S224010E60934C3440EDB2EE04E025AD03354025435D60F0E0002543695E688C4C3440EDB2E7 +S224010E802E04E025ED02354025435D60012543695E68874C3440EDB2EE04E025AD033540F2 +S224010EA025435D60D7E0002543695E687F4C3440EDB22E04E025ED02354025435D600225F4 +S224010EC043695E687A4C3440EDB2EE04E025AD03354025435D60BEE0002543695E68734C8C +S224010EE03440EDB22E04E025ED02354025435D60032543695E686E4C3440EDB2EE04E025BB +S224010F00AD03354025435D60A5E0002543695E68664C3440EDB22E04E025ED02354025439D +S224010F205D60042543695E68614C3440EDB2EE04E025AD03354025435D608CE00025436915 +S224010F405E685A4C3440EDB22E04E025ED02354025435D60052543695E68554C3440EDB2FC +S224010F60EE04E025AD03354025435D6073E0002543695E684D4C3440EDB22E04E025ED026E +S224010F80354025435D60062543695E68484C3440EDB2EE04E025AD03354025435D605AE0F2 +S224010FA0002543695E68414C3440EDB22E04E025ED02354025435D60072543695E683C4C0E +S224010FC03440EDB2EE04E025AD03354025435D6041E0012543695E68344C3440EDB22E0439 +S224010FE0E025ED02354025435D6034E0022543695E682E4C3440EDB22E04E025ED02354088 +S22401100025435D6027E0032543695E68274C3440EDB22E04E025ED02354025435D601AE0C4 +S224011020042543695E68214C3440EDB22E04E025ED02354025435D600DE0052543695E6846 +S2240110401A4C3440EDB22E04E025ED02354025435D6000E00022D2B2002A14D08B88002B7F +S22401106010D08B88092B0DDA8B885D1E43695E686B4C3440EDB22E02E025ED003540254393 +S2240110805D6000E000220978002901D0012100E00021406943681024A343C9B209011024C6 +S2240110A02140194341601000C0B270BDFFFFF8FFFFFFC7FF006A08600120704700B540685D +S2240110C0806C00090200D207D20F002A04D0FA2080000860012000E0002000BD00B5097845 +S2240110E0002901D0012100E000214068826C10239A43C9B2090110231940114381640120BC +S22401110000BD00B54068406C00090200D207D20F002A04D0FA20C0010860012000E00020DC +S22401112000BD00B50978002901D0012100E000214068426C10239A43C9B209011023194022 +S22401114011434164012000BDFA20400208600120704710B50200002053685B681B091C0071 +S224011160E407E40F002C01D1002017E053685B681B0C1C00E407E40F002C03D11000FFF7D1 +S22401118087FC0AE053685B681B0C1C00E407E40F002C02D0100000F000F9C0B210BD70B5E2 +S2240111A002000020002553685C681026B443EDB22D011026354025435D604B780A2B0DD1C3 +S2240111C0002053685C68174D2540C0B200048024640220402843586001200FE04B78182B88 +S2240111E00CD1012053685C680E4D2540C0B2000480246402204028435860012009780029DE +S22401120001D0012100E00021526853681024A343C9B209011024214019435160C0B270BD7F +S224011220FFF8FFFFFFFFFEFF10B50A00002143689B681B091C00E407E40F002C03D01100EC +S224011240FFF757FC01000800C0B210BD00B50978002901D0012100E00021406882681023DF +S2240112609A43C9B209011023194011438160012000BD10B50A0000214368DB681B091C0049 +S224011280E407E40F002C03D01100FFF732FC01000800C0B210BD00B50978002901D001219C +S2240112A000E000214068C26810239A43C9B20901102319401143C160012000BD10B50A0012 +S2240112C0002143681B691B091C00E407E40F002C03D01100FFF70DFC01000800C0B210BD43 +S2240112E000B50978002901D0012100E000214068026910239A43C9B209011023194011430D +S2240113000161012000BD10B50A00002143685B691B091C00E407E40F002C03D01100FFF704 +S224011320E8FB01000800C0B210BD00B50978002901D0012100E000214068426910239A43C6 +S224011340C9B209011023194011434161012000BD10B50A00002143689B691B091C00E407D8 +S224011360E40F002C03D01100FFF7C3FB01000800C0B210BD00B50978002901D0012100E036 +S22401138000214068826910239A43C9B209011023194011438161012000BD70B582B0040003 +S2240113A00D000026002000906068C06900090100C907C90F002901D1002051E06068C06964 +S2240113C0000C4007400F00280BD0022815D00ED304281ED017D3062827D020D307282AD02D +S2240113E02FE069462000FFF70BF9060029E069462000FFF707F8060023E069462000FFF76E +S224011400F9F906001DE069462000FFF79DFE060017E069462000FFF751FE060011E06946BA +S2240114202000FFF76EFE06000BE069462000FFF741FE060005E069462000FFF7E1F80600A0 +S224011440FFE7F6B2002E09D06068C069000A4107490F491C009801F0E0FA28603000C0B264 +S22401146076BD70B5012200254368DC691026B443EDB22D01102635402543DD614B78032B9A +S22401148019D0052B0AD0072B22D00E2B54D00F2B38D0102B43D0112B27D05AE00025436805 +S2240114A0DE69C54C3440EDB22E04E025ED0235402543DD614EE001254368DE69BE4C3440B6 +S2240114C0EDB22E04E025ED0235402543DD6141E002254368DE69B84C3440EDB22E04E0259E +S2240114E0ED0235402543DD6134E003254368DE69B14C3440EDB22E04E025ED02354025439B +S224011500DD6127E004254368DE69AB4C3440EDB22E04E025ED0235402543DD611AE00525F6 +S2240115204368DE69A44C3440EDB22E04E025ED0235402543DD610DE006254368DE699E4C7B +S2240115403440EDB22E04E025ED0235402543DD6100E000228B88002B10D08B88092B0DDAE3 +S2240115608B885D1E4368DE69B44C3440EDB22E02E025ED0035402543DD6100E00022097812 +S224011580002901D0012100E000214068C3691024A343C9B20901102421401943C161100092 +S2240115A0C0B270BD10B50200002053681B6A1B091C00E407E40F002C01D100201EE053686A +S2240115C01B6A1B0C9B079B0F002B05D0022B0BD006D3032B0CD010E01000FFF711F80CE037 +S2240115E01000FFF707F908E01000FEF70BFF04E0FA20400208600120FFE7C0B210BD70B5D5 +S2240116000122002543681C6A1026B443EDB22D011026354025431D624B78032B20D0052BAE +S22401162004D0072B0FD0112B27D033E0002543681E6AC34C3440EDB22E04C025AD023540C4 +S22401164025431D6227E0012543681E6ABC4C3440EDB22E04C025AD02354025431D621AE006 +S224011660022543681E6AB64C3440EDB22E04C025AD02354025431D620DE0032543681E6A8B +S224011680AF4C3440EDB22E04C025AD02354025431D6200E000220978002901D0012100E095 +S2240116A000214068036A1024A343C9B2090110242140194301621000C0B270BD10B5020085 +S2240116C0002053689B6A1B091C00E407E40F002C01D100201DE053689B6A1B0C9B079B0FB8 +S2240116E0002B05D0022B0BD006D3032B0CD00FE01000FFF706FD0BE01000FFF7DBFC07E052 +S2240117001000FFF7DBFC03E01000FFF7D7FCFFE7C0B210BD70B50022002543689C6A1026B2 +S224011720B443EDB22D011026354025439D624B78102B0DD1002243689C6A814D2540D2B267 +S2240117401404C022920222402A439A62012220E04B780E2B0DD1012243689C6A784D25402F +S224011760D2B21404C022920222402A439A6201220FE04B780F2B0CD1022243689C6A704D08 +S2240117802540D2B21404C022920222402A439A6201220978002901D0012100E00021406898 +S2240117A0836A1024A343C9B2090110242140194381621000C0B270BDFFFFF8FF10B5020058 +S2240117C0002053681B6B1B0C1C00E407E40F002C03D11000FFF78DF90AE053681B6B1B0CA3 +S2240117E01C00E407E40F002C02D01000FFF7ACFCC0B210BD10B5020000204B780B2B0CD141 +S22401180000215268136B8F4C1C40C9B2090480235B021940214311630EE0497811290BD1B4 +S22401182001215268136B874C1C40C9B2090480235B02194021431163C0B210BDFFF8FFFF2C +S22401184010B50200002053685B6B1B0C1C00E407E40F002C03D11000FFF74BF90AE053680A +S2240118605B6B1B0C1C00E407E40F002C02D01000FFF76AFCC0B210BD10B5020000204B7828 +S2240118800B2B0CD100215268536B6E4C1C40C9B2090480235B021940214351630EE04978D8 +S2240118A011290BD101215268536B664C1C40C9B2090480235B02194021435163C0B210BD2C +S2240118C010B50200002053689B6B1B0C1C00E407E40F002C03D11000FFF70BF90AE053688A +S2240118E09B6B1B0C1C00E407E40F002C02D01000FFF72AFCC0B210BD10B5020000204B78A8 +S2240119000B2B0CD100215268936B4E4C1C40C9B2090480235B021940214391630EE04978F7 +S22401192011290BD101215268936B464C1C40C9B2090480235B02194021439163C0B210BD4B +S224011940FFFFFCFF10B5020000205368DB6B1B0C1C00E407E40F002C03D11000FFF7C9F8B8 +S2240119600AE05368DB6B1B0C1C00E407E40F002C02D01000FFF7E8FBC0B210BD10B5020068 +S22401198000204B780B2B0CD100215268D36B2D4C1C40C9B2090480235B0219402143D163E4 +S2240119A00EE0497811290BD101215268D36B254C1C40C9B2090480235B0219402143D163FC +S2240119C0C0B210BD10B50200002053681B6C1B0C1C00E407E40F002C03D11000FFF789F8F1 +S2240119E00AE053681B6C1B0C1C00E407E40F002C02D01000FFF7A8FBC0B210BD10B50200E7 +S224011A0000204B780B2B0CD100215268136C0D4C1C40C9B2090480235B0219402143116401 +S224011A200EE0497811290BD101215268136C054C1C40C9B2090480235B0219402143116419 +S224011A40C0B210BDFFFFFEFF10B5020000201368DB681B091C00E407E40F002C03D1100073 +S224011A60FFF747F80BE01268D26812091300DB07DB0F002B03D0FA20400208600120C0B23D +S224011A8010BD00B50A00002153780B2B0CD100210068C26810239A43C9B2090110231940E1 +S224011AA01143C16001210EE05278112A0BD101210068C26810239A43C9B2090110231940E5 +S224011AC01143C16001210800C0B200BD80B50269126812091300DB07DB0F002B01D1002001 +S224011AE001E0FEF7D5FF02BD00B50978002901D0012100E000210069026810239A43C9B2C6 +S224011B0009011023194011430160012000BD80B50269526812091300DB07DB0F002B01D145 +S224011B20002001E0FEF7E5FF02BD00B50978002901D0012100E000210069426810239A4390 +S224011B40C9B209011023194011434160012000BD80B50269126912091300DB07DB0F002B5B +S224011B6001D1002001E0FEF7C4FF02BD00B50978002901D0012100E00021006902691023BB +S224011B809A43C9B209011023194011430161012000BD80B50269526912091300DB07DB0F68 +S224011BA0002B01D1002001E0FEF7A3FF02BD00B50978002901D0012100E000210069426964 +S224011BC010239A43C9B209011023194011434161012000BD80B50269926912091300DB075F +S224011BE0DB0F002B01D1002001E0FEF751FF02BD00B50978002901D0012100E00021006937 +S224011C00826910239A43C9B209011023194011438161012000BD80B50269D2691209130095 +S224011C20DB07DB0F002B01D1002001E0FEF761FF02BD00B50978002901D0012100E000216D +S224011C400069C26910239A43C9B20901102319401143C161012000BD70B582B004000D000D +S224011C602069006A00090100C907C90F002901D1002035E00120002000902069006A000CB9 +S224011C808007800F002805D002280FD008D3032812D017E069462000FEF781FA060012E00C +S224011CA069462000FEF70EFA06000CE069462000FEF784FA060006E069462000FEF76FFA05 +S224011CC0060000E000262069006A0121000A8007800F8140009800F0A0FE28603000C0B2AC +S224011CE076BD70B50022002503691C6A1026B443EDB22D011026354025431D624B78012BD2 +S224011D0001D100230AE04B78002B01D1012305E04B78022B01D1022300E0FF23DBB2FF2B75 +S224011D200BD00269146A9A4D2540DBB21C04C0239B0223402B4313620122D2B2002A24D055 +S224011D408B88012B01D100250FE08B88022B01D101250AE08B88042B01D1022505E08B8803 +S224011D60082B01D1032500E0FF25EDB2FF2D0BD003691E6ABB4C3440EDB22E02C025AD00B6 +S224011D80354025431D6200E000220978002901D0012100E000210069036A1024A343C9B2D6 +S224011DA0090110242140194301621000C0B270BD80B50269926A12091300DB07DB0F002B4F +S224011DC001D1002001E0FEF794FE02BD00B50978002901D0012100E000210069826A102309 +S224011DE09A43C9B209011023194011438162012000BD80B50269126B12091300DB07DB0FC3 +S224011E00002B01D100201BE001220269126B120C9207920F002A05D0022A09D005D3032A38 +S224011E2009D00BE0FEF7ECFB09E0FEF7EBFA06E0FEF7E0FC03E0FEF7E3FB00E00020C0B25A +S224011E4002BD70B50022002503691C6B1026B443EDB22D011026354025431D634B78052BDE +S224011E6001D100230AE04B78032B01D1012305E04B78072B01D1022300E0FF23DBB2FF2B0C +S224011E800BD00269146B424D2540DBB21C04C0239B0223402B43136301220978002901D071 +S224011EA0012100E000210069036B1024A343C9B2090110242140194301631000C0B270BD7F +S224011EC080B50269526B12091300DB07DB0F002B01D100201BE001220269526B120C92078B +S224011EE0920F002A05D0022A09D005D3032A09D00BE0FEF785FB09E0FEF784FA06E0FEF7C2 +S224011F0079FC03E0FEF77CFB00E00020C0B202BD70B50022002503695C6B1026B443EDB25B +S224011F202D011026354025435D634B78052B01D100230AE04B78032B01D1012305E04B7839 +S224011F40072B01D1022300E0FF23DBB2FF2B0BD00269546B0E4D2540DBB21C04C0239B02A7 +S224011F6023402B43536301220978002901D0012100E000210069436B1024A343C9B209015D +S224011F8010242140194341631000C0B270BD0000FFFFFCFF80B50269126C12091300DB07D0 +S224011FA0DB0F002B01D100201BE001220269126C120C9207920F002A05D0022A09D005D3D9 +S224011FC0032A09D00BE0FEF71BFB09E0FEF71AFA06E0FEF70FFC03E0FEF712FB00E0002042 +S224011FE0C0B202BD70B50022002503691C6C1026B443EDB22D011026354025431D644B78F9 +S224012000052B01D100230AE04B78032B01D1012305E04B78072B01D1022300E0FF23DBB264 +S224012020FF2B0BD00269146C784D2540DBB21C04C0239B0223402B4313640122097800293E +S22401204001D0012100E000210069036C1024A343C9B2090110242140194301641000C0B237 +S22401206070BD0000FFFCFFFF002070470020704780B50269926C12091300DB07DB0F002BC3 +S22401208001D100201BE001220269926C120C9207920F002A05D0022A09D005D3032A09D087 +S2240120A00BE0FEF7ADFA09E0FEF7ACF906E0FEF7A1FB03E0FEF7A4FA00E00020C0B202BDF2 +S2240120C070B50022002503699C6C1026B443EDB22D011026354025439D644B78052B01D147 +S2240120E000230AE04B78032B01D1012305E04B78072B01D1022300E0FF23DBB2FF2B0BD081 +S2240121000269946C904D2540DBB21C04C0239B0223402B43936401220978002901D0012157 +S22401212000E000210069836C1024A343C9B2090110242140194381641000C0B270BD80B5E7 +S2240121400269126E12091300DB07DB0F002B01D100201BE001220269126E120C9207920F16 +S224012160002A05D0022A09D005D3032A09D00BE0FEF746FA09E0FEF745F906E0FEF73AFB2B +S22401218003E0FEF73DFA00E00020C0B202BD70B50022002503691C6E1026B443EDB22D019D +S2240121A01026354025431D664B78052B01D100230AE04B78032B01D1012305E04B78072BF0 +S2240121C001D1022300E0FF23DBB2FF2B0BD00269146E5D4D2540DBB21C04C0239B022340E2 +S2240121E02B43136601220978002901D0012100E000210069036E1024A343C9B20901102484 +S2240122002140194301661000C0B270BDFFFFFCFF70B582B005000C002869406E000901003B +S224012220C907C90F002901D1002037E00120002000902869406E000C8007800F002805D08F +S22401224002280FD008D3032812D017E069462800FDF7A5FF060012E069462800FDF732FF2D +S22401226006000CE069462800FDF7A8FF060006E069462800FDF793FF060000E0002628690E +S224012280406E000A8106890E491C022900D20221009800F0C2FB20603000C0B276BD70B51E +S2240122A00022002503695C6E1026B443EDB22D011026354025435D664B78012B01D10023E7 +S2240122C00AE04B78002B01D1012305E04B78022B01D1022300E0FF23DBB2FF2B0BD002695F +S2240122E0546E194D2540DBB21C04C0239B0223402B4353660122D2B2002A12D08B889B1E15 +S2240123003F2B0DD28B885D1E03695E6E0F4C3440EDB22E02FC25AD01354025435D6600E0BB +S22401232000220978002901D0012100E000210069436E1024A343C9B209011024214019432D +S22401234041661000C0B270BDFFFFFCFFFFC0FFFF0020704700B50978002901D0012100E062 +S22401236000210069826E10239A43C9B209011023194011438166012000BD80B50269D26EC3 +S22401238012091300DB07DB0F002B01D1002001E0FEF7AFFB02BD00B50978002901D001218F +S2240123A000E000210069C26E10239A43C9B20901102319401143C166012000BD80B5026963 +S2240123C0126F12091300DB07DB0F002B01D1002001E0FEF78EFB02BD00B50978002901D011 +S2240123E0012100E000210069026F10239A43C9B209011023194011430167012000BD80B5EA +S22401240002698023D25812091300DB07DB0F002B01D1002001E0FEF73BFB02BD00B5097866 +S224012420002901D0012100E0002100698022825810239A43C9B2090110231940114380227D +S2240124408150012000BD80B502698423D25812091300DB07DB0F002B01D1002001E0FEF769 +S22401246017FB02BD00B50978002901D0012100E0002100698422825810239A43C9B20901B4 +S22401248010231940114384228150012000BD80B502699423D25812091300DB07DB0F002B5B +S2240124A001D1002001E0FDF70DFE02BD00B50978002901D0012100E0002100699422825839 +S2240124C010239A43C9B2090110231940114394228150012000BD80B502699C23D258120978 +S2240124E01300DB07DB0F002B01D1002001E0FDF765FE02BD00B50978002901D0012100E0B1 +S224012500002100699C22825810239A43C9B209011023194011439C228150012000BD406A07 +S224012520086001207047806A086001207047C06A08600120704780B501220269A023D25811 +S224012540120C5207520F002A0BD0022A0FD00BD3042A12D00ED3062A15D011D3072A12D0B2 +S22401256014E0FFF7DCFF12E0FFF7DDFF0FE0FFF7DEFF0CE0FEF7C2F809E0FDF7BFFF06E0EE +S224012580FEF7B4F903E0FEF7B9F800E00020C0B202BD10B5020001204978042946D00629BE +S2240125A035D0082951D0372904D0382911D039291ED059E000231169A0228A58BA4C144024 +S2240125C0DBB21B04E022D2021A402243A023CA504BE001231169A0228A58B34C1440DBB28A +S2240125E01B04E022D2021A402243A023CA503CE002231169A0228A58AB4C1440DBB21B04EE +S224012600E022D2021A402243A023CA502DE003231169A0228A58A44C1440DBB21B04E022FF +S224012620D2021A402243A023CA501EE004231169A0228A589C4C1440DBB21B04E022D20223 +S2240126401A402243A023CA500FE005231169A0228A58954C1440DBB21B04E022D2021A4092 +S2240126602243A023CA5000E00020C0B210BD80B501220269A423D258120C5207520F002A1D +S2240126800BD0022A0FD00BD3042A12D00ED3062A15D011D3072A12D014E0FFF740FF12E058 +S2240126A0FFF741FF0FE0FFF742FF0CE0FEF726F809E0FDF723FF06E0FEF718F903E0FEF7F6 +S2240126C01DF800E00020C0B202BD10B5020001204978042946D0062935D0082951D03729DC +S2240126E004D0382911D039291ED059E000231169A4228A586C4C1440DBB21B04E022D20262 +S2240127001A402243A423CA504BE001231169A4228A58654C1440DBB21B04E022D2021A40C1 +S2240127202243A423CA503CE002231169A4228A585D4C1440DBB21B04E022D2021A402243AC +S224012740A423CA502DE003231169A4228A58564C1440DBB21B04E022D2021A402243A4233F +S224012760CA501EE004231169A4228A584E4C1440DBB21B04E022D2021A402243A423CA50E2 +S2240127800FE005231169A4228A58474C1440DBB21B04E022D2021A402243A423CA5000E011 +S2240127A00020C0B210BD80B501220269C023D258120C1300DB07DB0F002B02D0012B03D0EB +S2240127C005E0FEF79EFC03E0FEF774FC00E00020C0B202BD10B50200012049780E2910D046 +S2240127E010291DD100231169C0228A58794C1440DBB21A0480235B021A402243C023CA50CB +S2240128000FE001231169C0228A58724C1440DBB21A0480235B021A402243C023CA5000E008 +S2240128200020C0B210BD80B501220269C423D258120C1300DB07DB0F002B02D0012B03D066 +S22401284005E0FEF75EFC03E0FEF734FC00E00020C0B202BD10B50200012049780E2910D045 +S22401286010291DD100231169C4228A58594C1440DBB21A0480235B021A402243C423CA5062 +S2240128800FE001231169C4228A58524C1440DBB21A0480235B021A402243C423CA5000E0A0 +S2240128A00020C0B210BD0000FFFFF8FF80B50269CC23D25812091300DB07DB0F002B01D10E +S2240128C0002001E0FEF7E4F802BD00B50978002901D0012100E000210069CC2282581023AA +S2240128E09A43C9B20901102319401143CC228150012000BDF0B5059D069E079F089C01605D +S22401290042608360C56006614761216881616168C161A1680162002100210AE0C9B2042269 +S2240129204A43A218D268C9B204234B43C3185A62491CC9B20329F1D3F0BD38B503000C00D0 +S2240129401100E4B23F2C01DB00200FE00020224AE4B2082565435259002A06D018001E4A52 +S224012960E4B208235C4312599047C0B232BD38B504000B001100DBB23F2B01DB002027E047 +S2240129800020154ADBB208255D4352195268002A1DD012486268802550511148A2681066D9 +S2240129A0104822688025505120000B4ADBB208256B43D21852689047002162688023D150E2 +S2240129C00021A2681166002122688023D150C0B232BD0000FFFFFEFFF878010052455355D4 +S2240129E0202096194B4D4352F446002804D4494200F013F8404260474042002905D45FD019 +S224012A0000F00BF8404249426047494200F005F84942604703460B43E6D40022030A8B4212 +S224012A200BD203098B4219D243088B422ED2411A00D20146524110467047FF2209023FD088 +S224012A4012068B4205D3121209028B4201D31212090203098B4219D300E0090AC3098B4263 +S224012A6001D3CB01C01A524183098B4201D38B01C01A524143098B4201D34B01C01A524177 +S224012A8003098B4201D30B01C01A5241C3088B4201D3CB00C01A524183088B4201D38B00AF +S224012AA0C01A524143088B4201D34B00C01A5241884200D3401A5241CFD201461046704780 +S224012AC008B500F001F808BD7047704700B501000020C9B2002905D0022907D004D30329C3 +S224012AE006D006E0102004E0182002E0282000E04820C0B200BD70B50D00006804008034D5 +S224012B00002000263000C0B2FFF7E0FF0421FFF781FFF6B2002E06D1C0B2ADB26843042109 +S224012B20484320183AE0F6B2012E11D1C0B2ADB268430600ADB228001521FFF76BFF010059 +S224012B40022041433000401804214843201825E0F6B2022E11D1C0B2ADB268430600ADB2B9 +S224012B6028000C21FFF756FF0100042041433000401804214843201810E0C0B2ADB268432A +S224012B800600ADB228000721FFF744FF0100022041433000401804214843201870BD00B548 +S224012BA001000020C9B20A00002A082A0ED9093A0ED0521E0ED0521E0ED0521E0ED0521EAB +S224012BC00ED0521E0ED0521E0ED00FE008000DE00C200BE0102009E0142007E0182005E029 +S224012BE0202003E0302001E04020FFE7C0B200BD80B50022002289B2FFF77DFF0068000C6C +S224012C000007000FC0B2FFF7CAFFC0B202BD00B50023D2B2002A0CD00268C023DB03134353 +S224012C2003604268520F5207C900C908114341600BE00268AE4B134003604268AD4B13403F +S224012C408A04AD4911401943416000BD0268AB4B134003600268C9B20904F0231B030B405B +S224012C6013430360704700B502685200520802600268A34B13400360C9B2002909D00168BD +S224012C80802212060A43026001688022D2050A43026000BD00B5C9B2002906D10168994AFB +S224012CA00A400260016801600BE0C9B2012908D10168944A0A40026001688022D2040A430E +S224012CC0026000BD10B5016880310022002305E004225A438A18002414605B1C027E80242E +S224012CE062439342F4D310BD10B4874982688023D15001214268136D2024A343C9B2490143 +S224012D002024214019431165002180688022815010BC704710B47C4982688023D1500121DE +S224012D204268136D1024A343C9B209011024214019431165002180688022815010BC70475E +S224012D40F0B4049C059D069E079F3F780776016042608360C46005614661F0BC704700216E +S224012D6081600021016100214161002181610021C1600021C16100214162002181620021B5 +S224012D80C16200210162012101700021C170002101710021C94341630021C943816300210B +S224012DA0C943C1630021C943016400214422815400214170002181700021302281540021A2 +S224012DC045228154002146228154002147228154002151228154002150228154002152228E +S224012DE081540021532281540021482281540021C164704710B5002102681368404C1C407D +S224012E00C9B289078023DB051940214311600021026813683D4C1C40C9B2090780235B0577 +S224012E2019402143116001680968090E0A00D207D20F002AF7D110BD10B504002068006831 +S224012E40000D0100C907C90F002914D0002021680A6852005208C0B2C0071043086002E00C +S224012E602000FFF757FF20680068000D0100C907C90F0029F4D1012021680A68244B13406E +S224012E80C0B240068022920410401843086020680068400E0100C907C90F0029F7D1012030 +S224012EA021680A68164B1340C0B280078022D205104018430860012021680A68134B13400B +S224012EC0C0B200078022520510401843086020680068000E0100C907C90F0029F7D0206848 +S224012EE00068C00E0100C907C90F0029EFD010BDFFFF9FFFFFFF03E00000FC1FFFFFF0FFB3 +S224012F00FFFFFFBFFFFFFFF052455355FFFFFFEFFFFFFFFDF0B593B007000C001500EDB22E +S224012F20290089B23800FFF7E6FD0600227A61683000FFF76CFEA17A3000FFF787FEE17AFA +S224012F403000FFF790FE617A3000FFF7A3FE207B002805D0684605706946380000F0E2FBA6 +S224012F6020693968EDB204225543491988221201885013B0F0BD0000F8B505000F00002478 +S224012F802800FFF7B1FE3A7828684368E7491940D2B2520380239B011A400A43426028005F +S224012FA0FFF74AFF012228680368E1491940D2B2D20580231B041A400A4302600122286852 +S224012FC0436BDC491940D2B2120780235B051A400A4342632800FFF775FE3020385CFFF768 +S224012FE075FD0100C9B2002907D080208000C9B2FFF713FD0400287E4443286801687F2271 +S2240130009143E4B26206520E0A430260012029680A6D52005208C0B2C00710430865B868DB +S224013020401E29680A6DC44B134080B24205C348104018430865F868401E29680A6DC04B55 +S22401304013400204F82040031040184308653869401E29680A6DBB4B134080B28202FC206C +S22401306000021040184308657869401E29680A6DB54B134080B24201F820800010401843DE +S2240130800865B869401E29680A6D1F239A4380B2C006C00E10430865F87800281BD00120ED +S2240130A029680A68A94B1340C0B2400780229205104018430860387929680A68A44B1340C5 +S2240130C0C0B2C00380221202104018430860386C2968886417E0002029680A689B4B134078 +S2240130E0C0B2400780229205104018430860002029680A68964B1340C0B2C0038022120283 +S224013100104018430860786B29680861B86B29684861F86B296888614420385C29680A6884 +S2240131208C4B1340C0B20004802252021040184308604520385C002818D0002029680A68B4 +S224013140854B1340C0B2400480229202104018430860012029684A68804B1340C0B2000350 +S2240131608022520110401843486017E0012029680A68794B1340C0B2400480229202104093 +S22401318018430860002029684A68744B1340C0B20003802252011040184348605020385C30 +S2240131A000282FD0012029680A686D4B1340C0B280058022D2031040184308600120296880 +S2240131C00A68684B1340C0B280068022D204104018430860012029680A68634B1340C0B257 +S2240131E080048022D202104018430860012069698A6C01239A43C0B20300DB07DB0F13433B +S2240132008B642EE0002029680A68554B1340C0B280058022D2031040184308600020296863 +S2240132200A68504B1340C0B280068022D204104018430860002029680A684B4B1340C0B227 +S22401324080048022D202104018430860002069698A6C01239A43C0B20300DB07DB0F1343DB +S2240132608B645120385C29680A683C4B1340C0B20003802252011040184308605220385CF4 +S22401328029684A68324B1340C0B2C003802212021040184348605320385C29684A68334B0F +S2240132A01340C0B280038022D201104018434860002000261AE02200D2B2F86CF6B21421D1 +S2240132C0714341182800FFF725FE641CA4B2F86CF6B214217143405AF96CF6B2142272433D +S2240132E08918498840188442E5DB761C30004821795CC0B2884206D20020F86CF6B2142103 +S2240133007143445AE2E7280000F08DF92800FFF771FD002029680A68054B1340C0B2C00565 +S22401332080221204104018430860F1BDFFDFFFFFFFFF7FFFFFFFFFEFFFFF1F800000E07FCE +S224013340FFFFE0FFFF03FFFF1FFCFFFFFFFFFFDFFF7FFFFFFFFFFEFFFFFFFDFFFFEFFFFF38 +S224013360FFFFBFFFFFFFFFFBFFFFFBFFFFBFFFFF80B5097889B2FFF7BEFB0168C0221205DD +S2240133800A43026001BDF8B506000D00297889B23000FFF7B0FB04000834297889B2300001 +S2240133A0FFF726FC0600002000271DE0FFB238000421FFF72FFB032915D12068FFB2E9192A +S2240133C0097A01432160241D0DE0FFB238000421FFF720FB0229E9D12068FFB2E919097AAF +S2240133E00902014321607F1CFFB2B7421FD2FFB238000421FFF70EFB002909D10020206011 +S2240134002068FFB2E919097A090601432160EAE7FFB238000421FFF7FDFA0129D5D12068F0 +S224013420FFB2E919097A090401432160DBE7F1BDF8B506000D00297889B23000FFF75BFBF6 +S22401344004002068000C0007000FFFF7A8FB48216854206801008902C90F201DC9B200292D +S22401346004D00168C900C908696004E00168890C4905490D6960041D297889B23000FFF734 +S224013480B7FB694608700020002712E02068FFB2E9190872241D0BE0FFB238000421FFF72F +S2240134A0B9FA0229F2D12068000AFFB2E91908727F1C380069460978C0B2884219D2FFB2CB +S2240134C038000421FFF7A6FA002905D12068000EFFB2E9190872EBE7FFB238000421FFF75B +S2240134E099FA0129D8D12068000CFFB2E9190872DEE730688068F1BD30B504000D00002096 +S22401350028782021FFF786FA012088402978402911DB0221226800290AD0022904D005D3E8 +S224013520032907D1106705E0506703E0D06201E01063FFE725E02978202911DB0121226898 +S22401354000290AD0022904D005D3032907D1106705E0506703E0D06201E01063FFE710E035 +S2240135600021226800290AD0022904D005D3032907D1106705E0506703E0D06201E0106340 +S224013580FFE730BD30B504000D00002028782021FFF740FA012088402978402913DB022226 +S2240135A023680021002A0AD0022A04D005D3032A07D1196F05E0596F03E0D96A01E0196BB8 +S2240135C0FFE7014029E02978202913DB012223680021002A0AD0022A04D005D3032A07D12D +S2240135E0196F05E0596F03E0D96A01E0196BFFE7014012E0002223680021002A0AD0022AEE +S22401360004D005D3032A07D1196F05E0596F03E0D96A01E0196BFFE70140002901D00120F1 +S22401362000E0002030BD00B5017E032939D10021C94302220368002A0AD0022A04D005D395 +S224013640032A07D1196705E0596703E0D96201E01963FFE70021C94301220368002A0AD01A +S224013660022A04D005D3032A07D1196705E0596703E0D96201E01963FFE70021C943002292 +S2240136800068002A0AD0022A04D005D3032A07D1016705E0416703E0C16201E00163FFE7B5 +S2240136A03FE0017E022926D10021C94301220368002A0AD0022A04D005D3032A07D1196728 +S2240136C005E0596703E0D96201E01963FFE70021C94300220068002A0AD0022A04D005D34B +S2240136E0032A07D1016705E0416703E0C16201E00163FFE715E0017E012912D10021C943EB +S22401370000220068002A0AD0022A04D005D3032A07D1016705E0416703E0C16201E00163F8 +S224013720FFE700BD30B504000D00002028782021FFF770F9012088402978402919DB022180 +S2240137402268002910D0022906D009D303290FD1916E084390660BE0D16E0843D06607E015 +S224013760516A0843506203E0916A08439062FFE735E02978202919DB01212268002910D0E2 +S224013780022906D009D303290FD1916E084390660BE0D16E0843D06607E0516A08435062B0 +S2240137A003E0916A08439062FFE718E000212268002910D0022906D009D303290FD1916E6E +S2240137C0084390660BE0D16E0843D06607E0516A0843506203E0916A08439062FFE730BD6A +S2240137E0F9B58FB01798002301230493012303930823009303230193022314230C93774B5A +S2240138000B93FA239B050A93C0B200280BD0744809905E26032008901F203018401C079027 +S224013820082006900AE06E48099026260320089007203018401C07900820069002920D9132 +S224013840029800F0D7F8059001242EE0280000F0E1F80100380000F0E8F80700029800F0B6 +S224013860C9F80100380000F06DF98021090400F0C1F939D8029800F0BDF80100380000F021 +S22401388061F901000798A8420EDB059800F0B2F90AD80494009505910C98A84204DB080003 +S2240138A00B9900F0BBF927D3641C0998A04223DB0D9800F09FF80500200000F0ABF80100DA +S2240138C0280000F0B2F80700029800F093F80100380000F0AAF800F0B5F90500002D02D097 +S2240138E006988542B2DA07E0029800F083F8390000F028F90100C5E710A80488A4B2200034 +S22401390000F078F80A9900F0BAF905000098B04200DA009E0CE0380000F07CF8290000F053 +S2240139207DF904D20196380000F074F80500761E0898864212DB3000401C2A4948430099F9 +S224013940FFF768F8A4B2011B012902DBA4B2071B01E0A4B2271AA4B2A042DCDA169C00986A +S2240139600199401A401E02901F4D01261AE0A4B2271A0AE01B4870430099FFF74BF8A4B211 +S224013980011B0129F3DBA4B2071B380000F042F8290000F043F904D20396380000F03AF815 +S2240139A00500761C0298B042E4DA0F9C04982060019800F0CDF90DA20CCA00F0D3F900F0D9 +S2240139C093FAA0600198A168401AE060029820610398606011B0F0BD00000000CDCCCC3D92 +S2240139E0FF0300001027000000401C46333333333333E33F9D2102000AD002D4491E921811 +S224013A00FCD5C905100A1206524100D3012A4841704700009D210200EED55242F446FFF7B7 +S224013A20EBFF0122D2071043604730B405004D400122D20715404B180418240E28D01B0E07 +S224013A402FD0FF2C34D0FF2B37D0E41A000209021043114343084808D10D1B1A02D2641E4B +S224013A60DB181B18DB18834200D31B1A4941F9D37F3426DDFE2C08DAE4054808C9071943DD +S224013A8091416041284330BC7047FF20C005F9E728001B0E03D0FF2BF5D14902F3D0D043A6 +S224013AA0F1E7FF2C01D14002F9D1FF20C005E9E74002F4D1FF2BF8D1F1E728004902E2D074 +S224013AC0EDE70B0200202442DCD15B129B1CD9D9D805D7E70122D20703004B402ED4431A72 +S224013AE001D2C01AC91830B44B180418240E1B0E22D0FF2C20D0E31A182B1DDC09021143CF +S224013B00C40D641E0002104394461925ED1A0A00AA40D940451801D36D08A41CE405D209A1 +S224013B20280A2D062A436546AA41604103181B0EFF2B01D3C00DC00530BC7047514006E088 +S224013B405140CCE70122D20703004B40F8D4431A03D2C01AC9185040514030B44B18090265 +S224013B6011430418240E1B0E40D0FF2C3AD025009D410BD31ED8C50D4002401A0BD3ED051A +S224013B800100400AC90591416841D5E7C50D40024918401AD0D001214008491C0018FCD5A8 +S224013BA08C4204D36D1A000AED054019C4E7E8051040C1E7182DBFDCAC1C0D00E140E541F2 +S224013BC04D40012D4941C40D00021043451A01D46D199543641EE405280A2D06954160419B +S224013BE030BC7047FF2BA7D1D843A5E72442A3D10020A1E70CB4012212060318DA4207D840 +S224013C004B18DA4204D802000A43921802D281420CBC7047FCD088420CBC70470CB401223C +S224013C2012060318DA4207D84B18DA4204D802000A43921802D288420CBC7047FCD0814250 +S224013C40FAE700000122D2070118090E7F3910D449421F310FD4001805D2C0011043C840EC +S224013C6000D5D0437047C0011043C84005D440427047002070470042F3D51000704730B4E5 +S224013C8005004D400122D20715404B180418240E2ED01B0E32D0FF2C34D0FF2B3AD0E41802 +S224013CA00002090210431143000A090A9446C2B24A43000AC3B24B43000A4843110A5B1822 +S224013CC01A43D2B2190A091801D44918641E080A7F3C23DBFE2C08DAE40509061143634635 +S224013CE099416041284330BC7047FF20C005F9E728001B0EFF2BF6D1D043F4E72800FF2CEE +S224013D00F1D1F9E74002F7D1FF2B01D14902F3D1E005E7E7D8054902E4D0EDE7430200201E +S224013D20641CDFD15B129B1CDCD9D805DAE70000010042221201D21E004207D002D4521E0F +S224013D400018FCD5C10A400512058918704700000100EED54042F446FFF7EBFF0122D20799 +S224013D6011436047F0B50E005E400125ED072E40B446AE0ADF184C18F44208D2F7420ED233 +S224013D80640D01D07F0D12D100206146F0BD05D1F74201D87F0D05D10020C143F0BDFBD111 +S224013DA0640DF9D00020C143490549088FE0E419C902DB0229432B43DB0A460DC0023143A4 +S224013DC08E4630B487B295B27D432E0CADB2140C7C43A419260C240425439CB27C43A41924 +S224013DE0190C7943270CC919A4B20F043C43090C000C97B247432E0CBE193543ADB2170CE0 +S224013E004743360CBF19A6B2BF193E043543240C3E0C36199FB24743BF19BCB23E0C891938 +S224013E201F0C47437F183E043443390C704680B297B247432E0CBE193543ADB2170C4743E2 +S224013E40360CBF19A6B2BF193E043543240C3E0C36199FB24743BF19BCB23E0C89191F0C57 +S224013E6047437F183E043443390C77463F0C90B278432E0C80190604ADB22E43050CA0B208 +S224013E802D18120C7A435019020C80B2240CA4189AB27A43121914042043120C89181B0CD2 +S224013EA07B43C91830BCEF0A394203D1B61940414941641E6F12BF0DE41B0BDBFF19BC4285 +S224013EC011DA240500274208AE417841614166463143F0BD641C05D1401C6141CF0201D347 +S224013EE04908F4E750E75DE74A1812D2400DC90208430121C9070843520D40210901521AF9 +S224013F00521C06D452421F3201D4D0407047C017704700207047000000B5C0B2802800DBC3 +S224013F207F20C0B200BD00B5C0B20100F139092901D2012003E0C0B2802800DB0020C0B2CB +S224013F4000BD30B583B00400180000233F236D462B706B461B78F0250D431D4069460D7065 +S224013F6069464A70C0B2FFF7D7FF69468870207800280FD0032004E000216A46C0B211549F +S224013F80401CC0B20828F7DB08226946E068A36D984704E003226946E068A36D984740B25A +S224013FA03EBD00B583B00300002000200F206946087068460078D98AF0220A4302406846A7 +S224013FC00270002007E01969C0B2095C6A46C0B212185170401C0100C9B2DA8A89B29142B2 +S224013FE0F1D31878002815D0002007E06946C0B2DA8A8218891800224A70401CC0B20721C1 +S224014000DA8A891A8842F1DB08226946D8689B6D984706E0DA8A521CD2B26946D8689B6DCA +S224014020984740B20EBD1CB504001F206946087068460078E18A89B2090AF0220A43024023 +S22401404068460270E08A694648700020002007E02169C0B2095C6A46C0B212189170401C38 +S224014060C0B20628F4DB08226946E068A36D984740B2002804D1218B891D21830121A1769D +S22401408040B216BD30B583B0040000202F206946087068460078A17EF0220A43024068460F +S2240140A00270E08A218B451AADB2082D00DB0725002009E02169228BC0B21218895C6A4607 +S2240140C0C0B212185170401C0100C9B22A0089B292B29142EED32078002816D00020002082 +S2240140E007E06946C0B2ADB24219891800224A70401CC0B20721ADB2491B8842F1DB082202 +S2240141006946E068A36D984706E02A00521CD2B26946E068A36D984740B200280AD1218B2A +S22401412049192183A17E491CA176A17E102901DB0021A17640B23EBD10B503000020087817 +S2240141400007000F002806D0D2B2521E08780007000F824208DA586D002802D09348596DB5 +S22401416088470620C04315E008780007000F42229852002006E0C0B20A185278DC6BC0B24B +S2240141802254401C0200D2B242241C5B92B2A242F1D3002010BD10B503000020D2B2082A6D +S2240141A008D0586D002802D08148596D88470620C04336E008780002F0221201024048781C +S2240141C0101880B2082808DA586D002802D07948596D88470620C04323E040229A5A0400D2 +S2240141E0A4B2A24208D2586D002802D07248596D88470220C04314E042229852002006E02A +S224014200C0B20A189278DC6BC0B22254401CC0B20628F5DB06204421585201204621585496 +S224014220002010BD70B5030000204620185C0C782407240FA04202D00320C0433BE0422030 +S224014240185A44241C5B001B80B2082800DB0720D2B2521E80B2824208DA586D002802D0FD +S2240142605648596D88470620C04324E0002209E0DC6BD2B244255D5B5519D2B28E1876785B +S2240142806655521C1400E4B20500A4B2ADB2AC42EED34421595A0818442158524620185CBB +S2240142A0401C462158544620185C102802DB002046215854002070BD80B50100D2B2032A33 +S2240142C008DA486D002802D03D48496D88470620C04300E0002002BD80B513009BB20A00B6 +S2240142E0C16800F001F802BD38B504000020002C02D10020C04357E0A08A190089B2884235 +S22401430008D2606D002802D0BF48616D88470220C04349E03420205C012808D1606D00283D +S22401432002D0BA48616D88470120C0433CE0E38200202083002005E0C0B2115C2569C0B2BA +S2240143402954401C0100C9B21D0089B2ADB2A942F2D3E08A082804DA2000FFF722FE0500E8 +S22401436020E02000FFF75FFE05006DB2002D19D10020A0830020A0770020E077E06D804784 +S2240143802200203203C2083AE06D80470022643051412200283203C2083A002020630120F9 +S2240143A034216054280040B232BD0000988B0100C48B0100908A0100C88A0100F08B010087 +S2240143C0108C01007CB514001A00D2B213009B1E072B00D316E10023002305E0DBB2E55C96 +S2240143E06E46DBB2F5545B1C1D001600EDB2F6B2B542F3D3002306E000246D46DBB2D2B28E +S2240144009E18AC555B1CDBB20824D2B2A41AA342F2DB0D00040068460078C0B200090028E1 +S22401442006D002285AD01CD3032800D19DE0E9E05120205C012804D10520C04350216054E3 +S22401444002E0002050216054D2B269462000FFF773FE40B2002803D1A56302205121605437 +S224014460D0E05120205C012804D10520C0435021605402E0002050216054D2B269462000D4 +S224014480FFF789FE40B20221C94388420DD10720C0435021605400205121605400230022F6 +S2240144A002212000FFF74DFDACE040B2002814D1A563012051216054607847216054012381 +S2240144C04720225C00212000FFF73BFDE06D8047002264305141A064E16493E05120205C7D +S2240144E0012804D00520C043502160548AE0A06B854200D086E0D2B269462000FFF792FE21 +S22401450040B20321C943884207D10320C0435021605400205121605474E040B2002823D1DE +S224014520E06D8047002264305141A064E1644420205A4221615A884203D3022051216054EC +S22401454012E04720205C401E472160544720205C002809D160784721605401234720225C24 +S22401456000212000FFF7EDFC4CE03420205C012848D1D2B269462000FFF79EFE40B20028D8 +S2240145803FD1E06D80470022643051412200283203C2083A684600780007000F022806D1E9 +S2240145A00720C043206302203421605429E0684600780007000F01280CD1E07F401CE077C0 +S2240145C0E07F02281DDB0620C043206302203421605416E0684600780007000F002810D142 +S2240145E068464078002802D18648A08302E068464078A08368468078FFF795FCA077002094 +S224014600E077FFE773BD0000008B0100348B010030B500245124045D022C02D00420C043D5 +S22401462024E0846B8568AC4201D1012400E000240C704221415A1C000D00A4B2ADB2AC4265 +S22401464000D21900002305E0C46B9BB2E45C9BB2D4545B1C1C000D00A4B2ADB2AC42F3D327 +S224014660039A1180002151228154002030BD10B402000B00187810705878507058685060AF +S22401468098689060D868D06018691061988A90820020D08200201083002090760020908310 +S2240146A0002090770020D077002000211400203403C4083C002000211400283403C4083CF6 +S2240146C0002010630020342150549869D063988B4021505200204221505200204421505282 +S2240146E0002046215054002047215054002000219064D16400205021505400205121505488 +S224014700186A5065586A9065986AD06510BC704710B504003420205C01285BD1A08B394950 +S224014720884202D0A08B002840D0A07F002810D0A07F00283AD0E06D804702000B002000BB +S224014740203003C8801A994100292FDC01DB00282CD22000FFF796FC40B2002823D1A08BAD +S2240147602849884202D0A08B401EA083E06D80470022643051412200283203C2083AE06D4E +S224014780804702000B00A07F0021801859412200203203C2083A208BE18A884206D3002079 +S2240147A03421605402E0022034216054E06D804702000B002000283003C8801A99410029DC +S2240147C008DC01DB002805D20120C04320630220342160545120205C012811D1E06D804736 +S2240147E0A26CE36C121A8B41002B09DC01DB002A06D20220C04350216054002051216054E0 +S22401480010BD0000FFFF0000F0B540B200281BD4AE4A40B2830804246343D258FF238407FF +S224014820A40F08256C43A3409A438901C9B283079B0F0824634399401143A44A40B2800883 +S22401484004235843115020E0A14B40B20207120F083A9208042462439D4C40B205072D0F5B +S224014860083DAD08042675436459FF258607B60F08277E43B540AC438901C9B28007800F34 +S22401488008256843814021439950F0BD80B5411E80225204914201D301200EE0401E8D4909 +S2240148A0086003210020C043FFF7AEFF00208A4908600720C1490860002002BD00B5017A9D +S2240148C000290FD0417A00290CD101684268914208D20168491C016001684268914201D162 +S2240148E00121417200BD10B5040088200001201803C80022401C514188221201A21803C25F +S224014900083A892000012018FFF7D8FF73482018FFF7D4FFAA482018FFF7D0FF10BD704870 +S224014920A84908607047A84803C8704780B5A7480068401CA5490860A34803C80022401C7D +S2240149405141A14A03C2083AA148FFF7CCFF01BD30B593B00020002450E069469D480068CD +S224014960FEF7CAFD49E068460470694699480068FEF708FE002840D09748C06CE4B2142129 +S22401498061434018407A0128E7D1694691480068FEF7B2FD69468F480068FEF749FD68460F +S2240149A04821425C6846010008318C488C4B1B784C256B43C018051D280000F06FFB019890 +S2240149C08649874A12784C235A4388508348844909784C225143401844216A464823D25CA2 +S2240149E042547F480078401C7D4908707C480078202802D300207A490870641C200079492C +S224014A000978C0B28842AED313B030BD10B50400002073490978744A1278914216D04C220D +S224014A206E48714909784C2359434118200000F035FB6D480078401C6B4908706A480078FC +S224014A40202802D30020684908700120C0B210BD70B594B000230024002400E0641C250031 +S224014A60604E3678EDB2B54209D25B4DED6CE4B214266643AD196D68A842EFD123005648E3 +S224014A80C06CDBB214245C43005B6C4620706846482402555048C06CDBB214246343C0186B +S224014AA040680190D2B2684604000834200000F0F5FA694647480068FEF765FC694645480E +S224014AC00068FEF755FC002014B070BD00E400E01CED00E014E000E018E000E09C08000014 +S224014AE055AAAA55E0B500200290404839490860012205213E4800F06DFB012205213C4805 +S224014B0000F0A0FB01220521394800F0A8FB05220421384800F05EFB05220521354800F0D8 +S224014B2059FB2D48FEF71BF908202E49087032482949C8640120284908700020264948701D +S224014B4000202549887000202349C87000202B49087001202A4908701F480078012805D10F +S224014B6002AA0B212748FDF7E8FE04E002AA03212448FDF7E2FE1848407801280AD10120DD +S224014B800190FA20C00000901F4B204A02992048FEF726FE002001901E4800901A4B1E4AB0 +S224014BA002991E48FEF71CFE0B490A480068FEF7E3F9092000F088FB07BD000010E000E0D0 +S224014BC0A8080000F063002000200020442A002008200020B84700206447002060340020F8 +S224014BE060470020AC47002061470020442900209C290020AC290020C4880100944700205E +S224014C00A8470020CC2800204C1D000080841E0080470020C409000020A107006C47002091 +S224014C2010B59EB000F044FBD24800F053FBD24800F0B8FCD1490022D14C200000F0E2FCCF +S224014C4054210022CF4C200000F0DCFC012069460876022006A94870012006A9888006AA55 +S224014C600721C948FDF783FE012069460876012006A9888006AA1321C348FDF778FE06AA51 +S224014C801421C148FDF773FE06AA1521BE48FDF76EFE06AA1621BC48FDF769FE06AA1721F1 +S224014CA0B948FDF764FEFFF71DFF01220321D54800F090FA01220321D24800F0C3FA022275 +S224014CC00321D04800F01BFA01220321CD4800F0C6FA01220B21CC4800F07CFA01220B2169 +S224014CE0C94800F0AFFA02220B21C74800F007FA01220B21C44800F0B2FA01220521C1486B +S224014D0000F068FA01220521BE4800F09BFA02220521BC4800F0F3F900220521B94800F004 +S224014D209EFACD49CD4800F097FCCD4A09219648FDF703FECA480068FA218900FDF76DFE96 +S224014D40FFF7A4FDC74800F0BFFA00F0A1FA0AE0AA206946C87108226946C348FFF778FE87 +S224014D60BE4800F024FDC14800680028FBD0BB484078022805D1FFF7D2FD2321BC4800F0FA +S224014D809BFDBA480068401EB8490860B9480068401CB8490860B8480068401CB6490860EB +S224014DA0B648007800284DD1B3480068FA21890088422BD30020B0490860B1480068002858 +S224014DC012D10120AE490860012205218D4800F046FA012203218B4800F041FA01220B2188 +S224014DE0894800F03CFA11E00020A549086000220521844800F033FA01220321814800F01E +S224014E002EFA00220B21804800F029FA99480068022800D2DEE004A80021002206C0083843 +S224014E2000209449086095480078694608749248006804A9C870082204A9FF201230FFF732 +S224014E4007FEC7E08D480078012800D0C2E0894800680A2814D302A80021002206C0083873 +S224014E6000208449086085480078694608728248006802A9C870082202A97B48FFF7E8FDE1 +S224014E807D480068FA218900884200D2A2E00020794908607B480078002820D17A48007845 +S224014EA000281CD179480078002818D100220521544800F0D4F901220321524800F0CFF953 +S224014EC001220B21504800F0CAF901206D49087000206D49087000206C4908707AE069483D +S224014EE00078012820D16848007800281CD167480078002818D100220521424800F0AFF93B +S224014F00002203213F4800F0AAF901220B213E4800F0A5F901205B49087001205A4908704F +S224014F2000205A49087055E05648007801282DD155480078012829D154480078002825D154 +S224014F40002205212F4800F08AF9002203212D4800F085F900220B212B4800F080F90120A5 +S224014F604849087001204849087001204749087030E000BFC4280020402A00200413000053 +S224014F806034002064470020CC2800203D48007801281FD13C48007801281BD13B48007856 +S224014FA0012817D101220521164800F058F901220321144800F053F901220B21124800F07A +S224014FC04EF900202F49087000202F49087000202E4908700BA8FFF719FD012800D0BFE6F8 +S224014FE00B982B49884203D00B982A4988420DD10BA84421435C0BA8021D0B992648FFF7A8 +S224015000E1F9ADE6A42900208C29002068460021002206C0083800201649086017480078A6 +S224015020694608700B98000A694648700B98694688706846C078401C6946C8700F480078ED +S224015040002800D084E655206946C871082269460548FFF7FDFC83E6400000200820002065 +S224015060542A0020FFFF000022020000442A0020D0290020482A0020502A0020480400202B +S2240150804C2A00206A4900206B4900206C49002032070000DF07000020200020124207D04E +S2240150A08B0706D00B78491C0370401C521EF7D87047830706D00B78491C0370401C521E4E +S2240150C0F9D1704770B4103A03D378C9103A78C0FBD2530701D318C918C001D508C908C01F +S2240150E0D20704D30B880380891C801C002A01D50B78037070BC704701604260704770B5EB +S224015100122966D2D2B2002A03D0022A41D020D35FE000250A000368042454431C59022630 +S224015120B443EDB26D00022635402543042462439D500022006804234B43C3580124A34342 +S224015140D2B21400E407E40F1C430422514344503FE001250A000368042454431C59022610 +S224015160B443EDB26D00022635402543042462439D500022006804234B43C3580124A34302 +S224015180D2B21400E407E40F1C430422514344501FE000250A000368042454431C590226F1 +S2240151A0B443EDB26D00022635402543042462439D500122006804234B43C3580124A343C1 +S2240151C0D2B21400E407E40F1C43042251434450FFE770BDF0B516000C0005680423634392 +S2240151E0EF58174B3B40F6B23702E026F6003E401E4304235C432E51D2B2002A0FD10122D3 +S224015200006804234B43C3580424A343D2B29200042422401A430423594342500EE00022E0 +S224015220006804234B43C3580424A343D2B29200042422401A43042359434250F0BD000023 +S224015240FFF8FFFF10B443685B6901248C40A343D2B28A401A434068426110BC704710B40C +S22401526043681B6801248C40A343D2B28A401A434068026010BC704700B540B2002805D443 +S2240152800121C006C00E81400D48016000BD000000B50C480068012809DB0A480068401E88 +S2240152A00849086007480068012800DA62B600BD72B604480068401C0249086070470000FE +S2240152C000E100E0C028002080B540B2FFF7D4FF01BD000010B58CB004007E4A7E4920009D +S2240152E000F098FE7D4805907D48069000200790002008900020099000200A9005A803904B +S224015300784802907848019078480090784B794A794920000830FDF7EDFA784920003830D0 +S22401532000F07CFE764920003C3000F079FE75492000403000F074FE73492000443000F05B +S22401534071FE724A72492000483000F06DFE71492000543000F06BFE6F492000583000F067 +S22401536068FE6E4920005C3000F066FE604A6C492000603000F062FE02206946087404A8B2 +S2240153800390544802905748019059480090594B554A644920008030FDF7D2FC6249200098 +S2240153A09C3000F031FF4B4A60492000A03000F040FF484A5E492000A83000F03DFF5D499B +S2240153C02000B03000F03CFF5B492000B43000F039FF5A492000B83000F036FF584920003B +S2240153E0BC3000F031FF57492000C03000F02EFF55492000C43000F02BFF544A54492000A7 +S224015400C830FFF779FE534A53492000D030FFF773FE524A52492000D830FFF76DFE514A06 +S22401542051492000E030FFF767FE504A50492000E830FFF761FE2E4B2C4A4E492000F030BB +S22401544000F008FF234A4C492000FC3000F006FF204A4A4982204000201800F0FFFE254B98 +S224015460214A254986204000201800F01DFA44498C204000201800F0F5FE4249B0204000F9 +S224015480201800F0FBFE4049B2204000201800F0F5FE104A3D49B4204000201800F010FF04 +S2240154A03B49B8204000201800F00EFF3949BA204000201800F008FF3749BC204000201876 +S2240154C000F002FF3549BE204000201800F068F80CB010BD00F005400040024000127A00E5 +S2240154E00024F40000E8064000F8064000E4064000E0064000F0064000F0074000400740DE +S224015500003000400040004000C00040001002400080004000900140008001400050004061 +S22401552000000240008003400060064000200740003007400070074000500740000003404B +S2240155400010034000D000400060024000500340000006404050034000100640805003402B +S22401556000200640C050034000300640005103400040064000D0074000800540009005402B +S2240155800080074000C0024000D0024000E0054000A0064000B0064000C0064000A007403C +S2240155A00160704710B5016809684A091100C907C90FC9B2012920D11049026851600021F7 +S2240155C0026813688024A343C9B2C90180242140194311600A490268916001680968C90AE4 +S2240155E00A00D207D20F002AF7D101680968490A0A00D207D20F002AF7D010BD20C528D95A +S224015600FFFF00001206130A1A43130C1A4300BF094205D0830705D00270401C491EF9D13B +S22401562070470000130030B414001500103902D310393CC0FCD2490700D30CC000D504C0D4 +S224015640890002D30280801C002900D5027030BC704700000022E5E710B50400200000F0EE +S2240156606EF80548A0600548E0600F206060044820612820A08210BD64890100688B01000F +S224015680C801002000210160002141600021017200214172704700220260416001210172FE +S2240156A0002141727047407A70477CB504000E00150068460021002206C00838EDB2782D55 +S2240156C005D06E48215A6E482018FFF7E4FF7920205C00280FD0EDB2112D0BD0EDB2122D45 +S2240156E008D0EDB2312D05D0EDB27E2D02D0EDB27F2D00D10CE07F206946087068464670AC +S224015700684685700322694620001830FEF7E4FD73BD10B50022002200E0521C92B2436858 +S2240157209A420AD2836892B2082454431B5D0C00E4B2A342F1D1012000E0002010BD38B51D +S22401574005000C00210028001830FEF790FF012068700020A8700020782168540020002136 +S22401576088221201AA1803C2083AA08D45496852E08D45496852208E4049685289200001D8 +S2240157802818FFF77FFF41482818FFF77BFF3C482818FFF777FF0020002004E000212A185F +S2240157A07B23D154401C3A498842F7D331BD7CB50400002069468880002000200020200033 +S2240157C01830FEF7A5FF01A80090314B22007B322100793120001830FEF71AFF40B2002803 +S2240157E03CD17B20255C2900C9B22000FFF791FF00282DD0002300E05B1C606883422DD205 +S224015800A06808215943405C2900C9B28842F3D1A0680821594340188078002806D07C2030 +S224015820205CC0B2C0097821605402E000207821605418007A2160546846828821007B3123 +S2240158402000A56808267343EB185B68984705E011222900C9B22000FFF727FF084820180C +S224015860FFF721FF012807D1012060700020A07003482018FFF706FF73BD00008C080000A8 +S224015880A8080000880800008A0800009C0800000208000000B5BFF34F8F0548054908603A +S2240158A0BFF34F8F00BFFDE701604260836070470400FA050CED00E010B504002F48A268EC +S2240158C08023D050C9B200295AD0022900D185E06DD3042900D1AFE000D296E0062900D1BB +S2240158E0D8E000D2BFE0082900D101E100D2E8E00A2900D12AE100D211E10C2900D153E1EE +S22401590000D23AE10E2900D17CE100D263E1102900D1A5E100D28CE1122900D1CEE100D2BD +S224015920B5E1142900D1F7E100D2DEE1162900D120E200D207E2182900D149E200D230E266 +S2240159401A2900D172E200D259E21C2900D19BE200D282E21E2900D1CCE200D2AFE2202991 +S22401596000D1FDE200D2E0E2222900D12EE300D211E3232900D144E346E300BF524553557F +S2240159800120A1684A6801239A43C0B20300DB07DB0F13434B600020A1684A6801239A4306 +S2240159A0C0B20300DB07DB0F13434B602CE30120A1688A6801239A43C0B20300DB07DB0F32 +S2240159C013438B600020A1688A6801239A43C0B20300DB07DB0F13438B6015E30120A168C0 +S2240159E0CA6801239A43C0B20300DB07DB0F1343CB600020A168CA6801239A43C0B20300DB +S224015A00DB07DB0F1343CB60FEE20120A1680A6901239A43C0B20300DB07DB0F13430B61B2 +S224015A200020A1680A6901239A43C0B20300DB07DB0F13430B61E7E20120A1684A690123F6 +S224015A409A43C0B20300DB07DB0F13434B610020A1684A6901239A43C0B20300DB07DB0F02 +S224015A6013434B61D0E20120A1688A6901239A43C0B20300DB07DB0F13438B610020A168A2 +S224015A808A6901239A43C0B20300DB07DB0F13438B61B9E20120A168CA6901239A43C0B21E +S224015AA00300DB07DB0F1343CB610020A168CA6901239A43C0B20300DB07DB0F1343CB616F +S224015AC0A2E20120A1680A6A01239A43C0B20300DB07DB0F13430B620020A1680A6A0123D8 +S224015AE09A43C0B20300DB07DB0F13430B628BE20120A168CA6A01239A43C0B20300DB079C +S224015B00DB0F1343CB620020A168CA6A01239A43C0B20300DB07DB0F1343CB6274E2012079 +S224015B2061680A6801239A43C0B20300DB07DB0F13430B60002061680A6801239A43C0B253 +S224015B400300DB07DB0F13430B605DE2012061684A6801239A43C0B20300DB07DB0F13433C +S224015B604B60002061684A6801239A43C0B20300DB07DB0F13434B6046E2012061680A6911 +S224015B8001239A43C0B20300DB07DB0F13430B61002061680A6901239A43C0B20300DB0747 +S224015BA0DB0F13430B612FE2012061684A6901239A43C0B20300DB07DB0F13434B61002021 +S224015BC061684A6901239A43C0B20300DB07DB0F13434B6118E2012061688A6901239A4327 +S224015BE0C0B20300DB07DB0F13438B61002061688A6901239A43C0B20300DB07DB0F1343A8 +S224015C008B6101E201206168CA6901239A43C0B20300DB07DB0F1343CB6100206168CA69B2 +S224015C2001239A43C0B20300DB07DB0F1343CB61EAE1012061680A6A01239A43C0B20300FB +S224015C40DB07DB0F13430B62002061680A6A01239A43C0B20300DB07DB0F13430B62D3E199 +S224015C60012061688A6A01239A43C0B20300DB07DB0F13438B62002061688A6A01239A43DD +S224015C80C0B20300DB07DB0F13438B62BCE1012061680A6B01239A43C0B20300DB07DB0F3C +S224015CA013430B63002061680A6B01239A43C0B20300DB07DB0F13430B63A5E10120616846 +S224015CC04A6B01239A43C0B20300DB07DB0F13434B63002061684A6B01239A43C0B20300AF +S224015CE0DB07DB0F13434B638EE1012061680A6C01239A43C0B20300DB07DB0F13430B64F8 +S224015D00002061680A6C01239A43C0B20300DB07DB0F13430B6477E1012061684A6C0123FB +S224015D209A43C0B20300DB07DB0F13434B64002061684A6C01239A43C0B20300DB07DB0F59 +S224015D4013434B6460E1012061688A6C01239A43C0B20300DB07DB0F13438B6400206168A7 +S224015D608A6C01239A43C0B20300DB07DB0F13438B6449E1012061680A6D01239A43C0B2A2 +S224015D800300DB07DB0F13430B65002061680A6D01239A43C0B20300DB07DB0F13430B6500 +S224015DA032E1012061680A6E01239A43C0B20300DB07DB0F13430B66002061680A6E0123DA +S224015DC09A43C0B20300DB07DB0F13430B661BE1012061684A6E01239A43C0B20300DB07E2 +S224015DE0DB0F13434B66002061684A6E01239A43C0B20300DB07DB0F13434B6604E10120BC +S224015E0061688A6E01239A43C0B20300DB07DB0F13438B66002061688A6E01239A43C0B2DE +S224015E200300DB07DB0F13438B66EDE001206168CA6E01239A43C0B20300DB07DB0F1343BF +S224015E40CB6600206168CA6E01239A43C0B20300DB07DB0F1343CB66D6E0012061680A6F08 +S224015E6001239A43C0B20300DB07DB0F13430B67002061680A6F01239A43C0B20300DB0758 +S224015E80DB0F13430B67BFE00120616880228A5801239A43C0B20300DB07DB0F1343802005 +S224015EA00B500020616880228A5801239A43C0B20300DB07DB0F134380200B50A4E00120DC +S224015EC0616884228A5801239A43C0B20300DB07DB0F134384200B500020616884228A5863 +S224015EE001239A43C0B20300DB07DB0F134384200B5089E00120616890228A5801239A431D +S224015F00C0B20300DB07DB0F134390200B500020616890228A5801239A43C0B20300DB0704 +S224015F20DB0F134390200B506EE0012061689C228A5801239A43C0B20300DB07DB0F1343A0 +S224015F409C200B50002061689C228A5801239A43C0B20300DB07DB0F13439C200B5053E0B9 +S224015F600120616894228A5801239A43C0B20300DB07DB0F134394200B5000206168942253 +S224015F808A5801239A43C0B20300DB07DB0F134394200B5038E001206168C8228A58012380 +S224015FA09A43C0B20300DB07DB0F1343C8200B5000206168C8228A5801239A43C0B20300F9 +S224015FC0DB07DB0F1343C8200B501DE001206168CC228A5801239A43C0B20300DB07DB0F5D +S224015FE01343CC200B5000206168CC228A5801239A43C0B20300DB07DB0F1343CC200B5066 +S22401600002E0FFF747FCFFE70020A1688022885010BD000001604260704700000160704737 +S2240160200160704701607047416082607047016070470160704700000160704710B50400DF +S224016040216062600020A060E0208002E060802040052061802000026061200000F0B9F88B +S22401606020760020E061207E002801D000206061200000F001F810BD012102680023C9B2AB +S2240160804900022319401160012102680023C9B20901102319401160012102680023C9B267 +S2240160A04901202319401160012102680023C9B28901402319401160012102680023C9B278 +S2240160C0C900082319401160012100680022C9B28900042211400160704710B501000020D7 +S2240160E001220B680024D2B2D201802422401A600A681268D2091300DB07DB0F002BF7D071 +S2240161000A68126852091300DB07DB0F002B0ED10A68126812091300DB07DB0F002B06D161 +S224016120096809680A00D207D20F002A00D00120C0B210BDF8B50600140000200021E4B2BB +S224016140402C00DB01201D00002D00D10120C0B200282CD130680068C0090100C907C90F8C +S224016160002901D1022022E03000FFF785FF0822002031680023FF23C0B20F183F7F9F43EF +S224016180D2B213403B43C0B208180377012031680022FF22C0B20B181B7F9343E4B222409E +S2240161A01A43C0B2081802773000FFF796FFC0B200280CD1002108E00A00D21D336800247E +S2240161C0D2B29A18127F6A54491C0829F4D3C0B2F2BD1CB56946002200230CC108390024BF +S2240161E00021FF216A4611706B4600220021FFF7A1FFC0B2002804D168460078800700D4AD +S22401620001242000C0B216BD00B5016000210268D36EC9B2002903D001211943D16602E0FE +S22401622001218B43D3660068006C0100C907C90F00BD016042607047016042607047000081 +S224016240016070470160704701607047016070470160704701604260836070470160426020 +S2240162607047000001600021017100214171002128228154002138228154704700B501603D +S22401628001680A6980235B0013430B6101680A6980239B0013430B61012102681369C9B2FD +S2240162A0002903D002211943116102E002218B43136100BF00BF00BF00210068016100BDBF +S2240162C0016042607047000001600168CA6A80231B021343CB6200BF00BF00BF00BF0A4B6C +S2240162E01340CB620168CA6A8023DB011343CB6200BF00BF00BF00BF044B1340CB6200218D +S2240163000068016070470000FF7FFFFFFFBFFFFF01000500000000000000000000000000B9 +S224016320030005000000000000000000000000001100050000000000000000000000000039 +S224016340630005000000000000000000000000000100000032070000DF070000B2070000F6 +S224016360582A002000020000582C00200808000000000000514A0100274901003200F4018B +S224016380881300001A62040050000000000000001B63040050000000000000001603F000B1 +S2240163A050000000000000001703F00050000000000000008873C000500000000000000022 +S2240163C00100C10050000000000000000101C10050000000000000000121C100500000005F +S2240163E0000000000127C10050000000000000000128C10050000000000000000129C10039 +S22401640050000000000000000131C10050000000000000000041C100500000000000000091 +S2240164200151C10050000000000000000063C10050000000000000000069C1005000000005 +S224016440000000000181C10050000000000000000136C20050000000000000000064C10035 +S22401646050000000000000000067C100500000000000000092F00000C4470020020000009F +S224016480F1700100F370010020F00000C647002002000000F5700100F770010000FF030120 +S2240164A000000000816B0100896B0100916B010001FF030100000000996B0100A16B0100E1 +S2240164C0A96B010002FF030100000000B16B0100B96B0100C16B010013F106010000000022 +S2240164E0D44700200400000080F1060100000000D84700201000000086F106010000000012 +S224016500E8470020010000008AF1060100000000E94700200600000095F1060100000000C0 +S224016520EF47002010000000A0F1060100000000FF47002008000000A1F106010000000050 +S2240165400748002008000000A2F10601000000000F48002008000000A5F106010000000008 +S2240165601748002008000000AEF10601000000001F48002010000000534F060100000000A8 +S2240165802F48002001000000804F0601000000003048002002000000654F06010000000032 +S2240165A03248002001000000664F0601000000003348002001000000674F06010000000025 +S2240165C034480020020000009EF10601000000003648002020000000AAF106010000000021 +S2240165E05648002008000000ABF10601000000005E4800200800000012F107030100000050 +S224016600664800200800000090F10703010000006E4800201100000091F1036063000000E3 +S2240166207F4800201000000093F10360630000008F4800201000000097F107030100000079 +S2240166409F4800200800000098F1036063000000A74800201000000099F103606300000067 +S224016660B7480020040000009DF1070301000000BB48002004000000EFDF07030100000058 +S224016680BF4800204000000001F1070301000000FF4800200400000010F10303010000001D +S2240166A00349002008000000514F0503010000000B49002010000000544F05030100000087 +S2240166C01B490020100000008CF10360630000002B490020180000008BF1036063000000EF +S2240166E0434900200400000000020303010000004749002001000000010203030100000020 +S224016700484900200100000087F1036063000000494900200A00000089F103606300000087 +S224016720534900201000000001FD036063000000634900200100000002FD03606300000031 +S224016740644900200100000003FD036063000000654900200100000001000000002202604B +S22401676041600121017200214172704770B504000E0015003148215A31482018FFF7EEFF7E +S2240167807820205C012806D02A00310092B220001830FDF7A1FD70BD7CB504000E001500C2 +S2240167A068460021002206C00838EDB2782D05D02248215A22482018FFF7D0FF7920205C62 +S2240167C000280FD0EDB2112D0BD0EDB2122D08D0EDB2312D05D0EDB27E2D02D0EDB27F2D05 +S2240167E000D10CE07F206946087068464670684685700322694620001830FDF76DFD73BD3F +S22401680070B582B014006A46AD4D2E681660DBB2042B11D3069A042313808078C9B2814221 +S22401682005D1042100222000FEF7ECFE04E0042269462000FEF732FC73BD00008C08000076 +S224016840A808000001207047F0B585B004000E001500002002A80021002206C00838002076 +S22401686069468880002000202800A1687A22A25C08235A438918497880B289B2884205D218 +S224016880132227212000FFF787FF16E16078012805D1222227212000FFF77EFF0DE1882056 +S2240168A00001201803C8FA22D2000023994208DC01DB904205D2372227212000FFF76CFF57 +S2240168C0FBE0370078784606760E67206946087202A84670F6B230000221FCF79BF8002926 +S2240168E076D0002077490870002500E06D1CEDB2042D38DA30007449EDB210226A43895C34 +S224016900C0B28842F2D17048EDB210216943401880786D49EDB210226A438918497888428E +S22401692021D28820000120180CC808386648EDB2102169434018083003C8121A8B41634841 +S22401694000218B4208DC01DB824205D2362227212000FFF721FFB0E000205B49EDB21022ED +S2240169606A4389184870EDB2042D05DB312227212000FFF711FFA0E0062301A80090DBB22B +S22401698002A8821C3100C9B22000FFF739FF68468088002816D068468288921C92B202A996 +S2240169A02000FFF7E3FE4748067068468088484908806846828802A8811C464C2000FEF760 +S2240169C06DFB7AE0312227212000FFF7E5FE74E0F6B23C480078401C864205D024222721DC +S2240169E02000FFF7D9FE68E0A81E80B20090BB1C37480288374933480078FFF723FFC0B2F7 +S224016A0001281FD1022202A92000FFF7AFFE00202C490870701EA0700020C0B204284CDA36 +S224016A203100294AC0B210234343D25CC9B2914206D10021244AC0B210234343D2185170C9 +S224016A40401CEAE7352227212000FFF7A5FE002230E01C4800781C49D2B210235343C95CC6 +S224016A60884226D11848D2B21021514340184078401C1549D2B210235343C918487012489C +S224016A80D2B210215143401880780F49D2B210235343C918497888420BD288200001201888 +S224016AA003C8094BD2B2102555435B19083303C3083B521CD2B2042ACBDB05B0F0BD000080 +S224016AC0308C01006E490020000000201027000068490020BC47002000220260416001218A +S224016AE0017200214172704770B504000E0015002248215AB7482018FFF7EEFF7820205C33 +S224016B00012806D02A00310092B220001830FDF7E3FB70BD7CB504000E0015006846002143 +S224016B20002206C00838EDB2782D05D01348215AA8482018FFF7D0FF7920205C00280FD02F +S224016B40EDB2112D0BD0EDB2122D08D0EDB2312D05D0EDB27E2D02D0EDB27F2D00D10CE0CB +S224016B607F206946087068464670684685700322694620001830FDF7AFFB73BD8C080000A4 +S224016B8000B50028FFD000BD00B50028FFD000BD00B50028FFD000BD00B50028FFD000BD4B +S224016BA000B50028FFD000BD00B50028FFD000BD00B50028FFD000BD00B50028FFD000BD2B +S224016BC000B50028FFD000BDF0B5FFB084B005000C001700002600200020002000200320CD +S224016BE06946087002A880218900FEF733FD0020694688803800A9687A22AA5C08235A43E5 +S224016C008918497880B289B2884205D2132231212800FFF77FFFDAE0684661784906490EF4 +S224016C204170A0780002E178401869463A1FCA806946C988002900D0261D002400E0641CC0 +S224016C4021006A461278C9B2914228D26249E4B214226243895A020092B29142EFD16878D3 +S224016C605D49E4B21422624389188978884222D15948E4B2142161434018C07800280ED0F2 +S224016C805548E4B2142161434018C078A978884205D0332231212800FFF73CFF97E02000FB +S224016CA069460978C0B288420BD3312231212800FFF730FF8BE0222231212800FFF72AFF4A +S224016CC085E080218900002202AF3800FEF79AFC68464078012804D05FD3032845D025D3BC +S224016CE05BE001A8009080239B0002AA6846C1883000394EE4B214276743F619B668B047E3 +S224016D0001203549E4B2142254430919087168468088042847DB6846007A712843D1684649 +S224016D20828802A92800FFF7DFFE50E02A48E4B21421614340180079002815D001A8009075 +S224016D4080239B0002AA6846C1883000224EE4B214276743F619F668B04700201E49E4B2B0 +S224016D601422544309190871D1E71B48E4B2142161434018007900280ED001A80090802368 +S224016D809B0002AA6846C1883000134EE4B214277C4334192469A047B9E71222312128007F +S224016DA0FFF7B8FE13E06846808803280AD16846007A7F2806D102A8827831212800FFF7B8 +S224016DC0A9FE04E0242231212800FFF7A3FE7FB004B0F0BDA80800008C010020002202605A +S224016DE041600121017200214172704770B504000E0015009248215A92482018FFF7EEFF36 +S224016E007820205C012806D02A00310092B220001830FDF761FA70BD7CB504000E0015007E +S224016E2068460021002206C00838EDB2782D05D08348215A83482018FFF7D0FF7920205C19 +S224016E4000280FD0EDB2112D0BD0EDB2122D08D0EDB2312D05D0EDB27E2D02D0EDB27F2D7E +S224016E6000D10CE07F206946087068464670684685700322694620001830FDF72DFA73BDFB +S224016E80F4B5FFB085B004000F0000200020002600200020002503A880218900FEF7DAFBE2 +S224016EA084A80088A1687A22A25C08235A438918497889B2884205D2132222212000FFF7E1 +S224016EC0ABFFBAE084A80088401EC00705D5132222212000FFF7A0FFAFE084A800884008FD +S224016EE080B2002805D1132222212000FFF794FFA3E00197622003A9B6B28855761C3200E9 +S224016F00012650E092B22069BFB210217943401880891018801C4C49884274DA2069BFB21D +S224016F201021794340188078052872D060782169BFB210237B43C918C978884269D301258D +S224016F400198B6B2805D03A992B28854521C0198B6B28019407803A992B288546846521CD9 +S224016F6002802069BFB210217943401882892069BFB2102179434018816803A86B461B8818 +S224016F80C01802900298FEF789F80298684600882169BFB210227A43891889894218EDB20B +S224016FA0002D3CD0B61C300084A9098880B2884235D20198B6B2805D00020199B6B289194B +S224016FC0497808430025002700E07F1C3900A38A89B29942E3D22169BFB210237B43C95A98 +S224016FE003009BB29942F0D1A0782169BFB210237B43C9180979884284D033222221200062 +S224017000FFF70AFF19E0142222212000FFF704FF13E0222222212000FFF7FEFE0DE0EDB2C8 +S224017020002D05D092B203A92000FFF7DFFE04E0312222212000FFF7EFFE7FB006B0F0BD56 +S2240170408C080000A8080000010200000022026041600121017200214172704770B5040075 +S2240170600E0015009148215A91482018FFF7EEFF7820205C012806D02A00310092B22000CD +S2240170801830FDF729F970BD7CB504000E00150068460021002206C00838EDB2782D05D0F7 +S2240170A08248215A82482018FFF7D0FF7920205C00280FD0EDB2112D0BD0EDB2122D08D034 +S2240170C0EDB2312D05D0EDB27E2D02D0EDB27F2D00D10CE07F2069460870684646706846DC +S2240170E085700322694620001830FDF7F5F873BD7047704770477047F0B5FFB082B00400E2 +S2240171000E001500002000200020022701A880218900FEF79FFA2800A1687A22A25C082366 +S2240171205A438918497880B289B2884205D213222F212000FFF7A8FFB4E06078012805D18F +S22401714022222F212000FFF79FFFABE0300041780902827889186A46C3781370002600E053 +S224017160761C32003B00D2B2DBB29A421FD2514AF6B214237343D25A0B009BB29A42EFD1DC +S2240171804C49F6B2142272438918897800290ED04849F6B21422724389188978A278914265 +S2240171A005D033222F212000FFF76EFF7AE03100C9B2FFB2B94205D331222F212000FFF789 +S2240171C063FF6FE06F216A461171417801AA5170817801AA9170C17801AAD1706946097817 +S2240171E0002902D003291CD057E000203149F6B2142272438918C8722E48F6B21421714330 +S2240172004018006900280BD02A48F6B214214E43801900698047042201A92000FFF71EFFF8 +S22401722040E0ADB22349F6B2142272438918097A091D8D4205DA22222F212000FFF724FF05 +S22401724030E001211B4AF6B214237343D218D1721849F6B21422724389180A7A011D15483B +S224017260F6B214237343C01845682800FDF716FF1048F6B2142171434018C06800280BD051 +S2240172800C48F6B214214E438019C0688047042201A92000FFF7E2FE04E031222F21200031 +S2240172A0FFF7F2FE7FB002B0F0BD00008C080000A80800006401002085490870704700B5D9 +S2240172C080B2142830DA0021824A80B20C234343D21811717F4980B20C2242438918097920 +S2240172E010220A437B4980B20C234343C9180A71784980B20C2242438918097940220A438A +S224017300744980B20C234343C9180A710021714A80B20C234343D218D18000216D4A80B25F +S2240173200C234343D018017200BD10B5010000200020002000220CE0664B92B20C2454438A +S2240173401B191B795B065B0EDBB20B4200D0401C521C92B2142AEFDB80B210BDF0B503002E +S2240173600C0000200020002100251FE05948ADB20C276F43C059000C89B25854491C554883 +S224017380ADB20C276F43C059000A89B25854491C5048ADB20C276F43C05989B25854491CF3 +S2240173A07006400E89B25854491C6D1CADB2142D0FDA4848ADB20C266E438019067930008B +S2240173C0C0B21042F1D0A4B289B20800001D8442CCDA080080B2F0BD70B502000B000020C7 +S2240173E00020002100241FE03A48A4B20C2666438059000C89B25054491C3648A4B20C2641 +S22401740066438059000A89B25054491C3148A4B20C266643805989B25054491C6806400E13 +S22401742089B25054491C641CA4B2142C0BDA2948A4B20C256543401905799BB289B2080000 +S224017440001D8342D0DA080080B270BD10B500212149401A04D09D3816D02F382BD034E084 +S22401746000240DE01B48A4B20C216143405880214903884203D2200080B2FFF720FF641C60 +S224017480A4B2142CEEDB20E0002410E01148A4B20C21614340588021C903401A8021C90327 +S2240174A0884203D2200080B2FFF709FF641CA4B2142CEBDB09E0002404E0200080B2FFF7C2 +S2240174C0FEFE641CA4B2142CF7DB10BD000000006D4900207400002033FFFF0000220260D6 +S2240174E041600121017200214172704770B504000E0015002248215A22482018FFF7EEFF0F +S2240175007820205C012806D02A00310092B220001830FCF7E1FE70BD7CB504000E001500F4 +S22401752068460021002206C00838EDB2782D05D01348215A13482018FFF7D0FF7920205CF2 +S22401754000280FD0EDB2112D0BD0EDB2122D08D0EDB2312D05D0EDB27E2D02D0EDB27F2D77 +S22401756000D10CE07F206946087068464670684685700322694620001830FCF7ADFE73BD71 +S2240175808C080000A80800008020704710B500210021012200E0521CD2B2052A09DA042315 +S2240175A09B1A082463430400DC40002CF3D00520811A0800C0B210BDF0B585B0040000202A +S2240175C000230025002300230023002300266378012B05D1222234212000FFF79DFF89E01A +S2240175E0A3689C467A23E75C08235F436346DB195B7892B29BB29A4205D21322342120008D +S224017600FFF78AFF76E00191019989780907090F6A46019B9B78DBB21B091370C9B2002903 +S2240176200AD0C9B2052907D26A461278002A03D06A461278052A05D3312234212000FFF7B2 +S2240176406BFF57E0002206E00002019BD2B29B18DB78C018521C13000F00DBB2FFB2BB42B0 +S224017660F2D3002208E02B02019DC9B2D2B28F18ED19ED785D19521C13006F463F78DBB269 +S224017680BB42F0D3002D05D1222234212000FFF743FF2FE000F082F8280000F082F8012004 +S2240176A000F085F8FFF770FF05002800FFF76EFF742102AAB6B29155761C3200010102AB60 +S2240176C092B29954521C012109E0431A082673432E00DE4002AB92B29E54521C491C0300B4 +S2240176E00E00DBB2F6B2B342EFD292B202A92000FFF7FCFE05B0F0BD0022026041600121E3 +S224017700017200214172704770B504000E0015007148215A71482018FFF7EEFF7820205CFD +S224017720012806D02A00310092B220001830FCF7D3FD70BD7CB504000E0015006846002126 +S224017740002206C00838EDB2782D05D06248215A62482018FFF7D0FF7920205C00280FD0FA +S224017760EDB2112D0BD0EDB2122D08D0EDB2312D05D0EDB27E2D02D0EDB27F2D00D10CE09F +S2240177807F206946087068464670684685700322694620001830FCF79FFD73BD504908601A +S2240177A070475049086070474E48006870474E49087070474C48007870474C480068704763 +S2240177C0F0B5FFB082B005000E0014000027684680218900FDF73EFF6878012805D12222A3 +S2240177E036212800FFF7A6FF71E02000A9687A22AA5C08235A438918497880B289B28842E4 +S22401780005D2132236212800FFF794FF5FE036480078012802D002284ED053E0707834493E +S2240178200870334800783349097888420DD03048007830490978491CC9B2884205D0732235 +S22401784036212800FFF776FF41E076206946BFB2C8557F1C3A007078694692B28854521C4A +S2240178602348007823490978884205D192B269462800FFF749FF2AE01A4800681B49096890 +S224017880A4B20919891E884205D2712236212800FFF750FF1BE015480068A4B2A11E40189E +S2240178A012490860124800781249087092B269462800FFF729FF0AE0312236212800FFF76F +S2240178C039FF04E0242236212800FFF733FF7FB002B0F0BD000000008C080000A8080000C7 +S2240178E0C8470020CC47002070490020D04700207149002072490020C5000100F1000100A3 +S2240179009F01010000000000BD0101008B0201000504010057040100FD0401004F050100B6 +S2240179200106010053060100FD0601004F070100F507010047080100ED0801003F090100F8 +S224017940E5090100330A0100910A0100C70A0100F30A01002B0B01005B0B0100ED0B0100F1 +S224017960910C0100E10D0100B510010000000000BD100100DD1001000311010023110100A8 +S2240179804911010000000000531101009F110100291201004D1201007312010097120100A4 +S2240179A0BD120100E1120100071301002B13010051130100751301009B130100631401008E +S2240179C0A5150100FF150100BD16010015170100BD170100F5170100411801007918010002 +S2240179E0C1180100F9180100451901007D190100C5190100FD190100491A0100831A0100A7 +S224017A00CD1A0100E91A01000F1B01002B1B0100511B01006D1B0100931B0100AF1B010092 +S224017A20D51B0100F11B0100171C0100331C0100591C0100E31C0100B11D0100CD1D01008E +S224017A40F31D0100431E0100C11E0100111F0100951F0100E51F0100692001006D200100CA +S224017A6071200100C12001003F2101008F210100112201009F220100512301005523010096 +S224017A807B23010097230100BD230100D9230100FF2301001D24010047240100652401004D +S224017AA08F240100AD240100D7240100F52401001F25010000000000272501000000000092 +S224017AC02F2501000000000037250100932501006F260100CB260100A7270100D5270100E1 +S224017AE02728010055280100AD280100CB28010000220260416001210172002141727047A3 +S224017B0070B504000E0015002248215A22482018FFF7EEFF7820205C012806D02A0031003B +S224017B2092B220001830FCF7D7FB70BD7CB504000E00150068460021002206C00838EDB2B3 +S224017B40782D05D01348215A13482018FFF7D0FF7920205C00280FD0EDB2112D0BD0EDB204 +S224017B60122D08D0EDB2312D05D0EDB27E2D02D0EDB27F2D00D10CE07F206946087068467E +S224017B804670684685700322694620001830FCF7A3FB73BD8C080000A80800007CB5040010 +S224017BA00020002068460023002528C008381000A3687A25655D082675435B195B7880B286 +S224017BC09BB2984205D213222E212000FFF7AEFF76E0487800028B7818436E236D462B7005 +S224017BE04B786D466B708B786D46AB70002300E05B1C1D00A68AADB2B5425CD225699BB237 +S224017C0010265E43AD5B0600B6B2B542F0D120699BB210255D434019007900280ED0A078BE +S224017C2025699BB210265E43AD192D79A84205D0332222212000FFF779FF41E092B2D01EE8 +S224017C4022699BB210255D4352199289904205D013222E212000FFF769FF31E020699BB25B +S224017C6010225A4380188078032808D0607822699BB210255D435219D278904205D2222275 +S224017C802E212000FFF752FF1AE020699BB210225A4380188289C91C20699BB210255D4356 +S224017CA0401985682800FDF7F9F9032269462000FFF726FF04E031222E212000FFF736FF8A +S224017CC073BD00000022026041600121017200214172704770B504000E0015006A48215AB0 +S224017CE06A482018FFF7EEFF7820205C012806D02A00310092B220001830FCF7EDFA70BD90 +S224017D007CB504000E00150068460021002206C00838EDB2782D05D05B48215A5B482018FC +S224017D20FFF7D0FF7920205C00280FD0EDB2112D0BD0EDB2122D08D0EDB2312D05D0EDB27D +S224017D407E2D02D0EDB27F2D00D10CE07F20694608706846467068468570032269462000D7 +S224017D601830FCF7B9FA73BD30B583B06B460024002530C3083B002383687A24045D08255D +S224017D806C431B195B7892B29BB29A4204D213222821FFF7B5FF75E04278012A04D1222269 +S224017DA02821FFF7ADFF6DE04A785206520E897868236C4623706B465A70D2B2002A05D03C +S224017DC0022A2FD018D3032A42D057E0C9B2012905D0C9B2022902D0C9B2032907D100217F +S224017DE02B4A117002226946FFF774FF03E031222821FFF785FF45E0C9B2012905D0C9B238 +S224017E00022902D0C9B2032907D10121204A117002226946FFF75EFF03E031222821FFF738 +S224017E206FFF2FE0C9B2012905D0C9B2022902D0C9B2032907D10221154A11700222694678 +S224017E40FFF748FF03E031222821FFF759FF19E0C9B2012905D0C9B2022902D0C9B2032980 +S224017E6007D103210A4A117002226946FFF732FF03E031222821FFF743FF03E0122228211A +S224017E80FFF73EFF37BD00008C080000A80800006F490020002202604160012101720021BE +S224017EA04172704770B504000E0015002248215A22482018FFF7EEFF7820205C012806D089 +S224017EC02A00310092B220001830FCF705FA70BD7CB504000E00150068460021002206C067 +S224017EE00838EDB2782D05D01348215A13482018FFF7D0FF7920205C00280FD0EDB2112DFC +S224017F000BD0EDB2122D08D0EDB2312D05D0EDB27E2D02D0EDB27F2D00D10CE07F20694686 +S224017F20087068464670684685700322694620001830FCF7D1F973BD8C080000A80800004F +S224017F4070B5FFB081B004000E0015000020002000200020684680218900FDF77BFB280005 +S224017F60A1687A22A25C08235A438918497880B289B2884205D2132219212000FFF7A8FFF4 +S224017F8067E070784006400E59216A46117069464870C0B2012804D0022822D00A283CD03D +S224017FA052E0ADB2032D05D0132219212000FFF78FFF4EE0B078C0B2FFF7B7F97F216A4654 +S224017FC0917001216A46D170010089B2090A6A46117169464871062269462000FFF762FF50 +S224017FE037E0ADB2032D05D0132219212000FFF76FFF2EE0B2787F2069468870D2B2FF21EB +S224018000FE316846C01CFFF7A9F9C01C020092B269462000FFF746FF1BE0ADB2022D05D07F +S224018020132219212000FFF753FF12E0FF21FE316846C01CFFF7D0F9C01C020092B2694608 +S2240180402000FFF72FFF04E0122219212000FFF73FFF7FB001B070BD0022026041600121DC +S224018060017200214172704770B504000E0015006048215A60482018FFF7EEFF7820205CB6 +S224018080012806D02A00310092B220001830FCF723F970BD7CB504000E0015006846002171 +S2240180A0002206C00838EDB2782D05D05148215A51482018FFF7D0FF7920205C00280FD0B3 +S2240180C0EDB2112D0BD0EDB2122D08D0EDB2312D05D0EDB27E2D02D0EDB27F2D00D10CE036 +S2240180E07F206946087068464670684685700322694620001830FCF7EFF873BD30B583B04F +S224018100040068460023002528C00838A0687A23E35C08256B43C018407892B280B28242AE +S22401812005D0132210212000FFF7B4FF60E048784006400E50216A461170694648702F4920 +S224018140615A89B2090A6A4691702C49615A6A46D1702B49615A89B2090A6A46117128491E +S224018160615A6A465171C0B2012806D03BD303280CD01AD3042827D035E00021A17060701F +S224018180062269462000FFF76FFF31E00021A1706070062269462000FFF766FF1548215A41 +S2240181A015482018FFF758FF22E00021A1706070062269462000FFF757FF0E48215A0E4869 +S2240181C02018FFF749FF13E00021A1706070062269462000FFF748FF0648215A06482018AB +S2240181E0FFF73AFF04E0122210212000FFF752FF37BD00008C080000A808000088080000D2 +S2240182008A0800000022026041600121017200214172704770B504000E0015002248215A50 +S22401822022482018FFF7EEFF7820205C012806D02A00310092B220001830FCF74DF870BD34 +S2240182407CB504000E00150068460021002206C00838EDB2782D05D01348215A1348201847 +S224018260FFF7D0FF7920205C00280FD0EDB2112D0BD0EDB2122D08D0EDB2312D05D0EDB238 +S2240182807E2D02D0EDB27F2D00D10CE07F2069460870684646706846857003226946200092 +S2240182A01830FCF719F873BD8C080000A80800007CB5040000256846002100230AC00838A2 +S2240182C06078012805D1222237212000FFF7B8FF3EE0A0687A21615C082359434018407803 +S2240182E092B280B2824205D2132237212000FFF7A7FF2DE077206946ADB248556D1CFFF750 +S22401830059FA012802D0022814D019E0FFF755FA0600FFF749FA864205D013223721200034 +S224018320FFF78EFF11E02A0092B269462000FFF771FF0AE0312237212000FFF781FF04E011 +S224018340242237212000FFF77BFF0020FFF72FFA73BD00000022026041600121017200219F +S2240183604172704770B504000E0015002248215A22482018FFF7EEFF7820205C012806D0C4 +S2240183802A00310092B220001830FBF7A5FF70BD7CB504000E00150068460021002206C0FE +S2240183A00838EDB2782D05D01348215A13482018FFF7D0FF7920205C00280FD0EDB2112D37 +S2240183C00BD0EDB2122D08D0EDB2312D05D0EDB27E2D02D0EDB27F2D00D10CE07F206946C2 +S2240183E0087068464670684685700322694620001830FBF771FF73BD8C080000A8080000E6 +S22401840030B583B0040068460023002528C00838A0687A23E35C08256B43C018407892B289 +S22401842080B2824205D2132285212000FFF7B0FF2DE06078012805D1222285212000FFF7E5 +S224018440A7FF24E048784006400EC5216A46117069464870C0B2012802D0022809D011E039 +S2240184600120FEF729FF022269462000FFF77AFF0DE00020FEF720FF022269462000FFF74C +S22401848071FF04E0122285212000FFF781FF37BD00220260416001210172002141727047D9 +S2240184A070B504000E0015002248215A22482018FFF7EEFF7820205C012806D02A00310092 +S2240184C092B220001830FBF707FF70BD7CB504000E00150068460021002206C00838EDB2D7 +S2240184E0782D05D01348215A13482018FFF7D0FF7920205C00280FD0EDB2112D0BD0EDB25B +S224018500122D08D0EDB2312D05D0EDB27E2D02D0EDB27F2D00D10CE07F20694608706846D4 +S2240185204670684685700322694620001830FBF7D3FE73BD8C080000A80800007CB56B4687 +S2240185400024002530C3083BFF2384687A25455D082675436419647892B2A4B2A24204D0B6 +S22401856013221121FFF7B2FF24E049784906490E51226C4622706A4651706A469370C9B226 +S224018580012904D012D303290BD005D30EE003226946FFF785FF0DE003226946FFF780FFA1 +S2240185A008E003226946FFF77BFF03E012221121FFF78CFF73BD0000002202604160012148 +S2240185C0017200214172704770B504000E0015003F48215A3F482018FFF7EEFF7820205C93 +S2240185E0012806D02A00310092B220001830FBF773FE70BD7CB504000E00150068460021B8 +S224018600002206C00838EDB2782D05D03048215A30482018FFF7D0FF7920205C00280FD08F +S224018620EDB2112D0BD0EDB2122D08D0EDB2312D05D0EDB27E2D02D0EDB27F2D00D10CE0D0 +S2240186407F206946087068464670684685700322694620001830FBF73FFE73BD7CB5040077 +S22401866000206B460025002660C3083BA3687A25655D082675435B195B7892B29BB29A426C +S22401868005D0132214212000FFF7B4FF1FE04A7812040243887803021343C8781843542145 +S2240186A06A46117001000C4A891A03D09D3901D02F3907D1FEF7CAFE012269462000FFF72A +S2240186C083FF04E0312214212000FFF793FF73BD8C080000A808000033FFFF0000220260D5 +S2240186E041600121017200214172704770B504000E0015003D48215A3D482018FFF7EEFFC7 +S2240187007820205C012806D02A00310092B220001830FBF7E1FD70BD7CB504000E001500E4 +S22401872068460021002206C00838EDB2782D05D02E48215A2E482018FFF7D0FF7920205CAA +S22401874000280FD0EDB2112D0BD0EDB2122D08D0EDB2312D05D0EDB27E2D02D0EDB27F2D65 +S22401876000D10CE07F206946087068464670684685700322694620001830FBF7ADFD73BD61 +S22401878030B583B0040068460023002528C00838A0687A23E35C08256B43C018407892B206 +S2240187A080B2824205D013223E212000FFF7B4FF1BE048784006400EC0B2002810D17E2122 +S2240187C06A46117069464870022269462000FFF78DFF0648215A06482018FFF77FFF04E0DF +S2240187E012223E212000FFF797FF37BD8C080000A8080000FFB524482449254A0392254AFC +S224018800254B264C0294264C264D0195264D274E274F009703E00F780770401C491C039F26 +S2240188208F42F8D10298984207D018781070521C5B1CF7E700202070641C0198A042F9D105 +S2240188400098B04204D030782870761C6D1CF7E718481949884212D0002008E01649042280 +S22401886042438958134A04234343D150401C134989088842F2D30F481149086002E00E4838 +S2240188800F490860FFBD00BF00000020106301005C6701004C040020388C0100388C010045 +S2240188A0002000207349002000000000000000000000000000000100000001000000000094 +S2240188C008ED00E000000100320700000001080001000000FFFFFFFF01000100DF07000095 +S2240188E00001080001000000FFFFFFFF02000100440400000001080001000000FFFFFFFF1B +S22401890003000100550500000001080001000000FFFFFFFF05000100B20700000000080026 +S22401892000000000FFFFFFFF06000100110100000000080000000000FFFFFFFF0700010010 +S224018940220200000000080000000000FFFFFFFF00000000000000000000000000000000E9 +S2240189600000000010020100FD800100110201003D85010027020100496801002803010081 +S224018980697D01003E02010081870100850201000184010022030000816E01002E0400004B +S2240189A09D7B0100140400005D86010019030100417F01002F030000F970010031040100EC +S2240189C0C96B010034050000B975010036020000C177010037010000B182010072B60021CE +S2240189E0002200230024002500260027B846B946BA46BB46BC460C490C4A521A013A05DD62 +S224018A000020042308601944043AFBDA08488546084880470848804762B600F00FF8804712 +S224018A20FCF7FEF8FEE7000000000020FF630020F05F0020CB2A0100F587010000BF00BF60 +S224018A4000BF00BF00F000F800F00BF8002801D000BF00BF002000BF00BFFCF7E1F800F0E6 +S224018A6002F80120704780B500F002F801BD00000746384600F002F8FBE7000080B500BFB6 +S224018A8000BF024A11001820ABBEFBE7260002004669727374206672616D652073686F75F7 +S224018AA06C64206E6F7420757365206D756C7469706C65206672616D65207472616E736D96 +S224018AC0697373696F6E2E004D756C74692D6672616D6520726573706F6E736520746F6F89 +S224018AE0206C6172676520666F7220726563656976696E67206275666665722E000000003A +S224018B004D6573736167652073697A6520746F6F206C617267652E205365742061206C612A +S224018B20726765722073656E64206275666665720A00000041626F72742070726576696F64 +S224018B407573206D6573736167652C207472616E736D697373696F6E20696E2070726F67DD +S224018B60726573732E0A0000000000000000000000000000000000000000000000000000FA +S224018B8000000000000000000000000000000000000000000000000053696E676C652D66DA +S224018BA072616D65206C656E67746820746F6F20736D616C6C206F7220746F6F206C6172EB +S224018BC067652E004669727374206672616D652073686F756C6420626520382062797465A0 +S224018BE07320696E206C656E6774682E00000000436F6E7365637574697665206672616DE7 +S224018C006520746F6F2073686F72742E00000000466C6F7720636F6E74726F6C20667261E7 +S224018C206D6520746F6F2073686F72742E0000000102030400000000FFFFFFFFFFFFFFFF6A +S224018C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S224018C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S224018C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S224018CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S224018CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S224018CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S224018D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S224018D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S224018D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S224018D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S224018D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S224018DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S224018DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S224018DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S224018E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S224018E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S224018E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S224018E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S224018E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S224018EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S224018EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S224018EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S224018F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S224018F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S224018F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S224018F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S224018F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S224018FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S224018FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S224018FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S224019000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S224019020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S224019040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S224019060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S224019080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S2240190A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S2240190C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S2240190E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S224019100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S224019120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S224019140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S224019160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S224019180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S2240191A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S2240191C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S2240191E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S224019200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S224019220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S224019240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S224019260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S224019280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S2240192A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S2240192C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S2240192E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S224019300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S224019320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S224019340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S224019360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S224019380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S2240193A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S2240193C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S2240193E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S224019400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S224019420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S224019440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S224019460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S224019480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S2240194A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S2240194C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S2240194E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S224019500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S224019520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S224019540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S224019560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S224019580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S2240195A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S2240195C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S2240195E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S224019600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S224019620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S224019640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S224019660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S224019680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S2240196A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S2240196C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S2240196E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S224019700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S224019720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S224019740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S224019760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S224019780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S2240197A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S2240197C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S2240197E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S224019800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S224019820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S224019840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S224019860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S224019880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S2240198A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S2240198C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S2240198E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S224019900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S224019920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S224019940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S224019960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S224019980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S2240199A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S2240199C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S2240199E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S224019A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S224019A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S224019A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S224019A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S224019A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S224019AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S224019AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S224019AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S224019B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S224019B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S224019B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S224019B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S224019B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S224019BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S224019BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S224019BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S224019C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S224019C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S224019C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S224019C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S224019C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S224019CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S224019CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S224019CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S224019D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S224019D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S224019D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S224019D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S224019D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S224019DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S224019DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S224019DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S224019E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S224019E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S224019E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S224019E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S224019E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S224019EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S224019EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S224019EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S224019F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S224019F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S224019F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224019F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S224019F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S224019FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S224019FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S224019FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S22401A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S22401A020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S22401A040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S22401A060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S22401A080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S22401A0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S22401A0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S22401A0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S22401A100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S22401A120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S22401A140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S22401A160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S22401A180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S22401A1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S22401A1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S22401A1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S22401A200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S22401A220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S22401A240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S22401A260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S22401A280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S22401A2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S22401A2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S22401A2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S22401A300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S22401A320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S22401A340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S22401A360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S22401A380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S22401A3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S22401A3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S22401A3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S22401A400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S22401A420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S22401A440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S22401A460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S22401A480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S22401A4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S22401A4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S22401A4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S22401A500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S22401A520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S22401A540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S22401A560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S22401A580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S22401A5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S22401A5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S22401A5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S22401A600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S22401A620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S22401A640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S22401A660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S22401A680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S22401A6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S22401A6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S22401A6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S22401A700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S22401A720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S22401A740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S22401A760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S22401A780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S22401A7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S22401A7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S22401A7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S22401A800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S22401A820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S22401A840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S22401A860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S22401A880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S22401A8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S22401A8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S22401A8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S22401A900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S22401A920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S22401A940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S22401A960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S22401A980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S22401A9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S22401A9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S22401A9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S22401AA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S22401AA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S22401AA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S22401AA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S22401AA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S22401AAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S22401AAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S22401AAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S22401AB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S22401AB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S22401AB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S22401AB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S22401AB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S22401ABA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S22401ABC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S22401ABE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S22401AC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S22401AC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S22401AC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S22401AC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S22401AC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S22401ACA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S22401ACC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S22401ACE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S22401AD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S22401AD20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S22401AD40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S22401AD60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S22401AD80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S22401ADA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S22401ADC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S22401ADE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S22401AE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S22401AE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S22401AE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S22401AE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S22401AE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S22401AEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S22401AEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S22401AEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S22401AF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S22401AF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S22401AF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S22401AF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S22401AF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S22401AFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S22401AFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S22401AFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S22401B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S22401B020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S22401B040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S22401B060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S22401B080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S22401B0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S22401B0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S22401B0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S22401B100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S22401B120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S22401B140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S22401B160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S22401B180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S22401B1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S22401B1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S22401B1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S22401B200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S22401B220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S22401B240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S22401B260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S22401B280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S22401B2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S22401B2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S22401B2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S22401B300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S22401B320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S22401B340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S22401B360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S22401B380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S22401B3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S22401B3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S22401B3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S22401B400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S22401B420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S22401B440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S22401B460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S22401B480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S22401B4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S22401B4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S22401B4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S22401B500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S22401B520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S22401B540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S22401B560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S22401B580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S22401B5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S22401B5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S22401B5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S22401B600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S22401B620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S22401B640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S22401B660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S22401B680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S22401B6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S22401B6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S22401B6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S22401B700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S22401B720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S22401B740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S22401B760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S22401B780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S22401B7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S22401B7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S22401B7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S22401B800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S22401B820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S22401B840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S22401B860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S22401B880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S22401B8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S22401B8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S22401B8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S22401B900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S22401B920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S22401B940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S22401B960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S22401B980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S22401B9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S22401B9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S22401B9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S22401BA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S22401BA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S22401BA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S22401BA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S22401BA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S22401BAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S22401BAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S22401BAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S22401BB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S22401BB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S22401BB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S22401BB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S22401BB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S22401BBA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S22401BBC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S22401BBE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S22401BC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S22401BC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S22401BC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S22401BC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S22401BC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S22401BCA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S22401BCC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S22401BCE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S22401BD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S22401BD20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S22401BD40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S22401BD60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S22401BD80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S22401BDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S22401BDC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S22401BDE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S22401BE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S22401BE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S22401BE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S22401BE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S22401BE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S22401BEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S22401BEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S22401BEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S22401BF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S22401BF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S22401BF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S22401BF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S22401BF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S22401BFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S22401BFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S22401BFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S22401C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S22401C020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S22401C040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S22401C060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S22401C080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S22401C0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S22401C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S22401C0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S22401C100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S22401C120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S22401C140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S22401C160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S22401C180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S22401C1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S22401C1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S22401C1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S22401C200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S22401C220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S22401C240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S22401C260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S22401C280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S22401C2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S22401C2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S22401C2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S22401C300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S22401C320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S22401C340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S22401C360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S22401C380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S22401C3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S22401C3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S22401C3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S22401C400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S22401C420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S22401C440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S22401C460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S22401C480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S22401C4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S22401C4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S22401C4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S22401C500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S22401C520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S22401C540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S22401C560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S22401C580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S22401C5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S22401C5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S22401C5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S22401C600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S22401C620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S22401C640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S22401C660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S22401C680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S22401C6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S22401C6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S22401C6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S22401C700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S22401C720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S22401C740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S22401C760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S22401C780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S22401C7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S22401C7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S22401C7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S22401C800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S22401C820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S22401C840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S22401C860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S22401C880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S22401C8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S22401C8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S22401C8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S22401C900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S22401C920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S22401C940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S22401C960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S22401C980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S22401C9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S22401C9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S22401C9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S22401CA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S22401CA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S22401CA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S22401CA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S22401CA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S22401CAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S22401CAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S22401CAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S22401CB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S22401CB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S22401CB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S22401CB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S22401CB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S22401CBA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S22401CBC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S22401CBE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S22401CC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S22401CC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S22401CC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S22401CC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S22401CC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S22401CCA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S22401CCC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S22401CCE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S22401CD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S22401CD20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S22401CD40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S22401CD60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S22401CD80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S22401CDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S22401CDC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S22401CDE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S22401CE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S22401CE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S22401CE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S22401CE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S22401CE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S22401CEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S22401CEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S22401CEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S22401CF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S22401CF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S22401CF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S22401CF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S22401CF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S22401CFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S22401CFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S22401CFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S22401D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S22401D020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S22401D040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S22401D060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S22401D080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S22401D0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S22401D0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S22401D0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S22401D100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S22401D120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S22401D140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S22401D160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S22401D180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S22401D1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S22401D1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S22401D1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S22401D200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S22401D220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S22401D240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S22401D260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S22401D280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S22401D2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S22401D2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S22401D2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S22401D300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S22401D320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S22401D340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S22401D360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S22401D380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S22401D3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S22401D3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S22401D3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S22401D400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S22401D420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S22401D440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S22401D460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S22401D480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S22401D4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S22401D4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S22401D4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S22401D500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S22401D520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S22401D540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S22401D560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S22401D580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S22401D5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S22401D5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S22401D5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S22401D600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S22401D620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S22401D640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S22401D660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S22401D680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S22401D6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S22401D6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S22401D6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S22401D700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S22401D720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S22401D740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S22401D760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S22401D780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S22401D7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S22401D7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S22401D7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S22401D800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S22401D820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S22401D840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S22401D860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S22401D880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S22401D8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S22401D8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S22401D8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S22401D900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S22401D920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S22401D940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S22401D960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S22401D980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S22401D9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S22401D9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S22401D9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S22401DA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S22401DA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S22401DA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S22401DA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S22401DA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S22401DAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S22401DAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S22401DAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S22401DB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S22401DB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S22401DB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S22401DB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S22401DB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S22401DBA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S22401DBC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S22401DBE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S22401DC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S22401DC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S22401DC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S22401DC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S22401DC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S22401DCA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S22401DCC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S22401DCE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S22401DD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S22401DD20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S22401DD40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S22401DD60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S22401DD80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S22401DDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S22401DDC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S22401DDE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S22401DE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S22401DE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S22401DE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S22401DE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S22401DE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S22401DEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S22401DEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S22401DEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S22401DF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S22401DF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S22401DF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S22401DF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S22401DF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S22401DFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S22401DFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S22401DFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S22401E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S22401E020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S22401E040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S22401E060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S22401E080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S22401E0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S22401E0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S22401E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S22401E100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S22401E120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S22401E140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S22401E160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S22401E180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S22401E1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S22401E1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S22401E1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S22401E200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S22401E220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S22401E240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S22401E260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S22401E280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S22401E2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S22401E2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S22401E2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S22401E300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S22401E320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S22401E340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S22401E360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S22401E380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S22401E3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S22401E3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S22401E3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S22401E400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S22401E420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S22401E440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S22401E460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S22401E480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S22401E4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S22401E4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S22401E4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S22401E500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S22401E520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S22401E540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S22401E560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S22401E580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S22401E5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S22401E5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S22401E5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S22401E600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S22401E620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S22401E640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S22401E660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S22401E680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S22401E6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S22401E6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S22401E6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S22401E700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S22401E720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S22401E740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S22401E760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S22401E780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S22401E7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S22401E7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S22401E7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S22401E800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S22401E820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S22401E840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S22401E860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S22401E880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S22401E8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S22401E8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S22401E8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S22401E900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S22401E920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S22401E940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S22401E960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S22401E980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S22401E9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S22401E9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S22401E9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S22401EA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S22401EA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S22401EA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S22401EA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S22401EA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S22401EAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S22401EAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S22401EAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S22401EB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S22401EB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S22401EB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S22401EB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S22401EB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S22401EBA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S22401EBC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S22401EBE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S22401EC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S22401EC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S22401EC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S22401EC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S22401EC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S22401ECA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S22401ECC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S22401ECE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S22401ED00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S22401ED20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S22401ED40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S22401ED60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S22401ED80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S22401EDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S22401EDC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S22401EDE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S22401EE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S22401EE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S22401EE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S22401EE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S22401EE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S22401EEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S22401EEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S22401EEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S22401EF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S22401EF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S22401EF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S22401EF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S22401EF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S22401EFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S22401EFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S22401EFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S22401F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S22401F020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S22401F040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S22401F060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S22401F080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S22401F0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S22401F0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S22401F0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S22401F100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S22401F120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S22401F140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S22401F160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S22401F180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S22401F1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S22401F1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S22401F1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S22401F200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S22401F220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S22401F240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S22401F260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S22401F280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S22401F2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S22401F2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S22401F2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S22401F300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S22401F320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S22401F340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S22401F360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S22401F380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S22401F3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S22401F3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S22401F3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S22401F400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S22401F420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S22401F440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S22401F460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S22401F480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S22401F4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S22401F4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S22401F4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S22401F500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S22401F520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S22401F540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S22401F560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S22401F580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S22401F5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S22401F5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S22401F5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S22401F600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S22401F620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S22401F640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S22401F660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S22401F680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S22401F6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S22401F6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S22401F6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S22401F700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S22401F720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S22401F740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S22401F760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S22401F780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S22401F7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S22401F7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S22401F7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S22401F800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S22401F820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S22401F840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S22401F860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S22401F880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S22401F8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S22401F8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S22401F8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S22401F900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S22401F920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S22401F940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S22401F960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S22401F980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S22401F9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S22401F9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S22401F9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S22401FA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S22401FA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S22401FA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S22401FA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S22401FA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S22401FAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S22401FAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S22401FAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S22401FB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S22401FB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S22401FB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S22401FB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S22401FB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S22401FBA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S22401FBC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S22401FBE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S22401FC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S22401FC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S22401FC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S22401FC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S22401FC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S22401FCA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S22401FCC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S22401FCE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S22401FD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S22401FD20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S22401FD40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S22401FD60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S22401FD80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S22401FDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S22401FDC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S22401FDE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S22401FE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S22401FE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S22401FE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S22401FE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S22401FE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S22401FEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S22401FEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S22401FEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S22401FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S22401FF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S22401FF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S22401FF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S22401FF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S22401FFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S22401FFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S22401FFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224020000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S224020020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S224020040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S224020060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S224020080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S2240200A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S2240200C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S2240200E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S224020100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S224020120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S224020140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S224020160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S224020180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S2240201A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S2240201C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S2240201E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S224020200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S224020220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S224020240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S224020260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S224020280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S2240202A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S2240202C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S2240202E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S224020300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S224020320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S224020340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S224020360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S224020380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S2240203A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S2240203C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S2240203E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S224020400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S224020420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S224020440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S224020460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S224020480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S2240204A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S2240204C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S2240204E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S224020500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S224020520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S224020540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S224020560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S224020580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S2240205A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S2240205C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S2240205E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S224020600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S224020620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S224020640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S224020660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S224020680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S2240206A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S2240206C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S2240206E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S224020700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S224020720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S224020740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S224020760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S224020780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S2240207A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S2240207C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S2240207E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S224020800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S224020820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S224020840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S224020860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S224020880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S2240208A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S2240208C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S2240208E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S224020900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S224020920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S224020940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S224020960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S224020980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S2240209A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S2240209C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S2240209E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S224020A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S224020A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S224020A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S224020A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S224020A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S224020AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S224020AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S224020AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S224020B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S224020B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S224020B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S224020B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S224020B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S224020BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S224020BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S224020BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S224020C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S224020C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S224020C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S224020C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S224020C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S224020CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S224020CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S224020CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S224020D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S224020D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S224020D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S224020D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S224020D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S224020DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S224020DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S224020DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S224020E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S224020E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S224020E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S224020E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S224020E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S224020EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S224020EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S224020EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S224020F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S224020F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S224020F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S224020F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S224020F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S224020FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S224020FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S224020FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S224021000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S224021020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S224021040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S224021060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S224021080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S2240210A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S2240210C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S2240210E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S224021100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S224021120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S224021140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S224021160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S224021180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S2240211A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S2240211C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S2240211E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S224021200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S224021220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S224021240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S224021260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S224021280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S2240212A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S2240212C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S2240212E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S224021300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S224021320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S224021340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S224021360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S224021380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S2240213A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S2240213C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S2240213E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S224021400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S224021420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S224021440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S224021460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S224021480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S2240214A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S2240214C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S2240214E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S224021500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S224021520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S224021540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S224021560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S224021580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S2240215A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S2240215C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S2240215E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S224021600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S224021620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S224021640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S224021660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S224021680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S2240216A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S2240216C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S2240216E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S224021700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S224021720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S224021740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S224021760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S224021780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S2240217A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S2240217C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S2240217E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S224021800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S224021820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S224021840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S224021860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S224021880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S2240218A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S2240218C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S2240218E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S224021900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S224021920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S224021940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S224021960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S224021980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S2240219A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S2240219C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S2240219E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S224021A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S224021A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S224021A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S224021A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S224021A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S224021AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S224021AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S224021AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S224021B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S224021B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S224021B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S224021B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S224021B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S224021BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S224021BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S224021BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S224021C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S224021C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S224021C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S224021C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S224021C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S224021CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S224021CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S224021CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S224021D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S224021D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S224021D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S224021D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S224021D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S224021DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S224021DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S224021DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S224021E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S224021E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S224021E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S224021E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S224021E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S224021EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S224021EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224021EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S224021F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S224021F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S224021F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S224021F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S224021F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S224021FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S224021FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S224021FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S224022000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S224022020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S224022040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S224022060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S224022080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S2240220A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S2240220C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S2240220E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S224022100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S224022120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S224022140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S224022160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S224022180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S2240221A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S2240221C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S2240221E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S224022200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S224022220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S224022240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S224022260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S224022280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S2240222A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S2240222C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S2240222E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S224022300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S224022320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S224022340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S224022360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S224022380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S2240223A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S2240223C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S2240223E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S224022400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S224022420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S224022440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S224022460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S224022480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S2240224A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S2240224C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S2240224E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S224022500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S224022520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S224022540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S224022560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S224022580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S2240225A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S2240225C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S2240225E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S224022600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S224022620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S224022640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S224022660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S224022680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S2240226A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S2240226C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S2240226E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S224022700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S224022720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S224022740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S224022760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S224022780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S2240227A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S2240227C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S2240227E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S224022800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S224022820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S224022840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S224022860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S224022880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S2240228A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S2240228C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S2240228E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S224022900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S224022920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S224022940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S224022960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S224022980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S2240229A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S2240229C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S2240229E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S224022A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S224022A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S224022A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S224022A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S224022A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S224022AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S224022AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S224022AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S224022B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S224022B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S224022B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S224022B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S224022B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S224022BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S224022BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S224022BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S224022C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S224022C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S224022C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S224022C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S224022C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S224022CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S224022CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S224022CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S224022D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S224022D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S224022D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S224022D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S224022D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S224022DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S224022DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S224022DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S224022E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S224022E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S224022E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S224022E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S224022E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S224022EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S224022EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S224022EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S224022F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S224022F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S224022F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S224022F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S224022F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S224022FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S224022FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S224022FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S224023000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S224023020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S224023040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S224023060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S224023080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S2240230A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S2240230C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S2240230E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S224023100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S224023120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S224023140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S224023160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S224023180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S2240231A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S2240231C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S2240231E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S224023200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S224023220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S224023240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S224023260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S224023280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S2240232A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S2240232C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S2240232E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S224023300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S224023320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S224023340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S224023360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S224023380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S2240233A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S2240233C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S2240233E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S224023400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S224023420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S224023440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S224023460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S224023480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S2240234A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S2240234C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S2240234E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S224023500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S224023520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S224023540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S224023560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S224023580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S2240235A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S2240235C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S2240235E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S224023600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S224023620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S224023640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S224023660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S224023680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S2240236A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S2240236C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S2240236E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S224023700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S224023720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S224023740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S224023760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S224023780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S2240237A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S2240237C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S2240237E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S224023800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S224023820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S224023840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S224023860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S224023880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S2240238A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S2240238C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S2240238E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S224023900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S224023920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S224023940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S224023960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S224023980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S2240239A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S2240239C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S2240239E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S224023A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S224023A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S224023A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S224023A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S224023A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S224023AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S224023AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S224023AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S224023B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S224023B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S224023B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S224023B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S224023B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S224023BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S224023BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S224023BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S224023C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S224023C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S224023C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S224023C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S224023C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S224023CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S224023CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S224023CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S224023D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S224023D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S224023D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S224023D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S224023D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S224023DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S224023DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S224023DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S224023E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S224023E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S224023E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S224023E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S224023E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S224023EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224023EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S224023EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S224023F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S224023F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S224023F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S224023F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S224023F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S224023FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S224023FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S224023FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S224024000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S224024020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S224024040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S224024060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S224024080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S2240240A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S2240240C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S2240240E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S224024100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S224024120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S224024140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S224024160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S224024180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S2240241A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S2240241C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S2240241E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S224024200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S224024220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S224024240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S224024260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S224024280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S2240242A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S2240242C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S2240242E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S224024300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S224024320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S224024340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S224024360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S224024380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S2240243A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S2240243C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S2240243E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S224024400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S224024420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S224024440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S224024460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S224024480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S2240244A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S2240244C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S2240244E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S224024500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S224024520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S224024540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S224024560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S224024580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S2240245A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S2240245C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S2240245E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S224024600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S224024620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S224024640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S224024660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S224024680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S2240246A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S2240246C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S2240246E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S224024700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S224024720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S224024740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S224024760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S224024780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S2240247A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S2240247C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S2240247E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S224024800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S224024820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S224024840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S224024860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S224024880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S2240248A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S2240248C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S2240248E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S224024900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S224024920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S224024940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S224024960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S224024980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S2240249A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S2240249C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S2240249E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S224024A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S224024A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S224024A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S224024A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S224024A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S224024AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S224024AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S224024AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S224024B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S224024B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S224024B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S224024B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S224024B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S224024BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S224024BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S224024BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S224024C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S224024C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S224024C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S224024C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S224024C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S224024CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S224024CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S224024CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S224024D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S224024D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S224024D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S224024D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S224024D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S224024DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S224024DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S224024DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S224024E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S224024E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S224024E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S224024E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S224024E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S224024EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S224024EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S224024EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S224024F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S224024F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S224024F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S224024F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S224024F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S224024FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S224024FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S224024FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S224025000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S224025020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S224025040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S224025060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S224025080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S2240250A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S2240250C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S2240250E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S224025100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S224025120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S224025140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S224025160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S224025180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S2240251A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S2240251C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S2240251E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S224025200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S224025220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S224025240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S224025260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S224025280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S2240252A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S2240252C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S2240252E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S224025300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S224025320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S224025340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S224025360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S224025380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S2240253A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S2240253C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S2240253E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S224025400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S224025420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S224025440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S224025460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S224025480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S2240254A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S2240254C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S2240254E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S224025500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S224025520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S224025540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S224025560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S224025580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S2240255A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S2240255C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S2240255E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S224025600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S224025620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S224025640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S224025660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S224025680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S2240256A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S2240256C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S2240256E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S224025700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S224025720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S224025740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S224025760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S224025780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S2240257A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S2240257C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S2240257E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S224025800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S224025820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S224025840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S224025860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S224025880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S2240258A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S2240258C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S2240258E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S224025900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S224025920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S224025940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S224025960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S224025980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S2240259A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S2240259C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S2240259E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S224025A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S224025A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S224025A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S224025A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S224025A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S224025AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S224025AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S224025AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S224025B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S224025B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S224025B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S224025B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S224025B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S224025BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S224025BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S224025BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S224025C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S224025C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S224025C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S224025C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S224025C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S224025CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S224025CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S224025CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S224025D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S224025D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S224025D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S224025D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S224025D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S224025DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S224025DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S224025DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S224025E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S224025E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S224025E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S224025E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S224025E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224025EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S224025EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S224025EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S224025F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S224025F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S224025F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S224025F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S224025F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S224025FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S224025FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S224025FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S224026000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S224026020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S224026040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S224026060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S224026080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S2240260A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S2240260C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S2240260E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S224026100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S224026120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S224026140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S224026160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S224026180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S2240261A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S2240261C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S2240261E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S224026200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S224026220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S224026240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S224026260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S224026280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S2240262A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S2240262C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S2240262E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S224026300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S224026320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S224026340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S224026360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S224026380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S2240263A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S2240263C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S2240263E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S224026400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S224026420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S224026440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S224026460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S224026480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S2240264A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S2240264C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S2240264E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S224026500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S224026520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S224026540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S224026560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S224026580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S2240265A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S2240265C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S2240265E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S224026600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S224026620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S224026640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S224026660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S224026680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S2240266A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S2240266C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S2240266E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S224026700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S224026720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S224026740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S224026760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S224026780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S2240267A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S2240267C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S2240267E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S224026800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S224026820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S224026840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S224026860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S224026880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S2240268A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S2240268C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S2240268E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S224026900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S224026920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S224026940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S224026960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S224026980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S2240269A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S2240269C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S2240269E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S224026A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S224026A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S224026A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S224026A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S224026A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S224026AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S224026AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S224026AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S224026B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S224026B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S224026B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S224026B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S224026B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S224026BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S224026BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S224026BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S224026C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S224026C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S224026C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S224026C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S224026C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S224026CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S224026CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S224026CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S224026D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S224026D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S224026D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S224026D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S224026D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S224026DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S224026DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S224026DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S224026E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S224026E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S224026E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S224026E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S224026E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S224026EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S224026EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S224026EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S224026F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S224026F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S224026F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S224026F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S224026F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S224026FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S224026FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S224026FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S224027000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S224027020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S224027040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S224027060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S224027080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S2240270A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S2240270C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S2240270E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S224027100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S224027120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S224027140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S224027160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S224027180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S2240271A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S2240271C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S2240271E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S224027200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S224027220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S224027240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S224027260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S224027280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S2240272A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S2240272C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S2240272E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S224027300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S224027320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S224027340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S224027360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S224027380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S2240273A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S2240273C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S2240273E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S224027400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S224027420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S224027440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S224027460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S224027480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S2240274A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S2240274C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S2240274E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S224027500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S224027520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S224027540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S224027560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S224027580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S2240275A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S2240275C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S2240275E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S224027600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S224027620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S224027640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S224027660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S224027680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S2240276A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S2240276C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S2240276E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S224027700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S224027720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S224027740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S224027760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S224027780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S2240277A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S2240277C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S2240277E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S224027800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S224027820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S224027840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S224027860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S224027880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S2240278A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S2240278C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S2240278E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S224027900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S224027920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S224027940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S224027960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S224027980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S2240279A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S2240279C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S2240279E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S224027A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S224027A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S224027A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S224027A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S224027A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S224027AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S224027AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S224027AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S224027B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S224027B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S224027B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S224027B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S224027B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S224027BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S224027BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S224027BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S224027C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S224027C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S224027C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S224027C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S224027C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S224027CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S224027CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S224027CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S224027D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S224027D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S224027D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S224027D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S224027D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S224027DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S224027DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S224027DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S224027E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S224027E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S224027E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S224027E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224027E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S224027EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S224027EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S224027EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S224027F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S224027F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S224027F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S224027F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S224027F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S224027FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S224027FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S224027FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S224028000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S224028020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S224028040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S224028060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S224028080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S2240280A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S2240280C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S2240280E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S224028100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S224028120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S224028140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S224028160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S224028180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S2240281A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S2240281C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S2240281E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S224028200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S224028220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S224028240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S224028260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S224028280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S2240282A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S2240282C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S2240282E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S224028300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S224028320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S224028340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S224028360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S224028380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S2240283A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S2240283C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S2240283E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S224028400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S224028420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S224028440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S224028460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S224028480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S2240284A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S2240284C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S2240284E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S224028500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S224028520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S224028540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S224028560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S224028580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S2240285A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S2240285C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S2240285E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S224028600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S224028620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S224028640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S224028660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S224028680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S2240286A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S2240286C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S2240286E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S224028700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S224028720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S224028740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S224028760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S224028780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S2240287A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S2240287C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S2240287E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S224028800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S224028820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S224028840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S224028860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S224028880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S2240288A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S2240288C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S2240288E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S224028900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S224028920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S224028940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S224028960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S224028980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S2240289A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S2240289C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S2240289E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S224028A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S224028A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S224028A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S224028A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S224028A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S224028AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S224028AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S224028AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S224028B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S224028B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S224028B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S224028B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S224028B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S224028BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S224028BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S224028BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S224028C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S224028C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S224028C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S224028C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S224028C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S224028CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S224028CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S224028CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S224028D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S224028D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S224028D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S224028D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S224028D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S224028DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S224028DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S224028DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S224028E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S224028E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S224028E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S224028E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S224028E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S224028EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S224028EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S224028EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S224028F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S224028F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S224028F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S224028F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S224028F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S224028FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S224028FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S224028FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S224029000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S224029020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S224029040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S224029060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S224029080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S2240290A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S2240290C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S2240290E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S224029100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S224029120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S224029140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S224029160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S224029180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S2240291A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S2240291C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S2240291E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S224029200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S224029220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S224029240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S224029260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S224029280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S2240292A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S2240292C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S2240292E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S224029300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S224029320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S224029340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S224029360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S224029380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S2240293A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S2240293C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S2240293E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S224029400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S224029420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S224029440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S224029460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S224029480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S2240294A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S2240294C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S2240294E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S224029500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S224029520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S224029540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S224029560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S224029580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S2240295A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S2240295C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S2240295E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S224029600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S224029620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S224029640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S224029660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S224029680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S2240296A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S2240296C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S2240296E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S224029700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S224029720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S224029740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S224029760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S224029780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S2240297A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S2240297C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S2240297E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S224029800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S224029820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S224029840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S224029860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S224029880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S2240298A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S2240298C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S2240298E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S224029900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S224029920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S224029940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S224029960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S224029980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S2240299A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S2240299C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S2240299E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S224029A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S224029A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S224029A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S224029A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S224029A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S224029AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S224029AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S224029AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S224029B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S224029B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S224029B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S224029B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S224029B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S224029BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S224029BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S224029BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S224029C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S224029C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S224029C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S224029C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S224029C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S224029CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S224029CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S224029CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S224029D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S224029D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S224029D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S224029D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S224029D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S224029DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S224029DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S224029DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S224029E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S224029E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S224029E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224029E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S224029E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S224029EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S224029EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S224029EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S224029F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S224029F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S224029F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S224029F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S224029F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S224029FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S224029FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S224029FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S22402A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S22402A020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S22402A040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S22402A060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S22402A080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S22402A0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S22402A0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S22402A0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S22402A100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S22402A120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S22402A140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S22402A160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S22402A180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S22402A1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S22402A1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S22402A1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S22402A200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S22402A220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S22402A240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S22402A260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S22402A280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S22402A2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S22402A2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S22402A2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S22402A300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S22402A320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S22402A340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S22402A360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S22402A380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S22402A3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S22402A3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S22402A3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S22402A400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S22402A420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S22402A440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S22402A460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S22402A480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S22402A4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S22402A4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S22402A4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S22402A500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S22402A520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S22402A540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S22402A560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S22402A580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S22402A5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S22402A5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S22402A5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S22402A600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S22402A620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S22402A640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S22402A660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S22402A680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S22402A6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S22402A6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S22402A6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S22402A700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S22402A720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S22402A740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S22402A760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S22402A780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S22402A7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S22402A7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S22402A7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S22402A800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S22402A820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S22402A840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S22402A860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S22402A880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S22402A8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S22402A8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S22402A8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S22402A900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S22402A920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S22402A940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S22402A960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S22402A980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S22402A9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S22402A9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S22402A9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S22402AA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S22402AA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S22402AA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S22402AA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S22402AA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S22402AAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S22402AAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S22402AAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S22402AB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S22402AB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S22402AB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S22402AB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S22402AB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S22402ABA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S22402ABC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S22402ABE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S22402AC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S22402AC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S22402AC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S22402AC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S22402AC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S22402ACA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S22402ACC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S22402ACE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S22402AD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S22402AD20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S22402AD40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S22402AD60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S22402AD80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S22402ADA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S22402ADC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S22402ADE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S22402AE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S22402AE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S22402AE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S22402AE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S22402AE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S22402AEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S22402AEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S22402AEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S22402AF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S22402AF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S22402AF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S22402AF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S22402AF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S22402AFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S22402AFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S22402AFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S22402B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S22402B020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S22402B040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S22402B060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S22402B080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S22402B0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S22402B0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S22402B0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S22402B100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S22402B120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S22402B140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S22402B160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S22402B180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S22402B1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S22402B1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S22402B1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S22402B200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S22402B220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S22402B240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S22402B260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S22402B280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S22402B2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S22402B2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S22402B2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S22402B300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S22402B320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S22402B340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S22402B360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S22402B380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S22402B3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S22402B3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S22402B3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S22402B400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S22402B420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S22402B440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S22402B460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S22402B480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S22402B4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S22402B4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S22402B4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S22402B500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S22402B520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S22402B540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S22402B560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S22402B580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S22402B5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S22402B5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S22402B5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S22402B600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S22402B620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S22402B640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S22402B660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S22402B680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S22402B6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S22402B6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S22402B6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S22402B700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S22402B720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S22402B740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S22402B760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S22402B780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S22402B7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S22402B7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S22402B7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S22402B800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S22402B820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S22402B840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S22402B860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S22402B880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S22402B8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S22402B8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S22402B8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S22402B900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S22402B920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S22402B940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S22402B960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S22402B980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S22402B9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S22402B9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S22402B9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S22402BA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S22402BA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S22402BA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S22402BA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S22402BA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S22402BAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S22402BAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S22402BAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S22402BB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S22402BB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S22402BB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S22402BB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S22402BB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S22402BBA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S22402BBC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S22402BBE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S22402BC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S22402BC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S22402BC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S22402BC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S22402BC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S22402BCA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S22402BCC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S22402BCE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S22402BD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S22402BD20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S22402BD40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S22402BD60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S22402BD80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S22402BDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S22402BDC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S22402BDE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S22402BE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S22402BE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S22402BE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S22402BE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S22402BE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S22402BEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S22402BEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S22402BEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S22402BF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S22402BF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S22402BF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S22402BF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S22402BF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S22402BFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S22402BFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S22402BFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S22402C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S22402C020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S22402C040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S22402C060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S22402C080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S22402C0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S22402C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S22402C0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S22402C100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S22402C120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S22402C140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S22402C160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S22402C180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S22402C1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S22402C1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S22402C1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S22402C200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S22402C220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S22402C240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S22402C260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S22402C280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S22402C2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S22402C2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S22402C2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S22402C300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S22402C320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S22402C340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S22402C360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S22402C380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S22402C3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S22402C3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S22402C3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S22402C400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S22402C420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S22402C440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S22402C460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S22402C480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S22402C4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S22402C4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S22402C4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S22402C500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S22402C520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S22402C540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S22402C560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S22402C580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S22402C5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S22402C5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S22402C5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S22402C600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S22402C620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S22402C640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S22402C660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S22402C680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S22402C6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S22402C6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S22402C6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S22402C700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S22402C720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S22402C740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S22402C760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S22402C780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S22402C7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S22402C7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S22402C7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S22402C800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S22402C820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S22402C840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S22402C860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S22402C880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S22402C8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S22402C8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S22402C8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S22402C900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S22402C920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S22402C940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S22402C960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S22402C980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S22402C9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S22402C9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S22402C9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S22402CA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S22402CA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S22402CA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S22402CA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S22402CA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S22402CAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S22402CAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S22402CAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S22402CB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S22402CB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S22402CB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S22402CB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S22402CB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S22402CBA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S22402CBC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S22402CBE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S22402CC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S22402CC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S22402CC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S22402CC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S22402CC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S22402CCA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S22402CCC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S22402CCE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S22402CD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S22402CD20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S22402CD40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S22402CD60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S22402CD80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S22402CDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S22402CDC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S22402CDE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S22402CE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S22402CE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S22402CE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S22402CE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S22402CE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S22402CEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S22402CEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S22402CEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S22402CF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S22402CF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S22402CF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S22402CF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S22402CF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S22402CFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S22402CFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S22402CFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S22402D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S22402D020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S22402D040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S22402D060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S22402D080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S22402D0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S22402D0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S22402D0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S22402D100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S22402D120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S22402D140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S22402D160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S22402D180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S22402D1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S22402D1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S22402D1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S22402D200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S22402D220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S22402D240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S22402D260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S22402D280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S22402D2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S22402D2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S22402D2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S22402D300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S22402D320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S22402D340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S22402D360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S22402D380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S22402D3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S22402D3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S22402D3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S22402D400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S22402D420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S22402D440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S22402D460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S22402D480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S22402D4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S22402D4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S22402D4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S22402D500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S22402D520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S22402D540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S22402D560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S22402D580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S22402D5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S22402D5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S22402D5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S22402D600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S22402D620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S22402D640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S22402D660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S22402D680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S22402D6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S22402D6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S22402D6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S22402D700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S22402D720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S22402D740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S22402D760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S22402D780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S22402D7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S22402D7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S22402D7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S22402D800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S22402D820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S22402D840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S22402D860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S22402D880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S22402D8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S22402D8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S22402D8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S22402D900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S22402D920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S22402D940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S22402D960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S22402D980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S22402D9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S22402D9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S22402D9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S22402DA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S22402DA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S22402DA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S22402DA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S22402DA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S22402DAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S22402DAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S22402DAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S22402DB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S22402DB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S22402DB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S22402DB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S22402DB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S22402DBA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S22402DBC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S22402DBE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S22402DC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S22402DC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S22402DC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S22402DC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S22402DC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S22402DCA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S22402DCC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S22402DCE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S22402DD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S22402DD20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S22402DD40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S22402DD60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S22402DD80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S22402DDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S22402DDC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S22402DDE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S22402DE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S22402DE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S22402DE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S22402DE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S22402DE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S22402DEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S22402DEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S22402DEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S22402DF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S22402DF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S22402DF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S22402DF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S22402DF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S22402DFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S22402DFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S22402DFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S22402E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S22402E020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S22402E040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S22402E060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S22402E080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S22402E0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S22402E0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S22402E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S22402E100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S22402E120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S22402E140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S22402E160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S22402E180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S22402E1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S22402E1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S22402E1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S22402E200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S22402E220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S22402E240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S22402E260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S22402E280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S22402E2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S22402E2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S22402E2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S22402E300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S22402E320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S22402E340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S22402E360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S22402E380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S22402E3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S22402E3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S22402E3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S22402E400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S22402E420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S22402E440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S22402E460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S22402E480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S22402E4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S22402E4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S22402E4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S22402E500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S22402E520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S22402E540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S22402E560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S22402E580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S22402E5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S22402E5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S22402E5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S22402E600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S22402E620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S22402E640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S22402E660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S22402E680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S22402E6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S22402E6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S22402E6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S22402E700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S22402E720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S22402E740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S22402E760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S22402E780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S22402E7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S22402E7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S22402E7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S22402E800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S22402E820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S22402E840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S22402E860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S22402E880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S22402E8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S22402E8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S22402E8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S22402E900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S22402E920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S22402E940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S22402E960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S22402E980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S22402E9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S22402E9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S22402E9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S22402EA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S22402EA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S22402EA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S22402EA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S22402EA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S22402EAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S22402EAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S22402EAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S22402EB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S22402EB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S22402EB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S22402EB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S22402EB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S22402EBA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S22402EBC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S22402EBE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S22402EC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S22402EC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S22402EC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S22402EC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S22402EC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S22402ECA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S22402ECC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S22402ECE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S22402ED00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S22402ED20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S22402ED40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S22402ED60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S22402ED80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S22402EDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S22402EDC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S22402EDE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S22402EE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S22402EE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S22402EE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S22402EE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S22402EE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S22402EEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S22402EEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S22402EEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S22402EF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S22402EF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S22402EF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S22402EF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S22402EF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S22402EFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S22402EFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S22402EFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S22402F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S22402F020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S22402F040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S22402F060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S22402F080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S22402F0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S22402F0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S22402F0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S22402F100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S22402F120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S22402F140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S22402F160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S22402F180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S22402F1A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S22402F1C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S22402F1E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S22402F200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S22402F220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S22402F240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S22402F260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S22402F280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S22402F2A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S22402F2C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S22402F2E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S22402F300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S22402F320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S22402F340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S22402F360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S22402F380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S22402F3A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S22402F3C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S22402F3E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S22402F400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S22402F420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S22402F440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S22402F460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S22402F480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S22402F4A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S22402F4C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S22402F4E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S22402F500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S22402F520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S22402F540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S22402F560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S22402F580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S22402F5A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S22402F5C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S22402F5E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S22402F600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S22402F620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S22402F640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S22402F660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S22402F680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S22402F6A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S22402F6C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S22402F6E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S22402F700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S22402F720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S22402F740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S22402F760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S22402F780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S22402F7A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S22402F7C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S22402F7E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S22402F800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S22402F820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S22402F840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S22402F860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S22402F880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S22402F8A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S22402F8C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S22402F8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S22402F900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S22402F920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S22402F940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S22402F960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S22402F980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S22402F9A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S22402F9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S22402F9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S22402FA00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S22402FA20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S22402FA40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S22402FA60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S22402FA80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S22402FAA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S22402FAC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S22402FAE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S22402FB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S22402FB20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S22402FB40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S22402FB60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S22402FB80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S22402FBA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S22402FBC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S22402FBE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S22402FC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S22402FC20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S22402FC40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S22402FC60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S22402FC80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S22402FCA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S22402FCC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S22402FCE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S22402FD00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S22402FD20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S22402FD40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S22402FD60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S22402FD80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S22402FDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S22402FDC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S22402FDE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S22402FE00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S22402FE20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S22402FE40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S22402FE60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S22402FE80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S22402FEA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S22402FEC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S22402FEE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S22402FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S22402FF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S22402FF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S22402FF60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S22402FF80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S22402FFA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S22402FFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S22402FFE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S224030000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S224030020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S224030040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S224030060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S224030080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S2240300A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S2240300C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S2240300E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S224030100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S224030120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S224030140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S224030160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S224030180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S2240301A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S2240301C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S2240301E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S224030200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S224030220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S224030240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S224030260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S224030280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S2240302A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S2240302C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S2240302E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S224030300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S224030320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S224030340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S224030360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S224030380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S2240303A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S2240303C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S2240303E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S224030400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S224030420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S224030440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S224030460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S224030480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S2240304A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S2240304C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S2240304E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S224030500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S224030520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S224030540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S224030560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S224030580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S2240305A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S2240305C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S2240305E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S224030600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S224030620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S224030640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S224030660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S224030680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S2240306A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S2240306C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S2240306E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S224030700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S224030720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S224030740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S224030760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S224030780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S2240307A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S2240307C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S2240307E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S224030800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S224030820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S224030840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S224030860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S224030880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S2240308A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S2240308C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S2240308E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S224030900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S224030920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S224030940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S224030960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S224030980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S2240309A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S2240309C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S2240309E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S224030A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S224030A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S224030A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S224030A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S224030A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S224030AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S224030AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S224030AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S224030B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S224030B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S224030B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S224030B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S224030B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S224030BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S224030BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S224030BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S224030C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S224030C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S224030C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S224030C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S224030C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S224030CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S224030CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S224030CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S224030D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S224030D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S224030D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S224030D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S224030D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S224030DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S224030DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S224030DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S224030E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S224030E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S224030E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S224030E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S224030E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S224030EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S224030EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S224030EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S224030F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S224030F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S224030F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S224030F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S224030F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S224030FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S224030FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S224030FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S224031000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S224031020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S224031040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S224031060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S224031080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S2240310A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S2240310C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S2240310E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S224031100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S224031120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S224031140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S224031160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S224031180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S2240311A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S2240311C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S2240311E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S224031200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S224031220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S224031240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S224031260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S224031280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S2240312A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S2240312C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S2240312E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S224031300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S224031320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S224031340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S224031360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S224031380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S2240313A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S2240313C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S2240313E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S224031400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S224031420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S224031440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S224031460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S224031480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S2240314A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S2240314C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S2240314E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S224031500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S224031520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S224031540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S224031560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S224031580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S2240315A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S2240315C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S2240315E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S224031600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S224031620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S224031640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S224031660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S224031680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S2240316A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S2240316C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S2240316E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S224031700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S224031720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S224031740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S224031760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S224031780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S2240317A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S2240317C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S2240317E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S224031800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S224031820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S224031840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S224031860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S224031880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S2240318A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S2240318C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S2240318E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S224031900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S224031920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S224031940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S224031960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S224031980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S2240319A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S2240319C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S2240319E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S224031A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S224031A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S224031A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S224031A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S224031A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S224031AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S224031AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S224031AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S224031B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S224031B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S224031B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S224031B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S224031B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S224031BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S224031BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S224031BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S224031C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S224031C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S224031C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S224031C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S224031C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S224031CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S224031CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S224031CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S224031D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S224031D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S224031D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S224031D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S224031D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S224031DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S224031DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224031DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S224031E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S224031E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S224031E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S224031E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S224031E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S224031EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S224031EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S224031EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S224031F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S224031F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S224031F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S224031F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S224031F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S224031FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S224031FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S224031FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S224032000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S224032020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S224032040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S224032060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S224032080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S2240320A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S2240320C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S2240320E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S224032100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S224032120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S224032140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S224032160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S224032180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S2240321A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S2240321C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S2240321E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S224032200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S224032220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S224032240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S224032260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S224032280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S2240322A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S2240322C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S2240322E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S224032300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S224032320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S224032340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S224032360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S224032380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S2240323A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S2240323C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S2240323E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S224032400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S224032420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S224032440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S224032460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S224032480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S2240324A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S2240324C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S2240324E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S224032500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S224032520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S224032540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S224032560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S224032580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S2240325A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S2240325C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S2240325E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S224032600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S224032620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S224032640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S224032660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S224032680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S2240326A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S2240326C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S2240326E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S224032700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S224032720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S224032740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S224032760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S224032780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S2240327A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S2240327C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S2240327E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S224032800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S224032820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S224032840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S224032860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S224032880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S2240328A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S2240328C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S2240328E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S224032900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S224032920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S224032940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S224032960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S224032980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S2240329A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S2240329C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S2240329E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S224032A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S224032A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S224032A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S224032A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S224032A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S224032AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S224032AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S224032AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S224032B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S224032B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S224032B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S224032B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S224032B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S224032BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S224032BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S224032BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S224032C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S224032C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S224032C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S224032C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S224032C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S224032CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S224032CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S224032CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S224032D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S224032D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S224032D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S224032D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S224032D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S224032DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S224032DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S224032DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S224032E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S224032E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S224032E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S224032E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S224032E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S224032EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S224032EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S224032EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S224032F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S224032F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S224032F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S224032F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S224032F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S224032FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S224032FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S224032FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S224033000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S224033020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S224033040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S224033060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S224033080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S2240330A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S2240330C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S2240330E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S224033100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S224033120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S224033140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S224033160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S224033180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S2240331A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S2240331C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S2240331E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S224033200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S224033220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S224033240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S224033260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S224033280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S2240332A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S2240332C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S2240332E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S224033300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S224033320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S224033340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S224033360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S224033380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S2240333A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S2240333C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S2240333E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S224033400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S224033420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S224033440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S224033460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S224033480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S2240334A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S2240334C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S2240334E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S224033500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S224033520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S224033540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S224033560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S224033580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S2240335A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S2240335C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S2240335E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S224033600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S224033620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S224033640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S224033660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S224033680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S2240336A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S2240336C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S2240336E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S224033700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S224033720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S224033740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S224033760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S224033780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S2240337A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S2240337C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S2240337E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S224033800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S224033820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S224033840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S224033860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S224033880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S2240338A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S2240338C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S2240338E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S224033900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S224033920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S224033940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S224033960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S224033980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S2240339A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S2240339C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S2240339E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S224033A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S224033A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S224033A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S224033A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S224033A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S224033AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S224033AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S224033AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S224033B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S224033B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S224033B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S224033B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S224033B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S224033BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S224033BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S224033BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S224033C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S224033C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S224033C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S224033C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S224033C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S224033CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S224033CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S224033CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S224033D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S224033D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S224033D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S224033D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S224033D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S224033DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224033DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S224033DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S224033E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S224033E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S224033E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S224033E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S224033E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S224033EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S224033EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S224033EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S224033F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S224033F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S224033F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S224033F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S224033F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S224033FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S224033FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S224033FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S224034000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S224034020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S224034040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S224034060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S224034080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S2240340A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S2240340C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S2240340E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S224034100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S224034120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S224034140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S224034160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S224034180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S2240341A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S2240341C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S2240341E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S224034200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S224034220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S224034240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S224034260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S224034280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S2240342A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S2240342C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S2240342E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S224034300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S224034320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S224034340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S224034360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S224034380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S2240343A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S2240343C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S2240343E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S224034400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S224034420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S224034440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S224034460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S224034480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S2240344A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S2240344C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S2240344E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S224034500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S224034520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S224034540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S224034560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S224034580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S2240345A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S2240345C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S2240345E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S224034600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S224034620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S224034640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S224034660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S224034680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S2240346A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S2240346C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S2240346E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S224034700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S224034720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S224034740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S224034760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S224034780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S2240347A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S2240347C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S2240347E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S224034800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S224034820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S224034840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S224034860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S224034880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S2240348A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S2240348C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S2240348E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S224034900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S224034920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S224034940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S224034960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S224034980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S2240349A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S2240349C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S2240349E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S224034A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S224034A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S224034A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S224034A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S224034A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S224034AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S224034AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S224034AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S224034B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S224034B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S224034B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S224034B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S224034B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S224034BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S224034BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S224034BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S224034C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S224034C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S224034C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S224034C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S224034C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S224034CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S224034CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S224034CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S224034D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S224034D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S224034D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S224034D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S224034D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S224034DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S224034DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S224034DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S224034E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S224034E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S224034E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S224034E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S224034E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S224034EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S224034EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S224034EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S224034F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S224034F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S224034F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S224034F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S224034F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S224034FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S224034FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S224034FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S224035000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S224035020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S224035040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S224035060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S224035080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S2240350A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S2240350C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S2240350E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S224035100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S224035120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S224035140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S224035160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S224035180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S2240351A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S2240351C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S2240351E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S224035200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S224035220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S224035240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S224035260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S224035280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S2240352A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S2240352C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S2240352E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S224035300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S224035320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S224035340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S224035360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S224035380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S2240353A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S2240353C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S2240353E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S224035400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S224035420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S224035440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S224035460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S224035480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S2240354A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S2240354C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S2240354E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S224035500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S224035520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S224035540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S224035560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S224035580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S2240355A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S2240355C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S2240355E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S224035600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S224035620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S224035640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S224035660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S224035680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S2240356A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S2240356C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S2240356E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S224035700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S224035720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S224035740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S224035760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S224035780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S2240357A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S2240357C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S2240357E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S224035800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S224035820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S224035840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S224035860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S224035880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S2240358A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S2240358C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S2240358E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S224035900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S224035920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S224035940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S224035960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S224035980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S2240359A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S2240359C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S2240359E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S224035A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S224035A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S224035A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S224035A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S224035A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S224035AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S224035AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S224035AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S224035B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S224035B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S224035B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S224035B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S224035B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S224035BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S224035BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S224035BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S224035C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S224035C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S224035C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S224035C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S224035C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S224035CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S224035CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S224035CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S224035D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S224035D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S224035D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S224035D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S224035D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224035DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S224035DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S224035DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S224035E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S224035E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S224035E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S224035E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S224035E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S224035EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S224035EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S224035EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S224035F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +S224035F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S224035F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S224035F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S224035F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S224035FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S224035FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S224035FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S224036000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +S224036020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +S224036040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +S224036060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +S224036080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +S2240360A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +S2240360C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +S2240360E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +S224036100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +S224036120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +S224036140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +S224036160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +S224036180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +S2240361A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +S2240361C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +S2240361E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +S224036200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +S224036220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +S224036240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +S224036260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +S224036280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +S2240362A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +S2240362C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +S2240362E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +S224036300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +S224036320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +S224036340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +S224036360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +S224036380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +S2240363A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +S2240363C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +S2240363E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +S224036400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +S224036420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +S224036440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +S224036460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +S224036480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +S2240364A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +S2240364C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +S2240364E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +S224036500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +S224036520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +S224036540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +S224036560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +S224036580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +S2240365A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +S2240365C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +S2240365E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +S224036600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +S224036620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +S224036640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +S224036660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +S224036680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +S2240366A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +S2240366C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +S2240366E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +S224036700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +S224036720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +S224036740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +S224036760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +S224036780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +S2240367A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +S2240367C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +S2240367E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +S224036800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +S224036820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +S224036840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +S224036860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +S224036880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +S2240368A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +S2240368C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +S2240368E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +S224036900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S224036920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +S224036940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +S224036960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +S224036980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +S2240369A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +S2240369C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +S2240369E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +S224036A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S224036A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S224036A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S224036A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S224036A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S224036AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S224036AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S224036AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S224036B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S224036B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S224036B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S224036B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S224036B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S224036BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S224036BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S224036BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S224036C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S224036C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S224036C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S224036C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S224036C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S224036CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S224036CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S224036CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S224036D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S224036D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S224036D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S224036D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S224036D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S224036DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S224036DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S224036DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S224036E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S224036E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S224036E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S224036E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S224036E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S224036EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S224036EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S224036EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S224036F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S224036F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S224036F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S224036F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S224036F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S224036FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S224036FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S224036FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S224037000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S224037020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S224037040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S224037060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S224037080FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S2240370A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S2240370C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S2240370E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S224037100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +S224037120FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S224037140FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S224037160FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S224037180FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S2240371A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S2240371C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S2240371E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +S224037200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +S224037220FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +S224037240FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +S224037260FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +S224037280FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +S2240372A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +S2240372C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +S2240372E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +S224037300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +S224037320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +S224037340FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +S224037360FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +S224037380FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +S2240373A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +S2240373C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +S2240373E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +S224037400FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +S224037420FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +S224037440FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +S224037460FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +S224037480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +S2240374A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +S2240374C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +S2240374E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +S224037500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +S224037520FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +S224037540FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +S224037560FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +S224037580FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +S2240375A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +S2240375C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +S2240375E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +S224037600FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +S224037620FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +S224037640FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +S224037660FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +S224037680FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +S2240376A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +S2240376C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +S2240376E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +S224037700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +S224037720FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +S224037740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +S224037760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +S224037780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +S2240377A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +S2240377C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +S2240377E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +S224037800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +S224037820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +S224037840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +S224037860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +S224037880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +S2240378A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +S2240378C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +S2240378E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +S224037900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +S224037920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +S224037940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +S224037960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +S224037980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +S2240379A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +S2240379C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +S2240379E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +S224037A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +S224037A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +S224037A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +S224037A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +S224037A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +S224037AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +S224037AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +S224037AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +S224037B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +S224037B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +S224037B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +S224037B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +S224037B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +S224037BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +S224037BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +S224037BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +S224037C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +S224037C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +S224037C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +S224037C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +S224037C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +S224037CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +S224037CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +S224037CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +S224037D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +S224037D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +S224037D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +S224037D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +S224037D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +S224037DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +S224037DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +S224037DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +S224037E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +S224037E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +S224037E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +S224037E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +S224037E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +S224037EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +S224037EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +S224037EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +S224037F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +S224037F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +S224037F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +S224037F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +S224037F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +S224037FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +S224037FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +S224037FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E3BD54AE +S804000001FA diff --git a/cva_asw_m0118/bat_complier_object/expdatproc.dll b/cva_asw_m0118/bat_complier_object/expdatproc.dll new file mode 100644 index 0000000..7a51585 Binary files /dev/null and b/cva_asw_m0118/bat_complier_object/expdatproc.dll differ diff --git a/cva_asw_m0118/bat_complier_object/gl_inst.dll b/cva_asw_m0118/bat_complier_object/gl_inst.dll new file mode 100644 index 0000000..babfa00 Binary files /dev/null and b/cva_asw_m0118/bat_complier_object/gl_inst.dll differ diff --git a/cva_asw_m0118/bat_complier_object/license.liz b/cva_asw_m0118/bat_complier_object/license.liz new file mode 100644 index 0000000..ab9c12c Binary files /dev/null and b/cva_asw_m0118/bat_complier_object/license.liz differ diff --git a/cva_asw_m0118/cva_asw_m0118.ewd b/cva_asw_m0118/cva_asw_m0118.ewd new file mode 100644 index 0000000..6ac3251 --- /dev/null +++ b/cva_asw_m0118/cva_asw_m0118.ewd @@ -0,0 +1,1615 @@ + + + 4 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 33 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + E2_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9a.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/cva_asw_m0118/cva_asw_m0118.ewp b/cva_asw_m0118/cva_asw_m0118.ewp new file mode 100644 index 0000000..8fe78e3 --- /dev/null +++ b/cva_asw_m0118/cva_asw_m0118.ewp @@ -0,0 +1,1816 @@ + + + 4 + + Debug + + ARM + + 1 + + General + 3 + + 36 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 38 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 12 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 192 + inputOutputBased + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BUILDACTION + 2 + + + + + src + + drivers + + adc + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\adc\adc_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\adc\adc_drv.h + + + + clock + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\clock\clock_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\clock\clock_drv.h + + + + cmp + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cmp\cmp_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cmp\cmp_drv.h + + + + cmu + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cmu\cmu_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cmu\cmu_drv.h + + + + cpu + + cmsis + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\arm_common_tables.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\arm_const_structs.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\arm_math.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_armcc.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_armclang.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_compiler.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_gcc.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_iccarm.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_version.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\core_cm0plus.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\mpu_armv7.h + + + + cva + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cva\CVM011x.h + + + + irq + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\irq\irq_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\irq\irq_drv.h + + + + startup + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\startup\startup.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\startup\startup.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\startup\system_M011x.h + + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cpu_drv.h + + + + crc + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\crc\crc_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\crc\crc_drv.h + + + + edma + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\edma\edma_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\edma\edma_drv.h + + + + eim + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\eim\eim_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\eim\eim_drv.h + + + + erm + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\erm\erm_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\erm\erm_drv.h + + + + fhu + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\fhu\fhu_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\fhu\fhu_drv.h + + + + flash + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\flash\flash_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\flash\flash_drv.h + + + + flexcan + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\flexcan\flexcan_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\flexcan\flexcan_drv.h + + + + i2c + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2c\i2c_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2c\i2c_drv.h + + + + i2sm + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2sm\i2sm_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2sm\i2sm_drv.h + + + + i2ss + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2ss\i2ss_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2ss\i2ss_drv.h + + + + lpit + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\lpit\lpit_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\lpit\lpit_drv.h + + + + lptmr + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\lptmr\lptmr_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\lptmr\lptmr_drv.h + + + + mft + + mft_cap + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_cap\mft_cap_ch.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_cap\mft_cap_ch.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_cap\mft_cap_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_cap\mft_cap_drv.h + + + + mft_oc + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_oc\mft_oc_ch.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_oc\mft_oc_ch.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_oc\mft_oc_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_oc\mft_oc_drv.h + + + + mft_pwm + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_pwm\mft_pwm_ch.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_pwm\mft_pwm_ch.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_pwm\mft_pwm_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_pwm\mft_pwm_drv.h + + + + mft_qd + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_qd\mft_qd_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_qd\mft_qd_drv.h + + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_drv.h + + + + mpu + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mpu\mpu_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mpu\mpu_drv.h + + + + pdb + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pdb\pdb_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pdb\pdb_drv.h + + + + pins + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pins\pins_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pins\pins_drv.h + + + + power + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\power\power_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\power\power_drv.h + + + + pwmlite + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pwmlite\pwmlite_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pwmlite\pwmlite_drv.h + + + + reset + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\reset\reset_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\reset\reset_drv.h + + + + rtc + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\rtc\rtc_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\rtc\rtc_drv.h + + + + spi + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\spi\spi_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\spi\spi_drv.h + + + + trgmux + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\trgmux\trgmux_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\trgmux\trgmux_drv.h + + + + uart + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\uart\uart_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\uart\uart_drv.h + + + + wdg + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\wdg\wdg_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\wdg\wdg_drv.h + + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\mcu.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\mcu.h + + + + linker + + $PROJ_DIR$\linker\asw_m0118_flash.icf + + + + middleware + + isotp + + $PROJ_DIR$\SDK\middleware\isotp\isotp.c + + + $PROJ_DIR$\SDK\middleware\isotp\isotp.h + + + + uds + + stack + + $PROJ_DIR$\SDK\middleware\uds\stack\uds.c + + + $PROJ_DIR$\SDK\middleware\uds\stack\uds.h + + + + user + + $PROJ_DIR$\SDK\middleware\uds\user\uds_dtc.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_dtc.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service10.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service10.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service11.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service11.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service14.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service14.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service19.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service19.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service22.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service22.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service27.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service27.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service28.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service28.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service2E.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service2E.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service2F.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service2F.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service31.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service31.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service34.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service34.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service36.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service36.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service37.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service37.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service3E.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service3E.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service85.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service85.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_user.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_user.h + + + + + + private_driver + + drivers + + cpu + + startup + + $PROJ_DIR$\src\private_driver\drivers\cpu\startup\app_startup_M011x.S + + + $PROJ_DIR$\src\private_driver\drivers\cpu\startup\app_system_M011x.c + + + + + + + reg + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\adc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\alonpcc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\alonscg0_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\alonscg1_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\axbs_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\cmp_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\cmu_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\crc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\dmamux_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\edma_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\eim_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\erm_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\fhu_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\flexcan_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\ftfc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\gpio_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\i2c_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\i2sm_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\i2ss_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\lpit_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\lptmr_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\mft_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\mpu_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\mscm_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\pdb_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\pmc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\port_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\pwmlite_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\rcmalon_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\rtc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\shutpcc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\shutscg_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\sim_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\spi_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\trgmux_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\uart_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\wdg_reg.h + + + + RTT + + $PROJ_DIR$\src\RTT\SEGGER_RTT.c + + + $PROJ_DIR$\src\RTT\SEGGER_RTT.h + + + $PROJ_DIR$\src\RTT\SEGGER_RTT_ASM_ARMv7M.S + + + $PROJ_DIR$\src\RTT\SEGGER_RTT_Conf.h + + + $PROJ_DIR$\src\RTT\SEGGER_RTT_printf.c + + + $PROJ_DIR$\src\RTT\SEGGER_RTT_Syscalls_GCC.c + + + + TLE9461 + + $PROJ_DIR$\src\TLE9461\SBC_TLE94x1.h + + + $PROJ_DIR$\src\TLE9461\TLE94x1.c + + + $PROJ_DIR$\src\TLE9461\TLE94x1.h + + + $PROJ_DIR$\src\TLE9461\TLE94x1_DEFINES.h + + + $PROJ_DIR$\src\TLE9461\TLE94x1_ISR.h + + + $PROJ_DIR$\src\TLE9461\TLE94x1_SPI.c + + + $PROJ_DIR$\src\TLE9461\TLE94x1_SPI.h + + + + user + + $PROJ_DIR$\src\appTask.c + + + $PROJ_DIR$\src\canuser.c + + + $PROJ_DIR$\src\extern.c + + + $PROJ_DIR$\src\hwctrl.c + + + + + $PROJ_DIR$\src\main.c + + diff --git a/cva_asw_m0118/cva_asw_m0118.ewt b/cva_asw_m0118/cva_asw_m0118.ewt new file mode 100644 index 0000000..88fb20b --- /dev/null +++ b/cva_asw_m0118/cva_asw_m0118.ewt @@ -0,0 +1,2146 @@ + + + 4 + + Debug + + ARM + + 1 + + C-STAT + 517 + + 517 + + 0 + + 1 + 600 + 0 + 10 + 0 + 1 + 100 + Debug/C-STAT + + + 2.5.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RuntimeChecking + 0 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + src + + drivers + + adc + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\adc\adc_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\adc\adc_drv.h + + + + clock + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\clock\clock_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\clock\clock_drv.h + + + + cmp + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cmp\cmp_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cmp\cmp_drv.h + + + + cmu + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cmu\cmu_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cmu\cmu_drv.h + + + + cpu + + cmsis + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\arm_common_tables.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\arm_const_structs.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\arm_math.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_armcc.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_armclang.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_compiler.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_gcc.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_iccarm.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_version.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\core_cm0plus.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\mpu_armv7.h + + + + cva + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cva\CVM011x.h + + + + irq + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\irq\irq_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\irq\irq_drv.h + + + + startup + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\startup\startup.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\startup\startup.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\startup\system_M011x.h + + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cpu_drv.h + + + + crc + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\crc\crc_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\crc\crc_drv.h + + + + edma + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\edma\edma_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\edma\edma_drv.h + + + + eim + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\eim\eim_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\eim\eim_drv.h + + + + erm + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\erm\erm_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\erm\erm_drv.h + + + + fhu + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\fhu\fhu_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\fhu\fhu_drv.h + + + + flash + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\flash\flash_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\flash\flash_drv.h + + + + flexcan + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\flexcan\flexcan_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\flexcan\flexcan_drv.h + + + + i2c + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2c\i2c_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2c\i2c_drv.h + + + + i2sm + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2sm\i2sm_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2sm\i2sm_drv.h + + + + i2ss + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2ss\i2ss_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2ss\i2ss_drv.h + + + + lpit + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\lpit\lpit_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\lpit\lpit_drv.h + + + + lptmr + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\lptmr\lptmr_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\lptmr\lptmr_drv.h + + + + mft + + mft_cap + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_cap\mft_cap_ch.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_cap\mft_cap_ch.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_cap\mft_cap_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_cap\mft_cap_drv.h + + + + mft_oc + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_oc\mft_oc_ch.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_oc\mft_oc_ch.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_oc\mft_oc_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_oc\mft_oc_drv.h + + + + mft_pwm + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_pwm\mft_pwm_ch.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_pwm\mft_pwm_ch.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_pwm\mft_pwm_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_pwm\mft_pwm_drv.h + + + + mft_qd + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_qd\mft_qd_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_qd\mft_qd_drv.h + + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_drv.h + + + + mpu + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mpu\mpu_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mpu\mpu_drv.h + + + + pdb + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pdb\pdb_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pdb\pdb_drv.h + + + + pins + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pins\pins_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pins\pins_drv.h + + + + power + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\power\power_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\power\power_drv.h + + + + pwmlite + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pwmlite\pwmlite_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pwmlite\pwmlite_drv.h + + + + reset + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\reset\reset_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\reset\reset_drv.h + + + + rtc + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\rtc\rtc_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\rtc\rtc_drv.h + + + + spi + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\spi\spi_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\spi\spi_drv.h + + + + trgmux + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\trgmux\trgmux_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\trgmux\trgmux_drv.h + + + + uart + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\uart\uart_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\uart\uart_drv.h + + + + wdg + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\wdg\wdg_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\wdg\wdg_drv.h + + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\mcu.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\mcu.h + + + + linker + + $PROJ_DIR$\linker\asw_m0118_flash.icf + + + + middleware + + isotp + + $PROJ_DIR$\SDK\middleware\isotp\isotp.c + + + $PROJ_DIR$\SDK\middleware\isotp\isotp.h + + + + uds + + stack + + $PROJ_DIR$\SDK\middleware\uds\stack\uds.c + + + $PROJ_DIR$\SDK\middleware\uds\stack\uds.h + + + + user + + $PROJ_DIR$\SDK\middleware\uds\user\uds_dtc.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_dtc.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service10.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service10.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service11.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service11.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service14.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service14.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service19.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service19.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service22.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service22.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service27.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service27.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service28.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service28.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service2E.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service2E.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service2F.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service2F.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service31.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service31.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service34.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service34.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service36.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service36.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service37.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service37.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service3E.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service3E.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service85.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service85.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_user.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_user.h + + + + + + private_driver + + drivers + + cpu + + startup + + $PROJ_DIR$\src\private_driver\drivers\cpu\startup\app_startup_M011x.S + + + $PROJ_DIR$\src\private_driver\drivers\cpu\startup\app_system_M011x.c + + + + + + + reg + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\adc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\alonpcc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\alonscg0_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\alonscg1_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\axbs_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\cmp_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\cmu_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\crc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\dmamux_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\edma_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\eim_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\erm_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\fhu_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\flexcan_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\ftfc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\gpio_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\i2c_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\i2sm_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\i2ss_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\lpit_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\lptmr_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\mft_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\mpu_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\mscm_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\pdb_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\pmc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\port_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\pwmlite_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\rcmalon_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\rtc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\shutpcc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\shutscg_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\sim_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\spi_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\trgmux_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\uart_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\wdg_reg.h + + + + RTT + + $PROJ_DIR$\src\RTT\SEGGER_RTT.c + + + $PROJ_DIR$\src\RTT\SEGGER_RTT.h + + + $PROJ_DIR$\src\RTT\SEGGER_RTT_ASM_ARMv7M.S + + + $PROJ_DIR$\src\RTT\SEGGER_RTT_Conf.h + + + $PROJ_DIR$\src\RTT\SEGGER_RTT_printf.c + + + $PROJ_DIR$\src\RTT\SEGGER_RTT_Syscalls_GCC.c + + + + TLE9461 + + $PROJ_DIR$\src\TLE9461\SBC_TLE94x1.h + + + $PROJ_DIR$\src\TLE9461\TLE94x1.c + + + $PROJ_DIR$\src\TLE9461\TLE94x1.h + + + $PROJ_DIR$\src\TLE9461\TLE94x1_DEFINES.h + + + $PROJ_DIR$\src\TLE9461\TLE94x1_ISR.h + + + $PROJ_DIR$\src\TLE9461\TLE94x1_SPI.c + + + $PROJ_DIR$\src\TLE9461\TLE94x1_SPI.h + + + + user + + $PROJ_DIR$\src\appTask.c + + + $PROJ_DIR$\src\canuser.c + + + $PROJ_DIR$\src\extern.c + + + $PROJ_DIR$\src\hwctrl.c + + + + + $PROJ_DIR$\src\main.c + + diff --git a/cva_asw_m0118/cva_asw_m0118.eww b/cva_asw_m0118/cva_asw_m0118.eww new file mode 100644 index 0000000..bd6421b --- /dev/null +++ b/cva_asw_m0118/cva_asw_m0118.eww @@ -0,0 +1,7 @@ + + + + $WS_DIR$\cva_asw_m0118.ewp + + + diff --git a/cva_asw_m0118/linker/asw_m0118_flash.icf b/cva_asw_m0118/linker/asw_m0118_flash.icf new file mode 100644 index 0000000..2b17ec3 --- /dev/null +++ b/cva_asw_m0118/linker/asw_m0118_flash.icf @@ -0,0 +1,141 @@ +/* +** ################################################################### +** Processor: CVM0118 +** Compiler: IAR ANSI C/C++ Compiler for ARM +** +** Abstract: +** Linker file for the IAR ANSI C/C++ Compiler for ARM +** +** Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD +** All rights reserved. +** +** Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use +** exclusively with CVA's microcontroller products. This file can be freely +** distributed within development tools that are supporting such microcontroller +** products. +** +** THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED +** OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. +** CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, +** OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +** +** http: www.cvachip.com +** +** ################################################################### +*/ + +/* If symbol __flash_vector_table__=1 is defined at link time + * the interrupt vector will not be copied to RAM. + * Warning: Using the interrupt vector from FLASH will not allow + * INT_SYS_InstallHandler because the section is Read Only. + */ + +/* If want to debug the asw code without bootloader, please enable the define */ +//define symbol __asw_debug_en__ = 0x00000001; + +define symbol __flash_vector_table__ = 0x00000001; + +define symbol __ram_vector_table_size__ = isdefinedsymbol(__flash_vector_table__) ? 0 : 0x00000200; +define symbol __ram_vector_table_offset__ = isdefinedsymbol(__flash_vector_table__) ? 0 : 0x000001FF; + +/* Flash */ +define symbol m_interrupts_start = isdefinedsymbol(__asw_debug_en__) ? 0 : 0x00010000; +define symbol m_interrupts_end = isdefinedsymbol(__asw_debug_en__) ? 0 : 0x000100BF; + +define symbol m_asw_header_start = 0x000100C0; +define symbol m_asw_header_end = 0x000100ff; + +define symbol m_asw_code_start = 0x00010100; +define symbol m_asw_code_end = 0x00037FFB; + +define symbol m_asw_crc_start = 0x00037FFC; +define symbol m_asw_crc_end = 0x00037FFF; + +/* .data space */ +define symbol m_interrupts_ram_start = 0x20000000; +define symbol m_interrupts_ram_end = 0x20000000 + __ram_vector_table_offset__; + +define symbol m_data_start = m_interrupts_ram_start + __ram_vector_table_size__; +define symbol m_data_end = m_data_start + 0x00001FFF; + +/* .bss stack ... */ +define symbol m_data_2_start = m_data_end + 0x00000001; +define symbol m_data_2_end = m_data_2_start + 0x00003FEF; + +/* No initial Ram space: 16 Bytes */ +define symbol m_data_noinit_start = 0x200063F0; +define symbol m_data_noinit_end = 0x200063FF; + +/* Stack space: 512 Bytes */ +/* Stack & Heap Sizes */ +if (isdefinedsymbol(__stack_size__)) { + define symbol __size_cstack__ = __stack_size__; +} else { + define symbol __size_cstack__ = 0x00000200; +} + +if (isdefinedsymbol(__heap_size__)) { + define symbol __size_heap__ = __heap_size__; +} else { + define symbol __size_heap__ = 0x00000200; +} + +define exported symbol __VECTOR_TABLE = m_interrupts_start; +define exported symbol __VECTOR_RAM = isdefinedsymbol(__flash_vector_table__) ? m_interrupts_start : m_interrupts_ram_start; +define exported symbol __RAM_VECTOR_TABLE_SIZE = __ram_vector_table_size__; + +define exported symbol __RAM_START = m_interrupts_ram_start; +define exported symbol __RAM_END = m_data_noinit_end; + +define memory mem with size = 4G; + +define region m_asw_header_region = mem:[from m_asw_header_start to m_asw_header_end]; + +define region m_asw_code_region = mem:[from m_interrupts_start to m_interrupts_end] + | mem:[from m_asw_code_start to m_asw_code_end]; + +define region m_asw_crc_region = mem:[from m_asw_crc_start to m_asw_crc_end]; + +define region DATA_region = mem:[from m_data_start to m_data_end]; + +define region DATA_noinit_region = mem:[from m_data_noinit_start to m_data_noinit_end]; + +define region DATA_region_2 = mem:[from m_data_2_start to m_data_2_end-__size_cstack__]; +define region CSTACK_region = mem:[from m_data_2_end-__size_cstack__+1 to m_data_2_end]; +define region m_interrupts_ram_region = mem:[from m_interrupts_ram_start to m_interrupts_ram_end]; + + +define block CSTACK with alignment = 8, size = __size_cstack__ { }; +define block HEAP with alignment = 8, size = __size_heap__ { }; +define block RW { readwrite }; +define block ZI { zi }; + + +define block customSectionBlock { section .customSection }; + +define block __CODE_ROM { section .textrw_init }; +define block __CODE_RAM { section .textrw }; + +initialize manually { section .textrw }; +initialize manually { section .bss, section .bss.no_init}; +initialize manually { section .customSection, section .code_ram}; +initialize manually { section .data}; +initialize manually { section __DLIB_PERTHREAD }; + +do not initialize { section .no_init, section .bss, section .data, section __DLIB_PERTHREAD, section .customSection}; + +place at address mem: m_interrupts_start { readonly section .intvec }; +place in m_asw_code_region { readonly }; +place in m_asw_code_region { block __CODE_ROM }; +place in DATA_region { block RW }; +place in DATA_region { block __CODE_RAM }; +place in DATA_region_2 { first block customSectionBlock }; +place in DATA_region_2 { block ZI }; +place in DATA_region_2 { last block HEAP }; +place in CSTACK_region { block CSTACK }; +place in m_interrupts_ram_region { section m_interrupts_ram }; +place in DATA_noinit_region { readwrite section .bss.no_init }; +place in m_asw_header_region { readonly section .asw_header}; +place in m_asw_crc_region { readonly section .checksum}; + diff --git a/cva_asw_m0118/settings/cva_asw_m0118.Debug.cspy.bat b/cva_asw_m0118/settings/cva_asw_m0118.Debug.cspy.bat new file mode 100644 index 0000000..b33c581 --- /dev/null +++ b/cva_asw_m0118/settings/cva_asw_m0118.Debug.cspy.bat @@ -0,0 +1,40 @@ +@REM This batch file has been generated by the IAR Embedded Workbench +@REM C-SPY Debugger, as an aid to preparing a command line for running +@REM the cspybat command line utility using the appropriate settings. +@REM +@REM Note that this file is generated every time a new debug session +@REM is initialized, so you may want to move or rename the file before +@REM making changes. +@REM +@REM You can launch cspybat by typing the name of this batch file followed +@REM by the name of the debug file (usually an ELF/DWARF or UBROF file). +@REM +@REM Read about available command line parameters in the C-SPY Debugging +@REM Guide. Hints about additional command line parameters that may be +@REM useful in specific cases: +@REM --download_only Downloads a code image without starting a debug +@REM session afterwards. +@REM --silent Omits the sign-on message. +@REM --timeout Limits the maximum allowed execution time. +@REM + + +@echo off + +if not "%~1" == "" goto debugFile + +@echo on + +"E:\Program Files\IAR Systems\Embedded Workbench 9.2\common\bin\cspybat" -f "F:\FCB_project\RP-77\CVM0118BOOT\cva_asw_m0118\settings\cva_asw_m0118.Debug.general.xcl" --backend -f "F:\FCB_project\RP-77\CVM0118BOOT\cva_asw_m0118\settings\cva_asw_m0118.Debug.driver.xcl" + +@echo off +goto end + +:debugFile + +@echo on + +"E:\Program Files\IAR Systems\Embedded Workbench 9.2\common\bin\cspybat" -f "F:\FCB_project\RP-77\CVM0118BOOT\cva_asw_m0118\settings\cva_asw_m0118.Debug.general.xcl" "--debug_file=%~1" --backend -f "F:\FCB_project\RP-77\CVM0118BOOT\cva_asw_m0118\settings\cva_asw_m0118.Debug.driver.xcl" + +@echo off +:end \ No newline at end of file diff --git a/cva_asw_m0118/settings/cva_asw_m0118.Debug.cspy.ps1 b/cva_asw_m0118/settings/cva_asw_m0118.Debug.cspy.ps1 new file mode 100644 index 0000000..e50a82c --- /dev/null +++ b/cva_asw_m0118/settings/cva_asw_m0118.Debug.cspy.ps1 @@ -0,0 +1,31 @@ +param([String]$debugfile = ""); + +# This powershell file has been generated by the IAR Embedded Workbench +# C - SPY Debugger, as an aid to preparing a command line for running +# the cspybat command line utility using the appropriate settings. +# +# Note that this file is generated every time a new debug session +# is initialized, so you may want to move or rename the file before +# making changes. +# +# You can launch cspybat by typing Powershell.exe -File followed by the name of this batch file, followed +# by the name of the debug file (usually an ELF / DWARF or UBROF file). +# +# Read about available command line parameters in the C - SPY Debugging +# Guide. Hints about additional command line parameters that may be +# useful in specific cases : +# --download_only Downloads a code image without starting a debug +# session afterwards. +# --silent Omits the sign - on message. +# --timeout Limits the maximum allowed execution time. +# + + +if ($debugfile -eq "") +{ +& "E:\Program Files\IAR Systems\Embedded Workbench 9.2\common\bin\cspybat" -f "F:\FCB_project\RP-77\CVM0118BOOT\cva_asw_m0118\settings\cva_asw_m0118.Debug.general.xcl" --backend -f "F:\FCB_project\RP-77\CVM0118BOOT\cva_asw_m0118\settings\cva_asw_m0118.Debug.driver.xcl" +} +else +{ +& "E:\Program Files\IAR Systems\Embedded Workbench 9.2\common\bin\cspybat" -f "F:\FCB_project\RP-77\CVM0118BOOT\cva_asw_m0118\settings\cva_asw_m0118.Debug.general.xcl" --debug_file=$debugfile --backend -f "F:\FCB_project\RP-77\CVM0118BOOT\cva_asw_m0118\settings\cva_asw_m0118.Debug.driver.xcl" +} diff --git a/cva_asw_m0118/settings/cva_asw_m0118.Debug.driver.xcl b/cva_asw_m0118/settings/cva_asw_m0118.Debug.driver.xcl new file mode 100644 index 0000000..e3d9d6b --- /dev/null +++ b/cva_asw_m0118/settings/cva_asw_m0118.Debug.driver.xcl @@ -0,0 +1,31 @@ +"--endian=little" + +"--cpu=Cortex-M0+" + +"--fpu=None" + +"-p" + +"E:\Program Files\IAR Systems\Embedded Workbench 9.2\arm\config\debugger\CVAChip\CVM0118.ddf" + +"--semihosting" + +"--device=CVM0118" + +"--drv_communication=USB0" + +"--drv_interface_speed=auto" + +"--jlink_initial_speed=1000" + +"--jlink_reset_strategy=0,0" + +"--drv_interface=SWD" + +"--drv_catch_exceptions=0x000" + +"--drv_swo_clock_setup=80000000,0,2000000" + + + + diff --git a/cva_asw_m0118/settings/cva_asw_m0118.Debug.general.xcl b/cva_asw_m0118/settings/cva_asw_m0118.Debug.general.xcl new file mode 100644 index 0000000..a484125 --- /dev/null +++ b/cva_asw_m0118/settings/cva_asw_m0118.Debug.general.xcl @@ -0,0 +1,11 @@ +"E:\Program Files\IAR Systems\Embedded Workbench 9.2\arm\bin\armPROC.dll" + +"E:\Program Files\IAR Systems\Embedded Workbench 9.2\arm\bin\armJLINK.dll" + +"F:\FCB_project\RP-77\CVM0118BOOT\cva_asw_m0118\Debug_FLASH\Exe\cva_asw_m0118.out" + +--plugin="E:\Program Files\IAR Systems\Embedded Workbench 9.2\arm\bin\armbat.dll" + + + + diff --git a/cva_asw_m0118/settings/cva_asw_m0118.crun b/cva_asw_m0118/settings/cva_asw_m0118.crun new file mode 100644 index 0000000..d71ea55 --- /dev/null +++ b/cva_asw_m0118/settings/cva_asw_m0118.crun @@ -0,0 +1,13 @@ + + + 1 + + + * + * + * + 0 + 1 + + + diff --git a/cva_asw_m0118/settings/cva_asw_m0118.dbgdt b/cva_asw_m0118/settings/cva_asw_m0118.dbgdt new file mode 100644 index 0000000..3a08e2b --- /dev/null +++ b/cva_asw_m0118/settings/cva_asw_m0118.dbgdt @@ -0,0 +1,999 @@ + + + + + 34048 + 34049 + 34050 + 34051 + 34052 + 34053 + 34054 + 34055 + 34056 + 34057 + 34058 + 34059 + 34060 + 34061 + 34062 + 34063 + 34064 + 34065 + 34066 + 34067 + 34068 + 34069 + 34070 + 34071 + 34072 + 34073 + 34074 + 34075 + 34076 + 34077 + 34078 + 34079 + 34080 + 34081 + 34082 + 34083 + 34084 + 34085 + 34086 + 34087 + 34088 + 34089 + 34090 + 34091 + 34092 + 34093 + 34094 + 34095 + 34096 + 34097 + 34098 + 34099 + 34100 + 34101 + 34102 + 34103 + 34104 + 34105 + + + + + 34001 + 0 + + + + + 34390 + 34323 + 34398 + 34400 + 34397 + 34320 + 34321 + 34324 + 0 + + + + + 37459 + 37460 + + + + + 57600 + 57601 + 57603 + 33024 + 0 + 57607 + 0 + 57635 + 57634 + 57637 + 0 + 57643 + 57644 + 0 + 33090 + 33057 + 57636 + 57640 + 57641 + 33026 + 33065 + 33063 + 33064 + 33053 + 33054 + 0 + 33035 + 33036 + 34399 + 0 + 33055 + 33056 + 33094 + 0 + + + + + + Disassembly + _I0 + + + 500 + 20 + + 1 + 1 + + + 14 + 32 + + + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1D0000000800108600000A0000000C8100000400000056860000010000000E810000010000000B81000001000000118600000900000046810000030000000A84000001000000 + + + 28002DDE00001FDE000020DE000021DE000026DE000028DE000023DE000022DE000024DE000027DE000025DE000020920000289200002992000037920000389200003492000033920000259200001E9200001D9200002CDE00000C84000033840000788400001184000008800000098000000A8000000B8000000C800000158000000A810000FFFFFFFF01E80000778400000784000086840000808C000044D50000 + 1D00048400004D000000048100001B0000003184000054000000208100002A0000000F8100002200000000900000580000000C8100001F000000068400004F000000098100001D000000038400004C0000000E840000510000003084000053000000449200000C0000001F810000290000000E810000210000001F920000090000000B8100001E0000002D9200000B000000D184000008000000058400004E000000028400004B000000058100001C000000108400005200000032840000550000000A840000500000000D8100002000000035E100004500000002E100003B0000002C9200000A000000 + + + 0 + 0A0000000A0000006E0000006E000000 + 000000001A030000000600002B030000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 4294967295 + 00000000CB010000000600007C020000 + 00000000B40100000006000065020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34052 + 00000000170000000601000078010000 + FE04000030000000FC05000000030000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34072 + 00000000170000000601000078010000 + FE04000030000000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34095 + 00000000170000000601000078010000 + FE04000030000000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34101 + 00000000170000000601000078010000 + FE04000030000000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34102 + 00000000170000000601000078010000 + FE04000030000000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34103 + 00000000170000000601000078010000 + FE04000030000000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34104 + 00000000170000000601000078010000 + FE04000030000000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34053 + 000000001700000022010000C8000000 + 0400000081020000FC05000000030000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34079 + 000000001700000022010000C8000000 + 0400000081020000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34054 + 000000001700000022010000C8000000 + 0400000081020000FC05000000030000 + 32768 + 0 + 0 + 32767 + 0 + + + 1 + + + 34062 + 000000001700000022010000C8000000 + 0400000081020000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34066 + 000000001700000022010000C8000000 + 0400000081020000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34067 + 000000001700000022010000C8000000 + 0400000081020000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34068 + 000000001700000022010000C8000000 + 0400000081020000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34087 + 000000001700000022010000C8000000 + 0400000081020000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34090 + 000000001700000022010000C8000000 + 0400000081020000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34100 + 000000001700000022010000C8000000 + 0400000081020000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34055 + 000000001700000080020000A8000000 + 00000000000000008002000091000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34056 + 00000000170000000601000078010000 + 0400000030000000020100004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34092 + 00000000170000000601000078010000 + 0400000030000000020100004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34093 + 00000000170000000601000078010000 + 0400000030000000020100004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34057 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34058 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34059 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34060 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34061 + 00000000170000000601000078010000 + FE04000030000000FC0500004B020000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34073 + 00000000170000000601000078010000 + FE04000030000000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34063 + 00000000170000000601000078010000 + FA040000320000000006000065020000 + 16384 + 0 + 0 + 32767 + 0 + + + 1 + + + 34064 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34065 + 000000001700000022010000C8000000 + 04000000CC010000FC0500004B020000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34070 + 000000001700000022010000C8000000 + 04000000CC010000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34088 + 000000001700000022010000C8000000 + 04000000CC010000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34089 + 000000001700000022010000C8000000 + 04000000CC010000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34069 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34071 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34074 + 00000000170000000601000078010000 + FE04000030000000FC0500004B020000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34082 + 00000000170000000601000078010000 + FE04000030000000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34083 + 00000000170000000601000078010000 + FE04000030000000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34084 + 00000000170000000601000078010000 + FE04000030000000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34085 + 00000000170000000601000078010000 + FE04000030000000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34075 + 000000001700000022010000C8000000 + 04000000CC010000FC0500004B020000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34076 + 000000001700000022010000C8000000 + 04000000CC010000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34077 + 000000001700000022010000C8000000 + 04000000CC010000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34078 + 000000001700000022010000C8000000 + 04000000CC010000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34080 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34081 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34086 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34091 + 000000001700000080020000A8000000 + 00000000000000008002000091000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34094 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34096 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34097 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34098 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34099 + 0000000017000000AE010000D8000000 + 0000000000000000AE010000C1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34105 + 00000000170000000601000078010000 + 00000000320000000601000065020000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 0000000036000000000000000010000001000000FFFFFFFFFFFFFFFF06010000320000000A01000065020000010000000200001004000000010000000000000000000000398500000000000000000000000000000000000001000000398500000100000039850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000338500000000000000000000000000000000000001000000338500000100000033850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000328500000000000000000000000000000000000001000000328500000100000032850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000318500000000000000000000000000000000000001000000318500000100000031850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000308500000000000000000000000000000000000001000000308500000100000030850000000000000040000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000000040000000100000000000000000000002E85000000000000000000000000000000000000010000002E850000010000002E850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000002B85000000000000000000000000000000000000010000002B850000010000002B850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000268500000000000000000000000000000000000001000000268500000100000026850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000218500000000000000000000000000000000000001000000218500000100000021850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000208500000000000000000000000000000000000001000000208500000100000020850000000000000080000000000000FFFFFFFFFFFFFFFF00000000B001000000060000B4010000000000000100000004000000010000000000000000000000FFFFFFFF040000001B8500001C8500001D8500001E850000FFFF02000B004354616262656450616E65008000000000000000000000CB010000000600007C02000000000000B40100000006000065020000000000004080004604000000FFFEFF084D0065006D006F007200790020003100000000001B85000001000000FFFFFFFFFFFFFFFFFFFEFF084D0065006D006F007200790020003200000000001C85000001000000FFFFFFFFFFFFFFFFFFFEFF084D0065006D006F007200790020003300000000001D85000001000000FFFFFFFFFFFFFFFFFFFEFF084D0065006D006F007200790020003400000000001E85000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFF1B85000001000000FFFFFFFF1B850000000000000040000000000000FFFFFFFFFFFFFFFFF604000018000000FA04000065020000000000000200000004000000010000000000000000000000FFFFFFFF050000001A8500002285000023850000248500002585000001800040000000000000FA0400002F000000000600007C020000FA040000180000000006000065020000000000004040004605000000FFFEFF124D006100630072006F00200052006500670069007300740072006100740069006F006E00000000001A85000001000000FFFFFFFFFFFFFFFFFFFEFF0B52006500670069007300740065007200730020003100000000002285000001000000FFFFFFFFFFFFFFFFFFFEFF0B52006500670069007300740065007200730020003200000000002385000001000000FFFFFFFFFFFFFFFFFFFEFF0B52006500670069007300740065007200730020003300000000002485000001000000FFFFFFFFFFFFFFFFFFFEFF0B52006500670069007300740065007200730020003400000000002585000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFF1A85000001000000FFFFFFFF1A850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000178500000000000000000000000000000000000001000000178500000100000017850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000158500000000000000000000000000000000000001000000158500000100000015850000000000000080000000000000FFFFFFFFFFFFFFFF00000000B001000000060000B4010000000000000100000004000000010000000000000000000000FFFFFFFF04000000118500001685000028850000298500000180008000000000000000000000CB010000000600007C02000000000000B40100000006000065020000000000004080004604000000FFFEFF09530057004F00200054007200610063006500000000001185000001000000FFFFFFFFFFFFFFFFFFFEFF11460069006E006400200049006E002000530057004F00200054007200610063006500000000001685000001000000FFFFFFFFFFFFFFFFFFFEFF12450054004D002000460075006E006300740069006F006E00200054007200610063006500000000002885000001000000FFFFFFFFFFFFFFFFFFFEFF09450054004D00200054007200610063006500000000002985000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFF1185000001000000FFFFFFFF11850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000108500000000000000000000000000000000000001000000108500000100000010850000000000000040000001000000FFFFFFFFFFFFFFFFF604000032000000FA040000650200000100000002000010040000000100000000000000000000000F85000000000000000000000000000000000000010000000F850000010000000F850000000000000040000000000000FFFFFFFFFFFFFFFFF604000018000000FA04000065020000000000000200000004000000010000000000000000000000FFFFFFFF020000000D8500001985000001800040000000000000FA0400002F000000000600007C020000FA040000180000000006000065020000000000004040004602000000FFFEFF0F4400650062007500670067006500720020004D006100630072006F007300000000000D85000001000000FFFFFFFFFFFFFFFFFFFEFF114D006100630072006F00200051007500690063006B006C00610075006E0063006800000000001985000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFF0D85000001000000FFFFFFFF0D850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000C85000000000000000000000000000000000000010000000C850000010000000C850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000B85000000000000000000000000000000000000010000000B850000010000000B850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000A85000000000000000000000000000000000000010000000A850000010000000A850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000098500000000000000000000000000000000000001000000098500000100000009850000000000000010000000000000FFFFFFFFFFFFFFFF06010000180000000A01000065020000000000000200000004000000010000000000000000000000FFFFFFFF03000000088500002C8500002D85000001800010000000000000000000002F000000060100007C02000000000000180000000601000065020000000000004010004603000000FFFEFF0A430061006C006C00200053007400610063006B00000000000885000001000000FFFFFFFFFFFFFFFFFFFEFF0753007400610063006B0020003100000000002C85000001000000FFFFFFFFFFFFFFFFFFFEFF0753007400610063006B0020003200000000002D85000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFF0885000001000000FFFFFFFF08850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000078500000000000000000000000000000000000001000000078500000100000007850000000000000080000001000000FFFFFFFFFFFFFFFF00000000650200000006000069020000010000000100001004000000010000000000000000000000FFFFFFFF08000000068500000E850000128500001385000014850000278500002A8500003485000001800080000001000000000000008002000000060000310300000000000069020000000600001A030000000000004080005608000000FFFEFF054200750069006C006400010000000685000001000000FFFFFFFFFFFFFFFFFFFEFF094400650062007500670020004C006F006700010000000E85000001000000FFFFFFFFFFFFFFFFFFFEFF0C4400650063006C00610072006100740069006F006E007300000000001285000001000000FFFFFFFFFFFFFFFFFFFEFF0A5200650066006500720065006E00630065007300000000001385000001000000FFFFFFFFFFFFFFFFFFFEFF0D460069006E006400200069006E002000460069006C0065007300000000001485000001000000FFFFFFFFFFFFFFFFFFFEFF1541006D0062006900670075006F0075007300200044006500660069006E006900740069006F006E007300000000002785000001000000FFFFFFFFFFFFFFFFFFFEFF1153006F0075007200630065002000420072006F0077007300650020004C006F006700000000002A85000001000000FFFFFFFFFFFFFFFFFFFEFF0B54006F006F006C0020004F0075007400700075007400000000003485000001000000FFFFFFFFFFFFFFFF01000000000000000000000000000000000000000000000001000000FFFFFFFF0685000001000000FFFFFFFF06850000000000000080000000000000FFFFFFFFFFFFFFFF00000000650200000006000069020000000000000100000004000000010000000000000000000000FFFFFFFF02000000058500001F85000001800080000000000000000000008002000000060000310300000000000069020000000600001A030000000000004080004602000000FFFEFF0B42007200650061006B0070006F0069006E0074007300000000000585000001000000FFFFFFFFFFFFFFFFFFFEFF1042007200650061006B0070006F0069006E007400200055007300610067006500000000001F85000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFF0585000001000000FFFFFFFF05850000000000000040000000000000FFFFFFFFFFFFFFFFF604000018000000FA0400001A030000000000000200000004000000010000000000000000000000FFFFFFFF0700000004850000188500002F8500003585000036850000378500003885000001800040000000000000FA0400002F0000000006000031030000FA04000018000000000600001A030000000000004040004607000000FFFEFF044100750074006F00000000000485000001000000FFFFFFFFFFFFFFFFFFFEFF064C006F00630061006C007300000000001885000001000000FFFFFFFFFFFFFFFFFFFEFF0A4C00690076006500200057006100740063006800000000002F85000001000000FFFFFFFFFFFFFFFFFFFEFF075700610074006300680020003100000000003585000001000000FFFFFFFFFFFFFFFFFFFEFF075700610074006300680020003200000000003685000001000000FFFFFFFFFFFFFFFFFFFEFF075700610074006300680020003300000000003785000001000000FFFFFFFFFFFFFFFFFFFEFF075700610074006300680020003400000000003885000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFF0485000001000000FFFFFFFF04850000000000000000000000000000 + + + CMSIS-Pack + 00200000010000000100FFFF01001100434D4643546F6F6C426172427574746F6ED184000002000000EA020000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF0A43004D005300490053002D005000610063006B0018000000 + + + 34048 + 0A0000000A0000006E0000006E000000 + 6704000000000000950400001A000000 + 8192 + 0 + 0 + 24 + 0 + + + 1 + + + Debug + 00200000010000000800FFFF01001100434D4643546F6F6C426172427574746F6E568600000200000005030000FFFEFF0000000000000000000000000001000000010000000180138600000200000001030000FFFEFF00000000000000000000000000010000000100000001805E8600000200000007030000FFFEFF0000000000000000000000000001000000010000000180608600000200000009030000FFFEFF00000000000000000000000000010000000100000001805D8600000200000006030000FFFEFF00000000000000000000000000010000000100000001801086000002000000FF020000FFFEFF0000000000000000000000000001000000010000000180118600000200040000030000FFFEFF000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E148600000200000002030000FFFEFF205200650073006500740020007400680065002000640065006200750067006700650064002000700072006F006700720061006D000A00520065007300650074000000000000000000000000000100000001000000000000000000000001000000060009802B87000000000000FFFFFFFFFFFEFF13440069007300610062006C0065006400200028004E006F0020007200650073006500740029000100000000000000000000000100000001000000000000000000000001000000000009802C87000000000000FFFFFFFFFFFEFF0853006F006600740077006100720065000100000000000000000000000100000001000000000000000000000001000000000009802D87000000000000FFFFFFFFFFFEFF144800610072006400770061007200650020002800520065007300650074002000700069006E0029000100000000000000000000000100000001000000000000000000000001000000000009802F87000000000000FFFFFFFFFFFEFF064E006F0072006D0061006C000100000000000000000000000100000001000000000000000000000001000000000009800000000000000400FFFFFFFFFFFEFF000000000000000000000000000100000001000000000000000000000001000000000009801986000000000000FFFFFFFFFFFEFF000100000000000000000000000100000001000000000000000000000001000000000000000000FFFEFF0544006500620075006700C6000000 + + + 34049 + 0A0000000A0000006E0000006E000000 + 51030000000000002D0400001A000000 + 8192 + 0 + 0 + 198 + 0 + + + 1 + + + Trace + 00200000010000000200FFFF01001100434D4643546F6F6C426172427574746F6E53920000000000006C030000FFFEFF03450054004D000000000000000000000000000100000001000000018054920000000004006D030000FFFEFF03530057004F00000000000000000000000000010000000100000000000000FFFEFF05540072006100630065002F000000 + + + 34050 + 0A0000000A0000006E0000006E000000 + 2D04000000000000670400001A000000 + 8192 + 0 + 0 + 47 + 0 + + + 1 + + + Main + 00200000010000002100FFFF01001100434D4643546F6F6C426172427574746F6E00E10000000000004B030000FFFEFF000000000000000000000000000100000001000000018001E10000000000004C030000FFFEFF000000000000000000000000000100000001000000018003E10000000000004E030000FFFEFF000000000000000000000000000100000001000000018000810000000000002B030000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018007E100000000000051030000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018023E100000000040053030000FFFEFF000000000000000000000000000100000001000000018022E100000000040052030000FFFEFF000000000000000000000000000100000001000000018025E100000000000054030000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001802BE100000000040055030000FFFEFF00000000000000000000000000010000000100000001802CE100000000040056030000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000FFFF01000D005061737465436F6D626F426F784281000000000000FFFFFFFFFFFEFF000000000000000000010000000000000001000000B400000002002050FFFFFFFFFFFEFF0096000000000000000000018021810000000004003D030000FFFEFF000000000000000000000000000100000001000000018024E100000000000046030000FFFEFF000000000000000000000000000100000001000000018028E100000000040045030000FFFEFF000000000000000000000000000100000001000000018029E100000000000047030000FFFEFF000000000000000000000000000100000001000000018002810000000000002C030000FFFEFF0000000000000000000000000001000000010000000180298100000000000041030000FFFEFF000000000000000000000000000100000001000000018027810000000000003F030000FFFEFF0000000000000000000000000001000000010000000180288100000000000040030000FFFEFF00000000000000000000000000010000000100000001801D8100000000000039030000FFFEFF00000000000000000000000000010000000100000001801E810000000004003A030000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800B8100000200000030030000FFFEFF00000000000000000000000000010000000100000001800C8100000200000031030000FFFEFF00000000000000000000000000010000000100000001805F8600000200000044030000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001801F810000020000003B030000FFFEFF000000000000000000000000000100000001000000018020810000020000003C030000FFFEFF0000000000000000000000000001000000010000000180468100000200020042030000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF044D00610069006E003B030000 + + + 34051 + 0A0000000A0000006E0000006E000000 + 0000000000000000510300001A000000 + 8192 + 0 + 0 + 827 + 0 + + + 1 + + + + diff --git a/cva_asw_m0118/settings/cva_asw_m0118.dnx b/cva_asw_m0118/settings/cva_asw_m0118.dnx new file mode 100644 index 0000000..b622afd --- /dev/null +++ b/cva_asw_m0118/settings/cva_asw_m0118.dnx @@ -0,0 +1,82 @@ + + + + 0 + 1 + 90 + 1 + 1 + 1 + main + 0 + 50 + + + 0 + E:\Program Files\IAR Systems\Embedded Workbench 9.2\arm\config\debugger\CVAChip\CVM0118.ddf + + + 1 + 0 + + + 334396109 + + + 1 + 0 + + + 0 + 1 + + + 1 + 10 + $PROJ_DIR$\TermIOInput.txt + 1 + 0 + 2 + 2 + + + _ 0 + _ 0 + + + 0 + + + _ 0 + _ 0 + 12 + 0 + 0x10000 + 0x0 + 0x0 + + + 0 + 0 + + + 0 + 1 + 0 + 0 + + + _ 0 + _ "" + + + 0 + + + 0 + + + 0 + 0 + + diff --git a/cva_asw_m0118/settings/cva_asw_m0118.wsdt b/cva_asw_m0118/settings/cva_asw_m0118.wsdt new file mode 100644 index 0000000..ffa611e --- /dev/null +++ b/cva_asw_m0118/settings/cva_asw_m0118.wsdt @@ -0,0 +1,504 @@ + + + + + cva_asw_m0118/Debug + + + + + 34048 + 34049 + 34050 + 34051 + 34052 + 34053 + 34054 + 34055 + 34056 + 34057 + 34058 + 34059 + 34060 + 34061 + 34062 + 34063 + + + + + 34001 + 0 + + + + + 57600 + 57601 + 57603 + 33024 + 0 + 57607 + 0 + 57635 + 57634 + 57637 + 0 + 57643 + 57644 + 0 + 33090 + 33057 + 57636 + 57640 + 57641 + 33026 + 33065 + 33063 + 33064 + 33053 + 33054 + 0 + 33035 + 33036 + 34399 + 0 + 33038 + 33039 + 0 + + + + + Log + _I0 + + + 1486 + 20 + + 2 + $PROJ_DIR$\DebugLog.log + 0 + 0 + + + + cva_asw_m0118 + cva_asw_m0118/src + cva_asw_m0118/src/user + + + + 14 + 32 + + + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 2D000000090010860000050000000C8100002600000056860000010000000E810000020000000B810000030000000581000001000000118600000500000046810000010000000A84000001000000 + + + 3B002DDE00001FDE000020DE000021DE000026DE000028DE000023DE000022DE000024DE000027DE000025DE0000209200002892000029920000379200003892000034920000339200001E9200001D9200002CDE00000C84000033840000788400001184000008800000098000000A8000000B8000000C800000158000000A810000FFFFFFFF01E80000778400000784000086840000808C000044D500000D8400000F8400000884000054840000328100001C81000009840000538400003C8400003D840000408400004C8400003E8400004B8400004D8400003F8400003A8400003B8400005A8400005B840000 + 1E0004840000B403000004810000820300003184000054000000208100002A0000000F8100002200000000900000BF0300000C8100001F00000006840000B60300000981000084030000038400004C00000025920000590000000E840000B803000030840000BA03000044920000730300001F810000290000000E810000210000001F920000700300000B810000850300002D92000072030000D184000008000000058400004E000000028400004B0000000581000083030000108400005200000032840000550000000A840000500000000D8100008703000035E10000AC03000002E10000A20300002C92000071030000 + + + 0 + 0A0000000A0000006E0000006E000000 + 000000001A030000000600002B030000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34050 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 4294967295 + 00000000FE0100000006000031030000 + 00000000E7010000000600001A030000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34051 + 000000001700000022010000C8000000 + 04000000FF010000FC05000000030000 + 32768 + 0 + 0 + 32767 + 0 + + + 1 + + + + File + Line + Messages + _I0 + + + 338 + 40 + 1107 + 20 + + 2 + $WS_DIR$\BuildLog.log + 0 + 0 + + + 34055 + 000000001700000022010000C8000000 + 04000000FF010000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34056 + 000000001700000022010000C8000000 + 04000000FF010000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 533 + 76 + 914 + 2 + + 0 + -1 + + + 34057 + 000000001700000022010000C8000000 + 04000000FF010000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 533 + 76 + 914 + 2 + + 0 + -1 + + + 34058 + 000000001700000022010000C8000000 + 04000000FF010000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34059 + 000000001700000022010000C8000000 + 04000000FF010000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 533 + 76 + 914 + 2 + + 0 + -1 + + + 34060 + 000000001700000022010000C8000000 + 04000000FF010000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 2 + $WS_DIR/SourceBrowseLog.log + 0 + -1 + + + 34062 + 000000001700000022010000C8000000 + 04000000FF010000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 2 + + 0 + -1 + + + 34052 + 000000001700000080020000A8000000 + 00000000000000008002000091000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 2 + + + + + + + + + <Right-click on a symbol in the editor to show a call graph> + + + + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + File + Function + Line + + + 200 + 700 + 100 + + + + 34053 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34054 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + + Check + File + Line + Message + Severity + + + 200 + 200 + 100 + 500 + 100 + + + + 34061 + 000000001700000080020000A8000000 + 00000000000000008002000091000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 2 + + + 0 + + + F:\FCB_project\RP-77\CVM0118BOOT\cva_asw_m0118\Debug\BrowseInfo\cva_asw_m0118.pbw + + + File + Name + Scope + Symbol type + + + 300 + 300 + 300 + 300 + + + + 34063 + 00000000170000000601000078010000 + 000000003200000006010000E3010000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 000000000E000000000000000010000001000000FFFFFFFFFFFFFFFF06010000320000000A010000E30100000100000002000010040000000100000000000000000000000F85000000000000000000000000000000000000010000000F850000010000000F850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000D85000000000000000000000000000000000000010000000D850000010000000D850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000068500000000000000000000000000000000000001000000068500000100000006850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000058500000000000000000000000000000000000001000000058500000100000005850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000048500000000000000000000000000000000000001000000048500000100000004850000000000000080000001000000FFFFFFFFFFFFFFFF00000000E301000000060000E701000001000000010000100400000001000000D2FDFFFF6F000000FFFFFFFF08000000038500000785000008850000098500000A8500000B8500000C8500000E850000FFFF02000B004354616262656450616E65008000000100000000000000FE010000000600003103000000000000E7010000000600001A030000000000004080005608000000FFFEFF054200750069006C006400010000000385000001000000FFFFFFFFFFFFFFFFFFFEFF094400650062007500670020004C006F006700010000000785000001000000FFFFFFFFFFFFFFFFFFFEFF0C4400650063006C00610072006100740069006F006E007300000000000885000001000000FFFFFFFFFFFFFFFFFFFEFF0A5200650066006500720065006E00630065007300000000000985000001000000FFFFFFFFFFFFFFFFFFFEFF0D460069006E006400200069006E002000460069006C0065007300000000000A85000001000000FFFFFFFFFFFFFFFFFFFEFF1541006D0062006900670075006F0075007300200044006500660069006E006900740069006F006E007300000000000B85000001000000FFFFFFFFFFFFFFFFFFFEFF1153006F0075007200630065002000420072006F0077007300650020004C006F006700000000000C85000001000000FFFFFFFFFFFFFFFFFFFEFF0B54006F006F006C0020004F0075007400700075007400000000000E85000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFF0385000001000000FFFFFFFF03850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000028500000000000000000000000000000000000001000000028500000100000002850000000000000000000000000000 + + + CMSIS-Pack + 00200000010000000100FFFF01001100434D4643546F6F6C426172427574746F6ED1840000020000006F030000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF0A43004D005300490053002D005000610063006B0018000000 + + + 34048 + 0A0000000A0000006E0000006E000000 + 3A03000000000000680300001A000000 + 8192 + 0 + 0 + 24 + 0 + + + 1 + + + Main + 00200000010000002000FFFF01001100434D4643546F6F6C426172427574746F6E00E1000000000000A0030000FFFEFF000000000000000000000000000100000001000000018001E1000000000000A1030000FFFEFF000000000000000000000000000100000001000000018003E1000000000000A3030000FFFEFF0000000000000000000000000001000000010000000180008100000000000080030000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018007E1000000000000A6030000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018023E1000000000400A8030000FFFEFF000000000000000000000000000100000001000000018022E1000000000400A7030000FFFEFF000000000000000000000000000100000001000000018025E1000000000400A9030000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001802BE1000000000400AA030000FFFEFF00000000000000000000000000010000000100000001802CE1000000000400AB030000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000FFFF01000D005061737465436F6D626F426F784281000000000000FFFFFFFFFFFEFF000000000000000000010000000000000001000000B400000002002050FFFFFFFFFFFEFF00960000000000000000000180218100000000040092030000FFFEFF000000000000000000000000000100000001000000018024E10000000000009B030000FFFEFF000000000000000000000000000100000001000000018028E10000000004009A030000FFFEFF000000000000000000000000000100000001000000018029E10000000000009C030000FFFEFF0000000000000000000000000001000000010000000180028100000000000081030000FFFEFF0000000000000000000000000001000000010000000180298100000000000096030000FFFEFF0000000000000000000000000001000000010000000180278100000000000094030000FFFEFF0000000000000000000000000001000000010000000180288100000000000095030000FFFEFF00000000000000000000000000010000000100000001801D810000000000008E030000FFFEFF00000000000000000000000000010000000100000001801E810000000004008F030000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800B8100000200000085030000FFFEFF00000000000000000000000000010000000100000001800C8100000200000086030000FFFEFF00000000000000000000000000010000000100000001805F8600000200000099030000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800E8100000200000088030000FFFEFF00000000000000000000000000010000000100000001800F8100000200000089030000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF044D00610069006E0024030000 + + + 34049 + 0A0000000A0000006E0000006E000000 + 00000000000000003A0300001A000000 + 8192 + 0 + 0 + 804 + 0 + + + 1 + + + + + 01000000030000000100000000000000000000000100000001000000FFFFFFFF00000000010000000100000000000000280000002800000001000000090000000700000001000000FFFEFF132400570053005F0044004900520024005C007300720063005C006D00610069006E002E00630001000000FFFF010017004966436F6E74656E7453746F726167654D6663496D706CFFFEFF00FFFEFFFF27013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E00340039003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0031003900310037003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0031003900310037003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF066D00610069006E002E00630000000000FFFFFFFFFFFFFFFFFFFEFF152400570053005F0044004900520024005C007300720063005C00650078007400650072006E002E006300010000000180FFFEFF00FFFEFFFF21013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E00340032003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0030003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0030003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF08650078007400650072006E002E00630000000000FFFFFFFFFFFFFFFFFFFEFF222400570053005F0044004900520024005C007300720063005C0054004C00450039003400360031005C0054004C00450039003400780031005F005300500049002E006300010000000180FFFEFF00FFFEFFFF27013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E00390037003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0034003300340035003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0034003300340035003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF0D54004C00450039003400780031005F005300500049002E00630000000000FFFFFFFFFFFFFFFFFFFEFF302400570053005F0044004900520024005C00530044004B005C006D006900640064006C00650077006100720065005C007500640073005C0075007300650072005C007500640073005F007300650072007600690063006500310031002E006300010000000180FFFEFF00FFFEFFFF24013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E0030003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E003800370038003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E003800370038003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF0F7500640073005F007300650072007600690063006500310031002E00630000000000FFFFFFFFFFFFFFFFFFFEFF2A2400570053005F0044004900520024005C00530044004B005C006D006900640064006C00650077006100720065005C007500640073005C0073007400610063006B005C007300740069006D00650072002E006800010000000180FFFEFF00FFFEFFFF27013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E00390036003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0033003500300030003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0033003500300030003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF087300740069006D00650072002E00680000000000FFFFFFFFFFFFFFFFFFFEFF152400570053005F0044004900520024005C007300720063005C00680077006300740072006C002E006300010000000180FFFEFF00FFFEFFFF20013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E0030003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0030003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0030003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF08680077006300740072006C002E00630000000000FFFFFFFFFFFFFFFFFFFEFF162400570053005F0044004900520024005C007300720063005C00630061006E0075007300650072002E006800010000000180FFFEFF00FFFEFFFF21013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E00310033003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0030003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0030003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF09630061006E0075007300650072002E00680000000000FFFFFFFFFFFFFFFFFFFEFF162400570053005F0044004900520024005C007300720063005C006100700070005400610073006B002E006300010000000180FFFEFF00FFFEFFFF21013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E00360030003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0030003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0030003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF096100700070005400610073006B002E00630000000000FFFFFFFFFFFFFFFFFFFEFF162400570053005F0044004900520024005C007300720063005C00630061006E0075007300650072002E006300010000000180FFFEFF00FFFEFFFF28013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E003200350031003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0038003900380031003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0038003900380031003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF09630061006E0075007300650072002E00630000000000FFFFFFFFFFFFFFFF0000000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD5000100000001000000020000000A0100004900000000060000FA010000 + + + + diff --git a/cva_asw_m0118/settings/cva_asw_m0118_Debug.jlink b/cva_asw_m0118/settings/cva_asw_m0118_Debug.jlink new file mode 100644 index 0000000..e830972 --- /dev/null +++ b/cva_asw_m0118/settings/cva_asw_m0118_Debug.jlink @@ -0,0 +1,47 @@ +[BREAKPOINTS] +ForceImpTypeAny = 0 +ShowInfoWin = 1 +EnableFlashBP = 2 +BPDuringExecution = 0 +[CFI] +CFISize = 0x00 +CFIAddr = 0x00 +[CPU] +MonModeVTableAddr = 0xFFFFFFFF +MonModeDebug = 0 +MaxNumAPs = 0 +LowPowerHandlingMode = 0 +OverrideMemMap = 0 +AllowSimulation = 1 +ScriptFile="" +[FLASH] +RMWThreshold = 0x00 +Loaders="" +EraseType = 0x00 +CacheExcludeSize = 0x00 +CacheExcludeAddr = 0x00 +MinNumBytesFlashDL = 0 +SkipProgOnCRCMatch = 1 +VerifyDownload = 1 +AllowCaching = 1 +EnableFlashDL = 2 +Override = 0 +Device="ARM7" +[GENERAL] +WorkRAMSize = 0x6400 +WorkRAMAddr = 0x20000000 +RAMUsageLimit = 0x00 +[SWO] +SWOLogFile="" +[MEM] +RdOverrideOrMask = 0x00 +RdOverrideAndMask = 0xFFFFFFFF +RdOverrideAddr = 0xFFFFFFFF +WrOverrideOrMask = 0x00 +WrOverrideAndMask = 0xFFFFFFFF +WrOverrideAddr = 0xFFFFFFFF +[RAM] +VerifyDownload = 0x00 +[MEM_MAP] +[DYN_MEM_MAP] +NumUserRegion = 0x00 diff --git a/cva_asw_m0118/settings/cva_asw_m0118_EditorBookmarks.xml b/cva_asw_m0118/settings/cva_asw_m0118_EditorBookmarks.xml new file mode 100644 index 0000000..38c3485 --- /dev/null +++ b/cva_asw_m0118/settings/cva_asw_m0118_EditorBookmarks.xml @@ -0,0 +1,2 @@ + + diff --git a/cva_asw_m0118/src/RTT/README.txt b/cva_asw_m0118/src/RTT/README.txt new file mode 100644 index 0000000..6ca82ce --- /dev/null +++ b/cva_asw_m0118/src/RTT/README.txt @@ -0,0 +1,23 @@ +README.txt for the SEGGER RTT Implementation Pack. + +MDK-ARM specifics: +https://wiki.segger.com/Keil_MDK-ARM#RTT_in_uVision + +Included files: +=============== +Root Directory + - Examples + - Main_RTT_InputEchoApp.c - Sample application which echoes input on Channel 0. + - Main_RTT_MenuApp.c - Sample application to demonstrate RTT bi-directional functionality. + - Main_RTT_PrintfTest.c - Sample application to test RTT small printf implementation. + - Main_RTT_SpeedTestApp.c - Sample application for measuring RTT performance. embOS needed. + - RTT + - SEGGER_RTT.c - The RTT implementation. + - SEGGER_RTT.h - Header for RTT implementation. + - SEGGER_RTT_Conf.h - Pre-processor configuration for the RTT implementation. + - SEGGER_RTT_Printf.c - Simple implementation of printf to write formatted strings via RTT. + - Syscalls + - RTT_Syscalls_GCC.c - Low-level syscalls to retarget printf() to RTT with GCC / Newlib. + - RTT_Syscalls_IAR.c - Low-level syscalls to retarget printf() to RTT with IAR compiler. + - RTT_Syscalls_KEIL.c - Low-level syscalls to retarget printf() to RTT with KEIL/uVision compiler. + - RTT_Syscalls_SES.c - Low-level syscalls to retarget printf() to RTT with SEGGER Embedded Studio. diff --git a/cva_asw_m0118/src/RTT/SEGGER_RTT.c b/cva_asw_m0118/src/RTT/SEGGER_RTT.c new file mode 100644 index 0000000..baa496f --- /dev/null +++ b/cva_asw_m0118/src/RTT/SEGGER_RTT.c @@ -0,0 +1,2078 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2021 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* condition is met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this condition and the following disclaimer. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 7.22b * +* * +********************************************************************** + +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT.c +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support + debugger memory accesses while the CPU is running. +Revision: $Rev: 22333 $ + +Additional information: + Type "int" is assumed to be 32-bits in size + H->T Host to target communication + T->H Target to host communication + + RTT channel 0 is always present and reserved for Terminal usage. + Name is fixed to "Terminal" + + Effective buffer size: SizeOfBuffer - 1 + + WrOff == RdOff: Buffer is empty + WrOff == (RdOff - 1): Buffer is full + WrOff > RdOff: Free space includes wrap-around + WrOff < RdOff: Used space includes wrap-around + (WrOff == (SizeOfBuffer - 1)) && (RdOff == 0): + Buffer full and wrap-around after next byte + + +---------------------------------------------------------------------- +*/ + +#include "SEGGER_RTT.h" + +#include // for memcpy + +/********************************************************************* +* +* Configuration, default values +* +********************************************************************** +*/ + +#if SEGGER_RTT_CPU_CACHE_LINE_SIZE + #ifdef SEGGER_RTT_CB_ALIGN + #error "Custom SEGGER_RTT_CB_ALIGN() is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" + #endif + #ifdef SEGGER_RTT_BUFFER_ALIGN + #error "Custom SEGGER_RTT_BUFFER_ALIGN() is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" + #endif + #ifdef SEGGER_RTT_PUT_CB_SECTION + #error "Custom SEGGER_RTT_PUT_CB_SECTION() is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" + #endif + #ifdef SEGGER_RTT_PUT_BUFFER_SECTION + #error "Custom SEGGER_RTT_PUT_BUFFER_SECTION() is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" + #endif + #ifdef SEGGER_RTT_BUFFER_ALIGNMENT + #error "Custom SEGGER_RTT_BUFFER_ALIGNMENT is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" + #endif + #ifdef SEGGER_RTT_ALIGNMENT + #error "Custom SEGGER_RTT_ALIGNMENT is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" + #endif +#endif + +#ifndef BUFFER_SIZE_UP + #define BUFFER_SIZE_UP 1024 // Size of the buffer for terminal output of target, up to host +#endif + +#ifndef BUFFER_SIZE_DOWN + #define BUFFER_SIZE_DOWN 16 // Size of the buffer for terminal input to target from host (Usually keyboard input) +#endif + +#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS + #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 // Number of up-buffers (T->H) available on this target +#endif + +#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS + #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 // Number of down-buffers (H->T) available on this target +#endif + +#ifndef SEGGER_RTT_BUFFER_SECTION + #if defined(SEGGER_RTT_SECTION) + #define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION + #endif +#endif + +#ifndef SEGGER_RTT_ALIGNMENT + #define SEGGER_RTT_ALIGNMENT SEGGER_RTT_CPU_CACHE_LINE_SIZE +#endif + +#ifndef SEGGER_RTT_BUFFER_ALIGNMENT + #define SEGGER_RTT_BUFFER_ALIGNMENT SEGGER_RTT_CPU_CACHE_LINE_SIZE +#endif + +#ifndef SEGGER_RTT_MODE_DEFAULT + #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP +#endif + +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK() +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK() +#endif + +#ifndef STRLEN + #define STRLEN(a) strlen((a)) +#endif + +#ifndef STRCPY + #define STRCPY(pDest, pSrc) strcpy((pDest), (pSrc)) +#endif + +#ifndef SEGGER_RTT_MEMCPY_USE_BYTELOOP + #define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 +#endif + +#ifndef SEGGER_RTT_MEMCPY + #ifdef MEMCPY + #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) MEMCPY((pDest), (pSrc), (NumBytes)) + #else + #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes)) + #endif +#endif + +#ifndef MIN + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX + #define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif +// +// For some environments, NULL may not be defined until certain headers are included +// +#ifndef NULL + #define NULL 0 +#endif + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ +#if (defined __ICCARM__) || (defined __ICCRX__) + #define RTT_PRAGMA(P) _Pragma(#P) +#endif + +#if SEGGER_RTT_ALIGNMENT || SEGGER_RTT_BUFFER_ALIGNMENT + #if (defined __GNUC__) + #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) + #elif (defined __ICCARM__) || (defined __ICCRX__) + #define PRAGMA(A) _Pragma(#A) +#define SEGGER_RTT_ALIGN(Var, Alignment) RTT_PRAGMA(data_alignment=Alignment) \ + Var + #elif (defined __CC_ARM) + #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) + #else + #error "Alignment not supported for this compiler." + #endif +#else + #define SEGGER_RTT_ALIGN(Var, Alignment) Var +#endif + +#if defined(SEGGER_RTT_SECTION) || defined (SEGGER_RTT_BUFFER_SECTION) + #if (defined __GNUC__) + #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section))) Var + #elif (defined __ICCARM__) || (defined __ICCRX__) +#define SEGGER_RTT_PUT_SECTION(Var, Section) RTT_PRAGMA(location=Section) \ + Var + #elif (defined __CC_ARM) + #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section), zero_init)) Var + #else + #error "Section placement not supported for this compiler." + #endif +#else + #define SEGGER_RTT_PUT_SECTION(Var, Section) Var +#endif + +#if SEGGER_RTT_ALIGNMENT + #define SEGGER_RTT_CB_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_ALIGNMENT) +#else + #define SEGGER_RTT_CB_ALIGN(Var) Var +#endif + +#if SEGGER_RTT_BUFFER_ALIGNMENT + #define SEGGER_RTT_BUFFER_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_BUFFER_ALIGNMENT) +#else + #define SEGGER_RTT_BUFFER_ALIGN(Var) Var +#endif + + +#if defined(SEGGER_RTT_SECTION) + #define SEGGER_RTT_PUT_CB_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_SECTION) +#else + #define SEGGER_RTT_PUT_CB_SECTION(Var) Var +#endif + +#if defined(SEGGER_RTT_BUFFER_SECTION) + #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_BUFFER_SECTION) +#else + #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) Var +#endif + +/********************************************************************* +* +* Static const data +* +********************************************************************** +*/ + +static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + +/********************************************************************* +* +* Static data +* +********************************************************************** +*/ + +// +// RTT Control Block and allocate buffers for channel 0 +// +SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT)); +SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acUpBuffer [SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_UP)])); +SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acDownBuffer[SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_DOWN)])); + +static unsigned char _ActiveTerminal; + +/********************************************************************* +* +* Static functions +* +********************************************************************** +*/ + +/********************************************************************* +* +* _DoInit() +* +* Function description +* Initializes the control block an buffers. +* May only be called via INIT() to avoid overriding settings. +* +*/ +#define INIT() { \ + volatile SEGGER_RTT_CB* pRTTCBInit; \ + pRTTCBInit = (volatile SEGGER_RTT_CB*)((char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); \ + do { \ + if (pRTTCBInit->acID[0] == '\0') { \ + _DoInit(); \ + } \ + } while (0); \ + } + +static void _DoInit(void) { + volatile SEGGER_RTT_CB* p; // Volatile to make sure that compiler cannot change the order of accesses to the control block + // + // Initialize control block + // + p = (volatile SEGGER_RTT_CB*)((char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access control block uncached so that nothing in the cache ever becomes dirty and all changes are visible in HW directly + p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS; + p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS; + // + // Initialize up buffer 0 + // + p->aUp[0].sName = "Terminal"; + p->aUp[0].pBuffer = _acUpBuffer; + p->aUp[0].SizeOfBuffer = BUFFER_SIZE_UP; + p->aUp[0].RdOff = 0u; + p->aUp[0].WrOff = 0u; + p->aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT; + // + // Initialize down buffer 0 + // + p->aDown[0].sName = "Terminal"; + p->aDown[0].pBuffer = _acDownBuffer; + p->aDown[0].SizeOfBuffer = BUFFER_SIZE_DOWN; + p->aDown[0].RdOff = 0u; + p->aDown[0].WrOff = 0u; + p->aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT; + // + // Finish initialization of the control block. + // Copy Id string in three steps to make sure "SEGGER RTT" is not found + // in initializer memory (usually flash) by J-Link + // + STRCPY((char*)&p->acID[7], "RTT"); + RTT__DMB(); // Force order of memory accessed inside core for cores that allow to change the order + STRCPY((char*)&p->acID[0], "SEGGER"); + RTT__DMB(); // Force order of memory accessed inside core for cores that allow to change the order + p->acID[6] = ' '; + RTT__DMB(); // Force order of memory accessed inside core for cores that allow to change the order +} + +/********************************************************************* +* +* _WriteBlocking() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* The caller is responsible for managing the write chunk sizes as +* _WriteBlocking() will block until all data has been posted successfully. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* >= 0 - Number of bytes written into buffer. +*/ +static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer, unsigned NumBytes) { + unsigned NumBytesToWrite; + unsigned NumBytesWritten; + unsigned RdOff; + unsigned WrOff; + volatile char* pDst; + // + // Write data to buffer and handle wrap-around if necessary + // + NumBytesWritten = 0u; + WrOff = pRing->WrOff; + do { + RdOff = pRing->RdOff; // May be changed by host (debug probe) in the meantime + if (RdOff > WrOff) { + NumBytesToWrite = RdOff - WrOff - 1u; + } else { + NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u); + } + NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around + NumBytesToWrite = MIN(NumBytesToWrite, NumBytes); + pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + NumBytesWritten += NumBytesToWrite; + NumBytes -= NumBytesToWrite; + WrOff += NumBytesToWrite; + while (NumBytesToWrite--) { + *pDst++ = *pBuffer++; + }; +#else + SEGGER_RTT_MEMCPY((void*)pDst, pBuffer, NumBytesToWrite); + NumBytesWritten += NumBytesToWrite; + pBuffer += NumBytesToWrite; + NumBytes -= NumBytesToWrite; + WrOff += NumBytesToWrite; +#endif + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0u; + } + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = WrOff; + } while (NumBytes); + return NumBytesWritten; +} + +/********************************************************************* +* +* _WriteNoCheck() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* It is callers responsibility to make sure data actually fits in buffer. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Notes +* (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking +*/ +static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsigned NumBytes) { + unsigned NumBytesAtOnce; + unsigned WrOff; + unsigned Rem; + volatile char* pDst; + + WrOff = pRing->WrOff; + Rem = pRing->SizeOfBuffer - WrOff; + if (Rem > NumBytes) { + // + // All data fits before wrap around + // + pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + WrOff += NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = WrOff; +#else + SEGGER_RTT_MEMCPY((void*)pDst, pData, NumBytes); + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = WrOff + NumBytes; +#endif + } else { + // + // We reach the end of the buffer, so need to wrap around + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF; + NumBytesAtOnce = Rem; + while (NumBytesAtOnce--) { + *pDst++ = *pData++; + }; + pDst = pRing->pBuffer + SEGGER_RTT_UNCACHED_OFF; + NumBytesAtOnce = NumBytes - Rem; + while (NumBytesAtOnce--) { + *pDst++ = *pData++; + }; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = NumBytes - Rem; +#else + NumBytesAtOnce = Rem; + pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF; + SEGGER_RTT_MEMCPY((void*)pDst, pData, NumBytesAtOnce); + NumBytesAtOnce = NumBytes - Rem; + pDst = pRing->pBuffer + SEGGER_RTT_UNCACHED_OFF; + SEGGER_RTT_MEMCPY((void*)pDst, pData + Rem, NumBytesAtOnce); + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = NumBytesAtOnce; +#endif + } +} + +/********************************************************************* +* +* _PostTerminalSwitch() +* +* Function description +* Switch terminal to the given terminal ID. It is the caller's +* responsibility to ensure the terminal ID is correct and there is +* enough space in the buffer for this to complete successfully. +* +* Parameters +* pRing Ring buffer to post to. +* TerminalId Terminal ID to switch to. +*/ +static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) { + unsigned char ac[2]; + + ac[0] = 0xFFu; + ac[1] = _aTerminalId[TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit + _WriteBlocking(pRing, (const char*)ac, 2u); +} + +/********************************************************************* +* +* _GetAvailWriteSpace() +* +* Function description +* Returns the number of bytes that can be written to the ring +* buffer without blocking. +* +* Parameters +* pRing Ring buffer to check. +* +* Return value +* Number of bytes that are free in the buffer. +*/ +static unsigned _GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP* pRing) { + unsigned RdOff; + unsigned WrOff; + unsigned r; + // + // Avoid warnings regarding volatile access order. It's not a problem + // in this case, but dampen compiler enthusiasm. + // + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + if (RdOff <= WrOff) { + r = pRing->SizeOfBuffer - 1u - WrOff + RdOff; + } else { + r = RdOff - WrOff - 1u; + } + return r; +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ + +/********************************************************************* +* +* SEGGER_RTT_ReadUpBufferNoLock() +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the application. +* Do not lock against interrupts and multiple access. +* Used to do the same operation that J-Link does, to transfer +* RTT data via other channels, such as TCP/IP or UART. +* +* Parameters +* BufferIndex Index of Up-buffer to be used. +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-up-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +* +* Additional information +* This function must not be called when J-Link might also do RTT. +*/ +unsigned SEGGER_RTT_ReadUpBufferNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) { + unsigned NumBytesRem; + unsigned NumBytesRead; + unsigned RdOff; + unsigned WrOff; + unsigned char* pBuffer; + SEGGER_RTT_BUFFER_UP* pRing; + volatile char* pSrc; + + INIT(); + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + pBuffer = (unsigned char*)pData; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + NumBytesRead = 0u; + // + // Read from current read position to wrap-around of buffer, first + // + if (RdOff > WrOff) { + NumBytesRem = pRing->SizeOfBuffer - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + pSrc = (pRing->pBuffer + RdOff) + SEGGER_RTT_UNCACHED_OFF; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + NumBytesRead += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + while (NumBytesRem--) { + *pBuffer++ = *pSrc++; + }; +#else + SEGGER_RTT_MEMCPY(pBuffer, (void*)pSrc, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; +#endif + // + // Handle wrap-around of buffer + // + if (RdOff == pRing->SizeOfBuffer) { + RdOff = 0u; + } + } + // + // Read remaining items of buffer + // + NumBytesRem = WrOff - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + if (NumBytesRem > 0u) { + pSrc = (pRing->pBuffer + RdOff) + SEGGER_RTT_UNCACHED_OFF; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + NumBytesRead += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + while (NumBytesRem--) { + *pBuffer++ = *pSrc++; + }; +#else + SEGGER_RTT_MEMCPY(pBuffer, (void*)pSrc, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; +#endif + } + // + // Update read offset of buffer + // + if (NumBytesRead) { + pRing->RdOff = RdOff; + } + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_ReadNoLock() +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* Do not lock against interrupts and multiple access. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) { + unsigned NumBytesRem; + unsigned NumBytesRead; + unsigned RdOff; + unsigned WrOff; + unsigned char* pBuffer; + SEGGER_RTT_BUFFER_DOWN* pRing; + volatile char* pSrc; + // + INIT(); + pRing = (SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + pBuffer = (unsigned char*)pData; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + NumBytesRead = 0u; + // + // Read from current read position to wrap-around of buffer, first + // + if (RdOff > WrOff) { + NumBytesRem = pRing->SizeOfBuffer - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + pSrc = (pRing->pBuffer + RdOff) + SEGGER_RTT_UNCACHED_OFF; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + NumBytesRead += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + while (NumBytesRem--) { + *pBuffer++ = *pSrc++; + }; +#else + SEGGER_RTT_MEMCPY(pBuffer, (void*)pSrc, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; +#endif + // + // Handle wrap-around of buffer + // + if (RdOff == pRing->SizeOfBuffer) { + RdOff = 0u; + } + } + // + // Read remaining items of buffer + // + NumBytesRem = WrOff - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + if (NumBytesRem > 0u) { + pSrc = (pRing->pBuffer + RdOff) + SEGGER_RTT_UNCACHED_OFF; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + NumBytesRead += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + while (NumBytesRem--) { + *pBuffer++ = *pSrc++; + }; +#else + SEGGER_RTT_MEMCPY(pBuffer, (void*)pSrc, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; +#endif + } + if (NumBytesRead) { + pRing->RdOff = RdOff; + } + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_ReadUpBuffer +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the application. +* Used to do the same operation that J-Link does, to transfer +* RTT data via other channels, such as TCP/IP or UART. +* +* Parameters +* BufferIndex Index of Up-buffer to be used. +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-up-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +* +* Additional information +* This function must not be called when J-Link might also do RTT. +* This function locks against all other RTT operations. I.e. during +* the read operation, writing is also locked. +* If only one consumer reads from the up buffer, +* call sEGGER_RTT_ReadUpBufferNoLock() instead. +*/ +unsigned SEGGER_RTT_ReadUpBuffer(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) { + unsigned NumBytesRead; + + SEGGER_RTT_LOCK(); + // + // Call the non-locking read function + // + NumBytesRead = SEGGER_RTT_ReadUpBufferNoLock(BufferIndex, pBuffer, BufferSize); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_Read +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) { + unsigned NumBytesRead; + + SEGGER_RTT_LOCK(); + // + // Call the non-locking read function + // + NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteWithOverwriteNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block. +* SEGGER_RTT_WriteWithOverwriteNoLock does not lock the application +* and overwrites data if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, data is overwritten. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +* (3) Do not use SEGGER_RTT_WriteWithOverwriteNoLock if a J-Link +* connection reads RTT data. +*/ +void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + volatile char* pDst; + // + // Get "to-host" ring buffer and copy some elements into local variables. + // + pData = (const char *)pBuffer; + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + // + // Check if we will overwrite data and need to adjust the RdOff. + // + if (pRing->WrOff == pRing->RdOff) { + Avail = pRing->SizeOfBuffer - 1u; + } else if ( pRing->WrOff < pRing->RdOff) { + Avail = pRing->RdOff - pRing->WrOff - 1u; + } else { + Avail = pRing->RdOff - pRing->WrOff - 1u + pRing->SizeOfBuffer; + } + if (NumBytes > Avail) { + pRing->RdOff += (NumBytes - Avail); + while (pRing->RdOff >= pRing->SizeOfBuffer) { + pRing->RdOff -= pRing->SizeOfBuffer; + } + } + // + // Write all data, no need to check the RdOff, but possibly handle multiple wrap-arounds + // + Avail = pRing->SizeOfBuffer - pRing->WrOff; + do { + if (Avail > NumBytes) { + // + // Last round + // + pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + Avail = NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff += Avail; +#else + SEGGER_RTT_MEMCPY((void*)pDst, pData, NumBytes); + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff += NumBytes; +#endif + break; + } else { + // + // Wrap-around necessary, write until wrap-around and reset WrOff + // + pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + NumBytes -= Avail; + while (Avail--) { + *pDst++ = *pData++; + }; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = 0; +#else + SEGGER_RTT_MEMCPY((void*)pDst, pData, Avail); + pData += Avail; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = 0; + NumBytes -= Avail; +#endif + Avail = (pRing->SizeOfBuffer - 1); + } + } while (NumBytes); +} + +/********************************************************************* +* +* SEGGER_RTT_WriteSkipNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteSkipNoLock does not lock the application and +* skips all data, if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* MUST be > 0!!! +* This is done for performance reasons, so no initial check has do be done. +* +* Return value +* 1: Data has been copied +* 0: No space, data has not been copied +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, all data is dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +#if (RTT_USE_ASM == 0) +unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + unsigned RdOff; + unsigned WrOff; + unsigned Rem; + volatile char* pDst; + // + // Cases: + // 1) RdOff <= WrOff => Space until wrap-around is sufficient + // 2) RdOff <= WrOff => Space after wrap-around needed (copy in 2 chunks) + // 3) RdOff < WrOff => No space in buf + // 4) RdOff > WrOff => Space is sufficient + // 5) RdOff > WrOff => No space in buf + // + // 1) is the most common case for large buffers and assuming that J-Link reads the data fast enough + // + pData = (const char *)pBuffer; + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + if (RdOff <= WrOff) { // Case 1), 2) or 3) + Avail = pRing->SizeOfBuffer - WrOff - 1u; // Space until wrap-around (assume 1 byte not usable for case that RdOff == 0) + if (Avail >= NumBytes) { // Case 1)? +CopyStraight: + pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF; + memcpy((void*)pDst, pData, NumBytes); + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = WrOff + NumBytes; + return 1; + } + Avail += RdOff; // Space incl. wrap-around + if (Avail >= NumBytes) { // Case 2? => If not, we have case 3) (does not fit) + Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer + pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF; + memcpy((void*)pDst, pData, Rem); // Copy 1st chunk + NumBytes -= Rem; + // + // Special case: First check that assumed RdOff == 0 calculated that last element before wrap-around could not be used + // But 2nd check (considering space until wrap-around and until RdOff) revealed that RdOff is not 0, so we can use the last element + // In this case, we may use a copy straight until buffer end anyway without needing to copy 2 chunks + // Therefore, check if 2nd memcpy is necessary at all + // + if (NumBytes) { + pDst = pRing->pBuffer + SEGGER_RTT_UNCACHED_OFF; + memcpy((void*)pDst, pData + Rem, NumBytes); + } + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = NumBytes; + return 1; + } + } else { // Potential case 4) + Avail = RdOff - WrOff - 1u; + if (Avail >= NumBytes) { // Case 4)? => If not, we have case 5) (does not fit) + goto CopyStraight; + } + } + return 0; // No space in buffer +} +#endif + +/********************************************************************* +* +* SEGGER_RTT_WriteDownBufferNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block inside a buffer. +* SEGGER_RTT_WriteDownBufferNoLock does not lock the application. +* Used to do the same operation that J-Link does, to transfer +* RTT data from other channels, such as TCP/IP or UART. +* +* Parameters +* BufferIndex Index of "Down"-buffer to be used. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Down"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +* +* Additional information +* This function must not be called when J-Link might also do RTT. +*/ +unsigned SEGGER_RTT_WriteDownBufferNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + unsigned Avail; + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + // + // Get "to-target" ring buffer. + // It is save to cast that to a "to-host" buffer. Up and Down buffer differ in volatility of offsets that might be modified by J-Link. + // + pData = (const char *)pBuffer; + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aDown[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + // + // How we output depends upon the mode... + // + switch (pRing->Flags) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother. + // + Avail = _GetAvailWriteSpace(pRing); + if (Avail < NumBytes) { + Status = 0u; + } else { + Status = NumBytes; + _WriteNoCheck(pRing, pData, NumBytes); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode, trim to what we can output without blocking. + // + Avail = _GetAvailWriteSpace(pRing); + Status = Avail < NumBytes ? Avail : NumBytes; + _WriteNoCheck(pRing, pData, Status); + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + Status = _WriteBlocking(pRing, pData, NumBytes); + break; + default: + Status = 0u; + break; + } + // + // Finish up. + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteNoLock does not lock the application. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + unsigned Avail; + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + // + // Get "to-host" ring buffer. + // + pData = (const char *)pBuffer; + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + // + // How we output depends upon the mode... + // + switch (pRing->Flags) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother. + // + Avail = _GetAvailWriteSpace(pRing); + if (Avail < NumBytes) { + Status = 0u; + } else { + Status = NumBytes; + _WriteNoCheck(pRing, pData, NumBytes); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode, trim to what we can output without blocking. + // + Avail = _GetAvailWriteSpace(pRing); + Status = Avail < NumBytes ? Avail : NumBytes; + _WriteNoCheck(pRing, pData, Status); + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + Status = _WriteBlocking(pRing, pData, NumBytes); + break; + default: + Status = 0u; + break; + } + // + // Finish up. + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteDownBuffer +* +* Function description +* Stores a specified number of characters in SEGGER RTT control block in a buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Down"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +* +* Additional information +* This function must not be called when J-Link might also do RTT. +* This function locks against all other RTT operations. I.e. during +* the write operation, writing from the application is also locked. +* If only one consumer writes to the down buffer, +* call SEGGER_RTT_WriteDownBufferNoLock() instead. +*/ +unsigned SEGGER_RTT_WriteDownBuffer(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + + INIT(); + SEGGER_RTT_LOCK(); + Status = SEGGER_RTT_WriteDownBufferNoLock(BufferIndex, pBuffer, NumBytes); // Call the non-locking write function + SEGGER_RTT_UNLOCK(); + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_Write +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +*/ +unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + + INIT(); + SEGGER_RTT_LOCK(); + Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes); // Call the non-locking write function + SEGGER_RTT_UNLOCK(); + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteString +* +* Function description +* Stores string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* s Pointer to string. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +* (2) String passed to this function has to be \0 terminated +* (3) \0 termination character is *not* stored in RTT buffer +*/ +unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) { + unsigned Len; + + Len = STRLEN(s); + return SEGGER_RTT_Write(BufferIndex, s, Len); +} + +/********************************************************************* +* +* SEGGER_RTT_PutCharSkipNoLock +* +* Function description +* Stores a single character/byte in SEGGER RTT buffer. +* SEGGER_RTT_PutCharSkipNoLock does not lock the application and +* skips the byte, if it does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* c Byte to be stored. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, the character is dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ + +unsigned SEGGER_RTT_PutCharSkipNoLock(unsigned BufferIndex, char c) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned WrOff; + unsigned Status; + volatile char* pDst; + // + // Get "to-host" ring buffer. + // + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + // + // Get write position and handle wrap-around if necessary + // + WrOff = pRing->WrOff + 1; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0; + } + // + // Output byte if free space is available + // + if (WrOff != pRing->RdOff) { + pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF; + *pDst = c; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = WrOff; + Status = 1; + } else { + Status = 0; + } + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_PutCharSkip +* +* Function description +* Stores a single character/byte in SEGGER RTT buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* c Byte to be stored. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, the character is dropped. +*/ + +unsigned SEGGER_RTT_PutCharSkip(unsigned BufferIndex, char c) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned WrOff; + unsigned Status; + volatile char* pDst; + // + // Prepare + // + INIT(); + SEGGER_RTT_LOCK(); + // + // Get "to-host" ring buffer. + // + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + // + // Get write position and handle wrap-around if necessary + // + WrOff = pRing->WrOff + 1; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0; + } + // + // Output byte if free space is available + // + if (WrOff != pRing->RdOff) { + pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF; + *pDst = c; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = WrOff; + Status = 1; + } else { + Status = 0; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return Status; +} + + /********************************************************************* +* +* SEGGER_RTT_PutChar +* +* Function description +* Stores a single character/byte in SEGGER RTT buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* c Byte to be stored. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +*/ + +unsigned SEGGER_RTT_PutChar(unsigned BufferIndex, char c) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned WrOff; + unsigned Status; + volatile char* pDst; + // + // Prepare + // + INIT(); + SEGGER_RTT_LOCK(); + // + // Get "to-host" ring buffer. + // + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + // + // Get write position and handle wrap-around if necessary + // + WrOff = pRing->WrOff + 1; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0; + } + // + // Wait for free space if mode is set to blocking + // + if (pRing->Flags == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { + while (WrOff == pRing->RdOff) { + ; + } + } + // + // Output byte if free space is available + // + if (WrOff != pRing->RdOff) { + pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF; + *pDst = c; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = WrOff; + Status = 1; + } else { + Status = 0; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_GetKey +* +* Function description +* Reads one character from the SEGGER RTT buffer. +* Host has previously stored data there. +* +* Return value +* < 0 - No character available (buffer empty). +* >= 0 - Character which has been read. (Possible values: 0 - 255) +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0. +*/ +int SEGGER_RTT_GetKey(void) { + char c; + int r; + + r = (int)SEGGER_RTT_Read(0u, &c, 1u); + if (r == 1) { + r = (int)(unsigned char)c; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_WaitKey +* +* Function description +* Waits until at least one character is avaible in the SEGGER RTT buffer. +* Once a character is available, it is read and this function returns. +* +* Return value +* >=0 - Character which has been read. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +* (2) This function is blocking if no character is present in RTT buffer +*/ +int SEGGER_RTT_WaitKey(void) { + int r; + + do { + r = SEGGER_RTT_GetKey(); + } while (r < 0); + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasKey +* +* Function description +* Checks if at least one character for reading is available in the SEGGER RTT buffer. +* +* Return value +* == 0 - No characters are available to read. +* == 1 - At least one character is available. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +*/ +int SEGGER_RTT_HasKey(void) { + SEGGER_RTT_BUFFER_DOWN* pRing; + unsigned RdOff; + int r; + + INIT(); + pRing = (SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[0] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + RdOff = pRing->RdOff; + if (RdOff != pRing->WrOff) { + r = 1; + } else { + r = 0; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasData +* +* Function description +* Check if there is data from the host in the given buffer. +* +* Return value: +* ==0: No data +* !=0: Data in buffer +* +*/ +unsigned SEGGER_RTT_HasData(unsigned BufferIndex) { + SEGGER_RTT_BUFFER_DOWN* pRing; + unsigned v; + + pRing = (SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + v = pRing->WrOff; + return v - pRing->RdOff; +} + +/********************************************************************* +* +* SEGGER_RTT_HasDataUp +* +* Function description +* Check if there is data remaining to be sent in the given buffer. +* +* Return value: +* ==0: No data +* !=0: Data in buffer +* +*/ +unsigned SEGGER_RTT_HasDataUp(unsigned BufferIndex) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned v; + + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + v = pRing->RdOff; + return pRing->WrOff - v; +} + +/********************************************************************* +* +* SEGGER_RTT_AllocDownBuffer +* +* Function description +* Run-time configuration of the next down-buffer (H->T). +* The next buffer, which is not used yet is configured. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. Buffer Index +* < 0 - Error +*/ +int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int BufferIndex; + volatile SEGGER_RTT_CB* pRTTCB; + + INIT(); + SEGGER_RTT_LOCK(); + pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + BufferIndex = 0; + do { + if (pRTTCB->aDown[BufferIndex].pBuffer == NULL) { + break; + } + BufferIndex++; + } while (BufferIndex < pRTTCB->MaxNumDownBuffers); + if (BufferIndex < pRTTCB->MaxNumDownBuffers) { + pRTTCB->aDown[BufferIndex].sName = sName; + pRTTCB->aDown[BufferIndex].pBuffer = (char*)pBuffer; + pRTTCB->aDown[BufferIndex].SizeOfBuffer = BufferSize; + pRTTCB->aDown[BufferIndex].RdOff = 0u; + pRTTCB->aDown[BufferIndex].WrOff = 0u; + pRTTCB->aDown[BufferIndex].Flags = Flags; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + } else { + BufferIndex = -1; + } + SEGGER_RTT_UNLOCK(); + return BufferIndex; +} + +/********************************************************************* +* +* SEGGER_RTT_AllocUpBuffer +* +* Function description +* Run-time configuration of the next up-buffer (T->H). +* The next buffer, which is not used yet is configured. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. Buffer Index +* < 0 - Error +*/ +int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int BufferIndex; + volatile SEGGER_RTT_CB* pRTTCB; + + INIT(); + SEGGER_RTT_LOCK(); + pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + BufferIndex = 0; + do { + if (pRTTCB->aUp[BufferIndex].pBuffer == NULL) { + break; + } + BufferIndex++; + } while (BufferIndex < pRTTCB->MaxNumUpBuffers); + if (BufferIndex < pRTTCB->MaxNumUpBuffers) { + pRTTCB->aUp[BufferIndex].sName = sName; + pRTTCB->aUp[BufferIndex].pBuffer = (char*)pBuffer; + pRTTCB->aUp[BufferIndex].SizeOfBuffer = BufferSize; + pRTTCB->aUp[BufferIndex].RdOff = 0u; + pRTTCB->aUp[BufferIndex].WrOff = 0u; + pRTTCB->aUp[BufferIndex].Flags = Flags; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + } else { + BufferIndex = -1; + } + SEGGER_RTT_UNLOCK(); + return BufferIndex; +} + +/********************************************************************* +* +* SEGGER_RTT_ConfigUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer (T->H). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. +* < 0 - Error +* +* Additional information +* Buffer 0 is configured on compile-time. +* May only be called once per buffer. +* Buffer name and flags can be reconfigured using the appropriate functions. +*/ +int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + volatile SEGGER_RTT_CB* pRTTCB; + volatile SEGGER_RTT_BUFFER_UP* pUp; + + INIT(); + pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + if (BufferIndex < SEGGER_RTT_MAX_NUM_UP_BUFFERS) { + SEGGER_RTT_LOCK(); + pUp = &pRTTCB->aUp[BufferIndex]; + if (BufferIndex) { + pUp->sName = sName; + pUp->pBuffer = (char*)pBuffer; + pUp->SizeOfBuffer = BufferSize; + pUp->RdOff = 0u; + pUp->WrOff = 0u; + } + pUp->Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_ConfigDownBuffer +* +* Function description +* Run-time configuration of a specific down-buffer (H->T). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 O.K. +* < 0 Error +* +* Additional information +* Buffer 0 is configured on compile-time. +* May only be called once per buffer. +* Buffer name and flags can be reconfigured using the appropriate functions. +*/ +int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + volatile SEGGER_RTT_CB* pRTTCB; + volatile SEGGER_RTT_BUFFER_DOWN* pDown; + + INIT(); + pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + if (BufferIndex < SEGGER_RTT_MAX_NUM_DOWN_BUFFERS) { + SEGGER_RTT_LOCK(); + pDown = &pRTTCB->aDown[BufferIndex]; + if (BufferIndex) { + pDown->sName = sName; + pDown->pBuffer = (char*)pBuffer; + pDown->SizeOfBuffer = BufferSize; + pDown->RdOff = 0u; + pDown->WrOff = 0u; + } + pDown->Flags = Flags; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) { + int r; + volatile SEGGER_RTT_CB* pRTTCB; + volatile SEGGER_RTT_BUFFER_UP* pUp; + + INIT(); + pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + if (BufferIndex < SEGGER_RTT_MAX_NUM_UP_BUFFERS) { + SEGGER_RTT_LOCK(); + pUp = &pRTTCB->aUp[BufferIndex]; + pUp->sName = sName; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameDownBuffer +* +* Function description +* Run-time configuration of a specific Down-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) { + int r; + volatile SEGGER_RTT_CB* pRTTCB; + volatile SEGGER_RTT_BUFFER_DOWN* pDown; + + INIT(); + pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + if (BufferIndex < SEGGER_RTT_MAX_NUM_DOWN_BUFFERS) { + SEGGER_RTT_LOCK(); + pDown = &pRTTCB->aDown[BufferIndex]; + pDown->sName = sName; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetFlagsUpBuffer +* +* Function description +* Run-time configuration of specific up-buffer flags (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer. +* Flags Flags to set for the buffer. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags) { + int r; + volatile SEGGER_RTT_CB* pRTTCB; + volatile SEGGER_RTT_BUFFER_UP* pUp; + + INIT(); + pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + if (BufferIndex < SEGGER_RTT_MAX_NUM_UP_BUFFERS) { + SEGGER_RTT_LOCK(); + pUp = &pRTTCB->aUp[BufferIndex]; + pUp->Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetFlagsDownBuffer +* +* Function description +* Run-time configuration of specific Down-buffer flags (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* Flags Flags to set for the buffer. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags) { + int r; + volatile SEGGER_RTT_CB* pRTTCB; + volatile SEGGER_RTT_BUFFER_DOWN* pDown; + + INIT(); + pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + if (BufferIndex < SEGGER_RTT_MAX_NUM_DOWN_BUFFERS) { + SEGGER_RTT_LOCK(); + pDown = &pRTTCB->aDown[BufferIndex]; + pDown->Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_Init +* +* Function description +* Initializes the RTT Control Block. +* Should be used in RAM targets, at start of the application. +* +*/ +void SEGGER_RTT_Init (void) { + _DoInit(); +} + +/********************************************************************* +* +* SEGGER_RTT_SetTerminal +* +* Function description +* Sets the terminal to be used for output on channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* +* Return value +* >= 0 O.K. +* < 0 Error (e.g. if RTT is configured for non-blocking mode and there was no space in the buffer to set the new terminal Id) +* +* Notes +* (1) Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed +*/ +int SEGGER_RTT_SetTerminal (unsigned char TerminalId) { + unsigned char ac[2]; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + int r; + + INIT(); + r = 0; + ac[0] = 0xFFu; + if (TerminalId < sizeof(_aTerminalId)) { // We only support a certain number of channels + ac[1] = _aTerminalId[TerminalId]; + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[0] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + SEGGER_RTT_LOCK(); // Lock to make sure that no other task is writing into buffer, while we are and number of free bytes in buffer does not change downwards after checking and before writing + if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { + _ActiveTerminal = TerminalId; + _WriteBlocking(pRing, (const char*)ac, 2u); + } else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes + Avail = _GetAvailWriteSpace(pRing); + if (Avail >= 2) { + _ActiveTerminal = TerminalId; // Only change active terminal in case of success + _WriteNoCheck(pRing, (const char*)ac, 2u); + } else { + r = -1; + } + } + SEGGER_RTT_UNLOCK(); + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_TerminalOut +* +* Function description +* Writes a string to the given terminal +* without changing the terminal for channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* s String to be printed on the terminal. +* +* Return value +* >= 0 - Number of bytes written. +* < 0 - Error. +* +*/ +int SEGGER_RTT_TerminalOut (unsigned char TerminalId, const char* s) { + int Status; + unsigned FragLen; + unsigned Avail; + SEGGER_RTT_BUFFER_UP* pRing; + // + INIT(); + // + // Validate terminal ID. + // + if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels + // + // Get "to-host" ring buffer. + // + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[0] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + // + // Need to be able to change terminal, write data, change back. + // Compute the fixed and variable sizes. + // + FragLen = STRLEN(s); + // + // How we output depends upon the mode... + // + SEGGER_RTT_LOCK(); + Avail = _GetAvailWriteSpace(pRing); + switch (pRing->Flags & SEGGER_RTT_MODE_MASK) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother switching terminals at all. + // + if (Avail < (FragLen + 4u)) { + Status = 0; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode and there is not enough space for everything, + // trim the output but always include the terminal switch. If no room + // for terminal switch, skip that totally. + // + if (Avail < 4u) { + Status = -1; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u)); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + break; + default: + Status = -1; + break; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + } else { + Status = -1; + } + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_GetAvailWriteSpace +* +* Function description +* Returns the number of bytes available in the ring buffer. +* +* Parameters +* BufferIndex Index of the up buffer. +* +* Return value +* Number of bytes that are free in the selected up buffer. +*/ +unsigned SEGGER_RTT_GetAvailWriteSpace (unsigned BufferIndex) { + SEGGER_RTT_BUFFER_UP* pRing; + + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + return _GetAvailWriteSpace(pRing); +} + + +/********************************************************************* +* +* SEGGER_RTT_GetBytesInBuffer() +* +* Function description +* Returns the number of bytes currently used in the up buffer. +* +* Parameters +* BufferIndex Index of the up buffer. +* +* Return value +* Number of bytes that are used in the buffer. +*/ +unsigned SEGGER_RTT_GetBytesInBuffer(unsigned BufferIndex) { + unsigned RdOff; + unsigned WrOff; + unsigned r; + volatile SEGGER_RTT_CB* pRTTCB; + // + // Avoid warnings regarding volatile access order. It's not a problem + // in this case, but dampen compiler enthusiasm. + // + pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + RdOff = pRTTCB->aUp[BufferIndex].RdOff; + WrOff = pRTTCB->aUp[BufferIndex].WrOff; + if (RdOff <= WrOff) { + r = WrOff - RdOff; + } else { + r = pRTTCB->aUp[BufferIndex].SizeOfBuffer - (WrOff - RdOff); + } + return r; +} + +/*************************** End of file ****************************/ diff --git a/cva_asw_m0118/src/RTT/SEGGER_RTT.h b/cva_asw_m0118/src/RTT/SEGGER_RTT.h new file mode 100644 index 0000000..f0eaa42 --- /dev/null +++ b/cva_asw_m0118/src/RTT/SEGGER_RTT.h @@ -0,0 +1,419 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2021 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* condition is met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this condition and the following disclaimer. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 7.22b * +* * +********************************************************************** + +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT.h +Purpose : Implementation of SEGGER real-time transfer which allows + real-time communication on targets which support debugger + memory accesses while the CPU is running. +Revision: $Rev: 20869 $ +---------------------------------------------------------------------- +*/ + +#ifndef SEGGER_RTT_H +#define SEGGER_RTT_H + +#include "SEGGER_RTT_Conf.h" + +/********************************************************************* +* +* Defines, defaults +* +********************************************************************** +*/ +#ifndef RTT_USE_ASM + #if (defined __SES_ARM) // SEGGER Embedded Studio + #define _CC_HAS_RTT_ASM_SUPPORT 1 + #elif (defined __CROSSWORKS_ARM) // Rowley Crossworks + #define _CC_HAS_RTT_ASM_SUPPORT 1 + #elif (defined __ARMCC_VERSION) // ARM compiler + #if (__ARMCC_VERSION >= 6000000) // ARM compiler V6.0 and later is clang based + #define _CC_HAS_RTT_ASM_SUPPORT 1 + #else + #define _CC_HAS_RTT_ASM_SUPPORT 0 + #endif + #elif (defined __GNUC__) // GCC + #define _CC_HAS_RTT_ASM_SUPPORT 1 + #elif (defined __clang__) // Clang compiler + #define _CC_HAS_RTT_ASM_SUPPORT 1 + #elif ((defined __IASMARM__) || (defined __ICCARM__)) // IAR assembler/compiler + #define _CC_HAS_RTT_ASM_SUPPORT 1 + #else + #define _CC_HAS_RTT_ASM_SUPPORT 0 + #endif + #if ((defined __IASMARM__) || (defined __ICCARM__)) // IAR assembler/compiler + // + // IAR assembler / compiler + // + #if (__VER__ < 6300000) + #define VOLATILE + #else + #define VOLATILE volatile + #endif + #if (defined __ARM7M__) // Needed for old versions that do not know the define yet + #if (__CORE__ == __ARM7M__) // Cortex-M3 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #endif + #endif + #if (defined __ARM7EM__) // Needed for old versions that do not know the define yet + #if (__CORE__ == __ARM7EM__) // Cortex-M4/M7 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() asm VOLATILE ("DMB"); + #endif + #endif + #if (defined __ARM8M_BASELINE__) // Needed for old versions that do not know the define yet + #if (__CORE__ == __ARM8M_BASELINE__) // Cortex-M23 + #define _CORE_HAS_RTT_ASM_SUPPORT 0 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() asm VOLATILE ("DMB"); + #endif + #endif + #if (defined __ARM8M_MAINLINE__) // Needed for old versions that do not know the define yet + #if (__CORE__ == __ARM8M_MAINLINE__) // Cortex-M33 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() asm VOLATILE ("DMB"); + #endif + #endif + #else + // + // GCC / Clang + // + #if (defined __ARM_ARCH_7M__) // Cortex-M3 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #elif (defined __ARM_ARCH_7EM__) // Cortex-M4/M7 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() __asm volatile ("dmb\n" : : :); + #elif (defined __ARM_ARCH_8M_BASE__) // Cortex-M23 + #define _CORE_HAS_RTT_ASM_SUPPORT 0 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() __asm volatile ("dmb\n" : : :); + #elif (defined __ARM_ARCH_8M_MAIN__) // Cortex-M33 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() __asm volatile ("dmb\n" : : :); + #else + #define _CORE_HAS_RTT_ASM_SUPPORT 0 + #endif + #endif + // + // If IDE and core support the ASM version, enable ASM version by default + // + #ifndef _CORE_HAS_RTT_ASM_SUPPORT + #define _CORE_HAS_RTT_ASM_SUPPORT 0 // Default for unknown cores + #endif + #if (_CC_HAS_RTT_ASM_SUPPORT && _CORE_HAS_RTT_ASM_SUPPORT) + #define RTT_USE_ASM (1) + #else + #define RTT_USE_ASM (0) + #endif +#endif + +// +// We need to know if a DMB is needed to make sure that on Cortex-M7 etc. +// the order of accesses to the ring buffers is guaranteed +// Needed for: Cortex-M7, Cortex-M23, Cortex-M33 +// +#ifndef _CORE_NEEDS_DMB + #define _CORE_NEEDS_DMB 0 +#endif + +#ifndef RTT__DMB + #if _CORE_NEEDS_DMB + #error "Don't know how to place inline assembly for DMB" + #else + #define RTT__DMB() + #endif +#endif + +#ifndef SEGGER_RTT_CPU_CACHE_LINE_SIZE + #define SEGGER_RTT_CPU_CACHE_LINE_SIZE (0) // On most target systems where RTT is used, we do not have a CPU cache, therefore 0 is a good default here +#endif + +#ifndef SEGGER_RTT_UNCACHED_OFF + #if SEGGER_RTT_CPU_CACHE_LINE_SIZE + #error "SEGGER_RTT_UNCACHED_OFF must be defined when setting SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" + #else + #define SEGGER_RTT_UNCACHED_OFF (0) + #endif +#endif +#if RTT_USE_ASM + #if SEGGER_RTT_CPU_CACHE_LINE_SIZE + #error "RTT_USE_ASM is not available if SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" + #endif +#endif + +#ifndef SEGGER_RTT_ASM // defined when SEGGER_RTT.h is included from assembly file +#include +#include + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ + +// +// Determine how much we must pad the control block to make it a multiple of a cache line in size +// Assuming: U8 = 1B +// U16 = 2B +// U32 = 4B +// U8/U16/U32* = 4B +// +#if SEGGER_RTT_CPU_CACHE_LINE_SIZE // Avoid division by zero in case we do not have any cache + #define SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(NumBytes) (((NumBytes + SEGGER_RTT_CPU_CACHE_LINE_SIZE - 1) / SEGGER_RTT_CPU_CACHE_LINE_SIZE) * SEGGER_RTT_CPU_CACHE_LINE_SIZE) +#else + #define SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(NumBytes) (NumBytes) +#endif +#define SEGGER_RTT__CB_SIZE (16 + 4 + 4 + (SEGGER_RTT_MAX_NUM_UP_BUFFERS * 24) + (SEGGER_RTT_MAX_NUM_DOWN_BUFFERS * 24)) +#define SEGGER_RTT__CB_PADDING (SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(SEGGER_RTT__CB_SIZE) - SEGGER_RTT__CB_SIZE) + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +// +// Description for a circular buffer (also called "ring buffer") +// which is used as up-buffer (T->H) +// +typedef struct { + const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" + char* pBuffer; // Pointer to start of buffer + unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. + unsigned WrOff; // Position of next item to be written by either target. + volatile unsigned RdOff; // Position of next item to be read by host. Must be volatile since it may be modified by host. + unsigned Flags; // Contains configuration flags +} SEGGER_RTT_BUFFER_UP; + +// +// Description for a circular buffer (also called "ring buffer") +// which is used as down-buffer (H->T) +// +typedef struct { + const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" + char* pBuffer; // Pointer to start of buffer + unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. + volatile unsigned WrOff; // Position of next item to be written by host. Must be volatile since it may be modified by host. + unsigned RdOff; // Position of next item to be read by target (down-buffer). + unsigned Flags; // Contains configuration flags +} SEGGER_RTT_BUFFER_DOWN; + +// +// RTT control block which describes the number of buffers available +// as well as the configuration for each buffer +// +// +typedef struct { + char acID[16]; // Initialized to "SEGGER RTT" + int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2) + int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2) + SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host + SEGGER_RTT_BUFFER_DOWN aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target +#if SEGGER_RTT__CB_PADDING + unsigned char aDummy[SEGGER_RTT__CB_PADDING]; +#endif +} SEGGER_RTT_CB; + +/********************************************************************* +* +* Global data +* +********************************************************************** +*/ +extern SEGGER_RTT_CB _SEGGER_RTT; + +/********************************************************************* +* +* RTT API functions +* +********************************************************************** +*/ +#ifdef __cplusplus + extern "C" { +#endif +int SEGGER_RTT_AllocDownBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_AllocUpBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_GetKey (void); +unsigned SEGGER_RTT_HasData (unsigned BufferIndex); +int SEGGER_RTT_HasKey (void); +unsigned SEGGER_RTT_HasDataUp (unsigned BufferIndex); +void SEGGER_RTT_Init (void); +unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize); +unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize); +int SEGGER_RTT_SetNameDownBuffer (unsigned BufferIndex, const char* sName); +int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName); +int SEGGER_RTT_SetFlagsDownBuffer (unsigned BufferIndex, unsigned Flags); +int SEGGER_RTT_SetFlagsUpBuffer (unsigned BufferIndex, unsigned Flags); +int SEGGER_RTT_WaitKey (void); +unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_ASM_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s); +void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_PutChar (unsigned BufferIndex, char c); +unsigned SEGGER_RTT_PutCharSkip (unsigned BufferIndex, char c); +unsigned SEGGER_RTT_PutCharSkipNoLock (unsigned BufferIndex, char c); +unsigned SEGGER_RTT_GetAvailWriteSpace (unsigned BufferIndex); +unsigned SEGGER_RTT_GetBytesInBuffer (unsigned BufferIndex); +// +// Function macro for performance optimization +// +#define SEGGER_RTT_HASDATA(n) (((SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[n] + SEGGER_RTT_UNCACHED_OFF))->WrOff - ((SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[n] + SEGGER_RTT_UNCACHED_OFF))->RdOff) + +#if RTT_USE_ASM + #define SEGGER_RTT_WriteSkipNoLock SEGGER_RTT_ASM_WriteSkipNoLock +#endif + +/********************************************************************* +* +* RTT transfer functions to send RTT data via other channels. +* +********************************************************************** +*/ +unsigned SEGGER_RTT_ReadUpBuffer (unsigned BufferIndex, void* pBuffer, unsigned BufferSize); +unsigned SEGGER_RTT_ReadUpBufferNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize); +unsigned SEGGER_RTT_WriteDownBuffer (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteDownBufferNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); + +#define SEGGER_RTT_HASDATA_UP(n) (((SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[n] + SEGGER_RTT_UNCACHED_OFF))->WrOff - ((SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[n] + SEGGER_RTT_UNCACHED_OFF))->RdOff) // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + +/********************************************************************* +* +* RTT "Terminal" API functions +* +********************************************************************** +*/ +int SEGGER_RTT_SetTerminal (unsigned char TerminalId); +int SEGGER_RTT_TerminalOut (unsigned char TerminalId, const char* s); + +/********************************************************************* +* +* RTT printf functions (require SEGGER_RTT_printf.c) +* +********************************************************************** +*/ +int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...); +int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList); + +#ifdef __cplusplus + } +#endif + +#endif // ifndef(SEGGER_RTT_ASM) + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ + +// +// Operating modes. Define behavior if buffer is full (not enough space for entire message) +// +#define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0) // Skip. Do not block, output nothing. (Default) +#define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1) // Trim: Do not block, output as much as fits. +#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2) // Block: Wait until there is space in the buffer. +#define SEGGER_RTT_MODE_MASK (3) + +// +// Control sequences, based on ANSI. +// Can be used to control color, and clear the screen +// +#define RTT_CTRL_RESET "\x1B[0m" // Reset to default colors +#define RTT_CTRL_CLEAR "\x1B[2J" // Clear screen, reposition cursor to top left + +#define RTT_CTRL_TEXT_BLACK "\x1B[2;30m" +#define RTT_CTRL_TEXT_RED "\x1B[2;31m" +#define RTT_CTRL_TEXT_GREEN "\x1B[2;32m" +#define RTT_CTRL_TEXT_YELLOW "\x1B[2;33m" +#define RTT_CTRL_TEXT_BLUE "\x1B[2;34m" +#define RTT_CTRL_TEXT_MAGENTA "\x1B[2;35m" +#define RTT_CTRL_TEXT_CYAN "\x1B[2;36m" +#define RTT_CTRL_TEXT_WHITE "\x1B[2;37m" + +#define RTT_CTRL_TEXT_BRIGHT_BLACK "\x1B[1;30m" +#define RTT_CTRL_TEXT_BRIGHT_RED "\x1B[1;31m" +#define RTT_CTRL_TEXT_BRIGHT_GREEN "\x1B[1;32m" +#define RTT_CTRL_TEXT_BRIGHT_YELLOW "\x1B[1;33m" +#define RTT_CTRL_TEXT_BRIGHT_BLUE "\x1B[1;34m" +#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "\x1B[1;35m" +#define RTT_CTRL_TEXT_BRIGHT_CYAN "\x1B[1;36m" +#define RTT_CTRL_TEXT_BRIGHT_WHITE "\x1B[1;37m" + +#define RTT_CTRL_BG_BLACK "\x1B[24;40m" +#define RTT_CTRL_BG_RED "\x1B[24;41m" +#define RTT_CTRL_BG_GREEN "\x1B[24;42m" +#define RTT_CTRL_BG_YELLOW "\x1B[24;43m" +#define RTT_CTRL_BG_BLUE "\x1B[24;44m" +#define RTT_CTRL_BG_MAGENTA "\x1B[24;45m" +#define RTT_CTRL_BG_CYAN "\x1B[24;46m" +#define RTT_CTRL_BG_WHITE "\x1B[24;47m" + +#define RTT_CTRL_BG_BRIGHT_BLACK "\x1B[4;40m" +#define RTT_CTRL_BG_BRIGHT_RED "\x1B[4;41m" +#define RTT_CTRL_BG_BRIGHT_GREEN "\x1B[4;42m" +#define RTT_CTRL_BG_BRIGHT_YELLOW "\x1B[4;43m" +#define RTT_CTRL_BG_BRIGHT_BLUE "\x1B[4;44m" +#define RTT_CTRL_BG_BRIGHT_MAGENTA "\x1B[4;45m" +#define RTT_CTRL_BG_BRIGHT_CYAN "\x1B[4;46m" +#define RTT_CTRL_BG_BRIGHT_WHITE "\x1B[4;47m" + + +#endif + +/*************************** End of file ****************************/ diff --git a/cva_asw_m0118/src/RTT/SEGGER_RTT_ASM_ARMv7M.S b/cva_asw_m0118/src/RTT/SEGGER_RTT_ASM_ARMv7M.S new file mode 100644 index 0000000..cbbc52f --- /dev/null +++ b/cva_asw_m0118/src/RTT/SEGGER_RTT_ASM_ARMv7M.S @@ -0,0 +1,242 @@ +/********************************************************************* +* (c) SEGGER Microcontroller GmbH * +* The Embedded Experts * +* www.segger.com * +********************************************************************** + +-------------------------- END-OF-HEADER ----------------------------- + +File : SEGGER_RTT_ASM_ARMv7M.S +Purpose : Assembler implementation of RTT functions for ARMv7M + +Additional information: + This module is written to be assembler-independent and works with + GCC and clang (Embedded Studio) and IAR. +*/ + +#define SEGGER_RTT_ASM // Used to control processed input from header file +#include "SEGGER_RTT.h" + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ + +#define _CCIAR 0 +#define _CCCLANG 1 + +#if (defined __SES_ARM) || (defined __GNUC__) || (defined __clang__) + #define _CC_TYPE _CCCLANG + #define _PUB_SYM .global + #define _EXT_SYM .extern + #define _END .end + #define _WEAK .weak + #define _THUMB_FUNC .thumb_func + #define _THUMB_CODE .code 16 + #define _WORD .word + #define _SECTION(Sect, Type, AlignExp) .section Sect ##, "ax" + #define _ALIGN(Exp) .align Exp + #define _PLACE_LITS .ltorg + #define _DATA_SECT_START + #define _C_STARTUP _start + #define _STACK_END __stack_end__ + #define _RAMFUNC + // + // .text => Link to flash + // .fast => Link to RAM + // OtherSect => Usually link to RAM + // Alignment is 2^x + // +#elif defined (__IASMARM__) + #define _CC_TYPE _CCIAR + #define _PUB_SYM PUBLIC + #define _EXT_SYM EXTERN + #define _END END + #define _WEAK _WEAK + #define _THUMB_FUNC + #define _THUMB_CODE THUMB + #define _WORD DCD + #define _SECTION(Sect, Type, AlignExp) SECTION Sect ## : ## Type ## :REORDER:NOROOT ## (AlignExp) + #define _ALIGN(Exp) alignrom Exp + #define _PLACE_LITS + #define _DATA_SECT_START DATA + #define _C_STARTUP __iar_program_start + #define _STACK_END sfe(CSTACK) + #define _RAMFUNC SECTION_TYPE SHT_PROGBITS, SHF_WRITE | SHF_EXECINSTR + // + // .text => Link to flash + // .textrw => Link to RAM + // OtherSect => Usually link to RAM + // NOROOT => Allows linker to throw away the function, if not referenced + // Alignment is 2^x + // +#endif + +#if (_CC_TYPE == _CCIAR) + NAME SEGGER_RTT_ASM_ARMv7M +#else + .syntax unified +#endif + +#if defined (RTT_USE_ASM) && (RTT_USE_ASM == 1) + #define SHT_PROGBITS 0x1 + +/********************************************************************* +* +* Public / external symbols +* +********************************************************************** +*/ + + _EXT_SYM __aeabi_memcpy + _EXT_SYM __aeabi_memcpy4 + _EXT_SYM _SEGGER_RTT + + _PUB_SYM SEGGER_RTT_ASM_WriteSkipNoLock + +/********************************************************************* +* +* SEGGER_RTT_WriteSkipNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteSkipNoLock does not lock the application and +* skips all data, if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* MUST be > 0!!! +* This is done for performance reasons, so no initial check has do be done. +* +* Return value +* 1: Data has been copied +* 0: No space, data has not been copied +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, all data is dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ + _SECTION(.text, CODE, 2) + _ALIGN(2) + _THUMB_FUNC +SEGGER_RTT_ASM_WriteSkipNoLock: // unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pData, unsigned NumBytes) { + // + // Cases: + // 1) RdOff <= WrOff => Space until wrap-around is sufficient + // 2) RdOff <= WrOff => Space after wrap-around needed (copy in 2 chunks) + // 3) RdOff < WrOff => No space in buf + // 4) RdOff > WrOff => Space is sufficient + // 5) RdOff > WrOff => No space in buf + // + // 1) is the most common case for large buffers and assuming that J-Link reads the data fast enough + // + // Register usage: + // R0 Temporary needed as RdOff, register later on + // R1 pData + // R2 + // R3 register. Hold free for subroutine calls + // R4 + // R5 pRing->pBuffer + // R6 pRing (Points to active struct SEGGER_RTT_BUFFER_DOWN) + // R7 WrOff + // + PUSH {R4-R7} + ADD R3,R0,R0, LSL #+1 + LDR.W R0,=_SEGGER_RTT // pRing = &_SEGGER_RTT.aUp[BufferIndex]; + ADD R0,R0,R3, LSL #+3 + ADD R6,R0,#+24 + LDR R0,[R6, #+16] // RdOff = pRing->RdOff; + LDR R7,[R6, #+12] // WrOff = pRing->WrOff; + LDR R5,[R6, #+4] // pRing->pBuffer + CMP R7,R0 + BCC.N _CheckCase4 // if (RdOff <= WrOff) { => Case 1), 2) or 3) + // + // Handling for case 1, later on identical to case 4 + // + LDR R3,[R6, #+8] // Avail = pRing->SizeOfBuffer - WrOff - 1u; => Space until wrap-around (assume 1 byte not usable for case that RdOff == 0) + SUBS R4,R3,R7 // (Used in case we jump into case 2 afterwards) + SUBS R3,R4,#+1 // + CMP R3,R2 + BCC.N _CheckCase2 // if (Avail >= NumBytes) { => Case 1)? +_Case4: + ADDS R5,R7,R5 // pBuffer += WrOff + ADDS R0,R2,R7 // v = WrOff + NumBytes + // + // 2x unrolling for the copy loop that is used most of the time + // This is a special optimization for small SystemView packets and makes them even faster + // + _ALIGN(2) +_LoopCopyStraight: // memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + LDRB R3,[R1], #+1 + STRB R3,[R5], #+1 // *pDest++ = *pSrc++ + SUBS R2,R2,#+1 + BEQ _CSDone + LDRB R3,[R1], #+1 + STRB R3,[R5], #+1 // *pDest++ = *pSrc++ + SUBS R2,R2,#+1 + BNE _LoopCopyStraight +_CSDone: +#if _CORE_NEEDS_DMB // Do not slow down cores that do not need a DMB instruction here + DMB // Cortex-M7 may delay memory writes and also change the order in which the writes happen. Therefore, make sure that all buffer writes are finished, before updating the in the struct +#endif + STR R0,[R6, #+12] // pRing->WrOff = WrOff + NumBytes; + MOVS R0,#+1 + POP {R4-R7} + BX LR // Return 1 +_CheckCase2: + ADDS R0,R0,R3 // Avail += RdOff; => Space incl. wrap-around + CMP R0,R2 + BCC.N _Case3 // if (Avail >= NumBytes) { => Case 2? => If not, we have case 3) (does not fit) + // + // Handling for case 2 + // + ADDS R0,R7,R5 // v = pRing->pBuffer + WrOff => Do not change pRing->pBuffer here because 2nd chunk needs org. value + SUBS R2,R2,R4 // NumBytes -= Rem; (Rem = pRing->SizeOfBuffer - WrOff; => Space until end of buffer) +_LoopCopyBeforeWrapAround: // memcpy(pRing->pBuffer + WrOff, pData, Rem); => Copy 1st chunk + LDRB R3,[R1], #+1 + STRB R3,[R0], #+1 // *pDest++ = *pSrc++ + SUBS R4,R4,#+1 + BNE _LoopCopyBeforeWrapAround + // + // Special case: First check that assumed RdOff == 0 calculated that last element before wrap-around could not be used + // But 2nd check (considering space until wrap-around and until RdOff) revealed that RdOff is not 0, so we can use the last element + // In this case, we may use a copy straight until buffer end anyway without needing to copy 2 chunks + // Therefore, check if 2nd memcpy is necessary at all + // + ADDS R4,R2,#+0 // Save (needed as counter in loop but must be written to after the loop). Also use this inst to update the flags to skip 2nd loop if possible + BEQ.N _No2ChunkNeeded // if (NumBytes) { +_LoopCopyAfterWrapAround: // memcpy(pRing->pBuffer, pData + Rem, NumBytes); + LDRB R3,[R1], #+1 // pData already points to the next src byte due to copy loop increment before this loop + STRB R3,[R5], #+1 // *pDest++ = *pSrc++ + SUBS R2,R2,#+1 + BNE _LoopCopyAfterWrapAround +_No2ChunkNeeded: +#if _CORE_NEEDS_DMB // Do not slow down cores that do not need a DMB instruction here + DMB // Cortex-M7 may delay memory writes and also change the order in which the writes happen. Therefore, make sure that all buffer writes are finished, before updating the in the struct +#endif + STR R4,[R6, #+12] // pRing->WrOff = NumBytes; => Must be written after copying data because J-Link may read control block asynchronously while writing into buffer + MOVS R0,#+1 + POP {R4-R7} + BX LR // Return 1 +_CheckCase4: + SUBS R0,R0,R7 + SUBS R0,R0,#+1 // Avail = RdOff - WrOff - 1u; + CMP R0,R2 + BCS.N _Case4 // if (Avail >= NumBytes) { => Case 4) == 1) ? => If not, we have case 5) == 3) (does not fit) +_Case3: + MOVS R0,#+0 + POP {R4-R7} + BX LR // Return 0 + _PLACE_LITS + +#endif // defined (RTT_USE_ASM) && (RTT_USE_ASM == 1) + _END + +/*************************** End of file ****************************/ diff --git a/cva_asw_m0118/src/RTT/SEGGER_RTT_Conf.h b/cva_asw_m0118/src/RTT/SEGGER_RTT_Conf.h new file mode 100644 index 0000000..f71e227 --- /dev/null +++ b/cva_asw_m0118/src/RTT/SEGGER_RTT_Conf.h @@ -0,0 +1,429 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2021 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* condition is met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this condition and the following disclaimer. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 7.22b * +* * +********************************************************************** + +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_Conf.h +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support + debugger memory accesses while the CPU is running. +Revision: $Rev: 21386 $ + +*/ + +#ifndef SEGGER_RTT_CONF_H +#define SEGGER_RTT_CONF_H + +#ifdef __IAR_SYSTEMS_ICC__ + #include +#endif + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ + +// +// Take in and set to correct values for Cortex-A systems with CPU cache +// +//#define SEGGER_RTT_CPU_CACHE_LINE_SIZE (32) // Largest cache line size (in bytes) in the current system +//#define SEGGER_RTT_UNCACHED_OFF (0xFB000000) // Address alias where RTT CB and buffers can be accessed uncached +// +// Most common case: +// Up-channel 0: RTT +// Up-channel 1: SystemView +// +#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS + #define SEGGER_RTT_MAX_NUM_UP_BUFFERS (3) // Max. number of up-buffers (T->H) available on this target (Default: 3) +#endif +// +// Most common case: +// Down-channel 0: RTT +// Down-channel 1: SystemView +// +#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS + #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (3) // Max. number of down-buffers (H->T) available on this target (Default: 3) +#endif + +#ifndef BUFFER_SIZE_UP + #define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k) +#endif + +#ifndef BUFFER_SIZE_DOWN + #define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16) +#endif + +#ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE + #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64) +#endif + +#ifndef SEGGER_RTT_MODE_DEFAULT + #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0) +#endif + +/********************************************************************* +* +* RTT memcpy configuration +* +* memcpy() is good for large amounts of data, +* but the overhead is big for small amounts, which are usually stored via RTT. +* With SEGGER_RTT_MEMCPY_USE_BYTELOOP a simple byte loop can be used instead. +* +* SEGGER_RTT_MEMCPY() can be used to replace standard memcpy() in RTT functions. +* This is may be required with memory access restrictions, +* such as on Cortex-A devices with MMU. +*/ +#ifndef SEGGER_RTT_MEMCPY_USE_BYTELOOP + #define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 // 0: Use memcpy/SEGGER_RTT_MEMCPY, 1: Use a simple byte-loop +#endif +// +// Example definition of SEGGER_RTT_MEMCPY to external memcpy with GCC toolchains and Cortex-A targets +// +//#if ((defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)) && (defined (__ARM_ARCH_7A__)) +// #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) SEGGER_memcpy((pDest), (pSrc), (NumBytes)) +//#endif + +// +// Target is not allowed to perform other RTT operations while string still has not been stored completely. +// Otherwise we would probably end up with a mixed string in the buffer. +// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here. +// +// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4. +// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches. +// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly. +// (Higher priority = lower priority number) +// Default value for embOS: 128u +// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) +// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC +// or define SEGGER_RTT_LOCK() to completely disable interrupts. +// +#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20) +#endif + +/********************************************************************* +* +* RTT lock configuration for SEGGER Embedded Studio, +* Rowley CrossStudio and GCC +*/ +#if ((defined(__SES_ARM) || defined(__SES_RISCV) || defined(__CROSSWORKS_ARM) || defined(__GNUC__) || defined(__clang__)) && !defined (__CC_ARM) && !defined(WIN32)) + #if (defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_8M_BASE__)) + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + __asm volatile ("mrs %0, primask \n\t" \ + "movs r1, #1 \n\t" \ + "msr primask, r1 \n\t" \ + : "=r" (_SEGGER_RTT__LockState) \ + : \ + : "r1", "cc" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \ + : \ + : "r" (_SEGGER_RTT__LockState) \ + : \ + ); \ + } + #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + __asm volatile ("mrs %0, basepri \n\t" \ + "mov r1, %1 \n\t" \ + "msr basepri, r1 \n\t" \ + : "=r" (_SEGGER_RTT__LockState) \ + : "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \ + : "r1", "cc" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \ + : \ + : "r" (_SEGGER_RTT__LockState) \ + : \ + ); \ + } + + #elif defined(__ARM_ARCH_7A__) + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + __asm volatile ("mrs r1, CPSR \n\t" \ + "mov %0, r1 \n\t" \ + "orr r1, r1, #0xC0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : "=r" (_SEGGER_RTT__LockState) \ + : \ + : "r1", "cc" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \ + "mrs r1, CPSR \n\t" \ + "bic r1, r1, #0xC0 \n\t" \ + "and r0, r0, #0xC0 \n\t" \ + "orr r1, r1, r0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : \ + : "r" (_SEGGER_RTT__LockState) \ + : "r0", "r1", "cc" \ + ); \ + } + #elif defined(__riscv) || defined(__riscv_xlen) + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + __asm volatile ("csrr %0, mstatus \n\t" \ + "csrci mstatus, 8 \n\t" \ + "andi %0, %0, 8 \n\t" \ + : "=r" (_SEGGER_RTT__LockState) \ + : \ + : \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("csrr a1, mstatus \n\t" \ + "or %0, %0, a1 \n\t" \ + "csrs mstatus, %0 \n\t" \ + : \ + : "r" (_SEGGER_RTT__LockState) \ + : "a1" \ + ); \ + } + #else + #define SEGGER_RTT_LOCK() + #define SEGGER_RTT_UNLOCK() + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR EWARM +*/ +#ifdef __ICCARM__ + #if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) || \ + (defined (__ARM8M_BASELINE__) && (__CORE__ == __ARM8M_BASELINE__)) + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + _SEGGER_RTT__LockState = __get_PRIMASK(); \ + __set_PRIMASK(1); + + #define SEGGER_RTT_UNLOCK() __set_PRIMASK(_SEGGER_RTT__LockState); \ + } + #elif (defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || \ + (defined (__ARM7M__) && (__CORE__ == __ARM7M__)) || \ + (defined (__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__)) || \ + (defined (__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + _SEGGER_RTT__LockState = __get_BASEPRI(); \ + __set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); + + #define SEGGER_RTT_UNLOCK() __set_BASEPRI(_SEGGER_RTT__LockState); \ + } + #elif (defined (__ARM7A__) && (__CORE__ == __ARM7A__)) || \ + (defined (__ARM7R__) && (__CORE__ == __ARM7R__)) + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + __asm volatile ("mrs r1, CPSR \n\t" \ + "mov %0, r1 \n\t" \ + "orr r1, r1, #0xC0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : "=r" (_SEGGER_RTT__LockState) \ + : \ + : "r1", "cc" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \ + "mrs r1, CPSR \n\t" \ + "bic r1, r1, #0xC0 \n\t" \ + "and r0, r0, #0xC0 \n\t" \ + "orr r1, r1, r0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : \ + : "r" (_SEGGER_RTT__LockState) \ + : "r0", "r1", "cc" \ + ); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR RX +*/ +#ifdef __ICCRX__ + #define SEGGER_RTT_LOCK() { \ + unsigned long _SEGGER_RTT__LockState; \ + _SEGGER_RTT__LockState = __get_interrupt_state(); \ + __disable_interrupt(); + + #define SEGGER_RTT_UNLOCK() __set_interrupt_state(_SEGGER_RTT__LockState); \ + } +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR RL78 +*/ +#ifdef __ICCRL78__ + #define SEGGER_RTT_LOCK() { \ + __istate_t _SEGGER_RTT__LockState; \ + _SEGGER_RTT__LockState = __get_interrupt_state(); \ + __disable_interrupt(); + + #define SEGGER_RTT_UNLOCK() __set_interrupt_state(_SEGGER_RTT__LockState); \ + } +#endif + +/********************************************************************* +* +* RTT lock configuration for KEIL ARM +*/ +#ifdef __CC_ARM + #if (defined __TARGET_ARCH_6S_M) + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + register unsigned char _SEGGER_RTT__PRIMASK __asm( "primask"); \ + _SEGGER_RTT__LockState = _SEGGER_RTT__PRIMASK; \ + _SEGGER_RTT__PRIMASK = 1u; \ + __schedule_barrier(); + + #define SEGGER_RTT_UNLOCK() _SEGGER_RTT__PRIMASK = _SEGGER_RTT__LockState; \ + __schedule_barrier(); \ + } + #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + register unsigned char BASEPRI __asm( "basepri"); \ + _SEGGER_RTT__LockState = BASEPRI; \ + BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \ + __schedule_barrier(); + + #define SEGGER_RTT_UNLOCK() BASEPRI = _SEGGER_RTT__LockState; \ + __schedule_barrier(); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for TI ARM +*/ +#ifdef __TI_ARM__ + #if defined (__TI_ARM_V6M0__) + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + _SEGGER_RTT__LockState = __get_PRIMASK(); \ + __set_PRIMASK(1); + + #define SEGGER_RTT_UNLOCK() __set_PRIMASK(_SEGGER_RTT__LockState); \ + } + #elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + _SEGGER_RTT__LockState = _set_interrupt_priority(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); + + #define SEGGER_RTT_UNLOCK() _set_interrupt_priority(_SEGGER_RTT__LockState); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for CCRX +*/ +#ifdef __RX + #include + #define SEGGER_RTT_LOCK() { \ + unsigned long _SEGGER_RTT__LockState; \ + _SEGGER_RTT__LockState = get_psw() & 0x010000; \ + clrpsw_i(); + + #define SEGGER_RTT_UNLOCK() set_psw(get_psw() | _SEGGER_RTT__LockState); \ + } +#endif + +/********************************************************************* +* +* RTT lock configuration for embOS Simulation on Windows +* (Can also be used for generic RTT locking with embOS) +*/ +#if defined(WIN32) || defined(SEGGER_RTT_LOCK_EMBOS) + +void OS_SIM_EnterCriticalSection(void); +void OS_SIM_LeaveCriticalSection(void); + +#define SEGGER_RTT_LOCK() { \ + OS_SIM_EnterCriticalSection(); + +#define SEGGER_RTT_UNLOCK() OS_SIM_LeaveCriticalSection(); \ + } +#endif + +/********************************************************************* +* +* RTT lock configuration fallback +*/ +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK() // Lock RTT (nestable) (i.e. disable interrupts) +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state) +#endif + +#endif +/*************************** End of file ****************************/ diff --git a/cva_asw_m0118/src/RTT/SEGGER_RTT_Syscalls_GCC.c b/cva_asw_m0118/src/RTT/SEGGER_RTT_Syscalls_GCC.c new file mode 100644 index 0000000..f0688f7 --- /dev/null +++ b/cva_asw_m0118/src/RTT/SEGGER_RTT_Syscalls_GCC.c @@ -0,0 +1,125 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2021 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* condition is met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this condition and the following disclaimer. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 7.22b * +* * +********************************************************************** + +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_Syscalls_GCC.c +Purpose : Low-level functions for using printf() via RTT in GCC. + To use RTT for printf output, include this file in your + application. +Revision: $Rev: 20755 $ +---------------------------------------------------------------------- +*/ +#if (defined __GNUC__) && !(defined __SES_ARM) && !(defined __CROSSWORKS_ARM) && !(defined __ARMCC_VERSION) && !(defined __CC_ARM) + +#include // required for _write_r +#include "SEGGER_RTT.h" + + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +// +// If necessary define the _reent struct +// to match the one passed by the used standard library. +// +struct _reent; + +/********************************************************************* +* +* Function prototypes +* +********************************************************************** +*/ +_ssize_t _write (int file, const void *ptr, size_t len); +_ssize_t _write_r(struct _reent *r, int file, const void *ptr, size_t len); + +/********************************************************************* +* +* Global functions +* +********************************************************************** +*/ + +/********************************************************************* +* +* _write() +* +* Function description +* Low-level write function. +* libc subroutines will use this system routine for output to all files, +* including stdout. +* Write data via RTT. +*/ +_ssize_t _write(int file, const void *ptr, size_t len) { + (void) file; /* Not used, avoid warning */ + SEGGER_RTT_Write(0, ptr, len); + return len; +} + +/********************************************************************* +* +* _write_r() +* +* Function description +* Low-level reentrant write function. +* libc subroutines will use this system routine for output to all files, +* including stdout. +* Write data via RTT. +*/ +_ssize_t _write_r(struct _reent *r, int file, const void *ptr, size_t len) { + (void) file; /* Not used, avoid warning */ + (void) r; /* Not used, avoid warning */ + SEGGER_RTT_Write(0, ptr, len); + return len; +} + +#endif +/****** End Of File *************************************************/ diff --git a/cva_asw_m0118/src/RTT/SEGGER_RTT_printf.c b/cva_asw_m0118/src/RTT/SEGGER_RTT_printf.c new file mode 100644 index 0000000..fba41db --- /dev/null +++ b/cva_asw_m0118/src/RTT/SEGGER_RTT_printf.c @@ -0,0 +1,505 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2021 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* condition is met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this condition and the following disclaimer. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 7.22b * +* * +********************************************************************** + +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_printf.c +Purpose : Replacement for printf to write formatted data via RTT +Revision: $Rev: 17697 $ +---------------------------------------------------------------------- +*/ +#include "SEGGER_RTT.h" +#include "SEGGER_RTT_Conf.h" + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ + +#ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE + #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64) +#endif + +#include +#include + + +#define FORMAT_FLAG_LEFT_JUSTIFY (1u << 0) +#define FORMAT_FLAG_PAD_ZERO (1u << 1) +#define FORMAT_FLAG_PRINT_SIGN (1u << 2) +#define FORMAT_FLAG_ALTERNATE (1u << 3) + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +typedef struct { + char* pBuffer; + unsigned BufferSize; + unsigned Cnt; + + int ReturnValue; + + unsigned RTTBufferIndex; +} SEGGER_RTT_PRINTF_DESC; + +/********************************************************************* +* +* Function prototypes +* +********************************************************************** +*/ + +/********************************************************************* +* +* Static code +* +********************************************************************** +*/ +/********************************************************************* +* +* _StoreChar +*/ +static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p, char c) { + unsigned Cnt; + + Cnt = p->Cnt; + if ((Cnt + 1u) <= p->BufferSize) { + *(p->pBuffer + Cnt) = c; + p->Cnt = Cnt + 1u; + p->ReturnValue++; + } + // + // Write part of string, when the buffer is full + // + if (p->Cnt == p->BufferSize) { + if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) { + p->ReturnValue = -1; + } else { + p->Cnt = 0u; + } + } +} + +/********************************************************************* +* +* _PrintUnsigned +*/ +static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc, unsigned v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) { + static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + unsigned Div; + unsigned Digit; + unsigned Number; + unsigned Width; + char c; + + Number = v; + Digit = 1u; + // + // Get actual field width + // + Width = 1u; + while (Number >= Base) { + Number = (Number / Base); + Width++; + } + if (NumDigits > Width) { + Width = NumDigits; + } + // + // Print leading chars if necessary + // + if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) { + if (FieldWidth != 0u) { + if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) { + c = '0'; + } else { + c = ' '; + } + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, c); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Compute Digit. + // Loop until Digit has the value of the highest digit required. + // Example: If the output is 345 (Base 10), loop 2 times until Digit is 100. + // + while (1) { + if (NumDigits > 1u) { // User specified a min number of digits to print? => Make sure we loop at least that often, before checking anything else (> 1 check avoids problems with NumDigits being signed / unsigned) + NumDigits--; + } else { + Div = v / Digit; + if (Div < Base) { // Is our divider big enough to extract the highest digit from value? => Done + break; + } + } + Digit *= Base; + } + // + // Output digits + // + do { + Div = v / Digit; + v -= Div * Digit; + _StoreChar(pBufferDesc, _aV2C[Div]); + if (pBufferDesc->ReturnValue < 0) { + break; + } + Digit /= Base; + } while (Digit); + // + // Print trailing spaces if necessary + // + if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, ' '); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + } +} + +/********************************************************************* +* +* _PrintInt +*/ +static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc, int v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) { + unsigned Width; + int Number; + + Number = (v < 0) ? -v : v; + + // + // Get actual field width + // + Width = 1u; + while (Number >= (int)Base) { + Number = (Number / (int)Base); + Width++; + } + if (NumDigits > Width) { + Width = NumDigits; + } + if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) { + FieldWidth--; + } + + // + // Print leading spaces if necessary + // + if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, ' '); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + // + // Print sign if necessary + // + if (pBufferDesc->ReturnValue >= 0) { + if (v < 0) { + v = -v; + _StoreChar(pBufferDesc, '-'); + } else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) { + _StoreChar(pBufferDesc, '+'); + } else { + + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Print leading zeros if necessary + // + if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, '0'); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Print number without sign + // + _PrintUnsigned(pBufferDesc, (unsigned)v, Base, NumDigits, FieldWidth, FormatFlags); + } + } + } +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* SEGGER_RTT_vprintf +* +* Function description +* Stores a formatted string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal") +* sFormat Pointer to format string +* pParamList Pointer to the list of arguments for the format string +* +* Return values +* >= 0: Number of bytes which have been stored in the "Up"-buffer. +* < 0: Error +*/ +int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) { + char c; + SEGGER_RTT_PRINTF_DESC BufferDesc; + int v; + unsigned NumDigits; + unsigned FormatFlags; + unsigned FieldWidth; + char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE]; + + BufferDesc.pBuffer = acBuffer; + BufferDesc.BufferSize = SEGGER_RTT_PRINTF_BUFFER_SIZE; + BufferDesc.Cnt = 0u; + BufferDesc.RTTBufferIndex = BufferIndex; + BufferDesc.ReturnValue = 0; + + do { + c = *sFormat; + sFormat++; + if (c == 0u) { + break; + } + if (c == '%') { + // + // Filter out flags + // + FormatFlags = 0u; + v = 1; + do { + c = *sFormat; + switch (c) { + case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break; + case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++; break; + case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++; break; + case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++; break; + default: v = 0; break; + } + } while (v); + // + // filter out field with + // + FieldWidth = 0u; + do { + c = *sFormat; + if ((c < '0') || (c > '9')) { + break; + } + sFormat++; + FieldWidth = (FieldWidth * 10u) + ((unsigned)c - '0'); + } while (1); + + // + // Filter out precision (number of digits to display) + // + NumDigits = 0u; + c = *sFormat; + if (c == '.') { + sFormat++; + do { + c = *sFormat; + if ((c < '0') || (c > '9')) { + break; + } + sFormat++; + NumDigits = NumDigits * 10u + ((unsigned)c - '0'); + } while (1); + } + // + // Filter out length modifier + // + c = *sFormat; + do { + if ((c == 'l') || (c == 'h')) { + sFormat++; + c = *sFormat; + } else { + break; + } + } while (1); + // + // Handle specifiers + // + switch (c) { + case 'c': { + char c0; + v = va_arg(*pParamList, int); + c0 = (char)v; + _StoreChar(&BufferDesc, c0); + break; + } + case 'd': + v = va_arg(*pParamList, int); + _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags); + break; + case 'u': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 10u, NumDigits, FieldWidth, FormatFlags); + break; + case 'x': + case 'X': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, NumDigits, FieldWidth, FormatFlags); + break; + case 's': + { + const char * s = va_arg(*pParamList, const char *); + do { + c = *s; + s++; + if (c == '\0') { + break; + } + _StoreChar(&BufferDesc, c); + } while (BufferDesc.ReturnValue >= 0); + } + break; + case 'p': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, 8u, 8u, 0u); + break; + case '%': + _StoreChar(&BufferDesc, '%'); + break; + default: + break; + } + sFormat++; + } else { + _StoreChar(&BufferDesc, c); + } + } while (BufferDesc.ReturnValue >= 0); + + if (BufferDesc.ReturnValue > 0) { + // + // Write remaining data, if any + // + if (BufferDesc.Cnt != 0u) { + SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt); + } + BufferDesc.ReturnValue += (int)BufferDesc.Cnt; + } + return BufferDesc.ReturnValue; +} + +/********************************************************************* +* +* SEGGER_RTT_printf +* +* Function description +* Stores a formatted string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal") +* sFormat Pointer to format string, followed by the arguments for conversion +* +* Return values +* >= 0: Number of bytes which have been stored in the "Up"-buffer. +* < 0: Error +* +* Notes +* (1) Conversion specifications have following syntax: +* %[flags][FieldWidth][.Precision]ConversionSpecifier +* (2) Supported flags: +* -: Left justify within the field width +* +: Always print sign extension for signed conversions +* 0: Pad with 0 instead of spaces. Ignored when using '-'-flag or precision +* Supported conversion specifiers: +* c: Print the argument as one char +* d: Print the argument as a signed integer +* u: Print the argument as an unsigned integer +* x: Print the argument as an hexadecimal integer +* s: Print the string pointed to by the argument +* p: Print the argument as an 8-digit hexadecimal integer. (Argument shall be a pointer to void.) +*/ +int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...) { + int r; + va_list ParamList; + + va_start(ParamList, sFormat); + r = SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList); + va_end(ParamList); + return r; +} +/*************************** End of file ****************************/ diff --git a/cva_asw_m0118/src/TLE9461/SBC_TLE94x1.h b/cva_asw_m0118/src/TLE9461/SBC_TLE94x1.h new file mode 100644 index 0000000..146c2cc --- /dev/null +++ b/cva_asw_m0118/src/TLE9461/SBC_TLE94x1.h @@ -0,0 +1,101 @@ +/** + * @cond + *********************************************************************************************************************** + * + * Copyright (c) 2018, Infineon Technologies AG + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the + * following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************************************************************/ +#ifndef SBC_TLE94X1_H +#define SBC_TLE94X1_H + +/* XML Version 0.0.6 */ +#define SBC_XML_VERSION (00006) + +#define CTRL_BUS_CTRL_0 (0x3) /*decimal 3*/ + +#define CTRL_BUS_CTRL_3 (0x0) /*decimal 0*/ + +#define CTRL_GPIO_CTRL (0x4) /*decimal 4*/ + +#define CTRL_HW_CTRL_0 (0x40) /*decimal 64*/ + +#define CTRL_HW_CTRL_1 (0x0) /*decimal 0*/ + +#define CTRL_HW_CTRL_2 (0x40) /*decimal 64*/ + +#define CTRL_HW_CTRL_3 (0x1) /*decimal 1*/ + +#define CTRL_M_S_CTRL (0x13) /*decimal 19*/ + +#define CTRL_PWM_CTRL (0x0) /*decimal 0*/ + +#define CTRL_PWM_FREQ_CTRL (0x0) /*decimal 0*/ + +#define CTRL_SWK_BTL0_CTRL (0x50) /*decimal 80*/ + +#define CTRL_SWK_CAN_FD_CTRL (0x0) /*decimal 0*/ + +#define CTRL_SWK_CDR_CTRL2 (0x1) /*decimal 1*/ + +#define CTRL_SWK_CDR_LIMIT_HIGH_CTRL (0x54) /*decimal 84*/ + +#define CTRL_SWK_CDR_LIMIT_LOW_CTRL (0x4C) /*decimal 76*/ + +#define CTRL_SWK_DATA_H_CTRL 0x00000000 + +#define CTRL_SWK_DATA_L_CTRL 0x00000000 + +#define CTRL_SWK_DLC_CTRL (0x0) /*decimal 0*/ + +#define CTRL_SWK_ID0_CTRL (0x0) /*decimal 0*/ + +#define CTRL_SWK_IDx_CTRL 0x00000000 + +#define CTRL_SWK_MASK_IDx_CTRL 0x00000000 + +#define CTRL_TIMER_CTRL (0x0) /*decimal 0*/ + +#define CTRL_WD_CTRL (0x15) /*decimal 21*/ + +#define CTRL_WK_CTRL_0 (0x0) /*decimal 0*/ + +#define CTRL_WK_CTRL_1 (0x0) /*decimal 0*/ + +#define CTRL_WK_PUPD_CTRL (0x0) /*decimal 0*/ + +#define LED_Math_extendedID (0x1) /*decimal 1*/ + +#define LED_Math_extendedIDMsk (0x1) /*decimal 1*/ + +#define MATH_Baudrate (0x2) /*decimal 2*/ + +#define MATH_CDR_FrequencyMHz (0x28) /*decimal 40*/ + +#define MATH_DoubleCDRFreq (0x0) /*decimal 0*/ + +#define MATH_EN_PN (0x1) /*decimal 1*/ + +#define MATH_PWM_DC (0.0) + +#endif /* SBC_TLE94X1_H */ diff --git a/cva_asw_m0118/src/TLE9461/TLE9461.icwp b/cva_asw_m0118/src/TLE9461/TLE9461.icwp new file mode 100644 index 0000000..5a043c4 --- /dev/null +++ b/cva_asw_m0118/src/TLE9461/TLE9461.icwp @@ -0,0 +1,233 @@ + + + 9e8e9087eecb39921ec31dfccce96b2a2efec664bafe2827aea4ddb51cb86761 + TLE94x1_Lib.xml + V0.0.6 + + + CTRL.HW_CTRL_2[4] + 0 + 0 + + + CTRL.HW_CTRL_1[4] + 0 + 0 + + + CTRL.WK_PUPD_CTRL[7:6] + 0 + 0 + + + CTRL.PWM_FREQ_CTRL[1:0] + 0 + 0 + + + MATH.PWM_DC + 0 + 0.0 + + + CTRL.WK_CTRL_1[7] + 0 + 0 + + + CTRL.HW_CTRL_0[0] + 0 + 0 + + + CTRL.HW_CTRL_0[5] + 0 + 0 + + + CTRL.BUS_CTRL_3[4] + 0 + 0 + + + CTRL.WK_PUPD_CTRL[1:0] + 0 + 0 + + + CTRL.WK_CTRL_0[6] + 0 + 0 + + + CTRL.TIMER_CTRL[3:0] + 0 + 0 + + + CTRL.TIMER_CTRL[6:4] + 0 + 0 + + + CTRL.HW_CTRL_1[5] + 0 + 0 + + + CTRL.HW_CTRL_3[2] + 0 + 0 + + + CTRL.WD_CTRL[5] + 0 + 0 + + + CTRL.HW_CTRL_0[2] + 0 + 0 + + + CTRL.HW_CTRL_2[7:5] + 2 + 2 + + + CTRL.HW_CTRL_2[3:2] + 0 + 0 + + + CTRL.SWK_CAN_FD_CTRL[3:1] + 2 + 0 + + + MATH.Baudrate + 2 + 2 + + + CTRL.SWK_ID0_CTRL[0] + 0 + 0 + + + CTRL.SWK_MASK_IDx_CTRL + 0x00000000 + 0 + + + CTRL.SWK_DLC_CTRL[3:0] + 0 + 0 + + + CTRL.SWK_DATA_H_CTRL + 0x00000000 + 0x00000000 + + + CTRL.SWK_DATA_L_CTRL + 0x00000000 + 0x00000000 + + + CTRL.HW_CTRL_1[3] + 0 + 0 + + + CTRL.HW_CTRL_2[0] + 0 + 0 + + + CTRL.M_S_CTRL[4:3] + 2 + 2 + + + MATH.EN_PN + 1 + 1 + + + CTRL.HW_CTRL_3[1:0] + 1 + 1 + + + CTRL.HW_CTRL_0[6] + 1 + 1 + + + CTRL.SWK_CAN_FD_CTRL[0] + 0 + 0 + + + MATH.DoubleCDRFreq + 0 + 0 + + + CTRL.SWK_IDx_CTRL + 0x00000000 + 0 + + + CTRL.GPIO_CTRL[2:0] + 4 + 4 + + + CTRL.WK_CTRL_1[0] + 0 + 0 + + + CTRL.WK_CTRL_1[5] + 0 + 0 + + + CTRL.WK_CTRL_0[2];CTRL.WD_CTRL[6] + 1 + 1 + + + CTRL.WD_CTRL[4] + 1 + 1 + + + CTRL.WD_CTRL[2:0] + 5 + 5 + + + CTRL.M_S_CTRL[1:0] + 3 + 3 + + + CTRL.HW_CTRL_1[7] + 0 + 0 + + + CTRL.M_S_CTRL[2] + 0 + 0 + + + CTRL.BUS_CTRL_0[2:0] + 3 + 3 + + + \ No newline at end of file diff --git a/cva_asw_m0118/src/TLE9461/TLE94x1.c b/cva_asw_m0118/src/TLE9461/TLE94x1.c new file mode 100644 index 0000000..73428d2 --- /dev/null +++ b/cva_asw_m0118/src/TLE9461/TLE94x1.c @@ -0,0 +1,591 @@ +/********************************************************************************************************************* + * Copyright (c) 2019, Infineon Technologies AG + * + * + * Distributed under the Boost Software License, Version 1.0. + * + * + * Boost Software License - Version 1.0 - August 17th, 2003 + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *********************************************************************************************************************/ + + +/****************************************************************************************************//** + * @file TLE94x1.c + * + * @brief Implementation of main library functions + * + * @version V1.0.1 + * @date 05. October 2020 + * @author Markus Noll / markus.noll@infineon.com + * @author Yannek Micha Rixen / Yannek.Rixen@infineon.com + ********************************************************************************************************/ + + + +/* ================================================================================ */ +/* ============================ HEADER FILES ================================ */ +/* ================================================================================ */ + +#include "TLE94x1.h" +#include "SBC_TLE94x1.h" +#include + + +/* ================================================================================ */ +/* ============================== Variables ================================= */ +/* ================================================================================ */ + + +/* -------------------------------- ISR Handling --------------------------------- */ + +static SBC_Func_Callback SBC_ISR_Callbacks[30]; +static uint32_t SBC_ISR_Vectors[30]; +static uint8_t SBC_ISR_ReadOutRegs[30]; +static uint8_t SBC_ISR_ReadOutVals[30]; +static uint8_t SBC_RegisteredCallbacks = 0; +static uint8_t SBC_RegisteredRedoutRegs = 0; + + + +/* ================================================================================ */ +/* =========================== Library Functions ============================ */ +/* ================================================================================ */ + + +/* -------------------------------- Main Functions ------------------------------- */ + + +SBC_ErrorCode SBC_WD_Trigger(void) { + /* Read WD config out of SBC and write back to trigger WD */ + uint8_t WD_Data = (uint8_t)SBC_Read_Command(SBC_WD_CTRL); + return SBC_Write_Reg(SBC_WD_CTRL, WD_Data, NULL); +} + + +uint16_t SBC_Read_Command(uint8_t SBC_Reg) { + /* Read and return data - Bit[15:8] = Status Information Field - Bit [7:0] Register data */ + return SBC_SPI_TRANSFER16(SBC_Read_Mask & SBC_Reg, 0x00U); +} + + +uint8_t SBC_Read_RegField(uint8_t SBC_Reg, uint8_t SBC_FieldMsk, uint8_t SBC_FieldPos) { + uint8_t data = ((uint8_t)SBC_Read_Command(SBC_Reg)) & 0xFFU; + return (data & SBC_FieldMsk) >> SBC_FieldPos; +} + + +SBC_ErrorCode SBC_Write_Reg(uint8_t SBC_Reg, uint8_t SBC_Val, uint16_t * returnval) { + SBC_ErrorCode errCode; + uint16_t returndata = SBC_SPI_TRANSFER16(SBC_Write_Bit | SBC_Reg, SBC_Val); + if(returnval != NULL) { + *returnval = returndata; + } + + errCode.SBC_Register = SBC_Reg; + errCode.flippedBitsMask = ((uint8_t)SBC_Read_Command(SBC_Reg)) ^ SBC_Val; + errCode.expectedValue = SBC_Val; + return errCode; +} + + +SBC_ErrorCode SBC_Write_RegField(uint8_t SBC_Reg, uint8_t SBC_FieldMsk, uint8_t SBC_FieldPos, uint8_t SBC_FieldVal, uint16_t * returnval) { + SBC_ErrorCode errCode; + + /* Read data out of register to be manipulated */ + uint16_t returndata = SBC_Read_Command(SBC_Reg); + if(returnval != NULL) { + *returnval = returndata; + } + uint8_t data = (uint8_t)returndata; + + /* Set the used bit field to all 0 */ + data &= ~(SBC_FieldMsk); + + /* Configure new data to bit field */ + data |= (SBC_FieldVal << SBC_FieldPos); + + (void)SBC_SPI_TRANSFER16(SBC_Write_Bit | SBC_Reg, data); + + errCode.SBC_Register = SBC_Reg; + errCode.expectedValue = (SBC_FieldVal << SBC_FieldPos); + uint8_t actualValue = ((uint8_t)SBC_Read_Command(SBC_Reg)) & SBC_FieldMsk; + errCode.flippedBitsMask = errCode.expectedValue ^ actualValue; + return errCode; +} + + +SBC_ErrorCode SBC_Init(void) { + SBC_ErrorCode errCode; + uint8_t WD_Checksum = CTRL_WD_CTRL; + uint8_t WD_CTRL = CTRL_WD_CTRL; + uint8_t SWK_ID3_CTRL, SWK_ID2_CTRL, SWK_ID1_CTRL, SWK_ID0_CTRL; + uint8_t SWK_MASK_ID3_CTRL, SWK_MASK_ID2_CTRL, SWK_MASK_ID1_CTRL, SWK_MASK_ID0_CTRL; + uint8_t SWK_CAN_FD_CTRL = CTRL_SWK_CAN_FD_CTRL; + + /* Calculate checksum */ + WD_Checksum = WD_Checksum ^ WD_Checksum >> 4; + WD_Checksum = WD_Checksum ^ WD_Checksum >> 2; + WD_Checksum = WD_Checksum ^ WD_Checksum >> 1; + + if((WD_Checksum & 1) > 0) { + /* Set parity bit */ + WD_CTRL = CTRL_WD_CTRL | 0x80U; + } + + /* Check if ID is configured to be extended */ + if((CTRL_SWK_ID0_CTRL & SBC_SWK_ID0_CTRL_IDE_Msk) == SBC_IDE_EXTENDED) { + /* extended ID */ + uint32_t SWK_ID_CTRL = CTRL_SWK_IDx_CTRL << 3; + uint32_t SWK_MASK_ID_CTRL = CTRL_SWK_MASK_IDx_CTRL << 3; + + SWK_ID3_CTRL = (uint8_t)(SWK_ID_CTRL >> 24); + SWK_ID2_CTRL = (uint8_t)(SWK_ID_CTRL >> 16); + SWK_ID1_CTRL = (uint8_t)(SWK_ID_CTRL >> 8); + SWK_ID0_CTRL = (((uint8_t)(SWK_ID_CTRL >> 1)) & SBC_SWK_ID0_CTRL_ID4_0_Msk) | SBC_IDE_EXTENDED; + SWK_MASK_ID3_CTRL = (uint8_t)(SWK_MASK_ID_CTRL >> 24); + SWK_MASK_ID2_CTRL = (uint8_t)(SWK_MASK_ID_CTRL >> 16); + SWK_MASK_ID1_CTRL = (uint8_t)(SWK_MASK_ID_CTRL >> 8); + SWK_MASK_ID0_CTRL = (((uint8_t)(SWK_MASK_ID_CTRL >> 1)) & SBC_SWK_MASK_ID0_CTRL_MASK_ID4_0_Msk); + } else { + /* Standard length ID */ + uint16_t SWK_ID_CTRL = CTRL_SWK_IDx_CTRL; + uint32_t SWK_MASK_ID_CTRL = CTRL_SWK_MASK_IDx_CTRL; + + SWK_ID3_CTRL = (uint8_t)(SWK_ID_CTRL >> 3); + SWK_ID2_CTRL = (uint8_t)(SWK_ID_CTRL << 5); + SWK_ID1_CTRL = 0x00U; + SWK_ID0_CTRL = 0x00U; + SWK_MASK_ID3_CTRL = (uint8_t)(SWK_MASK_ID_CTRL >> 3); + SWK_MASK_ID2_CTRL = (uint8_t)(SWK_MASK_ID_CTRL << 5); + SWK_MASK_ID1_CTRL = 0x00U; + SWK_MASK_ID0_CTRL = 0x00U; + } + + /* DIS_ERR_CNT is set only when FD Tolerance is set. */ + if((CTRL_SWK_CAN_FD_CTRL & SBC_SWK_CAN_FD_CTRL_CAN_FD_EN_Msk) == SBC_CAN_FD_EN_ENABLED) { + SWK_CAN_FD_CTRL &= SBC_DIS_ERR_CNT_DISABLED << SBC_SWK_CAN_FD_CTRL_DIS_ERR_CNT_Pos; + } + + /* Describes initialization sequence */ + uint8_t initSequence[39][2] = { + {SBC_WD_CTRL, WD_CTRL}, + {SBC_M_S_CTRL, CTRL_M_S_CTRL}, + {SBC_HW_CTRL_0, CTRL_HW_CTRL_0}, + {SBC_HW_CTRL_3, CTRL_HW_CTRL_3}, + {SBC_BUS_CTRL_3, CTRL_BUS_CTRL_3}, + {SBC_WK_CTRL_0, CTRL_WK_CTRL_0}, + {SBC_WK_CTRL_1, CTRL_WK_CTRL_1}, + {SBC_WK_PUPD_CTRL, CTRL_WK_PUPD_CTRL}, + {SBC_TIMER_CTRL, CTRL_TIMER_CTRL}, + {SBC_PWM_FREQ_CTRL, CTRL_PWM_FREQ_CTRL}, /* The desired duty cycle should be set first before GPIO is enabled as PWM HS or PWM LS. */ + {SBC_PWM_CTRL, CTRL_PWM_CTRL}, + {SBC_GPIO_CTRL, CTRL_GPIO_CTRL}, + {SBC_HW_CTRL_1, CTRL_HW_CTRL_1}, /* May lock configuration (CFG_LOCK_0) */ + {SBC_HW_CTRL_2, CTRL_HW_CTRL_2}, /* May lock configuration (CFG_LOCK_1) */ + {SBC_BUS_CTRL_0, CTRL_BUS_CTRL_0}, + + /* -------------------------- SELECTIVE WAKE REGISTERS --------------------------- */ + + /* Configuring CDR */ + {SBC_SWK_CDR_CTRL2, CTRL_SWK_CDR_CTRL2}, + {SBC_SWK_BTL0_CTRL, CTRL_SWK_BTL0_CTRL}, + {SBC_SWK_CDR_LIMIT_HIGH_CTRL, CTRL_SWK_CDR_LIMIT_HIGH_CTRL}, + {SBC_SWK_CDR_LIMIT_LOW_CTRL, CTRL_SWK_CDR_LIMIT_LOW_CTRL}, + {SBC_SWK_CDR_CTRL1, (SBC_SEL_FILT_TC16 << SBC_SWK_CDR_CTRL1_SEL_FILT_Pos) | (SBC_CDR_EN_ENABLED << SBC_SWK_CDR_CTRL1_CDR_EN_Pos)}, + + + /* Set ID */ + {SBC_SWK_ID3_CTRL, SWK_ID3_CTRL}, + {SBC_SWK_ID2_CTRL, SWK_ID2_CTRL}, + {SBC_SWK_ID1_CTRL, SWK_ID1_CTRL}, + {SBC_SWK_ID0_CTRL, SWK_ID0_CTRL}, + + /* Set Mask */ + {SBC_SWK_MASK_ID3_CTRL, SWK_MASK_ID3_CTRL}, + {SBC_SWK_MASK_ID2_CTRL, SWK_MASK_ID2_CTRL}, + {SBC_SWK_MASK_ID1_CTRL, SWK_MASK_ID1_CTRL}, + {SBC_SWK_MASK_ID0_CTRL, SWK_MASK_ID0_CTRL}, + + /* Set Data */ + {SBC_SWK_DATA7_CTRL, (uint8_t)(CTRL_SWK_DATA_H_CTRL >> 24)}, + {SBC_SWK_DATA6_CTRL, (uint8_t)(CTRL_SWK_DATA_H_CTRL >> 16)}, + {SBC_SWK_DATA5_CTRL, (uint8_t)(CTRL_SWK_DATA_H_CTRL >> 8)}, + {SBC_SWK_DATA4_CTRL, (uint8_t)(CTRL_SWK_DATA_H_CTRL >> 0)}, + {SBC_SWK_DATA3_CTRL, (uint8_t)(CTRL_SWK_DATA_L_CTRL >> 24)}, + {SBC_SWK_DATA2_CTRL, (uint8_t)(CTRL_SWK_DATA_L_CTRL >> 16)}, + {SBC_SWK_DATA1_CTRL, (uint8_t)(CTRL_SWK_DATA_L_CTRL >> 8)}, + {SBC_SWK_DATA0_CTRL, (uint8_t)(CTRL_SWK_DATA_L_CTRL >> 0)}, + + /* Set DLC */ + {SBC_SWK_DLC_CTRL, CTRL_SWK_DLC_CTRL}, + + {SBC_SWK_CAN_FD_CTRL, SWK_CAN_FD_CTRL}, + + /* End Configuration */ + {0x00U, 0x00U} + }; + + /* Call SPI Init */ + if(SBC_SPI_INIT() != 0) { + errCode.SBC_Register = 0x00; + errCode.flippedBitsMask = 0xFF; + errCode.expectedValue = 0x00; + return errCode; + }; + + uint8_t i = 0; + + /* Write all initialization items to Lite SBC */ + while(initSequence[i][0] != 0x00U || initSequence[i][1] != 0x00U) { + errCode = SBC_Write_Reg(initSequence[i][0], initSequence[i][1], NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + i++; + } + + errCode.SBC_Register = 0x00; + errCode.flippedBitsMask = 0x00; + errCode.expectedValue = 0x00; + return errCode; +} + + + +/* -------------------------------- ISR Functions -------------------------------- */ + + +void SBC_Register_Callback(uint32_t ISR_Vector, void (*Callback_Handler)(uint8_t callbackHandler)) { + /* Save callback */ + SBC_ISR_Callbacks[SBC_RegisteredCallbacks] = Callback_Handler; + + /* Save callback vector */ + SBC_ISR_Vectors[SBC_RegisteredCallbacks] = ISR_Vector; + + /* Check if the register will be readout already to avoid double-readout later */ + uint8_t RegFound = 0; + for (uint8_t i = 0; i < SBC_RegisteredRedoutRegs; i++) { + if (SBC_ISR_ReadOutRegs[i] == (ISR_Vector >> 24)) { + RegFound = 1; + } + } + + /* If readout status-reg was not found, register in the readout list */ + if (RegFound == 0) { + SBC_ISR_ReadOutRegs[SBC_RegisteredRedoutRegs] = (uint8_t)(ISR_Vector >> 24); + SBC_RegisteredRedoutRegs++; + } + + SBC_RegisteredCallbacks++; +} + + +SBC_ErrorCode SBC_ISR(void) { + SBC_ErrorCode errCode; + + /* Readout all registered status-registers */ + for (uint8_t i = 0; i < SBC_RegisteredRedoutRegs; i++) { + SBC_ISR_ReadOutVals[i] = (uint8_t) SBC_Read_Command(SBC_ISR_ReadOutRegs[i]); + } + + /* Handle all interrupts */ + for (uint8_t i = 0; i < SBC_RegisteredCallbacks; i++) { + /* Decode ISR Vector */ + uint8_t Compare = (uint8_t)SBC_ISR_Vectors[i]; + uint8_t FieldPos = (uint8_t)(SBC_ISR_Vectors[i] >> 8); + uint8_t FieldMsk = (uint8_t)(SBC_ISR_Vectors[i] >> 16); + uint8_t RegAddr = (uint8_t)(SBC_ISR_Vectors[i] >> 24); + + /* Readback of associated status-bit */ + uint8_t ReadBack = 0; + for (uint8_t j = 0; j < SBC_RegisteredRedoutRegs; j++) { + if (SBC_ISR_ReadOutRegs[j] == RegAddr) { + ReadBack = SBC_ISR_ReadOutVals[j]; + break; + } + } + + /* If compare-values matched -> proceed callback and clear field */ + if (((ReadBack & FieldMsk) >> FieldPos) == Compare) { + SBC_ISR_Callbacks[i](ReadBack); + } + } + + /* Clear all ISR related registers */ + for (uint8_t i = 0; i < SBC_RegisteredRedoutRegs; i++) { + errCode = SBC_Write_Reg(SBC_ISR_ReadOutRegs[i], 0x00U, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + } + + errCode.SBC_Register = 0x00U; + errCode.flippedBitsMask = 0x00U; + errCode.expectedValue = 0x00U; + return errCode; +} + + + +/* -------------------------------- API Calls ----------------------------------- */ + +SBC_ErrorCode SBC_Mode_Normal(void) { + return SBC_Write_RegField(SBC_M_S_CTRL, SBC_M_S_CTRL_MODE_Msk, SBC_M_S_CTRL_MODE_Pos, SBC_MODE_NORMAL, NULL); +} + + +SBC_ErrorCode SBC_Mode_Stop(void) { + return SBC_Write_RegField(SBC_M_S_CTRL, SBC_M_S_CTRL_MODE_Msk, SBC_M_S_CTRL_MODE_Pos, SBC_MODE_STOP, NULL); +} + + +SBC_ErrorCode SBC_Mode_Sleep(void) { + uint8_t registerReadOut; + + SBC_ErrorCode errCode; + + /* If CAN PN is configured */ + if(MATH_EN_PN != 0) { + + /* Reading value of SWK_STAT. */ + registerReadOut = (uint8_t)SBC_Read_Command(SBC_SWK_STAT); + + /* CAN Protocol Handler in sync? The selective wake routine should be aborted if sync is not set. Note: for SYNC to be set the transceiver must have been in Normal Mode and a valid CAN communication must have been sent on the bus by any node. */ + if((registerReadOut & SBC_SWK_STAT_SYNC_Msk) >> SBC_SWK_STAT_SYNC_Pos != SBC_SYNC_VALID_FRAME_RECEIVED) { + errCode.SBC_Register = SBC_SWK_STAT; + errCode.flippedBitsMask = SBC_SWK_STAT_SYNC_Msk; + errCode.expectedValue = SBC_SYNC_VALID_FRAME_RECEIVED << SBC_SWK_STAT_SYNC_Pos; + return errCode; + } + + /* Set SWK Configuration valid */ + errCode = SBC_Write_RegField(SBC_SWK_CTRL, SBC_SWK_CTRL_CFG_VAL_Msk, SBC_SWK_CTRL_CFG_VAL_Pos, SBC_CFG_VAL_VALID, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + + + /* Clear SYSERR bit */ + errCode = SBC_Write_RegField(SBC_BUS_STAT, SBC_BUS_STAT_SYSERR_Msk, SBC_BUS_STAT_SYSERR_Pos, 0x00, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + + /* Set CAN Mode to off and once again to desired configuration */ + errCode = SBC_Write_Reg(SBC_BUS_CTRL_0, 0x03, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + + errCode = SBC_Write_Reg(SBC_BUS_CTRL_0, CTRL_BUS_CTRL_0, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + + /* Check SWK_STAT for SYNC == 1 && SWK_SET == 1 && WUF == 0 && WUP == 0. Ignore CANSIL */ + registerReadOut = (uint8_t)SBC_Read_Command(SBC_SWK_STAT); + if( ((SBC_SWK_STAT_SYNC_Msk & registerReadOut) == SBC_SWK_STAT_SYNC_Msk) + && ((SBC_SWK_STAT_SWK_SET_Msk & registerReadOut) == SBC_SWK_STAT_SWK_SET_Msk) + && ((SBC_SWK_STAT_WUP_Msk & registerReadOut) != SBC_SWK_STAT_WUP_Msk) + && ((SBC_SWK_STAT_WUF_Msk & registerReadOut) != SBC_SWK_STAT_WUF_Msk)) { + /* Empty */ + } else { + errCode.SBC_Register = SBC_SWK_STAT; + errCode.expectedValue = 0b01000100U; + errCode.flippedBitsMask = errCode.expectedValue ^ registerReadOut; + return errCode; + } + + + + } + + + + /* Clear Wake Status Registers, so that SBC can sleep. */ + errCode = SBC_Write_Reg(SBC_WK_STAT_0, 0x00, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + errCode = SBC_Write_Reg(SBC_WK_STAT_1, 0x00, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + + /* Select sleep mode */ + (void)SBC_Write_RegField(SBC_M_S_CTRL, SBC_M_S_CTRL_MODE_Msk, SBC_M_S_CTRL_MODE_Pos, SBC_MODE_SLEEP, NULL); + registerReadOut = (uint8_t)SBC_Read_Command(SBC_M_S_CTRL); + + /* This piece of code is ideally never reached as the microcontroller should be already turned off then */ + if(registerReadOut != 0) { + errCode.SBC_Register = SBC_M_S_CTRL; + errCode.flippedBitsMask = registerReadOut; + errCode.expectedValue = 0x00U; + return errCode; + } + + errCode.SBC_Register = 0x00U; + errCode.flippedBitsMask = 0x00U; + errCode.expectedValue = 0x00U; + return errCode; +} + + +SBC_ErrorCode SBC_Set_DutyCycle_PWM (uint8_t PWM_DC) { + return SBC_Write_Reg(SBC_PWM_CTRL, PWM_DC, NULL); +} + + +SBC_ErrorCode SBC_Set_Timer_On (uint8_t OnTime) { + return SBC_Write_RegField(SBC_TIMER_CTRL, SBC_TIMER_CTRL_TIMER_ON_Msk, SBC_TIMER_CTRL_TIMER_ON_Pos, OnTime, NULL); +} + + +SBC_ErrorCode SBC_Set_Timer_Period (uint8_t Period) { + return SBC_Write_RegField(SBC_TIMER_CTRL, SBC_TIMER_CTRL_TIMER_PER_Msk, SBC_TIMER_CTRL_TIMER_PER_Pos, Period, NULL); +} + + +SBC_ErrorCode SBC_FO_Test_On(void) { + return SBC_Write_RegField(SBC_HW_CTRL_0, SBC_HW_CTRL_0_FO_ON_Msk, SBC_HW_CTRL_0_FO_ON_Pos, SBC_FO_ON_ACTIVE, NULL); +} + + +SBC_ErrorCode SBC_FO_Test_Off(void) { + return SBC_Write_RegField(SBC_HW_CTRL_0, SBC_HW_CTRL_0_FO_ON_Msk, SBC_HW_CTRL_0_FO_ON_Pos, SBC_FO_ON_NOT_ACTIVE, NULL); +} + + +SBC_ErrorCode SBC_CP_On(void) { + return SBC_Write_RegField(SBC_HW_CTRL_0, SBC_HW_CTRL_0_CP_EN_Msk, SBC_HW_CTRL_0_CP_EN_Pos, SBC_CP_EN_ON, NULL); +} + + +SBC_ErrorCode SBC_CP_Off(void) { + return SBC_Write_RegField(SBC_HW_CTRL_0, SBC_HW_CTRL_0_CP_EN_Msk, SBC_HW_CTRL_0_CP_EN_Pos, SBC_CP_EN_OFF, NULL); +} + + +SBC_ErrorCode SBC_WK_MEAS_On(void) { + return SBC_Write_RegField(SBC_WK_CTRL_1, SBC_WK_CTRL_1_WK_MEAS_Msk, SBC_WK_CTRL_1_WK_MEAS_Pos, SBC_WK_MEAS_WK_AS_VOLTAGESENSING, NULL); +} + + +SBC_ErrorCode SBC_WK_MEAS_Off(void) { + return SBC_Write_RegField(SBC_WK_CTRL_1, SBC_WK_CTRL_1_WK_MEAS_Msk, SBC_WK_CTRL_1_WK_MEAS_Pos, SBC_WK_MEAS_WK_AS_WAKEUP, NULL); +} + + +SBC_ErrorCode SBC_TIMER_WK_EN_On(void) { + return SBC_Write_RegField(SBC_WK_CTRL_0, SBC_WK_CTRL_0_TIMER_WK_EN_Msk, SBC_WK_CTRL_0_TIMER_WK_EN_Pos, WK_CTRL_0_TIMER_WK_EN_WAKESOURCE, NULL); +} + + +SBC_ErrorCode SBC_TIMER_WK_EN_Off(void) { + return SBC_Write_RegField(SBC_WK_CTRL_0, SBC_WK_CTRL_0_TIMER_WK_EN_Msk, SBC_WK_CTRL_0_TIMER_WK_EN_Pos, WK_CTRL_0_TIMER_WK_EN_WAKEUP_DISABLED, NULL); +} + + +uint16_t SBC_SYS_STAT_Read(void) { + uint16_t systemStatus = 0; + uint16_t returndata = SBC_Read_Command(SBC_SYS_STATUS_CTRL_0); + systemStatus = returndata & 0x00FFU; + systemStatus |= SBC_Read_Command(SBC_SYS_STATUS_CTRL_1) << 8; + return systemStatus; +} + + +SBC_ErrorCode SBC_SYS_STAT_Write(uint16_t SystemStatus) { + SBC_ErrorCode errCode; + + /* Write lower bits */ + errCode = SBC_Write_Reg(SBC_SYS_STATUS_CTRL_0, (uint8_t)SystemStatus, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + + /* Write higher bits */ + return SBC_Write_Reg(SBC_SYS_STATUS_CTRL_1, (uint8_t)(SystemStatus >> 8), NULL); +} + + +SBC_ErrorCode SBC_Lock_Configuration(void) { + SBC_ErrorCode errCode; + + /* Lock CP_EN and GPIO cannot be modified */ + errCode = SBC_Write_RegField(SBC_HW_CTRL_1, SBC_HW_CTRL_1_CFG_LOCK_0_Msk, SBC_HW_CTRL_1_CFG_LOCK_0_Pos, SBC_CFG_LOCK_0_LOCKED, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + + /* Lock Bits with bit type ‘rwl’ (except CP_EN and GPIO) until next device power-up. */ + errCode = SBC_Write_RegField(SBC_HW_CTRL_2, SBC_HW_CTRL_2_CFG_LOCK_1_Msk, SBC_HW_CTRL_2_CFG_LOCK_1_Pos, SBC_CFG_LOCK_1_LOCKED, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + + errCode.SBC_Register = 0x00; + errCode.flippedBitsMask = 0x00; + errCode.expectedValue = 0x00; + return errCode; +} + + +SBC_ErrorCode SBC_Unlock_Configuration(void) { + SBC_ErrorCode errCode; + + /* Unlock CP_EN and GPIO configuration. */ + errCode = SBC_Write_RegField(SBC_HW_CTRL_1, SBC_HW_CTRL_1_CFG_LOCK_0_Msk, SBC_HW_CTRL_1_CFG_LOCK_0_Pos, SBC_CFG_LOCK_0_NOTLOCKED, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + + /* Unlock Bits with bit type ‘rwl’ (except CP_EN and GPIO). */ + errCode = SBC_Write_RegField(SBC_HW_CTRL_2, SBC_HW_CTRL_2_CFG_LOCK_1_Msk, SBC_HW_CTRL_2_CFG_LOCK_1_Pos, SBC_CFG_LOCK_1_NOTLOCKED, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + + errCode.SBC_Register = 0x00; + errCode.flippedBitsMask = 0x00; + errCode.expectedValue = 0x00; + return errCode; +} + +SBC_ErrorCode SBC_Clear_Wake_Status(void) { + SBC_ErrorCode errCode = SBC_Write_Reg(SBC_WK_STAT_0, 0x00, NULL); + if(errCode.flippedBitsMask != 0) { + return errCode; + } + errCode = SBC_Write_Reg(SBC_WK_STAT_1, 0x00, NULL); + if(errCode.flippedBitsMask != 0) { + return errCode; + } + errCode.SBC_Register = 0x00; + errCode.flippedBitsMask = 0x00; + errCode.expectedValue = 0x00; + return errCode; +} diff --git a/cva_asw_m0118/src/TLE9461/TLE94x1.h b/cva_asw_m0118/src/TLE9461/TLE94x1.h new file mode 100644 index 0000000..a434389 --- /dev/null +++ b/cva_asw_m0118/src/TLE9461/TLE94x1.h @@ -0,0 +1,393 @@ +/********************************************************************************************************************* + * Copyright (c) 2019, Infineon Technologies AG + * + * + * Distributed under the Boost Software License, Version 1.0. + * + * + * Boost Software License - Version 1.0 - August 17th, 2003 + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *********************************************************************************************************************/ + + +/****************************************************************************************************//** + * @file TLE94x1.h + * + * @brief Main header declaration file for TLE94x1 SBC family device + * + * @version V1.0.0 + * @date 15. April 2019 + * @author Markus Noll / markus.noll@infineon.com + * @author Yannek Micha Rixen / Yannek.Rixen@infineon.com + *******************************************************************************************************/ + + + + +#ifndef TLE94x1_H +#define TLE94x1_H + + + + + + +/* ================================================================================ */ +/* ============================ HEADER FILES ================================ */ +/* ================================================================================ */ + + + +#include "TLE94x1_DEFINES.h" +#include "TLE94x1_ISR.h" +#include "TLE94x1_SPI.h" +#include + + + + +/* ================================================================================ */ +/* ================================ MACROS ================================== */ +/* ================================================================================ */ + + +/** + * @def SBC_Write_Bit + * + * @brief This bit has to be set in order to write to a register. + */ +#define SBC_Write_Bit (0x80U) + +/** + * @def SBC_Read_Mask + * + * @brief A mask to prevent the user from accidentally writing to a register. + */ +#define SBC_Read_Mask (0x7FU) + + + + +/* ================================================================================ */ +/* =========================== Library Functions ============================ */ +/* ================================================================================ */ + +struct __SBC_ErrorCode; + +/** + * @brief A structure for simple error readout. + * + * flippedBitsMask is greater than 0 if the value read from the register at SBC_Register differs from expectedValue. + */ +typedef struct __SBC_ErrorCode { + uint8_t SBC_Register; //!< The register where an error occurred. + uint8_t flippedBitsMask; //!< Masks the bits that differ from the expected value. Is 0 if readout is as expected. + uint8_t expectedValue; //!< Expected readout of the register. +} SBC_ErrorCode; + +/** + * @brief Typedef for interrupt callbacks. + */ +typedef void (*SBC_Func_Callback)(uint8_t callbackHandler); + + + + + + +/* -------------------------------- Main Functions ------------------------------- */ + + +/** + * @brief This method will trigger the watchdog. + * + * The function must be called periodically according to the configured watchdog-time. + */ +SBC_ErrorCode SBC_WD_Trigger(void); + + +/** + * @brief This method will proceed a readout of a register. + * + * @param SBC_Reg Address of the register to be read out. See TLE94x1_DEFINES.h for definitions + * @retval A 16 bit value will be returned. + * Bit[15:8] is the Status-Information-Field, Bit [7:0] is the read register-value. + * For furhter information of the Status-Information-Field see chapter 13.3 in the datasheet. + */ +uint16_t SBC_Read_Command(uint8_t SBC_Reg); + + +/** + * @brief This method will proceed a readout of a dedicated bitfield within a register + * + * @param SBC_Reg Address of the register to be readout. See TLE94x1_DEFINES.h for definitions + * @param SBC_FieldMsk Bit mask of the field to be readout. See TLE94x1_DEFINES.h for definitions + * @param SBC_FieldPos Bit position of the field to be readout. See TLE94x1_DEFINES.h for definitions + * + * + * @retval A 8 bit value will be returned and includes the data of the bitfield to be read out * + */ +uint8_t SBC_Read_RegField(uint8_t SBC_Reg, uint8_t SBC_FieldMsk, uint8_t SBC_FieldPos); + + + +/** + * @brief Writes a whole byte to a register and verifies it. + * + * @param SBC_Reg Address of the register to be manipulated. See TLE94x1_DEFINES.h for definitions + * @param SBC_Val Byte to write to SBC_Reg + * @param *returnval A 16 bit value will be returned. + * Bit[15:8] is the Status-Information-Field, Bit [7:0] is the value of the manipulated register before write + * For furhter information of the Status-Information-Field see chapter 13.3 in the datasheet. + * + * @retval See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Write_Reg(uint8_t SBC_Reg, uint8_t SBC_Val, uint16_t * returnval); + + +/** + * @brief This method can be used for manipulating a single bit-field in a control-register. + * + * It will readout the old value of the registers, manipulate the desired bit-field and keep + * the other bit-configuration as it was. + * For usage examples have a look at the implementations of different API calls below. + * + * @param SBC_Reg Address of the register to be manipulated. See TLE94x1_DEFINES.h for definitions + * @param SBC_FieldMsk Bit mask of the field to manipulate. See TLE94x1_DEFINES.h for definitions + * @param SBC_FieldPos Bit position of the field to manipulate. See TLE94x1_DEFINES.h for definitions + * @param SBC_FieldVal New value which will be written to the bit-field. See TLE94x1_DEFINES.h for enumerations + * @param *returnval A 16 bit value will be returned. + * Bit[15:8] is the Status-Information-Field, Bit [7:0] is the value of the manipulated register before write + * For furhter information of the Status-Information-Field see chapter 13.3 in the datasheet. + * + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + * + */ +SBC_ErrorCode SBC_Write_RegField(uint8_t SBC_Reg, uint8_t SBC_FieldMsk, uint8_t SBC_FieldPos, uint8_t SBC_FieldVal, uint16_t * returnval); + + +/** + * @brief This method must be called one time at startup of the microcontroller. + * + * This method will initialize all registers of the SBC with the configuration-data of SBC_TLE94x1.h. + * After this, the SBC can be used as normal. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Init(void); + +/* -------------------------------- ISR Functions -------------------------------- */ + + +/** + * @brief This function can register a self-defined function to a specific interrupt-event of the SBC. + * + * Everytime the SBC_ISR() method is called and the associated status-bit is set, it will consider to + * proceed a callback to this function later. + * See all the possible ISR_Vectors in the TLE94x1_ISR.h + * + * + * @param ISR_Vector Definition of the interrupt event. See all possible events in TLE94x1_ISR.h + * + * @param *Callback_Handler Pointer to the function which will be called back. + * The function must accept a uint8_t as first argument. + */ +void SBC_Register_Callback(uint32_t ISR_Vector, void (*Callback_Handler)(uint8_t callbackHandler)); + + +/** + * @brief Interrupt Service Routine for handling interrupts. + * + * This method must be called automatically everytime a rising-edge on the INTN pin is recognized. + * In case, the INTN pin is not connected, this method can also be called periodically by the user during runtime. + * The ISR will proceed a readout of all registered interrupts. If a status-bit of a registered interrupt is set, + * it will initiate a callback to the registered function and give the registered function the status-register value + * as a parameter. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_ISR(void); + + + +/* -------------------------------- API Calls ----------------------------------- */ + +/** + * @brief Enters SBC normal mode + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Mode_Normal(void); + + +/** + * @brief Enters SBC stop mode + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Mode_Stop(void); + + +/** + * @brief Clears all wake status registers and enter SBC sleep mode. Depending on configuration also the selective-wake feature will be initialized + * before entering sleep mode. In case, the SWK option is enabled and the internal CAN protocol handler is not in sync when calling this function, + * the sleep mode will be not entered. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Mode_Sleep(void); + + +/** + * @brief Sets the duty-cycle of the internal PWM generator + * + * @param PWM_DC Set the duty-cycle with values of 0-255 for 0% to 100% + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Set_DutyCycle_PWM(uint8_t PWM_DC); + + +/** + * @brief Sets the OnTime of the internal timer. + * + * @param OnTime On time which will be configured to the timer. See TLE94x1_DEFINES.h for enumerations. + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Set_Timer_On(uint8_t OnTime); + +/** + * @brief Sets the Period time of the internal timer + * + * @param Period Period time which will be configured to the timer. See TLE94x1_DEFINES.h for enumerations. + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Set_Timer_Period(uint8_t Period); + + +/** + * @brief FO output activated by software for testing. Only working if FO/GPIO is configured as FO + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_FO_Test_On(void); + + +/** + * @brief FO output deactivated by software for testing. Only working if FO/GPIO is configured as FO + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_FO_Test_Off(void); + + +/** + * @brief Charge-Pump (VCP-Pin) is enabled. See chapter 5.3 in datasheet. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_CP_On(void); + + +/** + * @brief Charge-Pump (VCP-Pin) is disabled. See chapter 5.3 in datasheet. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_CP_Off(void); + + +/** + * @brief Enable Voltage Sensing. No wake-up events are generated. See chapter 9.2.4 in datasheet. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_WK_MEAS_On(void); + + +/** + * @brief Disable Voltage Sensing and enable wake-up functionality. See chapter 9.2.4 in datasheet. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_WK_MEAS_Off(void); + + +/** + * @brief WK is enabled as wake source. See chapter 5.2. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_TIMER_WK_EN_On(void); + + +/** + * @brief WK wake-up disabled. See chapter 5.2. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_TIMER_WK_EN_Off(void); + + +/** + * @brief Reads System Status Control, both lower and higher bits. See page 138 in datasheet. + * + * @retval Upper 8 bit are read from register SBC_SYS_STATUS_CTRL_1 and the lower 8 bit from SBC_SYS_STATUS_CTRL_0 + */ +uint16_t SBC_SYS_STAT_Read(void); + + +/** + * @brief Writes System Status Control, both lower and higher bits. See page 138 in datasheet. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_SYS_STAT_Write(uint16_t SystemStatus); + + +/** + * @brief Locks CP_EN, GPIO configuration and 'rwl'-bits. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Lock_Configuration(void); + + +/** + * @brief Unlocks CP_EN, GPIO configuration and 'rwl'-bits. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Unlock_Configuration(void); + + +/** + * @brief Clears both Wake Status registers. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Clear_Wake_Status(void); + +#endif /*TLE94x1_H*/ diff --git a/cva_asw_m0118/src/TLE9461/TLE94x1_DEFINES.h b/cva_asw_m0118/src/TLE9461/TLE94x1_DEFINES.h new file mode 100644 index 0000000..57d8ab2 --- /dev/null +++ b/cva_asw_m0118/src/TLE9461/TLE94x1_DEFINES.h @@ -0,0 +1,3248 @@ +/********************************************************************************************************************* + * Copyright (c) 2019, Infineon Technologies AG + * + * + * Distributed under the Boost Software License, Version 1.0. + * + * + * Boost Software License - Version 1.0 - August 17th, 2003 + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *********************************************************************************************************************/ + + +/****************************************************************************************************//** + * @file TLE94x1_DEFINES.h + * + * @brief Main header declaration file for TLE94x1 SBC family device + * + * @version V1.0.0 + * @date 15. April 2019 + * @author Markus Noll / markus.noll@infineon.com + * @author Yannek Micha Rixen / Yannek.Rixen@infineon.com + *******************************************************************************************************/ + + + +#ifndef TLE94x1_DEFINES_H +#define TLE94x1_DEFINES_H + + + + + + +/* ================================================================================ */ +/* ================ General Control Registers ================ */ +/* ================================================================================ */ + + + +/** + * @def SBC_M_S_CTRL + * + * @brief Control register address. + */ +#define SBC_M_S_CTRL (0b00000001U) + +/** + * @def SBC_HW_CTRL_0 + * + * @brief Control register address. + */ +#define SBC_HW_CTRL_0 (0b00000010U) + +/** + * @def SBC_WD_CTRL + * + * @brief Control register address. + */ +#define SBC_WD_CTRL (0b00000011U) + +/** + * @def SBC_BUS_CTRL_0 + * + * @brief Control register address. + */ +#define SBC_BUS_CTRL_0 (0b00000100U) + +/** + * @def SBC_WK_CTRL_0 + * + * @brief Control register address. + */ +#define SBC_WK_CTRL_0 (0b00000110U) + +/** + * @def SBC_WK_CTRL_1 + * + * @brief Control register address. + */ +#define SBC_WK_CTRL_1 (0b00000111U) + +/** + * @def SBC_WK_PUPD_CTRL + * + * @brief Control register address. + */ +#define SBC_WK_PUPD_CTRL (0b00001000U) + +/** + * @def SBC_BUS_CTRL_3 + * + * @brief Control register address. + */ +#define SBC_BUS_CTRL_3 (0b00001011U) + +/** + * @def SBC_TIMER_CTRL + * + * @brief Control register address. + */ +#define SBC_TIMER_CTRL (0b00001100U) + +/** + * @def SBC_HW_CTRL_1 + * + * @brief Control register address. + */ +#define SBC_HW_CTRL_1 (0b00001110U) + +/** + * @def SBC_HW_CTRL_2 + * + * @brief Control register address. + */ +#define SBC_HW_CTRL_2 (0b00001111U) + +/** + * @def SBC_GPIO_CTRL + * + * @brief Control register address. + */ +#define SBC_GPIO_CTRL (0b00010111U) + +/** + * @def SBC_PWM_CTRL + * + * @brief Control register address. + */ +#define SBC_PWM_CTRL (0b00011000U) + +/** + * @def SBC_PWM_FREQ_CTRL + * + * @brief Control register address. + */ +#define SBC_PWM_FREQ_CTRL (0b00011100U) + +/** + * @def SBC_HW_CTRL_3 + * + * @brief Control register address. + */ +#define SBC_HW_CTRL_3 (0b00011101U) + +/** + * @def SBC_SYS_STATUS_CTRL_0 + * + * @brief Control register address. + */ +#define SBC_SYS_STATUS_CTRL_0 (0b00011110U) + +/** + * @def SBC_SYS_STATUS_CTRL_1 + * + * @brief Control register address. + */ +#define SBC_SYS_STATUS_CTRL_1 (0b00011111U) + + + + + + +/* ================================================================================ */ +/* ================ Selective Wake Control Registers ================ */ +/* ================================================================================ */ + + + +/** + * @def SBC_SWK_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_CTRL (0b00100000U) + +/** + * @def SBC_SWK_BTL0_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_BTL0_CTRL (0b00100001U) + +/** + * @def SBC_SWK_BTL1_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_BTL1_CTRL (0b00100010U) + +/** + * @def SBC_SWK_ID3_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_ID3_CTRL (0b00100011U) + +/** + * @def SBC_SWK_ID2_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_ID2_CTRL (0b00100100U) + +/** + * @def SBC_SWK_ID1_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_ID1_CTRL (0b00100101U) + +/** + * @def SBC_SWK_ID0_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_ID0_CTRL (0b00100110U) + +/** + * @def SBC_SWK_MASK_ID3_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_MASK_ID3_CTRL (0b00100111U) + +/** + * @def SBC_SWK_MASK_ID2_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_MASK_ID2_CTRL (0b00101000U) + +/** + * @def SBC_SWK_MASK_ID1_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_MASK_ID1_CTRL (0b00101001U) + +/** + * @def SBC_SWK_MASK_ID0_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_MASK_ID0_CTRL (0b00101010U) + +/** + * @def SBC_SWK_DLC_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_DLC_CTRL (0b00101011U) + +/** + * @def SBC_SWK_DATA7_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_DATA7_CTRL (0b00101100U) + +/** + * @def SBC_SWK_DATA6_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_DATA6_CTRL (0b00101101U) + +/** + * @def SBC_SWK_DATA5_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_DATA5_CTRL (0b00101110U) + +/** + * @def SBC_SWK_DATA4_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_DATA4_CTRL (0b00101111U) + +/** + * @def SBC_SWK_DATA3_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_DATA3_CTRL (0b00110000U) + +/** + * @def SBC_SWK_DATA2_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_DATA2_CTRL (0b00110001U) + +/** + * @def SBC_SWK_DATA1_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_DATA1_CTRL (0b00110010U) + +/** + * @def SBC_SWK_DATA0_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_DATA0_CTRL (0b00110011U) + +/** + * @def SBC_SWK_CAN_FD_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_CAN_FD_CTRL (0b00110100U) + +/** + * @def SBC_SWK_OSC_TRIM_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_OSC_TRIM_CTRL (0b00111000U) + +/** + * @def SBC_SWK_OPT_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_OPT_CTRL (0b00111001U) + +/** + * @def SBC_SWK_OSC_CAL_H_STAT + * + * @brief Selective wake register address. + */ +#define SBC_SWK_OSC_CAL_H_STAT (0b00111010U) + +/** + * @def SBC_SWK_OSC_CAL_L_STAT + * + * @brief Selective wake register address. + */ +#define SBC_SWK_OSC_CAL_L_STAT (0b00111011U) + +/** + * @def SBC_SWK_CDR_CTRL1 + * + * @brief Selective wake register address. + */ +#define SBC_SWK_CDR_CTRL1 (0b00111100U) + +/** + * @def SBC_SWK_CDR_CTRL2 + * + * @brief Selective wake register address. + */ +#define SBC_SWK_CDR_CTRL2 (0b00111101U) + +/** + * @def SBC_SWK_CDR_LIMIT_HIGH_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_CDR_LIMIT_HIGH_CTRL (0b00111110U) + +/** + * @def SBC_SWK_CDR_LIMIT_LOW_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_CDR_LIMIT_LOW_CTRL (0b00111111U) + + + + + + +/* ================================================================================ */ +/* ================ General Status Registers ================ */ +/* ================================================================================ */ + + + + +/** + * @def SBC_SUP_STAT_1 + * + * @brief Status register address. + */ +#define SBC_SUP_STAT_1 (0b01000000U) + +/** + * @def SBC_SUP_STAT_0 + * + * @brief Status register address. + */ +#define SBC_SUP_STAT_0 (0b01000001U) + +/** + * @def SBC_THERM_STAT + * + * @brief Status register address. + */ +#define SBC_THERM_STAT (0b01000010U) + +/** + * @def SBC_DEV_STAT + * + * @brief Status register address. + */ +#define SBC_DEV_STAT (0b01000011U) + +/** + * @def SBC_BUS_STAT + * + * @brief Status register address. + */ +#define SBC_BUS_STAT (0b01000100U) + +/** + * @def SBC_WK_STAT_0 + * + * @brief Status register address. + */ +#define SBC_WK_STAT_0 (0b01000110U) + +/** + * @def SBC_WK_STAT_1 + * + * @brief Status register address. + */ +#define SBC_WK_STAT_1 (0b01000111U) + +/** + * @def SBC_WK_LVL_STAT + * + * @brief Status register address. + */ +#define SBC_WK_LVL_STAT (0b01001000U) + +/** + * @def SBC_GPIO_OC_STAT + * + * @brief Status register address. + */ +#define SBC_GPIO_OC_STAT (0b01010100U) + +/** + * @def SBC_GPIO_OL_STAT + * + * @brief Status register address. + */ +#define SBC_GPIO_OL_STAT (0b01010101U) + + + + + + +/* ================================================================================ */ +/* ================ Selective Wake Status Registers ================ */ +/* ================================================================================ */ + + + + +/** + * @def SBC_SWK_STAT + * + * @brief Selective wake status register address. + */ +#define SBC_SWK_STAT (0b01110000U) + +/** + * @def SBC_SWK_ECNT_STAT + * + * @brief Selective wake status register address. + */ +#define SBC_SWK_ECNT_STAT (0b01110001U) + +/** + * @def SBC_SWK_CDR_STAT1 + * + * @brief Selective wake status register address. + */ +#define SBC_SWK_CDR_STAT1 (0b01110010U) + +/** + * @def SBC_SWK_CDR_STAT2 + * + * @brief Selective wake status register address. + */ +#define SBC_SWK_CDR_STAT2 (0b01110011U) + +/** + * @def SBC_FAM_PROD_STAT + * + * @brief Selective wake status register address. + */ +#define SBC_FAM_PROD_STAT (0b01111110U) + + + + + + +/* ================================================================================ */ +/* ============ General Control Registers Position & Mask ================ */ +/* ================================================================================ */ + + + +/* -------------------------------- M_S_CTRL ------------------------------------ */ + +/** + * @def SBC_M_S_CTRL_MODE_Pos + * + * @brief Control register bit position. + */ +#define SBC_M_S_CTRL_MODE_Pos (6U) +/** + * @def SBC_M_S_CTRL_MODE_Msk + * + * @brief Control register bit mask. + */ +#define SBC_M_S_CTRL_MODE_Msk (0b11000000U) +/** + * @def SBC_M_S_CTRL_VCC2_ON_Pos + * + * @brief Control register bit position. + */ +#define SBC_M_S_CTRL_VCC2_ON_Pos (3U) +/** + * @def SBC_M_S_CTRL_VCC2_ON_Msk + * + * @brief Control register bit mask. + */ +#define SBC_M_S_CTRL_VCC2_ON_Msk (0b00011000U) +/** + * @def SBC_M_S_CTRL_VCC1_OV_RST_Pos + * + * @brief Control register bit position. + */ +#define SBC_M_S_CTRL_VCC1_OV_RST_Pos (2U) +/** + * @def SBC_M_S_CTRL_VCC1_OV_RST_Msk + * + * @brief Control register bit mask. + */ +#define SBC_M_S_CTRL_VCC1_OV_RST_Msk (0b00000100U) +/** + * @def SBC_M_S_CTRL_VCC1_RT_Pos + * + * @brief Control register bit position. + */ +#define SBC_M_S_CTRL_VCC1_RT_Pos (0U) +/** + * @def SBC_M_S_CTRL_VCC1_RT_Msk + * + * @brief Control register bit mask. + */ +#define SBC_M_S_CTRL_VCC1_RT_Msk (0b00000011U) + + +/* -------------------------------- HW_CTRL_0 ----------------------------------- */ + + +/** + * @def SBC_HW_CTRL_0_SOFT_RESET_RST_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_0_SOFT_RESET_RST_Pos (6U) + +/** + * @def SBC_HW_CTRL_0_SOFT_RESET_RST_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_0_SOFT_RESET_RST_Msk (0b01000000U) + +/** + * @def SBC_HW_CTRL_0_FO_ON_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_0_FO_ON_Pos (5U) + +/** + * @def SBC_HW_CTRL_0_FO_ON_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_0_FO_ON_Msk (0b00100000U) + +/** + * @def SBC_HW_CTRL_0_CP_EN_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_0_CP_EN_Pos (2U) + +/** + * @def SBC_HW_CTRL_0_CP_EN_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_0_CP_EN_Msk (0b00000100U) + +/** + * @def SBC_HW_CTRL_0_CFG1_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_0_CFG1_Pos (0U) + +/** + * @def SBC_HW_CTRL_0_CFG1_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_0_CFG1_Msk (0b00000001U) + + +/* -------------------------------- WD_CTRL ----------------------------------- */ + + +/** + * @def SBC_WD_CTRL_CHECKSUM_Pos + * + * @brief Control register bit position. + */ +#define SBC_WD_CTRL_CHECKSUM_Pos (7U) + +/** + * @def SBC_WD_CTRL_CHECKSUM_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WD_CTRL_CHECKSUM_Msk (0b10000000U) + +/** + * @def SBC_WD_CTRL_WD_STM_EN_0_Pos + * + * @brief Control register bit position. + */ +#define SBC_WD_CTRL_WD_STM_EN_0_Pos (6U) + +/** + * @def SBC_WD_CTRL_WD_STM_EN_0_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WD_CTRL_WD_STM_EN_0_Msk (0b01000000U) + +/** + * @def SBC_WD_CTRL_WD_WIN_Pos + * + * @brief Control register bit position. + */ +#define SBC_WD_CTRL_WD_WIN_Pos (5U) + +/** + * @def SBC_WD_CTRL_WD_WIN_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WD_CTRL_WD_WIN_Msk (0b00100000U) + +/** + * @def SBC_WD_CTRL_WD_EN_WK_BUS_Pos + * + * @brief Control register bit position. + */ +#define SBC_WD_CTRL_WD_EN_WK_BUS_Pos (4U) + +/** + * @def SBC_WD_CTRL_WD_EN_WK_BUS_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WD_CTRL_WD_EN_WK_BUS_Msk (0b00010000U) + +/** + * @def SBC_WD_CTRL_WD_TIMER_Pos + * + * @brief Control register bit position. + */ +#define SBC_WD_CTRL_WD_TIMER_Pos (0U) + +/** + * @def SBC_WD_CTRL_WD_TIMER_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WD_CTRL_WD_TIMER_Msk (0b00000111U) + + +/* -------------------------------- BUS_CTRL_0 ---------------------------------- */ + +/** + * @def SBC_BUS_CTRL_0_CAN_Pos + * + * @brief Control register bit position. + */ +#define SBC_BUS_CTRL_0_CAN_Pos (0U) + +/** + * @def SBC_BUS_CTRL_0_CAN_Msk + * + * @brief Control register bit mask. + */ +#define SBC_BUS_CTRL_0_CAN_Msk (0b00000111U) + + +/* -------------------------------- WK_CTRL_0 ----------------------------------- */ + +/** + * @def SBC_WK_CTRL_0_TIMER_WK_EN_Pos + * + * @brief Control register bit position. + */ +#define SBC_WK_CTRL_0_TIMER_WK_EN_Pos (6U) + +/** + * @def SBC_WK_CTRL_0_TIMER_WK_EN_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WK_CTRL_0_TIMER_WK_EN_Msk (0b01000000U) + +/** + * @def SBC_WK_CTRL_0_WD_STM_EN_1_Pos + * + * @brief Control register bit position. + */ +#define SBC_WK_CTRL_0_WD_STM_EN_1_Pos (2U) + +/** + * @def SBC_WK_CTRL_0_WD_STM_EN_1_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WK_CTRL_0_WD_STM_EN_1_Msk (0b00000100U) + + +/* -------------------------------- WK_CTRL_1 ----------------------------------- */ + + +/** + * @def SBC_WK_CTRL_1_INT_GLOBAL_Pos + * + * @brief Control register bit position. + */ +#define SBC_WK_CTRL_1_INT_GLOBAL_Pos (7U) + +/** + * @def SBC_WK_CTRL_1_INT_GLOBAL_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WK_CTRL_1_INT_GLOBAL_Msk (0b10000000U) + +/** + * @def SBC_WK_CTRL_1_WK_MEAS_Pos + * + * @brief Control register bit position. + */ +#define SBC_WK_CTRL_1_WK_MEAS_Pos (5U) + +/** + * @def SBC_WK_CTRL_1_WK_MEAS_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WK_CTRL_1_WK_MEAS_Msk (0b00100000U) + +/** + * @def SBC_WK_CTRL_1_WK_EN_Pos + * + * @brief Control register bit position. + */ +#define SBC_WK_CTRL_1_WK_EN_Pos (0U) + +/** + * @def SBC_WK_CTRL_1_WK_EN_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WK_CTRL_1_WK_EN_Msk (0b00000001U) + + +/* -------------------------------- WK_PUPD_CTRL -------------------------------- */ + + +/** + * @def SBC_WK_PUPD_CTRL_GPIO_WK_PUPD_Pos + * + * @brief Control register bit position. + */ +#define SBC_WK_PUPD_CTRL_GPIO_WK_PUPD_Pos (6U) + +/** + * @def SBC_WK_PUPD_CTRL_GPIO_WK_PUPD_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WK_PUPD_CTRL_GPIO_WK_PUPD_Msk (0b11000000U) + +/** + * @def SBC_WK_PUPD_CTRL_WK_PUPD_Pos + * + * @brief Control register bit position. + */ +#define SBC_WK_PUPD_CTRL_WK_PUPD_Pos (0U) + +/** + * @def SBC_WK_PUPD_CTRL_WK_PUPD_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WK_PUPD_CTRL_WK_PUPD_Msk (0b00000011U) + + +/* ------------------------------- BUS_CTRL_3 ---------------------------------- */ + +/** + * @def SBC_BUS_CTRL_3_CAN_FLASH_Pos + * + * @brief Control register bit position. + */ +#define SBC_BUS_CTRL_3_CAN_FLASH_Pos (4U) + +/** + * @def SBC_BUS_CTRL_3_CAN_FLASH_Msk + * + * @brief Control register bit mask. + */ +#define SBC_BUS_CTRL_3_CAN_FLASH_Msk (0b00010000U) + + +/* ------------------------------- TIMER_CTRL ---------------------------------- */ + + +/** + * @def SBC_TIMER_CTRL_TIMER_ON_Pos + * + * @brief Control register bit position. + */ +#define SBC_TIMER_CTRL_TIMER_ON_Pos (4U) + +/** + * @def SBC_TIMER_CTRL_TIMER_ON_Msk + * + * @brief Control register bit mask. + */ +#define SBC_TIMER_CTRL_TIMER_ON_Msk (0b01110000U) + +/** + * @def SBC_TIMER_CTRL_TIMER_PER_Pos + * + * @brief Control register bit position. + */ +#define SBC_TIMER_CTRL_TIMER_PER_Pos (0U) + +/** + * @def SBC_TIMER_CTRL_TIMER_PER_Msk + * + * @brief Control register bit mask. + */ +#define SBC_TIMER_CTRL_TIMER_PER_Msk (0b00001111U) + + +/* -------------------------------- HW_CTRL_1 ----------------------------------- */ + + +/** + * @def SBC_HW_CTRL_1_RSTN_HYS_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_1_RSTN_HYS_Pos (7U) + +/** + * @def SBC_HW_CTRL_1_RSTN_HYS_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_1_RSTN_HYS_Msk (0b10000000U) + +/** + * @def SBC_HW_CTRL_1_TSD2_DEL_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_1_TSD2_DEL_Pos (5U) + +/** + * @def SBC_HW_CTRL_1_TSD2_DEL_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_1_TSD2_DEL_Msk (0b00100000U) + +/** + * @def SBC_HW_CTRL_1_RSTN_DEL_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_1_RSTN_DEL_Pos (4U) + +/** + * @def SBC_HW_CTRL_1_RSTN_DEL_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_1_RSTN_DEL_Msk (0b00010000U) + +/** + * @def SBC_HW_CTRL_1_CFG_LOCK_0_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_1_CFG_LOCK_0_Pos (3U) + +/** + * @def SBC_HW_CTRL_1_CFG_LOCK_0_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_1_CFG_LOCK_0_Msk (0b00001000U) + + +/* -------------------------------- HW_CTRL_2 ----------------------------------- */ + + +/** + * @def SBC_HW_CTRL_2_2MHZ_FREQ_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_2_2MHZ_FREQ_Pos (5U) + +/** + * @def SBC_HW_CTRL_2_2MHZ_FREQ_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_2_2MHZ_FREQ_Msk (0b11100000U) + +/** + * @def SBC_HW_CTRL_2_I_PEAK_TH_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_2_I_PEAK_TH_Pos (4U) + +/** + * @def SBC_HW_CTRL_2_I_PEAK_TH_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_2_I_PEAK_TH_Msk (0b00010000U) + +/** + * @def SBC_HW_CTRL_2_SS_MOD_FR_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_2_SS_MOD_FR_Pos (2U) + +/** + * @def SBC_HW_CTRL_2_SS_MOD_FR_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_2_SS_MOD_FR_Msk (0b00001100U) + +/** + * @def SBC_HW_CTRL_2_CFG_LOCK_1_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_2_CFG_LOCK_1_Pos (0U) + +/** + * @def SBC_HW_CTRL_2_CFG_LOCK_1_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_2_CFG_LOCK_1_Msk (0b00000001U) + + +/* -------------------------------- GPIO_CTRL ----------------------------------- */ + +/** + * @def SBC_GPIO_CTRL_GPIO_Pos + * + * @brief Control register bit position. + */ +#define SBC_GPIO_CTRL_GPIO_Pos (0U) + +/** + * @def SBC_GPIO_CTRL_GPIO_Msk + * + * @brief Control register bit mask. + */ +#define SBC_GPIO_CTRL_GPIO_Msk (0b00000111U) + + +/* -------------------------------- PWM_CTRL -------------------------------------- */ + +/** + * @def SBC_PWM_DC_PWM_DC_Pos + * + * @brief Control register bit position. + */ +#define SBC_PWM_CTRL_PWM_DC_Pos (0U) + +/** + * @def SBC_PWM_DC_PWM_DC_Msk + * + * @brief Control register bit mask. + */ +#define SBC_PWM_CTRL_PWM_DC_Msk (0b11111111U) + + +/* -------------------------------- PWM_FREQ_CTRL -------------------------------------- */ + +/** + * @def SBC_PWM_FREQ_CTRL_PWM_FREQ_Pos + * + * @brief Control register bit position. + */ +#define SBC_PWM_FREQ_CTRL_PWM_FREQ_Pos (0U) + + +/** + * @def SBC_PWM_FREQ_CTRL_PWM_FREQ_Msk + * + * @brief Control register bit mask. + */ +#define SBC_PWM_FREQ_CTRL_PWM_FREQ_Msk (0b00000011U) + + +/* -------------------------------- HW_CTRL_3 ----------------------------------- */ + + +/** + * @def SBC_HW_CTRL_3_TSD_THR_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_3_TSD_THR_Pos (2U) + +/** + * @def SBC_HW_CTRL_3_TSD_THR_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_3_TSD_THR_Msk (0b00000100U) + +/** + * @def SBC_HW_CTRL_3_ICC1_LIM_ADJ_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_3_ICC1_LIM_ADJ_Pos (0U) + +/** + * @def SBC_HW_CTRL_3_ICC1_LIM_ADJ_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_3_ICC1_LIM_ADJ_Msk (0b00000011U) + + +/* -------------------------------- SYS_STATUS_CTRL_0 --------------------------- */ + +/** + * @def SBC_SYS_STATUS_CTRL_0_SYS_STAT_L_Pos + * + * @brief Control register bit position. + */ +#define SBC_SYS_STATUS_CTRL_0_SYS_STAT_L_Pos (0U) + +/** + * @def SBC_SYS_STATUS_CTRL_0_SYS_STAT_L_Msk + * + * @brief Control register bit mask. + */ +#define SBC_SYS_STATUS_CTRL_0_SYS_STAT_L_Msk (0b11111111U) + + +/* -------------------------------- SYS_STATUS_CTRL_1 --------------------------- */ + + +/** + * @def SBC_SYS_STATUS_CTRL_0_SYS_STAT_H_Pos + * + * @brief Control register bit position. + */ +#define SBC_SYS_STATUS_CTRL_0_SYS_STAT_H_Pos (0U) + +/** + * @def SBC_SYS_STATUS_CTRL_0_SYS_STAT_H_Msk + * + * @brief Control register bit mask. + */ +#define SBC_SYS_STATUS_CTRL_0_SYS_STAT_H_Msk (0b11111111U) + + + + + + +/* ================================================================================ */ +/* ======== Selective Wake Control Registers Position & Mask ============= */ +/* ================================================================================ */ + + + +/* -------------------------------- SWK_CTRL ------------------------------------ */ + + +/** + * @def SBC_SWK_CTRL_OSC_CAL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CTRL_OSC_CAL_Pos (7U) + +/** + * @def SBC_SWK_CTRL_OSC_CAL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CTRL_OSC_CAL_Msk (0b10000000U) + +/** + * @def SBC_SWK_CTRL_TRIM_EN_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CTRL_TRIM_EN_Pos (5U) + +/** + * @def SBC_SWK_CTRL_TRIM_EN_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CTRL_TRIM_EN_Msk (0b01100000U) + +/** + * @def SBC_SWK_CTRL_CANTO_MASK_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CTRL_CANTO_MASK_Pos (4U) + +/** + * @def SBC_SWK_CTRL_CANTO_MASK_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CTRL_CANTO_MASK_Msk (0b00010000U) + +/** + * @def SBC_SWK_CTRL_CFG_VAL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CTRL_CFG_VAL_Pos (0U) + +/** + * @def SBC_SWK_CTRL_CFG_VAL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CTRL_CFG_VAL_Msk (0b00000001U) + + +/* -------------------------------- SWK_BTL0_CTRL ------------------------------- */ + + +/** + * @def SBC_SWK_BTL0_CTRL_TBIT_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_BTL0_CTRL_TBIT_Pos (0U) + +/** + * @def SBC_SWK_BTL0_CTRL_TBIT_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_BTL0_CTRL_TBIT_Msk (0b11111111U) + + +/* -------------------------------- SWK_BTL1_CTRL ------------------------------- */ + + +/** + * @def SBC_SWK_BTL1_CTRL_SP_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_BTL1_CTRL_SP_Pos (0U) + +/** + * @def SBC_SWK_BTL1_CTRL_SP_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_BTL1_CTRL_SP_Msk (0b00111111U) + + +/* -------------------------------- SWK_ID3_CTRL -------------------------------- */ + + +/** + * @def SBC_SWK_ID3_CTRL_ID28_21_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_ID3_CTRL_ID28_21_Pos (0U) + +/** + * @def SBC_SWK_ID3_CTRL_ID28_21_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_ID3_CTRL_ID28_21_Msk (0b11111111U) + + +/* -------------------------------- SWK_ID2_CTRL -------------------------------- */ + + +/** + * @def SBC_SWK_ID2_CTRL_ID20_13_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_ID2_CTRL_ID20_13_Pos (0U) + +/** + * @def SBC_SWK_ID2_CTRL_ID20_13_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_ID2_CTRL_ID20_13_Msk (0b11111111U) + + +/* -------------------------------- SWK_ID1_CTRL -------------------------------- */ + + +/** + * @def SBC_SWK_ID1_CTRL_ID12_5_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_ID1_CTRL_ID12_5_Pos (0U) + +/** + * @def SBC_SWK_ID1_CTRL_ID12_5_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_ID1_CTRL_ID12_5_Msk (0b11111111U) + + +/* -------------------------------- SWK_ID0_CTRL -------------------------------- */ + + +/** + * @def SBC_SWK_ID0_CTRL_ID4_0_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_ID0_CTRL_ID4_0_Pos (2U) + +/** + * @def SBC_SWK_ID0_CTRL_ID4_0_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_ID0_CTRL_ID4_0_Msk (0b01111100U) + +/** + * @def SBC_SWK_ID0_CTRL_RTR_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_ID0_CTRL_RTR_Pos (1U) + +/** + * @def SBC_SWK_ID0_CTRL_RTR_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_ID0_CTRL_RTR_Msk (0b00000010U) + +/** + * @def SBC_SWK_ID0_CTRL_IDE_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_ID0_CTRL_IDE_Pos (0U) + +/** + * @def SBC_SWK_ID0_CTRL_IDE_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_ID0_CTRL_IDE_Msk (0b00000001U) + + +/* -------------------------------- SWK_MASK_ID3_CTRL --------------------------- */ + + +/** + * @def SBC_SWK_MASK_ID3_CTRL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_MASK_ID3_CTRL_Pos (0U) + +/** + * @def SBC_SWK_MASK_ID3_CTRL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_MASK_ID3_CTRL_Msk (0b11111111U) + + +/* -------------------------------- SWK_MASK_ID2_CTRL --------------------------- */ + + +/** + * @def SBC_SWK_MASK_ID2_CTRL_MASK_ID20_13_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_MASK_ID2_CTRL_MASK_ID20_13_Pos (0U) + +/** + * @def SBC_SWK_MASK_ID2_CTRL_MASK_ID20_13_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_MASK_ID2_CTRL_MASK_ID20_13_Msk (0b11111111U) + + +/* -------------------------------- SWK_MASK_ID1_CTRL --------------------------- */ + + +/** + * @def SBC_SWK_MASK_ID1_CTRL_MASK_ID12_5_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_MASK_ID1_CTRL_MASK_ID12_5_Pos (0U) + +/** + * @def SBC_SWK_MASK_ID1_CTRL_MASK_ID12_5_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_MASK_ID1_CTRL_MASK_ID12_5_Msk (0b11111111U) + + +/* -------------------------------- SWK_MASK_ID0_CTRL --------------------------- */ + + +/** + * @def SBC_SWK_MASK_ID0_CTRL_MASK_ID4_0_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_MASK_ID0_CTRL_MASK_ID4_0_Pos (2U) + +/** + * @def SBC_SWK_MASK_ID0_CTRL_MASK_ID4_0_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_MASK_ID0_CTRL_MASK_ID4_0_Msk (0b01111100U) + + +/* -------------------------------- SWK_DLC_CTRL -------------------------------- */ + + +/** + * @def SBC_SWK_DLC_CTRL_DLC_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_DLC_CTRL_DLC_Pos (0U) + +/** + * @def SBC_SWK_DLC_CTRL_DLC_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_DLC_CTRL_DLC_Msk (0b00001111U) + + +/* -------------------------------- SWK_DATA7_CTRL ------------------------------ */ + + +/** + * @def SBC_SWK_DATA7_CTRL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_DATA7_CTRL_Pos (0U) + +/** + * @def SBC_SWK_DATA7_CTRL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_DATA7_CTRL_Msk (0b11111111U) + + +/* -------------------------------- SWK_DATA6_CTRL ------------------------------ */ + + +/** + * @def SBC_SWK_DATA6_CTRL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_DATA6_CTRL_Pos (0U) + +/** + * @def SBC_SWK_DATA6_CTRL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_DATA6_CTRL_Msk (0b11111111U) + + +/* -------------------------------- SWK_DATA5_CTRL ------------------------------ */ + + +/** + * @def SBC_SWK_DATA5_CTRL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_DATA5_CTRL_Pos (0U) + +/** + * @def SBC_SWK_DATA5_CTRL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_DATA5_CTRL_Msk (0b11111111U) + + +/* -------------------------------- SWK_DATA4_CTRL ------------------------------ */ + + +/** + * @def SBC_SWK_DATA4_CTRL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_DATA4_CTRL_Pos (0U) + +/** + * @def SBC_SWK_DATA4_CTRL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_DATA4_CTRL_Msk (0b11111111U) + + +/* -------------------------------- SWK_DATA3_CTRL ------------------------------ */ + + +/** + * @def SBC_SWK_DATA3_CTRL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_DATA3_CTRL_Pos (0U) + +/** + * @def SBC_SWK_DATA3_CTRL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_DATA3_CTRL_Msk (0b11111111U) + + +/* -------------------------------- SWK_DATA2_CTRL ------------------------------ */ + + +/** + * @def SBC_SWK_DATA2_CTRL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_DATA2_CTRL_Pos (0U) + +/** + * @def SBC_SWK_DATA2_CTRL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_DATA2_CTRL_Msk (0b11111111U) + + +/* -------------------------------- SWK_DATA1_CTRL ------------------------------ */ + + +/** + * @def SBC_SWK_DATA1_CTRL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_DATA1_CTRL_Pos (0U) + +/** + * @def SBC_SWK_DATA1_CTRL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_DATA1_CTRL_Msk (0b11111111U) + + +/* -------------------------------- SWK_DATA0_CTRL ------------------------------ */ + + +/** + * @def SBC_SWK_DATA0_CTRL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_DATA0_CTRL_Pos (0U) + +/** + * @def SBC_SWK_DATA0_CTRL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_DATA0_CTRL_Msk (0b11111111U) + + +/* -------------------------------- SWK_CAN_FD_CTRL ----------------------------- */ + + +/** + * @def SBC_SWK_CAN_FD_CTRL_DIS_ERR_CNT_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CAN_FD_CTRL_DIS_ERR_CNT_Pos (5U) + +/** + * @def SBC_SWK_CAN_FD_CTRL_DIS_ERR_CNT_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CAN_FD_CTRL_DIS_ERR_CNT_Msk (0b00100000U) + +/** + * @def SBC_SWK_CAN_FD_CTRL_RX_FILT_BYP_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CAN_FD_CTRL_RX_FILT_BYP_Pos (4U) + +/** + * @def SBC_SWK_CAN_FD_CTRL_RX_FILT_BYP_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CAN_FD_CTRL_RX_FILT_BYP_Msk (0b00010000U) + +/** + * @def SBC_SWK_CAN_FD_CTRL_FD_FILTER_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CAN_FD_CTRL_FD_FILTER_Pos (1U) + +/** + * @def SBC_SWK_CAN_FD_CTRL_FD_FILTER_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CAN_FD_CTRL_FD_FILTER_Msk (0b00001110U) + +/** + * @def SBC_SWK_CAN_FD_CTRL_CAN_FD_EN_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CAN_FD_CTRL_CAN_FD_EN_Pos (0U) + +/** + * @def SBC_SWK_CAN_FD_CTRL_CAN_FD_EN_Msk + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CAN_FD_CTRL_CAN_FD_EN_Msk (0b00000001U) + + +/* -------------------------------- SWK_OSC_TRIM_CTRL --------------------------- */ + + +/** + * @def SBC_SWK_OSC_TRIM_CTRL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_OSC_TRIM_CTRL_Pos (0U) + +/** + * @def SBC_SWK_OSC_TRIM_CTRL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_OSC_TRIM_CTRL_Msk (0b01111111U) + + +/* -------------------------------- SWK_OPT_CTRL -------------------------------- */ + + +/** + * @def SBC_SWK_OPT_CTRL_RX_WK_SEL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_OPT_CTRL_RX_WK_SEL_Pos (7U) + +/** + * @def SBC_SWK_OPT_CTRL_RX_WK_SEL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_OPT_CTRL_RX_WK_SEL_Msk (0b10000000U) + + +/* -------------------------------- SWK_OSC_CAL_H_STAT -------------------------- */ + + +/** + * @def SBC_SWK_OSC_CAL_H_STAT_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_OSC_CAL_H_STAT_Pos (0U) + +/** + * @def SBC_SWK_OSC_CAL_H_STAT_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_OSC_CAL_H_STAT_Msk (0b11111111U) + + +/* -------------------------------- SWK_OPT_CAL_L_STAT -------------------------- */ + + +/** + * @def SBC_SWK_OPT_CAL_L_STAT_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_OPT_CAL_L_STAT_Pos (0U) + +/** + * @def SBC_SWK_OPT_CAL_L_STAT_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_OPT_CAL_L_STAT_Msk (0b11111111U) + + +/* -------------------------------- SWK_CDR_CTRL1 ------------------------------- */ + + +/** + * @def SBC_SWK_CDR_CTRL1_SEL_FILT_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CDR_CTRL1_SEL_FILT_Pos (2U) + +/** + * @def SBC_SWK_CDR_CTRL1_SEL_FILT_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CDR_CTRL1_SEL_FILT_Msk (0b00001100U) + +/** + * @def SBC_SWK_CDR_CTRL1_CDR_EN_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CDR_CTRL1_CDR_EN_Pos (0U) + +/** + * @def SBC_SWK_CDR_CTRL1_CDR_EN_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CDR_CTRL1_CDR_EN_Msk (0b00000001U) + + +/* -------------------------------- SWK_CDR_CTRL2 ------------------------------- */ + + +/** + * @def SBC_SWK_CDR_CTRL2_SEL_OSC_CLK_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CDR_CTRL2_SEL_OSC_CLK_Pos (0U) + +/** + * @def SBC_SWK_CDR_CTRL2_SEL_OSC_CLK_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CDR_CTRL2_SEL_OSC_CLK_Msk (0b00000011U) + + +/* -------------------------------- SWK_CDR_LIMIT_HIGH_CTRL --------------------- */ + + +/** + * @def SBC_SWK_CDR_LIMIT_HIGH_CTRL_CDR_LIM_H_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CDR_LIMIT_HIGH_CTRL_CDR_LIM_H_Pos (0U) + +/** + * @def SBC_SWK_CDR_LIMIT_HIGH_CTRL_CDR_LIM_H_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CDR_LIMIT_HIGH_CTRL_CDR_LIM_H_Msk (0b11111111U) + + +/* -------------------------------- SWK_CDR_LIMIT_LOW_CTRL ---------------------- */ + + +/** + * @def SBC_SWK_CDR_LIMIT_LOW_CTRL_CDR_LIM_L_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CDR_LIMIT_LOW_CTRL_CDR_LIM_L_Pos (0U) + +/** + * @def SBC_SWK_CDR_LIMIT_LOW_CTRL_CDR_LIM_L_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CDR_LIMIT_LOW_CTRL_CDR_LIM_L_Msk (0b11111111U) + + + + + + +/* ================================================================================ */ +/* ============= General Status Registers Position & Mask ================ */ +/* ================================================================================ */ + + + +/* -------------------------------- SUP_STAT_1 ---------------------------------- */ + + +/** + * @def SBC_SUP_STAT_1_VS_UV_Pos + * + * @brief General status register bit position. + */ +#define SBC_SUP_STAT_1_VS_UV_Pos (6U) + +/** + * @def SBC_SUP_STAT_1_VS_UV_Msk + * + * @brief General status register bit mask. + */ +#define SBC_SUP_STAT_1_VS_UV_Msk (0b01000000U) + +/** + * @def SBC_SUP_STAT_1_VS_OV_Pos + * + * @brief General status register bit position. + */ +#define SBC_SUP_STAT_1_VS_OV_Pos (5U) + +/** + * @def SBC_SUP_STAT_1_VS_OV_Msk + * + * @brief General status register bit mask. + */ +#define SBC_SUP_STAT_1_VS_OV_Msk (0b00100000U) + +/** + * @def SBC_SUP_STAT_1_VCC1_OV_Pos + * + * @brief General status register bit position. + */ +#define SBC_SUP_STAT_1_VCC1_OV_Pos (1U) + +/** + * @def SBC_SUP_STAT_1_VCC1_OV_Msk + * + * @brief General status register bit mask. + */ +#define SBC_SUP_STAT_1_VCC1_OV_Msk (0b00000010U) + +/** + * @def SBC_SUP_STAT_1_VCC1_WARN_Pos + * + * @brief General status register bit position. + */ +#define SBC_SUP_STAT_1_VCC1_WARN_Pos (0U) + +/** + * @def SBC_SUP_STAT_1_VCC1_WARN_Msk + * + * @brief General status register bit mask. + */ +#define SBC_SUP_STAT_1_VCC1_WARN_Msk (0b00000001U) + + +/* -------------------------------- SUP_STAT_0 ---------------------------------- */ + + +/** + * @def SBC_SUP_STAT_0_POR_Pos + * + * @brief General status register bit position. + */ +#define SBC_SUP_STAT_0_POR_Pos (7U) + +/** + * @def SBC_SUP_STAT_0_POR_Msk + * + * @brief General status register bit mask. + */ +#define SBC_SUP_STAT_0_POR_Msk (0b10000000U) + +/** + * @def SBC_SUP_STAT_0_VCC2_OT_Pos + * + * @brief General status register bit position. + */ +#define SBC_SUP_STAT_0_VCC2_OT_Pos (4U) + +/** + * @def SBC_SUP_STAT_0_VCC2_OT_Msk + * + * @brief General status register bit mask. + */ +#define SBC_SUP_STAT_0_VCC2_OT_Msk (0b00010000U) + +/** + * @def SBC_SUP_STAT_0_VCC2_UV_Pos + * + * @brief General status register bit position. + */ +#define SBC_SUP_STAT_0_VCC2_UV_Pos (3U) + +/** + * @def SBC_SUP_STAT_0_VCC2_UV_Msk + * + * @brief General status register bit mask. + */ +#define SBC_SUP_STAT_0_VCC2_UV_Msk (0b00001000U) + +/** + * @def SBC_SUP_STAT_0_VCC1_SC_Pos + * + * @brief General status register bit position. + */ +#define SBC_SUP_STAT_0_VCC1_SC_Pos (2U) + +/** + * @def SBC_SUP_STAT_0_VCC1_SC_Msk + * + * @brief General status register bit mask. + */ +#define SBC_SUP_STAT_0_VCC1_SC_Msk (0b00000100U) + +/** + * @def SBC_SUP_STAT_0_VCC1_UV_Pos + * + * @brief General status register bit position. + */ +#define SBC_SUP_STAT_0_VCC1_UV_Pos (0U) + +/** + * @def SBC_SUP_STAT_0_VCC1_UV_Msk + * + * @brief General status register bit mask. + */ +#define SBC_SUP_STAT_0_VCC1_UV_Msk (0b00000001U) + + +/* -------------------------------- THERM_STAT ---------------------------------- */ + + +/** + * @def SBC_THERM_STAT_TSD2_SAFE_Pos + * + * @brief General status register bit position. + */ +#define SBC_THERM_STAT_TSD2_SAFE_Pos (3U) + +/** + * @def SBC_THERM_STAT_TSD2_SAFE_Msk + * + * @brief General status register bit mask. + */ +#define SBC_THERM_STAT_TSD2_SAFE_Msk (0b00001000U) + +/** + * @def SBC_THERM_STAT_TSD2_Pos + * + * @brief General status register bit position. + */ +#define SBC_THERM_STAT_TSD2_Pos (2U) + +/** + * @def SBC_THERM_STAT_TSD2_Msk + * + * @brief General status register bit mask. + */ +#define SBC_THERM_STAT_TSD2_Msk (0b00000100U) + +/** + * @def SBC_THERM_STAT_TSD1_Pos + * + * @brief General status register bit position. + */ +#define SBC_THERM_STAT_TSD1_Pos (1U) + +/** + * @def SBC_THERM_STAT_TSD1_Msk + * + * @brief General status register bit mask. + */ +#define SBC_THERM_STAT_TSD1_Msk (0b00000010U) + +/** + * @def SBC_THERM_STAT_TPW_Pos + * + * @brief General status register bit position. + */ +#define SBC_THERM_STAT_TPW_Pos (0U) + +/** + * @def SBC_THERM_STAT_TPW_Msk + * + * @brief General status register bit mask. + */ +#define SBC_THERM_STAT_TPW_Msk (0b00000001U) + + +/* -------------------------------- DEV_STAT ------------------------------------ */ + + +/** + * @def SBC_DEV_STAT_DEV_STAT_Pos + * + * @brief General status register bit position. + */ +#define SBC_DEV_STAT_DEV_STAT_Pos (6U) + +/** + * @def SBC_DEV_STAT_DEV_STAT_Msk + * + * @brief General status register bit mask. + */ +#define SBC_DEV_STAT_DEV_STAT_Msk (0b11000000U) + +/** + * @def SBC_DEV_STAT_WD_FAIL_Pos + * + * @brief General status register bit position. + */ +#define SBC_DEV_STAT_WD_FAIL_Pos (2U) + +/** + * @def SBC_DEV_STAT_WD_FAIL_Msk + * + * @brief General status register bit mask. + */ +#define SBC_DEV_STAT_WD_FAIL_Msk (0b00001100U) + +/** + * @def SBC_DEV_STAT_SPI_FAIL_Pos + * + * @brief General status register bit position. + */ +#define SBC_DEV_STAT_SPI_FAIL_Pos (1U) + +/** + * @def SBC_DEV_STAT_SPI_FAIL_Msk + * + * @brief General status register bit mask. + */ +#define SBC_DEV_STAT_SPI_FAIL_Msk (0b00000010U) + +/** + * @def SBC_DEV_STAT_FAILURE_Pos + * + * @brief General status register bit position. + */ +#define SBC_DEV_STAT_FAILURE_Pos (0U) + +/** + * @def SBC_DEV_STAT_FAILURE_Msk + * + * @brief General status register bit mask. + */ +#define SBC_DEV_STAT_FAILURE_Msk (0b00000001U) + + +/* -------------------------------- BUS_STAT ------------------------------------ */ + + +/** + * @def SBC_BUS_STAT_CANTO_Pos + * + * @brief General status register bit position. + */ +#define SBC_BUS_STAT_CANTO_Pos (4U) + +/** + * @def SBC_BUS_STAT_CANTO_Msk + * + * @brief General status register bit mask. + */ +#define SBC_BUS_STAT_CANTO_Msk (0b00010000U) + +/** + * @def SBC_BUS_STAT_SYSERR_Pos + * + * @brief General status register bit position. + */ +#define SBC_BUS_STAT_SYSERR_Pos (3U) + +/** + * @def SBC_BUS_STAT_SYSERR_Msk + * + * @brief General status register bit mask. + */ +#define SBC_BUS_STAT_SYSERR_Msk (0b00001000U) + +/** + * @def SBC_BUS_STAT_CAN_FAIL_Pos + * + * @brief General status register bit position. + */ +#define SBC_BUS_STAT_CAN_FAIL_Pos (1U) + +/** + * @def SBC_BUS_STAT_CAN_FAIL_Msk + * + * @brief General status register bit mask. + */ +#define SBC_BUS_STAT_CAN_FAIL_Msk (0b00000110U) + +/** + * @def SBC_BUS_STAT_VCAN_UV_Pos + * + * @brief General status register bit position. + */ +#define SBC_BUS_STAT_VCAN_UV_Pos (0U) + +/** + * @def SBC_BUS_STAT_VCAN_UV_Msk + * + * @brief General status register bit mask. + */ +#define SBC_BUS_STAT_VCAN_UV_Msk (0b00000001U) + + +/* -------------------------------- WK_STAT_0 ----------------------------------- */ + + +/** + * @def SBC_WK_STAT_0_CAN_WU_Pos + * + * @brief General status register bit position. + */ +#define SBC_WK_STAT_0_CAN_WU_Pos (5U) + +/** + * @def SBC_WK_STAT_0_CAN_WU_Msk + * + * @brief General status register bit mask. + */ +#define SBC_WK_STAT_0_CAN_WU_Msk (0b00100000U) + +/** + * @def SBC_WK_STAT_0_TIMER_WU_Pos + * + * @brief General status register bit position. + */ +#define SBC_WK_STAT_0_TIMER_WU_Pos (4U) + +/** + * @def SBC_WK_STAT_0_TIMER_WU_Msk + * + * @brief General status register bit mask. + */ +#define SBC_WK_STAT_0_TIMER_WU_Msk (0b00010000U) + +/** + * @def SBC_WK_STAT_0_WK_WU_Pos + * + * @brief General status register bit position. + */ +#define SBC_WK_STAT_0_WK_WU_Pos (0U) + +/** + * @def SBC_WK_STAT_0_WK_WU_Msk + * + * @brief General status register bit mask. + */ +#define SBC_WK_STAT_0_WK_WU_Msk (0b00000001U) + + +/* -------------------------------- WK_STAT_1 ----------------------------------- */ + + +/** + * @def SBC_WK_STAT_1_GPIO_WK_WU_Pos + * + * @brief General status register bit position. + */ +#define SBC_WK_STAT_1_GPIO_WK_WU_Pos (4U) + +/** + * @def SBC_WK_STAT_1_GPIO_WK_WU_Msk + * + * @brief General status register bit mask. + */ +#define SBC_WK_STAT_1_GPIO_WK_WU_Msk (0b00010000U) + + +/* -------------------------------- WK_LVL_STAT --------------------------------- */ + + +/** + * @def SBC_WK_LVL_STAT_SBC_DEV_LVL_Pos + * + * @brief General status register bit position. + */ +#define SBC_WK_LVL_STAT_SBC_DEV_LVL_Pos (7U) + +/** + * @def SBC_WK_LVL_STAT_SBC_DEV_LVL_Msk + * + * @brief General status register bit mask. + */ +#define SBC_WK_LVL_STAT_SBC_DEV_LVL_Msk (0b10000000U) + +/** + * @def SBC_WK_LVL_STAT_CFG0_STATE_Pos + * + * @brief General status register bit position. + */ +#define SBC_WK_LVL_STAT_CFG0_STATE_Pos (6U) + +/** + * @def SBC_WK_LVL_STAT_CFG0_STATE_Msk + * + * @brief General status register bit mask. + */ +#define SBC_WK_LVL_STAT_CFG0_STATE_Msk (0b01000000U) + +/** + * @def SBC_WK_LVL_STAT_GPIO_LVL_Pos + * + * @brief General status register bit position. + */ +#define SBC_WK_LVL_STAT_GPIO_LVL_Pos (4U) + +/** + * @def SBC_WK_LVL_STAT_GPIO_LVL_Msk + * + * @brief General status register bit mask. + */ +#define SBC_WK_LVL_STAT_GPIO_LVL_Msk (0b00010000U) + +/** + * @def SBC_WK_LVL_STAT_WK_LVL_Pos + * + * @brief General status register bit position. + */ +#define SBC_WK_LVL_STAT_WK_LVL_Pos (0U) + +/** + * @def SBC_WK_LVL_STAT_WK_LVL_Msk + * + * @brief General status register bit mask. + */ +#define SBC_WK_LVL_STAT_WK_LVL_Msk (0b00000001U) + + +/* -------------------------------- GPIO_OC_STAT -------------------------------- */ + + +/** + * @def SBC_GPIO_OC_STAT_GPIO_OC_Pos + * + * @brief General status register bit position. + */ +#define SBC_GPIO_OC_STAT_GPIO_OC_Pos (6U) + +/** + * @def SBC_GPIO_OC_STAT_GPIO_OC_Msk + * + * @brief General status register bit mask. + */ +#define SBC_GPIO_OC_STAT_GPIO_OC_Msk (0b01000000U) + + +/* -------------------------------- GPIO_OL_STAT -------------------------------- */ + + +/** + * @def SBC_GPIO_OL_STAT_GPIO_OL_Pos + * + * @brief General status register bit position. + */ +#define SBC_GPIO_OL_STAT_GPIO_OL_Pos (6U) + +/** + * @def SBC_GPIO_OL_STAT_GPIO_OL_Msk + * + * @brief General status register bit mask. + */ +#define SBC_GPIO_OL_STAT_GPIO_OL_Msk (0b01000000U) + + + + + + + +/* ================================================================================ */ +/* ========= Selective Wake Status Registers Position & Mask ============= */ +/* ================================================================================ */ + + + + +/* -------------------------------- SWK_STAT ------------------------------------ */ + + +/** + * @def SBC_SWK_STAT_SYNC_Pos + * + * @brief Selective wake status register bit position. + */ +#define SBC_SWK_STAT_SYNC_Pos (6U) + +/** + * @def SBC_SWK_STAT_SYNC_Msk + * + * @brief Selective wake status register bit mask. + */ +#define SBC_SWK_STAT_SYNC_Msk (0b01000000U) + +/** + * @def SBC_SWK_STAT_CANSIL_Pos + * + * @brief Selective wake status register bit position. + */ +#define SBC_SWK_STAT_CANSIL_Pos (3U) + +/** + * @def SBC_SWK_STAT_CANSIL_Msk + * + * @brief Selective wake status register bit mask. + */ +#define SBC_SWK_STAT_CANSIL_Msk (0b00001000U) + +/** + * @def SBC_SWK_STAT_SWK_SET_Pos + * + * @brief Selective wake status register bit position. + */ +#define SBC_SWK_STAT_SWK_SET_Pos (2U) + +/** + * @def SBC_SWK_STAT_SWK_SET_Msk + * + * @brief Selective wake status register bit mask. + */ +#define SBC_SWK_STAT_SWK_SET_Msk (0b00000100U) + +/** + * @def SBC_SWK_STAT_WUP_Pos + * + * @brief Selective wake status register bit position. + */ +#define SBC_SWK_STAT_WUP_Pos (1U) + +/** + * @def SBC_SWK_STAT_WUP_Msk + * + * @brief Selective wake status register bit mask. + */ +#define SBC_SWK_STAT_WUP_Msk (0b00000010U) + +/** + * @def SBC_SWK_STAT_WUF_Pos + * + * @brief Selective wake status register bit position. + */ +#define SBC_SWK_STAT_WUF_Pos (0U) + +/** + * @def SBC_SWK_STAT_WUF_Msk + * + * @brief Selective wake status register bit mask. + */ +#define SBC_SWK_STAT_WUF_Msk (0b00000001U) + + + + + +/* -------------------------------- SWK_ECNT_STAT -------------------------------- */ + + +/** + * @def SBC_SWK_ECNT_STAT_ECNT_Pos + * + * @brief Selective wake status register bit position. + */ +#define SBC_SWK_ECNT_STAT_ECNT_Pos (0U) + +/** + * @def SBC_SWK_ECNT_STAT_ECNT_Msk + * + * @brief Selective wake status register bit mask. + */ +#define SBC_SWK_ECNT_STAT_ECNT_Msk (0b00111111U) + + +/* -------------------------------- SWK_CDR_STAT1 -------------------------------- */ + + +/** + * @def SBC_SWK_CDR_STAT1_NAVG_SAT_Pos + * + * @brief Selective wake status register bit position. + */ +#define SBC_SWK_CDR_STAT1_NAVG_SAT_Pos (0U) + +/** + * @def SBC_SWK_CDR_STAT1_NAVG_SAT_Msk + * + * @brief Selective wake status register bit mask. + */ +#define SBC_SWK_CDR_STAT1_NAVG_SAT_Msk (0b11111111U) + + +/* -------------------------------- SWK_CDR_STAT2 -------------------------------- */ + + +/** + * @def SBC_SWK_CDR_STAT2_NAVG_SAT_Pos + * + * @brief Selective wake status register bit position. + */ +#define SBC_SWK_CDR_STAT2_NAVG_SAT_Pos (4U) + +/** + * @def SBC_SWK_CDR_STAT2_NAVG_SAT_Msk + * + * @brief Selective wake status register bit mask. + */ +#define SBC_SWK_CDR_STAT2_NAVG_SAT_Msk (0b11110000U) + + + + + + +/* ================================================================================ */ +/* ====== Family and Product Information Register Position & Mask ======== */ +/* ================================================================================ */ + + + +/* -------------------------------- FAM_PROD_STAT -------------------------------- */ + + +/** + * @def SBC_FAM_PROD_STAT_FAM_Pos + * + * @brief Family and product register bit position. + */ +#define SBC_FAM_PROD_STAT_FAM_Pos (4U) + +/** + * @def SBC_FAM_PROD_STAT_FAM_Msk + * + * @brief Family and product register bit mask. + */ +#define SBC_FAM_PROD_STAT_FAM_Msk (0b11110000U) + +/** + * @def SBC_FAM_PROD_STAT_PROD_Pos + * + * @brief Family and product register bit position. + */ +#define SBC_FAM_PROD_STAT_PROD_Pos (0U) + +/** + * @def SBC_FAM_PROD_STAT_PROD_Msk + * + * @brief Family and product register bit mask. + */ +#define SBC_FAM_PROD_STAT_PROD_Msk (0b00001111U) + + + + + + +/* ================================================================================ */ +/* =============== General Control Registers Enumerations ================ */ +/* ================================================================================ */ + + + +/* -------------------------------- M_S_CTRL ------------------------------------ */ + +typedef enum +{ + SBC_MODE_NORMAL = 0x00U, + SBC_MODE_SLEEP, + SBC_MODE_STOP, + SBC_MODE_RESET +}; + +typedef enum +{ + SBC_VCC2_OFF = 0x00U, + SBC_VCC2_ON_NORMAL, + SBC_VCC2_ON_NORMAL_STOP, + SBC_VCC2_ON_ALWAYS +}; + +typedef enum +{ + SBC_VCC1_OV_RST_NOACTION = 0x00U, + SBC_VCC1_OV_RST_RESTART_FAILSAFE +}; + +typedef enum +{ + SBC_VCC1_RT_VRT1 = 0x00U, + SBC_VCC1_RT_VRT2, + SBC_VCC1_RT_VRT3, + SBC_VCC1_RT_VRT4 +}; + + +/* -------------------------------- HW_CTRL_0 ----------------------------------- */ + +typedef enum +{ + SBC_SOFT_RESET_RST_TRIGGER_SOFTRST = 0x00U, + SBC_SOFT_RESET_RST_NOTRIGGER_SOFTRST +}; + +typedef enum +{ + SBC_FO_ON_NOT_ACTIVE = 0x00U, + SBC_FO_ON_ACTIVE +}; + +typedef enum +{ + SBC_CP_EN_OFF = 0x00U, + SBC_CP_EN_ON +}; + +typedef enum +{ + SBC_CFG1_RESTART_FAILSAFE_2WDFAIL = 0x00U, + SBC_CFG1_RESTART_FAILSAFE_1WDFAIL +}; + + +/* -------------------------------- WD_CTRL ------------------------------------- */ + +typedef enum +{ + SBC_CHECKSUM_0 = 0x00U, + SBC_CHECKSUM_1 +}; + +typedef enum +{ + SBC_WD_STM_EN_0_ACTIVE_STOPMODE = 0x00U, + SBC_WD_STM_EN_0_NOTACTIVE_STOPMODE +}; + +typedef enum +{ + SBC_WD_WIN_TIMEOUT_WD = 0x00U, + SBC_WD_WIN_WINDOW_WD +}; + +typedef enum +{ + SBC_WD_EN_WK_BUS_NOSTART_AFTER_CANWAKE = 0x00U, + SBC_WD_EN_WK_BUS_START_LONGOPENWINDOW_CANWAKE +}; + +typedef enum +{ + SBC_WD_TIMER_10MS = 0x00U, + SBC_WD_TIMER_20MS, + SBC_WD_TIMER_50MS, + SBC_WD_TIMER_100MS, + SBC_WD_TIMER_200MS, + SBC_WD_TIMER_500MS, + SBC_WD_TIMER_1000MS, + SBC_WD_TIMER_10000MS +}; + + +/* -------------------------------- BUS_CTRL_0 ---------------------------------- */ + +typedef enum +{ + SBC_BUS_CTRL_0_CAN_WAKECAPABLE_NOSWK = 0x01U, + SBC_BUS_CTRL_0_CAN_RECEIVEONLY_NOSWK, + SBC_BUS_CTRL_0_CAN_NORMAL_NOSWK, + SBC_BUS_CTRL_0_CAN_OFF, + SBC_BUS_CTRL_0_CAN_WAKECAPABLE_SWK, + SBC_BUS_CTRL_0_CAN_RECEIVEONLY_SWK, + SBC_BUS_CTRL_0_CAN_NORMAL_SWK +}; + + +/* -------------------------------- WK_CTRL_0 ----------------------------------- */ + +typedef enum +{ + WK_CTRL_0_TIMER_WK_EN_WAKEUP_DISABLED = 0x00U, + WK_CTRL_0_TIMER_WK_EN_WAKESOURCE +}; + +typedef enum +{ + SBC_WD_STM_EN_1_WATCHDOG_STOPMPDE = 0x00U, + SBC_WD_STM_EN_1_NOWATCHDOG_STOPMODE +}; + + +/* -------------------------------- WK_CTRL_1 ----------------------------------- */ + +typedef enum +{ + SBC_INT_GLOBAL_WAKESOURCES_ONLY = 0x00U, + SBC_INT_GLOBAL_ALLINFORMATIONBITS +}; + +typedef enum +{ + SBC_WK_MEAS_WK_AS_WAKEUP = 0x00U, + SBC_WK_MEAS_WK_AS_VOLTAGESENSING +}; + +typedef enum +{ + SBC_WK_EN_WAKEUP_DISABLED = 0x00U, + SBC_WK_EN_WAKEUP_ENABLED +}; + + +/* -------------------------------- WK_PUPD_CTRL -------------------------------- */ + +typedef enum +{ + SBC_GPIO_WK_PUPD_NOPULLING = 0x00U, + SBC_GPIO_WK_PUPD_PULLDOWN, + SBC_GPIO_WK_PUPD_PULLUP, + SBC_GPIO_WK_PUPD_AUTOMATIC_PULLING +}; + +typedef enum +{ + SBC_WK_PUPD_NOPULLING = 0x00U, + SBC_WK_PUPD_PULLDOWN, + SBC_WK_PUPD_PULLUP, + SBC_WK_PUPD_AUTOMATIC_PULLING +}; + + +/* -------------------------------- BUS_CTRL_3 ---------------------------------- */ + +typedef enum +{ + SBC_CAN_FLASH_DISABLED = 0x00U, + SBC_CAN_FLASH_ENABLED +}; + + +/* -------------------------------- TIMER_CTRL ---------------------------------- */ + +typedef enum +{ + SBC_TIMER_ON_TIMEROFF_HSX_LOW = 0x00U, + SBC_TIMER_ON_100US, + SBC_TIMER_ON_300US, + SBC_TIMER_ON_1MS, + SBC_TIMER_ON_10MS, + SBC_TIMER_ON_20MS, + SBC_TIMER_ON_TIMEROFF_HSX_HIGH +}; + +typedef enum +{ + SBC_TIMER_PER_10MS = 0x00U, + SBC_TIMER_PER_20MS, + SBC_TIMER_PER_50MS, + SBC_TIMER_PER_100MS, + SBC_TIMER_PER_200MS, + SBC_TIMER_PER_500MS, + SBC_TIMER_PER_1S, + SBC_TIMER_PER_2S, + SBC_TIMER_PER_5S, + SBC_TIMER_PER_10S, + SBC_TIMER_PER_20S, + SBC_TIMER_PER_50S, + SBC_TIMER_PER_100S, + SBC_TIMER_PER_200S, + SBC_TIMER_PER_500S, + SBC_TIMER_PER_1000S +}; + + +/* -------------------------------- HW_CTRL_1 ----------------------------------- */ + +typedef enum +{ + SBC_RSTN_HYS_DEFAULT = 0x00U, + SBC_RSTN_HYS_HIGHEST_VRT +}; + +typedef enum +{ + SBC_TSD2_DEL_NO_WAIT_RELEASE_EXTENSION = 0x00U, + SBC_TSD2_DEL_64S_AFTER_16_TSD2_EVENTS +}; + +typedef enum +{ + SBC_RSTN_DEL_TRD1 = 0x00U, + SBC_RSTN_DEL_TRD2 +}; + +typedef enum +{ + SBC_CFG_LOCK_0_NOTLOCKED = 0x00U, + SBC_CFG_LOCK_0_LOCKED +}; + + +/* -------------------------------- HW_CTRL_2 ----------------------------------- */ + +typedef enum +{ + SBC_2MHZ_FREQ_1_8_MHZ = 0x00U, + SBC_2MHZ_FREQ_2_0_MHZ, + SBC_2MHZ_FREQ_2_2_MHZ, + SBC_2MHZ_FREQ_2_4_MHZ +}; + +typedef enum +{ + SBC_I_PEAK_TH_LOW = 0x00U, + SBC_I_PEAK_TH_HIGH +}; + +typedef enum +{ + SBC_SS_MOD_FR_DISABLED = 0x00U, + SBC_SS_MOD_FR_15_6KHZ, + SBC_SS_MOD_FR_31_2KHZ, + SBC_SS_MOD_FR_62_5KHZ +}; + +typedef enum +{ + SBC_CFG_LOCK_1_NOTLOCKED = 0x00U, + SBC_CFG_LOCK_1_LOCKED +}; + + +/* -------------------------------- GPIO_CTRL ----------------------------------- */ + +typedef enum +{ + SBC_GPIO_FO = 0x00U, + SBC_GPIO_HSS_TIMER = 0x03U, + SBC_GPIO_OFF, + SBC_GPIO_WAKE_INPUT, + SBC_GPIO_LSS_PWM, + SBC_GPIO_HSS_PWM +}; + + +/* -------------------------------- PWM_CTRL ------------------------------------ */ + +typedef enum +{ + SBC_PWM_DC_0 = 0x00U, + SBC_PWM_DC_10 = 0x19U, + SBC_PWM_DC_20 = 0x51U, + SBC_PWM_DC_30 = 0x4DU, + SBC_PWM_DC_40 = 0x66U, + SBC_PWM_DC_50 = 0x80U, + SBC_PWM_DC_60 = 0x99U, + SBC_PWM_DC_70 = 0xB3U, + SBC_PWM_DC_80 = 0xCCU, + SBC_PWM_DC_90 = 0xE6U, + SBC_PWM_DC_100 = 0xFFU +}; + + +/* -------------------------------- PWM_FREQ_CTRL ------------------------------- */ + +typedef enum +{ + SBC_PWM_FREQ_100HZ = 0x00U, + SBC_PWM_FREQ_200HZ, + SBC_PWM_FREQ_325HZ, + SBC_PWM_FREQ_400HZ +}; + + +/* -------------------------------- HW_CTRL_3 ----------------------------------- */ + +typedef enum +{ + SBC_TSD_THR_DEFAULT = 0x00U, + SBC_TSD_THR_HIGHER +}; + +typedef enum +{ + SBC_ICC1_LIM_ADJ_750MA = 0x00U, + SBC_ICC1_LIM_ADJ_1000MA, + SBC_ICC1_LIM_ADJ_1200MA, + SBC_ICC1_LIM_ADJ_1500MA +}; + + + + + + +/* ================================================================================ */ +/* ========== Selective Wake Control Registers Enumerations ============== */ +/* ================================================================================ */ + + + +/* -------------------------------- SWK_CTRL ------------------------------------ */ + +typedef enum +{ + SBC_OSC_CAL_DISABLED = 0x00U, + SBC_OSC_CAL_ENABLED +}; + +typedef enum +{ + SBC_TRIM_EN_LOCKED = 0x00U, + SBC_TRIM_EN_UNLOCKED = 0x03U +}; + +typedef enum +{ + SBC_CANTO_MASK_NOINT = 0x00U, + SBC_CANTO_MASK_INT_ON_TO +}; + +typedef enum +{ + SBC_CFG_VAL_NOTVALID = 0x00U, + SBC_CFG_VAL_VALID +}; + + +/* -------------------------------- SWK_ID0_CTRL --------------------------------- */ + +typedef enum +{ + SBC_RTR_NORMAL_DATA_FRAME = 0x00U, + SBC_RTR_REMOTE_TRANSMIT_REQUEST +}; + +typedef enum +{ + SBC_IDE_STANDARD = 0x00U, + SBC_IDE_EXTENDED +}; + + +/* -------------------------------- SWK_DLC_CTRL --------------------------------- */ + +typedef enum +{ + SBC_DLC_0BYTES = 0x00U, + SBC_DLC_1BYTES, + SBC_DLC_2BYTES, + SBC_DLC_3BYTES, + SBC_DLC_4BYTES, + SBC_DLC_5BYTES, + SBC_DLC_6BYTES, + SBC_DLC_7BYTES, + SBC_DLC_8BYTES +}; + + +/* -------------------------------- SWK_CAN_FD_CTRL ------------------------------ */ + +typedef enum +{ + SBC_DIS_ERR_CNT_ENABLED = 0x00U, + SBC_DIS_ERR_CNT_DISABLED +}; + +typedef enum +{ + SBC_RX_FILT_BYP_NOTBYPASSED = 0x00U, + SBC_RX_FILT_BYP_BYPASSED +}; + +typedef enum +{ + SBC_FD_FILTER_50NS = 0x00U, + SBC_FD_FILTER_100NS, + SBC_FD_FILTER_150NS, + SBC_FD_FILTER_200NS, + SBC_FD_FILTER_250NS, + SBC_FD_FILTER_300NS, + SBC_FD_FILTER_350NS, + SBC_FD_FILTER_700NS +}; + +typedef enum +{ + SBC_CAN_FD_EN_DISABLED = 0x00U, + SBC_CAN_FD_EN_ENABLED +}; + + +/* -------------------------------- SWK_OPT_CTRL --------------------------------- */ + +typedef enum +{ + SBC_RX_WK_SEL_LOWPOWER = 0x00U, + SBC_RX_WK_SEL_STANDARD +}; + + +/* -------------------------------- SWK_CDR_CTRL1 -------------------------------- */ + +typedef enum +{ + SBC_SEL_FILT_TC8 = 0x00U, + SBC_SEL_FILT_TC16, + SBC_SEL_FILT_TC32, + SBC_SEL_FILT_ADAPT +}; + +typedef enum +{ + SBC_CDR_EN_DISABLED = 0x00U, + SBC_CDR_EN_ENABLED +}; + + +/* -------------------------------- SWK_CDR_CTRL2 -------------------------------- */ + +typedef enum +{ + SBC_SEL_OSC_CLK_80MHZ = 0x00U, + SBC_SEL_OSC_CLK_40MHZ, + SBC_SEL_OSC_CLK_20MHZ, + SBC_SEL_OSC_CLK_10MHZ +}; + + + + + + +/* ================================================================================ */ +/* ========== General Status Information Registers Enumerations ========== */ +/* ================================================================================ */ + + + +/* -------------------------------- SUP_STAT_1 ---------------------------------- */ + +typedef enum +{ + SBC_VS_UV_NOEVENT = 0x00U, + SBC_VS_UV_EVENT +}; + +typedef enum +{ + SBC_VS_OV_NOEVENT = 0x00U, + SBC_VS_OV_EVENT +}; + +typedef enum +{ + SBC_VCC1_OV_NOEVENT = 0x00U, + SBC_VCC1_OV_EVENT +}; + +typedef enum +{ + SBC_VCC1_UV_PREWARN_NOEVENT = 0x00U, + SBC_VCC1_UV_PREWARN_EVENT +}; + + +/* -------------------------------- SUP_STAT_0 ----------------------------------- */ + +typedef enum +{ + SBC_POR_NOEVENT = 0x00U, + SBC_POR_EVENT +}; + +typedef enum +{ + SBC_VCC2_OT_NOEVENT = 0x00U, + SBC_VCC2_OT_EVENT +}; + +typedef enum +{ + SBC_VCC2_UV_NOEVENT = 0x00U, + SBC_VCC2_UV_EVENT +}; + +typedef enum +{ + SBC_VCC1_SC_NOEVENT = 0x00U, + SBC_VCC1_SC_TO_GND_EVENT +}; + +typedef enum +{ + SBC_VCC1_UV_NOEVENT = 0x00U, + SBC_VCC1_UV_EVENT +}; + + +/* -------------------------------- THERM_STAT ----------------------------------- */ + +typedef enum +{ + SBC_TSD2_SAFE_NOSAFESTATE = 0x00U, + SBC_TSD2_SAFE_SAFESTATE_DETECTED +}; + +typedef enum +{ + SBC_TSD2_NOEVENT = 0x00U, + SBC_TSD2_EVENT +}; + +typedef enum +{ + SBC_TSD1_NOEVENT = 0x00U, + SBC_TSD1_EVENT +}; + +typedef enum +{ + SBC_TPW_NOEVENT = 0x00U, + SBC_TPW_EVENT +}; + + +/* -------------------------------- DEV_STAT ------------------------------------- */ + +typedef enum +{ + SBC_DEV_STAT_CLEARED = 0x00U, + SBC_DEV_STAT_RESTART_AFTER_FAIL, + SBC_DEV_STAT_SLEEP_MODE +}; + +typedef enum +{ + SBC_WD_FAIL_NOFAIL = 0x00U, + SBC_WD_FAIL_1FAIL, + SBC_WD_FAIL_2FAIL +}; + +typedef enum +{ + SBC_SPI_FAIL_NOEVENT = 0x00U, + SBC_SPI_FAIL_EVENT +}; + +typedef enum +{ + SBC_FAILURE_NOEVENT = 0x00U, + SBC_FAILURE_EVENT +}; + + +/* -------------------------------- BUS_STAT ------------------------------------- */ + +typedef enum +{ + SBC_CANTO_NORMAL = 0x00U, + SBC_CANTO_TIMEOUT +}; + +typedef enum +{ + SBC_SYSERR_NOEVENT = 0x00U, + SBC_SYSERR_DETECTED +}; + +typedef enum +{ + SBC_CAN_FAIL_NO_FAIL = 0x00U, + SBC_CAN_FAIL_TSD, + SBC_CAN_FAIL_TXD_DOM_TO, + SBC_CAN_FAIL_BUS_DOM_TO +}; + +typedef enum +{ + SBC_VCAN_UV_NOEVENT = 0x00U, + SBC_VCAN_UV_EVENT +}; + + +/* -------------------------------- WK_STAT_0 ------------------------------------ */ + +typedef enum +{ + SBC_CAN_WU_NOEVENT = 0x00U, + SBC_CAN_WU_EVENT +}; + +typedef enum +{ + SBC_TIMER_WU_NOEVENT = 0x00U, + SBC_TIMER_WU_EVENT +}; + +typedef enum +{ + SBC_WK_WU_NOEVENT = 0x00U, + SBC_WK_WU_EVENT +}; + + +/* -------------------------------- WK_STAT_1 ------------------------------------ */ + +typedef enum +{ + SBC_GPIO_WK_WU_NOEVENT = 0x00U, + SBC_GPIO_WK_WU_EVENT +}; + + +/* -------------------------------- WK_LVL_STAT ---------------------------------- */ + +typedef enum +{ + SBC_DEV_LVL_NORMAL = 0x00U, + SBC_DEV_LVL_DEVELOPMENT_MODE +}; + +typedef enum +{ + SBC_CFG0_STATE_CONFIG_2_4 = 0x00U, + SBC_CFG0_STATE_CONFIG_1_3 +}; + +typedef enum +{ + SBC_GPIO_LVL_LOW = 0x00U, + SBC_GPIO_LVL_HIGH +}; + +typedef enum +{ + SBC_WK_LVL_LOW = 0x00U, + SBC_WK_LVL_HIGH +}; + + +/* -------------------------------- GPIO_OC_STAT --------------------------------- */ + +typedef enum +{ + SBC_GPIO_OC_NOEVENT = 0x00U, + SBC_GPIO_OC_EVENT +}; + + +/* -------------------------------- GPIO_OL_STAT --------------------------------- */ + +typedef enum +{ + SBC_GPIO_OL_NOEVENT = 0x00U, + SBC_GPIO_OL_EVENT +}; + + + + + + +/* ================================================================================ */ +/* ============= Selective Wake Status Registers Enumerations ============ */ +/* ================================================================================ */ + + + +/* -------------------------------- SWK_STAT ------------------------------------ */ + +typedef enum +{ + SBC_SYNC_NOT_SYNCHRONOUS = 0x00U, + SBC_SYNC_VALID_FRAME_RECEIVED +}; + +typedef enum +{ + SBC_CANSIL_NOT_EXCEEDED = 0x00U, + SBC_CANSIL_EXCEEDED +}; + +typedef enum +{ + SBC_SWK_SET_SWK_NOT_ACTIVE = 0x00U, + SBC_SWK_SET_SWK_ACTIVE +}; + +typedef enum +{ + SBC_WUP_NO_WUP = 0x00U, + SBC_WUP_DETECTED +}; + +typedef enum +{ + SBC_WUF_NO_WUF = 0x00U, + SBC_WUF_DETECTED +}; + + +/* -------------------------------- SWK_ECNT_STAT ------------------------------ */ + +typedef enum +{ + SBC_ECNT_NOEVENT = 0x00U, + SBC_ECNT_31_FRAME_ERRORS = 0x1FU, + SBC_ECNT_ERROR_OVERFLOW = 0x20U +}; + + +/* ================================================================================ */ +/* ======== Family and Product Information Registers Enumerations ======== */ +/* ================================================================================ */ + + + +/* -------------------------------- FAM_PROD_STAT ------------------------------- */ + +typedef enum +{ + SBC_FAM_DRIVER = 0x01U, + SBC_FAM_DCDC, + SBC_FAM_MIDRANGE, + SBC_FAM_MULTICAN, + SBC_FAM_LITE, + SBC_FAM_MIDRANGEPLUS = 0x07U +}; + +typedef enum +{ + SBC_PROD_TLE9461 = 0x06U, + SBC_PROD_TLE9461V33, + SBC_PROD_TLE9471 = 0x0EU, + SBC_PROD_TLE9471V33 +}; + + +#endif /* TLE94x1_DEFINES_H */ diff --git a/cva_asw_m0118/src/TLE9461/TLE94x1_ISR.h b/cva_asw_m0118/src/TLE9461/TLE94x1_ISR.h new file mode 100644 index 0000000..b40bbbe --- /dev/null +++ b/cva_asw_m0118/src/TLE9461/TLE94x1_ISR.h @@ -0,0 +1,127 @@ +/********************************************************************************************************************* + * Copyright (c) 2019, Infineon Technologies AG + * + * + * Distributed under the Boost Software License, Version 1.0. + * + * + * Boost Software License - Version 1.0 - August 17th, 2003 + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *********************************************************************************************************************/ + + +/****************************************************************************************************//** + * @file TLE94x1_ISR.h + * + * @brief Declaration file for ISR-Vectors and ISR related functions + * + * @version V1.0.0 + * @date 15. April 2019 + * @author Markus Noll / markus.noll@infineon.com + * @author Yannek Micha Rixen / Yannek.Rixen@infineon.com + *******************************************************************************************************/ + + + + +#ifndef TLE94x1_ISR_H +#define TLE94x1_ISR_H + + + + + + + +/* ================================================================================ */ +/* ============================ HEADER FILES ================================== */ +/* ================================================================================ */ + +#include "TLE94x1_DEFINES.h" + + + + + + + + +/* ================================================================================ */ +/* ================================ MACROS ==================================== */ +/* ================================================================================ */ + + +/** + * @def SBC_ISR_VECTOR + * + * @brief Vector defining the handling of interrupts. + * + * Vectors of this type have to be registered by the SBC_Register_Callback method. + */ +#define SBC_ISR_VECTOR(REG,MASK,POS,COMPARE) ((((uint32_t)REG) << 24) | (((uint32_t)MASK) << 16) | (((uint32_t)POS) << 8) | ((uint32_t)COMPARE)) + + + + + + +/* ================================================================================ */ +/* ======================= General Interrupt Defines ========================== */ +/* ================================================================================ */ + + + +/* Interrupts based on WK_STAT_0 and WK_STAT_1 register are always available */ +#define SBC_ISR_CAN_WU SBC_ISR_VECTOR(SBC_WK_STAT_0, SBC_WK_STAT_0_CAN_WU_Msk, SBC_WK_STAT_0_CAN_WU_Pos, SBC_CAN_WU_EVENT) +#define SBC_ISR_TIMER_WU SBC_ISR_VECTOR(SBC_WK_STAT_0, SBC_WK_STAT_0_TIMER_WU_Msk, SBC_WK_STAT_0_TIMER_WU_Pos, SBC_TIMER_WU_EVENT) +#define SBC_ISR_WK_WU SBC_ISR_VECTOR(SBC_WK_STAT_0, SBC_WK_STAT_0_WK_WU_Msk, SBC_WK_STAT_0_WK_WU_Pos, SBC_WK_WU_EVENT) +#define SBC_ISR_GPIO_WK_WU SBC_ISR_VECTOR(SBC_WK_STAT_1, SBC_WK_STAT_1_GPIO_WK_WU_Msk, SBC_WK_STAT_1_GPIO_WK_WU_Pos, SBC_GPIO_WK_WU_EVENT) + + +/* Following interrupts only usable if INT_GLOBAL bit is set to '1' */ +#define SBC_ISR_VS_UV SBC_ISR_VECTOR(SBC_SUP_STAT_1, SBC_SUP_STAT_1_VS_UV_Msk, SBC_SUP_STAT_1_VS_UV_Pos, SBC_VS_UV_EVENT) +#define SBC_ISR_VS_OV SBC_ISR_VECTOR(SBC_SUP_STAT_1, SBC_SUP_STAT_1_VS_OV_Msk, SBC_SUP_STAT_1_VS_OV_Pos, SBC_VS_OV_EVENT) +#define SBC_ISR_VCC1_OV SBC_ISR_VECTOR(SBC_SUP_STAT_1, SBC_SUP_STAT_1_VCC1_OV_Msk, SBC_SUP_STAT_1_VCC1_OV_Pos, SBC_VCC1_OV_EVENT) +#define SBC_ISR_VCC1_UV_PREWARN SBC_ISR_VECTOR(SBC_SUP_STAT_1, SBC_SUP_STAT_1_VCC1_WARN_Msk, SBC_SUP_STAT_1_VCC1_WARN_Pos, SBC_VCC1_UV_PREWARN_EVENT) +#define SBC_ISR_VCC2_OT SBC_ISR_VECTOR(SBC_SUP_STAT_0, SBC_SUP_STAT_0_VCC2_OT_Msk, SBC_SUP_STAT_0_VCC2_OT_Pos, SBC_VCC2_OT_EVENT) +#define SBC_ISR_VCC2_UV SBC_ISR_VECTOR(SBC_SUP_STAT_0, SBC_SUP_STAT_0_VCC2_UV_Msk, SBC_SUP_STAT_0_VCC2_UV_Pos, SBC_VCC2_UV_EVENT) +#define SBC_ISR_VCC1_UV SBC_ISR_VECTOR(SBC_SUP_STAT_0, SBC_SUP_STAT_0_VCC1_UV_Msk, SBC_SUP_STAT_0_VCC1_UV_Pos, SBC_VCC1_UV_EVENT) +#define SBC_ISR_TSD2_SAFESTATE SBC_ISR_VECTOR(SBC_THERM_STAT, SBC_THERM_STAT_TSD2_SAFE_Msk, SBC_THERM_STAT_TSD2_SAFE_Pos, SBC_TSD2_SAFE_SAFESTATE_DETECTED) +#define SBC_ISR_TSD1 SBC_ISR_VECTOR(SBC_THERM_STAT, SBC_THERM_STAT_TSD1_Msk, SBC_THERM_STAT_TSD1_Pos, SBC_TSD1_EVENT) +#define SBC_ISR_TPW SBC_ISR_VECTOR(SBC_THERM_STAT, SBC_THERM_STAT_TPW_Msk, SBC_THERM_STAT_TPW_Pos, SBC_TPW_EVENT) +#define SBC_ISR_RESTART_AFTER_FAIL SBC_ISR_VECTOR(SBC_DEV_STAT, SBC_DEV_STAT_DEV_STAT_Msk, SBC_DEV_STAT_DEV_STAT_Pos, SBC_DEV_STAT_RESTART_AFTER_FAIL) +#define SBC_ISR_FROM_SLEEPMODE SBC_ISR_VECTOR(SBC_DEV_STAT, SBC_DEV_STAT_DEV_STAT_Msk, SBC_DEV_STAT_DEV_STAT_Pos, SBC_DEV_STAT_SLEEP_MODE) +#define SBC_ISR_WD_FAIL_1 SBC_ISR_VECTOR(SBC_DEV_STAT, SBC_DEV_STAT_WD_FAIL_Msk, SBC_DEV_STAT_WD_FAIL_Pos, SBC_WD_FAIL_1FAIL) +#define SBC_ISR_WD_FAIL_2 SBC_ISR_VECTOR(SBC_DEV_STAT, SBC_DEV_STAT_WD_FAIL_Msk, SBC_DEV_STAT_WD_FAIL_Pos, SBC_WD_FAIL_2FAIL) +#define SBC_ISR_FAILURE SBC_ISR_VECTOR(SBC_DEV_STAT, SBC_DEV_STAT_FAILURE_Msk, SBC_DEV_STAT_FAILURE_Pos, SBC_FAILURE_EVENT) +#define SBC_ISR_CAN_TSD SBC_ISR_VECTOR(SBC_BUS_STAT, SBC_BUS_STAT_CAN_FAIL_Msk, SBC_BUS_STAT_CAN_FAIL_Pos, SBC_CAN_FAIL_TSD) +#define SBC_ISR_CAN_TXD_DOM_TO SBC_ISR_VECTOR(SBC_BUS_STAT, SBC_BUS_STAT_CAN_FAIL_Msk, SBC_BUS_STAT_CAN_FAIL_Pos, SBC_CAN_FAIL_TXD_DOM_TO) +#define SBC_ISR_CAN_BUS_DOM_TO SBC_ISR_VECTOR(SBC_BUS_STAT, SBC_BUS_STAT_CAN_FAIL_Msk, SBC_BUS_STAT_CAN_FAIL_Pos, SBC_CAN_FAIL_BUS_DOM_TO) +#define SBC_ISR_VCAN_UV SBC_ISR_VECTOR(SBC_BUS_STAT, SBC_BUS_STAT_VCAN_UV_Msk, SBC_BUS_STAT_VCAN_UV_Pos, SBC_VCAN_UV_EVENT) +#define SBC_ISR_GPIO_OC SBC_ISR_VECTOR(SBC_GPIO_OC_STAT, SBC_GPIO_OC_STAT_GPIO_OC_Msk, SBC_GPIO_OC_STAT_GPIO_OC_Pos, SBC_GPIO_OC_EVENT) +#define SBC_ISR_GPIO_OL SBC_ISR_VECTOR(SBC_GPIO_OL_STAT, SBC_GPIO_OL_STAT_GPIO_OL_Msk, SBC_GPIO_OL_STAT_GPIO_OL_Pos, SBC_GPIO_OL_EVENT) + + +#endif /*TLE94x1_ISR_H*/ diff --git a/cva_asw_m0118/src/TLE9461/TLE94x1_SPI.c b/cva_asw_m0118/src/TLE9461/TLE94x1_SPI.c new file mode 100644 index 0000000..b90577c --- /dev/null +++ b/cva_asw_m0118/src/TLE9461/TLE94x1_SPI.c @@ -0,0 +1,156 @@ +/********************************************************************************************************************* + * Copyright (c) 2019, Infineon Technologies AG + * + * + * Distributed under the Boost Software License, Version 1.0. + * + * + * Boost Software License - Version 1.0 - August 17th, 2003 + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *********************************************************************************************************************/ + + +/****************************************************************************************************//** + * @file TLE94x1_SPI.c + * + * @brief Implementation of all SPI related functions + * + * @version V1.0.0 + * @date 15. April 2019 + * @author Markus Noll / markus.noll@infineon.com + * @author Yannek Micha Rixen / Yannek.Rixen@infineon.com + *******************************************************************************************************/ + + + + +/* ================================================================================ */ +/* ============================ HEADER FILES ================================ */ +/* ================================================================================ */ + +#include "TLE94x1_SPI.h" +#include "mcu.h" + +void SPI_PortInit(void); + + + + +/* ================================================================================ */ +/* ======================= SPI communication functions ====================== */ +/* ================================================================================ */ + + +uint8_t spitxbuf[10],spirxbuf[10]; +extern McuType mcu; +uint8_t SBC_SPI_INIT(void) { + SpiDrv_InitCfgType masterCfg; + + SPI_PortInit(); + + SpiDrv_GetDefaultConfig(&masterCfg); + masterCfg.basicParameters.isMasterNode = true; + masterCfg.basicParameters.baudRate = 1000000ul; + masterCfg.basicParameters.pcsSelection = 1; + //masterCfg.basicParameters.clockPolarity = SPIDRV_CLK_POLARITY_IDLE_IN_HIGH; + masterCfg.basicParameters.clockPhase = SPIDRV_CLK_PHASE_DATA_SAMPLE_ON_TRAILING_EDGE; + + while(ClockDrv_GetFreq(&mcu.clockDrv, CLOCKDRV_SPI0, &masterCfg.basicParameters.busClockFreq) == false) + { + ; + } + SpiDrv_SetConfig(&mcu.spiDrv0, &masterCfg); + + SpiDrv_SetRxFifoWaterMask(&mcu.spiDrv0, 0); + //SpiDrv_SetIsrConfig(&mcu.spiDrv0, SPIDRV_ISR_SRC_RX_DATA, true); + + /* Enable the SPI interrupts */ + return 0; +} + + + +uint16_t SBC_SPI_TRANSFER16(uint8_t Upper, uint8_t Lower) { + uint16_t ret; + //LPSPI_DRV_SetPcs(LPSPICOM1,LPSPI_PCS0,LPSPI_ACTIVE_LOW); + spitxbuf[0] = Upper; + spitxbuf[1] = Lower; + + SpiDrv_MasterSyncTransfer(&mcu.spiDrv0,SPIDRV_FRAME_SIZE_BIT_TYPE_BYTE,2,spitxbuf,spirxbuf); + //LPSPI_DRV_MasterTransferBlocking(LPSPICOM1,spitxbuf,spirxbuf,2,10); + ret = spirxbuf[0]; + ret <<= 8; + ret |= spirxbuf[1]; + //LPSPI_DRV_SetPcs(LPSPICOM1,LPSPI_PCS0,LPSPI_ACTIVE_HIGH); + return ret; +} + + +/********************CVA SPI DRV**********************/ + +void SPI0_Handler(void) +{ + if(SpiDrv_GetStatus(&mcu.spiDrv0, SPIDRV_STATUS_RX_DATA) == true && SpiDrv_GetIsrConfig(&mcu.spiDrv0, SPIDRV_ISR_SRC_RX_DATA) == true) + { + //spi0IrqCnt++; + //uint8_t len = SpiDrv_AsyncReceive(&mcu.spiDrv0, (void *)masterRxBuff, true); + } +} + +void SPI_PortInit(void) +{ + /* SPI CS */ + PinsDrv_SetMuxModeSel(&mcu.ptb, 5, PINSDRV_MUX_ALT3); + /* Strength driver */ + PortReg_SetPcrDrvStr(mcu.ptb.port, 5, 1); + /* fast slew rate */ + PortReg_SetPcrSr(mcu.ptb.port, 5, 1); + + /* SPI CLK */ + PinsDrv_SetMuxModeSel(&mcu.ptb, 2, PINSDRV_MUX_ALT3); + /* Strength driver */ + PortReg_SetPcrDrvStr(mcu.ptb.port, 2, 1); + /* fast slew rate */ + PortReg_SetPcrSr(mcu.ptb.port, 2, 1); + + /* SPI SIN */ + PinsDrv_SetMuxModeSel(&mcu.ptb, 4, PINSDRV_MUX_ALT3); + /* Strength driver */ + PortReg_SetPcrDrvStr(mcu.ptb.port, 4, 1); + /* fast slew rate */ + PortReg_SetPcrSr(mcu.ptb.port, 4, 1); + + /* SPI SOUT */ + PinsDrv_SetMuxModeSel(&mcu.ptb, 3, PINSDRV_MUX_ALT3); + /* Strength driver */ + PortReg_SetPcrDrvStr(mcu.ptb.port, 3, 1); + /* fast slew rate */ + PortReg_SetPcrSr(mcu.ptb.port, 3, 1); +} + +void SPI_TEST_TASK(void) +{ + +} \ No newline at end of file diff --git a/cva_asw_m0118/src/TLE9461/TLE94x1_SPI.h b/cva_asw_m0118/src/TLE9461/TLE94x1_SPI.h new file mode 100644 index 0000000..abf88cc --- /dev/null +++ b/cva_asw_m0118/src/TLE9461/TLE94x1_SPI.h @@ -0,0 +1,95 @@ +/********************************************************************************************************************* + * Copyright (c) 2019, Infineon Technologies AG + * + * + * Distributed under the Boost Software License, Version 1.0. + * + * + * Boost Software License - Version 1.0 - August 17th, 2003 + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *********************************************************************************************************************/ + + +/****************************************************************************************************//** + * @file TLE94x1_SPI.h + * + * @brief Declaration file for TLE94x1 SBC family device SPI functions + * + * @version V1.0.0 + * @date 15. April 2019 + * @author Markus Noll / markus.noll@infineon.com + * @author Yannek Micha Rixen / Yannek.Rixen@infineon.com + *******************************************************************************************************/ + + + + +#ifndef TLE94x1_SPI_H +#define TLE94x1_SPI_H + + + + + + +/* ================================================================================ */ +/* ============================ HEADER FILES ================================ */ +/* ================================================================================ */ + +#include + + + +/* ================================================================================ */ +/* ============================= SPI Functions ============================== */ +/* ================================================================================ */ + +/** + * @brief IMPORTANT! THIS METHOD HAS TO BE DEFINED BY THE USER + * + * The function has to initialze the SPI of the uC and will be called once during SBC_Init(). + * In case, the SPI hardware is already initialized by some other code before, it can be left blank. + * + * @retval Method has to return 0 if initialization was successful. + */ +uint8_t SBC_SPI_INIT(void); + +/** + * @brief IMPORTANT! THIS METHOD HAS TO BE DEFINED BY THE USER + * + * The function will be called by the library everytime when a SPI communication is needed. + * The function proceeds a bidirectional 16-bit transfer to/from the SBC . + * As some UCs only supports 8-Bit transfers, the input arguments are split in two 8-bit arguments. + * For further implementation details have a look at datasheet chapter 13.1 or at the Arduino-examples. + * + * @param Upper The first 8 bit to transmit to the SBC. + * @param Lower The second 8 bit to transmit to the SBC. + * @retval The function will return all 16 bits received from the SBC. + * Bit[15:8] are the first 8 bits received (Status-Information-Field). + * Bit[7:0] is the data-field transmitted of the SBC. + */ +uint16_t SBC_SPI_TRANSFER16(uint8_t Upper, uint8_t Lower); + +#endif /* TLE94x1_SPI_H */ diff --git a/cva_asw_m0118/src/appTask.c b/cva_asw_m0118/src/appTask.c new file mode 100644 index 0000000..717d9af --- /dev/null +++ b/cva_asw_m0118/src/appTask.c @@ -0,0 +1,136 @@ +/******************************************************************************* + * the includes + ******************************************************************************/ +#include "appTask.h" +#include "canuser.h" +#include "uds_user.h" +#include "TLE94x1.h" +/******************************************************************************* + * the defines + ******************************************************************************/ +/* Indication value with boot loader request from asw */ +#define ASW_BOOT_REQ_ACTIVE (0x55AAAA55ul) +/* Asw code head id to show asw is not empty */ +#define ASW_HEAD_MASK (0xAABBCCDDul) + +#define ASW_VECTOR_START_ADDR 0xc000ul + +#define UDS_SEND_BUF (512) +#define UDS_RECV_BUF (2056) + + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ +#pragma location = ".bss.no_init" +static uint32_t sAswBoot_Req = 0; + + +McuType mcu; +volatile uint32_t gSystick1msEvent = 0, gSystick1msCnt = 0, gTestRunCnt = 0, gTestIoEn = 0, gSysTick1sCnt = 0; + +int64_t timer_1ms = 0; +uint8_t udsSendBuf[UDS_SEND_BUF] = {0}; +uint8_t udsRecvBuf[UDS_RECV_BUF] = {0}; +UdsType udsObj; +uint32_t rollingcounter=0; + + +Uds_ParamsType udsParam = { + .isotpParams.framePadding = true, + .isotpParams.blockSize = 0, + .isotpParams.recvPhysId = UDS_PHYS_RECV_MSG_ID, + .isotpParams.recvFuncId = UDS_FUNC_RECV_MSG_ID, + .isotpParams.sendid = UDS_PHYS_RESP_MSG_ID, + .isotpParams.sendBuf = udsSendBuf, + .isotpParams.sendBufSize = UDS_SEND_BUF, + .isotpParams.recvBuf = udsRecvBuf, + .isotpParams.recvBufSize = UDS_RECV_BUF, + .isotpParams.debug = NULL, + .isotpParams.sendCanMsg = FlexCanBoot_TxMessage, + .isotpParams.getTimeMs = Get_Cur_Time_Stamp, + .p2Server_ms = 50, + .p2xServer_10ms = 500, + .s3Server_ms = 5000, +}; + + + + + +/******************************************************************************* + * the functions + ******************************************************************************/ + + + +void Asw_SetBootloaderRequest(void) +{ + sAswBoot_Req = ASW_BOOT_REQ_ACTIVE; +} + +int64_t Get_Cur_Time_Stamp(void) +{ + return timer_1ms; +} + +void SysTick_Handler(void) +{ + gSystick1msEvent++; + timer_1ms++; + Uds_Tick(&udsObj); +} + +void appTaskInit(void) +{ + /* UDS init */ + Uds_UserInit(&udsObj, &udsParam); + +} + +void appTask(void) +{ + + if(gSystick1msEvent > 0u) + { + if(udsObj.session == UDS_SESSION_PROGRAMMING) + { + Asw_SetBootloaderRequest(); + ResetDrv_SoftwareResetModule(&mcu.resetDrv, RESETDRV_SWRESET_SYS); + } + + gSystick1msEvent--; + gSystick1msCnt++; + gSysTick1sCnt++; + CANMsgTask(); + if (gSystick1msCnt % 5 == 0) + { + + } + if (gSystick1msCnt % 50 == 0) + { + SBC_WD_Trigger();//喂狗 + } + if (gSystick1msCnt % 1000 == 0) + { + //TxTestMsg(NULL); + //uint8_t ret = SBC_Read_Command(SBC_M_S_CTRL);//sbc测试 + //SEGGER_RTT_printf(0,"%06d : M_S_CTRL = 0x%x\n",rollingcounter++,ret); + } + + + if (gSystick1msCnt >= 10000) + { + gSystick1msCnt = 0; + + } + + + + + } +} diff --git a/cva_asw_m0118/src/appTask.h b/cva_asw_m0118/src/appTask.h new file mode 100644 index 0000000..d88b443 --- /dev/null +++ b/cva_asw_m0118/src/appTask.h @@ -0,0 +1,38 @@ +#ifndef __APPTASK_H__ +#define __APPTASK_H__ + +/******************************************************************************* +* the includes +******************************************************************************/ +#include "Mcu.h" + +/******************************************************************************* +* the defines +******************************************************************************/ + + +/******************************************************************************* +* the typedefs +******************************************************************************/ + + +/******************************************************************************* +* the globals +******************************************************************************/ + + + + +/******************************************************************************* +* the functions +******************************************************************************/ +void appTask(void); +void appTaskInit(void); +int64_t Get_Cur_Time_Stamp(void); + + + + + +#endif + diff --git a/cva_asw_m0118/src/can_message.h b/cva_asw_m0118/src/can_message.h new file mode 100644 index 0000000..f347e65 --- /dev/null +++ b/cva_asw_m0118/src/can_message.h @@ -0,0 +1,47 @@ + +/** + * @file: can_message.h + * + * Purpose: Declare custom and register CAN datatype. + * + * $Authors: fcb $ + * + * $Copyright: $ + * + */ +#ifndef __CANMESSAGE__HEADER__ +#define __CANMESSAGE__HEADER__ + +#include + +/* @DO NOT REMOVE: The following typedef is required for targets (FM5, C166 etc.) to actually + use it for their code generation TLC file. Since their datatype is being + discarded, this is being defined in our header which they will be referencing.*/ +typedef enum {CAN_MESSAGE_STANDARD, CAN_MESSAGE_EXTENDED} CanFrameType; + +/* Define invalid CAN Identifier value. This can be used to specify invalid CAN Message + This represents a uint32_T value */ +#define INVALID_CAN_ID 0xFFFFFFFFU + +typedef struct +{ + + /* Is Extended frame */ + uint8_t IDE; + + /* Length */ + uint8_t DLC; + + /* CAN ID */ + uint32_t MsgId; + + /* Data field */ + uint8_t Data[8]; + +} CAN_MESSAGE; + +typedef CAN_MESSAGE CAN_DATATYPE; + + + +#endif diff --git a/cva_asw_m0118/src/canuser.c b/cva_asw_m0118/src/canuser.c new file mode 100644 index 0000000..16daf14 --- /dev/null +++ b/cva_asw_m0118/src/canuser.c @@ -0,0 +1,275 @@ +/******************************************************************************* + * the includes + ******************************************************************************/ +#include "canuser.h" +#include "appTask.h" +#include "can_message.h" +/******************************************************************************* + * the defines + ******************************************************************************/ + + + + + + + + + + +#define CAN_BUFFER_FIFO_SIZE (32u) + +/******************************************************************************* +* the typedefs +******************************************************************************/ + typedef enum +{ + UDS_MSG_IDX_STD_RX_PHYS, + UDS_MSG_IDX_STD_RX_FUNC, + UDS_MSG_IDX_STD_RX_TEST1, + UDS_MSG_IDX_STD_RX_TEST2, + UDS_MSG_IDX_STD_TX_TEST1, + UDS_MSG_IDX_STD_TX, + UDS_MSG_IDX_STD_TEST1, + UDS_MSG_IDX_STD_TEST2, + + UDS_MSG_IDX_NUM +} Uds_MsgIdIdxType; + + + +typedef struct +{ + FlexCan_FrameStructureType rxMsg[CAN_BUFFER_FIFO_SIZE]; + FlexCan_FrameStructureType txMsg[CAN_BUFFER_FIFO_SIZE]; + uint8_t wrIdx; + uint8_t rdIdx; +} FlexCan_DataInfoType; + + +/******************************************************************************* +* the globals +******************************************************************************/ +extern UdsType udsObj; + extern McuType mcu; + FlexCan_DataInfoType flexCan_DataInfo; +FlexCanDrv_ControllerCfgType flexCanCfg; +FlexCanDrvType* flexCanDrv_DemoObj; +uint8_t flexCanBoot_EnhanceRxFFCnt = 0; +uint8_t txMsgBuf[8] = {0}; +/******************************************************************************* +* the const +******************************************************************************/ + +const FlexCanDrv_MsgCfgType msgCfgObj[UDS_MSG_IDX_NUM] = { + {UDS_MSG_IDX_STD_RX_PHYS, 1, UDS_PHYS_RECV_MSG_ID, false, FLEXCANDRV_MSGTYPE_RX, DLC_BYTE_8, false, true, 0xFFFFFFFF}, /* CAN_MSGOBJ_STD_RX_PHYS */ + {UDS_MSG_IDX_STD_RX_FUNC, 1, UDS_FUNC_RECV_MSG_ID, false, FLEXCANDRV_MSGTYPE_RX, DLC_BYTE_8, false, true, 0xFFFFFFFF}, /* CAN_MSGOBJ_STD_RX_FUNC */ + {UDS_MSG_IDX_STD_RX_TEST1, 1, APP_RX_TEST1_MSG_ID, false, FLEXCANDRV_MSGTYPE_RX, DLC_BYTE_8, false, true, 0xFFFFFFFF}, /* CAN_MSGOBJ_STD_RX_FUNC */ + {UDS_MSG_IDX_STD_RX_TEST2, 1, APP_RX_TEST2_MSG_ID, false, FLEXCANDRV_MSGTYPE_RX, DLC_BYTE_8, false, true, 0xFFFFFFFF}, /* CAN_MSGOBJ_STD_RX_FUNC */ + {UDS_MSG_IDX_STD_TX, 1, UDS_PHYS_RESP_MSG_ID, false, FLEXCANDRV_MSGTYPE_TX, DLC_BYTE_8, false, false, 0xFFFFFFFF}, /* CAN_MSGOBJ_STD_TX */ + {UDS_MSG_IDX_STD_TEST1, 1, APP_TX_TEST1_MSG_ID, false, FLEXCANDRV_MSGTYPE_TX, DLC_BYTE_8, false, false, 0xFFFFFFFF}, /* CAN_MSGOBJ_STD_TX */ + {UDS_MSG_IDX_STD_TEST2, 1, APP_TX_TEST2_MSG_ID, false, FLEXCANDRV_MSGTYPE_TX, DLC_BYTE_8, false, false, 0xFFFFFFFF}, /* CAN_MSGOBJ_STD_TX */ +}; + + + /******************************************************************************* + * the functions + ******************************************************************************/ + +void CAN_ORed_0_31_MB_Handler(void) +{ + uint8_t i = 0; + FlexCanDrv_MsgObjType msgObj; + + for(i = 0; i < flexCanCfg.msgNum; i++) + { + msgObj.msgBufId = i; + + if(FlexCanDrv_GetMsgObjFlag(flexCanDrv_DemoObj, &msgObj)) + { + if(flexCanCfg.msgCfg[i].msgType == FLEXCANDRV_MSGTYPE_RX) + { + /* clear message buffer interrupt flag */ + FlexCanDrv_ClearMsgObjFlag(flexCanDrv_DemoObj, &msgObj); + + /* get the new message data */ + FlexCanDrv_GetRxMsg(flexCanDrv_DemoObj, &msgObj); + + memcpy(flexCan_DataInfo.rxMsg[flexCan_DataInfo.wrIdx].data, msgObj.data, msgObj.dlc); + flexCan_DataInfo.rxMsg[flexCan_DataInfo.wrIdx].id = msgObj.msgId; + flexCan_DataInfo.rxMsg[flexCan_DataInfo.wrIdx].len = msgObj.dlc; + flexCan_DataInfo.wrIdx++; + if(flexCan_DataInfo.wrIdx >= CAN_BUFFER_FIFO_SIZE) + { + flexCan_DataInfo.wrIdx = 0; + } + } + else + { + /* clear message buffer interrupt flag */ + FlexCanDrv_ClearMsgObjFlag(flexCanDrv_DemoObj, &msgObj); + } + } + } +} + +bool FlexCanBoot_ReadoutMsg(FlexCan_FrameStructureType *pRxMsgObj) +{ + bool ret = false; + + if(flexCan_DataInfo.wrIdx != flexCan_DataInfo.rdIdx) + { + memcpy(pRxMsgObj, &flexCan_DataInfo.rxMsg[flexCan_DataInfo.rdIdx], sizeof(FlexCan_FrameStructureType)); + flexCan_DataInfo.rdIdx++; + if(flexCan_DataInfo.rdIdx >= CAN_BUFFER_FIFO_SIZE) + { + flexCan_DataInfo.rdIdx = 0; + } + + ret = true; + } + + return ret; +} + +int8_t FlexCanBoot_TxMessage(uint32_t msgId, const uint8_t *pData, uint8_t size) +{ + FlexCanDrv_MsgObjType txMsgObj; + uint8_t msgIdx = 0, i = 0; + + for(i = 0; i < flexCanCfg.msgNum; i++) + { + if(msgId == flexCanCfg.msgCfg[i].msgId) + { + msgIdx = i; + break; + } + } + + txMsgObj.msgBufId = flexCanCfg.msgCfg[msgIdx].msgBufId; + txMsgObj.dlc = size; + txMsgObj.msgId = flexCanCfg.msgCfg[msgIdx].msgId; + memcpy(&txMsgObj.data[0], pData, size); + + FlexCanDrv_SetTxMsg(flexCanDrv_DemoObj, &txMsgObj); + /* transmit standard CAN Tx message */ + FlexCanDrv_TransmitMsg(flexCanDrv_DemoObj, &txMsgObj); + + return 0; +} + +void FlexCanBoot_Init(void) +{ + uint32_t busClockFreq = 0; + + /* CAN init */ + memset(&flexCan_DataInfo, 0, sizeof(flexCan_DataInfo)); + memset(&flexCanCfg, 0, sizeof(flexCanCfg)); + + flexCanDrv_DemoObj = &mcu.flexCanDrv; + + /* set PTC1 MUX as GPIO */ + PinsDrv_SetMuxModeSel(&mcu.ptc, 5, PINSDRV_MUX_AS_GPIO); + /* set PTC1 as GPIO output */ + PinsDrv_SetPinDirection(&mcu.ptc, 5, 1); + /* set PTC1 as high to control CAN transceiver STB */ + PinsDrv_WritePin(&mcu.ptc, 5, 1); + + /* set PTE4 as MUX 5 - CAN0.RX */ + PinsDrv_SetMuxModeSel(&mcu.ptb, 0, PINSDRV_MUX_ALT5); + + /* set PTE5 as MUX 5 - CAN0.TX */ + PinsDrv_SetMuxModeSel(&mcu.ptb, 1, PINSDRV_MUX_ALT5); + + /* get CAN controller default configuration */ + FlexCanDrv_GetDefaultCfg(&flexCanCfg); + flexCanCfg.msgNum = sizeof(msgCfgObj) / sizeof(FlexCanDrv_MsgCfgType); + flexCanCfg.msgCfg = msgCfgObj; + + flexCanCfg.clkSrc = FLEXCANDRV_CLKSRC_CHICLK; + flexCanCfg.fdEnable = false; + flexCanCfg.fdISOEnable = false; + flexCanCfg.fifoEnable = false; + flexCanCfg.msgBufDataLenSel = FLEXCANDRV_MB_SIZE_BYTE_8; + flexCanCfg.individualMaskEnable = true; + + if(flexCanCfg.clkSrc == FLEXCANDRV_CLKSRC_CHICLK) + { + ClockDrv_GetFreq(&mcu.clockDrv, CLOCKDRV_APB, &busClockFreq); + } + else + { + ClockDrv_GetFreq(&mcu.clockDrv, CLOCKDRV_SOSC_DIV, &busClockFreq); + } + + if(flexCanCfg.fdEnable == true) + { + FlexCanDrv_BitTimingCalc(&flexCanCfg.fdBitTiming, + busClockFreq, /* module clock source: 16M */ + 2000000, /* baudrate: 2M */ + 7500, /* sample point: 75% */ + 2000, /* SJW: 20% */ + 1); /* FD bit timing */ + } + + FlexCanDrv_BitTimingCalc(&flexCanCfg.bitTiming, + busClockFreq, /* module clock source: 16M */ + 500000, /* baudrate: 500K */ + 7500, /* sample point: 75% */ + 2500, /* SJW: 20% */ + 0); /* classic CAN bit timing */ + + /* initialize CAN module */ + FlexCanDrv_Configure(flexCanDrv_DemoObj, &flexCanCfg); + + /* enable rx interrupt */ + IrqDrv_EnableIrq(CAN_ORed_0_31_MB_IRQn); +} + +static void TxMessage(CAN_MESSAGE* msg) +{ + FlexCanBoot_TxMessage(msg->MsgId, msg->Data, msg->DLC); +} + +void TxTestMsg(uint8_t *pdata) +{ + uint8_t txMsgBuf[8] = {0}; + if (pdata != NULL) + { + memcpy(txMsgBuf,pdata,8); + } + + FlexCanBoot_TxMessage(APP_TX_TEST2_MSG_ID, txMsgBuf, 8); + //SEGGER_RTT_printf(0,"test data\n"); +} + +void CANMsgTask(void)//1ms task +{ + static uint16_t msg_counter=0; + FlexCan_FrameStructureType rxMsg; + msg_counter++; + if (msg_counter % 100 == 0) + { + TxTestMsg(NULL); + } + + if (msg_counter >= 1000) + { + msg_counter = 0; + } + /* Handler user routine */ + if(FlexCanBoot_ReadoutMsg(&rxMsg) == true) + { + if((rxMsg.id == UDS_PHYS_RECV_MSG_ID) || (rxMsg.id == UDS_FUNC_RECV_MSG_ID)) + { + IsoTp_HandleIncomingCanMsg(&udsObj.isotp, rxMsg.id, rxMsg.data, rxMsg.len); + } + else + { + //scm_canmatrix_Receive(&scm_canmatrix_rx,rxMsg.data,rxMsg.id,rxMsg.len); + //参考 + } + } + + Uds_Run(&udsObj); +} \ No newline at end of file diff --git a/cva_asw_m0118/src/canuser.h b/cva_asw_m0118/src/canuser.h new file mode 100644 index 0000000..86307b9 --- /dev/null +++ b/cva_asw_m0118/src/canuser.h @@ -0,0 +1,59 @@ +#ifndef __CANUSER_H__ +#define __CANUSER_H__ + + + +/******************************************************************************* + * the includes + ******************************************************************************/ +#include "mcu.h" +#include "uds.h" + +/******************************************************************************* +* the defines +******************************************************************************/ +#define CAN_DATA_BUFFER_SIZE (64u) + +#define UDS_PHYS_RECV_MSG_ID (0x732) +#define UDS_FUNC_RECV_MSG_ID (0x7DF) +#define UDS_PHYS_RESP_MSG_ID (0x7B2) + +#define APP_TX_TEST1_MSG_ID (0x111) +#define APP_TX_TEST2_MSG_ID (0x222) +#define APP_RX_TEST1_MSG_ID (0x444) +#define APP_RX_TEST2_MSG_ID (0x555) + + /******************************************************************************* + * the typedefs + ******************************************************************************/ + typedef struct +{ + uint32_t id; + uint8_t data[CAN_DATA_BUFFER_SIZE]; + uint8_t len; + uint16_t timeStamp; + uint32_t hrTimeStamp; +} FlexCan_FrameStructureType; + + /******************************************************************************* + * the globals + ******************************************************************************/ + + + + + /******************************************************************************* + * the functions + ******************************************************************************/ + +void FlexCanBoot_Init(void); +bool FlexCanBoot_ReadoutMsg(FlexCan_FrameStructureType *pRxMsgObj); +int8_t FlexCanBoot_TxMessage(uint32_t msgId, const uint8_t* pData, uint8_t size); + +void CANMsgTask(void); +void TxTestMsg(uint8_t *data); + + +#endif + + diff --git a/cva_asw_m0118/src/extern.c b/cva_asw_m0118/src/extern.c new file mode 100644 index 0000000..d1a741b --- /dev/null +++ b/cva_asw_m0118/src/extern.c @@ -0,0 +1,102 @@ + +/******************************************************************************* + * the includes + ******************************************************************************/ +#include "extern.h" +#include "TLE94x1.h" +#include +#include "drivers/reset/reset_drv.h" +#include "mcu.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ +#define ASW_HEAD_MASK (0xAABBCCDDul) + + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +typedef struct +{ + uint8_t HWVersion[4]; + uint8_t BLVersion[8]; + uint8_t bootBuildTime[12]; + uint8_t bootBuildDate[16]; + uint8_t ECUName[8]; + uint8_t Reverse[16]; +} Bootloade_CfgInfoType;//64 byte + +typedef struct +{ + uint32_t sAswHeader; + uint8_t appBuildTime[12]; + uint8_t appBuildDate[16]; + uint8_t appSW_VERSION[16]; + uint8_t reverse[16]; +} app_CfgInfoType;//64 byte + +/******************************************************************************* + * the globals + ******************************************************************************/ + +extern McuType mcu; + +/******************************************************************************* + * the constants + ******************************************************************************/ +#pragma location = ".asw_header" +__root const app_CfgInfoType app_info = { + .sAswHeader = ASW_HEAD_MASK,//0x00010400 + .appBuildTime = __TIME__,//0x00010404 + .appBuildDate = __DATE__,//0x00010410 + .appSW_VERSION = "SW0101_20241211", +}; + + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void getSW_VERSION(unsigned char *pdata) +{ + memcpy(pdata, &(app_info.appSW_VERSION), sizeof(app_info.appSW_VERSION)); +} + +void getHW_VERSION(unsigned char *pdata) +{ + Bootloade_CfgInfoType * PBootInfo; + PBootInfo = (Bootloade_CfgInfoType *)0x00000C0; + memcpy(pdata, &(PBootInfo->HWVersion), sizeof(PBootInfo->HWVersion)); + //memcpy(pdata, HW_VERSION, ); +} + +void getBuildTime(unsigned char *pdata) +{ + memcpy(pdata, &(app_info.appBuildDate), 12); + memcpy(pdata + 12, &(app_info.appBuildTime), 8); + pdata[11] = ' '; +} + +void getBL_VERSION(unsigned char *pdata) +{ + Bootloade_CfgInfoType * PBootInfo; + PBootInfo = (Bootloade_CfgInfoType *)0x00000C0; + memcpy(pdata, &(PBootInfo->BLVersion), sizeof(PBootInfo->BLVersion)); +} + +void getEcuName(unsigned char *pdata) +{ + Bootloade_CfgInfoType * PBootInfo; + PBootInfo = (Bootloade_CfgInfoType *)0x00000C0; + memcpy(pdata, &(PBootInfo->ECUName), sizeof(PBootInfo->ECUName)); +} + +void extHardwareReset(void) +{ + SBC_Write_RegField(SBC_M_S_CTRL, SBC_M_S_CTRL_MODE_Msk, SBC_M_S_CTRL_MODE_Pos, SBC_MODE_RESET, NULL); +} +void extSortwareReset(void) +{ + ResetDrv_SoftwareResetModule(&mcu.resetDrv,RESETDRV_SWRESET_SYS); +} \ No newline at end of file diff --git a/cva_asw_m0118/src/extern.h b/cva_asw_m0118/src/extern.h new file mode 100644 index 0000000..598a13c --- /dev/null +++ b/cva_asw_m0118/src/extern.h @@ -0,0 +1,18 @@ +#ifndef __EXTERN_H__ +#define __EXTERN_H__ + + +void getSW_VERSION(unsigned char *pdata); +void getHW_VERSION(unsigned char *pdata); +void getBL_VERSION(unsigned char *pdata); +void getBuildTime(unsigned char *pdata); +void getEcuName(unsigned char *pdata); + +void extHardwareReset(void); +void extSortwareReset(void); + + + +#endif + + diff --git a/cva_asw_m0118/src/hwctrl.c b/cva_asw_m0118/src/hwctrl.c new file mode 100644 index 0000000..76fffcd --- /dev/null +++ b/cva_asw_m0118/src/hwctrl.c @@ -0,0 +1,106 @@ +/******************************************************************************* + * the includes + ******************************************************************************/ +#include "hwctrl.h" +#include "canuser.h" +#include "TLE94x1.h" +/******************************************************************************* + * the defines + ******************************************************************************/ + + + /******************************************************************************* + * the typedefs + ******************************************************************************/ + + + /******************************************************************************* + * the globals + ******************************************************************************/ + extern McuType mcu; + uint32_t gCpuClockFrequency = 0; + + /******************************************************************************* + * the const + ******************************************************************************/ + + + + /******************************************************************************* + * the functions + ******************************************************************************/ +static void hw_clock_init(void); + + + + +void hw_init(void) +{ + /* Initialize all MCU drivers: flash drv included */ + Mcu_Init(&mcu); + + WdgDrv_Disable(&mcu.wdgDrv); + + //初始化时钟 + hw_clock_init(); + + SBC_SPI_INIT(); + + + + /* get CAN controller default configuration */ + FlexCanBoot_Init(); + + SBC_Init(); +} + +static void hw_clock_init(void) +{ + /* Setup the clock */ + ClockDrv_ModuleClkConfigType clockConfig; + + /* Setup the Pll div2 clock */ + clockConfig.gating = true; + clockConfig.source = CLOCKDRV_PLL; + clockConfig.div = 1; + ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PLL_DIV, &clockConfig); + + /* Enable the clock for all port peripheral */ + clockConfig.gating = true; + clockConfig.div = 1; + ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PORTA, &clockConfig); + ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PORTB, &clockConfig); + ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PORTC, &clockConfig); + ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PORTD, &clockConfig); + ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PORTE, &clockConfig); + + /* Setup the Pll div2 clock */ + clockConfig.gating = true; + clockConfig.source = CLOCKDRV_PLL; + clockConfig.div = 1; + ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PLL_DIV, &clockConfig); + + clockConfig.gating = true; + clockConfig.source = CLOCKDRV_PLL; + clockConfig.div = 2; + ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PLL_DIV, &clockConfig); + + /* Setup the SPI clock */ + clockConfig.gating = true; + clockConfig.source = CLOCKDRV_PLL_DIV; + ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_SPI0, &clockConfig); + + uint32_t tTcr = SpiReg_GetTcr((const SpiRegType *)&mcu.spiDrv0.reg); + SpiDrv_SetPrescaler(&tTcr,0x02); + + /* Set system tick clock, 1ms event */ + ClockDrv_GetFreq(&mcu.clockDrv, CLOCKDRV_SYS, &gCpuClockFrequency); + SysTick_Config(gCpuClockFrequency / 1000u); + + IrqDrv_EnableIrq(SysTick_IRQn); + + +} + + + diff --git a/cva_asw_m0118/src/hwctrl.h b/cva_asw_m0118/src/hwctrl.h new file mode 100644 index 0000000..2ae9450 --- /dev/null +++ b/cva_asw_m0118/src/hwctrl.h @@ -0,0 +1,34 @@ +#ifndef __HWCTRL_H__ +#define __HWCTRL_H__ + +/******************************************************************************* + * the includes + ******************************************************************************/ +#include "mcu.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + + + /******************************************************************************* + * the typedefs + ******************************************************************************/ + + + /******************************************************************************* + * the globals + ******************************************************************************/ + + + + + /******************************************************************************* + * the functions + ******************************************************************************/ +void hw_init(void); + + + + +#endif diff --git a/cva_asw_m0118/src/main.c b/cva_asw_m0118/src/main.c new file mode 100644 index 0000000..ebdee43 --- /dev/null +++ b/cva_asw_m0118/src/main.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/*! \brief a loop memory to memory transfer + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "mcu.h" +#include "SEGGER_RTT.h" +#include "appTask.h" +#include "canuser.h" +#include "hwctrl.h" +/******************************************************************************* + * the defines + ******************************************************************************/ + + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + + + + + +/******************************************************************************* + * the functions + ******************************************************************************/ + + + +int main(void) +{ + + IrqDrv_DisableGlobalInterrupt(); + + hw_init(); + + + SEGGER_RTT_Init(); + SEGGER_RTT_printf(0,"app start\n"); + + IrqDrv_EnableGlobalInterrupt(); + appTaskInit(); + + while(1) + { + appTask(); + } +} diff --git a/cva_asw_m0118/src/private_driver/drivers/cpu/startup/app_startup_M011x.S b/cva_asw_m0118/src/private_driver/drivers/cpu/startup/app_startup_M011x.S new file mode 100644 index 0000000..9b8ff31 --- /dev/null +++ b/cva_asw_m0118/src/private_driver/drivers/cpu/startup/app_startup_M011x.S @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/*****************************************************************************/ +/* Version: GNU Compiler Collection */ +/*****************************************************************************/ + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:ROOT(2) + + EXTERN main + EXTERN SystemInit + EXTERN init_data_bss + EXTERN __iar_program_start + PUBLIC __vector_table + PUBLIC __vector_table_0x1c + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA + +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; Non Maskable Interrupt + DCD HardFault_Handler ; Cortex-M0 SV Hard Fault Interrupt + DCD 0 + DCD 0 + DCD 0 +__vector_table_0x1c + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD SVC_Handler ; Cortex-M0 SV Call Interrupt + DCD 0 + DCD 0 + DCD PendSV_Handler ; Cortex-M0 Pend SV Interrupt + DCD SysTick_Handler ; Cortex-M0 System Tick Interrupt + + + DCD DMA01_Handler /* 0 (040H) DMA channel 0,1 transfer complete*/ + DCD DMA23_Handler /* 1 (044H) DMA channel 2,3 transfer complete*/ + DCD DMA_Error_Handler /* 2 (048H) DMA error interrupt channels 0-3*/ + DCD FHU_Handler /* 3 (04CH) FHU Interrupt, ERM single bit error correction*/ + DCD RTC_Alarm_Handler /* 4 (050H) RTC alarm interrupt*/ + DCD RTC_Seconds_Handler /* 5 (054H) RTC seconds interrupt*/ + DCD LPTMR_Handler /* 6 (058H) LPTIMER interrupt request*/ + DCD PORT_Handler /* 7 (05CH) Port ABCDE pin detect interrupt */ + DCD CAN_ORed_Handler /* 8 (060H) CAN OR'ed [BusOff\BusOffDone\TransWarning\ReceiveWarning\..... ] */ + DCD CAN_ORed_0_31_MB_Handler /* 9 (064H) CAN OR'ed Message buffer (0-31) */ + DCD CAN_ORed_32_63_MB_Handler /* 10 (068H) CAN OR'ed Message buffer (32-63) */ + DCD MFT0_Ch0_Ch7_Handler /* 11 (06CH) MFT0 Channel 0 to 7 interrupt */ + DCD MFT0_Fault_Handler /* 12 (070H) MFT0 Fault interrupt */ + DCD MFT0_Ovf_Reload_Handler /* 13 (074H) MFT0 Counter overflow and Reload interrupt */ + DCD MFT1_Ch0_Ch7_Handler /* 14 (078H) MFT1 Channel 0 to 7 interrupt */ + DCD MFT1_Fault_Handler /* 15 (07CH) MFT1 Fault interrupt */ + DCD MFT1_Ovf_Reload_Handler /* 16 (080H) MFT1 Counter overflow and Reload interrupt */ + DCD FTFC_Handler /* 17 (084H) FTFC Command done,read collision,err response interrupt */ + DCD PDB_Handler /* 18 (088H) PDB interrupt */ + DCD LPIT_Handler /* 19 (08CH) LPIT interrupt */ + DCD CMU_Handler /* 20 (090H) CMU PLL,SOSC interrupt */ + DCD WDOG_Handler /* 21 (094H) Interrupt request out before wdg reset out */ + DCD RCM_Handler /* 22 (098H) RCM Asynchronous Interrupt, Reset interrutpt */ + DCD I2C_Handler /* 23 (09CH) I2C Interrupt */ + DCD SPI0_Handler /* 24 (0A0H) SPI0 Interrupt */ + DCD SPI1_Handler /* 25 (0A4H) SPI1 Interrupt */ + DCD ADC_Handler /* 26 (0A8H) ADC interrupt request. */ + DCD CMP_Handler /* 27 (0ACH) CMP interrupt request */ + DCD I2S_SLV_MST_Handler /* 28 (0B0H) I2S Slave and Master interrupt */ + DCD UART0_RxTx_Handler /* 29 (0B4H) UART0 Transmit / Receive Interrupt */ + DCD UART1_RxTx_Handler /* 30 (0B8H) UART1 Transmit / Receive Interrupt */ + DCD UART2_RxTx_Handler /* 31 (0BCH) UART2 Transmit / Receive Interrupt */ +__Vectors_End + +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:REORDER:NOROOT(2) +Reset_Handler + CPSID I ; Mask interrupts + ;; Init the rest of the registers + LDR R1,=0 + LDR R2,=0 + LDR R3,=0 + LDR R4,=0 + LDR R5,=0 + LDR R6,=0 + LDR R7,=0 + MOV R8,R7 + MOV R9,R7 + MOV R10,R7 + MOV R11,R7 + MOV R12,R7 + +#ifdef START_FROM_FLASH + IMPORT __RAM_START, __RAM_END + ;; INIT ECC RAM + + LDR R1, =__RAM_START + LDR R2, =__RAM_END + + SUBS R2, R2, R1 + SUBS R2, #1 + BLE .LC5 + + MOVS R0, #0 + MOVS R3, #4 + .LC4: + STR R0, [R1] + ADD R1, R1, R3 + SUBS R2, #4 + BGE .LC4 + .LC5: +#endif + ;; Initialize the stack pointer + LDR R0, =sfe(CSTACK) + MOV R13,R0 + +#ifndef __NO_SYSTEM_INIT + ;; Call the CMSIS system init routine + LDR R0, =SystemInit + BLX R0 +#endif + + ;; Init .data and .bss sections + LDR R0, =init_data_bss + BLX R0 + CPSIE I ; Unmask interrupts + BLX __iar_program_start + BLX R0 + BL main +JumpToSelf + B JumpToSelf + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler + B . + + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +HardFault_Handler + B . + + + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SVC_Handler + B . + + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +PendSV_Handler + B . + + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SysTick_Handler + B . + + PUBWEAK DMA01_Handler + PUBWEAK DMA23_Handler + PUBWEAK DMA_Error_Handler + PUBWEAK FHU_Handler + PUBWEAK RTC_Alarm_Handler + PUBWEAK RTC_Seconds_Handler + PUBWEAK LPTMR_Handler + PUBWEAK PORT_Handler + PUBWEAK CAN_ORed_Handler + PUBWEAK CAN_ORed_0_31_MB_Handler + PUBWEAK CAN_ORed_32_63_MB_Handler + PUBWEAK MFT0_Ch0_Ch7_Handler + PUBWEAK MFT0_Fault_Handler + PUBWEAK MFT0_Ovf_Reload_Handler + PUBWEAK MFT1_Ch0_Ch7_Handler + PUBWEAK MFT1_Fault_Handler + PUBWEAK MFT1_Ovf_Reload_Handler + PUBWEAK FTFC_Handler + PUBWEAK PDB_Handler + PUBWEAK LPIT_Handler + PUBWEAK CMU_Handler + PUBWEAK WDOG_Handler + PUBWEAK RCM_Handler + PUBWEAK I2C_Handler + PUBWEAK SPI0_Handler + PUBWEAK SPI1_Handler + PUBWEAK ADC_Handler + PUBWEAK CMP_Handler + PUBWEAK I2S_SLV_MST_Handler + PUBWEAK UART0_RxTx_Handler + PUBWEAK UART1_RxTx_Handler + PUBWEAK UART2_RxTx_Handler + PUBWEAK DefaultISR + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler +HardFault_Handler +SVC_Handler +PendSV_Handler +SysTick_Handler +DMA01_Handler +DMA23_Handler +DMA_Error_Handler +FHU_Handler +RTC_Alarm_Handler +RTC_Seconds_Handler +LPTMR_Handler +PORT_Handler +CAN_ORed_Handler +CAN_ORed_0_31_MB_Handler +CAN_ORed_32_63_MB_Handler +MFT0_Ch0_Ch7_Handler +MFT0_Fault_Handler +MFT0_Ovf_Reload_Handler +MFT1_Ch0_Ch7_Handler +MFT1_Fault_Handler +MFT1_Ovf_Reload_Handler +FTFC_Handler +PDB_Handler +LPIT_Handler +CMU_Handler +WDOG_Handler +RCM_Handler +I2C_Handler +SPI0_Handler +SPI1_Handler +ADC_Handler +CMP_Handler +I2S_SLV_MST_Handler +UART0_RxTx_Handler +UART1_RxTx_Handler +UART2_RxTx_Handler +DefaultISR + + END diff --git a/cva_asw_m0118/src/private_driver/drivers/cpu/startup/app_system_M011x.c b/cva_asw_m0118/src/private_driver/drivers/cpu/startup/app_system_M011x.c new file mode 100644 index 0000000..2d0205a --- /dev/null +++ b/cva_asw_m0118/src/private_driver/drivers/cpu/startup/app_system_M011x.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "drivers/cpu/startup/system_M011x.h" +#include "drivers/cpu/cpu_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void SystemInit(void) +{ +#if 0 + /* PFLASH prefetch */ + SimReg_SetFlashPFlsFlushEn(SIM, 1); /* Flush PFLASH prefetch */ + SimReg_SetFlashPFlsPfbEn(SIM, 1); /* Enable PFLASH prefetch*/ + + /* Unlock SCG */ + Scg0Reg_SetKey(SCG0, 0x19962020); + +#ifdef _USE_EXT_OSC_ + /* Use External oscillator */ + Scg0Reg_SetOscCtrlRange(SCG0, 1); /* set SOSC frequency range(use max value when SOSC as the clock source of the PLL) */ + Scg0Reg_SetOscCtrlEnSosc(SCG0, 1); /* enable SOSC */ + while(Scg0Reg_GetStatusSoscRdy(SCG0) == 0) + { + ; /* wait until SOSC is ready */ + } + + /* Disable PLL */ + Scg0Reg_SetPllCtrl0PllEn(SCG0, 0); + /* PLL configuration: + * - PLL input clock source : SOSC + * - PLL pre-divider : 1 + * - feedback divider : 40 + * - PLL Feedback clock divider pre-scaler : 1 + * - PLL post-divider setting : 4 + * Final PLL output frequency is 8M(SOSC) * 40 / 4 / 2 = 80M + */ + Scg0Reg_SetPllCtrl1PllClkinSel(SCG0, 0); + Scg0Reg_SetPllCtrl0PllPreDiv(SCG0, 0); + Scg0Reg_SetPllCtrl0PllM(SCG0, 80); + Scg0Reg_SetPllCtrl0PllFdkSel(SCG0, 0); + Scg0Reg_SetPllCtrl0PllPosDiv(SCG0, 4); + /* Enable PLL */ + Scg0Reg_SetPllCtrl0PllEn(SCG0, 1); + + /* Use systick for delay */ + SysTick->LOAD = 8000U; + SysTick->VAL = 0U; + SysTick->CTRL = 5U; /* SysTick uses the processor clock and enable sysTick */ + while(SysTick->CTRL < 0x10000){ + ;/* wait for COUNTFLAG setting*/ + } + /*recover sysTick register*/ + SysTick->CTRL = 4U; + SysTick->LOAD = 0U; + SysTick->VAL = 0U; + + while(Scg0Reg_GetStatusPllLock(SCG0) == 0) + { + ; + } + + /* Flash AHB bus read access time configure */ + FtfcReg_SetFcnfgBusReadTm(FTFC, 1); /* 2T required for 80M AHB */ + + /* Set clk_pll as system clock */ + Scg2Reg_SetCsrSrcSys(SCG2, 2); + while(Scg2Reg_GetCsrSysSt(SCG2) != 2) + { + ; + } +#else + /* Disable PLL */ + Scg0Reg_SetPllCtrl0PllEn(SCG0, 0); + /* PLL configuration: + * - PLL input clock source : SIRC + * - PLL pre-divider : 1 + * - feedback divider : 80 + * - PLL Feedback clock divider pre-scaler : 1 + * - PLL post-divider setting : 4 + * Final PLL output frequency is 8M(SIRC) * 80 / 4 / 2 = 80M + */ + Scg0Reg_SetPllCtrl1PllClkinSel(SCG0, 1); + Scg0Reg_SetPllCtrl0PllPreDiv(SCG0, 0); + Scg0Reg_SetPllCtrl0PllM(SCG0, 80); + Scg0Reg_SetPllCtrl0PllFdkSel(SCG0, 0); + Scg0Reg_SetPllCtrl0PllPosDiv(SCG0, 4); + /* Enable PLL */ + Scg0Reg_SetPllCtrl0PllEn(SCG0, 1); + while(Scg0Reg_GetStatusPllLock(SCG0) == 0) + { + ; + } + + /* Flash AHB bus read access time configure */ + FtfcReg_SetFcnfgBusReadTm(FTFC, 1); /* 2T required for 80M AHB */ + + /* Set clk_pll as system clock */ + Scg2Reg_SetCsrSrcSys(SCG2, 2); + while(Scg2Reg_GetCsrSysSt(SCG2) != 2) + { + ; + } +#endif + + /* Set Core and APB clock source divider */ + Scg1Reg_SetCkSrcSysDiv(SCG1, 0); /* Divide-by-1 */ + Scg2Reg_SetCsrDivAips(SCG2, 0); /* Divide-by-1 */ + + /* Finish setting up the clock */ + Scg0Reg_SetKey(SCG0, 0); /* lock SCG again */ + +#endif +} diff --git a/cva_bootloader_m0118/.idea/.gitignore b/cva_bootloader_m0118/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/cva_bootloader_m0118/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/cva_bootloader_m0118/.idea/cva_bootloader_m0118.iml b/cva_bootloader_m0118/.idea/cva_bootloader_m0118.iml new file mode 100644 index 0000000..bc2cd87 --- /dev/null +++ b/cva_bootloader_m0118/.idea/cva_bootloader_m0118.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/cva_bootloader_m0118/.idea/editor.xml b/cva_bootloader_m0118/.idea/editor.xml new file mode 100644 index 0000000..757a55c --- /dev/null +++ b/cva_bootloader_m0118/.idea/editor.xml @@ -0,0 +1,491 @@ + + + + + \ No newline at end of file diff --git a/cva_bootloader_m0118/.idea/modules.xml b/cva_bootloader_m0118/.idea/modules.xml new file mode 100644 index 0000000..ca315b6 --- /dev/null +++ b/cva_bootloader_m0118/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/cva_bootloader_m0118/.vscode/settings.json b/cva_bootloader_m0118/.vscode/settings.json new file mode 100644 index 0000000..0ce7a27 --- /dev/null +++ b/cva_bootloader_m0118/.vscode/settings.json @@ -0,0 +1,20 @@ +{ + "MicroPython.executeButton": [ + { + "text": "▶", + "tooltip": "运行", + "alignment": "left", + "command": "extension.executeFile", + "priority": 3.5 + } + ], + "MicroPython.syncButton": [ + { + "text": "$(sync)", + "tooltip": "同步", + "alignment": "left", + "command": "extension.execute", + "priority": 4 + } + ] +} \ No newline at end of file diff --git a/cva_bootloader_m0118/OUTPUT/RP-77B_BOOT_BL0101_ID731_7B1.srec b/cva_bootloader_m0118/OUTPUT/RP-77B_BOOT_BL0101_ID731_7B1.srec new file mode 100644 index 0000000..55db13e --- /dev/null +++ b/cva_bootloader_m0118/OUTPUT/RP-77B_BOOT_BL0101_ID731_7B1.srec @@ -0,0 +1,3107 @@ +S01C00006376615F626F6F746C6F616465725F6D303131382E73726563AE +S1130000F05B002071C100009B2D00000B4000003C +S113001000000000000000000000000000000000DC +S11300200000000000000000000000006741000024 +S1130030000000000000000067420000B35C000004 +S113004004C5000004C5000004C5000004C5000088 +S113005004C5000004C5000004C5000004C5000078 +S113006004C50000D55C000004C5000004C5000000 +S113007004C5000004C5000004C5000004C5000058 +S113008004C5000004C5000004C5000004C5000048 +S113009004C5000004C5000004C5000004C5000038 +S11300A0BD64000004C5000004C5000004C50000D0 +S11300B004C5000004C5000004C5000004C5000018 +S11300C048573031424C30313031000031353A3408 +S11300D0343A30310000000044656320313220326C +S11300E0303234000000000052502D3737420000F7 +S11300F000000000000000000000000000000000FC +S113040027C08FD2A0D34DDC000000000000FFFF06 +S1130410BFFFFFFFFFFFFFFFFE88E6BE30A25B8E3B +S113042000B5020093680120DB680340DBB2002BB7 +S11304300AD093681B6A9B081840C0B2002803D0F6 +S1130440D0690860012000E0002000BDF2B584B04E +S11304500200002001009468E66801239E43012302 +S11304600D00EDB21D403543E560049E3678002E44 +S113047051D0D169294CA14201D1010012E0D169C6 +S1130480274CA14201D219000CE0D169254CA142AC +S113049001D2022106E0D169234CA14201D20321F9 +S11304A000E004210C00E4B2042C01D1002033E06C +S11304B06C46617094680194019CE4680C25AC431B +S11304C06D466D78AD000C262E4026430396039CA2 +S11304D0019DEC606C4620709068C4681025AC43A4 +S11304E06D462D782D011026354025430295029C3A +S11304F0C4601C009568EE680127BE432700FFB264 +S11305001F403743EF609068006A84081800204059 +S1130510C0B20028F7D0012005B0F0BD00093D00AD +S113052001127A0001366E01015A620200B502001E +S11305309068006A43081800C007C00FC0B20028C2 +S113054003D090690860012000E0002000BDF2B5EE +S113055084B005000026A8680124416920000840F1 +S1130560C0B200286AD0A868016A20000840C0B25E +S1130570002863D0A8688069010920000840C0B23F +S1130580002802D0012806D00BE069462800FFF7B6 +S113059047FF060005E069462800FFF7C7FF06008D +S11305A0FFE73000C0B2002801D1002048E0270056 +S11305B0A8684069000A8007800FC0B2002805D0EF +S11305C0022808D004D3032808D00AE0270008E052 +S11305D00220070005E00420070002E008200700CD +S11305E0FFE7A868406940084006400EC0B20028F2 +S11305F002D18020029000E00290A8684069C00AFD +S11306004007400FC0B2002802D10820019000E04A +S11306100190A8684069810A20000840C0B2401CCB +S113062003900098029948430399484301997943F8 +S1130630490002F05AFB0499086026003000C0B259 +S113064005B0F0BDFCB502000020040095686E6999 +S113065001239E4301232700FFB21F403743019724 +S1130660019E6E611E006F463E704E78002E02D0D1 +S1130670012E0FD01DE004009568AF691026B74322 +S1130680BC462600F6B2360110273E4067463E437C +S1130690AE6111E01C009568AF691026B743BC46F3 +S11306A02600F6B2360110273E4067463E43AE614F +S11306B002E004006D462C706C462478002C01D1B5 +S11306C0002093E0CC68012C01D104000FE0CC6839 +S11306D0022C01D11C000AE0CC68042C01D10224B4 +S11306E005E0CC68082C01D1032400E0FF24250098 +S11306F0EDB2FF2D01D1002078E06D466C70956855 +S11307006E69834F3740BC466E4676783702C02602 +S1130710B6003E4067463E436E614F88002F1CD0B2 +S11307204D88812D19DA4D88802D01D1050000E016 +S11307304D8896680196019E7769FE26B743BC46AC +S11307402E00F6B27700FE263E4067463E43019FE8 +S11307507E610F69002F02D11AE0002046E00D6986 +S1130760092D15D20D69082D00D0086995686E69A8 +S1130770B04F3740BC460600F6B2F702E026B60199 +S11307803E4067463E436E618F68012F02D104E00C +S113079000202BE08868022813D18868401E9568E1 +S11307A06E69A54F3740BC460600F6B2B6028027F4 +S11307B0FF003E4067463E436E610F78002F02D132 +S11307C012E0002012E0180095686E690127BE430C +S11307D00700FFB21F4037436F619068056A180035 +S11307E02840C0B20028F8D068460078F6BDF3B5BA +S11307F081B0070000242600009478690125C069AF +S1130800010928000840C0B2002818D06946380001 +S1130810FFF706FE06003000C0B200280FD078694A +S1130820C069000A4007400F85402900412905D2CC +S1130830009802F05AFA0299086000E0260030009D +S1130840C0B2FEBDFEB5020000206B4618706B46B8 +S113085058705369DE691024E443264010256F461E +S11308607F783F012F403743DF618E88012E01D10D +S113087003001EE08B88022B01D1012319E08B8831 +S1130880042B01D1022314E08B88082B01D103230C +S11308900FE08B88102B01D104230AE08B88202BD6 +S11308A001D1052305E08B88402B01D1062300E00C +S11308B007231E00F6B2072E17D06E4673705669D2 +S11308C00196019EF669A54F3740BC466E46767880 +S11308D03702E026F6003E4067463E430296029EFB +S11308E0019FFE6101266F463E700E78002E01D0F6 +S11308F0012600E006005769F86904403000C0B2E0 +S1130900000105402543FD6168460078FEBD0000F6 +S1130910FFFCFFFFF3B581B007000024260000941C +S1130920786901258069010928000840C0B20028BF +S113093018D069463800FFF773FD06003000C0B2D6 +S113094000280FD078698069000A4007400F85406D +S11309502900412905D2009802F0C7F902990860DC +S113096000E026003000C0B2FEBDFEB5020000204B +S11309706B4618706B46587053699E691024E443A3 +S1130980264010256F467F783F012F4037439F61F3 +S11309908E88012E01D103001EE08B88022B01D129 +S11309A0012319E08B88042B01D1022314E08B88E6 +S11309B0082B01D103230FE08B88102B01D10423D2 +S11309C00AE08B88202B01D1052305E08B88402B7E +S11309D001D1062300E007231E00F6B2072E17D02C +S11309E06E46737056690196019EB6695B4F374037 +S11309F0BC466E4676783702E026F6003E406746EF +S1130A003E430296029E019FBE6101266F463E70E0 +S1130A100E78002E01D0012600E006005769B8695F +S1130A2004403000C0B2000105402543BD61684662 +S1130A300078FEBDFFC7FFFFFFFBFFFFF3B581B0EA +S1130A400700002426000094786901254069010903 +S1130A5028000840C0B2002818D069463800FFF7C3 +S1130A6065FD06003000C0B200280FD078694069E7 +S1130A70000A4007400F85402900412905D200980B +S1130A8002F033F90299086000E026003000C0B299 +S1130A90FEBDFEB5020000206B4618706B46587010 +S1130AA053695E691024E443264010256F467F781D +S1130AB03F012F4037435F618E88012E01D103002F +S1130AC01EE08B88022B01D1012319E08B88042BB3 +S1130AD001D1022314E08B88082B01D103230FE0FA +S1130AE08B88102B01D104230AE08B88202B01D1A1 +S1130AF0052305E08B88402B01D1062300E0072362 +S1130B001E00F6B2072E17D06E4673705669019612 +S1130B10019E7669114F3740BC466E46767837029F +S1130B20E026F6003E4067463E430296029E019F41 +S1130B307E6101266F463E700E78002E01D001269C +S1130B4000E006005769786904403000C0B2000133 +S1130B50054025437D6168460078FEBDFFF8FFFF30 +S1130B60F3B581B0070000242600009478690125BC +S1130B700069010928000840C0B2002818D069465D +S1130B803800FFF7D3FC06003000C0B200280FD0B5 +S1130B9078690069000A4007400F8540290041290F +S1130BA005D2009802F0A1F80299086000E026003E +S1130BB03000C0B2FEBDFEB5020000206B461870C6 +S1130BC06B46587053691E691024E443264010256F +S1130BD06F467F783F012F4037431F618E88012E77 +S1130BE001D103001EE08B88022B01D1012319E0FF +S1130BF08B88042B01D1022314E08B88082B01D1AC +S1130C0003230FE08B88102B01D104230AE08B8887 +S1130C10202B01D1052305E08B88402B01D106232D +S1130C2000E007231E00F6B2072E17D06E4673703D +S1130C3056690196019E3669A14F3740BC466E46FF +S1130C4076783702E026F6003E4067463E43029639 +S1130C50029E019F3E6101266F463E700E78002E73 +S1130C6001D0012600E006005769386904403000CD +S1130C70C0B20001054025433D6168460078FEBDD1 +S1130C80F3B581B00700002426000094786901259B +S1130C90406A010928000840C0B2002818D06946FB +S1130CA03800FFF754FC06003000C0B200280FD013 +S1130CB07869406A000A4007400F854029004129AD +S1130CC005D2009802F011F80299086000E02600AD +S1130CD03000C0B2FEBDFEB5020000206B461870A5 +S1130CE06B46587053695E6A1024E443264010250D +S1130CF06F467F783F012F4037435F628E88012E15 +S1130D0001D103001EE08B88022B01D1012319E0DD +S1130D108B88042B01D1022314E08B88082B01D18A +S1130D2003230FE08B88102B01D104230AE08B8866 +S1130D30202B01D1052305E08B88402B01D106230C +S1130D4000E007231E00F6B2072E17D06E4673701C +S1130D5056690196019E766A594F3740BC466E46E5 +S1130D6076783702E026F6003E4067463E43029618 +S1130D70029E019F7E6201266F463E700E78002E11 +S1130D8001D0012600E006005769786A044030006B +S1130D90C0B20001054025437D6268460078FEBD6F +S1130DA0F3B581B00700002426000094786901257A +S1130DB0006A010928000840C0B2002818D069461A +S1130DC03800FFF7C4FB06003000C0B200280FD083 +S1130DD07869006A000A4007400F854029004129CC +S1130DE005D2009801F081FF0299086000E0260016 +S1130DF03000C0B2FEBDFEB5020000206B46187084 +S1130E006B46587053691E6A1024E443264010252B +S1130E106F467F783F012F4037431F628E88012E33 +S1130E2001D103001EE08B88022B01D1012319E0BC +S1130E308B88042B01D1022314E08B88082B01D169 +S1130E4003230FE08B88102B01D104230AE08B8845 +S1130E50202B01D1052305E08B88402B01D10623EB +S1130E6000E007231E00F6B2072E17D06E467370FB +S1130E7056690196019E366A114F3740BC466E464C +S1130E8076783702E026F6003E4067463E430296F7 +S1130E90029E019F3E6201266F463E700E78002E30 +S1130EA001D0012600E006005769386A044030008A +S1130EB0C0B20001054025433D6268460078FEBD8E +S1130EC0FFF8FFFF70B504000E000025606900689C +S1130ED0000E8007800FC0B2002805D002280FD072 +S1130EE008D3032812D017E031002000FFF71EFBBF +S1130EF0050011E031002000FFF792FA05000BE035 +S1130F0031002000FFF723FB050005E0310020003D +S1130F10FFF70CFB0500FFE72800C0B270BDF0B579 +S1130F2002004878012801D100230AE0487800280B +S1130F3001D1012305E04878022801D1022300E011 +S1130F40FF231800C0B2FF2801D1002017E01C00C5 +S1130F5050690668934D35402600F6B23704C02622 +S1130F60B6023E402E43066050690068000E8007BA +S1130F70800F1C00C0B2E4B2A042F5D10120F0BD44 +S1130F80F8B504000E00002569462000FFF79AFF1B +S1130F9007003800C0B2002801D100200BE0E0684F +S1130FA000680107090F0098C9B2491C01F09DFEB1 +S1130FB030603800C0B2F2BD30B502008888002825 +S1130FC010D0888811280DDA8C88641ED3681868BC +S1130FD00F25A8432500EDB22D072D0F05431D60F5 +S1130FE0012000E0002030BDF8B504000E0000250B +S1130FF069462000FFF7C4FF07003800C0B200288C +S113100001D100200CE060690068000A0107090FA3 +S11310100098C9B2491C01F068FE30603800C0B2C3 +S1131020F2BD70B502008888002812D08888112883 +S11310300FDA8C88641E53691D685B4828402500BC +S1131040EDB22E02F0252D01354005431D6001202F +S113105000E0002070BDF8B504000F0000252E004C +S11310602069C8214058000C8007800FC0B20028B6 +S113107005D002280FD008D3032812D017E0694600 +S11310802000FFF753FA060011E069462000FFF73D +S1131090C7F906000BE069462000FFF758FA06007E +S11310A005E069462000FFF741FA0600FFE730003B +S11310B0C0B2002801D1002019E02069C82140589D +S11310C001090800C007C00FC0B200280CD0206975 +S11310D0C8214058000A0107090F0098C9B2491CE9 +S11310E001F003FE386000E02E003000C0B2F2BD13 +S11310F0FCB502004878012801D100230AE04878B1 +S1131100002801D1012305E04878022801D10223F7 +S113111000E0FF231800C0B2FF2801D100203FE007 +S1131120888800283BD08888112838DA68460370FC +S11311301069C82405591B4C2C406D462D782D048C +S1131140C026B6022E4026430196019CC825445170 +S11311508C88641E1569C826AE59134F3740BC46A7 +S11311602600F6B23702F02636013E4067463E437B +S1131170C827EE510F78002F01D0012400E000248D +S11311801569C82028581026B0432600F6B2360147 +S113119010273E400643C8202E50012000E00020C6 +S11311A0F6BD0000FFFFFCFFFFF0FFFFF8B50400F1 +S11311B00F006069406801090800C007C00FC0B291 +S11311C0002801D100209BE0002005000090606908 +S11311D007264068000C3040C0B2002843D1606943 +S11311E04068C00C3040C0B200280BD0022815D093 +S11311F00ED304281ED017D3062827D020D30728BF +S11312002AD02FE069462000FFF725FF050066E09D +S113121069462000FFF704F9050060E069462000F4 +S1131220FFF784F905005AE069462000FFF78FF9BB +S1131230050054E069462000FFF7A2FE05004EE0D9 +S113124069462000FFF7D0FE050048E0694620000B +S1131250FFF7CDFA050042E069462000FFF7EEFBF8 +S113126005003CE03BE060694068000C3040C0B2DF +S113127001280AD033D3032813D00CD305281CD05B +S113128015D3072825D01ED329E069462000FFF78F +S1131290F7FC050023E06946200000F038FA050059 +S11312A01DE06946200000F00BFA050017E06946CE +S11312B0200000F0DEF9050011E06946200000F08E +S11312C067FD05000BE069462000FFF72FF90500D4 +S11312D005E069462000FFF729F90500FFE728002B +S11312E0C0B201280AD160694068000A0640310092 +S11312F00098C9B2491C01F0F8FC38602800C0B25B +S1131300F2BDF2B582B0010001206A4610700020DF +S113131002004B695C681025AC431500EDB22D0149 +S11313201026354025435D60029C6478002C40D033 +S1131330012C5DD0022C7AD0032C00D1D4E0052CF2 +S113134000D1F0E0072C00D10CE10A2C00D18DE093 +S11313500B2C00D1A9E00C2C0CD00F2C00D12BE1CC +S1131360102C00D11AE1112C00D109E11A2C00D162 +S113137030E13DE102004B695D68B94C2C40150039 +S1131380EDB22D04E026F6022E4026430196019C80 +S11313905C6004004D696E68B24F3740BC4626005D +S11313A0F6B2F704E026B6033E4067463E436E605D +S11313B021E102004B695D68A94C2C401500EDB297 +S11313C02D04E026F6022E4026430196019C5C6023 +S11313D001244D696E68A34F3740BC462600F6B21F +S11313E0F704E026B6033E4067463E436E6002E1E2 +S11313F002004B695D689A4C2C401500EDB22D0437 +S1131400E026F6022E4026430196019C5C600224ED +S11314104D696E68934F3740BC462600F6B2F70418 +S1131420E026B6033E4067463E436E60E3E00200BA +S11314304B695D688A4C2C401500EDB22D04E02602 +S1131440F6022E4026430196019C5C6003244D69FC +S11314506E68844F3740BC462600F6B2F704E02697 +S1131460B6033E4067463E436E60C4E002004B69EB +S11314705D687B4C2C401500EDB22D04E026F6028D +S11314802E4026430196019C5C6004244D696E68DD +S1131490744F3740BC462600F6B2F704E026B60384 +S11314A03E4067463E436E60A5E002004B695D68BE +S11314B06B4C2C401500EDB22D04E026F6022E40B4 +S11314C026430196019C5C6005244D696E68654F56 +S11314D03740BC462600F6B2F704E026B6033E4089 +S11314E067463E436E6086E002004B695D685C4C73 +S11314F02C401500EDB22D04E026F6022E402643C2 +S11315000196019C5C6006244D696E68554F374016 +S1131510BC462600F6B2F704E026B6033E40674612 +S11315203E436E6067E002004B695D684C4C2C40A2 +S11315301500EDB22D04E026F6022E402643019656 +S1131540019C5C6007244D696E68464F3740BC4679 +S11315502600F6B2F704E026B6033E4067463E4353 +S11315606E6048E001224B695D683D4C2C401500DB +S1131570EDB22E04E025ED02354025435D603AE0EE +S113158002224B695D68364C2C401500EDB22E04E6 +S1131590E025ED02354025435D602CE003224B69D4 +S11315A05D682F4C2C401500EDB22E04E025ED02B1 +S11315B0354025435D601EE004224B695D68284C7C +S11315C02C401500EDB22E04E025ED0235402543F4 +S11315D05D6010E005224B695D68214C2C401500CC +S11315E0EDB22E04E025ED02354025435D6002E0B6 +S11315F002006B461A706A461278002A1AD0029AC0 +S11316009288002A13D0029A9288092A0FDA029A41 +S11316109288521E4B695D687F4C2C401500EDB2D8 +S11316202E02E025ED00354025435D6002E0020016 +S11316306B461A70029A1278002A01D0012200E047 +S113164002004B6958681024A0431400E4B224013A +S113165010252C4004435C6068460078FEBD000001 +S1131660FFFFF8FFFFFFC7FF0200106A08600120B8 +S1131670704700B502005068806C03091800C00769 +S1131680C00FC0B2002804D0FA20800008600120F6 +S113169000E0002000BD70B502000878002801D0E9 +S11316A0012400E000245368986C1025A843250009 +S11316B0EDB22D011026354005439D64012070BD17 +S11316C000B502005068406C03091800C007C00F41 +S11316D0C0B2002804D0FA20C0010860012000E054 +S11316E0002000BD70B502000878002801D0012454 +S11316F000E000245368586C1025A8432500EDB27F +S11317002D011026354005435D64012070BD0200A3 +S1131710FA20400208600120704770B504000E00F2 +S1131720002561680120496809090140C9B20029FE +S113173001D100201AE061684968090C0140C9B26E +S1131740002905D131002000FFF71AFC05000BE049 +S113175061684968090C0840C0B2012804D131000D +S1131760200000F02FF905002800C0B270BDF2B5CA +S113177082B0010000206A46107005004C6866685B +S11317801022D243164010232F00FFB23F011F4006 +S113179037436760029E76780A2E11D16C466070DA +S11317A04C6866681D4D35406E4676783604802751 +S11317B07F023E402E43666001256F463D7018E06F +S11317C0029C6478182C14D1012425004E680196DB +S11317D0019E7668114F3740BC462E00F6B236049F +S11317E080277F023E4067463E43019F7E606F46EE +S11317F03C70029C2478002C01D0012400E00400F9 +S11318004D68686802402000C0B2000103401343E1 +S11318106B6068460078FEBDFFF8FFFFFFFFFEFF28 +S113182070B504000E000025606880680109080096 +S1131830C007C00FC0B2002804D031002000FFF759 +S1131840D3FB05002800C0B270BD70B50200087853 +S1131850002801D0012400E0002453689868102572 +S1131860A8432500EDB22D011026354005439D60A7 +S1131870012070BD70B504000E0000256068C068CA +S113188001090800C007C00FC0B2002804D031000D +S11318902000FFF7A9FB05002800C0B270BD70B599 +S11318A002000878002801D0012400E000245368D5 +S11318B0D8681025A8432500EDB22D011026354027 +S11318C00543DD60012070BD70B504000E000025E5 +S11318D06068006901090800C007C00FC0B2002891 +S11318E004D031002000FFF77FFB05002800C0B2C0 +S11318F070BD70B502000878002801D0012400E012 +S11319000024536818691025A8432500EDB22D0161 +S11319101026354005431D61012070BD70B50400DB +S11319200E0000256068406901090800C007C00F67 +S1131930C0B2002804D031002000FFF755FB050099 +S11319402800C0B270BD70B502000878002801D02C +S1131950012400E00024536858691025A843250099 +S1131960EDB22D011026354005435D61012070BDA7 +S113197070B504000E000025606880690109080044 +S1131980C007C00FC0B2002804D031002000FFF708 +S11319902BFB05002800C0B270BD70B502000878AA +S11319A0002801D0012400E0002453689869102520 +S11319B0A8432500EDB22D011026354005439D6155 +S11319C0012070BDF8B505000F0000200400009050 +S11319D06868C06901090800C007C00FC0B20028C8 +S11319E001D1002054E068680726C069000C30402B +S11319F0C0B200280BD0022815D00ED304281ED064 +S1131A0017D3062827D020D307282AD02FE06946E9 +S1131A102800FFF713F8040029E069462800FEF7C0 +S1131A20E6FE040023E069462800FFF729F90400D4 +S1131A301DE069462800FFF76AFE040017E06946C6 +S1131A402800FFF716FE040011E069462800FFF79E +S1131A5037FE04000BE069462800FFF705FE04008A +S1131A6005E069462800FEF7E9FF0400FFE72000CF +S1131A70C0B200280AD06868C069000A0640310074 +S1131A80C9B2491C009801F030F938602000C0B296 +S1131A90F2BDF3B50100012002006B461A7000226A +S1131AA014004D68EE6910239E4310232700FFB2F3 +S1131AB03F011F403743EF61019E7678032E1CD00F +S1131AC0052E0AD0072E28D00E2E66D00F2E44D015 +S1131AD0102E52D0112E30D06FE014004D68EE69F4 +S1131AE0AA4F3740BC462600F6B23704E026F60279 +S1131AF03E4067463E43EE6162E004004D68EE6995 +S1131B00A24F3740BC462600F6B23704E026F60260 +S1131B103E4067463E43EE6152E002244D68EE6962 +S1131B209A4F3740BC462600F6B23704E026F60248 +S1131B303E4067463E43EE6142E003244D68EE6951 +S1131B40924F3740BC462600F6B23704E026F60230 +S1131B503E4067463E43EE6132E004244D68EE6940 +S1131B608A4F3740BC462600F6B23704E026F60218 +S1131B703E4067463E43EE6122E005244D68EE692F +S1131B80824F3740BC462600F6B23704E026F60200 +S1131B903E4067463E43EE6112E006244D68EE691E +S1131BA07A4F3740BC462600F6B23704E026F602E8 +S1131BB03E4067463E43EE6102E014006D462C70E1 +S1131BC0019CA488002C15D0019CA488092C11DA4E +S1131BD0019CA488641E4D68EE69C04F3740BC4622 +S1131BE02600F6B23702E026F6003E4067463E4342 +S1131BF0EE6102E014006D462C70019C2478002CE8 +S1131C0001D00200FFE74C68E0691025A8431500E5 +S1131C10EDB22D012B400343E36168460078F6BD25 +S1131C2070B504000E00002561680120096A0909E5 +S1131C300140C9B2002901D1002026E06168096A87 +S1131C40090C8907890FC9B2002905D002290FD0D0 +S1131C5008D3032912D016E031002000FEF7EEFE6F +S1131C60050010E031002000FFF70AF805000AE043 +S1131C7031002000FEF7BBFD050004E0FA21490213 +S1131C8031600500FFE72800C0B270BDF2B582B034 +S1131C900100012002006B461A7000226B465A7044 +S1131CA04D682E6A1023DB431E4010246F467F7854 +S1131CB03F01274037432F62029E7678032E2AD0B5 +S1131CC0052E04D0072E13D0112E37D049E06D46CF +S1131CD06A704D682E6AC94F3740BC466E467678A6 +S1131CE03704C026B6023E4067463E432E623AE0C1 +S1131CF005004E680196019E366AC04F3740BC46C7 +S1131D002E00F6B23704C026B6023E4067463E4374 +S1131D10019F3E6227E002254E680196019E366AC5 +S1131D20B64F3740BC462E00F6B23704C026B60282 +S1131D303E4067463E43019F3E6214E003254E68E1 +S1131D400196019E366AAD4F3740BC462E00F6B26E +S1131D503704C026B6023E4067463E43019F3E62BA +S1131D6001E06D462A70029D2D78002D01D00200FD +S1131D70FFE74D68286A03401000C0B20001044028 +S1131D801C432C6268460078FEBD0000FFFFF8FF8C +S1131D9070B504000E0000256068806A010908001F +S1131DA0C007C00FC0B2002801D1002027E060683E +S1131DB0806A000C8007800FC0B2002805D002287A +S1131DC00FD008D3032812D017E031002000FFF70A +S1131DD077FC050011E031002000FFF745FC050009 +S1131DE00BE031002000FFF744FC050005E0310062 +S1131DF02000FFF73EFC0500FFE72800C0B270BDDD +S1131E00F2B582B0010000206A46107005004C68EB +S1131E10A66A1022D243164010232F00FFB23F01BE +S1131E201F403743A762029E7678102E11D16C466C +S1131E3060704C68A66A714D35406E4676783704FA +S1131E40C026B6023E402E43A66201256F463D7071 +S1131E5031E0029C64780E2C15D1012425004E68D3 +S1131E600196019EB66A654F3740BC462E00F6B215 +S1131E703704C026B6023E4067463E43019FBE6219 +S1131E806F463C7017E0029C64780F2C13D1022437 +S1131E904D68AE6A594F3740BC462600F6B2370447 +S1131EA0C026B6023E4067463E430196019EAE629E +S1131EB001266F463E70029C2478002C01D0012438 +S1131EC000E004004D68A86A02402000C0B200018E +S1131ED003401343AB6268460078FEBDFFF8FFFF82 +S1131EE070B504000E00002561680120096B090C1F +S1131EF00140C9B2002905D131002000FFF774F870 +S1131F0005000BE06168096B090C0840C0B20128A8 +S1131F1004D131002000FFF7FAFB05002800C0B20D +S1131F2070BDF0B50200002318004C780B2C0CD1C6 +S1131F305468266B9D4D35401E00F6B2370480264A +S1131F40760237402F4327630FE04B78112B0CD1D7 +S1131F5001235468266B954D35401E00F6B23704B4 +S1131F608026760237402F432763C0B2F0BD70B598 +S1131F7004000E00002561680120496B090C014032 +S1131F80C9B2002905D131002000FFF72DF8050062 +S1131F900BE06168496B090C0840C0B2012804D108 +S1131FA031002000FFF7B3FB05002800C0B270BD6C +S1131FB0F0B50200002318004C780B2C0CD15468A7 +S1131FC0666B7A4D35401E00F6B2370480267602E1 +S1131FD037402F4367630FE04B78112B0CD101235B +S1131FE05468666B714D35401E00F6B23704802686 +S1131FF0760237402F436763C0B2F0BDFFFFFCFF9A +S113200070B504000E00002561680120896B090C7D +S11320100140C9B2002905D131002000FEF7E4FFD8 +S113202005000BE06168896B090C0840C0B2012807 +S113203004D131002000FFF76AFB05002800C0B27C +S113204070BDF0B50200002318004C780B2C0CD1A5 +S11320505468A66B554D35401E00F6B237048026F1 +S1132060760237402F43A7630FE04B78112B0CD136 +S113207001235468A66B4D4D35401E00F6B237045B +S11320808026760237402F43A763C0B2F0BD70B5F7 +S113209004000E00002561680120C96B090C014091 +S11320A0C9B2002905D131002000FEF79DFF0500CB +S11320B00BE06168C96B090C0840C0B2012804D167 +S11320C031002000FFF723FB05002800C0B270BDDB +S11320D0F0B50200002318004C780B2C0CD1546886 +S11320E0E66B324D35401E00F6B237048026760288 +S11320F037402F43E7630FE04B78112B0CD10123BA +S11321005468E66B294D35401E00F6B2370480262C +S1132110760237402F43E763C0B2F0BD70B50400C8 +S11321200E00002561680120096C090C0140C9B248 +S1132130002905D131002000FEF756FF05000BE011 +S11321406168096C090C0840C0B2012804D131004F +S11321502000FFF7DCFA05002800C0B270BDF0B51E +S11321600200002318004C780B2C0CD15468266C08 +S11321700E4D35401E00F6B23704802676023740F5 +S11321802F4327640FE04B78112B0CD101235468A3 +S1132190266C064D35401E00F6B2370480267602C2 +S11321A037402F432764C0B2F0BD0000FFFFFEFF9D +S11321B070B504000E00002521680120C9680909D2 +S11321C00140C9B2002905D131002000FEF70CFFFF +S11321D005000AE02168C96809090140C9B201295A +S11321E003D1FA214902316005002800C0B270BD54 +S11321F0F0B50200002318004C780B2C0DD11468A4 +S1132200E5681026B5431E00F6B2360110273E409D +S11322102E43E6600125280012E04B78112B0FD1E4 +S113222001231C001568EF681026B743BC4626003E +S1132230F6B2360110273E4067463E43EE60180072 +S1132240C0B2F0BD38B505000C002869006801096A +S11322500800C007C00FC0B2002801D1002003E06D +S113226021002800FEF78CFE32BD70B5020008780C +S1132270002801D0012400E0002413691868102507 +S1132280A8432500EDB22D011026354005431D60FD +S1132290012070BD38B505000C00286940680109AB +S11322A00800C007C00FC0B2002801D1002003E01D +S11322B021002800FEF798FE32BD70B502000878B0 +S11322C0002801D0012400E0002413695868102577 +S11322D0A8432500EDB22D011026354005435D606D +S11322E0012070BD38B505000C002869006901099A +S11322F00800C007C00FC0B2002801D1002003E0CD +S113230021002800FEF770FE32BD70B50200087887 +S1132310002801D0012400E0002413691869102565 +S1132320A8432500EDB22D011026354005431D615B +S1132330012070BD38B505000C0028694069010909 +S11323400800C007C00FC0B2002801D1002003E07C +S113235021002800FEF748FE32BD70B5020008785F +S1132360002801D0012400E00024136958691025D5 +S1132370A8432500EDB22D011026354005435D61CB +S1132380012070BD38B505000C0028698069010979 +S11323900800C007C00FC0B2002801D1002003E02C +S11323A021002800FEF7ECFD32BD70B5020008786C +S11323B0002801D0012400E0002413699869102545 +S11323C0A8432500EDB22D011026354005439D613B +S11323D0012070BD38B505000C002869C0690109E9 +S11323E00800C007C00FC0B2002801D1002003E0DC +S11323F021002800FEF7F8FD32BD70B50200087810 +S1132400002801D0012400E000241369D8691025B4 +S1132410A8432500EDB22D01102635400543DD61AA +S1132420012070BDF2B582B0060030690124006A53 +S1132430010920000840C0B2002801D1002037E083 +S11324402000694608710027009730690325006A57 +S1132450000C2840C0B2002805D002280FD008D3B1 +S1132460032812D017E069463000FEF75FF8070032 +S113247011E069463000FDF7D3FF07000BE0694621 +S11324803000FEF764F8070005E069463000FEF707 +S11324904DF80700FFE73069006A000A0540AC40C8 +S11324A00098210000F021FC029908603800C0B2B5 +S11324B0FEBDFEB5020000206B4618706B465870D6 +S11324C013691E6A1024E443264010256F467F7862 +S11324D03F012F4037431F624E78012E01D1030084 +S11324E00AE04B78002B01D1012305E04B78022B45 +S11324F001D1022300E0FF231E00F6B2FF2E17D005 +S11325006E46737016690196019E366A844F374091 +S1132510BC466E4676783704C026B6023E4067460F +S11325203E430296029E019F3E6201266F463E7024 +S11325306E463678002E36D08E88012E01D10600E4 +S11325400FE08E88022E01D101260AE08E88042E27 +S113255001D1022605E08E88082E01D1032600E071 +S1132560FF266F467E706E467678FF2E19D06E4633 +S113257076786F46BE7016690296029E376A694E77 +S11325803E400196019FBC466E46B6783702C0268F +S1132590B6003E4067463E430196019E029F3E625E +S11325A001E06E4630700E78002E01D0012600E066 +S11325B006001769386A04403000C0B200010540C3 +S11325C025433D6268460078FEBD38B505000C0021 +S11325D02869806A01090800C007C00FC0B200283A +S11325E001D1002003E021002800FEF7FDFC32BDEC +S11325F070B502000878002801D0012400E000240E +S11326001369986A1025A8432500EDB22D01102600 +S1132610354005439D62012070BD70B505000C0076 +S113262028690126006B00093040C0B2002801D19E +S1132630002023E02869006B000C8007800FC0B2E3 +S1132640002805D002280DD007D303280FD013E0AB +S113265021002800FEF7F2F90FE021002800FEF720 +S1132660C6F80AE021002800FEF70AFB05E0210075 +S11326702800FEF7E3F900E00020C0B270BDFEB50B +S1132680020000206B4618706B46587013691E6B6D +S11326901024E443264010256F467F783F012F40E5 +S11326A037431F634E78052E01D103000AE04B78AF +S11326B0032B01D1012305E04B78072B01D1022321 +S11326C000E0FF231E00F6B2FF2E17D06E46737093 +S11326D016690196019E366B114F3740BC466E4613 +S11326E076783704C026B6023E4067463E430296DB +S11326F0029E019F3E6301266F463E700E78002EB7 +S113270001D0012600E006001769386B0440300050 +S1132710C0B20001054025433D6368460078FEBD14 +S1132720FFFFFCFFFFFCFFFF0200506A086001206E +S113273070470200906A0860012070470200D06A66 +S113274008600120704770B505000C000126286957 +S1132750A0214058000C4007400FC0B200280BD005 +S1132760022813D00DD304281AD014D3062821D05C +S11327701BD307281ED022E021002800FFF7D4FF36 +S11327801EE021002800FFF7D4FF19E021002800F3 +S1132790FFF7D4FF14E021002800FEF7E1F90FE071 +S11327A021002800FEF7B6F80AE021002800FEF711 +S11327B0F7FA05E021002800FEF7D2F900E0002036 +S11327C0C0B270BDF0B50200012318004C78042C8F +S11327D049D0062C37D0082C55D02A2C04D02B2CC9 +S11327E012D02C2C1FD05EE000231469A02566595A +S11327F0AD4D35401E00F6B23704E026F6023E40E9 +S11328002E43A025665150E01469A0256659A64DB3 +S113281035401E00F6B23704E026F6023E402E4351 +S1132820A025665141E002231469A02566599E4DF6 +S113283035401E00F6B23704E026F6023E402E4331 +S1132840A025665131E003231469A0256659964DED +S113285035401E00F6B23704E026F6023E402E4311 +S1132860A025665121E004231469A02566598E4DE4 +S113287035401E00F6B23704E026F6023E402E43F1 +S1132880A025665111E005231469A0256659864DDB +S113289035401E00F6B23704E026F6023E402E43D1 +S11328A0A025665101E000231800C0B2F0BD70B548 +S11328B005000C0001262869A4214058000C40079B +S11328C0400FC0B200280BD0022813D00DD3042827 +S11328D01AD014D3062821D01BD307281ED022E0F7 +S11328E021002800FFF720FF1EE021002800FFF749 +S11328F020FF19E021002800FFF720FF14E0210049 +S11329002800FEF72DF90FE021002800FEF702F859 +S11329100AE021002800FEF743FA05E02100280020 +S1132920FEF71EF900E00020C0B270BDF0B5020051 +S1132930012318004C78042C49D0062C37D0082CDD +S113294055D02A2C04D02B2C12D02C2C1FD05EE076 +S113295000231469A4256659534D35401E00F6B270 +S11329603704E026F6023E402E43A425665150E08B +S11329701469A42566594C4D35401E00F6B237043F +S1132980E026F6023E402E43A425665141E0022390 +S11329901469A4256659444D35401E00F6B2370427 +S11329A0E026F6023E402E43A425665131E003237F +S11329B01469A42566593C4D35401E00F6B237040F +S11329C0E026F6023E402E43A425665121E004236E +S11329D01469A4256659344D35401E00F6B23704F7 +S11329E0E026F6023E402E43A425665111E005235D +S11329F01469A42566592C4D35401E00F6B23704DF +S1132A00E026F6023E402E43A425665101E0002351 +S1132A101800C0B2F0BD70B505000C00012006001E +S1132A202969C0228958090C0840C0B2002802D084 +S1132A30012805D009E021002800FEF741FE05E049 +S1132A4021002800FEF710FE00E00020C0B270BD97 +S1132A50F0B50200012318004C780E2C11D0102C74 +S1132A601ED100231469C02566598E4D35401E00C1 +S1132A70F6B2360480277F023E402E43C0256651BD +S1132A8010E01469C0256659864D35401E00F6B223 +S1132A90360480277F023E402E43C025665101E064 +S1132AA000231800C0B2F0BDFFFFF8FF70B50500A9 +S1132AB00C00012006002969C4228958090C084029 +S1132AC0C0B2002802D0012805D009E02100280066 +S1132AD0FEF7F6FD05E021002800FEF7C5FD00E045 +S1132AE00020C0B270BDF0B50200012318004C787C +S1132AF00E2C11D0102C1ED100231469C425665944 +S1132B00684D35401E00F6B2360480277F023E40F1 +S1132B102E43C425665110E01469C4256659614DDD +S1132B2035401E00F6B2360480277F023E402E4315 +S1132B30C425665101E000231800C0B2F0BD38B5C9 +S1132B4005000C002869CC21405801090800C00781 +S1132B50C00FC0B2002801D1002003E021002800EA +S1132B60FEF70EFA32BD70B502000878002801D0D5 +S1132B70012300E000231469CC2020581025A84329 +S1132B801D00EDB22D01102635400543CC20255003 +S1132B90012070BDFEB50899099A0A9B0B9C009D03 +S1132BA00560019D4560029D8560C16002614361CD +S1132BB0256885616568C561A568056200252E00E4 +S1132BC02E00F6B2032E0BD22E00F6B2B600A619D2 +S1132BD0F6682F00FFB2BF00C7197E626D1CEFE7D5 +S1132BE0F7BDF8B506000C0017002000C0B232286B +S1132BF001DB002011E000252B4A2000C0B2C000F8 +S1132C001058002807D0390030002300DBB2DB0065 +S1132C10D258904705002800C0B2F2BDF4B588B080 +S1132C2004000F003800C0B2322801DB002037E076 +S1132C3000252E001C4A3800C0B2C000101840689D +S1132C4000282BD0194807906068069007980699C9 +S1132C508023C85016480590A068049005980499EC +S1132C600866144803902068029003980299802310 +S1132C70C850089920003B00DBB2DB00D218526830 +S1132C809047060001956068019980228150009563 +S1132C90A168009A0A6622688023D5503000C0B229 +S1132CA009B0F0BDFFFFFEFF3CB80000524553558C +S1132CB0202096194B4D4352F446002804D449422F +S1132CC000F013F8404260474042002905D45FD029 +S1132CD000F00BF8404249426047494200F005F8D1 +S1132CE04942604703460B43E6D40022030A8B4261 +S1132CF00BD203098B4219D243088B422ED2411ABC +S1132D0000D20146524110467047FF2209023FD0CB +S1132D1012068B4205D3121209028B4201D31212FE +S1132D20090203098B4219D300E0090AC3098B4243 +S1132D3001D3CB01C01A524183098B4201D38B01C9 +S1132D40C01A524143098B4201D34B01C01A52416C +S1132D5003098B4201D30B01C01A5241C3088B42B1 +S1132D6001D3CB00C01A524183088B4201D38B009C +S1132D70C01A524143088B4201D34B00C01A52413E +S1132D80884200D3401A5241CFD2014610467047C0 +S1132D9008B500F001F808BD7047FEE700B5010072 +S1132DA000200A00D2B2002A05D0022A09D005D395 +S1132DB0032A09D00AE01022100007E018221000AC +S1132DC004E02822100001E048221000C0B200BD37 +S1132DD0F8B505000C002868060080360027684610 +S1132DE007703800C0B2FFF7D9FF0100C9B28908E3 +S1132DF00800C0B2220092B2504380003018F2BDE5 +S1132E0000B5010000200A00D2B2002A082A0ED917 +S1132E10093A0ED0521E0FD0521E10D0521E11D09D +S1132E20521E12D0521E13D0521E14D016E00800A7 +S1132E3014E00C22100011E0102210000EE0142205 +S1132E4010000BE01822100008E02022100005E01A +S1132E503022100002E040221000FFE7C0B200BDA3 +S1132E60F8B505000C0000206946487069460870F2 +S1132E70210089B22800FFF7ABFF06003068000C80 +S1132E8007073F0F3800C0B2FFF7BAFFC0B2F2BD68 +S1132E9070B500231400E4B2002C0CD00468C025E3 +S1132EA0ED03254305604468640F6407CD00ED0815 +S1132EB0254345600BE00468BC4D2540056044682B +S1132EC0BB4E26408C04BB4D25403543456070BD48 +S1132ED010B40268B84B1340036002680B00DBB205 +S1132EE01B04F02424031C401443046010BC7047EA +S1132EF000B502685200520802600268AF4B1340EA +S1132F0003600A00D2B2002A09D0026880231B069B +S1132F101343036002688023DB051343036000BD91 +S1132F2000B50A00D2B2002A06D10268A44B1340AD +S1132F300360026802600CE00A00D2B2012A08D1E0 +S1132F4002689F4B1340036002688023DB04134331 +S1132F50036000BD30B50268803200231D001C00F0 +S1132F60057EED01AC4205D2A500551929000B6080 +S1132F70641CF5E730BDF8B4924982688023D150CF +S1132F8001234468256D2026B5431E00F6B2760160 +S1132F9020273E402E430096009D25650025866827 +S1132FA08027F551F1BC7047F8B4864982688023C4 +S1132FB0D15001234468256D1026B5431E00F6B296 +S1132FC0360110273E402E430096009D25650025BE +S1132FD086688027F551F1BC7047F2B40599069CC8 +S1132FE0079D089E37780776009F076042608360DC +S1132FF0C16004614561F1BC704730B50022110025 +S11330008260026142618261C260C2614262826224 +S1133010C2620262012303701300C37013000371C0 +S11330200023DB4343638363C363036414004425C5 +S113303044551400452544551400C8254455082416 +S11330404625445514002100C9B2202906DA21007E +S1133050C9B2890041188B64641CF4E71100417003 +S11330601100817011003023C1541100C923C154CF +S11330701100CA23C1541100CB23C1541100D5231C +S1133080C1541100D423C1541100D623C1541100DA +S1133090D723C1541100CC23C154D021425030BD98 +S11330A0F0B50024210002681368444D1D400B0054 +S11330B0DBB29B078026F60533402B43136005687B +S11330C02E68414F3740BC462600F6B236078027AB +S11330D07F053E4067463E432E60016809680A0E3C +S11330E01100C907C90FC9B20029F6D1F0BDF8B55E +S11330F00400206801250068000D2840C0B20028A3 +S113310014D0002021680A68520052080300DBB280 +S1133110DB0713430B6020680068000D2840C0B231 +S1133120002803D02000FFF73FFFF4E728002168C0 +S11331300B68264A1A400300DBB25B068026B604FD +S1133140334013430B6020680068400E2840C0B22F +S11331500028F8D16846057020680168174A0A40BB +S11331606946097889078023DB051940114301600A +S11331702A0023681E68144F3740BC461600F6B276 +S1133180360780277F053E4067463E431E60206821 +S11331900068000E2840C0B20028F8D020680068FB +S11331A0C00E2840C0B20028F1D0F1BDFFFF9FFF40 +S11331B0FFFF03E00000FC1FFFFFF0FFFFFFFFBF66 +S11331C0FFFFFFF052455355FFFFFFEFFFFFFFFDE9 +S11331D0F8B594B007000C0016003100C9B289B2EA +S11331E03800FFF7F5FD0500227A61682800FFF733 +S11331F04FFEA17A2800FFF76BFEE17A2800FFF763 +S113320077FE617A2800FFF78BFE207B002805D02B +S11332106846067101A9380000F009FD607A0128AA +S11332200AD1206969460E7039686A46127892009C +S11332308A1888231B01D05015B0F0BDF0B58DB0AD +S113324005000E0000206946487000206946087099 +S11332502800FFF790FE012029680A6852005208EE +S11332600300DBB2DB0713430B6028680068010D21 +S11332700800C007C00FC0B20028F6D030786946F5 +S113328048712868029002984068CE490140684617 +S1133290407940038022920110400843059005982C +S11332A0029948602800FFF722FF0120694608714F +S11332B02F683968C448084069460979C9058022DD +S11332C012041140014304910498386001206946B6 +S11332D0C8702C68616BBD4808406946C978090705 +S11332E08022520511400143039103986063280032 +S11332F0FFF730FE3020305CFFF750FD69468870E0 +S113330068468078002809D0802080006946897842 +S1133310FFF7EBFC297E48436946487068464078CD +S11333206946087128680690069800687F218843DA +S1133330694609794906490E01430C910C9806998E +S1133340086001206946C870286805900598006DDA +S1133350400040086946C978C90701430B910B989E +S113336005990865CE48B16809186A46D18129686B +S1133370049104990A6DCB4911406A46D2895205D9 +S1133380C94B13400B430A930A99049A1165F168D7 +S113339009186A46918129680B6DC44A1A406B4624 +S11333A09B891B04F82464031C4014430994099A60 +S11333B00A65326912186B465A812A68146DBC4B2F +S11333C023406C466489A702FC2424023C401C432D +S11333D00894089B136573691B186C4623812B683A +S11333E01C6DB44F2740BC466C4624896701F82401 +S11333F0A4003C4067463C430794079C1C65B469A1 +S113340020186C46E0802868046D1F27BC436F4673 +S1133410FF88FF06FF0E27430765F478002C6ED063 +S113342001206946887128680268A34911406A46E8 +S11334309279520780239B051A400A430692069903 +S1133440016031796A46517129680B68CB4A1A4088 +S11334506B465B79DB0380242402234013430593EA +S1133460059A0A60326C04922A680392049A039BB8 +S11334709A644422B25C6B461A712A681468C04B81 +S113348023406C4624792702C024A4003C401C43FA +S11334900294029B13604523F35C6C46E3702B6833 +S11334A05C6BB84F2740BC466C46E4782706F02492 +S11334B024053C4067463C435C63C827F75D012F05 +S11334C03BD1002069460870684600784621715C4B +S11334D0884232D26846007880003018806C694691 +S11334E009782A680B00DBB29B00D31888242401D6 +S11334F018516B461B785B1C6C462370E4E7002074 +S113350029680B686C4A1A400300DBB25B0780240D +S1133510A405234013430193019A0A6000222B68F7 +S11335201C68964F2740BC461400E4B2E40380278D +S11335303F023C4067463C431C60706B0390286824 +S113354003990161B16B02912968029A4A61F26B95 +S113355001922A68019B9361C823F35C6C46E37073 +S11335602B681C68BC4F2740BC466C46E478240496 +S113357080277F023C4067463C431C60C927F75DB7 +S1133580002F25D0002029680B68B44A1A40030094 +S1133590DBB25B048024A402234013430193019A09 +S11335A00A6001222B685C68AD4F2740BC461400BA +S11335B0E4B2240380277F013C4067463C435C60BF +S11335C024E000BFFFDFFFFFFFFF7FFFFFFFFFEFF0 +S11335D0012029680B68A14A1A400300DBB25B048E +S11335E08024A402234013430193019A0A60002219 +S11335F02B685C689A4F2740BC461400E4B224034D +S113360080277F013C4067463C435C60D420305CAB +S1133610002853D0012001006A46917129680B6883 +S1133620904A1A406B469B799B058024E40323400F +S113363013430593059A0A6002006B465A712A687F +S11336401468894B23406C466479A4068027FF04E0 +S11336503C401C430494049B136003006C46237198 +S11336602B681C68814F2740BC466C462479A4040F +S11336708027FF023C4067463C430394039C1C6044 +S113368004006F46FC706C690294029CA46C0127D0 +S1133690BC436F46FF7838402043029CA06453E04B +S11336A0FFFF0000FFFF1F800000E07FFFFFE0FF3F +S11336B0FF03FFFF1FFCFFFFFFFFFFDF00200100F0 +S11336C06A46517129680B68664A1A406B465B79F1 +S11336D09B058024E403234013430593059A0A6061 +S11336E002006B461A712A6814685F4B23406C46CB +S11336F02479A4068027FF043C401C430494049BC3 +S1133700136003006C46E3702B681C68574F274016 +S1133710BC466C46E478A4048027FF023C4067461C +S11337203C430394039C1C606C690294029CA76C48 +S11337300124A743BC460700FFB23C00E407E40FA2 +S113374067463C43029FBC64D520305C69460871DF +S113375028680268424911406A461279120380239C +S11337605B011A400A43049204990160D621715CFA +S11337706A46D17029684B68004A05E0FF7FFFFF65 +S1133780FFFCFFFFFFFFFFF01A406B46DB78DB0313 +S113379080242402234013430393039A4A60D722CC +S11337A0B25C2B685C68324F2740BC461400E4B21C +S11337B0A4038027FF013C4067463C430294029CDB +S11337C05C6000273800CC21715CC0B288422DD2E5 +S11337D00020D02171583A00D2B214235A438C5A93 +S11337E0220092B2D02030583900C9B21423594370 +S11337F0435AD020305884463900C9B2142041437A +S1133800604640184088181882420DDA2200D2B26D +S1133810D02030583900C9B2142359434118280024 +S1133820FFF7D6FC641CDBE77F1CCBE7280000F025 +S113383082F92800FFF734FC002029680B680D4A40 +S11338401A400300DBB2DC0580231B041C40144334 +S11338500C600DB0F0BD0000FFFFFEFFFFFFFDFF99 +S1133860FFEFFFFFFFFFBFFFFFFFFFFBFFFFFBFFBC +S1133870FFBFFFFFFFFF7FFF38B504000D0029786D +S113388089B22000FFF7A4FA0168C02212050A4396 +S1133890026031BDF1B50C00217889B20098FFF7C0 +S11338A097FA05000835217889B20098FFF7D8FA0D +S11338B000210B000A001300DBB2834238D2032339 +S11338C01E00324209D129602B681600F6B2A619EF +S11338D0367A36061E432E6028E01600F6B21E40E5 +S11338E0012E08D12B681600F6B2A619367A3604D2 +S11338F01E432E601AE01600F6B21E40022E08D1B6 +S11339002B681600F6B2A619367A36021E432E60CC +S11339100CE01600F6B23340032B07D12B681600D7 +S1133920F6B2A619367A1E432E602D1D521CC2E72C +S1133930F1BDF8B506000C00217889B23000FFF71C +S113394047FA05002868000C0007000FFFF758FA33 +S1133950482160542868400D0100C907C90F684612 +S11339600170281D69460978002904D00168C9003E +S1133970C908616004E00168890C4905490D61606A +S1133980051D217889B23000FFF76AFA00210A0088 +S11339900A000300D2B2DBB29A422AD203221300F5 +S11339A0194206D12A68120E0B00DBB2E3181A7210 +S11339B01DE00B00DBB21340012B06D12A68120C68 +S11339C00B00DBB2E3181A7211E00B00DBB21A40F1 +S11339D0022A06D12A68120A0B00DBB2E3181A7213 +S11339E005E02A680B00DBB2E3181A722D1D491C8E +S11339F0CEE732689268F1BDF0B500252E000A7852 +S1133A00D206D20E0124230093400F78402F12DBFC +S1133A101C0002260568002E0AD0022E04D005D30D +S1133A20032E07D12C6705E06C6703E0EC6201E02C +S1133A302C63FFE725E00E78202E11DB1D000668BD +S1133A40002C0AD0022C04D005D3032C07D13567EF +S1133A5005E0756703E0F56201E03563FFE710E018 +S1133A601C000668002D0AD0022D04D005D3032DB6 +S1133A7007D1346705E0746703E0F46201E034635E +S1133A80FFE7F0BDF0B50300002215000878C40676 +S1133A90E40E01200600A6400F78402F16DB02201A +S1133AA01D6800280DD0022805D007D303280BD1A8 +S1133AB02F6F3A0008E06F6F3A0005E0EF6A3A00B2 +S1133AC002E02F6B3A00FFE732402EE00D78202D04 +S1133AD015DB1D6800280DD0022805D007D3032864 +S1133AE00BD12F6F3A0008E06F6F3A0005E0EF6AE0 +S1133AF03A0002E02F6B3A00FFE7324015E0100075 +S1133B001D6800280DD0022805D007D303280BD147 +S1133B102F6F3A0008E06F6F3A0005E0EF6A3A0051 +S1133B2002E02F6B3A00FFE73240002A01D0012067 +S1133B3000E00020F0BDF0B5017E032937D100215B +S1133B40C9430D0002270668002F0AD0022F04D0B3 +S1133B5005D3032F07D1356705E0756703E0F562E8 +S1133B6001E03563FFE70A0001230468002B0AD053 +S1133B70022B04D005D3032B07D1226705E062672B +S1133B8003E0E26201E02263FFE700260568002EFD +S1133B900AD0022E04D005D3032E07D1296705E0ED +S1133BA0696703E0E96201E02963FFE73EE0017E23 +S1133BB0022925D10021C9430A0001250368002DEB +S1133BC00AD0022D04D005D3032D07D11A6705E0CE +S1133BD05A6703E0DA6201E01A63FFE7002604682B +S1133BE0002E0AD0022E04D005D3032E07D121675C +S1133BF005E0616703E0E16201E02163FFE715E0AE +S1133C00017E012912D10021C94300230268002B3F +S1133C100AD0022B04D005D3032B07D1116705E08A +S1133C20516703E0D16201E01163FFE7F0BDF0B535 +S1133C3000231E000A78D406E40E01221500A540D4 +S1133C400F78402F1ADB2A0002230668002B10D0BD +S1133C50022B06D009D3032B0FD1B76E1743B766D7 +S1133C600BE0F76E1743F76607E0776A174377624E +S1133C7003E0B76A1743B762FFE735E00E78202EFA +S1133C8019DB2B000668002A10D0022A06D009D3BB +S1133C90032A0FD1B76E1F43B7660BE0F76E1F43BD +S1133CA0F76607E0776A1F43776203E0B76A1F434A +S1133CB0B762FFE718E02A000668002B10D0022B39 +S1133CC006D009D3032B0FD1B76E1743B7660BE0A9 +S1133CD0F76E1743F76607E0776A1743776203E0E6 +S1133CE0B76A1743B762FFE7F0BDFFB591B000258F +S1133CF001200990012008900820019003210491DB +S1133D000222059214221092834A0F92FA229205FB +S1133D100E921BAA1278002A0DD1804A0D925E22BF +S1133D2002920C911F2107910299079A8918491C44 +S1133D300B910A900CE0794A0D92262202920C9182 +S1133D40072107910299079A8918491C0B910A9037 +S1133D50139800F0EDF8040001260D98B04259DBE9 +S1133D60129800F0E5F80500300000F0F1F80100C9 +S1133D70280000F0F8F80500139800F0D9F80100C5 +S1133D80280000F0F0F800F041F9009000980028B5 +S1133D9003D000980A99884200DA3BE0009800F0CA +S1133DA0D7F80100280000F0DEF80700139800F0AF +S1133DB0BFF80100380000F07EF98021090400F00A +S1133DC0D3F908D8139800F0B3F80100380000F0D4 +S1133DD072F9020006E0139800F0AAF8390000F026 +S1133DE06AF902000B980099884211DB2000110047 +S1133DF000F0BAF90CD809960098019014001098B4 +S1133E000099884204DB10000F9900F0C1F901D336 +S1133E10761CA2E714A8008800F08AF80E9900F036 +S1133E20CAF9039001980299884201DA0198029034 +S1133E30029C0C98844225DB2000401C38494843EE +S1133E400199FEF74FFF050014A80088281A0128DD +S1133E5003DB14A800882F1A02E014A80088471B6B +S1133E6014A8008885420DDB380000F071F803992E +S1133E7000F08EF904D20494380000F069F803903D +S1133E80641ED6E701980499401A401E05902548FF +S1133E90039001250598A84221DB21486843019934 +S1133EA0FEF720FF07001AA80088381A012804DB4F +S1133EB01AA80088381A069003E01AA80088C01BC4 +S1133EC00690069800F044F8039900F061F904D2D2 +S1133ED00895069800F03CF803906D1CDAE7099801 +S1133EE011990860049800F0CFF90FA20CCA00F0F1 +S1133EF0D5F900F095FA11998860049811998968A8 +S1133F00401A1199C8600598119908610898119987 +S1133F10486015B0F0BD0000CDCCCC3DFF030000DF +S1133F201027000000401C46333333333333E33F60 +S1133F309D2102000AD002D4491E9218FCD5C9055D +S1133F40100A1206524100D3012A4841704700006A +S1133F509D210200EED55242F446FFF7EBFF012209 +S1133F60D2071043604730B405004D400122D20708 +S1133F7015404B180418240E25D01B0E2CD0FF2CF2 +S1133F8031D0FF2B34D0E41A00020902104311434C +S1133F9043084808D10D1B1A02D2641EDB181B18F3 +S1133FA0DB18834200D31B1A4941F9D37F3423DD44 +S1133FB0FF2C05DAE40548086041284330BC70470B +S1133FC0FF20C005F9E728001B0E03D0FF2BF5D115 +S1133FD04902F3D0D043F1E7FF2C01D14002F9D1DB +S1133FE0FF20C005E9E74002F4D1FF2BF8D1F1E747 +S1133FF028004902E2D0EDE70B0200202442DCD184 +S11340005B129B1CD9D9D805D7E7FEE70122D2075A +S11340100118090E7F3910D449421F310FD40018FA +S113402005D2C0011043C84000D5D0437047C00139 +S11340301043C84005D440427047002070470042F6 +S1134040F3D5100070470122D20703004B402ED451 +S1134050431A01D2C01AC91830B44B180418240EDC +S11340601B0E22D0FF2C20D0E31A182B1DDC0902D2 +S11340701143C40D641E0002104394461925ED1A21 +S11340800A00AA40D940451801D36D08A41CE405D0 +S1134090D209280A2D062A436546AA41604103181D +S11340A01B0EFF2B01D3C00DC00530BC704751401F +S11340B006E05140CCE70122D20703004B40F8D47C +S11340C0431A03D2C01AC9185040514030B44B1897 +S11340D0090211430418240E1B0E40D0FF2C3AD0C1 +S11340E025009D410BD31ED8C50D4002401A0BD3A9 +S11340F0ED050100400AC90591416841D5E7C50DA8 +S113410040024918401AD0D001214008491C001827 +S1134110FCD58C4204D36D1A000AED054019C4E79E +S1134120E8051040C1E7182DBFDCAC1C0D00E140D0 +S1134130E5414D40012D4941C40D00021043451A8B +S113414001D46D199543641EE405280A2D06954192 +S1134150604130BC7047FF2BA7D1D843A5E7244268 +S1134160A3D10020A1E7FEE70CB401221206031834 +S1134170DA4207D84B18DA4204D802000A439218EC +S113418002D281420CBC7047FCD088420CBC704700 +S11341900CB4012212060318DA4207D84B18DA428B +S11341A004D802000A43921802D288420CBC704719 +S11341B0FCD08142FAE730B405004D400122D20719 +S11341C015404B180418240E2ED01B0E32D0FF2C91 +S11341D034D0FF2B3AD0E4180002090210431143F3 +S11341E0000A090A9446C2B24A43000AC3B24B43C6 +S11341F0000A4843110A5B181A43D2B2190A091873 +S113420001D44918641E080A7F3C23DBFE2C08DA1B +S1134210E40509061143634699416041284330BCD3 +S11342207047FF20C005F9E728001B0EFF2BF6D1CD +S1134230D043F4E72800FF2CF1D1F9E74002F7D18D +S1134240FF2B01D14902F3D1E005E7E7D805490284 +S1134250E4D0EDE743020020641CDFD15B129B1C19 +S1134260DCD9D805DAE7FEE7010042221201D21EAA +S1134270004207D002D4521E0018FCD5C10A4005E2 +S113428012058918704700000100EED54042F4463B +S1134290FFF7EBFF0122D20711436047F0B50E0090 +S11342A05E400125ED072E40B446AE0ADF184C18D7 +S11342B0F44208D2F7420ED2640D01D07F0D12D120 +S11342C000206146F0BD05D1F74201D87F0D05D12C +S11342D00020C143F0BDFBD1640DF9D00020C143DF +S11342E0490549088FE0E419C902DB0229432B433D +S11342F0DB0A460DC00231438E4630B487B295B214 +S11343007D432E0CADB2140C7C43A419260C24045A +S113431025439CB27C43A419190C7943270CC91971 +S1134320A4B20F043C43090C000C97B247432E0C73 +S1134330BE193543ADB2170C4743360CBF19A6B2AC +S1134340BF193E043543240C3E0C36199FB2474333 +S1134350BF19BCB23E0C89191F0C47437F183E0499 +S11343603443390C704680B297B247432E0CBE19C1 +S11343703543ADB2170C4743360CBF19A6B2BF196B +S11343803E043543240C3E0C36199FB24743BF19F3 +S1134390BCB23E0C89191F0C47437F183E043443BA +S11343A0390C77463F0C90B278432E0C80190604E2 +S11343B0ADB22E43050CA0B22D18120C7A4350193D +S11343C0020C80B2240CA4189AB27A431219140471 +S11343D02043120C89181B0C7B43C91830BCEF0A0C +S11343E0394203D1B61940414941641E6F12BF0DD1 +S11343F0E41B0BDBFF19BC4211DA24050027420839 +S1134400AE417841614166463143F0BD641C05D13B +S1134410401C6141CF0201D34908F4E750E75DE74E +S11344204A1812D2400DC90208430121C9070843A2 +S1134430520D40210901521A521C06D452421F3215 +S113444001D4D0407047C017704700207047000067 +S1134450F8B59CB0050000263700300069460870A6 +S1134460029601963400300069468870402200218B +S11344700CA800F00DFE04A8D349202200F012FE7F +S1134480082069464870FF20801C0390300001001A +S11344906A465278C9B291420FD20021C9430CAA8C +S11344A00300DBB2DB00D15031000CAA0300DBB205 +S11344B0DB00D2189180401CE9E7370038006946D8 +S11344C04978C0B288424BD20220040003982100EC +S11344D089B288423ED3286804A93A00D2B2920035 +S11344E08958FEF702FC210089B2FEF7FEFB019019 +S11344F001986968884213D10CA83900C9B2C9006F +S113450041188C803900C9B2C900401887710CA8C1 +S11345103900C9B2C900465001206946887019E0C3 +S113452001986968884213D20CA83900C9B2C9003D +S113453041188C803900C9B2C90040188771686875 +S11345400199401A0CA93A00D2B2D200885001E075 +S1134550641CBBE768468078002801D17F1CADE766 +S1134560684606700CA869460978C900405802904C +S11345700126300069464978C0B2884211D20CA89D +S11345803100C9B2C90040580299884207D20CA828 +S11345903100C9B2C9004058029068460670761CC2 +S11345A0E7E70CA869460978C900411889880229F7 +S11345B017DA286804A96A46527892008918091FF4 +S11345C00968FEF792FB0399FEF78FFB019068469A +S11345D04078401EA8600398801EE8600198286116 +S11345E014E069460978C90041188979A9606946C7 +S11345F00978C90040188088801EE86068680CA9A2 +S11346006A461278D2008958401A28611DB0F0BD5C +S1134610F8B58AB004000D00002000900700029055 +S11346202000006E00900021684600F0F4FC002198 +S1134630684600F0E1FC697B684600F0A3FC697AF7 +S1134640684600F075FCA97A684600F068FC686862 +S113465006902868059005A8FFF7FAFE07986946B2 +S1134660087108980290029E03940398006CFF213D +S113467088433100C9B20143049104980399086442 +S113468068460179684600F061FCE989491E89B2EF +S1134690684600F0F3FCA87B800604D5E97E6846F2 +S11346A000F07EFC03E00021684600F079FCE97A22 +S11346B0684600F059FC687D002805D0022829D0FE +S11346C010D303283ED04BE00021684600F0B2FC32 +S11346D0E97F684600F090FC2020295C684600F0E1 +S11346E09AFC4AE00121684600F086FC00216846F5 +S11346F000F091FC287C002804D10021684600F0D9 +S113470099FC06E0287C012803D10121684600F0C9 +S113471091FC32E0287C002804D10021684600F096 +S113472089FC06E0287C012803D10121684600F0B9 +S113473081FC0121684600F05FFC0021684600F01E +S11347406AFC1AE00021684600F074FCE97F6846C0 +S113475000F052FC2020295C684600F05CFC0CE070 +S11347600021684600F066FCE97F684600F044FCDE +S11347702020295C684600F04EFC009820660BB0AF +S1134780F0BDF8B50A7A6B461A700200536A6C469B +S11347902478012C03D101241C43546202E05C08F8 +S11347A0640054620C7BCD7AAC4005006E6ACB4F3A +S11347B03740BC462600F6B23702F02636013E40AA +S11347C067463E436E62F1BD08C40000F6B588B08A +S11347D0099909780200D6690B00DBB2012B03D1D9 +S11347E001233343D36102E073085B00D361099B67 +S11347F05B780400E5691F00FFB2012F03D1022199 +S11348002943E16103E0290002229143E16109990E +S113481089780200566A0F00FFB2012F03D10823E2 +S11348203343536203E033000824A3435362099BD8 +S1134830DB780400256A1F00FFB2012F04D1802118 +S113484049002943216202E0A549294021620090E0 +S113485000210E000122009F7F6A1740002F01D023 +S113486013001E00F6B2002E0FD1099B5B790400E1 +S1134870656A1E00F6B2012E03D104262E43666239 +S113488003E02E000427BE436662099BDB796C4675 +S1134890237005002E696B461B78012B03D104237A +S11348A033432B6103E033000424A3432B61099BAE +S11348B09B796C46237103001C696F463F79012F75 +S11348C003D1082525431D6103E025000826B543CF +S11348D01D61089D6D786E46F5700490049D2E6CE4 +S11348E0804D35406E46F67836022E430796079D76 +S11348F0049E3564089DAD786E46B5700390039DA3 +S11349002E6C794D35406E46B67836042E430696A5 +S1134910069D039E3564089DED786E467570029081 +S1134920029D2D6C2D022D0A6E46767836062E4396 +S11349300596059D029E3564089D2D796E46357059 +S113494005006F6A7026B743BC466E463678370159 +S113495070263E4067463E436E62089F7F79002F73 +S113496005D0022F39D024D3032F4AD06DE0089B01 +S11349709B79002B00D10A0003005C6A1500EDB29C +S1134980002D04D08025ED0425435D6202E0574DDF +S113499025405D6205006E6A554F3740BC460E00E7 +S11349A0F6B23706C026B6043E4067463E436E6202 +S11349B06CE013000400616A4D4D0D401900C9B24A +S11349C00E06C021890431402943616205006E6AE4 +S11349D08027FF0437436F6258E002230400616AB2 +S11349E0434D0D401900C9B20E06C021890431405F +S11349F02943616205006E6A8027FF0437436F62B2 +S1134A0044E0089B9B79002B01D01100FFE70200D2 +S1134A10536A0C00E4B2002C04D08024E4041C4348 +S1134A20546202E0314C1C405462032405006E6A57 +S1134A302F4F3740BC462600F6B23706C026B604D0 +S1134A403E4067463E436E6220E0089B9B79002B04 +S1134A5000D10A0003005C6A1500EDB2002D04D0F9 +S1134A608025ED0425435D6202E0204D25405D6212 +S1134A7005006E6A1E4F3740BC460E00F6B237067C +S1134A80C026B6043E4067463E436E620AB0F0BD9F +S1134A908149016081494160012202720021417211 +S1134AA08172C172017342730822C281C175017699 +S1134AB041768176C17601774177C177202281548E +S1134AC08177022202740A22130043741300837450 +S1134AD0C27401754175817570470000FFF0FFFFD6 +S1134AE0FFFEFFFFFF00FFFFFFFF00FFFFFFFFFBD5 +S1134AF0FFFFFFFCF0B587B004000D0000206946FD +S1134B004870206802900298006906900698012176 +S1134B108843029908612068019001980069059012 +S1134B20059880214900014301980161276838698B +S1134B3004900498802189000143396100BF00BFBB +S1134B4000BF29002068FFF71CFE2A001732290045 +S1134B5010312068FFF73AFE012001006A46117007 +S1134B60266831690391039908433061290020685C +S1134B70FFF74EFD07B0F0BDF2B482B002990160B8 +S1134B8001680A690192019A80235B0013430B6157 +S1134B90026813690093009B8024A4001C431461E1 +S1134BA001230468256902262E43266100BF00BF45 +S1134BB000BF002607683E61F7BC7047F0B50300EC +S1134BC00022100014000D006D1E17D06D1E1DD0A4 +S1134BD0FE3D24D080267600AD1B29D08026B60069 +S1134BE0AD1B2ED08026F600AD1B33D080263601B7 +S1134BF0AD1B38D08B4EAD1B3ED046E01D686F69AF +S1134C003E00F607F60FF6B234003EE01D686E690A +S1134C1077083E00F607F60FF6B2340035E01D685B +S1134C206E69370A3E00F607F60FF6B234002CE040 +S1134C301D686E69770A3E00F607F60FF6B2340077 +S1134C4023E01D686E69B70A3E00F607F60FF6B258 +S1134C5034001AE01D686E69F70A3E00F607F60F85 +S1134C60F6B2340011E01D686E69370B3E00F6079A +S1134C70F60FF6B2340008E01D686E69370E3E0088 +S1134C80F607F60FF6B23400FFE7002C01D001223C +S1134C901000C0B2F0BD000000B4C40440420F00D4 +S1134CA0FFB583B0012069460870002420000399F1 +S1134CB009682200CB6DDB06DB0E1025EB1A6D466E +S1134CC06B706B465B786D46AD8A9BB2AB4200D28B +S1134CD0A2E00194250020006946488003980068FA +S1134CE0006E0190002101A800F078F9012101A8CB +S1134CF000F065F9002101A800F08DF9002101A858 +S1134D0000F07AF96846007CC100491E89B201A806 +S1134D1000F0B4F901980399096808662600300088 +S1134D206946898A80B2884269D203980168220060 +S1134D3001204F6903003B40DBB2002B06D16D1C00 +S1134D4039498D42F1D321006A4611706946097CC4 +S1134D50012907D10699320092B2895C039A12683C +S1134D60516614E06946097C022908D1069932008B +S1134D7092B25200895A039A1268516607E0069962 +S1134D80320092B292008958039A12685166250043 +S1134D900399096822000B6F5B080340002B01D0C4 +S1134DA003001A00D2B2002A06D06D1C1E498D429F +S1134DB0EED32000694608706846007C012807D1BC +S1134DC003980068406F0C99320092B2885414E042 +S1134DD06846007C022808D103980068406F0C994B +S1134DE0320092B25200885207E003980068406F84 +S1134DF00C99320092B292008850761C8FE7002101 +S1134E0001A800F0EBF8002101A800F0D8F80198FF +S1134E1003990968086601E06846047068460078EA +S1134E2007B0F0BD00F0FF00E9030000F0B5030097 +S1134E30002210000C00641E14D0641E1CD0FE3C22 +S1134E4024D080256D00641B2BD08025AD00641B0D +S1134E5032D08025ED00641B39D080252D01641BE0 +S1134E6040D04AE0012425001E68B7692F40AF42B4 +S1134E7000D12200100040E002241D68AE692640E3 +S1134E80A64201D101263200100036E080246400DD +S1134E901D68AE692640A64201D1012632001000E9 +S1134EA02BE08024A4001D68AE692640A64201D1EF +S1134EB001263200100020E08024E4001D68AE6961 +S1134EC02640A64201D101263200100015E08024BC +S1134ED024011D68AE692640A64201D10126320094 +S1134EE010000AE0802464011D68AE692640A642D1 +S1134EF001D1012632001000FFE7C0B2F0BD70B44A +S1134F000A0003689D6D524C2C401500EDB22E042E +S1134F10F8256D03354025439D6570BC70470268D4 +S1134F20520052080B00DBB2DB07134303607047E7 +S1134F3010B40268474B13400A00D2B2920780248F +S1134F40E40522401A43026010BC704710B40268A2 +S1134F50414B13400A00D2B2D406E022920522400B +S1134F601A43026010BC704710B402683B4B1340F4 +S1134F700A00D2B21406C022920422401A430260EC +S1134F8010BC704710B40268354B13400A00D2B20B +S1134F90D2058024240422401A43026010BC7047C6 +S1134FA000B502680B00DBB2012B04D18023DB03C4 +S1134FB01343036002E02B4B1340036000BD00B5B4 +S1134FC002680B00DBB2012B04D180239B03134343 +S1134FD0036002E0244B1340036000BD10B4026878 +S1134FE0224B13400A00D2B21205802464032240EB +S1134FF01A43026010BC704700B502680B00DBB2B4 +S1135000012B04D180231B031343036002E0184BDC +S11350101340036000BD00B502680B00DBB2012B36 +S113502004D18023DB021343036002E0114B1340DD +S1135030036000BD10B402680F4B13400A00D2B2E3 +S11350401404C022920222401A43026010BC70472A +S1135050FFFFE0FFFFFFFFBFFFFFFFC7FFFFFFFCF6 +S1135060FFFF7FFFFFFFBFFFFFFFDFFFFFFFEFFF3C +S1135070FFFFF7FFFFFFFBFFFFFFFCFF0268120BC0 +S113508012030B009BB21B051B0D134303607047F7 +S113509010B50400080011000200200000F02AF8F6 +S11350A0200010BD70B4103A03D378C9103A78C008 +S11350B0FBD2530701D318C918C001D508C908C0C9 +S11350C0D20704D30B880380891C801C002A01D5D5 +S11350D00B78037070BC70478B0701D18307E1D054 +S11350E0124205D00B78491C0370401C521EF9D1A2 +S11350F0704700001206130A1A43130C1A4300BF28 +S1135100094205D0830705D00270401C491EF9D11D +S1135110704700001300103906D330B41400150092 +S113512010393CC0FCD230BC490700D30CC000D5B8 +S113513004C0890002D30280801C002900D50270BB +S11351407047000000B5010008000200D2B2802AB6 +S113515001DB7F221000C0B200BD00B501000800D1 +S1135160C0B2F12805DB0800C0B2FA2801DA012038 +S113517006E00800C0B2802801DA080000E0002040 +S1135180C0B200BDFEB582B0070000252C006E46FB +S11351903F20307030786946097AF0220A43024091 +S11351A032706846007B70706846007CFFF7CAFF67 +S11351B0B0703878002810D0032004002000C0B25A +S11351C0082804DA2000C0B23554641CF6E708222B +S11351D06946F868BB6D984704E003226946F8689D +S11351E0BB6D984740B205B0F0BDFEB50600002087 +S11351F0050001006A460F2313701378F48AF02720 +S113520027431F40177004002100C9B2F38A89B2F2 +S1135210994209D231692300DBB2C95C2300DBB2B5 +S1135220D3185970641CEFE73178002916D00500B3 +S11352302800C0B20721F38AC91A884208DA280074 +S1135240C0B2F18A40181018CC2141706D1CEFE7F0 +S113525008226946F068B36D984706E0F28A521C4A +S1135260D2B26946F068B36D984740B2FEBD3EB510 +S1135270050068461F2101700178EA8A92B2120A79 +S1135280F02313430B400370E98A4170002421008A +S1135290C9B2E4B22100C9B2062909DA2969220097 +S11352A0D2B2895C2200D2B282189170641CF1E7F8 +S11352B008226946E868AB6D9847010049B20029A5 +S11352C004D1298B891D29830121A97640B23EBDD1 +S11352D0FEB5060000273900C9B201A82F220270CA +S11352E00278B37EF0241C4314400470F28A338B9A +S11352F0D21A6B461A806A461288082A02DB0722F1 +S11353006B461A803C00E4B22100C9B26A46128896 +S113531089B291420BD23169328B2300DBB2D218AD +S1135320895C2200D2B282185170641CECE7317897 +S113533000291BD03900C9B23D00EDB22A00D2B217 +S113534007216B461B88C91A8A4209DA2900C9B2A7 +S11353506A46128889184118CC224A706D1CEDE700 +S1135360082201A9F068B36D984707E068460288EF +S1135370521CD2B201A9F068B36D9847010049B23A +S113538000290BD1318B6A46128889183183B17E8A +S1135390491CB176B17E102900DBB77640B2FEBD60 +S11353A0F8B504000D00160000210F000F202B7823 +S11353B00200134206D03200D2B2521E2B780340B0 +S11353C09A4208DA606D002802D0A248616D8847CD +S11353D00620C04315E02A7810404222A05208005B +S11353E0C0B24222A25A80B2904209D20800C0B28E +S11353F028184078E26B0B00DBB2D054491CEEE76E +S11354000020F2BDF8B504000D00170000210800CB +S11354106A4610703800C0B2082808D0606D0028B1 +S113542002D08D48616D88470620C04339E0287852 +S11354300002F0221201024068781618300080B28F +S1135440082808DA606D002802D08448616D884716 +S11354500620C04325E04020205A320092B29042F8 +S113546008D2606D002802D07D48616D8847022013 +S1135470C04316E0422026520800C0B2062809DACA +S11354800800C0B228188078E26B0B00DBB2D0545D +S1135490491CF1E706204422A05201204622A054D0 +S11354A00020F2BDF4B505000C00002217004620D0 +S11354B0285C21780907090F884202D00320C043E1 +S11354C040E04220285A4421695A461A300080B2EA +S11354D0082801DB0720060068460078401E3100DA +S11354E089B2884208DA686D002802D05D48696D87 +S11354F088470620C04325E011000800C0B23300ED +S113550080B29BB298420CD2E86B0B00DBB244270A +S1135510EF5BDB190F00FFB2E7197F78C754491C12 +S1135520EBE74420285A80194423E8524620285C9B +S1135530401C4623E8544620285C102801DB462002 +S11355402A540020F2BD70B504000D00160030008E +S1135550C0B2032808DA606D002802D04248616DA9 +S113556088470620C04300E0002070BD70B50400E9 +S11355700E0015002B009BB23200E168200000F001 +S113558001F870BDFEB5040000263700002C02D1DE +S11355900020C0435CE0A08A69460989884208D299 +S11355A0606D002802D03148616D88470220C043F5 +S11355B04EE03420205C012808D1606D002802D020 +S11355C0CA48616D88470120C04341E068460089AC +S11355D0E0823000208335002800C0B26946098982 +S11355E080B2884209D201982900C9B2405C21697D +S11355F02A00D2B288546D1CEEE7E08A082804DA47 +S11356002000FFF7F2FD070020E02000FFF72FFE47 +S11356100700380040B2002818D13000A0833000C1 +S1135620A0773000E077E06D80472200203203C28B +S1135630083AE06D8047002264305141220028324C +S113564003C2083A2663012034216054380040B272 +S1135650FEBD000070C300009CC3000068C20000CF +S1135660A0C20000C8C30000E8C30000D8C2000004 +S1135670FFB583B004006846007E022803DB684659 +S1135680007E092800DB2FE100252900C9B228008B +S1135690C0B201006A46127EC9B2914209D205998C +S11356A00200D2B2895C01AA0300DBB2D154401CCF +S11356B0EFE72F00FFB23800C0B208216A46127E1D +S11356C0891A884208DA01A83900C9B26A46127EEA +S11356D0891845547F1CEEE701AE3078C0B200094A +S11356E0002806D0022865D021D3032800D1B3E0D6 +S11356F0FAE05120205C012804D10520C043502148 +S1135700605401E0502025546846027E01A920001F +S1135710FFF746FE694608706946002008560028CF +S113572004D10498A063022051216054DCE051208C +S1135730205C012804D10520C0435021605401E0BD +S1135740502025546846027E01A92000FFF75AFE26 +S1135750694608706946002008560221C9438842F8 +S11357600CD10720C04350216054512025540023FC +S1135770002202212000FFF705FDB5E06946002064 +S11357800856002815D10498A063012051216054C3 +S113579060784721605401234720225C00212000C7 +S11357A0FFF7F0FCE06D8047002264305141A064B3 +S11357B0E16499E05120205C012804D00520C04315 +S11357C05021605490E00498A16B884200D08BE093 +S11357D06846027E01A92000FFF764FE694608704E +S11357E00326F643694600200856B04207D101A8B3 +S11357F000F0A6FB502026545120255474E069463D +S113580000200856002826D1E06D8047002264302D +S11358105141A064E1644420205A4221615A8842E3 +S113582003D302205121605415E06078002812D07F +S11358304720205C401E472160544720205C0028FC +S113584009D160784721605401234720225C00215C +S11358502000FFF797FC47E03420205C012843D167 +S11358606846027E01A92000FFF76DFE69460870B4 +S1135870694600200856002835D1E06D8047002293 +S1135880643051412200283203C2083A0F20317893 +S11358900140022906D10720C0432063022034219D +S11358A0605420E03178014001290CD1E07F401C94 +S11358B0E077E07F022816DB0620C0432063022045 +S11358C0342160540FE0317801420CD17078002803 +S11358D002D18448A08301E07078A083B078FFF7F8 +S11358E03CFCA077E577FFE707B0F0BD0CC30000F0 +S11358F0FEB50100089A0020030051240C5D022C1F +S113590002D00420C04328E08C6B8D68AC4201D1E6 +S1135910012400E00400009D2C7042240C5B6D46C1 +S11359202D892600B6B2B54202D26D462D892C00CF +S113593005002B0026009BB2B6B2B34209D2CB6B52 +S11359402E00B6B29B5D019E2F00BFB2F3556D1CB5 +S1135950EFE714805123C8540020FEBD70B4020048 +S11359600B00187810705878507058685060986818 +S11359709060D868D06018691061988A9082002479 +S11359802000D08220001083200090762000908395 +S1135990200090772000D0770020002115002035CA +S11359A003C5083D1500283503C5083D14632500CB +S11359B0342695559D69D5639D8B402695532500C6 +S11359C04226955325004426955325004626955591 +S11359D02500472695559064D164200050215054E9 +S11359E051201454186A5065586A9065986AD065B5 +S11359F070BC704770B504003420205C01285AD173 +S1135A00384DA08BA84202D0A08B002841D0A07FA3 +S1135A10002810D0A07F00283BD0E06D8047020012 +S1135A200B002000203003C8801A9941002930DC83 +S1135A3001DB00282DD22000FFF74AFC06003000CD +S1135A4040B2002822D1A08BA84202D0A08B4019DA +S1135A50A083E06D80470022643051412200283247 +S1135A6003C2083AE06D804702000B00A07F0021CA +S1135A70801859412200203203C2083A208BE18A5F +S1135A80884206D300203421605402E002203421ED +S1135A906054E06D8047220028320CCA121A8B41F0 +S1135AA0002B08DC01DB002A05D20120C04320635F +S1135AB00220342160545120205C012811D1E06D72 +S1135AC08047A26CE36C121A8B41002B09DC01DBCA +S1135AD0002A06D20220C0435021605400205121E4 +S1135AE0605470BDFFFF000008B4024B9C4608BC24 +S1135AF06047C04639020020F0B5020052B2002AC5 +S1135B0017D41822B74B040064B2A408A4001C598B +S1135B10FF25C6001640B540AC438D01EDB2C6006A +S1135B20324095402543020052B2920892009D50A3 +S1135B301BE00F22AC4B182405006DB21540083D44 +S1135B40AD08AE0005006DB22A40083A92089200F2 +S1135B509A58FF25C7002740BD40AA438D01EDB2E6 +S1135B60C7003C40A54015439D51F0BD10B504004D +S1135B70601E80214904884201D301200EE0601E8A +S1135B809A49086003210020C043FFF7B5FF0020B5 +S1135B90974908600720BD490860002010BD002215 +S1135BA002604160012303724272704700B5017ABA +S1135BB000290FD0417A00290CD101684268914232 +S1135BC008D20168491C016001684268914201D110 +S1135BD00121417200BD70B504000E001500AC48EF +S1135BE0215AD6482018FFF7DAFF7820205C0128D4 +S1135BF006D02A0092B2310020001830FFF7B6FC1C +S1135C0070BDFEB505000E001400082100226F4689 +S1135C103800FFF76FFA2000C0B2782805D09C48FE +S1135C20295AC6482818FFF7BAFF7920285C0028AB +S1135C3014D02000C0B211280FD02000C0B2122806 +S1135C400BD02000C0B2312807D02000C0B27E287B +S1135C5003D02000C0B27F2800D10AE068467F212B +S1135C600170467084700322694628001830FFF7DB +S1135C707DFCF7BD10B5040088200001201803C87E +S1135C800022401C514188221201A21803C2083A82 +S1135C90892000012018FFF789FFB5482018FFF775 +S1135CA085FFA6482018FFF781FF10BDB14803C83F +S1135CB0704780B5B0480168491C0160AD4A03CA09 +S1135CC0083A0023401C594103C2083AC448FFF76C +S1135CD0D1FF01BDF8B596B0002000216A461170CD +S1135CE0C04C68460078CC21615C884251D2684639 +S1135CF0007869460873BC4D03A92868FDF7C2FE05 +S1135D00002840D0D02020586946097814225143F5 +S1135D104018407A012832D103A92868FDF76CFEA7 +S1135D2003A92868FDF705FE03AC4820205C029017 +S1135D3003A808300190AD4D982040012E1830780A +S1135D404C2148432818071D029A01993800FFF78F +S1135D50C3F9049831784C225143685030784C216F +S1135D604843281844214822A25C42543078401CFD +S1135D7030703078202806D30020307003E003A967 +S1135D802868FDF739FE68460078401C69460870AB +S1135D90A6E717B0F0BDF1B582B0002468460470E0 +S1135DA092489349451898214901415C2A789142C7 +S1135DB015D04C2629784C22514340180190029F5B +S1135DC0320001993800FFF787F92878401C2870C1 +S1135DD02878202800D32C70012069460870684672 +S1135DE00078FEBD00E400E01CED00E014E000E0FB +S1135DF018E000E0F3B595B0170000242600F6B2D1 +S1135E002000C0B2E4B277482100CC22825CC9B23F +S1135E1091420ED21599D02282582300DBB2142568 +S1135E206B43D2185268914201D1260001E0641CF0 +S1135E30E9E7D03002A902683300DBB214256B43D2 +S1135E40D25A0A7048228F5400683100C9B2142211 +S1135E5051434018406803903800C0B2019016982E +S1135E60009002A805000835019A00992800FFF760 +S1135E7033F95D4D02A92868FDF70CFD02A92868D5 +S1135E80FDF7FAFC002017B0F0BD000010E000E0C0 +S1135E908C080000FEB500240294534F554E300088 +S1135EA0803038603500D03505220021280000F00C +S1135EB036FA05220121280000F031FA494D280064 +S1135EC0FDF79BF80420CC2168544B48D02168503E +S1135ED0012001002970210069702100A9702100AE +S1135EE0E97030216C54C821685402AA0B21300097 +S1135EF00830FCF776FE687801280BD10120019068 +S1135F00FA20C0000090A94BA94A029928001C302D +S1135F10FDF7EBFE00200190A6480090A34BA64A93 +S1135F20029928000830FDF7E0FE29003868FDF7E3 +S1135F3085F9092000F082FAF7BD0000A8080000E6 +S1135F4010B5040000200100C9B2082908DA0100D4 +S1135F50C9B2615C994A0300DBB2D154401CF2E738 +S1135F60082296498D208000FFF744FF10BD0000F1 +S1135F709C08000000200020A0320020F8B586B064 +S1135F80012501AC28002070022630006070280032 +S1135F90A0808B4F01AA07213800FCF73FFE2800A0 +S1135FA0207030006070A68001AA07213800FCF739 +S1135FB035FE25700720607001AA29213800FCF7FE +S1135FC02DFE8048006E009002216846FEF7BEFF59 +S1135FD000F03CFA00F0B9FB07B0F0BD000000008F +S1135FE008200020D04F0020A8500020CC3C0020E6 +S1135FF0011300001C310020C8C10000F8B59CB09A +S113600000F064FD7049002000F0BCFF00F00CFAC1 +S11360106E4C200000F0C6FFC0204000201801F0A4 +S11360205FF86B480390002002906A4D029A03992E +S11360302800FFF75FF8D820019000200090664DFB +S1136040009A01992800FFF755F804A8012101706E +S11360500121818004AA132120000830FCF7DEFD11 +S113606004AA142120000830FCF7D8FD04AA152145 +S113607020000830FCF7D2FD04AA162120000830C5 +S1136080FCF7CCFD04AA172120000830FCF7C6FD5C +S11360902500E03501220121280000F040F900220A +S11360A00121280000F096F902220121280000F0C5 +S11360B0B6F8FFF7EFFE494F4949380001F03AF8C6 +S11360C0484E494B494A3900300001F0BAFA484D6C +S11360D02A00092120000830FCF783FD2868FA21F2 +S11360E08900FCF702FEFFF741FD424800F0A6F9E3 +S11360F03000FFF7F9FC00F089F93F4801680029F6 +S11361003DD0002404603D4D2868401C2860286868 +S11361100A21FCF7EAFD002905D139480078012855 +S113612001D100F0ABFA2868FA21890088420FD324 +S11361302C60012000F0B0FA04003248026811001B +S1136140491C01602300DBB22F49002000F01AFF34 +S11361502B48017800290AD12C490A78521C0A706C +S113616009780B2903DB01210170FFF707FF0120E8 +S113617001F06AFB380001F041FC01F04FFB09A873 +S1136180FFF709FE0128B8D109982149884203D0B4 +S1136190099820498842B0D109A84421435C021DD2 +S11361A0099938001830FFF763FAA6E74C1D000080 +S11361B080841E00C409000020A10700EC06002012 +S11361C02431002080320020A8C400001C310020AB +S11361D004130000CC3C0020D04F002008200020F5 +S11361E0B80600207C310020035C0000D75B00006F +S11361F0A8320020FFFF0000A0320020A4320020BB +S1136200D3550020AC500020C0C40000D25500205B +S113621031070000DF070000016042607047F5B5F8 +S113622083B0122979D26846007C002803D0022862 +S11362304DD026D371E00023684643700800039ACA +S11362401268840014590225AC436D466D786D00C4 +S11362500226354025430195019C850054516C4626 +S113626023700B00039C24689D0065590126B543E7 +S11362706E4637783E00F607F60F2E439D006651B2 +S11362804BE0012002000191039B1B68019CA400C8 +S11362901C590225AC431500EDB26D0002263540B1 +S11362A025430295029C019DAD005C5100240091A0 +S11362B0039D2D68009EB600AE590127BE432700FA +S11362C0FFB238403043009EB600A85125E00020BC +S11362D00191039A1268019B9B00D3580224A343A3 +S11362E00400E4B2640002252C401C430294029B87 +S11362F0019CA400135101231C000091039D2D68EF +S1136300009EB600AE590127BE432700FFB23B40B2 +S11363103343009EB600AB51FFE705B0F0BDF5B5C1 +S113632082B06846007B002828D16846007B6A4614 +S113633010700800029A12688300D458244B23403A +S11363406C4624782402E025ED0025401D43019588 +S1136350019B8400135101230C00029D2D68A600AB +S1136360AF590426B743BC461E00F6B2B600042754 +S11363703E4067463E43A700EE5127E000200A0056 +S1136380029B1B6894001C590425AC430500EDB224 +S1136390AD000426354025430195019C95005C51D0 +S11363A06C46247B6D462C700C00029D2D68A60063 +S11363B0AE59074F3740BC466E4636783702E02662 +S11363C0F6003E4067463E43A700EE51FFBD000085 +S11363D0FFF8FFFF30B443685B6901248C40A3439A +S11363E01400E4B28C401C43230045686B6130BC4C +S11363F07047000000B5010049B2002905D401210D +S1136400C206D20E91400B4A116000BD00B50A4885 +S11364100168012906DB0168491E01600068012842 +S113642000DA62B600BD000072B603480168491C78 +S11364300160704700E100E01831002010B504004D +S1136440200040B2FFF7D6FF10BD000018B589B098 +S113645000F041F86846FEF71BFB0120694608720C +S1136460804A0192C87248727F4C6A4629212000F2 +S11364700830FCF7B6FB0028F6D0B2204000241800 +S113648069462000FEF736FB00212000FEF737FDA9 +S113649000200AB010BD7CB506000D00734B1E70C1 +S11364A05D70734C0094022201217248FEF7F8FBE0 +S11364B0207800026178084380B276BD10B56D4C37 +S11364C002212000FEF77AFB012803D102212000DB +S11364D0FEF7ACFC10BDF0B595B0674C0322052166 +S11364E02000FFF71CFF01256846C57105200E90AA +S11364F021680D910D990E9A92008958402291437A +S11365006A46D279920140231A400A43149214999C +S11365100D9A0E9B9B00D15069468D710C9020689A +S11365200B900B980C99890040582027FF43384062 +S11365302026694689794901314001431391139812 +S11365400B990C9A92008850032202212000FFF735 +S1136550E6FE6846457102200A902168099109996E +S11365600A9A92008958402291436A4652799201CC +S113657040231A400A431292129B09990A9A9200E4 +S11365808B5069460D710890206807900798089908 +S1136590890040583840694609794901314001432E +S11365A0119111980799089A9200885003220421A6 +S11365B02000FFF7B4FE6846C570042006902168E9 +S11365C005910599069A92008958402291436A469A +S11365D0D278920140231A400A431092109B0599E5 +S11365E0069A92008B5069468D700490206803903F +S11365F003980499890040583840694689784901CC +S1136600314001430F910F980399049A92008850E6 +S1136610032203212000FFF782FE68464570032011 +S113662002902168029A92008B58402293439C4620 +S11366306A465278920140231A4063461A43029BE9 +S11366409B00CA506B461D70236884001C59274068 +S11366506C462478640126403E4384001E5115B0E4 +S1136660F0BD000040420F001C310020685500209E +S11366707455002080320020EC3100201CB503202A +S113668000F00AF8040000222100C9B2032000F03F +S11366900BF80090009816BD10B5040000216006A8 +S11366A0400EFFF7F8FE10BDF8B505000C0017000A +S11366B02100C9B280202843C0B2FFF7ECFE0600D7 +S11366C0002F00D03E80684605702800C0B2FFF756 +S11366D0E3FF604069464870684684700098F2BDE4 +S11366E0FEB582B004000F000A9E2000C0B2FFF77E +S11366F0D3FF0500002E00D035802800B84369463A +S1136700097C6A46127B91400143684601706846E1 +S1136710017880202043C0B2FFF7BDFE68460471B3 +S11367206846007C6946097B884001A9887020007E +S1136730C0B2FFF7B1FF0100394001A8807848409A +S113674001AA5070019805B0F0BDF0B599B01527B5 +S11367503800002529006A4651710100C9B20909AF +S113676041400800C0B2800848400100C9B249084D +S1136770414068460171684600790100C907C90FA4 +S1136780012901DB952007002C000495200080B22C +S1136790C008694648732000400169460873280010 +S11367A06946C8722800694688720498C008694618 +S11367B04872049840016946087228006946C87105 +S11367C028006946887105A832495022FEF76AFC00 +S11367D005AE77706846407B292170546846007B7B +S11367E02B2170546846C07A2D2170546846807AF3 +S11367F02F2170546846407A312170546846007ADB +S1136800332170546846C0793521705468468079C4 +S113681037217054684640794B217054FFF716FEB7 +S1136820002809D0280069460870FF20694648708E +S11368306846857000982BE02C002000C0B2400010 +S1136840305C002806D12000C0B2400030184078E7 +S1136850002814D000222000C0B240003018417833 +S11368602000C0B24000305CFFF71EFF0090684675 +S11368704078002801D000980AE0641CDDE7280075 +S11368806946087028006946487068468570009813 +S113689019B0F0BD18C2000010B55B4C0320206194 +S11368A060615A48A0615A49E1618021C9002162AE +S11368B00021A1626162E162206656486066102090 +S11368C0A0662167E166616753A1E01D01F010F93C +S11368D05249200001F00CF92020A07110BDF1B53F +S11368E086B00C001500002001900698C768069831 +S11368F0006900900098874203D20098C01B401E94 +S113690005E006988068C01B00994018401E06994F +S11369108968C91B884202D306988068C01BA842B4 +S113692001D2060000E02E0006984068C0190390CA +S11369300596049403980290059A04990298FEF728 +S1136940CBFB0298019880190190A419AD1BBF19C3 +S113695006988068874201D1002007000698C76026 +S1136960002DC4D1019807B0F0BDF8B588B004007B +S11369700D001600E0680390A0680399401A029085 +S1136980029886420FD260680399401800900596D9 +S11369900495009F059A04993800FEF79DFB03981F +S11369A08019E06020E00298019060680399401823 +S11369B00090019807900695009F079A0699380061 +S11369C0FEF78AFB0298301A0190606800900198E3 +S11369D00590029828180490009F059A049938009D +S11369E0FEF77AFB0198E06009B0F0BD00B5010044 +S11369F00A69CB68934204D38868401EC01A801881 +S1136A0001E0D01A401E00BDB0500020E8C40000D0 +S1136A10585100205855002052545400F4C400002A +S1136A20F1B582B00F00150001972748029918228A +S1136A3051434018060018367069002803D0022814 +S1136A4021D010D326E03000FFF7D0FF009000984B +S1136A50A84201D2002405E02C002A00019930004C +S1136A60FFF783FF17E03000FFF7C0FF00900098A6 +S1136A70A84201D2009C00E02C00220001993000C1 +S1136A80FFF773FF07E02A0001993000FFF727FFA3 +S1136A90040000E000242000FEBDF1B50F00160044 +S1136AA0094D2878002801D1FFF7F6FEEFF3108492 +S1136AB0012080F31088320039000098FFF7B0FFFE +S1136AC084F31088F2BD0000B050002080B5FFF7B9 +S1136AD0E3FE01BD70B504000E00A56861682800DE +S1136AE0401C814207D3206846552800401CA06002 +S1136AF0E068401CE060A068616888420DD1A2682B +S1136B0021682069FFF7C9FFA168884203D00020EB +S1136B10C043E06001E00020A06070BDF7B584B020 +S1136B201F000C9D059802900124012602980699E5 +S1136B30884206D302980699FCF7D7F80290761C8F +S1136B40F4E7BE4200D23E000D98C0071BD4002DCE +S1136B5019D00D98800705D5002F03D13020694640 +S1136B60087002E0202069460870002D0BD0AE4268 +S1136B7009D26D1E684601780498FFF7ABFF0498AC +S1136B80C0680028F1D50498C06800283CD4022FBE +S1136B9001D37F1E08E005982100FCF7A6F80190B8 +S1136BA001980699884202D306984443EFE7059872 +S1136BB02100FCF79AF80190059801996143401A65 +S1136BC0059012480199415C0498FFF783FF0498EB +S1136BD0C068002806D420000699FCF786F8040053 +S1136BE0002CE4D10D98C0070ED5002D0CD0002D3B +S1136BF00AD0AE4208D26D1E20210498FFF76AFF26 +S1136C000498C0680028F2D507B0F0BDD8C40000CD +S1136C10FEB582B007000A9C0298002802D50298AB +S1136C20454200E0029D01260398854206DB2800C8 +S1136C300399FCF757F80500761CF5E7049886429B +S1136C4001D204980600002C06D00298002802D431 +S1136C500B98400700D5641E0B98800702D5049852 +S1136C60002810D00B98C0070DD4002C0BD0002C9A +S1136C7009D0A64207D2641E20213800FFF72AFF5C +S1136C80F8680028F3D5F868002836D4029800285C +S1136C9007D50298414202912D213800FFF71AFFCF +S1136CA006E00B98400703D52B213800FFF712FFAD +S1136CB0F868002821D40B988007800F022810D18F +S1136CC0049800280DD1002C0BD0002C09D0A6422A +S1136CD007D2641E30213800FFF7FCFEF868002854 +S1136CE0F3D5F868002808D40B9801900094049B0D +S1136CF0039A02993800FFF711FF05B0F0BDF5B50E +S1136D009BB00C000AA80590402006900020079034 +S1136D101B9809900020089020780700641C380014 +S1136D20C0B2002800D11BE13800C0B2252800D031 +S1136D300DE10020050001210291227817003A009C +S1136D40D2B2232A13D02B2A0CD02D2A02D0302AD7 +S1136D5003D011E00D43641C0FE02A000225154303 +S1136D60641C0AE02A0004251543641C05E02A007B +S1136D7008251543641C00E00290029A002ADCD125 +S1136D80039021780F003900C9B2302903DB3900A0 +S1136D90C9B23A2906DB049020780100C9B22E2931 +S1136DA020D109E0641C03990A2251433A00D2B26B +S1136DB0891830390391E4E7641C21780800010044 +S1136DC0C9B2302903DB0100C9B23A2900DB09E06A +S1136DD0641C04990A2251430200D2B28918303942 +S1136DE00491EAE727783800C0B26C2803D0380051 +S1136DF0C0B2682803D1641C20780700F3E7380088 +S1136E00C0B2252800D19BE058284ED063280AD070 +S1136E1064281CD070287BD073285DD075282DD0B1 +S1136E20782842D091E01C9800681C9908601C984E +S1136E30006800681C990968091D1C9A1160029079 +S1136E40029E3100C9B205A8FFF744FE7DE01C98FC +S1136E5000681C9908601C98006800681C990968FF +S1136E60091D1C9A11600290019503980090049BDF +S1136E700A22029905A8FFF7CBFE66E01C98006879 +S1136E801C9908601C98006800681C990968091D11 +S1136E901C9A11600290019503980090049B0A22A9 +S1136EA0029905A8FFF73AFE4FE01C9800681C9968 +S1136EB008601C98006800681C990968091D1C9AE0 +S1136EC011600290019503980090049B102202998E +S1136ED005A8FFF723FE38E01C9800681C99086099 +S1136EE01C98006806681C980068001D1C990860BE +S1136EF030780700761C3800C0B2002807D039006B +S1136F00C9B205A8FFF7E6FD08980028F0D51CE0F3 +S1136F101C9800681C9908601C98006800681C99FB +S1136F200968091D1C9A1160029000200190082034 +S1136F30009008231022029905A8FFF7EFFD04E052 +S1136F40252105A8FFF7C6FDFFE7641C04E039000E +S1136F50C9B205A8FFF7BEFD0898002800D4DBE6F7 +S1136F60089801280BDB0798002804D0079A0AA97F +S1136F701B98FFF792FD0898079940180890089805 +S1136F801DB0F0BD0CB438B505000C0004A8009089 +S1136F906A4621002800FFF7B2FE01B0029930BC16 +S1136FA003B00847F0B58BB004003548059006904F +S1136FB000200790089009900A90324D324F334ECA +S1136FC005A8039002960197314800902B00314A9E +S1136FD0314920000830FBF7DDFD2A002F4920004D +S1136FE0603000F0BFFD02206946087404A80390D5 +S1136FF02B48029001960095264B3A00294920001F +S11370008030FBF7EAFF284A28492000C830FFF700 +S113701003F9274A27492000D030FFF7FDF8264A14 +S113702026492000D830FFF7F7F8254A25492000E3 +S1137030E030FFF7F1F8244A24492000E830FFF754 +S1137040EBF80095124B320021492000F03000F09B +S1137050BFFE104B3A00104988204000201800F071 +S1137060C9FE1C49B22040002018FDF785FD1A49CD +S1137070C0204000201800F031F80BB0F0BD00BF74 +S113708000127A0000E0064000F8064000E80640DE +S113709000E4064000F0064000F007400000024013 +S11370A000F005400080034000500340000006400B +S11370B0405003400010064080500340002006402A +S11370C0C0500340003006400051034000400640D9 +S11370D000D0074000C0024000A007400160704794 +S11370E010B502680121126852090A401300DBB28C +S11370F0012B19D10D4B0468636003681B6880245D +S1137100A343046823600A4B0468A36003681B68F4 +S1137110DB0A0B40DBB2002BF8D103681B685B0A67 +S11371200B40DBB2002BF8D010BD000020C528D9DD +S1137130FFFF000038B505000C002100280000F016 +S113714024FC0548A8600548E8600F2068600448EE +S113715028610620A88231BDF8C0000040C30000A9 +S11371605C080020F3B581B01400C0252600F6B2F7 +S1137170281D0090029F320000993800FDF7ACFFF3 +S1137180F7BD43780B707047F3B581B01400C02588 +S11371902600F6B2280028300090029F32000099A1 +S11371A03800FDF799FFF7BDF5B583B00C00C02595 +S11371B00C2002902800183001902600029A0199B0 +S11371C03000FDF789FF082628000C3000902700C6 +S11371D00C37320000993800FDF77EFF2020E07262 +S11371E005B0F0BDF3B581B01400C0252600F6B299 +S11371F00095029F320000993800FDF76DFFF7BD3E +S113720030B500231C001500E4B2EDB2AC4205D247 +S113721020241D00EDB24C555B1CF3E730BD00008B +S113722008B4024B9C4608BC6047C0464D0200208F +S113723008B4024B9C4608BC6047C0464D0400207D +S113724038B50124724D0C21280000F0DBFD002824 +S113725013D10121280000F0D5FD01280AD1A3484B +S11372600168A34A914202D00020040007E00021F3 +S1137270016004E00020040001E00020040020007C +S1137280C0B232BD802000017047F0B50400200078 +S113729000252E00954209D2964E4F5D4740FFB21D +S11372A0BF00F659000A70406D1CF3E71E00F6B2E9 +S11372B0012E02D10026F643301AF0BDFEB5002798 +S11372C001970097FFF7B0F88B48FBF710FF852470 +S11372D024018A4D3A0021002800FDF70BFF80208D +S11372E040020568864806688648066086490D603F +S11372F00A6882F30988096881F3088880214902B1 +S1137300BE4A116000688047F7BD70B585252D0120 +S113731000247A4E220029003000FDF7EBFEFFF72F +S113732083F823213A4800F02DFE70BD80B500207B +S1137330009003230622C0210120FFF7D1F901BDEB +S1137340E0B56846762101706C4B3421595C41707C +S11373500222694658689B68984707BD80B567480C +S1137360417C002916D184210901415C012903D003 +S1137370B249415C01290AD10021A14A815001216D +S1137380AE4A8154022141744068417002E00420F5 +S113739000F082F901BDF8B5584C607C002802D099 +S11373A0607C012832D1E06900282FD0206AE1698D +S11373B088422BD200252E006769C048205C032830 +S11373C014D0FFF731F801216069FFF729FF0600A7 +S11373D03000C0B2002807D1E169491E8020C000F6 +S11373E03818FFF71DFF0600FFF710F83000C0B291 +S11373F0002805D102206074E561A561256205E0DD +S1137400E561A5612562032000F046F9F1BD0000A5 +S11374102C320020F8B59F480078012864D1374CFD +S1137420607C002802D0607C01285DD1B048205CDB +S1137430012859D1E06AA16A884255D20026370052 +S11374409E48205C03282BD0300069460870300029 +S113745069464870022069460870FEF7E5FF35006A +S1137460280069460978C0B2884217D28022D20027 +S11374702800C0B28002201801003531606AE36A36 +S1137480C0182B00DBB29B02C018FFF7D1FE070027 +S11374903800C0B2002801D16D1CE1E7FEF7B6FF49 +S11374A03800C0B2002813D1E06A802109014018D5 +S11374B0E062E06AA16A884205D330008D496054D5 +S11374C00220607401E001206074FFF739FF07E0D7 +S11374D0300088496054A662E662032000F0DCF8BC +S11374E03000834960542663F1BD0000F06300203E +S11374F055AAAA55049A00009C310020C0280020F7 +S1137500040001001431002010310020F8B5A34C10 +S1137510607C002802D0607C01286DD126001136E1 +S113752001253570654820180178012902D00178B9 +S1137530002957D18D4801F009F900284AD18C4817 +S113754001F004F9002845D1884800688949884237 +S113755007D03A482554022030700020B7496054BF +S11375604AE08F480768824800688E4940180090B6 +S11375700098A021890288420ED200988A49884244 +S11375800AD30123009A802149020020C043FFF757 +S11375907CFE8649605002E00020844960508348A4 +S11375A02058874207D025482554022030700020F7 +S11375B0A249605420E0A1482554204820180178AD +S11375C0002903D1052000F067F815E005700220BA +S11375D0307011E01948255402203070002097497A +S11375E0605409E00178022906D00078032803D109 +S11375F09248255402203070F1BD000008ED00E0EF +S11376004808000080B56548417C002902D0417CCF +S1137610012912D18A4941580A290CD30749415CEE +S1137620002908D19A490020FFF7ACFCFEF7FCFEC4 +S1137630FFF744FE01E00121417401BD430800004D +S11376407047FEB582B00600852000010190002538 +S11376500095524C2700009A01993800FDF74AFD25 +S11376602660029860600398A0600498E0604F4828 +S113767025503000FEF738FAFFF7E2FD012807D164 +S11376806F48255001204A496054022061684870BF +S113769005B0F0BDFD3000200021404A0B005374BA +S11376A010747C4BD15070477B48007C70477A48FB +S11376B0407C704779480078704700004408000017 +S11376C010B560493A4A8A181378002B07D18423ED +S11376D01B01C85400236F4C0B5101231370022269 +S11376E04A7410BD574A6E4BD0546E4BD1547047F8 +S11376F03E0800003D08000038B505000C00514864 +S11377008461456100210A00674BC254674A815471 +S1137710802149028D420CD1A02189028C4208D1DA +S11377200121634A81548169624A8918890AC161C5 +S113773017E0002D0AD1082C08D102215C4A81549B +S113774081695C4A8918890AC1610AE05A498D42F3 +S113775007D15A498C4204D20321554A815402214B +S1137760C1610120FFF798FF31BD0000C000010096 +S1137770F87F0300DDCCBBAA38B505000C00314806 +S113778001214A4A815400210A00474BC2544562F0 +S11377908462C1620220FFF77FFF31BDC028002050 +S11377A0FC7F03000000FFFF0140000038080000D8 +S11377B043080000F4B503000022140010000C007C +S11377C0A4B2A24208D21F4C256BAD18641935250A +S11377D09E5C6655521CF2E71A4C256B0E00B6B23D +S11377E0AD1925636D462D783426A555256B802665 +S11377F03601B54204D301252E002B4FE65528004F +S1137800C0B2F2BD00200F4902004A7404220A7477 +S113781002000A4BCA542A4A8850704780B5094866 +S1137820017C062909DA2749027C92008A58002A39 +S113783003D0007C80000858804701BD3C0800004C +S113784048080000C028002010B504001248017C3C +S1137850002902D0017C052906D10E4941180A6885 +S11378602300DBB2D2180A600D4941180A78012AB4 +S11378700CD100220A700B49405C012804D1FFF7A7 +S113788055FDFFF742FD01E0FFF73FFD10BD00008D +S113789090C4000048080000C0280020FC300020EC +S11378A041080000420800003E0800003D080000B6 +S11378B044080000FF030000F05B00200108000002 +S11378C038080000A00600200021016041600A0081 +S11378D00272417270470022026041600123037208 +S11378E042727047407A7047FEB505000E001400DE +S11378F0082100226F463800FDF7FCFB2000C0B2CF +S1137900782805D07448295A74482818FFF7E3FFEB +S11379107920285C002814D02000C0B211280FD090 +S11379202000C0B212280BD02000C0B2312807D0EA +S11379302000C0B27E2803D02000C0B27F2800D12E +S11379400AE068467F21017046708470032269460C +S113795028001830FDF70AFEF7BD10B50200002319 +S11379601800180080B25468A0420CD290681C0021 +S1137970A4B2E400005D0C00E4B2A04201D10120F5 +S113798002E05B1CEDE7002010BD70B505000C00A3 +S1137990210028001830FDF7E1FF0120687000265F +S11379A03000A8703000782168540020002188221B +S11379B01201AA1803C2083AA08D49496852E08D01 +S11379C048496852208E4449685289200001281889 +S11379D0FFF77AFF44482818FFF776FF3F48281836 +S11379E0FFF772FF310030004049884205D2310070 +S11379F02A187B23D154401CF6E770BDFEB5040061 +S1137A00002630006946C880300069460871370096 +S1137A10350020001830FDF7EDFF01A8801C009010 +S1137A20324B22007B322100793120001830FDF7DF +S1137A305FFF6946087169460420085600283CD156 +S1137A407B20205C07003900C9B22000FFF785FFC6 +S1137A5000282CD03500606885422ED2A068E90049 +S1137A60405C3900C9B288421FD1A068E9004018BF +S1137A708078002806D07C20205CC0B2C009782120 +S1137A80605402E030007821605428007A21605468 +S1137A906846C28821007B3120000400A368E80006 +S1137AA0181843682000984707E06D1CD3E711229B +S1137AB03900C9B22000FFF717FF08482018FFF764 +S1137AC011FF012806D101206070A6700348201818 +S1137AD0FFF7FAFEF7BD00008C080000A8080000BC +S1137AE0880800008A0800009C08000002080000C2 +S1137AF031B48B0707D00B780370002B20D0401CC7 +S1137B00491C8B07F7D1164CE501830722D104C920 +S1137B10131B93432B4205D104C004C9131B934385 +S1137B202B42F9D0FF231A42027009D0120A1A42DA +S1137B30427005D0120A1A42827001D0120AC27031 +S1137B4031BC70470270120A4270120A8270120A23 +S1137B50C270001D04C9131B93432B42F2D0E1E70A +S1137B6001010101F8B504000F00150027606560EC +S1137B700026A660E0208002E060802040052061AD +S1137B80802000026061200000F002F92076E661A6 +S1137B90207E002800D06661200000F001F8F1BDCD +S1137BA0F1B489B0012069460871099909680791FF +S1137BB0002106916A461279520002231A40069265 +S1137BC0069A079B1A606A46D070099A1268059152 +S1137BD06B46DB781B01102423400593059B13603F +S1137BE06B469870099B1B6804916C46A4786401E9 +S1137BF020252C400494049C1C606C466070099CF5 +S1137C00246803916D466D78AD0140263540039597 +S1137C10039D25606D462870099D2D6802916E466E +S1137C203678F60008273E400296029E2E60099E92 +S1137C30366808910100C9B28900042739403160CF +S1137C400AB0F0BC7047F0B50100002528000122FD +S1137C5013000C681E00F6B2F60180273E40266031 +S1137C600B681B68DB091340DBB2002BF8D00B68F0 +S1137C701B685B091340DBB2002B0CD10B681B683B +S1137C801B091340DBB2002B05D10B681B681340A2 +S1137C90DBB2002B00D01000C0B2F0BDFFB587B03E +S1137CA000242700250009A80078402801DB0120D2 +S1137CB007000A98002801D1012007003800C0B24B +S1137CC000284DD10798006801260068C1093000DA +S1137CD00840C0B2002802D10220070040E0079803 +S1137CE0FFF75EFF08206946C870200069464870A7 +S1137CF00798006805900294FF20049005996A464D +S1137D0052788918097F049A91436A46D378049A71 +S1137D101A400A430292029A05996B465B78C91885 +S1137D200A7709A909786A46917069460E7007991D +S1137D300E6801940390684600783018007F039918 +S1137D40884369468978039A0A400243019201985C +S1137D5069460978711808770798FFF774FF0700D8 +S1137D603800C0B200280FD12500082D0CD22800FD +S1137D70C01D0799096822000300DBB2CB181B7FE2 +S1137D800A9E73556D1CF0E73800C0B20BB0F0BD0D +S1137D907CB50500082200216846FDF779F9002624 +S1137DA03400FF20694608706B4600220021280039 +S1137DB0FFF774FF01000800C0B2002805D168462F +S1137DC00078800701D4012004002000C0B276BDF1 +S1137DD010B4019C016042608360C46010BC7047B1 +S1137DE000B5BFF34F8F054805490860BFF34F8FB7 +S1137DF000BFFDE701604260836070470400FA053C +S1137E000CED00E030B50200002318000C00E4B2D1 +S1137E100D2C01DBC0B2B4E00C00E4B2002C14D091 +S1137E20022C29D01CD3042C3ED031D3062C53D0A1 +S1137E3046D3082C68D05BD30A2C7DD070D30C2C8D +S1137E4000D191E000D283E09AE0156801242D6806 +S1137E502540EDB2012D01D1200000E018008FE093 +S1137E60156801242D686D082540EDB2012D01D15E +S1137E70200000E0180083E0156801242D68AD0897 +S1137E802540EDB2012D01D1200000E0180077E07B +S1137E90156801242D68ED082540EDB2012D01D1AE +S1137EA0200000E018006BE0156801242D682D09FE +S1137EB02540EDB2012D01D1200000E018005FE063 +S1137EC0156801242D686D092540EDB2012D01D1FD +S1137ED0200000E0180053E0156801242D68ED0926 +S1137EE02540EDB2012D01D1200000E0180047E04B +S1137EF0156801242D682D0A2540EDB2012D01D10C +S1137F00200000E018003BE0156801242D686D0A8C +S1137F102540EDB2012D01D1200000E018002FE032 +S1137F20156801242D68AD0A2540EDB2012D01D15B +S1137F30200000E0180023E0156801242D68ED0AF4 +S1137F402540EDB2012D01D1200000E0180017E01A +S1137F50156801242D682D0B2540EDB2012D01D1AA +S1137F60200000E018000BE0156801242D686D0B5B +S1137F702540EDB2012D01D1200000E01800FFE7FB +S1137F80C0B230BDF3B581B0304801998968802210 +S1137F9088506A46127A002A5AD0022A00D187E011 +S1137FA06ED3042A00D1B3E000D299E0062A00D1AE +S1137FB0DEE000D2C4E0082A00D109E100D2EFE0FB +S1137FC00A2A00D134E100D21AE10C2A00D15FE17F +S1137FD000D245E10E2A00D18AE100D270E1102AD4 +S1137FE000D1B5E100D29BE1122A00D1E0E100D238 +S1137FF0C6E1142A00D10BE200D2F1E1162A00D125 +S113800036E200D21CE2182A00D161E200D247E233 +S11380101A2A00D18CE200D272E21C2A00D1B7E203 +S113802000D29DE21E2A00D1EAE200D2CCE2202A4C +S113803000D11DE300D2FFE2222A00D150E300D296 +S113804032E3232A00D167E369E300BF5245535565 +S113805001200100019A9268546801239C430B009B +S1138060DBB20340234353600024019DAD686E6876 +S11380700127BE432700FFB23840304368604EE317 +S113808001200100019A9268946801239C430B002B +S1138090DBB20340234393600024019DAD68AE68C6 +S11380A00127BE432700FFB238403043A86036E3BF +S11380B001200100019A9268D46801239C430B00BB +S11380C0DBB203402343D3600024019DAD68EE6816 +S11380D00127BE432700FFB238403043E8601EE367 +S11380E001200100019A9268146901239C430B004A +S11380F0DBB20340234313610024019DAD682E6964 +S11381000127BE432700FFB238403043286106E30D +S113811001200100019A9268546901239C430B00D9 +S1138120DBB20340234353610024019DAD686E69B3 +S11381300127BE432700FFB2384030436861EEE2B6 +S113814001200100019A9268946901239C430B0069 +S1138150DBB20340234393610024019DAD68AE6903 +S11381600127BE432700FFB238403043A861D6E25E +S113817001200100019A9268D46901239C430B00F9 +S1138180DBB203402343D3610024019DAD68EE6953 +S11381900127BE432700FFB238403043E861BEE206 +S11381A001200100019A9268146A01239C430B0088 +S11381B0DBB20340234313620024019DAD682E6AA1 +S11381C00127BE432700FFB2384030432862A6E2AD +S11381D001200100019A9268D46A01239C430B0098 +S11381E0DBB203402343D3620024019DAD68EE6AF1 +S11381F00127BE432700FFB238403043E8628EE2D5 +S113820001200100019A5268146801239C430B0069 +S1138210DBB20340234313600024019D6D682E6884 +S11382200127BE432700FFB238403043286076E27E +S113823001200100019A5268546801239C430B00F9 +S1138240DBB20340234353600024019D6D686E68D4 +S11382500127BE432700FFB23840304368605EE226 +S113826001200100019A5268146901239C430B0008 +S1138270DBB20340234313610024019D6D682E6922 +S11382800127BE432700FFB238403043286146E24D +S113829001200100019A5268546901239C430B0098 +S11382A0DBB20340234353610024019D6D686E6972 +S11382B00127BE432700FFB23840304368612EE2F5 +S11382C001200100019A5268946901239C430B0028 +S11382D0DBB20340234393610024019D6D68AE69C2 +S11382E00127BE432700FFB238403043A86116E29D +S11382F001200100019A5268D46901239C430B00B8 +S1138300DBB203402343D3610024019D6D68EE6911 +S11383100127BE432700FFB238403043E861FEE145 +S113832001200100019A5268146A01239C430B0046 +S1138330DBB20340234313620024019D6D682E6A5F +S11383400127BE432700FFB2384030432862E6E1EC +S113835001200100019A5268946A01239C430B0096 +S1138360DBB20340234393620024019D6D68AE6A2F +S11383700127BE432700FFB238403043A862CEE154 +S113838001200100019A5268146B01239C430B00E5 +S1138390DBB20340234313630024019D6D682E6BFD +S11383A00127BE432700FFB2384030432863B6E1BB +S11383B001200100019A5268546B01239C430B0075 +S11383C0DBB20340234353630024019D6D686E6B4D +S11383D00127BE432700FFB23840304368639EE163 +S11383E001200100019A5268146C01239C430B0084 +S11383F0DBB20340234313640024019D6D682E6C9B +S11384000127BE432700FFB238403043286486E189 +S113841001200100019A5268546C01239C430B0013 +S1138420DBB20340234353640024019D6D686E6CEA +S11384300127BE432700FFB23840304368646EE131 +S113844001200100019A5268946C01239C430B00A3 +S1138450DBB20340234393640024019D6D68AE6C3A +S11384600127BE432700FFB238403043A86456E1D9 +S113847001200100019A5268146D01239C430B00F2 +S1138480DBB20340234313650024019D6D682E6D08 +S11384900127BE432700FFB23840304328653EE140 +S11384A001200100019A5268146E01239C430B00C1 +S11384B0DBB20340234313660024019D6D682E6ED6 +S11384C00127BE432700FFB238403043286626E127 +S11384D001200100019A5268546E01239C430B0051 +S11384E0DBB20340234353660024019D6D686E6E26 +S11384F00127BE432700FFB23840304368660EE1CF +S113850001200100019A5268946E01239C430B00E0 +S1138510DBB20340234393660024019D6D68AE6E75 +S11385200127BE432700FFB238403043A866F6E077 +S113853001200100019A5268D46E01239C430B0070 +S1138540DBB203402343D3660024019D6D68EE6EC5 +S11385500127BE432700FFB238403043E866DEE01F +S113856001200100019A5268146F01239C430B00FF +S1138570DBB20340234313670024019D6D682E6F13 +S11385800127BE432700FFB2384030432867C6E0C6 +S113859001200100019A52688023D45801239C438E +S11385A00B00DBB203402343802413510024019DBC +S11385B06D688026AE590127BE432700FFB23840BC +S11385C030438026A851AAE001200100019A526894 +S11385D08423D45801239C430B00DBB20340234380 +S11385E0842413510024019D6D688426AE5901270B +S11385F0BE432700FFB2384030438426A8518EE0A2 +S113860001200100019A52689023D45801239C430D +S11386100B00DBB203402343902413510024019D3B +S11386206D689026AE590127BE432700FFB238403B +S113863030439026A85172E001200100019A52684B +S11386409C23D45801239C430B00DBB203402343F7 +S11386509C2413510024019D6D689C26AE5901276A +S1138660BE432700FFB2384030439C26A85156E051 +S113867001200100019A52689423D45801239C4399 +S11386800B00DBB203402343942413510024019DC7 +S11386906D689426AE590127BE432700FFB23840C7 +S11386A030439426A8513AE001200100019A52680F +S11386B0C823D45801239C430B00DBB2034023435B +S11386C0C82413510024019D6D68C826AE590127A2 +S11386D0BE432700FFB238403043C826A8511EE0ED +S11386E001200100019A5268CC23D45801239C43F1 +S11386F00B00DBB203402343CC2413510024019D1F +S11387006D68CC26AE590127BE432700FFB238401E +S11387103043CC26A85102E0FFF762FBFFE70020BC +S11387200199896880228850F7BD000008B4024B83 +S11387309C4608BC6047C0460100002008B4024BB8 +S11387409C4608BC6047C046A7000020F0B595B021 +S11387500400002528006946C8736007400F0028FC +S113876001D00120CAE067480068029002980068BE +S113877001260068C0093040C0B2002801D1092098 +S1138780BCE00298FFF7D2FF68468673280069466A +S113879008710298006814900995FF2013901499A9 +S11387A06A4612798918097F139A91436A46927B23 +S11387B0139B13400B4309930999149A6B461B7935 +S11387C0D218117721006A4651736946CE70029916 +S11387D0096812910895119012996A46D2788918FD +S11387E0097F119A91436A46527B119B13400B43B4 +S11387F008930899129A6B46DB78D2181177210AEC +S11388006A46117302216A469170029909681091AF +S113881007950F9010996A4692788918097F0F9AE4 +S113882091436A46127B0F9B13400B4307930799AE +S1138830109A6B469B78D21811772100090C6A466E +S1138840D17103216A465170029909680E91069507 +S11388500D900E996A4652788918097F0D9A9143B2 +S11388606A46D2790D9B13400B43069306990E9AE0 +S11388706B465B78D2181177210E6A4691710421F8 +S11388806A461170029909680C9105950B900C9930 +S11388906A4612788918097F0B9A91436A4692793D +S11388A00B9B13400B43059305990C9A6B461B785D +S11388B0D218117729006A465171052702990E686A +S11388C004950A903800C0B23018007F0A99884392 +S11388D0694649790A9A0A40024304920498390085 +S11388E0C9B2711808770298FFF728FF0100080041 +S11388F0C0B2002801D10B2000E02800C0B215B09E +S1138900F0BD0000F05B0020F1B489B0012069469D +S11389100871099909680791002106916A4612793C +S1138920520002231A400692069A079B1A606A466E +S1138930D070099A126805916B46DB781B011024EC +S113894023400593059B13606B469870099B1B6835 +S113895004916C46A478640120252C400494049C62 +S11389601C606C466070099C246803916D466D78A8 +S1138970AD01402635400395039D25606D46287062 +S1138980099D2D6802916E463678F60008273E4010 +S11389900296029E2E60099E366808910100C9B2B3 +S11389A089000427394031600AB0F0BC7047F0B543 +S11389B0010000252800012213000C681E00F6B2F5 +S11389C0F60180273E4026600B681B68DB091340D4 +S11389D0DBB2002BF8D00B681B685B091340DBB2D9 +S11389E0002B0CD10B681B681B091340DBB2002B56 +S11389F005D10B681B681A40D2B2002A01D00722A5 +S1138A001000C0B2F0BDF2B584B004000025280007 +S1138A106946887028006946487020680126006805 +S1138A20C10A30000840C0B200280ED16846007C5C +S1138A3001280AD160680068010D30000840C0B206 +S1138A40012802D130006946487020680068C109D5 +S1138A5030000840C0B2002801D109206DE0200098 +S1138A60FFF752FF0D20694608702900226801951E +S1138A70FF2002900B00DBB2D3181F7F029B9F43A1 +S1138A80BC466B461F78029B3B4067463B430193C1 +S1138A90019B0F00FFB2D7193B776B461B7C002B61 +S1138AA001D0370000E02F0031006A4611702168C0 +S1138AB00391019502900398694609784018007F54 +S1138AC0029988433900C9B2029A0A4002430192CA +S1138AD0019803996A461278891808772000FFF7ED +S1138AE066FF6946097C002909D021680968CA0A19 +S1138AF031001140C9B2002901D10521080069469D +S1138B00097C002909D1216809680A0B3100114048 +S1138B10C9B2002901D1052108000100C9B2002908 +S1138B200BD169464978002907D021683200D2B2B6 +S1138B30520380239B011A400A60C0B205B0F0BD05 +S1138B4010B50400824804602000FFF7DDFE002019 +S1138B50E06110BDF3B595B0002738006946087090 +S1138B607B48046815988005800D002803D00120F7 +S1138B7069460870E7E038003D001698854200D346 +S1138B80E1E0206801260068C10930000840C0B255 +S1138B90002803D1092069460870D4E02000FFF7BB +S1138BA0B3FE05216846017338006A469071206857 +S1138BB014900997FF201390149A6B469B79D2184E +S1138BC0137F139A93439C466A46137B139A1A4065 +S1138BD063461A430992099B9C46149B6A46927900 +S1138BE09A1863461377159A6B46DA7232006B460D +S1138BF05A712268129208971190129A6B465B7907 +S1138C00D218137F119A93439C466A46D37A119AD9 +S1138C101A4063461A430892089B9C46129B6A4674 +S1138C2052799A1863461377159AAB02D218120A2E +S1138C306B469A7202226B461A7122681092079749 +S1138C400F90109A6B461B79D218137F0F9A934397 +S1138C509C466A46937A0F9A1A4063461A430792CF +S1138C60079B9C46109B6A4612799A1863461377B1 +S1138C70159AAB02D218120C6B465A7203226B4639 +S1138C80DA7022680E9206970D900E9A6B46DB7886 +S1138C90D218137F0D9A93439C466A46537A0D9AD1 +S1138CA01A4063461A430692069B9C460E9B6A46EC +S1138CB0D2789A1863461377159AAB02D218120E1B +S1138CC06B461A7204226B469A7022680C920597BE +S1138CD00B900C9A6B469B78D218137F0B9A934394 +S1138CE09C466A46137A0B9A1A4063461A430592C5 +S1138CF0059B9C460C9B6A4692789A1863461377A8 +S1138D006A46D6716A465170266804970A90684686 +S1138D1040783018007F0A9988436946C9790A9ACD +S1138D200A40024304920498694649787118087706 +S1138D302000FFF73CFE694608706846007800286A +S1138D4001D16D1C19E76846007817B0F0BD00002A +S1138D50F05B0020F7B598B00025280069464874F8 +S1138D60874800680190072018990140002901D024 +S1138D70012501E11A990840002801D00325FBE0F0 +S1138D8028006946087002950B9501980068012730 +S1138D900068C10A38000840C0B2012802D1380076 +S1138DA06946087068460078002803D000210198BD +S1138DB0FFF729FE18988005800D0B900B98A021D1 +S1138DC0490544182E001A98864205D21998805DE8 +S1138DD02070641C761CF6E7019800680068C109DD +S1138DE038000840C0B2002801D10925BCE0019830 +S1138DF0FFF78AFD062069460874280069468872D0 +S1138E000198006816900A95FF20159016996A46F5 +S1138E10927A8918097F159A91436A46137C159AA8 +S1138E201A400A430A920A9A16996B469B7AC91801 +S1138E300A7718996A46D17369464F72019909688D +S1138E4014910995139014996A46527A8918097FE6 +S1138E50139A91436A46D27B139B13400B430993A5 +S1138E600999149A6B465B7AD21811771899090AF2 +S1138E706A46917302216A46117201990968129136 +S1138E800895119012996A46127A8918097F119AE5 +S1138E9091436A46927B119B13400B4308930899B4 +S1138EA0129A6B461B7AD21811771899090C6A46E4 +S1138EB0517303216A46D17001990968109107958D +S1138EC00F9010996A46D2788918097F0F9A9143B6 +S1138ED06A46527B0F9B13400B4307930799109AE2 +S1138EE06B46DB78D21811771899090E6A4611730C +S1138EF004216A469170019909680E9106950D90B6 +S1138F000E996A4692788918097F0D9A91436A46A8 +S1138F10127B0D9B13400B43069306990E9A6B46E6 +S1138F209B78D21811771A99C908491E6A46D172DA +S1138F3005216A46517001990F6805950C906846A1 +S1138F4040783818007F0C9988436946C97A0C9A8E +S1138F500A400243059205986946497879180877CA +S1138F600198FFF724FD050068460078002803D027 +S1138F7001210198FFF747FD2800C0B21BB0F0BDE6 +S1138F80F05B002000220260416001230372427200 +S1138F90704770B504000E0015009E48215A9E4883 +S1138FA02018FFF7EFFF7820205C012806D02A0064 +S1138FB092B2310020001830FCF7D8FA70BDFEB52B +S1138FC005000E001400082100226F463800FCF74B +S1138FD091F82000C0B2782805D08E48295A8E48CE +S1138FE02818FFF7CFFF7920285C002814D0200030 +S1138FF0C0B211280FD02000C0B212280BD020001C +S1139000C0B2312807D02000C0B27E2803D020008F +S1139010C0B27F2800D10AE068467F210170467003 +S113902084700322694628001830FCF79FFAF7BDC4 +S113903030B5002003000421020013000C00DBB251 +S1139040E4B2A34208D2754B1400E4B214256C4375 +S11390501B191871521CF0E730BDFFB581B0070031 +S113906000252E002C0028006946087029002A00DB +S1139070002F02D10A98058032E03878C0B2000986 +S11390806B46187038780007000F6B46587028003C +S113909001006A461278C9B291420BD20100C9B2EA +S11390A0791849780322121AD200914031430E00F4 +S11390B0401CEDE7280069464978C0B288420BD2CB +S11390C02800C0B2381840790321491BC9008840E0 +S11390D0204304006D1CEDE721003000FEF70CFB7B +S11390E005B0F0BD7047FBB504001700089D2E883D +S11390F0FEF7DAFA012814D1FEF7D9FA0100C9B251 +S1139100022908D10121320092B2B954761C0021FF +S1139110424A11710DE00221320092B2B954761C18 +S113912007E00320310089B27854761C00203B49C3 +S113913008712E80F7BDF8B504000F0015001E005D +S1139140FEF760FBF1BD7047FBB504001700089DF6 +S11391502E88FEF7A9FA042822D1FEF7A8FA0128DE +S113916005D10220310089B27854761C18E0FEF74C +S11391709EFA022814D1FEF79DFA012808D1012095 +S1139180310089B27854761C00202549087007E024 +S11391900320310089B27854761C002020490870DD +S11391A02E80F7BDF8B504000F0015001E00FEF771 +S11391B029FBF1BD7047FBB504001700089D2E88FC +S11391C0FEF772FA042822D1FEF771FA012805D1BC +S11391D00220310089B27854761C18E0FEF767FA51 +S11391E0022814D1FEF766FA012808D101203100C3 +S11391F089B27854761C00200849087607E00320D9 +S1139200310089B27854761C0020044908762E80F7 +S1139210F7BD00008C080000A80800000C0800201E +S113922038080020704770477047F7B5FFB087B023 +S11392300026049630006946087330006946488168 +S11392403400300069460870042069464873802061 +S113925080000190320005AD01992800FBF74AFF18 +S113926030006946088188A8008886998968869AAA +S11392707A23D25CD2008918497889B2884205D20F +S1139280132231218698FFF79AFE2BE17F278798D6 +S11392904078384069460873879880780002879937 +S11392A0C97840186946C88188A80088001F6946A3 +S11392B0488168464089002802D08798001D0490A0 +S11392C0350028006946497BC0B2884234D28748B9 +S11392D02900C9B214225143415A6A46D2899142A3 +S11392E028D1869949782A00D2B214235A43821885 +S11392F09278914218D12900C9B2142251434118DD +S1139300C97800290FD02900C9B21422514340184A +S1139310C07886998978884205D03322312186988D +S1139320FFF74DFEDEE007E0222231218698FFF7A9 +S113933046FED7E06D1CC4E728006946497BC0B2ED +S1139340884205D3312231218698FFF738FEC9E0DF +S1139350802080000190009605AC009A01992000BD +S1139360FBF7C8FE05AC71202070879840786070C8 +S113937087988078A0708798C078E0700420694648 +S113938008816846007B012805D000D281E00328CB +S11393905BD02CD37DE055482900C9B21422514337 +S11393A040180079012808D12770312060702420EA +S11393B0A07003206946088118E04C4E02A8009072 +S11393C080239B0005AA68464189049884462F009F +S11393D0FFB214204743F01987686046B84701205C +S11393E02900C9B214225143711808715AE03F4848 +S11393F02900C9B2142251434018007900281BD017 +S113940002A8009080239B0005AA6846418904981D +S11394100190364884462F00FFB21420474360462B +S1139420C019C7680198B84730482900C9B2142246 +S113943051434018067107E02770312060702420E2 +S1139440A0700320694608812CE0284E2800C0B291 +S11394501421484330180079002811D002A8009044 +S113946080239B0005AA684641890498B4462F00CE +S1139470FFB2142677436646F6193669B04707E00B +S11394802770312060702420A07003206946088171 +S113949008E02770312060701220A0700320694614 +S11394A008811FE068460089042809DB20787128B8 +S11394B006D16846028905A98698FFF76AFD11E07E +S11394C068460089032808D120787F2805D1A2782E +S11394D031218698FFF773FD04E024223121869818 +S11394E0FFF76DFD7FB00AB0F0BD00000C0800204E +S11394F0002202604160012303724272704770B51A +S113950004000E0015009648215A96482018FFF7CB +S1139510EFFF7820205C012806D02A0092B23100A7 +S113952020001830FCF722F870BDFEB505000E00CF +S11395301400082100226F463800FBF7DBFD2000F1 +S1139540C0B2782805D08648295A86482818FFF7DB +S1139550CFFF7920285C002814D02000C0B2112845 +S11395600FD02000C0B212280BD02000C0B2312886 +S113957007D02000C0B27E2803D02000C0B27F28CC +S113958000D10AE068467F2101704670847003228E +S1139590694628001830FBF7E9FFF7BDFAB583B038 +S11395A00400150001A870490A68026088200001BF +S11395B0201803C8009001A8009901700099090AB5 +S11395C041700099090CC9B2427807235A4389189B +S11395D081700099090EC9B2027803235A4389188D +S11395E0C1706846007C042819D3042001000A9A3B +S11395F011806946097BA278914208D10290002625 +S11396002F00320002993800FBF774FD07E0029046 +S113961001AE2F00029A31003800FBF75DFD05B062 +S1139620F0BDFEB504002000C0B2012802D0092814 +S113963046D093E04D4D68460E782F7877400770FA +S11396404E786F78774047708E78AF787740877020 +S1139650CE78ED787540C57001ADC678F0273740F7 +S11396602F70C678B700BC263E404778BF07BF0FAF +S113967037436F7046783700FFB2BF08BC4607789F +S1139680C0263E4067463E43AE7006783601807879 +S11396900007000F3043E87028781E78B0420BD1E1 +S11396A068785E78B04207D1A8789E78B04203D13A +S11396B0E878DD78A84201D0002050E001204EE097 +S11396C02A4D68460E782F78774007704E786F7869 +S11396D0774047708E78AF7877408770CE78ED7892 +S11396E07540C57001AD4678B700BC468778F02652 +S11396F03E4067463E432E700678F6B2B6083B27D6 +S11397003740BC4647787E263E4067463E436E70EF +S1139710C6783700FFB23F09BC4607782C263E4086 +S113972067463E43AE7086783601C0787D27074091 +S11397303743EF7028781E78B0420BD168785E7892 +S1139740B04207D1A8789E78B04203D1E878DD789A +S1139750A84201D0002002E0012000E00020FEBD6C +S11397608C080000A8080000FCC4000000C500002C +S1139770F7B586B000206946887208210020009061 +S113978003AC009A2000FBF7B5FC00206946C880B2 +S11397900020694608810020694648716846008CAB +S11397A006998968069A7A23D25CD2008918497886 +S11397B089B2884205D2132227210698FFF7B5FE05 +S11397C014E106984078012805D122222721069821 +S11397D0FFF7ABFE0AE1079840784006400E694661 +S11397E0087103AF6720387068460079787068465E +S11397F00079C00700D47FE0002630007C4908705F +S113980034002000C0B2022837DA7A4D6846007965 +S11398102100C9B20901695C88422CD12000C0B280 +S11398200001281880782100C9B209016918497813 +S113983088421FD206988821090140180CC80838AC +S11398402000C0B200012818083003C8121A8B4146 +S1139850694800218B4208DC01DB824205D23622B2 +S113986027210698FFF761FEC0E02000C0B2000186 +S11398702818467001E0641CC3E72000C0B2022827 +S113988005DB312227210698FFF74FFEAEE00620C4 +S11398906946088101A8801C009068460389DBB2F0 +S11398A0BA1C684601790698FFF778FE6846C088B6 +S11398B000281BD06846C288921C92B203A906985D +S11398C0FFF71DFE68460079494908706846C0885C +S11398D04A4908806846C088009003A8851C484E01 +S11398E0009A29003000FBF7F7FB7FE031222721A3 +S11398F00698FFF71AFE79E03D4D6846007929780D +S1139900491C884205D0242227210698FFF70DFE22 +S11399106CE06846008C801E80B200900798831C1F +S11399203648028836492878FFF77BFE6946487135 +S113993068464079012822D1022203A90698FFF73C +S1139940DEFD00200100297069460979491E069A46 +S1139950917004002100C9B2022947DA25496A46F8 +S113996012792300DBB21B01CB5C9A4205D10200C1 +S11399702300DBB21B01C9184A70641CEAE73522D4 +S113998027210698FFF7D1FD00242000C0B2022849 +S11399902CDA184A28782100C9B20901515C88429E +S11399A022D12000C0B2000110184078401C2100D0 +S11399B0C9B20901511848702000C0B20001101842 +S11399C080782100C9B209015118497888420BD224 +S11399D0069888210901401803C82300DBB21B0143 +S11399E0D218083203C2083A641CCEE709B0F0BDAD +S11399F0D55500208006002010270000D0550020F7 +S1139A008055002000000000963007772C610EEE90 +S1139A10BA51099919C46D078FF46A7035A563E9C1 +S1139A20A395649E3288DB0EA4B8DC791EE9D5E0E8 +S1139A3088D9D2972B4CB609BD7CB17E072DB8E7E7 +S1139A40911DBF906410B71DF220B06A4871B9F33C +S1139A50DE41BE847DD4DA1AEBE4DD6D51B5D4F475 +S1139A60C785D38356986C13C0A86B647AF962FDDA +S1139A70ECC9658A4F5C0114D96C0663633D0FFA27 +S1139A80F50D088DC8206E3B5E10694CE44160D52D +S1139A90727167A2D1E4033C47D4044BFD850DD217 +S1139AA06BB50AA5FAA8B5356C98B242D6C9BBDB2A +S1139AB040F9BCACE36CD832755CDF45CF0DD6DC25 +S1139AC0593DD1ABAC30D9263A00DE518051D7C8CC +S1139AD01661D0BFB5F4B42123C4B3569995BACF57 +S1139AE00FA5BDB89EB802280888055FB2D90CC678 +S1139AF024E90BB1877C6F2F114C6858AB1D61C1F1 +S1139B003D2D66B69041DC760671DB01BC20D2980F +S1139B102A10D5EF8985B1711FB5B606A5E4BF9F9C +S1139B2033D4B8E8A2C9077834F9000F8EA809968F +S1139B3018980EE1BB0D6A7F2D3D6D08976C6491FA +S1139B40015C63E6F4516B6B62616C1CD830658513 +S1139B504E0062F2ED95066C7BA5011BC1F40882F0 +S1139B6057C40FF5C6D9B06550E9B712EAB8BE8B31 +S1139B707C88B9FCDF1DDD62492DDA15F37CD38CBA +S1139B80654CD4FB5861B24DCE51B53A7400BCA3B8 +S1139B90E230BBD441A5DF4AD795D83D6DC4D1A4EA +S1139BA0FBF4D6D36AE96943FCD96E34468867ADC1 +S1139BB0D0B860DA732D0444E51D03335F4C0AAA60 +S1139BC0C97C0DDD3C710550AA41022710100BBE63 +S1139BD086200CC925B56857B3856F2009D466B9AA +S1139BE09FE461CE0EF9DE5E98C9D9292298D0B0DF +S1139BF0B4A8D7C7173DB359810DB42E3B5CBDB78C +S1139C00AD6CBAC02083B8EDB6B3BF9A0CE2B6030C +S1139C109AD2B1743947D5EAAF77D29D1526DB04C1 +S1139C208316DC73120B63E3843B64943E6A6D0D0C +S1139C30A85A6A7A0BCF0EE49DFF099327AE000A57 +S1139C40B19E077D44930FF0D2A3088768F2011EEA +S1139C50FEC206695D5762F7CB67658071366C1981 +S1139C60E7066B6E761BD4FEE02BD3895A7ADA10A2 +S1139C70CC4ADD676FDFB9F9F9EFBE8E43BEB71783 +S1139C80D58EB060E8A3D6D67E93D1A1C4C2D8380D +S1139C9052F2DF4FF167BBD16757BCA6DD06B53F73 +S1139CA04B36B248DA2B0DD84C1B0AAFF64A0336B2 +S1139CB0607A0441C3EF60DF55DF67A8EF8E6E3131 +S1139CC079BE69468CB361CB1A8366BCA0D26F257A +S1139CD036E2685295770CCC03470BBBB9160222C7 +S1139CE02F260555BE3BBAC5280BBDB2925AB42BDC +S1139CF0046AB35CA7FFD7C231CFD0B58B9ED92CF1 +S1139D001DAEDE5BB0C2649B26F263EC9CA36A7555 +S1139D100A936D02A906099C3F360EEB856707720C +S1139D2013570005824ABF95147AB8E2AE2BB17B73 +S1139D30381BB60C9B8ED2920DBED5E5B7EFDC7CFA +S1139D4021DFDB0BD4D2D38642E2D4F1F8B3DD6851 +S1139D506E83DA1FCD16BE815B26B9F6E177B06F4C +S1139D607747B718E65A0888706A0FFFCA3B066639 +S1139D705C0B0111FF9E658F69AE62F8D3FF6B61C6 +S1139D8045CF6C1678E20AA0EED20DD75483044E68 +S1139D90C2B30339612667A7F71660D04D476949F6 +S1139DA0DB776E3E4A6AD1AEDC5AD6D9660BDF4009 +S1139DB0F03BD83753AEBCA9C59EBBDE7FCFB247BC +S1139DC0E9FFB5301CF2BDBD8AC2BACA3093B353A1 +S1139DD0A6A3B4240536D0BA9306D7CD2957DE54AA +S1139DE0BF67D9232E7A66B3B84A61C4021B685D83 +S1139DF0942B6F2A37BE0BB4A18E0CC31BDF055AFC +S1139E008DEF022DF0B590B0012001006A469170EB +S1139E10DA4A04920499C96A0423DB4319406C4664 +S1139E20A478A40004252C400C430B940B99049CA7 +S1139E30E16201006C46617003920399C96A0124CE +S1139E40A1436C46647804400C430A940A99039C29 +S1139E50E16200210C006D462C700292029AD26AD3 +S1139E6013406A4612789200042422401A4309924D +S1139E70099A029BDA62CB4A0892CB4A0792089B62 +S1139E80079C23660300C94C0194019C24680F2598 +S1139E90AC431D00EDB22D072D0F25430695069CFE +S1139EA0019D2C60C24CC34D0595059D8026AC5187 +S1139EB0C14D2D682D0EAD07AD0FEDB2022D2AD187 +S1139EC00B006C462370BD4B5D68BD4C2C406D4649 +S1139ED02D782D02F02636012E4026430296029C50 +S1139EE05C600C00B44D0195019E3668B54F374057 +S1139EF0BC462600F6B23704C026B6023E4067468A +S1139F003E43019F3E602B001B681B0E9B079B0F6B +S1139F10DBB2002BF7D103000092009CE4680C250F +S1139F20AC431D00EDB2AD000C262E402643019635 +S1139F30019C009DEC6004001500EE680127BE43FF +S1139F402700FFB207403743EF6013001B6A9C08E9 +S1139F5003002340DBB2002BF7D00B006C46637187 +S1139F600892089B5B690124A3436C46647904400E +S1139F701C430F940F9B089C63610B006C46237178 +S1139F800792079B9B691024A3436C462479240100 +S1139F9010252C401C430E940E9B079CA3610B00C0 +S1139FA06C46E3700692069B5C69874B23406C46C3 +S1139FB0E4782402C025AD0025401D430D950D9B7A +S1139FC0069C636150236C46A3700592059B5B69F4 +S1139FD0FE24A3436C46A4786400FE2525401D435B +S1139FE00C950C9B059C63610B006C46637004929A +S1139FF0049B5C69754B23406C466478A4028025FD +S113A000ED002C401C430B940B9B049C63610423C4 +S113A0101C006D462C700392039C65696C4C2C40AB +S113A0206D462D78ED02E026B6012E4026430A96B1 +S113A0300A9C039D6C6104000292029D6D690126D5 +S113A040B5432600F6B206402E430996099D029EAA +S113A0507561FA256D015F4E35605F4D29605F4E75 +S113A06005273760346880277F02BC42FAD3336007 +S113A070584B1960296013001C6A03002340DBB2AB +S113A080002BF8D002246B461C71554B0693069D99 +S113A090C826AE594B4D35406E4636793704C02636 +S113A0A0B6023E402E430896089D069EC827F551E9 +S113A0B009256E46F5700593059DC826AD59404E99 +S113A0C02E400296029D6E46F6783702F02636013F +S113A0D03E402E430296029D059EC827F551050079 +S113A0E06E46B5700493049BC8255B591025AB4399 +S113A0F06D46AD782D01102635401D430795079B0D +S113A100049DC826AB516B4658702C4D6B682C4887 +S113A11018406B465B781E02F0231B013340034357 +S113A1206B606846047024480390039C2668254CA1 +S113A13034406E4636783704C026B6023E40264385 +S113A140039C266003001B681B0E9B079B0FDBB25E +S113A150022BF7D10B00154C0094009C24680F25AA +S113A160AC431D00EDB22D072D0F25430295029C33 +S113A170009D2C600C000568114E01E000F00540C4 +S113A1802E402500EDB22F02F0252D013D40354330 +S113A19005600191019E1666064E8027F15110B0AC +S113A1A0F0BD00BF2020961900E0064000E4064000 +S113A1B05245535500F0064000E8064000000240B6 +S113A1C0FFF0FFFFFFFFFCFFFFFCFFFFFFFBFFFFB4 +S113A1D0FFC7FFFF14E000E018E000E010E000E03B +S113A1E000F80640002202604160012303724272BB +S113A1F0704770B504000E001500B848215AB848DD +S113A2002018FFF7EFFF7820205C012806D02A00F1 +S113A21092B2310020001830FBF7A8F970BDFEB5EA +S113A22005000E001400082100226F463800FAF7DA +S113A23061FF2000C0B2782805D0A848295AA84850 +S113A2402818FFF7CFFF7920285C002814D02000BD +S113A250C0B211280FD02000C0B212280BD02000A9 +S113A260C0B2312807D02000C0B27E2803D020001D +S113A270C0B27F2800D10AE068467F210170467091 +S113A28084700322694628001830FBF76FF9F7BD84 +S113A290F7B5FFB085B0050000206946488000206E +S113A2A06946C88000260020694688800024002072 +S113A2B069460870802189000020029004AF029A48 +S113A2C03800FAF717FF86A80088A9687A22AA5CE2 +S113A2D0D2008918497889B2884205D213222221F2 +S113A2E02800FFF79CFFF6E086A80088401EC00700 +S113A2F005D5132222212800FFF791FFEBE086A861 +S113A300008840086946488068464088002805D18E +S113A310132222212800FFF782FFDCE0622004A937 +S113A320320092B28854761C0127380086A9098825 +S113A33080B2884200D3BEE08598390089B2405C7F +S113A340000285993A0092B289184978084369460F +S113A350C880002001006A46117004002000A98A08 +S113A36080B2884200D3A0E02869210089B2142277 +S113A3704A43805A6946C988884200D093E0A87845 +S113A3802969220092B214235343C91809798842D7 +S113A39005D0332222212800FFF741FF9BE0300043 +S113A3A080B22969220092B214235343C9188989BF +S113A3B04018801C4B49884205DB142222212800C6 +S113A3C0FFF72DFF87E02869210089B214224A4350 +S113A3D080188078052809D068782969220092B20B +S113A3E014235343C918C978884205D22222222152 +S113A3F02800FFF714FF6EE02869210089B21422B7 +S113A4004A4380188289D2B22869210089B2142370 +S113A4104B43C0188168280005002B699C46230023 +S113A4209BB21420584363461818036928009847C0 +S113A43001206946087004A885993A0092B2895CA3 +S113A440320092B28154761C85993A0092B28918EE +S113A4504978320092B28154761C68468680286915 +S113A460210089B214224A43801880890390286904 +S113A470210089B214224A4380188068029004A8FB +S113A480694689884618039A02993000FAF724FE2F +S113A490684680882969220092B214235343C9185C +S113A4A08989461801E0641C58E76846007800284A +S113A4B001D0BF1C39E768460078002806D0320076 +S113A4C092B204A92800FFF794FE04E0312222216D +S113A4D02800FFF7A4FE7FB008B0F0BD8C08000090 +S113A4E0A80800000102000000220260416001236C +S113A4F003724272704770B504000E0015009D4847 +S113A500215A9D482018FFF7EFFF7820205C01288E +S113A51006D02A0092B2310020001830FBF726F84A +S113A52070BDFEB505000E001400082100226F4620 +S113A5303800FAF7DFFD2000C0B2782805D08D4836 +S113A540295A8D482818FFF7CFFF7920285C002866 +S113A55014D02000C0B211280FD02000C0B212289D +S113A5600BD02000C0B2312807D02000C0B27E2812 +S113A57003D02000C0B27F2800D10AE068467F21C2 +S113A5800170467084700322694628001830FAF777 +S113A590EDFFF7BD7047704770477047F4B5FFB0E3 +S113A5A085B005000E000027380069464880380051 +S113A5B06946087038006946087102206946487087 +S113A5C0802189003A0004AC2000FAF793FD84A8A6 +S113A5D00088A9687A22AA5CD2008918497889B2CD +S113A5E0884205D213222F212800FFF79AFFBDE0ED +S113A5F06878012805D122222F212800FFF791FF36 +S113A600B4E070780002B178401869464880F07868 +S113A610694608703C00200069464978C0B2884207 +S113A62023D256482100C9B214225143415A6A46E2 +S113A6305288914217D12100C9B2142251434118C2 +S113A640897800290ED02100C9B214225143401840 +S113A6508078A978884205D033222F212800FFF77B +S113A66060FF83E001E0641CD5E720006946497877 +S113A670C0B2884205D331222F212800FFF751FFB1 +S113A68074E004A86F21017071784170B178817011 +S113A690F178C17068460078002802D003281CD0E5 +S113A6A05FE036482100C9B2142251434118CF72E9 +S113A6B02100C9B2142251434118096900290BD061 +S113A6C02100C9B214225143401800698047042272 +S113A6D004A92800FFF70FFF48E0284F84A800884A +S113A6E02100C9B2142251437918097A091D8842FC +S113A6F005DA22222F212800FFF713FF36E001207C +S113A7002100C9B2142251437918C8722000C0B282 +S113A710142148433818007A0390301D0290200019 +S113A720C0B214214843381840680190039A029932 +S113A7300198FAF7D1FC01982000C0B214214843D3 +S113A7403818C06800280BD02000C0B21421484338 +S113A7503818C0688047042204A92800FFF7CBFEFC +S113A76004E031222F212800FFF7DBFE7FB006B082 +S113A770F0BD00008C080000A8080000E4070020D9 +S113A780002202604160012303724272704770B577 +S113A79004000E0015002548215A25482018FFF70B +S113A7A0EFFF7820205C012806D02A0092B2310005 +S113A7B020001830FAF7DAFE70BDFEB505000E0071 +S113A7C01400082100226F463800FAF793FC200099 +S113A7D0C0B2782805D01548295A15482818FFF71B +S113A7E0CFFF7920285C002814D02000C0B21128A3 +S113A7F00FD02000C0B212280BD02000C0B23128E4 +S113A80007D02000C0B27E2803D02000C0B27F2829 +S113A81000D10AE068467F210170467084700322EB +S113A820694628001830FAF7A1FEF7BD8C0800002D +S113A830A808000010B50024FCF724FD801C10BDFE +S113A84010B501000020030001221300DBB2052B28 +S113A8500CDA04239B1ADB000C00DC40002C03D030 +S113A86005239B1A180001E0521CEEE7C0B210BD8C +S113A870F7B586B00020050001006A461170040097 +S113A880070001006A465170029001006A46D170C7 +S113A890060006994978012905D122223421069817 +S113A8A0FFF78BFFA4E069460B8C06998A689446EF +S113A8B0069A7A21515CC90062465118497889B2D6 +S113A8C08B4205D2132234210698FFF776FF8FE0DE +S113A8D0079989780907090F6A46117007998978D9 +S113A8E0C9B209096A4691706946097800290BD0F2 +S113A8F069460978052907D269468978002903D071 +S113A90069468978052905D3312234210698FFF751 +S113A91054FF6DE001000A006B461B78D2B29A42E4 +S113A92008D22A02079B0D00EDB25B19DB78D5181B +S113A930491CF0E70700380069468978C0B28842AC +S113A9400BD2210207986A4612783B00DBB2D21878 +S113A9508018C0780C187F1CEDE7002C05D122224A +S113A96034210698FFF729FF42E000F083F828001D +S113A97000F08EF8200000F08EF8012000F091F82D +S113A980FFF758FF02900298FFF75AFF6946487094 +S113A99003A87421320092B28154761C6946497826 +S113A9A00901320092B28154761C69468E800126D8 +S113A9B0694649783200D2B291420FD302996A466D +S113A9C05278921BD200D1406A46928881546946DB +S113A9D08988491C6A469180761CE9E72100280091 +S113A9E0FCF7CAFE6846828803A90698FFF7CFFEE3 +S113A9F009B0F0BD0022026041600123037242727B +S113AA007047FEB505000E001400082100226F46B1 +S113AA103800FAF76FFB2000C0B2782805D06348ED +S113AA20295A63482818FFF7E5FF7920285C002895 +S113AA3014D02000C0B211280FD02000C0B21228B8 +S113AA400BD02000C0B2312807D02000C0B27E282D +S113AA5003D02000C0B27F2800D10AE068467F21DD +S113AA600170467084700322694628001830FAF792 +S113AA707DFDF7BD002001004E4A117001004E4AD1 +S113AA8011704E4908604E4908604E49086070478D +S113AA904B49086070474B49086070474948006853 +S113AAA070474949087070474748007870474348E1 +S113AAB000687047F6B583B005000A2100226C4691 +S113AAC02000FAF717FB6878012805D122223621E5 +S113AAD02800FFF796FF66E06846008AA9687A2294 +S113AAE0AA5CD2008918497889B2884205D2132217 +S113AAF036212800FFF785FF55E033480078012808 +S113AB0002D0022844D049E02A4C039840782070AF +S113AB10294E2078317888420BD020783178491C2E +S113AB20C9B2884205D0732236212800FFF769FF95 +S113AB3039E0224F2348006839686A46128A891826 +S113AB40891E884205D2712236212800FFF759FF59 +S113AB5029E020783178491CC9B2884217D122787B +S113AB606846018A891E89B20398801CFCF722FE7C +S113AB70012805D138686946098A4018801E386062 +S113AB8020783070684676210170217841700AE09F +S113AB90312236212800FFF734FF04E02422362135 +S113ABA02800FFF72EFF05B0F0BD00008C08000060 +S113ABB0A8080000D8550020D9550020945500203D +S113ABC08C55002090550020D755002091490870DD +S113ABD0704730B5010089B2142928DA00218E4A61 +S113ABE00B000400A4B20C2565435419237103001F +S113ABF09BB20C245C4313191B1D1C7810252543A0 +S113AC001D7003009BB20C245C4313191B1D1C789C +S113AC10402525431D7003009BB20C245C4313198B +S113AC20D98003009BB20C245C431219117230BD0D +S113AC3070B5010000231C001A0018001C00A4B207 +S113AC40142C10DA744C1D00ADB20C266E43A419FA +S113AC5024796406640E22001400E4B20C4200D08D +S113AC60401C5B1CEAE780B270BDF2B50100002411 +S113AC702500230020002500ADB2142D39DA664DDD +S113AC802600B6B20C277743EE19367933001E003E +S113AC90F6B216422BD06E4636880700BFB23F1D6F +S113ACA0BE4223DB2600B6B20C277743EE59360C9E +S113ACB00700BFB2CE55401C2600B6B20C2777431E +S113ACC0EE59360A0700BFB2CE55401C2600B6B274 +S113ACD00C277743ED590600B6B28D55401C5D062E +S113ACE06D0E0600B6B28D55401C00E001E0641CF8 +S113ACF0C1E780B2F2BDF0B50200002425002300B4 +S113AD0020002500ADB2142D33DA434D2600B6B22F +S113AD100C277743EE19367933000E00B6B20700DC +S113AD20BFB23F1DBE4224DB2600B6B20C277743D8 +S113AD30EE59360C0700BFB2D655401C2600B6B2F9 +S113AD400C277743EE59360A0700BFB2D655401C8C +S113AD502600B6B20C277743ED590600B6B29555D6 +S113AD60401C5D066D0E0600B6B29555401C641C71 +S113AD70C7E780B2F0BD38B504000020050021000B +S113AD80264A891A04D09D3918D02F3935D03FE08E +S113AD900500280080B214280FDA1F48290089B260 +S113ADA00C224A43805880214903884203D2280058 +S113ADB080B2FFF70EFF6D1CEBE729E005002800C9 +S113ADC080B2142818DA1448290089B20C224A43A4 +S113ADD081588022D20391420CD3290089B20C22DB +S113ADE04A43805880210904884203D2280080B253 +S113ADF0FFF7EFFE6D1CE2E70AE00500280080B2D1 +S113AE00142805DA280080B2FFF7E3FE6D1CF5E78D +S113AE1031BD0000D4550020F406002033FFFF00AC +S113AE200100050000000000000000000000000018 +S113AE300900050000000000000000000000000000 +S113AE405D730000977300001574000041760000E4 +S113AE500D750000057600000100000031070000B8 +S113AE60DF070000B1070000AC3200200002000040 +S113AE70AC3400202008000000000000F55D000054 +S113AE80AD5C00003200F4018813000001020304E9 +S113AE90050607081A6204005000000000000000C4 +S113AEA01B63040050000000000000001603F000C3 +S113AEB050000000000000001703F00050000000E4 +S113AEC0000000008873C000500000000000000073 +S113AED00100C10050000000000000000101C10099 +S113AEE050000000000000000121C10050000000DB +S113AEF0000000000127C100500000000000000015 +S113AF000128C10050000000000000000129C10018 +S113AF1050000000000000000131C100500000009A +S113AF20000000000041C1005000000000000000CB +S113AF300151C10050000000000000000063C10086 +S113AF4050000000000000000069C1005000000033 +S113AF50000000000181C10050000000000000005A +S113AF600136C20050000000000000000064C1006F +S113AF7050000000000000000067C1005000000005 +S113AF800000000092F0000088550020020000003C +S113AF9095A5000097A5000020F000008A55002028 +S113AFA00200000099A500009BA5000001FD020914 +S113AFB0000000005B900000E5900000E7900000B6 +S113AFC002FD020900000000A5910000B5910000F7 +S113AFD0B791000003FD0209000000003791000052 +S113AFE0479100004991000004FD0209000000009F +S113AFF025920000279200002992000086F10601A4 +S113B000000000009855002001000000837100003A +S113B01087F1060100000000995500200800000097 +S113B0208971000080F1060100000000A155002094 +S113B030080000006571000091F1060100000000A5 +S113B040A955002018000000A971000093F1060121 +S113B05000000000C155002004000000E57100005C +S113B06095F1060100000000C5550020080000000D +S113B07001720000002202604160012303724272E7 +S113B080704770B504000E0015007E48215A7E48B2 +S113B0902018FFF7EFFF7820205C012806D02A0053 +S113B0A092B2310020001830FAF760FA70BDFEB594 +S113B0B005000E001400082100226F463800FAF73C +S113B0C019F82000C0B2782805D06E48295A6E4875 +S113B0D02818FFF7CFFF7920285C002814D020001F +S113B0E0C0B211280FD02000C0B212280BD020000B +S113B0F0C0B2312807D02000C0B27E2803D020007F +S113B100C0B27F2800D10AE068467F2101704670F2 +S113B11084700322694628001830FAF727FAF7BD2D +S113B120F6B583B004000E00082100273A0001ADF3 +S113B1302800F9F7DFFF3800694648706846008A3E +S113B140A1687A22A25CD2008918497889B288421F +S113B15005D2132228212000FFF7A9FF8EE0607892 +S113B160012805D1222228212000FFF7A0FF85E035 +S113B17070784006400E69460870B57801A86821C9 +S113B180017069460978417068460078002805D046 +S113B190022838D01CD3032850D06AE02800C0B25B +S113B1A0012807D02800C0B2022803D02800C0B26A +S113B1B0032807D135480770022201A92000FFF7B0 +S113B1C060FF04E0312228212000FFF770FF55E0E2 +S113B1D02800C0B2012807D02800C0B2022803D03A +S113B1E02800C0B2032808D101202849087002228F +S113B1F001A92000FFF745FF04E0312228212000A7 +S113B200FFF755FF3AE02800C0B2012807D0280014 +S113B210C0B2022803D02800C0B2032808D10220FB +S113B2201A490870022201A92000FFF72AFF04E04E +S113B230312228212000FFF73AFF1FE02800C0B286 +S113B240012807D02800C0B2022803D02800C0B2C9 +S113B250032808D103200D490870022201A9200007 +S113B260FFF70FFF04E0312228212000FFF71FFF22 +S113B27004E0122228212000FFF719FF05B0F0BDD9 +S113B280000000008C080000A8080000D65500202B +S113B290002202604160012303724272704770B55C +S113B2A004000E0015002548215A25482018FFF7F0 +S113B2B0EFFF7820205C012806D02A0092B23100EA +S113B2C020001830FAF752F970BDFEB505000E00E3 +S113B2D01400082100226F463800F9F70BFF200004 +S113B2E0C0B2782805D01548295A15482818FFF700 +S113B2F0CFFF7920285C002814D02000C0B2112888 +S113B3000FD02000C0B212280BD02000C0B23128C8 +S113B31007D02000C0B27E2803D02000C0B27F280E +S113B32000D10AE068467F210170467084700322D0 +S113B330694628001830FAF719F9F7BD8C0800009F +S113B340A8080000F6B585B005000E000024200012 +S113B350694608802000694648800821220003AF1E +S113B3603800F9F7C7FE6846008BA9687A22AA5C00 +S113B370D2008918497889B2884205D213222E2135 +S113B3802800FFF7A2FF82E070780002B17808433A +S113B3906946088003A86E21017071784170B17804 +S113B3A081702000A98A80B288426BD2286921006A +S113B3B089B214224A43805A6946098888425FD177 +S113B3C02869210089B214224A4380180079002890 +S113B3D00FD0A8782969220092B214235343C918C4 +S113B3E00979884205D0332222212800FFF76DFF16 +S113B3F04DE06846008BC01E2969220092B21423D6 +S113B4005343C9188989884205D013222E21280064 +S113B410FFF75BFF3BE02869210089B214224A430D +S113B42080188078032809D068782969220092B2AC +S113B43014235343C918C978884205D222222E21E5 +S113B4402800FFF742FF22E02869210089B2142274 +S113B4504A43801880890290F01C019028692100D9 +S113B46089B214224A4380188768029A01993800E5 +S113B470F9F732FE032203A92800FFF710FF06E0C4 +S113B480641C8EE731222E212800FFF71EFF07B02F +S113B490F0BD000000220260416001230372427289 +S113B4A0704770B504000E0015002548215A254840 +S113B4B02018FFF7EFFF7820205C012806D02A002F +S113B4C092B2310020001830FAF750F870BDFEB582 +S113B4D005000E001400082100226F463800F9F719 +S113B4E009FE2000C0B2782805D01548295A15480D +S113B4F02818FFF7CFFF7920285C002814D02000FB +S113B500C0B211280FD02000C0B212280BD02000E6 +S113B510C0B2312807D02000C0B27E2803D020005A +S113B520C0B27F2800D10AE068467F2101704670CE +S113B53084700322694628001830FAF717F8F7BD1B +S113B5408C080000A8080000F6B5FFB082B0070020 +S113B5500022100069464870100069460870100007 +S113B5606946488015008021890001AC2000F9F764 +S113B570C1FD82A80088B9687A22BA5CD200891811 +S113B580497889B2884205D2132219213800FFF77D +S113B5909EFF75E07F268198407830406946487068 +S113B5A001AC592020706846407860706846407845 +S113B5B0012804D0022827D00A2844D05BE082A8BE +S113B5C00088032805D0132219213800FFF77FFFD4 +S113B5D056E0819880786946087068460078FFF7DD +S113B5E027FB69464880A6700120E07068464088C1 +S113B5F080B2000A2071684640886071062201A961 +S113B6003800FFF74EFF3BE082A80088032805D0EE +S113B610132219213800FFF75AFF31E0819880780E +S113B62069460870A67068460278FF21FE31E01C66 +S113B630FFF71BFB05002A00D21C92B201A93800B7 +S113B640FFF72FFF1CE082A80088022805D01322F0 +S113B65019213800FFF73BFF12E0FF21FE31E01C07 +S113B660FFF749FB05002A00D21C92B201A9380059 +S113B670FFF717FF04E0122219213800FFF727FF14 +S113B6807FB004B0F0BD00000022026041600123DD +S113B69003724272704770B504000E0015006348CF +S113B6A0215A63482018FFF7EFFF7820205C012817 +S113B6B006D02A0092B2310020001830F9F756FF64 +S113B6C070BDFEB505000E001400082100226F466F +S113B6D03800F9F70FFD2000C0B2782805D0534890 +S113B6E0295A53482818FFF7CFFF7920285C0028EF +S113B6F014D02000C0B211280FD02000C0B21228EC +S113B7000BD02000C0B2312807D02000C0B27E2860 +S113B71003D02000C0B27F2800D10AE068467F2110 +S113B7200170467084700322694628001830F9F7C6 +S113B7301DFFF7BDF2B582B00500170008210024F3 +S113B74022006E463000F9F7D5FC3800A9687A2249 +S113B750AA5CD2008918497880B289B2884205D09F +S113B760132210212800FFF7ACFF5EE00298407816 +S113B7704606760E68465021017046702D49695A76 +S113B78089B2090A81702B49695AC1702A49695AD8 +S113B79089B2090A01712849695A4171FDF748FCC7 +S113B7A03000C0B2012806D03AD303280BD018D3F6 +S113B7B0042827D034E0AC706E7006226946280055 +S113B7C0FFF769FF31E0AC706E700622694628000D +S113B7D0FFF761FF1548295A15482818FFF754FF49 +S113B7E023E0AC706E70062269462800FFF753FF11 +S113B7F00E48295A0E482818FFF746FF0120FBF788 +S113B8005FFF12E0AC706E70062269462800FFF7F5 +S113B81042FF0648295A06482818FFF735FF04E076 +S113B820122210212800FFF74CFFF7BD8C080000FE +S113B830A8080000880800008A080000210400000D +S113B8404D0400002D050000000000004F0500001D +S113B85045060000EF070000450800001509000038 +S113B8606B0900003D0A0000930A0000610B000010 +S113B870B70B0000810C0000D70C0000A10D0000E4 +S113B880F70D0000C50E00001F0F0000810F00001F +S113B890B90F0000E90F000023100000571000004A +S113B8A0F1100000AD110000031300006916000040 +S113B8B0000000007316000097160000C116000077 +S113B8C0E51600000F170000000000001B17000021 +S113B8D06F170000211800004B18000075180000B5 +S113B8E09F180000C9180000F31800001D1900007B +S113B8F047190000711900009B190000C5190000C8 +S113B900931A0000211C00008D1C0000911D0000F2 +S113B910011E0000E11E0000231F00006F1F000035 +S113B920B11F000001200000432000008F20000010 +S113B930D12000001D2100005F210000B121000082 +S113B940F1210000452200006B2200009522000036 +S113B950BB220000E52200000B2300003523000079 +S113B9605B23000085230000AB230000D5230000E7 +S113B970FB23000025240000B3240000CB25000095 +S113B980F12500001B2600007F2600002927000067 +S113B9900000000033270000000000003D270000E5 +S113B9A00000000047270000C5270000AF28000062 +S113B9B02D290000172A0000512A0000AD2A00009A +S113B9C0E72A00003F2B0000672B000000220260E2 +S113B9D04160012303724272704770B504000E0087 +S113B9E015002548215A25482018FFF7EFFF782035 +S113B9F0205C012806D02A0092B2310020001830C1 +S113BA00F9F7B4FD70BDFEB505000E001400082161 +S113BA1000226F463800F9F76DFB2000C0B2782889 +S113BA2005D01548295A15482818FFF7CFFF792063 +S113BA30285C002814D02000C0B211280FD02000A8 +S113BA40C0B212280BD02000C0B2312807D0200089 +S113BA50C0B27E2803D02000C0B27F2800D10AE003 +S113BA6068467F210170467084700322694628006D +S113BA701830F9F77BFDF7BD8C080000A80800001A +S113BA80F2B582B0040016000022150008216F46AA +S113BA903800F9F72FFB6078012805D122223721DD +S113BAA02000FFF7B0FF40E03000A1687A22A25CDA +S113BAB0D2008918497880B289B2884205D213220B +S113BAC037212000FFF79FFF2FE0772069462A00E7 +S113BAD092B288546D1C2F00FEF7E6FF012802D0B5 +S113BAE0022814D019E0FEF7E2FF0500FEF7D6FFA6 +S113BAF0854205D0132237212000FFF784FF11E08F +S113BB003A0092B269462000FFF767FF0AE031224B +S113BB1037212000FFF777FF04E02422372120009B +S113BB20FFF771FF0020FEF7BCFFF7BD00220260A3 +S113BB304160012303724272704770B504000E0025 +S113BB4015002548215A25482018FFF7EFFF7820D3 +S113BB50205C012806D02A0092B23100200018305F +S113BB60F9F704FD70BDFEB505000E0014000821B0 +S113BB7000226F463800F9F7BDFA2000C0B27828D9 +S113BB8005D01548295A15482818FFF7CFFF792002 +S113BB90285C002814D02000C0B211280FD0200047 +S113BBA0C0B212280BD02000C0B2312807D0200028 +S113BBB0C0B27E2803D02000C0B27F2800D10AE0A2 +S113BBC068467F210170467084700322694628000C +S113BBD01830F9F7CBFCF7BD8C080000A80800006A +S113BBE0FEB504000F0016000821002201AD280054 +S113BBF0F9F780FAFF253100A0687A22A25CD2000E +S113BC008018407889B280B2814205D01322112174 +S113BC102000FFF7A8FF37E078784006400E694619 +S113BC20087001A851210170694609784170857036 +S113BC3068460078012804D021D3032815D00AD3FC +S113BC401DE0032201A92000FFF777FF0121012055 +S113BC50FBF748FD18E0032201A92000FFF76DFF60 +S113BC6002210120FBF73EFD0EE0032201A9200082 +S113BC70FFF763FF03210120FBF734FD04E01222E8 +S113BC8011212000FFF76FFFF7BD000000220260C2 +S113BC904160012303724272704770B504000E00C4 +S113BCA015002548215A25482018FFF7EFFF782072 +S113BCB0205C012806D02A0092B2310020001830FE +S113BCC0F9F754FC70BDFEB505000E001400082100 +S113BCD000226F463800F9F70DFA2000C0B2782828 +S113BCE005D01548295A15482818FFF7CFFF7920A1 +S113BCF0285C002814D02000C0B211280FD02000E6 +S113BD00C0B212280BD02000C0B2312807D02000C6 +S113BD10C0B27E2803D02000C0B27F2800D10AE040 +S113BD2068467F21017046708470032269462800AA +S113BD301830F9F71BFCF7BD8C080000A8080000B8 +S113BD40FEB504000E001500082100226F463800DD +S113BD50F9F7D0F92800A1687A22A25CD2008918E8 +S113BD60497880B289B2884205D213228521200005 +S113BD70FFF7A9FF2DE06078012805D12222852153 +S113BD802000FFF7A0FF24E0707847067F0E684686 +S113BD90C521017047703800C0B2012802D00228C2 +S113BDA009D011E00120FEF711FF022269462000AC +S113BDB0FFF773FF0DE00020FEF708FF022269463B +S113BDC02000FFF76AFF04E0122285212000FFF71C +S113BDD07AFFF7BD002202604160012303724272C0 +S113BDE0704770B504000E0015004448215A4448B9 +S113BDF02018FFF7EFFF7820205C012806D02A00E6 +S113BE0092B2310020001830F9F7B0FB70BDFEB5D6 +S113BE1005000E001400082100226F463800F9F7CF +S113BE2069F92000C0B2782805D03448295A34482A +S113BE302818FFF7CFFF7920285C002814D02000B1 +S113BE40C0B211280FD02000C0B212280BD020009D +S113BE50C0B2312807D02000C0B27E2803D0200011 +S113BE60C0B27F2800D10AE068467F210170467085 +S113BE7084700322694628001830F9F777FBF7BD70 +S113BE80F7B504000D000022160008216F463800A3 +S113BE90F9F730F968460089A1687A22A25CD200D9 +S113BEA08918497889B2884205D0132214212000C8 +S113BEB0FFF7ADFF20E0687800043043A978090259 +S113BEC00143EE780E4354206946087030000D4952 +S113BED0401A03D09D3801D02F3808D13000FEF726 +S113BEE04AFF012269462000FFF77BFF04E031226C +S113BEF014212000FFF78BFFF7BD00008C08000021 +S113BF00A808000033FFFF00002202604160012303 +S113BF1003724272704770B504000E001500254884 +S113BF20215A25482018FFF7EFFF7820205C0128CC +S113BF3006D02A0092B2310020001830F9F716FB1F +S113BF4070BDFEB505000E001400082100226F46E6 +S113BF503800F9F7CFF82000C0B2782805D015488A +S113BF60295A15482818FFF7CFFF7920285C0028A4 +S113BF7014D02000C0B211280FD02000C0B2122863 +S113BF800BD02000C0B2312807D02000C0B27E28D8 +S113BF9003D02000C0B27F2800D10AE068467F2188 +S113BFA00170467084700322694628001830F9F73E +S113BFB0DDFAF7BD8C080000A8080000FEB50400F7 +S113BFC00E001500082100226F463800F9F792F898 +S113BFD02800A1687A22A25CD2008918497880B22C +S113BFE089B2884205D013223E212000FFF7A9FF21 +S113BFF015E0707847067F0E3800C0B2002809D1DA +S113C00068467E2101704770022269462000FFF7CE +S113C01082FF04E012223E212000FFF792FFF7BDC9 +S113C020F0B587B02548029025482649069126494F +S113C03001912649264A0592264A274B0493274B09 +S113C0400093274B274C0394069C844207D0047822 +S113C050029D2C70029C641C0294401CF4E7059C15 +S113C0608C4207D00C78019D2C70019C641C0194B7 +S113C070491CF4E7049C944203D000241470521C1D +S113C080F8E7039C9C4207D01C78009D2C705B1C35 +S113C090009C641C0094F4E70024134DAD08AC42EA +S113C0A007D2124DA600AD59114EA700F551641CDC +S113C0B0F3E70F4D0F4E356007B0F0BD800600204A +S113C0C020AE000074B000000000002008890000C9 +S113C0D0848F000000200020DA55002000000000BA +S113C0E0000000000000000000000000000000004C +S113C0F00000000008ED00E01002010035B7000068 +S113C10011020100E1BB0000270201007197000049 +S113C1102803010021B100003E020100BDBF000060 +S113C1208502010041BD00002203000091A200002D +S113C1302E04000045B300001404000081BE00007A +S113C1401903010049B500002F0300009DA500005C +S113C150310401002B9200003405000071A8000096 +S113C16036020000B5AA00003701000081BA0000C1 +S113C17072B6002100220023002400250026002797 +S113C180B846B946BA46BB46BC460A490A4A521A98 +S113C190013A05DD0020042308601944043AFBDA5F +S113C1A006488546064880470648804762B6F9F740 +S113C1B025FFFEE700000020EF5B0020F05B00207D +S113C1C0059E000021C000000000010031070000AE +S113C1D00001080001000000FFFFFFFF0100010053 +S113C1E0DF0700000001080001000000FFFFFFFF5F +S113C1F002000100B1070000000008000000000078 +S113C200FFFFFFFF030001003402000000000800EC +S113C21000000000FFFFFFFF0300011302401D01A7 +S113C2200B000600070008000C001C00180017048F +S113C2300E000F4004033D0121503E543F4C3C0589 +S113C24023002400250026002700280029002A00B6 +S113C2502C002D002E002F0030003100320033005E +S113C2602B0034000000000046697273742066726B +S113C270616D652073686F756C64206E6F742075D2 +S113C2807365206D756C7469706C65206672616D80 +S113C29065207472616E736D697373696F6E2E00BD +S113C2A04D756C74692D6672616D6520726573706D +S113C2B06F6E736520746F6F206C617267652066A2 +S113C2C06F7220726563656976696E672062756650 +S113C2D06665722E000000004D657373616765200A +S113C2E073697A6520746F6F206C617267652E20A4 +S113C2F05365742061206C61726765722073656E8A +S113C30064206275666665720A00000041626F729D +S113C310742070726576696F7573206D65737361CF +S113C32067652C207472616E736D697373696F6EC7 +S113C33020696E2070726F67726573732E0A000035 +S113C34000000000000000000000000000000000E9 +S113C35000000000000000000000000000000000D9 +S113C36000000000000000000000000000000000C9 +S113C37053696E676C652D6672616D65206C656EC0 +S113C38067746820746F6F20736D616C6C206F72BA +S113C39020746F6F206C617267652E00466972733A +S113C3A074206672616D652073686F756C642062B9 +S113C3B065203820627974657320696E206C656E1F +S113C3C06774682E00000000436F6E7365637574B4 +S113C3D0697665206672616D6520746F6F2073687D +S113C3E06F72742E00000000466C6F7720636F6ECE +S113C3F074726F6C206672616D6520746F6F207348 +S113C400686F72742E00000001000000020000003A +S113C41004000000080000001000000020000000DC +S113C420400000008000000000F00DF8002801D05A +S113C43000BF00BF00BF00BF002000BF00BFF9F76E +S113C440DDFD00F002F80120704780B500F002F82D +S113C45001BD00000746384600F002F8FBE7000083 +S113C46080B500BF00BF024A11001820ABBEFBE735 +S113C470260002000548014603B4684680F3098893 +S113C48000BF00BF00BF00BFFFF7CEFFA5EDF5FE64 +S113C4902D2D2D2D2D4A756D70546F4170702D2DDD +S113C4A02D2D2D0A000000002D2D2D2D2D494E542B +S113C4B04F20424F4F542D2D2D2D2D0A00000000EA +S113C4C025303464203A204D5F535F4354524C204E +S113C4D03D20307825780A00303132333435363710 +S113C4E038394142434445465465726D696E616C06 +S113C4F00000000053454747455200000102030471 +S107C5004D535751EB +S903C475C3 diff --git a/cva_bootloader_m0118/OUTPUT/RP-77B_BOOT_BL0101_ID732_7B2.srec b/cva_bootloader_m0118/OUTPUT/RP-77B_BOOT_BL0101_ID732_7B2.srec new file mode 100644 index 0000000..3178425 --- /dev/null +++ b/cva_bootloader_m0118/OUTPUT/RP-77B_BOOT_BL0101_ID732_7B2.srec @@ -0,0 +1,3092 @@ +S01C00006376615F626F6F746C6F616465725F6D303131382E73726563AE +S1130000F05B002085C000009B2D00000B40000029 +S113001000000000000000000000000000000000DC +S11300200000000000000000000000006741000024 +S1130030000000000000000067420000B35C000004 +S113004018C4000018C4000018C4000018C400003C +S113005018C4000018C4000018C4000018C400002C +S113006018C40000D55C000018C4000018C40000C7 +S113007018C4000018C4000018C4000018C400000C +S113008018C4000018C4000018C4000018C40000FC +S113009018C4000018C4000018C4000018C40000EC +S11300A0D163000018C4000018C4000018C4000084 +S11300B018C4000018C4000018C4000018C40000CC +S11300C048573031424C30313031000031353A3408 +S11300D0343A30310000000044656320313220326C +S11300E0303234000000000052502D3737420000F7 +S11300F000000000000000000000000000000000FC +S113040027C08FD2A0D34DDC000000000000FFFF06 +S1130410BFFFFFFFFFFFFFFFFE88E6BE30A25B8E3B +S113042000B5020093680120DB680340DBB2002BB7 +S11304300AD093681B6A9B081840C0B2002803D0F6 +S1130440D0690860012000E0002000BDF2B584B04E +S11304500200002001009468E66801239E43012302 +S11304600D00EDB21D403543E560049E3678002E44 +S113047051D0D169294CA14201D1010012E0D169C6 +S1130480274CA14201D219000CE0D169254CA142AC +S113049001D2022106E0D169234CA14201D20321F9 +S11304A000E004210C00E4B2042C01D1002033E06C +S11304B06C46617094680194019CE4680C25AC431B +S11304C06D466D78AD000C262E4026430396039CA2 +S11304D0019DEC606C4620709068C4681025AC43A4 +S11304E06D462D782D011026354025430295029C3A +S11304F0C4601C009568EE680127BE432700FFB264 +S11305001F403743EF609068006A84081800204059 +S1130510C0B20028F7D0012005B0F0BD00093D00AD +S113052001127A0001366E01015A620200B502001E +S11305309068006A43081800C007C00FC0B20028C2 +S113054003D090690860012000E0002000BDF2B5EE +S113055084B005000026A8680124416920000840F1 +S1130560C0B200286AD0A868016A20000840C0B25E +S1130570002863D0A8688069010920000840C0B23F +S1130580002802D0012806D00BE069462800FFF7B6 +S113059047FF060005E069462800FFF7C7FF06008D +S11305A0FFE73000C0B2002801D1002048E0270056 +S11305B0A8684069000A8007800FC0B2002805D0EF +S11305C0022808D004D3032808D00AE0270008E052 +S11305D00220070005E00420070002E008200700CD +S11305E0FFE7A868406940084006400EC0B20028F2 +S11305F002D18020029000E00290A8684069C00AFD +S11306004007400FC0B2002802D10820019000E04A +S11306100190A8684069810A20000840C0B2401CCB +S113062003900098029948430399484301997943F8 +S1130630490002F05AFB0499086026003000C0B259 +S113064005B0F0BDFCB502000020040095686E6999 +S113065001239E4301232700FFB21F403743019724 +S1130660019E6E611E006F463E704E78002E02D0D1 +S1130670012E0FD01DE004009568AF691026B74322 +S1130680BC462600F6B2360110273E4067463E437C +S1130690AE6111E01C009568AF691026B743BC46F3 +S11306A02600F6B2360110273E4067463E43AE614F +S11306B002E004006D462C706C462478002C01D1B5 +S11306C0002093E0CC68012C01D104000FE0CC6839 +S11306D0022C01D11C000AE0CC68042C01D10224B4 +S11306E005E0CC68082C01D1032400E0FF24250098 +S11306F0EDB2FF2D01D1002078E06D466C70956855 +S11307006E69834F3740BC466E4676783702C02602 +S1130710B6003E4067463E436E614F88002F1CD0B2 +S11307204D88812D19DA4D88802D01D1050000E016 +S11307304D8896680196019E7769FE26B743BC46AC +S11307402E00F6B27700FE263E4067463E43019FE8 +S11307507E610F69002F02D11AE0002046E00D6986 +S1130760092D15D20D69082D00D0086995686E69A8 +S1130770B04F3740BC460600F6B2F702E026B60199 +S11307803E4067463E436E618F68012F02D104E00C +S113079000202BE08868022813D18868401E9568E1 +S11307A06E69A54F3740BC460600F6B2B6028027F4 +S11307B0FF003E4067463E436E610F78002F02D132 +S11307C012E0002012E0180095686E690127BE430C +S11307D00700FFB21F4037436F619068056A180035 +S11307E02840C0B20028F8D068460078F6BDF3B5BA +S11307F081B0070000242600009478690125C069AF +S1130800010928000840C0B2002818D06946380001 +S1130810FFF706FE06003000C0B200280FD078694A +S1130820C069000A4007400F85402900412905D2CC +S1130830009802F05AFA0299086000E0260030009D +S1130840C0B2FEBDFEB5020000206B4618706B46B8 +S113085058705369DE691024E443264010256F461E +S11308607F783F012F403743DF618E88012E01D10D +S113087003001EE08B88022B01D1012319E08B8831 +S1130880042B01D1022314E08B88082B01D103230C +S11308900FE08B88102B01D104230AE08B88202BD6 +S11308A001D1052305E08B88402B01D1062300E00C +S11308B007231E00F6B2072E17D06E4673705669D2 +S11308C00196019EF669A54F3740BC466E46767880 +S11308D03702E026F6003E4067463E430296029EFB +S11308E0019FFE6101266F463E700E78002E01D0F6 +S11308F0012600E006005769F86904403000C0B2E0 +S1130900000105402543FD6168460078FEBD0000F6 +S1130910FFFCFFFFF3B581B007000024260000941C +S1130920786901258069010928000840C0B20028BF +S113093018D069463800FFF773FD06003000C0B2D6 +S113094000280FD078698069000A4007400F85406D +S11309502900412905D2009802F0C7F902990860DC +S113096000E026003000C0B2FEBDFEB5020000204B +S11309706B4618706B46587053699E691024E443A3 +S1130980264010256F467F783F012F4037439F61F3 +S11309908E88012E01D103001EE08B88022B01D129 +S11309A0012319E08B88042B01D1022314E08B88E6 +S11309B0082B01D103230FE08B88102B01D10423D2 +S11309C00AE08B88202B01D1052305E08B88402B7E +S11309D001D1062300E007231E00F6B2072E17D02C +S11309E06E46737056690196019EB6695B4F374037 +S11309F0BC466E4676783702E026F6003E406746EF +S1130A003E430296029E019FBE6101266F463E70E0 +S1130A100E78002E01D0012600E006005769B8695F +S1130A2004403000C0B2000105402543BD61684662 +S1130A300078FEBDFFC7FFFFFFFBFFFFF3B581B0EA +S1130A400700002426000094786901254069010903 +S1130A5028000840C0B2002818D069463800FFF7C3 +S1130A6065FD06003000C0B200280FD078694069E7 +S1130A70000A4007400F85402900412905D200980B +S1130A8002F033F90299086000E026003000C0B299 +S1130A90FEBDFEB5020000206B4618706B46587010 +S1130AA053695E691024E443264010256F467F781D +S1130AB03F012F4037435F618E88012E01D103002F +S1130AC01EE08B88022B01D1012319E08B88042BB3 +S1130AD001D1022314E08B88082B01D103230FE0FA +S1130AE08B88102B01D104230AE08B88202B01D1A1 +S1130AF0052305E08B88402B01D1062300E0072362 +S1130B001E00F6B2072E17D06E4673705669019612 +S1130B10019E7669114F3740BC466E46767837029F +S1130B20E026F6003E4067463E430296029E019F41 +S1130B307E6101266F463E700E78002E01D001269C +S1130B4000E006005769786904403000C0B2000133 +S1130B50054025437D6168460078FEBDFFF8FFFF30 +S1130B60F3B581B0070000242600009478690125BC +S1130B700069010928000840C0B2002818D069465D +S1130B803800FFF7D3FC06003000C0B200280FD0B5 +S1130B9078690069000A4007400F8540290041290F +S1130BA005D2009802F0A1F80299086000E026003E +S1130BB03000C0B2FEBDFEB5020000206B461870C6 +S1130BC06B46587053691E691024E443264010256F +S1130BD06F467F783F012F4037431F618E88012E77 +S1130BE001D103001EE08B88022B01D1012319E0FF +S1130BF08B88042B01D1022314E08B88082B01D1AC +S1130C0003230FE08B88102B01D104230AE08B8887 +S1130C10202B01D1052305E08B88402B01D106232D +S1130C2000E007231E00F6B2072E17D06E4673703D +S1130C3056690196019E3669A14F3740BC466E46FF +S1130C4076783702E026F6003E4067463E43029639 +S1130C50029E019F3E6101266F463E700E78002E73 +S1130C6001D0012600E006005769386904403000CD +S1130C70C0B20001054025433D6168460078FEBDD1 +S1130C80F3B581B00700002426000094786901259B +S1130C90406A010928000840C0B2002818D06946FB +S1130CA03800FFF754FC06003000C0B200280FD013 +S1130CB07869406A000A4007400F854029004129AD +S1130CC005D2009802F011F80299086000E02600AD +S1130CD03000C0B2FEBDFEB5020000206B461870A5 +S1130CE06B46587053695E6A1024E443264010250D +S1130CF06F467F783F012F4037435F628E88012E15 +S1130D0001D103001EE08B88022B01D1012319E0DD +S1130D108B88042B01D1022314E08B88082B01D18A +S1130D2003230FE08B88102B01D104230AE08B8866 +S1130D30202B01D1052305E08B88402B01D106230C +S1130D4000E007231E00F6B2072E17D06E4673701C +S1130D5056690196019E766A594F3740BC466E46E5 +S1130D6076783702E026F6003E4067463E43029618 +S1130D70029E019F7E6201266F463E700E78002E11 +S1130D8001D0012600E006005769786A044030006B +S1130D90C0B20001054025437D6268460078FEBD6F +S1130DA0F3B581B00700002426000094786901257A +S1130DB0006A010928000840C0B2002818D069461A +S1130DC03800FFF7C4FB06003000C0B200280FD083 +S1130DD07869006A000A4007400F854029004129CC +S1130DE005D2009801F081FF0299086000E0260016 +S1130DF03000C0B2FEBDFEB5020000206B46187084 +S1130E006B46587053691E6A1024E443264010252B +S1130E106F467F783F012F4037431F628E88012E33 +S1130E2001D103001EE08B88022B01D1012319E0BC +S1130E308B88042B01D1022314E08B88082B01D169 +S1130E4003230FE08B88102B01D104230AE08B8845 +S1130E50202B01D1052305E08B88402B01D10623EB +S1130E6000E007231E00F6B2072E17D06E467370FB +S1130E7056690196019E366A114F3740BC466E464C +S1130E8076783702E026F6003E4067463E430296F7 +S1130E90029E019F3E6201266F463E700E78002E30 +S1130EA001D0012600E006005769386A044030008A +S1130EB0C0B20001054025433D6268460078FEBD8E +S1130EC0FFF8FFFF70B504000E000025606900689C +S1130ED0000E8007800FC0B2002805D002280FD072 +S1130EE008D3032812D017E031002000FFF71EFBBF +S1130EF0050011E031002000FFF792FA05000BE035 +S1130F0031002000FFF723FB050005E0310020003D +S1130F10FFF70CFB0500FFE72800C0B270BDF0B579 +S1130F2002004878012801D100230AE0487800280B +S1130F3001D1012305E04878022801D1022300E011 +S1130F40FF231800C0B2FF2801D1002017E01C00C5 +S1130F5050690668934D35402600F6B23704C02622 +S1130F60B6023E402E43066050690068000E8007BA +S1130F70800F1C00C0B2E4B2A042F5D10120F0BD44 +S1130F80F8B504000E00002569462000FFF79AFF1B +S1130F9007003800C0B2002801D100200BE0E0684F +S1130FA000680107090F0098C9B2491C01F09DFEB1 +S1130FB030603800C0B2F2BD30B502008888002825 +S1130FC010D0888811280DDA8C88641ED3681868BC +S1130FD00F25A8432500EDB22D072D0F05431D60F5 +S1130FE0012000E0002030BDF8B504000E0000250B +S1130FF069462000FFF7C4FF07003800C0B200288C +S113100001D100200CE060690068000A0107090FA3 +S11310100098C9B2491C01F068FE30603800C0B2C3 +S1131020F2BD70B502008888002812D08888112883 +S11310300FDA8C88641E53691D685B4828402500BC +S1131040EDB22E02F0252D01354005431D6001202F +S113105000E0002070BDF8B504000F0000252E004C +S11310602069C8214058000C8007800FC0B20028B6 +S113107005D002280FD008D3032812D017E0694600 +S11310802000FFF753FA060011E069462000FFF73D +S1131090C7F906000BE069462000FFF758FA06007E +S11310A005E069462000FFF741FA0600FFE730003B +S11310B0C0B2002801D1002019E02069C82140589D +S11310C001090800C007C00FC0B200280CD0206975 +S11310D0C8214058000A0107090F0098C9B2491CE9 +S11310E001F003FE386000E02E003000C0B2F2BD13 +S11310F0FCB502004878012801D100230AE04878B1 +S1131100002801D1012305E04878022801D10223F7 +S113111000E0FF231800C0B2FF2801D100203FE007 +S1131120888800283BD08888112838DA68460370FC +S11311301069C82405591B4C2C406D462D782D048C +S1131140C026B6022E4026430196019CC825445170 +S11311508C88641E1569C826AE59134F3740BC46A7 +S11311602600F6B23702F02636013E4067463E437B +S1131170C827EE510F78002F01D0012400E000248D +S11311801569C82028581026B0432600F6B2360147 +S113119010273E400643C8202E50012000E00020C6 +S11311A0F6BD0000FFFFFCFFFFF0FFFFF8B50400F1 +S11311B00F006069406801090800C007C00FC0B291 +S11311C0002801D100209BE0002005000090606908 +S11311D007264068000C3040C0B2002843D1606943 +S11311E04068C00C3040C0B200280BD0022815D093 +S11311F00ED304281ED017D3062827D020D30728BF +S11312002AD02FE069462000FFF725FF050066E09D +S113121069462000FFF704F9050060E069462000F4 +S1131220FFF784F905005AE069462000FFF78FF9BB +S1131230050054E069462000FFF7A2FE05004EE0D9 +S113124069462000FFF7D0FE050048E0694620000B +S1131250FFF7CDFA050042E069462000FFF7EEFBF8 +S113126005003CE03BE060694068000C3040C0B2DF +S113127001280AD033D3032813D00CD305281CD05B +S113128015D3072825D01ED329E069462000FFF78F +S1131290F7FC050023E06946200000F038FA050059 +S11312A01DE06946200000F00BFA050017E06946CE +S11312B0200000F0DEF9050011E06946200000F08E +S11312C067FD05000BE069462000FFF72FF90500D4 +S11312D005E069462000FFF729F90500FFE728002B +S11312E0C0B201280AD160694068000A0640310092 +S11312F00098C9B2491C01F0F8FC38602800C0B25B +S1131300F2BDF2B582B0010001206A4610700020DF +S113131002004B695C681025AC431500EDB22D0149 +S11313201026354025435D60029C6478002C40D033 +S1131330012C5DD0022C7AD0032C00D1D4E0052CF2 +S113134000D1F0E0072C00D10CE10A2C00D18DE093 +S11313500B2C00D1A9E00C2C0CD00F2C00D12BE1CC +S1131360102C00D11AE1112C00D109E11A2C00D162 +S113137030E13DE102004B695D68B94C2C40150039 +S1131380EDB22D04E026F6022E4026430196019C80 +S11313905C6004004D696E68B24F3740BC4626005D +S11313A0F6B2F704E026B6033E4067463E436E605D +S11313B021E102004B695D68A94C2C401500EDB297 +S11313C02D04E026F6022E4026430196019C5C6023 +S11313D001244D696E68A34F3740BC462600F6B21F +S11313E0F704E026B6033E4067463E436E6002E1E2 +S11313F002004B695D689A4C2C401500EDB22D0437 +S1131400E026F6022E4026430196019C5C600224ED +S11314104D696E68934F3740BC462600F6B2F70418 +S1131420E026B6033E4067463E436E60E3E00200BA +S11314304B695D688A4C2C401500EDB22D04E02602 +S1131440F6022E4026430196019C5C6003244D69FC +S11314506E68844F3740BC462600F6B2F704E02697 +S1131460B6033E4067463E436E60C4E002004B69EB +S11314705D687B4C2C401500EDB22D04E026F6028D +S11314802E4026430196019C5C6004244D696E68DD +S1131490744F3740BC462600F6B2F704E026B60384 +S11314A03E4067463E436E60A5E002004B695D68BE +S11314B06B4C2C401500EDB22D04E026F6022E40B4 +S11314C026430196019C5C6005244D696E68654F56 +S11314D03740BC462600F6B2F704E026B6033E4089 +S11314E067463E436E6086E002004B695D685C4C73 +S11314F02C401500EDB22D04E026F6022E402643C2 +S11315000196019C5C6006244D696E68554F374016 +S1131510BC462600F6B2F704E026B6033E40674612 +S11315203E436E6067E002004B695D684C4C2C40A2 +S11315301500EDB22D04E026F6022E402643019656 +S1131540019C5C6007244D696E68464F3740BC4679 +S11315502600F6B2F704E026B6033E4067463E4353 +S11315606E6048E001224B695D683D4C2C401500DB +S1131570EDB22E04E025ED02354025435D603AE0EE +S113158002224B695D68364C2C401500EDB22E04E6 +S1131590E025ED02354025435D602CE003224B69D4 +S11315A05D682F4C2C401500EDB22E04E025ED02B1 +S11315B0354025435D601EE004224B695D68284C7C +S11315C02C401500EDB22E04E025ED0235402543F4 +S11315D05D6010E005224B695D68214C2C401500CC +S11315E0EDB22E04E025ED02354025435D6002E0B6 +S11315F002006B461A706A461278002A1AD0029AC0 +S11316009288002A13D0029A9288092A0FDA029A41 +S11316109288521E4B695D687F4C2C401500EDB2D8 +S11316202E02E025ED00354025435D6002E0020016 +S11316306B461A70029A1278002A01D0012200E047 +S113164002004B6958681024A0431400E4B224013A +S113165010252C4004435C6068460078FEBD000001 +S1131660FFFFF8FFFFFFC7FF0200106A08600120B8 +S1131670704700B502005068806C03091800C00769 +S1131680C00FC0B2002804D0FA20800008600120F6 +S113169000E0002000BD70B502000878002801D0E9 +S11316A0012400E000245368986C1025A843250009 +S11316B0EDB22D011026354005439D64012070BD17 +S11316C000B502005068406C03091800C007C00F41 +S11316D0C0B2002804D0FA20C0010860012000E054 +S11316E0002000BD70B502000878002801D0012454 +S11316F000E000245368586C1025A8432500EDB27F +S11317002D011026354005435D64012070BD0200A3 +S1131710FA20400208600120704770B504000E00F2 +S1131720002561680120496809090140C9B20029FE +S113173001D100201AE061684968090C0140C9B26E +S1131740002905D131002000FFF71AFC05000BE049 +S113175061684968090C0840C0B2012804D131000D +S1131760200000F02FF905002800C0B270BDF2B5CA +S113177082B0010000206A46107005004C6866685B +S11317801022D243164010232F00FFB23F011F4006 +S113179037436760029E76780A2E11D16C466070DA +S11317A04C6866681D4D35406E4676783604802751 +S11317B07F023E402E43666001256F463D7018E06F +S11317C0029C6478182C14D1012425004E680196DB +S11317D0019E7668114F3740BC462E00F6B236049F +S11317E080277F023E4067463E43019F7E606F46EE +S11317F03C70029C2478002C01D0012400E00400F9 +S11318004D68686802402000C0B2000103401343E1 +S11318106B6068460078FEBDFFF8FFFFFFFFFEFF28 +S113182070B504000E000025606880680109080096 +S1131830C007C00FC0B2002804D031002000FFF759 +S1131840D3FB05002800C0B270BD70B50200087853 +S1131850002801D0012400E0002453689868102572 +S1131860A8432500EDB22D011026354005439D60A7 +S1131870012070BD70B504000E0000256068C068CA +S113188001090800C007C00FC0B2002804D031000D +S11318902000FFF7A9FB05002800C0B270BD70B599 +S11318A002000878002801D0012400E000245368D5 +S11318B0D8681025A8432500EDB22D011026354027 +S11318C00543DD60012070BD70B504000E000025E5 +S11318D06068006901090800C007C00FC0B2002891 +S11318E004D031002000FFF77FFB05002800C0B2C0 +S11318F070BD70B502000878002801D0012400E012 +S11319000024536818691025A8432500EDB22D0161 +S11319101026354005431D61012070BD70B50400DB +S11319200E0000256068406901090800C007C00F67 +S1131930C0B2002804D031002000FFF755FB050099 +S11319402800C0B270BD70B502000878002801D02C +S1131950012400E00024536858691025A843250099 +S1131960EDB22D011026354005435D61012070BDA7 +S113197070B504000E000025606880690109080044 +S1131980C007C00FC0B2002804D031002000FFF708 +S11319902BFB05002800C0B270BD70B502000878AA +S11319A0002801D0012400E0002453689869102520 +S11319B0A8432500EDB22D011026354005439D6155 +S11319C0012070BDF8B505000F0000200400009050 +S11319D06868C06901090800C007C00FC0B20028C8 +S11319E001D1002054E068680726C069000C30402B +S11319F0C0B200280BD0022815D00ED304281ED064 +S1131A0017D3062827D020D307282AD02FE06946E9 +S1131A102800FFF713F8040029E069462800FEF7C0 +S1131A20E6FE040023E069462800FFF729F90400D4 +S1131A301DE069462800FFF76AFE040017E06946C6 +S1131A402800FFF716FE040011E069462800FFF79E +S1131A5037FE04000BE069462800FFF705FE04008A +S1131A6005E069462800FEF7E9FF0400FFE72000CF +S1131A70C0B200280AD06868C069000A0640310074 +S1131A80C9B2491C009801F030F938602000C0B296 +S1131A90F2BDF3B50100012002006B461A7000226A +S1131AA014004D68EE6910239E4310232700FFB2F3 +S1131AB03F011F403743EF61019E7678032E1CD00F +S1131AC0052E0AD0072E28D00E2E66D00F2E44D015 +S1131AD0102E52D0112E30D06FE014004D68EE69F4 +S1131AE0AA4F3740BC462600F6B23704E026F60279 +S1131AF03E4067463E43EE6162E004004D68EE6995 +S1131B00A24F3740BC462600F6B23704E026F60260 +S1131B103E4067463E43EE6152E002244D68EE6962 +S1131B209A4F3740BC462600F6B23704E026F60248 +S1131B303E4067463E43EE6142E003244D68EE6951 +S1131B40924F3740BC462600F6B23704E026F60230 +S1131B503E4067463E43EE6132E004244D68EE6940 +S1131B608A4F3740BC462600F6B23704E026F60218 +S1131B703E4067463E43EE6122E005244D68EE692F +S1131B80824F3740BC462600F6B23704E026F60200 +S1131B903E4067463E43EE6112E006244D68EE691E +S1131BA07A4F3740BC462600F6B23704E026F602E8 +S1131BB03E4067463E43EE6102E014006D462C70E1 +S1131BC0019CA488002C15D0019CA488092C11DA4E +S1131BD0019CA488641E4D68EE69C04F3740BC4622 +S1131BE02600F6B23702E026F6003E4067463E4342 +S1131BF0EE6102E014006D462C70019C2478002CE8 +S1131C0001D00200FFE74C68E0691025A8431500E5 +S1131C10EDB22D012B400343E36168460078F6BD25 +S1131C2070B504000E00002561680120096A0909E5 +S1131C300140C9B2002901D1002026E06168096A87 +S1131C40090C8907890FC9B2002905D002290FD0D0 +S1131C5008D3032912D016E031002000FEF7EEFE6F +S1131C60050010E031002000FFF70AF805000AE043 +S1131C7031002000FEF7BBFD050004E0FA21490213 +S1131C8031600500FFE72800C0B270BDF2B582B034 +S1131C900100012002006B461A7000226B465A7044 +S1131CA04D682E6A1023DB431E4010246F467F7854 +S1131CB03F01274037432F62029E7678032E2AD0B5 +S1131CC0052E04D0072E13D0112E37D049E06D46CF +S1131CD06A704D682E6AC94F3740BC466E467678A6 +S1131CE03704C026B6023E4067463E432E623AE0C1 +S1131CF005004E680196019E366AC04F3740BC46C7 +S1131D002E00F6B23704C026B6023E4067463E4374 +S1131D10019F3E6227E002254E680196019E366AC5 +S1131D20B64F3740BC462E00F6B23704C026B60282 +S1131D303E4067463E43019F3E6214E003254E68E1 +S1131D400196019E366AAD4F3740BC462E00F6B26E +S1131D503704C026B6023E4067463E43019F3E62BA +S1131D6001E06D462A70029D2D78002D01D00200FD +S1131D70FFE74D68286A03401000C0B20001044028 +S1131D801C432C6268460078FEBD0000FFFFF8FF8C +S1131D9070B504000E0000256068806A010908001F +S1131DA0C007C00FC0B2002801D1002027E060683E +S1131DB0806A000C8007800FC0B2002805D002287A +S1131DC00FD008D3032812D017E031002000FFF70A +S1131DD077FC050011E031002000FFF745FC050009 +S1131DE00BE031002000FFF744FC050005E0310062 +S1131DF02000FFF73EFC0500FFE72800C0B270BDDD +S1131E00F2B582B0010000206A46107005004C68EB +S1131E10A66A1022D243164010232F00FFB23F01BE +S1131E201F403743A762029E7678102E11D16C466C +S1131E3060704C68A66A714D35406E4676783704FA +S1131E40C026B6023E402E43A66201256F463D7071 +S1131E5031E0029C64780E2C15D1012425004E68D3 +S1131E600196019EB66A654F3740BC462E00F6B215 +S1131E703704C026B6023E4067463E43019FBE6219 +S1131E806F463C7017E0029C64780F2C13D1022437 +S1131E904D68AE6A594F3740BC462600F6B2370447 +S1131EA0C026B6023E4067463E430196019EAE629E +S1131EB001266F463E70029C2478002C01D0012438 +S1131EC000E004004D68A86A02402000C0B200018E +S1131ED003401343AB6268460078FEBDFFF8FFFF82 +S1131EE070B504000E00002561680120096B090C1F +S1131EF00140C9B2002905D131002000FFF774F870 +S1131F0005000BE06168096B090C0840C0B20128A8 +S1131F1004D131002000FFF7FAFB05002800C0B20D +S1131F2070BDF0B50200002318004C780B2C0CD1C6 +S1131F305468266B9D4D35401E00F6B2370480264A +S1131F40760237402F4327630FE04B78112B0CD1D7 +S1131F5001235468266B954D35401E00F6B23704B4 +S1131F608026760237402F432763C0B2F0BD70B598 +S1131F7004000E00002561680120496B090C014032 +S1131F80C9B2002905D131002000FFF72DF8050062 +S1131F900BE06168496B090C0840C0B2012804D108 +S1131FA031002000FFF7B3FB05002800C0B270BD6C +S1131FB0F0B50200002318004C780B2C0CD15468A7 +S1131FC0666B7A4D35401E00F6B2370480267602E1 +S1131FD037402F4367630FE04B78112B0CD101235B +S1131FE05468666B714D35401E00F6B23704802686 +S1131FF0760237402F436763C0B2F0BDFFFFFCFF9A +S113200070B504000E00002561680120896B090C7D +S11320100140C9B2002905D131002000FEF7E4FFD8 +S113202005000BE06168896B090C0840C0B2012807 +S113203004D131002000FFF76AFB05002800C0B27C +S113204070BDF0B50200002318004C780B2C0CD1A5 +S11320505468A66B554D35401E00F6B237048026F1 +S1132060760237402F43A7630FE04B78112B0CD136 +S113207001235468A66B4D4D35401E00F6B237045B +S11320808026760237402F43A763C0B2F0BD70B5F7 +S113209004000E00002561680120C96B090C014091 +S11320A0C9B2002905D131002000FEF79DFF0500CB +S11320B00BE06168C96B090C0840C0B2012804D167 +S11320C031002000FFF723FB05002800C0B270BDDB +S11320D0F0B50200002318004C780B2C0CD1546886 +S11320E0E66B324D35401E00F6B237048026760288 +S11320F037402F43E7630FE04B78112B0CD10123BA +S11321005468E66B294D35401E00F6B2370480262C +S1132110760237402F43E763C0B2F0BD70B50400C8 +S11321200E00002561680120096C090C0140C9B248 +S1132130002905D131002000FEF756FF05000BE011 +S11321406168096C090C0840C0B2012804D131004F +S11321502000FFF7DCFA05002800C0B270BDF0B51E +S11321600200002318004C780B2C0CD15468266C08 +S11321700E4D35401E00F6B23704802676023740F5 +S11321802F4327640FE04B78112B0CD101235468A3 +S1132190266C064D35401E00F6B2370480267602C2 +S11321A037402F432764C0B2F0BD0000FFFFFEFF9D +S11321B070B504000E00002521680120C9680909D2 +S11321C00140C9B2002905D131002000FEF70CFFFF +S11321D005000AE02168C96809090140C9B201295A +S11321E003D1FA214902316005002800C0B270BD54 +S11321F0F0B50200002318004C780B2C0DD11468A4 +S1132200E5681026B5431E00F6B2360110273E409D +S11322102E43E6600125280012E04B78112B0FD1E4 +S113222001231C001568EF681026B743BC4626003E +S1132230F6B2360110273E4067463E43EE60180072 +S1132240C0B2F0BD38B505000C002869006801096A +S11322500800C007C00FC0B2002801D1002003E06D +S113226021002800FEF78CFE32BD70B5020008780C +S1132270002801D0012400E0002413691868102507 +S1132280A8432500EDB22D011026354005431D60FD +S1132290012070BD38B505000C00286940680109AB +S11322A00800C007C00FC0B2002801D1002003E01D +S11322B021002800FEF798FE32BD70B502000878B0 +S11322C0002801D0012400E0002413695868102577 +S11322D0A8432500EDB22D011026354005435D606D +S11322E0012070BD38B505000C002869006901099A +S11322F00800C007C00FC0B2002801D1002003E0CD +S113230021002800FEF770FE32BD70B50200087887 +S1132310002801D0012400E0002413691869102565 +S1132320A8432500EDB22D011026354005431D615B +S1132330012070BD38B505000C0028694069010909 +S11323400800C007C00FC0B2002801D1002003E07C +S113235021002800FEF748FE32BD70B5020008785F +S1132360002801D0012400E00024136958691025D5 +S1132370A8432500EDB22D011026354005435D61CB +S1132380012070BD38B505000C0028698069010979 +S11323900800C007C00FC0B2002801D1002003E02C +S11323A021002800FEF7ECFD32BD70B5020008786C +S11323B0002801D0012400E0002413699869102545 +S11323C0A8432500EDB22D011026354005439D613B +S11323D0012070BD38B505000C002869C0690109E9 +S11323E00800C007C00FC0B2002801D1002003E0DC +S11323F021002800FEF7F8FD32BD70B50200087810 +S1132400002801D0012400E000241369D8691025B4 +S1132410A8432500EDB22D01102635400543DD61AA +S1132420012070BDF2B582B0060030690124006A53 +S1132430010920000840C0B2002801D1002037E083 +S11324402000694608710027009730690325006A57 +S1132450000C2840C0B2002805D002280FD008D3B1 +S1132460032812D017E069463000FEF75FF8070032 +S113247011E069463000FDF7D3FF07000BE0694621 +S11324803000FEF764F8070005E069463000FEF707 +S11324904DF80700FFE73069006A000A0540AC40C8 +S11324A00098210000F021FC029908603800C0B2B5 +S11324B0FEBDFEB5020000206B4618706B465870D6 +S11324C013691E6A1024E443264010256F467F7862 +S11324D03F012F4037431F624E78012E01D1030084 +S11324E00AE04B78002B01D1012305E04B78022B45 +S11324F001D1022300E0FF231E00F6B2FF2E17D005 +S11325006E46737016690196019E366A844F374091 +S1132510BC466E4676783704C026B6023E4067460F +S11325203E430296029E019F3E6201266F463E7024 +S11325306E463678002E36D08E88012E01D10600E4 +S11325400FE08E88022E01D101260AE08E88042E27 +S113255001D1022605E08E88082E01D1032600E071 +S1132560FF266F467E706E467678FF2E19D06E4633 +S113257076786F46BE7016690296029E376A694E77 +S11325803E400196019FBC466E46B6783702C0268F +S1132590B6003E4067463E430196019E029F3E625E +S11325A001E06E4630700E78002E01D0012600E066 +S11325B006001769386A04403000C0B200010540C3 +S11325C025433D6268460078FEBD38B505000C0021 +S11325D02869806A01090800C007C00FC0B200283A +S11325E001D1002003E021002800FEF7FDFC32BDEC +S11325F070B502000878002801D0012400E000240E +S11326001369986A1025A8432500EDB22D01102600 +S1132610354005439D62012070BD70B505000C0076 +S113262028690126006B00093040C0B2002801D19E +S1132630002023E02869006B000C8007800FC0B2E3 +S1132640002805D002280DD007D303280FD013E0AB +S113265021002800FEF7F2F90FE021002800FEF720 +S1132660C6F80AE021002800FEF70AFB05E0210075 +S11326702800FEF7E3F900E00020C0B270BDFEB50B +S1132680020000206B4618706B46587013691E6B6D +S11326901024E443264010256F467F783F012F40E5 +S11326A037431F634E78052E01D103000AE04B78AF +S11326B0032B01D1012305E04B78072B01D1022321 +S11326C000E0FF231E00F6B2FF2E17D06E46737093 +S11326D016690196019E366B114F3740BC466E4613 +S11326E076783704C026B6023E4067463E430296DB +S11326F0029E019F3E6301266F463E700E78002EB7 +S113270001D0012600E006001769386B0440300050 +S1132710C0B20001054025433D6368460078FEBD14 +S1132720FFFFFCFFFFFCFFFF0200506A086001206E +S113273070470200906A0860012070470200D06A66 +S113274008600120704770B505000C000126286957 +S1132750A0214058000C4007400FC0B200280BD005 +S1132760022813D00DD304281AD014D3062821D05C +S11327701BD307281ED022E021002800FFF7D4FF36 +S11327801EE021002800FFF7D4FF19E021002800F3 +S1132790FFF7D4FF14E021002800FEF7E1F90FE071 +S11327A021002800FEF7B6F80AE021002800FEF711 +S11327B0F7FA05E021002800FEF7D2F900E0002036 +S11327C0C0B270BDF0B50200012318004C78042C8F +S11327D049D0062C37D0082C55D02A2C04D02B2CC9 +S11327E012D02C2C1FD05EE000231469A02566595A +S11327F0AD4D35401E00F6B23704E026F6023E40E9 +S11328002E43A025665150E01469A0256659A64DB3 +S113281035401E00F6B23704E026F6023E402E4351 +S1132820A025665141E002231469A02566599E4DF6 +S113283035401E00F6B23704E026F6023E402E4331 +S1132840A025665131E003231469A0256659964DED +S113285035401E00F6B23704E026F6023E402E4311 +S1132860A025665121E004231469A02566598E4DE4 +S113287035401E00F6B23704E026F6023E402E43F1 +S1132880A025665111E005231469A0256659864DDB +S113289035401E00F6B23704E026F6023E402E43D1 +S11328A0A025665101E000231800C0B2F0BD70B548 +S11328B005000C0001262869A4214058000C40079B +S11328C0400FC0B200280BD0022813D00DD3042827 +S11328D01AD014D3062821D01BD307281ED022E0F7 +S11328E021002800FFF720FF1EE021002800FFF749 +S11328F020FF19E021002800FFF720FF14E0210049 +S11329002800FEF72DF90FE021002800FEF702F859 +S11329100AE021002800FEF743FA05E02100280020 +S1132920FEF71EF900E00020C0B270BDF0B5020051 +S1132930012318004C78042C49D0062C37D0082CDD +S113294055D02A2C04D02B2C12D02C2C1FD05EE076 +S113295000231469A4256659534D35401E00F6B270 +S11329603704E026F6023E402E43A425665150E08B +S11329701469A42566594C4D35401E00F6B237043F +S1132980E026F6023E402E43A425665141E0022390 +S11329901469A4256659444D35401E00F6B2370427 +S11329A0E026F6023E402E43A425665131E003237F +S11329B01469A42566593C4D35401E00F6B237040F +S11329C0E026F6023E402E43A425665121E004236E +S11329D01469A4256659344D35401E00F6B23704F7 +S11329E0E026F6023E402E43A425665111E005235D +S11329F01469A42566592C4D35401E00F6B23704DF +S1132A00E026F6023E402E43A425665101E0002351 +S1132A101800C0B2F0BD70B505000C00012006001E +S1132A202969C0228958090C0840C0B2002802D084 +S1132A30012805D009E021002800FEF741FE05E049 +S1132A4021002800FEF710FE00E00020C0B270BD97 +S1132A50F0B50200012318004C780E2C11D0102C74 +S1132A601ED100231469C02566598E4D35401E00C1 +S1132A70F6B2360480277F023E402E43C0256651BD +S1132A8010E01469C0256659864D35401E00F6B223 +S1132A90360480277F023E402E43C025665101E064 +S1132AA000231800C0B2F0BDFFFFF8FF70B50500A9 +S1132AB00C00012006002969C4228958090C084029 +S1132AC0C0B2002802D0012805D009E02100280066 +S1132AD0FEF7F6FD05E021002800FEF7C5FD00E045 +S1132AE00020C0B270BDF0B50200012318004C787C +S1132AF00E2C11D0102C1ED100231469C425665944 +S1132B00684D35401E00F6B2360480277F023E40F1 +S1132B102E43C425665110E01469C4256659614DDD +S1132B2035401E00F6B2360480277F023E402E4315 +S1132B30C425665101E000231800C0B2F0BD38B5C9 +S1132B4005000C002869CC21405801090800C00781 +S1132B50C00FC0B2002801D1002003E021002800EA +S1132B60FEF70EFA32BD70B502000878002801D0D5 +S1132B70012300E000231469CC2020581025A84329 +S1132B801D00EDB22D01102635400543CC20255003 +S1132B90012070BDFEB50899099A0A9B0B9C009D03 +S1132BA00560019D4560029D8560C16002614361CD +S1132BB0256885616568C561A568056200252E00E4 +S1132BC02E00F6B2032E0BD22E00F6B2B600A619D2 +S1132BD0F6682F00FFB2BF00C7197E626D1CEFE7D5 +S1132BE0F7BDF8B506000C0017002000C0B232286B +S1132BF001DB002011E000252B4A2000C0B2C000F8 +S1132C001058002807D0390030002300DBB2DB0065 +S1132C10D258904705002800C0B2F2BDF4B588B080 +S1132C2004000F003800C0B2322801DB002037E076 +S1132C3000252E001C4A3800C0B2C000101840689D +S1132C4000282BD0194807906068069007980699C9 +S1132C508023C85016480590A068049005980499EC +S1132C600866144803902068029003980299802310 +S1132C70C850089920003B00DBB2DB00D218526830 +S1132C809047060001956068019980228150009563 +S1132C90A168009A0A6622688023D5503000C0B229 +S1132CA009B0F0BDFFFFFEFF50B700005245535579 +S1132CB0202096194B4D4352F446002804D449422F +S1132CC000F013F8404260474042002905D45FD029 +S1132CD000F00BF8404249426047494200F005F8D1 +S1132CE04942604703460B43E6D40022030A8B4261 +S1132CF00BD203098B4219D243088B422ED2411ABC +S1132D0000D20146524110467047FF2209023FD0CB +S1132D1012068B4205D3121209028B4201D31212FE +S1132D20090203098B4219D300E0090AC3098B4243 +S1132D3001D3CB01C01A524183098B4201D38B01C9 +S1132D40C01A524143098B4201D34B01C01A52416C +S1132D5003098B4201D30B01C01A5241C3088B42B1 +S1132D6001D3CB00C01A524183088B4201D38B009C +S1132D70C01A524143088B4201D34B00C01A52413E +S1132D80884200D3401A5241CFD2014610467047C0 +S1132D9008B500F001F808BD7047FEE700B5010072 +S1132DA000200A00D2B2002A05D0022A09D005D395 +S1132DB0032A09D00AE01022100007E018221000AC +S1132DC004E02822100001E048221000C0B200BD37 +S1132DD0F8B505000C002868060080360027684610 +S1132DE007703800C0B2FFF7D9FF0100C9B28908E3 +S1132DF00800C0B2220092B2504380003018F2BDE5 +S1132E0000B5010000200A00D2B2002A082A0ED917 +S1132E10093A0ED0521E0FD0521E10D0521E11D09D +S1132E20521E12D0521E13D0521E14D016E00800A7 +S1132E3014E00C22100011E0102210000EE0142205 +S1132E4010000BE01822100008E02022100005E01A +S1132E503022100002E040221000FFE7C0B200BDA3 +S1132E60F8B505000C0000206946487069460870F2 +S1132E70210089B22800FFF7ABFF06003068000C80 +S1132E8007073F0F3800C0B2FFF7BAFFC0B2F2BD68 +S1132E9070B500231400E4B2002C0CD00468C025E3 +S1132EA0ED03254305604468640F6407CD00ED0815 +S1132EB0254345600BE00468BC4D2540056044682B +S1132EC0BB4E26408C04BB4D25403543456070BD48 +S1132ED010B40268B84B1340036002680B00DBB205 +S1132EE01B04F02424031C401443046010BC7047EA +S1132EF000B502685200520802600268AF4B1340EA +S1132F0003600A00D2B2002A09D0026880231B069B +S1132F101343036002688023DB051343036000BD91 +S1132F2000B50A00D2B2002A06D10268A44B1340AD +S1132F300360026802600CE00A00D2B2012A08D1E0 +S1132F4002689F4B1340036002688023DB04134331 +S1132F50036000BD30B50268803200231D001C00F0 +S1132F60057EED01AC4205D2A500551929000B6080 +S1132F70641CF5E730BDF8B4924982688023D150CF +S1132F8001234468256D2026B5431E00F6B2760160 +S1132F9020273E402E430096009D25650025866827 +S1132FA08027F551F1BC7047F8B4864982688023C4 +S1132FB0D15001234468256D1026B5431E00F6B296 +S1132FC0360110273E402E430096009D25650025BE +S1132FD086688027F551F1BC7047F2B40599069CC8 +S1132FE0079D089E37780776009F076042608360DC +S1132FF0C16004614561F1BC704730B50022110025 +S11330008260026142618261C260C2614262826224 +S1133010C2620262012303701300C37013000371C0 +S11330200023DB4343638363C363036414004425C5 +S113303044551400452544551400C8254455082416 +S11330404625445514002100C9B2202906DA21007E +S1133050C9B2890041188B64641CF4E71100417003 +S11330601100817011003023C1541100C923C154CF +S11330701100CA23C1541100CB23C1541100D5231C +S1133080C1541100D423C1541100D623C1541100DA +S1133090D723C1541100CC23C154D021425030BD98 +S11330A0F0B50024210002681368444D1D400B0054 +S11330B0DBB29B078026F60533402B43136005687B +S11330C02E68414F3740BC462600F6B236078027AB +S11330D07F053E4067463E432E60016809680A0E3C +S11330E01100C907C90FC9B20029F6D1F0BDF8B55E +S11330F00400206801250068000D2840C0B20028A3 +S113310014D0002021680A68520052080300DBB280 +S1133110DB0713430B6020680068000D2840C0B231 +S1133120002803D02000FFF73FFFF4E728002168C0 +S11331300B68264A1A400300DBB25B068026B604FD +S1133140334013430B6020680068400E2840C0B22F +S11331500028F8D16846057020680168174A0A40BB +S11331606946097889078023DB051940114301600A +S11331702A0023681E68144F3740BC461600F6B276 +S1133180360780277F053E4067463E431E60206821 +S11331900068000E2840C0B20028F8D020680068FB +S11331A0C00E2840C0B20028F1D0F1BDFFFF9FFF40 +S11331B0FFFF03E00000FC1FFFFFF0FFFFFFFFBF66 +S11331C0FFFFFFF052455355FFFFFFEFFFFFFFFDE9 +S11331D0F8B594B007000C0016003100C9B289B2EA +S11331E03800FFF7F5FD0500227A61682800FFF733 +S11331F04FFEA17A2800FFF76BFEE17A2800FFF763 +S113320077FE617A2800FFF78BFE207B002805D02B +S11332106846067101A9380000F009FD607A0128AA +S11332200AD1206969460E7039686A46127892009C +S11332308A1888231B01D05015B0F0BDF0B58DB0AD +S113324005000E0000206946487000206946087099 +S11332502800FFF790FE012029680A6852005208EE +S11332600300DBB2DB0713430B6028680068010D21 +S11332700800C007C00FC0B20028F6D030786946F5 +S113328048712868029002984068CE490140684617 +S1133290407940038022920110400843059005982C +S11332A0029948602800FFF722FF0120694608714F +S11332B02F683968C448084069460979C9058022DD +S11332C012041140014304910498386001206946B6 +S11332D0C8702C68616BBD4808406946C978090705 +S11332E08022520511400143039103986063280032 +S11332F0FFF730FE3020305CFFF750FD69468870E0 +S113330068468078002809D0802080006946897842 +S1133310FFF7EBFC297E48436946487068464078CD +S11333206946087128680690069800687F218843DA +S1133330694609794906490E01430C910C9806998E +S1133340086001206946C870286805900598006DDA +S1133350400040086946C978C90701430B910B989E +S113336005990865CE48B16809186A46D18129686B +S1133370049104990A6DCB4911406A46D2895205D9 +S1133380C94B13400B430A930A99049A1165F168D7 +S113339009186A46918129680B6DC44A1A406B4624 +S11333A09B891B04F82464031C4014430994099A60 +S11333B00A65326912186B465A812A68146DBC4B2F +S11333C023406C466489A702FC2424023C401C432D +S11333D00894089B136573691B186C4623812B683A +S11333E01C6DB44F2740BC466C4624896701F82401 +S11333F0A4003C4067463C430794079C1C65B469A1 +S113340020186C46E0802868046D1F27BC436F4673 +S1133410FF88FF06FF0E27430765F478002C6ED063 +S113342001206946887128680268A34911406A46E8 +S11334309279520780239B051A400A430692069903 +S1133440016031796A46517129680B68CB4A1A4088 +S11334506B465B79DB0380242402234013430593EA +S1133460059A0A60326C04922A680392049A039BB8 +S11334709A644422B25C6B461A712A681468C04B81 +S113348023406C4624792702C024A4003C401C43FA +S11334900294029B13604523F35C6C46E3702B6833 +S11334A05C6BB84F2740BC466C46E4782706F02492 +S11334B024053C4067463C435C63C827F75D012F05 +S11334C03BD1002069460870684600784621715C4B +S11334D0884232D26846007880003018806C694691 +S11334E009782A680B00DBB29B00D31888242401D6 +S11334F018516B461B785B1C6C462370E4E7002074 +S113350029680B686C4A1A400300DBB25B0780240D +S1133510A405234013430193019A0A6000222B68F7 +S11335201C68964F2740BC461400E4B2E40380278D +S11335303F023C4067463C431C60706B0390286824 +S113354003990161B16B02912968029A4A61F26B95 +S113355001922A68019B9361C823F35C6C46E37073 +S11335602B681C68BC4F2740BC466C46E478240496 +S113357080277F023C4067463C431C60C927F75DB7 +S1133580002F25D0002029680B68B44A1A40030094 +S1133590DBB25B048024A402234013430193019A09 +S11335A00A6001222B685C68AD4F2740BC461400BA +S11335B0E4B2240380277F013C4067463C435C60BF +S11335C024E000BFFFDFFFFFFFFF7FFFFFFFFFEFF0 +S11335D0012029680B68A14A1A400300DBB25B048E +S11335E08024A402234013430193019A0A60002219 +S11335F02B685C689A4F2740BC461400E4B224034D +S113360080277F013C4067463C435C60D420305CAB +S1133610002853D0012001006A46917129680B6883 +S1133620904A1A406B469B799B058024E40323400F +S113363013430593059A0A6002006B465A712A687F +S11336401468894B23406C466479A4068027FF04E0 +S11336503C401C430494049B136003006C46237198 +S11336602B681C68814F2740BC466C462479A4040F +S11336708027FF023C4067463C430394039C1C6044 +S113368004006F46FC706C690294029CA46C0127D0 +S1133690BC436F46FF7838402043029CA06453E04B +S11336A0FFFF0000FFFF1F800000E07FFFFFE0FF3F +S11336B0FF03FFFF1FFCFFFFFFFFFFDF00200100F0 +S11336C06A46517129680B68664A1A406B465B79F1 +S11336D09B058024E403234013430593059A0A6061 +S11336E002006B461A712A6814685F4B23406C46CB +S11336F02479A4068027FF043C401C430494049BC3 +S1133700136003006C46E3702B681C68574F274016 +S1133710BC466C46E478A4048027FF023C4067461C +S11337203C430394039C1C606C690294029CA76C48 +S11337300124A743BC460700FFB23C00E407E40FA2 +S113374067463C43029FBC64D520305C69460871DF +S113375028680268424911406A461279120380239C +S11337605B011A400A43049204990160D621715CFA +S11337706A46D17029684B68004A05E0FF7FFFFF65 +S1133780FFFCFFFFFFFFFFF01A406B46DB78DB0313 +S113379080242402234013430393039A4A60D722CC +S11337A0B25C2B685C68324F2740BC461400E4B21C +S11337B0A4038027FF013C4067463C430294029CDB +S11337C05C6000273800CC21715CC0B288422DD2E5 +S11337D00020D02171583A00D2B214235A438C5A93 +S11337E0220092B2D02030583900C9B21423594370 +S11337F0435AD020305884463900C9B2142041437A +S1133800604640184088181882420DDA2200D2B26D +S1133810D02030583900C9B2142359434118280024 +S1133820FFF7D6FC641CDBE77F1CCBE7280000F025 +S113383082F92800FFF734FC002029680B680D4A40 +S11338401A400300DBB2DC0580231B041C40144334 +S11338500C600DB0F0BD0000FFFFFEFFFFFFFDFF99 +S1133860FFEFFFFFFFFFBFFFFFFFFFFBFFFFFBFFBC +S1133870FFBFFFFFFFFF7FFF38B504000D0029786D +S113388089B22000FFF7A4FA0168C02212050A4396 +S1133890026031BDF1B50C00217889B20098FFF7C0 +S11338A097FA05000835217889B20098FFF7D8FA0D +S11338B000210B000A001300DBB2834238D2032339 +S11338C01E00324209D129602B681600F6B2A619EF +S11338D0367A36061E432E6028E01600F6B21E40E5 +S11338E0012E08D12B681600F6B2A619367A3604D2 +S11338F01E432E601AE01600F6B21E40022E08D1B6 +S11339002B681600F6B2A619367A36021E432E60CC +S11339100CE01600F6B23340032B07D12B681600D7 +S1133920F6B2A619367A1E432E602D1D521CC2E72C +S1133930F1BDF8B506000C00217889B23000FFF71C +S113394047FA05002868000C0007000FFFF758FA33 +S1133950482160542868400D0100C907C90F684612 +S11339600170281D69460978002904D00168C9003E +S1133970C908616004E00168890C4905490D61606A +S1133980051D217889B23000FFF76AFA00210A0088 +S11339900A000300D2B2DBB29A422AD203221300F5 +S11339A0194206D12A68120E0B00DBB2E3181A7210 +S11339B01DE00B00DBB21340012B06D12A68120C68 +S11339C00B00DBB2E3181A7211E00B00DBB21A40F1 +S11339D0022A06D12A68120A0B00DBB2E3181A7213 +S11339E005E02A680B00DBB2E3181A722D1D491C8E +S11339F0CEE732689268F1BDF0B500252E000A7852 +S1133A00D206D20E0124230093400F78402F12DBFC +S1133A101C0002260568002E0AD0022E04D005D30D +S1133A20032E07D12C6705E06C6703E0EC6201E02C +S1133A302C63FFE725E00E78202E11DB1D000668BD +S1133A40002C0AD0022C04D005D3032C07D13567EF +S1133A5005E0756703E0F56201E03563FFE710E018 +S1133A601C000668002D0AD0022D04D005D3032DB6 +S1133A7007D1346705E0746703E0F46201E034635E +S1133A80FFE7F0BDF0B50300002215000878C40676 +S1133A90E40E01200600A6400F78402F16DB02201A +S1133AA01D6800280DD0022805D007D303280BD1A8 +S1133AB02F6F3A0008E06F6F3A0005E0EF6A3A00B2 +S1133AC002E02F6B3A00FFE732402EE00D78202D04 +S1133AD015DB1D6800280DD0022805D007D3032864 +S1133AE00BD12F6F3A0008E06F6F3A0005E0EF6AE0 +S1133AF03A0002E02F6B3A00FFE7324015E0100075 +S1133B001D6800280DD0022805D007D303280BD147 +S1133B102F6F3A0008E06F6F3A0005E0EF6A3A0051 +S1133B2002E02F6B3A00FFE73240002A01D0012067 +S1133B3000E00020F0BDF0B5017E032937D100215B +S1133B40C9430D0002270668002F0AD0022F04D0B3 +S1133B5005D3032F07D1356705E0756703E0F562E8 +S1133B6001E03563FFE70A0001230468002B0AD053 +S1133B70022B04D005D3032B07D1226705E062672B +S1133B8003E0E26201E02263FFE700260568002EFD +S1133B900AD0022E04D005D3032E07D1296705E0ED +S1133BA0696703E0E96201E02963FFE73EE0017E23 +S1133BB0022925D10021C9430A0001250368002DEB +S1133BC00AD0022D04D005D3032D07D11A6705E0CE +S1133BD05A6703E0DA6201E01A63FFE7002604682B +S1133BE0002E0AD0022E04D005D3032E07D121675C +S1133BF005E0616703E0E16201E02163FFE715E0AE +S1133C00017E012912D10021C94300230268002B3F +S1133C100AD0022B04D005D3032B07D1116705E08A +S1133C20516703E0D16201E01163FFE7F0BDF0B535 +S1133C3000231E000A78D406E40E01221500A540D4 +S1133C400F78402F1ADB2A0002230668002B10D0BD +S1133C50022B06D009D3032B0FD1B76E1743B766D7 +S1133C600BE0F76E1743F76607E0776A174377624E +S1133C7003E0B76A1743B762FFE735E00E78202EFA +S1133C8019DB2B000668002A10D0022A06D009D3BB +S1133C90032A0FD1B76E1F43B7660BE0F76E1F43BD +S1133CA0F76607E0776A1F43776203E0B76A1F434A +S1133CB0B762FFE718E02A000668002B10D0022B39 +S1133CC006D009D3032B0FD1B76E1743B7660BE0A9 +S1133CD0F76E1743F76607E0776A1743776203E0E6 +S1133CE0B76A1743B762FFE7F0BDFFB591B000258F +S1133CF001200990012008900820019003210491DB +S1133D000222059214221092834A0F92FA229205FB +S1133D100E921BAA1278002A0DD1804A0D925E22BF +S1133D2002920C911F2107910299079A8918491C44 +S1133D300B910A900CE0794A0D92262202920C9182 +S1133D40072107910299079A8918491C0B910A9037 +S1133D50139800F0EDF8040001260D98B04259DBE9 +S1133D60129800F0E5F80500300000F0F1F80100C9 +S1133D70280000F0F8F80500139800F0D9F80100C5 +S1133D80280000F0F0F800F041F9009000980028B5 +S1133D9003D000980A99884200DA3BE0009800F0CA +S1133DA0D7F80100280000F0DEF80700139800F0AF +S1133DB0BFF80100380000F07EF98021090400F00A +S1133DC0D3F908D8139800F0B3F80100380000F0D4 +S1133DD072F9020006E0139800F0AAF8390000F026 +S1133DE06AF902000B980099884211DB2000110047 +S1133DF000F0BAF90CD809960098019014001098B4 +S1133E000099884204DB10000F9900F0C1F901D336 +S1133E10761CA2E714A8008800F08AF80E9900F036 +S1133E20CAF9039001980299884201DA0198029034 +S1133E30029C0C98844225DB2000401C38494843EE +S1133E400199FEF74FFF050014A80088281A0128DD +S1133E5003DB14A800882F1A02E014A80088471B6B +S1133E6014A8008885420DDB380000F071F803992E +S1133E7000F08EF904D20494380000F069F803903D +S1133E80641ED6E701980499401A401E05902548FF +S1133E90039001250598A84221DB21486843019934 +S1133EA0FEF720FF07001AA80088381A012804DB4F +S1133EB01AA80088381A069003E01AA80088C01BC4 +S1133EC00690069800F044F8039900F061F904D2D2 +S1133ED00895069800F03CF803906D1CDAE7099801 +S1133EE011990860049800F0CFF90FA20CCA00F0F1 +S1133EF0D5F900F095FA11998860049811998968A8 +S1133F00401A1199C8600598119908610898119987 +S1133F10486015B0F0BD0000CDCCCC3DFF030000DF +S1133F201027000000401C46333333333333E33F60 +S1133F309D2102000AD002D4491E9218FCD5C9055D +S1133F40100A1206524100D3012A4841704700006A +S1133F509D210200EED55242F446FFF7EBFF012209 +S1133F60D2071043604730B405004D400122D20708 +S1133F7015404B180418240E25D01B0E2CD0FF2CF2 +S1133F8031D0FF2B34D0E41A00020902104311434C +S1133F9043084808D10D1B1A02D2641EDB181B18F3 +S1133FA0DB18834200D31B1A4941F9D37F3423DD44 +S1133FB0FF2C05DAE40548086041284330BC70470B +S1133FC0FF20C005F9E728001B0E03D0FF2BF5D115 +S1133FD04902F3D0D043F1E7FF2C01D14002F9D1DB +S1133FE0FF20C005E9E74002F4D1FF2BF8D1F1E747 +S1133FF028004902E2D0EDE70B0200202442DCD184 +S11340005B129B1CD9D9D805D7E7FEE70122D2075A +S11340100118090E7F3910D449421F310FD40018FA +S113402005D2C0011043C84000D5D0437047C00139 +S11340301043C84005D440427047002070470042F6 +S1134040F3D5100070470122D20703004B402ED451 +S1134050431A01D2C01AC91830B44B180418240EDC +S11340601B0E22D0FF2C20D0E31A182B1DDC0902D2 +S11340701143C40D641E0002104394461925ED1A21 +S11340800A00AA40D940451801D36D08A41CE405D0 +S1134090D209280A2D062A436546AA41604103181D +S11340A01B0EFF2B01D3C00DC00530BC704751401F +S11340B006E05140CCE70122D20703004B40F8D47C +S11340C0431A03D2C01AC9185040514030B44B1897 +S11340D0090211430418240E1B0E40D0FF2C3AD0C1 +S11340E025009D410BD31ED8C50D4002401A0BD3A9 +S11340F0ED050100400AC90591416841D5E7C50DA8 +S113410040024918401AD0D001214008491C001827 +S1134110FCD58C4204D36D1A000AED054019C4E79E +S1134120E8051040C1E7182DBFDCAC1C0D00E140D0 +S1134130E5414D40012D4941C40D00021043451A8B +S113414001D46D199543641EE405280A2D06954192 +S1134150604130BC7047FF2BA7D1D843A5E7244268 +S1134160A3D10020A1E7FEE70CB401221206031834 +S1134170DA4207D84B18DA4204D802000A439218EC +S113418002D281420CBC7047FCD088420CBC704700 +S11341900CB4012212060318DA4207D84B18DA428B +S11341A004D802000A43921802D288420CBC704719 +S11341B0FCD08142FAE730B405004D400122D20719 +S11341C015404B180418240E2ED01B0E32D0FF2C91 +S11341D034D0FF2B3AD0E4180002090210431143F3 +S11341E0000A090A9446C2B24A43000AC3B24B43C6 +S11341F0000A4843110A5B181A43D2B2190A091873 +S113420001D44918641E080A7F3C23DBFE2C08DA1B +S1134210E40509061143634699416041284330BCD3 +S11342207047FF20C005F9E728001B0EFF2BF6D1CD +S1134230D043F4E72800FF2CF1D1F9E74002F7D18D +S1134240FF2B01D14902F3D1E005E7E7D805490284 +S1134250E4D0EDE743020020641CDFD15B129B1C19 +S1134260DCD9D805DAE7FEE7010042221201D21EAA +S1134270004207D002D4521E0018FCD5C10A4005E2 +S113428012058918704700000100EED54042F4463B +S1134290FFF7EBFF0122D20711436047F0B50E0090 +S11342A05E400125ED072E40B446AE0ADF184C18D7 +S11342B0F44208D2F7420ED2640D01D07F0D12D120 +S11342C000206146F0BD05D1F74201D87F0D05D12C +S11342D00020C143F0BDFBD1640DF9D00020C143DF +S11342E0490549088FE0E419C902DB0229432B433D +S11342F0DB0A460DC00231438E4630B487B295B214 +S11343007D432E0CADB2140C7C43A419260C24045A +S113431025439CB27C43A419190C7943270CC91971 +S1134320A4B20F043C43090C000C97B247432E0C73 +S1134330BE193543ADB2170C4743360CBF19A6B2AC +S1134340BF193E043543240C3E0C36199FB2474333 +S1134350BF19BCB23E0C89191F0C47437F183E0499 +S11343603443390C704680B297B247432E0CBE19C1 +S11343703543ADB2170C4743360CBF19A6B2BF196B +S11343803E043543240C3E0C36199FB24743BF19F3 +S1134390BCB23E0C89191F0C47437F183E043443BA +S11343A0390C77463F0C90B278432E0C80190604E2 +S11343B0ADB22E43050CA0B22D18120C7A4350193D +S11343C0020C80B2240CA4189AB27A431219140471 +S11343D02043120C89181B0C7B43C91830BCEF0A0C +S11343E0394203D1B61940414941641E6F12BF0DD1 +S11343F0E41B0BDBFF19BC4211DA24050027420839 +S1134400AE417841614166463143F0BD641C05D13B +S1134410401C6141CF0201D34908F4E750E75DE74E +S11344204A1812D2400DC90208430121C9070843A2 +S1134430520D40210901521A521C06D452421F3215 +S113444001D4D0407047C017704700207047000067 +S1134450F8B59CB0050000263700300069460870A6 +S1134460029601963400300069468870402200218B +S11344700CA800F00DFE04A8D349202200F012FE7F +S1134480082069464870FF20801C0390300001001A +S11344906A465278C9B291420FD20021C9430CAA8C +S11344A00300DBB2DB00D15031000CAA0300DBB205 +S11344B0DB00D2189180401CE9E7370038006946D8 +S11344C04978C0B288424BD20220040003982100EC +S11344D089B288423ED3286804A93A00D2B2920035 +S11344E08958FEF702FC210089B2FEF7FEFB019019 +S11344F001986968884213D10CA83900C9B2C9006F +S113450041188C803900C9B2C900401887710CA8C1 +S11345103900C9B2C900465001206946887019E0C3 +S113452001986968884213D20CA83900C9B2C9003D +S113453041188C803900C9B2C90040188771686875 +S11345400199401A0CA93A00D2B2D200885001E075 +S1134550641CBBE768468078002801D17F1CADE766 +S1134560684606700CA869460978C900405802904C +S11345700126300069464978C0B2884211D20CA89D +S11345803100C9B2C90040580299884207D20CA828 +S11345903100C9B2C9004058029068460670761CC2 +S11345A0E7E70CA869460978C900411889880229F7 +S11345B017DA286804A96A46527892008918091FF4 +S11345C00968FEF792FB0399FEF78FFB019068469A +S11345D04078401EA8600398801EE8600198286116 +S11345E014E069460978C90041188979A9606946C7 +S11345F00978C90040188088801EE86068680CA9A2 +S11346006A461278D2008958401A28611DB0F0BD5C +S1134610F8B58AB004000D00002000900700029055 +S11346202000006E00900021684600F0F4FC002198 +S1134630684600F0E1FC697B684600F0A3FC697AF7 +S1134640684600F075FCA97A684600F068FC686862 +S113465006902868059005A8FFF7FAFE07986946B2 +S1134660087108980290029E03940398006CFF213D +S113467088433100C9B20143049104980399086442 +S113468068460179684600F061FCE989491E89B2EF +S1134690684600F0F3FCA87B800604D5E97E6846F2 +S11346A000F07EFC03E00021684600F079FCE97A22 +S11346B0684600F059FC687D002805D0022829D0FE +S11346C010D303283ED04BE00021684600F0B2FC32 +S11346D0E97F684600F090FC2020295C684600F0E1 +S11346E09AFC4AE00121684600F086FC00216846F5 +S11346F000F091FC287C002804D10021684600F0D9 +S113470099FC06E0287C012803D10121684600F0C9 +S113471091FC32E0287C002804D10021684600F096 +S113472089FC06E0287C012803D10121684600F0B9 +S113473081FC0121684600F05FFC0021684600F01E +S11347406AFC1AE00021684600F074FCE97F6846C0 +S113475000F052FC2020295C684600F05CFC0CE070 +S11347600021684600F066FCE97F684600F044FCDE +S11347702020295C684600F04EFC009820660BB0AF +S1134780F0BDF8B50A7A6B461A700200536A6C469B +S11347902478012C03D101241C43546202E05C08F8 +S11347A0640054620C7BCD7AAC4005006E6ACB4F3A +S11347B03740BC462600F6B23702F02636013E40AA +S11347C067463E436E62F1BD1CC30000F6B588B077 +S11347D0099909780200D6690B00DBB2012B03D1D9 +S11347E001233343D36102E073085B00D361099B67 +S11347F05B780400E5691F00FFB2012F03D1022199 +S11348002943E16103E0290002229143E16109990E +S113481089780200566A0F00FFB2012F03D10823E2 +S11348203343536203E033000824A3435362099BD8 +S1134830DB780400256A1F00FFB2012F04D1802118 +S113484049002943216202E0A549294021620090E0 +S113485000210E000122009F7F6A1740002F01D023 +S113486013001E00F6B2002E0FD1099B5B790400E1 +S1134870656A1E00F6B2012E03D104262E43666239 +S113488003E02E000427BE436662099BDB796C4675 +S1134890237005002E696B461B78012B03D104237A +S11348A033432B6103E033000424A3432B61099BAE +S11348B09B796C46237103001C696F463F79012F75 +S11348C003D1082525431D6103E025000826B543CF +S11348D01D61089D6D786E46F5700490049D2E6CE4 +S11348E0804D35406E46F67836022E430796079D76 +S11348F0049E3564089DAD786E46B5700390039DA3 +S11349002E6C794D35406E46B67836042E430696A5 +S1134910069D039E3564089DED786E467570029081 +S1134920029D2D6C2D022D0A6E46767836062E4396 +S11349300596059D029E3564089D2D796E46357059 +S113494005006F6A7026B743BC466E463678370159 +S113495070263E4067463E436E62089F7F79002F73 +S113496005D0022F39D024D3032F4AD06DE0089B01 +S11349709B79002B00D10A0003005C6A1500EDB29C +S1134980002D04D08025ED0425435D6202E0574DDF +S113499025405D6205006E6A554F3740BC460E00E7 +S11349A0F6B23706C026B6043E4067463E436E6202 +S11349B06CE013000400616A4D4D0D401900C9B24A +S11349C00E06C021890431402943616205006E6AE4 +S11349D08027FF0437436F6258E002230400616AB2 +S11349E0434D0D401900C9B20E06C021890431405F +S11349F02943616205006E6A8027FF0437436F62B2 +S1134A0044E0089B9B79002B01D01100FFE70200D2 +S1134A10536A0C00E4B2002C04D08024E4041C4348 +S1134A20546202E0314C1C405462032405006E6A57 +S1134A302F4F3740BC462600F6B23706C026B604D0 +S1134A403E4067463E436E6220E0089B9B79002B04 +S1134A5000D10A0003005C6A1500EDB2002D04D0F9 +S1134A608025ED0425435D6202E0204D25405D6212 +S1134A7005006E6A1E4F3740BC460E00F6B237067C +S1134A80C026B6043E4067463E436E620AB0F0BD9F +S1134A908149016081494160012202720021417211 +S1134AA08172C172017342730822C281C175017699 +S1134AB041768176C17601774177C177202281548E +S1134AC08177022202740A22130043741300837450 +S1134AD0C27401754175817570470000FFF0FFFFD6 +S1134AE0FFFEFFFFFF00FFFFFFFF00FFFFFFFFFBD5 +S1134AF0FFFFFFFCF0B587B004000D0000206946FD +S1134B004870206802900298006906900698012176 +S1134B108843029908612068019001980069059012 +S1134B20059880214900014301980161276838698B +S1134B3004900498802189000143396100BF00BFBB +S1134B4000BF29002068FFF71CFE2A001732290045 +S1134B5010312068FFF73AFE012001006A46117007 +S1134B60266831690391039908433061290020685C +S1134B70FFF74EFD07B0F0BDF2B482B002990160B8 +S1134B8001680A690192019A80235B0013430B6157 +S1134B90026813690093009B8024A4001C431461E1 +S1134BA001230468256902262E43266100BF00BF45 +S1134BB000BF002607683E61F7BC7047F0B50300EC +S1134BC00022100014000D006D1E17D06D1E1DD0A4 +S1134BD0FE3D24D080267600AD1B29D08026B60069 +S1134BE0AD1B2ED08026F600AD1B33D080263601B7 +S1134BF0AD1B38D08B4EAD1B3ED046E01D686F69AF +S1134C003E00F607F60FF6B234003EE01D686E690A +S1134C1077083E00F607F60FF6B2340035E01D685B +S1134C206E69370A3E00F607F60FF6B234002CE040 +S1134C301D686E69770A3E00F607F60FF6B2340077 +S1134C4023E01D686E69B70A3E00F607F60FF6B258 +S1134C5034001AE01D686E69F70A3E00F607F60F85 +S1134C60F6B2340011E01D686E69370B3E00F6079A +S1134C70F60FF6B2340008E01D686E69370E3E0088 +S1134C80F607F60FF6B23400FFE7002C01D001223C +S1134C901000C0B2F0BD000000B4C40440420F00D4 +S1134CA0FFB583B0012069460870002420000399F1 +S1134CB009682200CB6DDB06DB0E1025EB1A6D466E +S1134CC06B706B465B786D46AD8A9BB2AB4200D28B +S1134CD0A2E00194250020006946488003980068FA +S1134CE0006E0190002101A800F078F9012101A8CB +S1134CF000F065F9002101A800F08DF9002101A858 +S1134D0000F07AF96846007CC100491E89B201A806 +S1134D1000F0B4F901980399096808662600300088 +S1134D206946898A80B2884269D203980168220060 +S1134D3001204F6903003B40DBB2002B06D16D1C00 +S1134D4039498D42F1D321006A4611706946097CC4 +S1134D50012907D10699320092B2895C039A12683C +S1134D60516614E06946097C022908D1069932008B +S1134D7092B25200895A039A1268516607E0069962 +S1134D80320092B292008958039A12685166250043 +S1134D900399096822000B6F5B080340002B01D0C4 +S1134DA003001A00D2B2002A06D06D1C1E498D429F +S1134DB0EED32000694608706846007C012807D1BC +S1134DC003980068406F0C99320092B2885414E042 +S1134DD06846007C022808D103980068406F0C994B +S1134DE0320092B25200885207E003980068406F84 +S1134DF00C99320092B292008850761C8FE7002101 +S1134E0001A800F0EBF8002101A800F0D8F80198FF +S1134E1003990968086601E06846047068460078EA +S1134E2007B0F0BD00F0FF00E9030000F0B5030097 +S1134E30002210000C00641E14D0641E1CD0FE3C22 +S1134E4024D080256D00641B2BD08025AD00641B0D +S1134E5032D08025ED00641B39D080252D01641BE0 +S1134E6040D04AE0012425001E68B7692F40AF42B4 +S1134E7000D12200100040E002241D68AE692640E3 +S1134E80A64201D101263200100036E080246400DD +S1134E901D68AE692640A64201D1012632001000E9 +S1134EA02BE08024A4001D68AE692640A64201D1EF +S1134EB001263200100020E08024E4001D68AE6961 +S1134EC02640A64201D101263200100015E08024BC +S1134ED024011D68AE692640A64201D10126320094 +S1134EE010000AE0802464011D68AE692640A642D1 +S1134EF001D1012632001000FFE7C0B2F0BD70B44A +S1134F000A0003689D6D524C2C401500EDB22E042E +S1134F10F8256D03354025439D6570BC70470268D4 +S1134F20520052080B00DBB2DB07134303607047E7 +S1134F3010B40268474B13400A00D2B2920780248F +S1134F40E40522401A43026010BC704710B40268A2 +S1134F50414B13400A00D2B2D406E022920522400B +S1134F601A43026010BC704710B402683B4B1340F4 +S1134F700A00D2B21406C022920422401A430260EC +S1134F8010BC704710B40268354B13400A00D2B20B +S1134F90D2058024240422401A43026010BC7047C6 +S1134FA000B502680B00DBB2012B04D18023DB03C4 +S1134FB01343036002E02B4B1340036000BD00B5B4 +S1134FC002680B00DBB2012B04D180239B03134343 +S1134FD0036002E0244B1340036000BD10B4026878 +S1134FE0224B13400A00D2B21205802464032240EB +S1134FF01A43026010BC704700B502680B00DBB2B4 +S1135000012B04D180231B031343036002E0184BDC +S11350101340036000BD00B502680B00DBB2012B36 +S113502004D18023DB021343036002E0114B1340DD +S1135030036000BD10B402680F4B13400A00D2B2E3 +S11350401404C022920222401A43026010BC70472A +S1135050FFFFE0FFFFFFFFBFFFFFFFC7FFFFFFFCF6 +S1135060FFFF7FFFFFFFBFFFFFFFDFFFFFFFEFFF3C +S1135070FFFFF7FFFFFFFBFFFFFFFCFF0268120BC0 +S113508012030B009BB21B051B0D134303607047F7 +S113509010B50400080011000200200000F02AF8F6 +S11350A0200010BD70B4103A03D378C9103A78C008 +S11350B0FBD2530701D318C918C001D508C908C0C9 +S11350C0D20704D30B880380891C801C002A01D5D5 +S11350D00B78037070BC70478B0701D18307E1D054 +S11350E0124205D00B78491C0370401C521EF9D1A2 +S11350F0704700001206130A1A43130C1A4300BF28 +S1135100094205D0830705D00270401C491EF9D11D +S1135110704700001300103906D330B41400150092 +S113512010393CC0FCD230BC490700D30CC000D5B8 +S113513004C0890002D30280801C002900D50270BB +S11351407047000000B5010008000200D2B2802AB6 +S113515001DB7F221000C0B200BD00B501000800D1 +S1135160C0B2F12805DB0800C0B2FA2801DA012038 +S113517006E00800C0B2802801DA080000E0002040 +S1135180C0B200BDFEB582B0070000252C006E46FB +S11351903F20307030786946097AF0220A43024091 +S11351A032706846007B70706846007CFFF7CAFF67 +S11351B0B0703878002810D0032004002000C0B25A +S11351C0082804DA2000C0B23554641CF6E708222B +S11351D06946F868BB6D984704E003226946F8689D +S11351E0BB6D984740B205B0F0BDFEB50600002087 +S11351F0050001006A460F2313701378F48AF02720 +S113520027431F40177004002100C9B2F38A89B2F2 +S1135210994209D231692300DBB2C95C2300DBB2B5 +S1135220D3185970641CEFE73178002916D00500B3 +S11352302800C0B20721F38AC91A884208DA280074 +S1135240C0B2F18A40181018CC2141706D1CEFE7F0 +S113525008226946F068B36D984706E0F28A521C4A +S1135260D2B26946F068B36D984740B2FEBD3EB510 +S1135270050068461F2101700178EA8A92B2120A79 +S1135280F02313430B400370E98A4170002421008A +S1135290C9B2E4B22100C9B2062909DA2969220097 +S11352A0D2B2895C2200D2B282189170641CF1E7F8 +S11352B008226946E868AB6D9847010049B20029A5 +S11352C004D1298B891D29830121A97640B23EBDD1 +S11352D0FEB5060000273900C9B201A82F220270CA +S11352E00278B37EF0241C4314400470F28A338B9A +S11352F0D21A6B461A806A461288082A02DB0722F1 +S11353006B461A803C00E4B22100C9B26A46128896 +S113531089B291420BD23169328B2300DBB2D218AD +S1135320895C2200D2B282185170641CECE7317897 +S113533000291BD03900C9B23D00EDB22A00D2B217 +S113534007216B461B88C91A8A4209DA2900C9B2A7 +S11353506A46128889184118CC224A706D1CEDE700 +S1135360082201A9F068B36D984707E068460288EF +S1135370521CD2B201A9F068B36D9847010049B23A +S113538000290BD1318B6A46128889183183B17E8A +S1135390491CB176B17E102900DBB77640B2FEBD60 +S11353A0F8B504000D00160000210F000F202B7823 +S11353B00200134206D03200D2B2521E2B780340B0 +S11353C09A4208DA606D002802D0A248616D8847CD +S11353D00620C04315E02A7810404222A05208005B +S11353E0C0B24222A25A80B2904209D20800C0B28E +S11353F028184078E26B0B00DBB2D054491CEEE76E +S11354000020F2BDF8B504000D00170000210800CB +S11354106A4610703800C0B2082808D0606D0028B1 +S113542002D08D48616D88470620C04339E0287852 +S11354300002F0221201024068781618300080B28F +S1135440082808DA606D002802D08448616D884716 +S11354500620C04325E04020205A320092B29042F8 +S113546008D2606D002802D07D48616D8847022013 +S1135470C04316E0422026520800C0B2062809DACA +S11354800800C0B228188078E26B0B00DBB2D0545D +S1135490491CF1E706204422A05201204622A054D0 +S11354A00020F2BDF4B505000C00002217004620D0 +S11354B0285C21780907090F884202D00320C043E1 +S11354C040E04220285A4421695A461A300080B2EA +S11354D0082801DB0720060068460078401E3100DA +S11354E089B2884208DA686D002802D05D48696D87 +S11354F088470620C04325E011000800C0B23300ED +S113550080B29BB298420CD2E86B0B00DBB244270A +S1135510EF5BDB190F00FFB2E7197F78C754491C12 +S1135520EBE74420285A80194423E8524620285C9B +S1135530401C4623E8544620285C102801DB462002 +S11355402A540020F2BD70B504000D00160030008E +S1135550C0B2032808DA606D002802D04248616DA9 +S113556088470620C04300E0002070BD70B50400E9 +S11355700E0015002B009BB23200E168200000F001 +S113558001F870BDFEB5040000263700002C02D1DE +S11355900020C0435CE0A08A69460989884208D299 +S11355A0606D002802D03148616D88470220C043F5 +S11355B04EE03420205C012808D1606D002802D020 +S11355C0CA48616D88470120C04341E068460089AC +S11355D0E0823000208335002800C0B26946098982 +S11355E080B2884209D201982900C9B2405C21697D +S11355F02A00D2B288546D1CEEE7E08A082804DA47 +S11356002000FFF7F2FD070020E02000FFF72FFE47 +S11356100700380040B2002818D13000A0833000C1 +S1135620A0773000E077E06D80472200203203C28B +S1135630083AE06D8047002264305141220028324C +S113564003C2083A2663012034216054380040B272 +S1135650FEBD000084C20000B0C200007CC1000096 +S1135660B4C10000DCC20000FCC20000ECC10000B8 +S1135670FFB583B004006846007E022803DB684659 +S1135680007E092800DB2FE100252900C9B228008B +S1135690C0B201006A46127EC9B2914209D205998C +S11356A00200D2B2895C01AA0300DBB2D154401CCF +S11356B0EFE72F00FFB23800C0B208216A46127E1D +S11356C0891A884208DA01A83900C9B26A46127EEA +S11356D0891845547F1CEEE701AE3078C0B200094A +S11356E0002806D0022865D021D3032800D1B3E0D6 +S11356F0FAE05120205C012804D10520C043502148 +S1135700605401E0502025546846027E01A920001F +S1135710FFF746FE694608706946002008560028CF +S113572004D10498A063022051216054DCE051208C +S1135730205C012804D10520C0435021605401E0BD +S1135740502025546846027E01A92000FFF75AFE26 +S1135750694608706946002008560221C9438842F8 +S11357600CD10720C04350216054512025540023FC +S1135770002202212000FFF705FDB5E06946002064 +S11357800856002815D10498A063012051216054C3 +S113579060784721605401234720225C00212000C7 +S11357A0FFF7F0FCE06D8047002264305141A064B3 +S11357B0E16499E05120205C012804D00520C04315 +S11357C05021605490E00498A16B884200D08BE093 +S11357D06846027E01A92000FFF764FE694608704E +S11357E00326F643694600200856B04207D101A8B3 +S11357F000F0B6FB502026545120255474E069462D +S113580000200856002826D1E06D8047002264302D +S11358105141A064E1644420205A4221615A8842E3 +S113582003D302205121605415E06078002812D07F +S11358304720205C401E472160544720205C0028FC +S113584009D160784721605401234720225C00215C +S11358502000FFF797FC47E03420205C012843D167 +S11358606846027E01A92000FFF76DFE69460870B4 +S1135870694600200856002835D1E06D8047002293 +S1135880643051412200283203C2083A0F20317893 +S11358900140022906D10720C0432063022034219D +S11358A0605420E03178014001290CD1E07F401C94 +S11358B0E077E07F022816DB0620C0432063022045 +S11358C0342160540FE0317801420CD17078002803 +S11358D002D18448A08301E07078A083B078FFF7F8 +S11358E03CFCA077E577FFE707B0F0BD20C20000DD +S11358F0FEB50100089A0020030051240C5D022C1F +S113590002D00420C04328E08C6B8D68AC4201D1E6 +S1135910012400E00400009D2C7042240C5B6D46C1 +S11359202D892600B6B2B54202D26D462D892C00CF +S113593005002B0026009BB2B6B2B34209D2CB6B52 +S11359402E00B6B29B5D019E2F00BFB2F3556D1CB5 +S1135950EFE714805123C8540020FEBD70B4020048 +S11359600B00187810705878507058685060986818 +S11359709060D868D06018691061988A9082002479 +S11359802000D08220001083200090762000908395 +S1135990200090772000D0770020002115002035CA +S11359A003C5083D1500283503C5083D14632500CB +S11359B0342695559D69D5639D8B402695532500C6 +S11359C04226955325004426955325004626955591 +S11359D02500472695559064D164200050215054E9 +S11359E051201454186A5065586A9065986AD065B5 +S11359F070BC704770B504003420205C01285AD173 +S1135A00384DA08BA84202D0A08B002841D0A07FA3 +S1135A10002810D0A07F00283BD0E06D8047020012 +S1135A200B002000203003C8801A9941002930DC83 +S1135A3001DB00282DD22000FFF74AFC06003000CD +S1135A4040B2002822D1A08BA84202D0A08B4019DA +S1135A50A083E06D80470022643051412200283247 +S1135A6003C2083AE06D804702000B00A07F0021CA +S1135A70801859412200203203C2083A208BE18A5F +S1135A80884206D300203421605402E002203421ED +S1135A906054E06D8047220028320CCA121A8B41F0 +S1135AA0002B08DC01DB002A05D20120C04320635F +S1135AB00220342160545120205C012811D1E06D72 +S1135AC08047A26CE36C121A8B41002B09DC01DBCA +S1135AD0002A06D20220C0435021605400205121E4 +S1135AE0605470BDFFFF000008B4024B9C4608BC24 +S1135AF06047C04639020020F0B5020052B2002AC5 +S1135B0017D41822B74B040064B2A408A4001C598B +S1135B10FF25C6001640B540AC438D01EDB2C6006A +S1135B20324095402543020052B2920892009D50A3 +S1135B301BE00F22AC4B182405006DB21540083D44 +S1135B40AD08AE0005006DB22A40083A92089200F2 +S1135B509A58FF25C7002740BD40AA438D01EDB2E6 +S1135B60C7003C40A54015439D51F0BD10B504004D +S1135B70601E80214904884201D301200EE0601E8A +S1135B809A49086003210020C043FFF7B5FF0020B5 +S1135B90974908600720BD490860002010BD002215 +S1135BA002604160012303724272704700B5017ABA +S1135BB000290FD0417A00290CD101684268914232 +S1135BC008D20168491C016001684268914201D110 +S1135BD00121417200BD70B504000E001500AC48EF +S1135BE0215AAC482018FFF7DAFF7820205C0128FE +S1135BF006D02A0092B2310020001830FFF7B6FC1C +S1135C0070BDFEB505000E001400082100226F4689 +S1135C103800FFF76FFA2000C0B2782805D09C48FE +S1135C20295A9C482818FFF7BAFF7920285C0028D5 +S1135C3014D02000C0B211280FD02000C0B2122806 +S1135C400BD02000C0B2312807D02000C0B27E287B +S1135C5003D02000C0B27F2800D10AE068467F212B +S1135C600170467084700322694628001830FFF7DB +S1135C707DFCF7BD10B5040088200001201803C87E +S1135C800022401C514188221201A21803C2083A82 +S1135C90892000012018FFF789FFBD482018FFF76D +S1135CA085FF7C482018FFF781FF10BDB94803C861 +S1135CB0704780B5B8480168491C0160B54A03CAF9 +S1135CC0083A0023401C594103C2083ACD48FFF763 +S1135CD0D1FF01BDF8B596B0002000216A461170CD +S1135CE0AE4C68460078CC21615C884251D268464B +S1135CF0007869460873C44D03A92868FDF7C2FEFD +S1135D00002840D0D02020586946097814225143F5 +S1135D104018407A012832D103A92868FDF76CFEA7 +S1135D2003A92868FDF705FE03AC4820205C029017 +S1135D3003A808300190B54D982040012E18307802 +S1135D404C2148432818071D029A01993800FFF78F +S1135D50C3F9049831784C225143685030784C216F +S1135D604843281844214822A25C42543078401CFD +S1135D7030703078202806D30020307003E003A967 +S1135D802868FDF739FE68460078401C69460870AB +S1135D90A6E717B0F0BDF1B582B0002468460470E0 +S1135DA09A489B49451898214901415C2A789142B7 +S1135DB015D04C2629784C22514340180190029F5B +S1135DC0320001993800FFF787F92878401C2870C1 +S1135DD02878202800D32C70012069460870684672 +S1135DE00078FEBD00E400E01CED00E014E000E0FB +S1135DF018E000E0F3B595B0170000242600F6B2D1 +S1135E002000C0B2E4B265482100CC22825CC9B251 +S1135E1091420ED21599D02282582300DBB2142568 +S1135E206B43D2185268914201D1260001E0641CF0 +S1135E30E9E7D03002A902683300DBB214256B43D2 +S1135E40D25A0A7048228F5400683100C9B2142211 +S1135E5051434018406803903800C0B2019016982E +S1135E60009002A805000835019A00992800FFF760 +S1135E7033F9654D02A92868FDF70CFD02A92868CD +S1135E80FDF7FAFC002017B0F0BD000010E000E0C0 +S1135E908C080000A8080000FEB5002402945A4FA4 +S1135EA05C4E3000803038603500D8350122052141 +S1135EB0280000F0B0F901220521280000F006FABC +S1135EC001220521280000F010FA3500D035052202 +S1135ED00021280000F09FF905220121280000F08C +S1135EE09AF92E4D2800FDF788F80420CC21685437 +S1135EF04948D021685001200100297021006970AF +S1135F002100A9702100E97030216C54C821685423 +S1135F1002AA0B2130000830FCF763FE68780128E0 +S1135F200BD101200190FA20C00000909E4B9F4AA3 +S1135F30029928001C30FDF7D8FE002001909C48EF +S1135F400090994B9B4A029928000830FDF7CDFE3A +S1135F5029003868FDF772F9092000F0F9F9F7BD56 +S1135F6010B5040000200100C9B2082908DA0100B4 +S1135F70C9B2615C904A0300DBB2D154401CF2E721 +S1135F8008228D498D208000FFF734FF10BD0000EA +S1135F909C08000000200020A0320020D04F0020E8 +S1135FA0F8B586B0012501AC280020700226300027 +S1135FB060702800A080814F01AA07213800FCF7F7 +S1135FC02DFE2800207030006070A68001AA0721F1 +S1135FD03800FCF723FE25700720607001AA2921F0 +S1135FE03800FCF71BFE7648006E009002216846DC +S1135FF0FEF7ACFF00F0B4F900F031FB07B0F0BDE0 +S11360000000000008200020A8500020CC3C002004 +S1136010011300001C310020DCC00000F8B59CB066 +S113602000F0DEFC6749002000F036FF00F086F93E +S1136030654C200000F040FFC0204000201800F014 +S1136040D9FF6248039000270297614D029A039991 +S11360502800FFF74FF8D820019000975D4D009A73 +S113606001992800FFF746F804A8012101700121D5 +S1136070818004AA132120000830FCF7CFFD04AA74 +S1136080142120000830FCF7C9FD04AA15212000C2 +S11360900830FCF7C3FD04AA162120000830FCF7E1 +S11360A0BDFD04AA172120000830FCF7B7FDFFF757 +S11360B0F3FE494E4949300000F0C6FF484B494AB7 +S11360C031002000603001F046FA474D2A000921D2 +S11360D020000830FCF785FD2868FA218900FCF7C8 +S11360E004FEFFF743FD414800F032F92000603020 +S11360F0FFF7FAFC00F014F93D48016800293CD090 +S113610007603C4C2068401C206020680A21FCF792 +S1136110ECFD002905D138480078012801D100F0B0 +S113612037FA2068FA21890088420FD327600120BA +S113613000F03CFA0400314802681100491C016077 +S11361402300DBB22E49002000F0A6FE2A48017885 +S113615000290AD12B490A78521C0A7009780B29A4 +S113616003DB01210170FFF71BFF012001F0F6FAA8 +S1136170300001F0CDFB01F0DBFA09A8FFF70BFEBC +S11361800128B9D109982049884203D009981F49A8 +S11361908842B1D109A84421435C021D0999300009 +S11361A01830FFF765FAA7E74C1D000080841E0035 +S11361B0C409000020A10700EC06002024310020BF +S11361C080320020BCC300001C31002004130000F6 +S11361D0CC3C0020D04F002008200020B80600202E +S11361E0035C0000D75B0000A8320020FFFF000022 +S11361F0A0320020A4320020D3550020AC5000204F +S1136200D4C30000D255002032070000DF0700008D +S1136210016042607047F5B582B06846007B002893 +S113622028D16846007B6A4610700800029A1268FA +S11362308300D458244B23406C4624782402E02560 +S1136240ED0025401D430195019B8400135101235A +S11362500C00029D2D68A600AF590426B743BC4626 +S11362601E00F6B2B60004273E4067463E43A70030 +S1136270EE5127E000200A00029B1B6894001C5981 +S11362800425AC430500EDB2AD000426354025439A +S11362900195019C95005C516C46247B6D462C70E5 +S11362A00C00029D2D68A600AE59074F3740BC462E +S11362B06E4636783702E026F6003E4067463E4397 +S11362C0A700EE51FFBD0000FFF8FFFF30B44368A4 +S11362D05B6901248C40A3431400E4B28C401C434A +S11362E0230045686B6130BC704730B443681B6859 +S11362F001248C40A3431400E4B28C401C432300CB +S113630045682B6030BC704700B5010049B20029D4 +S113631005D40121C206D20E91400B4A116000BD82 +S113632000B50A480168012906DB0168491E0160BD +S11363300068012800DA62B600BD000072B60348A6 +S11363400168491C0160704700E100E01831002039 +S113635010B50400200040B2FFF7D6FF10BD0000C6 +S113636018B589B000F041F86846FEF791FB0120AA +S113637069460872804A0192C87248727F4C6A4624 +S1136380292120000830FCF72CFC0028F6D0B2208C +S11363904000241869462000FEF7ACFB00212000D1 +S11363A0FEF7ADFD00200AB010BD7CB506000D005F +S11363B0734B1E705D70734C00940222012172486D +S11363C0FEF76EFC207800026178084380B276BD47 +S11363D010B56D4C02212000FEF7F0FB012803D11B +S11363E002212000FEF722FD10BDF0B595B0674CE8 +S11363F0032205212000FFF70EFF01256846C57121 +S113640005200E9021680D910D990E9A92008958DD +S1136410402291436A46D279920140231A400A43AA +S1136420149214990D9A0E9B9B00D15069468D715C +S11364300C9020680B900B980C99890040582027E9 +S1136440FF43384020266946897949013140014398 +S1136450139113980B990C9A9200885003220221ED +S11364602000FFF7D8FE6846457102200A90216893 +S1136470099109990A9A92008958402291436A46DF +S11364805279920140231A400A431292129B0999AD +S11364900A9A92008B5069460D7108902068079003 +S11364A00798089989004058384069460979490194 +S11364B031400143119111980799089A920088502C +S11364C0032204212000FFF7A6FE6846C5700420BD +S11364D00690216805910599069A920089584022F0 +S11364E091436A46D278920140231A400A4310929B +S11364F0109B0599069A92008B5069468D70049002 +S113650020680390039804998900405838406946EC +S113651089784901314001430F910F980399049AF6 +S113652092008850032203212000FFF774FE68467E +S11365304570032002902168029A92008B584022F1 +S113654093439C466A465278920140231A4063461C +S11365501A43029B9B00CA506B461D70236884003B +S11365601C5927406C462478640126403E4384002D +S11365701E5115B0F0BD000040420F001C31002038 +S1136580685500207455002080320020EC31002032 +S11365901CB5032000F00AF8040000222100C9B24F +S11365A0032000F00BF80090009816BD10B504000D +S11365B000216006400EFFF7F8FE10BDF8B5050097 +S11365C00C0017002100C9B280202843C0B2FFF795 +S11365D0ECFE0600002F00D03E80684605702800BF +S11365E0C0B2FFF7E3FF60406946487068468470B4 +S11365F00098F2BDFEB582B004000F000A9E200090 +S1136600C0B2FFF7D3FF0500002E00D0358028006C +S1136610B8436946097C6A46127B91400143684647 +S113662001706846017880202043C0B2FFF7BDFEA8 +S1136630684604716846007C6946097B884001A964 +S113664088702000C0B2FFF7B1FF0100394001A8F3 +S11366508078484001AA5070019805B0F0BDF0B5AB +S113666099B015273800002529006A4651710100A8 +S1136670C9B2090941400800C0B28008484001007D +S1136680C9B2490841406846017168460079010071 +S1136690C907C90F012901DB952007002C000495C7 +S11366A0200080B2C0086946487320004001694652 +S11366B0087328006946C8722800694688720498DD +S11366C0C008694648720498400169460872280067 +S11366D06946C87128006946887105A83249502264 +S11366E0FEF7E0FC05AE77706846407B29217054C4 +S11366F06846007B2B2170546846C07A2D21705463 +S11367006846807A2F2170546846407A312170544B +S11367106846007A332170546846C0793521705434 +S11367206846807937217054684640794B2170540B +S1136730FFF716FE002809D0280069460870FF20DC +S1136740694648706846857000982BE02C0020004C +S1136750C0B24000305C002806D12000C0B2400026 +S113676030184078002814D000222000C0B2400025 +S1136770301841782000C0B24000305CFFF71EFFA3 +S1136780009068464078002801D000980AE0641C14 +S1136790DDE72800694608702800694648706846A5 +S11367A08570009819B0F0BD2CC1000010B55B4C89 +S11367B00320206160615A48A0615A49E161802147 +S11367C0C90021620021A1626162E162206656482B +S11367D060661020A0662167E166616753A1E01D31 +S11367E001F010F95249200001F00CF92020A071A9 +S11367F010BDF1B586B00C0015000020019006987C +S1136800C7680698006900900098874203D20098F0 +S1136810C01B401E05E006988068C01B0099401804 +S1136820401E06998968C91B884202D3069880686D +S1136830C01BA84201D2060000E02E000698406862 +S1136840C01903900596049403980290059A04993C +S11368500298FEF741FC0298019880190190A4194E +S1136860AD1BBF1906988068874201D1002007003C +S11368700698C760002DC4D1019807B0F0BDF8B5E3 +S113688088B004000D001600E0680390A068039926 +S1136890401A0290029886420FD260680399401809 +S11368A0009005960495009F059A04993800FEF718 +S11368B013FC03988019E06020E00298019060685E +S11368C0039940180090019807900695009F079A35 +S11368D006993800FEF700FC0298301A01906068AF +S11368E0009001980590029828180490009F059A3A +S11368F004993800FEF7F0FB0198E06009B0F0BDA0 +S113690000B501000A69CB68934204D38868401E2D +S1136910C01A801801E0D01A401E00BDB0500020FB +S1136920FCC3000058510020585500205254540014 +S113693008C40000F1B582B00F0015000197274884 +S1136940029918225143401806001836706900282D +S113695003D0022821D010D326E03000FFF7D0FF67 +S113696000900098A84201D2002405E02C002A00DF +S113697001993000FFF783FF17E03000FFF7C0FFF5 +S113698000900098A84201D2009C00E02C00220054 +S113699001993000FFF773FF07E02A0001993000E6 +S11369A0FFF727FF040000E000242000FEBDF1B53E +S11369B00F001600094D2878002801D1FFF7F6FED4 +S11369C0EFF31084012080F310883200390000981E +S11369D0FFF7B0FF84F31088F2BD0000B050002030 +S11369E080B5FFF7E3FE01BD70B504000E00A56895 +S11369F061682800401C814207D32068465528005E +S1136A00401CA060E068401CE060A06861688842A7 +S1136A100DD1A26821682069FFF7C9FFA1688842E7 +S1136A2003D00020C043E06001E00020A06070BDFE +S1136A30F7B584B01F000C9D05980290012401262F +S1136A4002980699884206D302980699FCF74DF9F4 +S1136A500290761CF4E7BE4200D23E000D98C007B7 +S1136A601BD4002D19D00D98800705D5002F03D114 +S1136A7030206946087002E0202069460870002D25 +S1136A800BD0AE4209D26D1E684601780498FFF718 +S1136A90ABFF0498C0680028F1D50498C0680028AA +S1136AA03CD4022F01D37F1E08E005982100FCF797 +S1136AB01CF9019001980699884202D30698444330 +S1136AC0EFE705982100FCF710F90190059801996A +S1136AD06143401A059012480199415C0498FFF7FC +S1136AE083FF0498C068002806D420000699FCF7A8 +S1136AF0FCF80400002CE4D10D98C0070ED5002D3D +S1136B000CD0002D0AD0AE4208D26D1E202104986C +S1136B10FFF76AFF0498C0680028F2D507B0F0BDFB +S1136B20ECC30000FEB582B007000A9C029800285E +S1136B3002D50298454200E0029D01260398854251 +S1136B4006DB28000399FCF7CDF80500761CF5E771 +S1136B500498864201D204980600002C06D00298BC +S1136B60002802D40B98400700D5641E0B988007B8 +S1136B7002D50498002810D00B98C0070DD4002C1F +S1136B800BD0002C09D0A64207D2641E2021380065 +S1136B90FFF72AFFF8680028F3D5F868002836D4F0 +S1136BA00298002807D50298414202912D2138000D +S1136BB0FFF71AFF06E00B98400703D52B21380096 +S1136BC0FFF712FFF868002821D40B988007800F84 +S1136BD0022810D1049800280DD1002C0BD0002CD1 +S1136BE009D0A64207D2641E30213800FFF7FCFE0C +S1136BF0F8680028F3D5F868002808D40B980190A9 +S1136C000094049B039A02993800FFF711FF05B022 +S1136C10F0BDF5B59BB00C000AA805904020069085 +S1136C20002007901B980990002008902078070006 +S1136C30641C3800C0B2002800D11BE13800C0B287 +S1136C40252800D00DE100200500012102912278C1 +S1136C5017003A00D2B2232A13D02B2A0CD02D2AA3 +S1136C6002D0302A03D011E00D43641C0FE02A0047 +S1136C7002251543641C0AE02A0004251543641CFC +S1136C8005E02A0008251543641C00E00290029ADE +S1136C90002ADCD1039021780F003900C9B23029D1 +S1136CA003DB3900C9B23A2906DB049020780100DD +S1136CB0C9B22E2920D109E0641C03990A22514348 +S1136CC03A00D2B2891830390391E4E7641C217880 +S1136CD008000100C9B2302903DB0100C9B23A2916 +S1136CE000DB09E0641C04990A2251430200D2B279 +S1136CF0891830390491EAE727783800C0B26C2843 +S1136D0003D03800C0B2682803D1641C207807007F +S1136D10F3E73800C0B2252800D19BE058284ED0B4 +S1136D2063280AD064281CD070287BD073285DD0D7 +S1136D3075282DD0782842D091E01C9800681C99C1 +S1136D4008601C98006800681C990968091D1C9A51 +S1136D5011600290029E3100C9B205A8FFF744FEFB +S1136D607DE01C9800681C9908601C980068006805 +S1136D701C990968091D1C9A1160029001950398D9 +S1136D800090049B0A22029905A8FFF7CBFE66E057 +S1136D901C9800681C9908601C98006800681C997D +S1136DA00968091D1C9A11600290019503980090CE +S1136DB0049B0A22029905A8FFF73AFE4FE01C98AB +S1136DC000681C9908601C98006800681C99096890 +S1136DD0091D1C9A11600290019503980090049B70 +S1136DE01022029905A8FFF723FE38E01C980068DA +S1136DF01C9908601C98006806681C980068001DAF +S1136E001C99086030780700761C3800C0B200284E +S1136E1007D03900C9B205A8FFF7E6FD0898002895 +S1136E20F0D51CE01C9800681C9908601C98006848 +S1136E3000681C990968091D1C9A116002900020C1 +S1136E4001900820009008231022029905A8FFF75A +S1136E50EFFD04E0252105A8FFF7C6FDFFE7641C4C +S1136E6004E03900C9B205A8FFF7BEFD0898002860 +S1136E7000D4DBE6089801280BDB0798002804D02F +S1136E80079A0AA91B98FFF792FD089807994018DA +S1136E90089008981DB0F0BD0CB438B505000C007E +S1136EA004A800906A4621002800FFF7B2FE01B052 +S1136EB0029930BC03B00847F0B58BB004003548E4 +S1136EC00590069000200790089009900A90324D92 +S1136ED0324F334E05A80390029601973148009033 +S1136EE02B00314A314920000830FBF753FE2A00B9 +S1136EF02F492000603000F0BFFD0220694608746D +S1136F0004A803902B48029001960095264B3A0062 +S1136F10294920008030FCF760F8284A28492000DD +S1136F20C830FFF775F9274A27492000D030FFF70A +S1136F306FF9264A26492000D830FFF769F9254A17 +S1136F4025492000E030FFF763F9244A2449200052 +S1136F50E830FFF75DF90095124B3200214920001B +S1136F60F03000F0BFFE104B3A001049882040007A +S1136F70201800F0C9FE1C49B22040002018FDF77B +S1136F80FBFD1A49C0204000201800F031F80BB076 +S1136F90F0BD00BF00127A0000E0064000F8064091 +S1136FA000E8064000E4064000F0064000F0074018 +S1136FB00000024000F00540008003400050034000 +S1136FC0000006404050034000100640805003403B +S1136FD000200640C05003400030064000510340EA +S1136FE00040064000D0074000C0024000A0074017 +S1136FF00160704710B502680121126852090A4005 +S11370001300DBB2012B19D10D4B046863600368D4 +S11370101B688024A343046823600A4B0468A360AC +S113702003681B68DB0A0B40DBB2002BF8D1036852 +S11370301B685B0A0B40DBB2002BF8D010BD0000CC +S113704020C528D9FFFF000038B505000C00210039 +S1137050280000F024FC0548A8600548E8600F20DB +S11370606860044828610620A88231BD0CC0000075 +S113707054C200005C080020F3B581B01400C025A0 +S11370802600F6B2281D0090029F320000993800B5 +S1137090FEF722F8F7BD43780B707047F3B581B063 +S11370A01400C0252600F6B2280028300090029F64 +S11370B0320000993800FEF70FF8F7BDF5B583B03C +S11370C00C00C0250C2002902800183001902600E6 +S11370D0029A01993000FDF7FFFF082628000C30C2 +S11370E0009027000C37320000993800FDF7F4FFB8 +S11370F02020E07205B0F0BDF3B581B01400C025C6 +S11371002600F6B20095029F320000993800FDF780 +S1137110E3FFF7BD30B500231C001500E4B2EDB267 +S1137120AC4205D220241D00EDB24C555B1CF3E7A4 +S113713030BD000008B4024B9C4608BC6047C04602 +S11371404D02002008B4024B9C4608BC6047C04670 +S11371504D04002038B50124724D0C21280000F0A4 +S1137160DBFD002813D10121280000F0D5FD012802 +S11371700AD1A3480168A34A914202D00020040026 +S113718007E00021016004E00020040001E0002089 +S113719004002000C0B232BD802000017047F0B569 +S11371A00400200000252E00954209D2964E4F5D22 +S11371B04740FFB2BF00F659000A70406D1CF3E768 +S11371C01E00F6B2012E02D10026F643301AF0BD9D +S11371D0FEB5002701970097FFF7B0F88B48FBF73F +S11371E086FF852424018A4D3A0021002800FDF7FA +S11371F081FF80204002056886480668864806604C +S113720086490D600A6882F30988096881F3088851 +S113721080214902BE4A116000688047F7BD70B5FD +S113722085252D0100247A4E220029003000FDF727 +S113723061FFFFF783F823213A4800F02DFE70BD6B +S113724080B50020009003230622C0210120FFF70F +S1137250D1F901BDE0B56846762101706C4B34214B +S1137260595C41700222694658689B68984707BD7B +S113727080B56748417C002916D184210901415C0D +S1137280012903D0B249415C01290AD10021A14A54 +S113729081500121AE4A81540221417440684170F9 +S11372A002E0042000F082F901BDF8B5584C607C7E +S11372B0002802D0607C012832D1E06900282FD058 +S11372C0206AE16988422BD200252E006769C048F4 +S11372D0205C032814D0FFF731F801216069FFF71F +S11372E029FF06003000C0B2002807D1E169491E19 +S11372F08020C0003818FFF71DFF0600FFF710F8C4 +S11373003000C0B2002805D102206074E561A56197 +S1137310256205E0E561A5612562032000F046F9D8 +S1137320F1BD00002C320020F8B59F4800780128F8 +S113733064D1374C607C002802D0607C01285DD188 +S1137340B048205C012859D1E06AA16A884255D22C +S1137350002637009E48205C03282BD03000694665 +S11373600870300069464870022069460870FEF7CC +S1137370E5FF3500280069460978C0B2884217D273 +S11373808022D2002800C0B28002201801003531CA +S1137390606AE36AC0182B00DBB29B02C018FFF7D7 +S11373A0D1FE07003800C0B2002801D16D1CE1E70E +S11373B0FEF7B6FF3800C0B2002813D1E06A80217E +S11373C009014018E062E06AA16A884205D33000EE +S11373D08D4960540220607401E001206074FFF75D +S11373E039FF07E0300088496054A662E662032052 +S11373F000F0DCF83000834960542663F1BD0000DE +S1137400F063002055AAAA55189900009C31002069 +S1137410C028002004000100143100201031002095 +S1137420F8B5A34C607C002802D0607C01286DD1A3 +S11374302600113601253570654820180178012988 +S113744002D00178002957D18D4801F009F90028AC +S11374504AD18C4801F004F9002845D188480068D5 +S11374608949884207D03A482554022030700020C8 +S1137470B74960544AE08F480768824800688E49DB +S1137480401800900098A021890288420ED20098EA +S11374908A4988420AD30123009A802149020020A4 +S11374A0C043FFF77CFE8649605002E00020844917 +S11374B0605083482058874207D02548255402202D +S11374C030700020A249605420E0A148255420488F +S11374D020180178002903D1052000F067F815E091 +S11374E005700220307011E01948255402203070D4 +S11374F000209749605409E00178022906D00078F9 +S1137500032803D19248255402203070F1BD0000B5 +S113751008ED00E04808000080B56548417C00297A +S113752002D0417C012912D18A4941580A290CD33D +S11375300749415C002908D19A490020FFF7ACFCB7 +S1137540FEF7FCFEFFF744FE01E00121417401BD9A +S1137550430800007047FEB582B006008520000194 +S1137560019000250095524C2700009A019938009B +S1137570FDF7C0FD2660029860600398A06004983F +S1137580E0604F4825503000FEF7AEFAFFF7E2FD09 +S1137590012807D16F48255001204A496054022030 +S11375A06168487005B0F0BDFD3000200021404AFC +S11375B00B00537410747C4BD15070477B48007C93 +S11375C070477A48407C70477948007870470000DB +S11375D04408000010B560493A4A8A181378002B11 +S11375E007D184231B01C85400236F4C0B51012382 +S11375F0137002224A7410BD574A6E4BD0546E4B1E +S1137600D15470473E0800003D08000038B505001D +S11376100C0051488461456100210A00674BC25443 +S1137620674A8154802149028D420CD1A0218902EC +S11376308C4208D10121634A81548169624A8918C4 +S1137640890AC16117E0002D0AD1082C08D1022152 +S11376505C4A815481695C4A8918890AC1610AE0DB +S11376605A498D4207D15A498C4204D20321554AC2 +S113767081540221C1610120FFF798FF31BD000050 +S1137680C0000100F87F0300DDCCBBAA38B50500BB +S11376900C00314801214A4A815400210A00474B19 +S11376A0C25445628462C1620220FFF77FFF31BD8C +S11376B0C0280020FC7F03000000FFFF0140000001 +S11376C03808000043080000F4B503000022140049 +S11376D010000C00A4B2A24208D21F4C256BAD18B6 +S11376E0641935259E5C6655521CF2E71A4C256BCD +S11376F00E00B6B2AD1925636D462D783426A55516 +S1137700256B80263601B54204D301252E002B4F6C +S1137710E6552800C0B2F2BD00200F4902004A74A9 +S113772004220A7402000A4BCA542A4A8850704739 +S113773080B50948017C062909DA2749027C9200B0 +S11377408A58002A03D0007C80000858804701BD75 +S11377503C08000048080000C028002010B50400C0 +S11377601248017C002902D0017C052906D10E496A +S113777041180A682300DBB2D2180A600D49411887 +S11377800A78012A0CD100220A700B49405C0128B6 +S113779004D1FFF755FDFFF742FD01E0FFF73FFD80 +S11377A010BD0000A4C3000048080000C028002049 +S11377B0FC30002041080000420800003E080000A0 +S11377C03D08000044080000FF030000F05B0020B7 +S11377D00108000038080000A00600200021016014 +S11377E041600A00027241727047002202604160E7 +S11377F00123037242727047407A7047FEB5050058 +S11378000E001400082100226F463800FDF772FCB8 +S11378102000C0B2782805D07448295A7448281822 +S1137820FFF7E3FF7920285C002814D02000C0B2C1 +S113783011280FD02000C0B212280BD02000C0B2F3 +S1137840312807D02000C0B27E2803D02000C0B267 +S11378507F2800D10AE068467F2101704670847059 +S11378600322694628001830FDF780FEF7BD10B5E5 +S1137870020000231800180080B25468A0420CD201 +S113788090681C00A4B2E400005D0C00E4B2A042C5 +S113789001D1012002E05B1CEDE7002010BD70B5B2 +S11378A005000C00210028001830FEF757F80120CD +S11378B0687000263000A8703000782168540020D9 +S11378C0002188221201AA1803C2083AA08D49494E +S11378D06852E08D48496852208E44496852892094 +S11378E000012818FFF77AFF44482818FFF776FFAD +S11378F03F482818FFF772FF3100300040498842A2 +S113790005D231002A187B23D154401CF6E770BD00 +S1137910FEB50400002630006946C8803000694680 +S113792008713700350020001830FEF763F801A80D +S1137930801C0090324B22007B32210079312000E0 +S11379401830FDF7D5FF69460871694604200856CA +S113795000283CD17B20205C07003900C9B22000FC +S1137960FFF785FF00282CD03500606885422ED2B1 +S1137970A068E900405C3900C9B288421FD1A06800 +S1137980E90040188078002806D07C20205CC0B232 +S1137990C0097821605402E0300078216054280046 +S11379A07A2160546846C28821007B31200004009B +S11379B0A368E800181843682000984707E06D1C86 +S11379C0D3E711223900C9B22000FFF717FF084896 +S11379D02018FFF711FF012806D101206070A6705E +S11379E003482018FFF7FAFEF7BD00008C080000DA +S11379F0A8080000880800008A0800009C0800000D +S1137A000208000031B48B0707D00B780370002BF9 +S1137A1020D0401C491C8B07F7D1164CE501830785 +S1137A2022D104C9131B93432B4205D104C004C9BA +S1137A30131B93432B42F9D0FF231A42027009D03F +S1137A40120A1A42427005D0120A1A42827001D0F8 +S1137A50120AC27031BC70470270120A4270120AD4 +S1137A608270120AC270001D04C9131B93432B4277 +S1137A70F2D0E1E701010101F8B504000F0015009F +S1137A80276065600026A660E0208002E060802018 +S1137A9040052061802000026061200000F002F9AE +S1137AA02076E661207E002800D06661200000F088 +S1137AB001F8F1BDF1B489B0012069460871099952 +S1137AC009680791002106916A461279520002233F +S1137AD01A400692069A079B1A606A46D070099A61 +S1137AE0126805916B46DB781B0110242340059333 +S1137AF0059B13606B469870099B1B6804916C4648 +S1137B00A478640120252C400494049C1C606C46D9 +S1137B106070099C246803916D466D78AD01402620 +S1137B2035400395039D25606D462870099D2D6899 +S1137B3002916E463678F60008273E400296029E71 +S1137B402E60099E366808910100C9B28900042795 +S1137B50394031600AB0F0BC7047F0B5010000252F +S1137B602800012213000C681E00F6B2F6018027DB +S1137B703E4026600B681B68DB091340DBB2002B18 +S1137B80F8D00B681B685B091340DBB2002B0CD1E7 +S1137B900B681B681B091340DBB2002B05D10B6873 +S1137BA01B681340DBB2002B00D01000C0B2F0BD44 +S1137BB0FFB587B000242700250009A800784028D5 +S1137BC001DB012007000A98002801D101200700E9 +S1137BD03800C0B200284DD107980068012600681B +S1137BE0C10930000840C0B2002802D102200700B9 +S1137BF040E00798FFF75EFF08206946C870200040 +S1137C00694648700798006805900294FF20049024 +S1137C1005996A4652788918097F049A91436A46FD +S1137C20D378049A1A400A430292029A05996B4641 +S1137C305B78C9180A7709A909786A469170694678 +S1137C400E7007990E680194039068460078301806 +S1137C50007F0399884369468978039A0A4002435E +S1137C600192019869460978711808770798FFF717 +S1137C7074FF07003800C0B200280FD12500082D7A +S1137C800CD22800C01D0799096822000300DBB24A +S1137C90CB181B7F0A9E73556D1CF0E73800C0B2E9 +S1137CA00BB0F0BD7CB50500082200216846FDF745 +S1137CB0EFF900263400FF20694608706B46002265 +S1137CC000212800FFF774FF01000800C0B200285B +S1137CD005D168460078800701D401200400200003 +S1137CE0C0B276BD10B4019C016042608360C46080 +S1137CF010BC704700B5BFF34F8F054805490860B5 +S1137D00BFF34F8F00BFFDE701604260836070479F +S1137D100400FA050CED00E030B502000023180061 +S1137D200C00E4B20D2C01DBC0B2B4E00C00E4B2F0 +S1137D30002C14D0022C29D01CD3042C3ED031D3D7 +S1137D40062C53D046D3082C68D05BD30A2C7DD0A4 +S1137D5070D30C2C00D191E000D283E09AE0156836 +S1137D6001242D682540EDB2012D01D1200000E051 +S1137D7018008FE0156801242D686D082540EDB2C8 +S1137D80012D01D1200000E0180083E015680124D2 +S1137D902D68AD082540EDB2012D01D1200000E091 +S1137DA0180077E0156801242D68ED082540EDB230 +S1137DB0012D01D1200000E018006BE015680124BA +S1137DC02D682D092540EDB2012D01D1200000E0E0 +S1137DD018005FE0156801242D686D092540EDB297 +S1137DE0012D01D1200000E0180053E015680124A2 +S1137DF02D68ED092540EDB2012D01D1200000E0F0 +S1137E00180047E0156801242D682D0A2540EDB2BD +S1137E10012D01D1200000E018003BE01568012489 +S1137E202D686D0A2540EDB2012D01D1200000E03E +S1137E3018002FE0156801242D68AD0A2540EDB225 +S1137E40012D01D1200000E0180023E01568012471 +S1137E502D68ED0A2540EDB2012D01D1200000E08E +S1137E60180017E0156801242D682D0B2540EDB28C +S1137E70012D01D1200000E018000BE01568012459 +S1137E802D686D0B2540EDB2012D01D1200000E0DD +S1137E901800FFE7C0B230BDF3B581B03048019996 +S1137EA08968802288506A46127A002A5AD0022AA7 +S1137EB000D187E06ED3042A00D1B3E000D299E068 +S1137EC0062A00D1DEE000D2C4E0082A00D109E18C +S1137ED000D2EFE00A2A00D134E100D21AE10C2AE0 +S1137EE000D15FE100D245E10E2A00D18AE100D23F +S1137EF070E1102A00D1B5E100D29BE1122A00D131 +S1137F00E0E100D2C6E1142A00D10BE200D2F1E193 +S1137F10162A00D136E200D21CE2182A00D161E20E +S1137F2000D247E21A2A00D18CE200D272E21C2A63 +S1137F3000D1B7E200D29DE21E2A00D1EAE200D2CB +S1137F40CCE2202A00D11DE300D2FFE2222A00D194 +S1137F5050E300D232E3232A00D167E369E300BF90 +S1137F605245535501200100019A92685468012337 +S1137F709C430B00DBB20340234353600024019D68 +S1137F80AD686E680127BE432700FFB23840304316 +S1137F9068604EE301200100019A9268946801230D +S1137FA09C430B00DBB20340234393600024019DF8 +S1137FB0AD68AE680127BE432700FFB238403043A6 +S1137FC0A86036E301200100019A9268D468012375 +S1137FD09C430B00DBB203402343D3600024019D88 +S1137FE0AD68EE680127BE432700FFB23840304336 +S1137FF0E8601EE301200100019A926814690123DC +S11380009C430B00DBB20340234313610024019D16 +S1138010AD682E690127BE432700FFB238403043C4 +S1138020286106E301200100019A92685469012342 +S11380309C430B00DBB20340234353610024019DA6 +S1138040AD686E690127BE432700FFB23840304354 +S11380506861EEE201200100019A926894690123AB +S11380609C430B00DBB20340234393610024019D36 +S1138070AD68AE690127BE432700FFB238403043E4 +S1138080A861D6E201200100019A9268D469012313 +S11380909C430B00DBB203402343D3610024019DC6 +S11380A0AD68EE690127BE432700FFB23840304374 +S11380B0E861BEE201200100019A9268146A01237A +S11380C09C430B00DBB20340234313620024019D55 +S11380D0AD682E6A0127BE432700FFB23840304303 +S11380E02862A6E201200100019A9268D46A012361 +S11380F09C430B00DBB203402343D3620024019D65 +S1138100AD68EE6A0127BE432700FFB23840304312 +S1138110E8628EE201200100019A5268146801238A +S11381209C430B00DBB20340234313600024019DF6 +S11381306D682E680127BE432700FFB238403043E4 +S1138140286076E201200100019A526854680123F4 +S11381509C430B00DBB20340234353600024019D86 +S11381606D686E680127BE432700FFB23840304374 +S113817068605EE201200100019A526814690123DB +S11381809C430B00DBB20340234313610024019D95 +S11381906D682E690127BE432700FFB23840304383 +S11381A0286146E201200100019A526854690123C2 +S11381B09C430B00DBB20340234353610024019D25 +S11381C06D686E690127BE432700FFB23840304313 +S11381D068612EE201200100019A5268946901232A +S11381E09C430B00DBB20340234393610024019DB5 +S11381F06D68AE690127BE432700FFB238403043A3 +S1138200A86116E201200100019A5268D469012391 +S11382109C430B00DBB203402343D3610024019D44 +S11382206D68EE690127BE432700FFB23840304332 +S1138230E861FEE101200100019A5268146A0123F9 +S11382409C430B00DBB20340234313620024019DD3 +S11382506D682E6A0127BE432700FFB238403043C1 +S11382602862E6E101200100019A5268946A012320 +S11382709C430B00DBB20340234393620024019D23 +S11382806D68AE6A0127BE432700FFB23840304311 +S1138290A862CEE101200100019A5268146B012307 +S11382A09C430B00DBB20340234313630024019D72 +S11382B06D682E6B0127BE432700FFB23840304360 +S11382C02863B6E101200100019A5268546B01232E +S11382D09C430B00DBB20340234353630024019D02 +S11382E06D686E6B0127BE432700FFB238403043F0 +S11382F068639EE101200100019A5268146C012315 +S11383009C430B00DBB20340234313640024019D10 +S11383106D682E6C0127BE432700FFB238403043FE +S1138320286486E101200100019A5268546C0123FB +S11383309C430B00DBB20340234353640024019DA0 +S11383406D686E6C0127BE432700FFB2384030438E +S113835068646EE101200100019A5268946C012363 +S11383609C430B00DBB20340234393640024019D30 +S11383706D68AE6C0127BE432700FFB2384030431E +S1138380A86456E101200100019A5268146D01238A +S11383909C430B00DBB20340234313650024019D7F +S11383A06D682E6D0127BE432700FFB2384030436D +S11383B028653EE101200100019A5268146E0123F0 +S11383C09C430B00DBB20340234313660024019D4E +S11383D06D682E6E0127BE432700FFB2384030433C +S11383E0286626E101200100019A5268546E012397 +S11383F09C430B00DBB20340234353660024019DDE +S11384006D686E6E0127BE432700FFB238403043CB +S113841068660EE101200100019A5268946E0123FE +S11384209C430B00DBB20340234393660024019D6D +S11384306D68AE6E0127BE432700FFB2384030435B +S1138440A866F6E001200100019A5268D46E012367 +S11384509C430B00DBB203402343D3660024019DFD +S11384606D68EE6E0127BE432700FFB238403043EB +S1138470E866DEE001200100019A5268146F0123CE +S11384809C430B00DBB20340234313670024019D8C +S11384906D682E6F0127BE432700FFB2384030437A +S11384A02867C6E001200100019A52688023D4584D +S11384B001239C430B00DBB203402343802413516C +S11384C00024019D6D688026AE590127BE43270014 +S11384D0FFB2384030438026A851AAE001200100B1 +S11384E0019A52688423D45801239C430B00DBB2C5 +S11384F003402343842413510024019D6D68842682 +S1138500AE590127BE432700FFB2384030438426CA +S1138510A8518EE001200100019A52689023D4589A +S113852001239C430B00DBB20340234390241351EB +S11385300024019D6D689026AE590127BE43270093 +S1138540FFB2384030439026A85172E00120010068 +S1138550019A52689C23D45801239C430B00DBB23C +S1138560034023439C2413510024019D6D689C26E1 +S1138570AE590127BE432700FFB2384030439C2642 +S1138580A85156E001200100019A52689423D4585E +S113859001239C430B00DBB2034023439424135177 +S11385A00024019D6D689426AE590127BE4327001F +S11385B0FFB2384030439426A8513AE0012001002C +S11385C0019A5268C823D45801239C430B00DBB2A0 +S11385D003402343C82413510024019D6D68C82619 +S11385E0AE590127BE432700FFB238403043C826A6 +S11385F0A8511EE001200100019A5268CC23D458EE +S113860001239C430B00DBB203402343CC241351CE +S11386100024019D6D68CC26AE590127BE43270076 +S1138620FFB238403043CC26A85102E0FFF762FB8A +S1138630FFE700200199896880228850F7BD000077 +S113864008B4024B9C4608BC6047C04601000020A9 +S113865008B4024B9C4608BC6047C046A7000020F3 +S1138660F0B595B00400002528006946C87360077A +S1138670400F002801D00120CAE06748006802903A +S11386800298006801260068C0093040C0B2002882 +S113869001D10920BCE00298FFF7D2FF6846867337 +S11386A02800694608710298006814900995FF2013 +S11386B0139014996A4612798918097F139A914381 +S11386C06A46927B139B13400B4309930999149AAE +S11386D06B461B79D218117721006A46517369469B +S11386E0CE700299096812910895119012996A4600 +S11386F0D2788918097F119A91436A46527B119B5B +S113870013400B4308930899129A6B46DB78D218EE +S11387101177210A6A46117302216A4691700299FF +S11387200968109107950F9010996A4692788918F4 +S1138730097F0F9A91436A46127B0F9B13400B43A8 +S113874007930799109A6B469B78D21811772100EA +S1138750090C6A46D17103216A465170029909686D +S11387600E9106950D900E996A4652788918097FE4 +S11387700D9A91436A46D2790D9B13400B4306939D +S113878006990E9A6B465B78D2181177210E6A46C9 +S1138790917104216A461170029909680C9105953A +S11387A00B900C996A4612788918097F0B9A9143A9 +S11387B06A4692790B9B13400B43059305990C9AD7 +S11387C06B461B78D218117729006A465171052728 +S11387D002990E6804950A903800C0B23018007FE0 +S11387E00A998843694649790A9A0A4002430492DD +S11387F004983900C9B2711808770298FFF728FF66 +S113880001000800C0B2002801D10B2000E02800BC +S1138810C0B215B0F0BD0000F05B0020F1B489B027 +S11388200120694608710999096807910021069198 +S11388306A461279520002231A400692069A079B4E +S11388401A606A46D070099A126805916B46DB7803 +S11388501B01102423400593059B13606B469870FD +S1138860099B1B6804916C46A478640120252C4064 +S11388700494049C1C606C466070099C24680391F9 +S11388806D466D78AD01402635400395039D256006 +S11388906D462870099D2D6802916E463678F60063 +S11388A008273E400296029E2E60099E3668089173 +S11388B00100C9B289000427394031600AB0F0BC14 +S11388C07047F0B5010000252800012213000C6850 +S11388D01E00F6B2F60180273E4026600B681B6836 +S11388E0DB091340DBB2002BF8D00B681B685B0973 +S11388F01340DBB2002B0CD10B681B681B0913401F +S1138900DBB2002B05D10B681B681A40D2B2002AD7 +S113891001D007221000C0B2F0BDF2B584B004004B +S11389200025280069468870280069464870206838 +S113893001260068C10A30000840C0B200280ED1E8 +S11389406846007C01280AD160680068010D300087 +S11389500840C0B2012802D130006946487020683E +S11389600068C10930000840C0B2002801D10920C4 +S11389706DE02000FFF752FF0D20694608702900C2 +S113898022680195FF2002900B00DBB2D3181F7FF1 +S1138990029B9F43BC466B461F78029B3B40674645 +S11389A03B430193019B0F00FFB2D7193B776B4602 +S11389B01B7C002B01D0370000E02F0031006A46F9 +S11389C01170216803910195029003986946097812 +S11389D04018007F029988433900C9B2029A0A40BC +S11389E002430192019803996A461278891808771C +S11389F02000FFF766FF6946097C002909D0216839 +S1138A000968CA0A31001140C9B2002901D10521FF +S1138A1008006946097C002909D1216809680A0B04 +S1138A2031001140C9B2002901D10521080001001B +S1138A30C9B200290BD169464978002907D02168B9 +S1138A403200D2B2520380239B011A400A60C0B2A2 +S1138A5005B0F0BD10B50400824804602000FFF7A3 +S1138A60DDFE0020E06110BDF3B595B000273800AD +S1138A70694608707B48046815988005800D0028B5 +S1138A8003D0012069460870E7E038003D001698DD +S1138A90854200D3E1E0206801260068C109300066 +S1138AA00840C0B2002803D1092069460870D4E008 +S1138AB02000FFF7B3FE05216846017338006A46BB +S1138AC09071206814900997FF201390149A6B46B4 +S1138AD09B79D218137F139A93439C466A46137B5F +S1138AE0139A1A4063461A430992099B9C46149BA5 +S1138AF06A4692799A1863461377159A6B46DA7226 +S1138B0032006B465A712268129208971190129A99 +S1138B106B465B79D218137F119A93439C466A463D +S1138B20D37A119A1A4063461A430892089B9C46CA +S1138B30129B6A4652799A1863461377159AAB02C8 +S1138B40D218120A6B469A7202226B461A71226874 +S1138B50109207970F90109A6B461B79D218137FC7 +S1138B600F9A93439C466A46937A0F9A1A40634637 +S1138B701A430792079B9C46109B6A4612799A18DF +S1138B8063461377159AAB02D218120C6B465A72CD +S1138B9003226B46DA7022680E9206970D900E9AA5 +S1138BA06B46DB78D218137F0D9A93439C466A4632 +S1138BB0537A0D9A1A4063461A430692069B9C46C2 +S1138BC00E9B6A46D2789A1863461377159AAB02BD +S1138BD0D218120E6B461A7204226B469A702268DF +S1138BE00C9205970B900C9A6B469B78D218137FC6 +S1138BF00B9A93439C466A46137A0B9A1A4063462F +S1138C001A430592059B9C460C9B6A4692789A18D7 +S1138C10634613776A46D6716A465170266804978C +S1138C200A90684640783018007F0A99884369465C +S1138C30C9790A9A0A400243049204986946497819 +S1138C40711808772000FFF73CFE694608706846F3 +S1138C500078002801D16D1C19E76846007817B028 +S1138C60F0BD0000F05B0020F7B598B000252800A7 +S1138C7069464874874800680190072018990140A4 +S1138C80002901D0012501E11A990840002801D0EA +S1138C900325FBE028006946087002950B950198AE +S1138CA0006801270068C10A38000840C0B20128E2 +S1138CB002D138006946087068460078002803D05D +S1138CC000210198FFF729FE18988005800D0B906C +S1138CD00B98A021490544182E001A98864205D203 +S1138CE01998805D2070641C761CF6E70198006872 +S1138CF00068C10938000840C0B2002801D1092524 +S1138D00BCE00198FFF78AFD062069460874280034 +S1138D10694688720198006816900A95FF2015909C +S1138D2016996A46927A8918097F159A91436A4678 +S1138D30137C159A1A400A430A920A9A16996B46AA +S1138D409B7AC9180A7718996A46D17369464F7293 +S1138D500199096814910995139014996A46527AF5 +S1138D608918097F139A91436A46D27B139B134057 +S1138D700B4309930999149A6B465B7AD2181177BD +S1138D801899090A6A46917302216A461172019977 +S1138D90096812910895119012996A46127A8918F5 +S1138DA0097F119A91436A46927B119B13400B43AE +S1138DB008930899129A6B461B7AD218117718995E +S1138DC0090C6A46517303216A46D17001990968F6 +S1138DD0109107950F9010996A46D2788918097FE7 +S1138DE00F9A91436A46527B0F9B13400B430793A0 +S1138DF00799109A6B46DB78D21811771899090EE7 +S1138E006A46117304216A469170019909680E91AA +S1138E1006950D900E996A4692788918097F0D9AE5 +S1138E2091436A46127B0D9B13400B4306930699AC +S1138E300E9A6B469B78D21811771A99C908491E65 +S1138E406A46D17205216A46517001990F680595E9 +S1138E500C90684640783818007F0C99884369461E +S1138E60C97A0C9A0A4002430592059869464978E2 +S1138E70791808770198FFF724FD05006846007803 +S1138E80002803D001210198FFF747FD2800C0B254 +S1138E901BB0F0BDF05B00200022026041600123A2 +S1138EA003724272704770B504000E0015009E48AC +S1138EB0215A9E482018FFF7EFFF7820205C0128F4 +S1138EC006D02A0092B2310020001830FCF74EFB85 +S1138ED070BDFEB505000E001400082100226F4687 +S1138EE03800FCF707F92000C0B2782805D08E4876 +S1138EF0295A8E482818FFF7CFFF7920285C0028CC +S1138F0014D02000C0B211280FD02000C0B2122803 +S1138F100BD02000C0B2312807D02000C0B27E2878 +S1138F2003D02000C0B27F2800D10AE068467F2128 +S1138F300170467084700322694628001830FCF7DB +S1138F4015FBF7BD30B50020030004210200130017 +S1138F500C00DBB2E4B2A34208D2754B1400E4B2B5 +S1138F6014256C431B191871521CF0E730BDFFB572 +S1138F7081B0070000252E002C00280069460870E7 +S1138F8029002A00002F02D10A98058032E038789F +S1138F90C0B200096B46187038780007000F6B46A2 +S1138FA05870280001006A461278C9B291420BD267 +S1138FB00100C9B2791849780322121AD2009140EB +S1138FC031430E00401CEDE7280069464978C0B2E1 +S1138FD088420BD22800C0B2381840790321491BBB +S1138FE0C9008840204304006D1CEDE721003000D7 +S1138FF0FEF70CFB05B0F0BD7047FBB5040017008D +S1139000089D2E88FEF7DAFA012814D1FEF7D9FA62 +S11390100100C9B2022908D10121320092B2B95427 +S1139020761C0021424A11710DE00221320092B2F5 +S1139030B954761C07E00320310089B27854761CB9 +S113904000203B4908712E80F7BDF8B504000F00DD +S113905015001E00FEF760FBF1BD7047FBB5040070 +S11390601700089D2E88FEF7A9FA042822D1FEF7DE +S1139070A8FA012805D10220310089B27854761C5F +S113908018E0FEF79EFA022814D1FEF79DFA012893 +S113909008D10120310089B27854761C002025497A +S11390A0087007E00320310089B27854761C002050 +S11390B0204908702E80F7BDF8B504000F00150094 +S11390C01E00FEF729FBF1BD7047FBB50400170035 +S11390D0089D2E88FEF772FA042822D1FEF771FA51 +S11390E0012805D10220310089B27854761C18E099 +S11390F0FEF767FA022814D1FEF766FA012808D1B0 +S11391000120310089B27854761C00200849087681 +S113911007E00320310089B27854761C002004490A +S113912008762E80F7BD00008C080000A808000017 +S11391300C08002038080020704770477047F7B5C6 +S1139140FFB087B0002604963000694608733000EB +S11391506946488134003000694608700420694635 +S11391604873802080000190320005AD01992800E9 +S1139170FBF7C0FF30006946088188A800888699FB +S11391808968869A7A23D25CD2008918497889B290 +S1139190884205D2132231218698FFF79AFE2BE1EB +S11391A07F27879840783840694608738798807885 +S11391B000028799C97840186946C88188A8008840 +S11391C0001F6946488168464089002802D0879874 +S11391D0001D0490350028006946497BC0B28842CE +S11391E034D287482900C9B214225143415A6A46ED +S11391F0D289914228D1869949782A00D2B214237F +S11392005A4382189278914218D12900C9B2142283 +S113921051434118C97800290FD02900C9B214223A +S113922051434018C07886998978884205D0332202 +S113923031218698FFF74DFEDEE007E0222231213E +S11392408698FFF746FED7E06D1CC4E72800694600 +S1139250497BC0B2884205D3312231218698FFF779 +S113926038FEC9E0802080000190009605AC009A89 +S113927001992000FBF73EFF05AC71202070879810 +S11392804078607087988078A0708798C078E07084 +S11392900420694608816846007B012805D000D275 +S11392A081E003285BD02CD37DE055482900C9B266 +S11392B01422514340180079012808D12770312025 +S11392C060702420A07003206946088118E04C4E89 +S11392D002A8009080239B0005AA6846418904984F +S11392E084462F00FFB214204743F0198768604674 +S11392F0B84701202900C9B21422514371180871DA +S11393005AE03F482900C9B2142251434018007959 +S113931000281BD002A8009080239B0005AA684661 +S1139320418904980190364884462F00FFB21420E6 +S113933047436046C019C7680198B84730482900B8 +S1139340C9B2142251434018067107E02770312036 +S113935060702420A0700320694608812CE0284E08 +S11393602800C0B21421484330180079002811D0D5 +S113937002A8009080239B0005AA684641890498AE +S1139380B4462F00FFB2142677436646F6193669B1 +S1139390B04707E02770312060702420A0700320BC +S11393A06946088108E02770312060701220A0709F +S11393B00320694608811FE068460089042809DB08 +S11393C02078712806D16846028905A98698FFF796 +S11393D06AFD11E068460089032808D120787F28B7 +S11393E005D1A27831218698FFF773FD04E0242289 +S11393F031218698FFF76DFD7FB00AB0F0BD000003 +S11394000C080020002202604160012303724272B2 +S1139410704770B504000E0015009648215A96480E +S11394202018FFF7EFFF7820205C012806D02A00DF +S113943092B2310020001830FCF798F870BDFEB5E8 +S113944005000E001400082100226F463800FBF7C7 +S113945051FE2000C0B2782805D08648295A864893 +S11394602818FFF7CFFF7920285C002814D02000AB +S1139470C0B211280FD02000C0B212280BD0200097 +S1139480C0B2312807D02000C0B27E2803D020000B +S1139490C0B27F2800D10AE068467F21017046707F +S11394A084700322694628001830FCF75FF8F7BD82 +S11394B0FAB583B00400150001A870490A68026077 +S11394C088200001201803C8009001A800990170A9 +S11394D00099090A41700099090CC9B2427807231E +S11394E05A43891881700099090EC9B2027803237E +S11394F05A438918C1706846007C042819D3042093 +S113950001000A9A11806946097BA278914208D128 +S1139510029000262F00320002993800FBF7EAFD82 +S113952007E0029001AE2F00029A31003800FBF7E9 +S1139530D3FD05B0F0BDFEB504002000C0B2012883 +S113954002D0092846D093E04D4D68460E782F7816 +S1139550774007704E786F78774047708E78AF7891 +S113956077408770CE78ED787540C57001ADC678C8 +S1139570F02737402F70C678B700BC263E404778A6 +S1139580BF07BF0F37436F7046783700FFB2BF087D +S1139590BC460778C0263E4067463E43AE70067818 +S11395A0360180780007000F3043E87028781E7871 +S11395B0B0420BD168785E78B04207D1A8789E7823 +S11395C0B04203D1E878DD78A84201D0002050E011 +S11395D001204EE02A4D68460E782F7877400770B8 +S11395E04E786F78774047708E78AF787740877081 +S11395F0CE78ED787540C57001AD4678B700BC46AD +S11396008778F0263E4067463E432E700678F6B2D1 +S1139610B6083B273740BC4647787E263E4067461F +S11396203E436E70C6783700FFB23F09BC460778E8 +S11396302C263E4067463E43AE7086783601C0789D +S11396407D2707403743EF7028781E78B0420BD14E +S113965068785E78B04207D1A8789E78B04203D18A +S1139660E878DD78A84201D0002002E0012000E083 +S11396700020FEBD8C080000A808000010C40000F3 +S113968014C40000F7B586B000206946887208212A +S11396900020009003AC009A2000FBF72BFD002073 +S11396A06946C880002069460881002069464871DF +S11396B06846008C06998968069A7A23D25CD2009F +S11396C08918497889B2884205D21322272106983D +S11396D0FFF7B5FE14E106984078012805D122224F +S11396E027210698FFF7ABFE0AE107984078400669 +S11396F0400E6946087103AF6720387068460079E8 +S1139700787068460079C00700D47FE000263000F6 +S11397107C49087034002000C0B2022837DA7A4D40 +S1139720684600792100C9B20901695C88422CD1DC +S11397302000C0B20001281880782100C9B20901B4 +S11397406918497888421FD206988821090140186F +S11397500CC808382000C0B200012818083003C81B +S1139760121A8B41694800218B4208DC01DB8242DA +S113977005D2362227210698FFF761FEC0E02000BB +S1139780C0B200012818467001E0641CC3E7200041 +S1139790C0B2022805DB312227210698FFF74FFECD +S11397A0AEE006206946088101A8801C0090684646 +S11397B00389DBB2BA1C684601790698FFF778FE84 +S11397C06846C08800281BD06846C288921C92B2A2 +S11397D003A90698FFF71DFE6846007949490870F9 +S11397E06846C0884A4908806846C088009003A833 +S11397F0851C484E009A29003000FBF76DFC7FE081 +S1139800312227210698FFF71AFE79E03D4D68467C +S113981000792978491C884205D0242227210698FA +S1139820FFF70DFE6CE06846008C801E80B200904D +S11398300798831C3648028836492878FFF77BFE50 +S11398406946487168464079012822D1022203A959 +S11398500698FFF7DEFD00200100297069460979AA +S1139860491E069A917004002100C9B2022947DA00 +S113987025496A4612792300DBB21B01CB5C9A426C +S113988005D102002300DBB21B01C9184A70641C15 +S1139890EAE7352227210698FFF7D1FD00242000AE +S11398A0C0B202282CDA184A28782100C9B209016A +S11398B0515C884222D12000C0B2000110184078C7 +S11398C0401C2100C9B20901511848702000C0B2DF +S11398D00001101880782100C9B209015118497893 +S11398E088420BD2069888210901401803C8230036 +S11398F0DBB21B01D218083203C2083A641CCEE75B +S113990009B0F0BDD55500208006002010270000C6 +S1139910D0550020805500200000000096300777C5 +S11399202C610EEEBA51099919C46D078FF46A704F +S113993035A563E9A395649E3288DB0EA4B8DC796F +S11399401EE9D5E088D9D2972B4CB609BD7CB17EEF +S1139950072DB8E7911DBF906410B71DF220B06ABF +S11399604871B9F3DE41BE847DD4DA1AEBE4DD6DCF +S113997051B5D4F4C785D38356986C13C0A86B64CF +S11399807AF962FDECC9658A4F5C0114D96C0663EF +S1139990633D0FFAF50D088DC8206E3B5E10694CCF +S11399A0E44160D5727167A2D1E4033C47D4044B0F +S11399B0FD850DD26BB50AA5FAA8B5356C98B242EF +S11399C0D6C9BBDB40F9BCACE36CD832755CDF456F +S11399D0CF0DD6DC593DD1ABAC30D9263A00DE519F +S11399E08051D7C81661D0BFB5F4B42123C4B3568F +S11399F09995BACF0FA5BDB89EB802280888055F0F +S1139A00B2D90CC624E90BB1877C6F2F114C68586E +S1139A10AB1D61C13D2D66B69041DC760671DB015C +S1139A20BC20D2982A10D5EF8985B1711FB5B6062E +S1139A30A5E4BF9F33D4B8E8A2C9077834F9000F6E +S1139A408EA8099618980EE1BB0D6A7F2D3D6D080E +S1139A50976C6491015C63E6F4516B6B62616C1CFE +S1139A60D83065854E0062F2ED95066C7BA5011B2E +S1139A70C1F4088257C40FF5C6D9B06550E9B712CE +S1139A80EAB8BE8B7C88B9FCDF1DDD62492DDA158E +S1139A90F37CD38C654CD4FB5861B24DCE51B53AAE +S1139AA07400BCA3E230BBD441A5DF4AD795D83DAE +S1139AB06DC4D1A4FBF4D6D36AE96943FCD96E34EE +S1139AC0468867ADD0B860DA732D0444E51D0333CE +S1139AD05F4C0AAAC97C0DDD3C710550AA410227DE +S1139AE010100BBE86200CC925B56857B3856F20AE +S1139AF009D466B99FE461CE0EF9DE5E98C9D9290E +S1139B002298D0B0B4A8D7C7173DB359810DB42E4D +S1139B103B5CBDB7AD6CBAC02083B8EDB6B3BF9A99 +S1139B200CE2B6039AD2B1743947D5EAAF77D29D25 +S1139B301526DB048316DC73120B63E3843B649405 +S1139B403E6A6D0DA85A6A7A0BCF0EE49DFF099305 +S1139B5027AE000AB19E077D44930FF0D2A3088775 +S1139B6068F2011EFEC206695D5762F7CB67658025 +S1139B7071366C19E7066B6E761BD4FEE02BD38925 +S1139B805A7ADA10CC4ADD676FDFB9F9F9EFBE8E85 +S1139B9043BEB717D58EB060E8A3D6D67E93D1A1C5 +S1139BA0C4C2D83852F2DF4FF167BBD16757BCA6A5 +S1139BB0DD06B53F4B36B248DA2B0DD84C1B0AAF45 +S1139BC0F64A0336607A0441C3EF60DF55DF67A8C5 +S1139BD0EF8E6E3179BE69468CB361CB1A8366BC55 +S1139BE0A0D26F2536E2685295770CCC03470BBBA5 +S1139BF0B91602222F260555BE3BBAC5280BBDB2A5 +S1139C00925AB42B046AB35CA7FFD7C231CFD0B544 +S1139C108B9ED92C1DAEDE5BB0C2649B26F263EC36 +S1139C209CA36A750A936D02A906099C3F360EEB44 +S1139C308567077213570005824ABF95147AB8E204 +S1139C40AE2BB17B381BB60C9B8ED2920DBED5E5E4 +S1139C50B7EFDC7C21DFDB0BD4D2D38642E2D4F134 +S1139C60F8B3DD686E83DA1FCD16BE815B26B9F6C4 +S1139C70E177B06F7747B718E65A0888706A0FFF24 +S1139C80CA3B06665C0B0111FF9E658F69AE62F8E4 +S1139C90D3FF6B6145CF6C1678E20AA0EED20DD7E4 +S1139CA05483044EC2B30339612667A7F71660D004 +S1139CB04D476949DB776E3E4A6AD1AEDC5AD6D944 +S1139CC0660BDF40F03BD83753AEBCA9C59EBBDE64 +S1139CD07FCFB247E9FFB5301CF2BDBD8AC2BACA14 +S1139CE03093B353A6A3B4240536D0BA9306D7CD84 +S1139CF02957DE54BF67D9232E7A66B3B84A61C4A4 +S1139D00021B685D942B6F2A37BE0BB4A18E0CC363 +S1139D101BDF055A8DEF022DF0B590B00120010034 +S1139D206A469170DA4A04920499C96A0423DB43AF +S1139D3019406C46A478A40004252C400C430B94D1 +S1139D400B99049CE16201006C46617003920399D3 +S1139D50C96A0124A1436C46647804400C430A9404 +S1139D600A99039CE16200210C006D462C7002925A +S1139D70029AD26A13406A4612789200042422405E +S1139D801A430992099A029BDA62CB4A0892CB4A97 +S1139D900792089B079C23660300C94C0194019C0D +S1139DA024680F25AC431D00EDB22D072D0F25436C +S1139DB00695069C019D2C60C24CC34D0595059DDE +S1139DC08026AC51C14D2D682D0EAD07AD0FEDB2FF +S1139DD0022D2AD10B006C462370BD4B5D68BD4C2F +S1139DE02C406D462D782D02F02636012E40264358 +S1139DF00296029C5C600C00B44D0195019E36688D +S1139E00B54F3740BC462600F6B23704C026B6022A +S1139E103E4067463E43019F3E602B001B681B0E7D +S1139E209B079B0FDBB2002BF7D103000092009C31 +S1139E30E4680C25AC431D00EDB2AD000C262E40A9 +S1139E4026430196019C009DEC6004001500EE6819 +S1139E500127BE432700FFB207403743EF601300DA +S1139E601B6A9C0803002340DBB2002BF7D00B00D5 +S1139E706C4663710892089B5B690124A3436C469A +S1139E80647904401C430F940F9B089C63610B008E +S1139E906C4623710792079B9B691024A3436C466D +S1139EA02479240110252C401C430E940E9B079CFE +S1139EB0A3610B006C46E3700692069B5C69874BBA +S1139EC023406C46E4782402C025AD0025401D43A0 +S1139ED00D950D9B069C636150236C46A3700592FF +S1139EE0059B5B69FE24A3436C46A4786400FE25AD +S1139EF025401D430C950C9B059C63610B006C462F +S1139F0063700492049B5C69754B23406C466478CF +S1139F10A4028025ED002C401C430B940B9B049C55 +S1139F20636104231C006D462C700392039C6569D5 +S1139F306C4C2C406D462D78ED02E026B6012E4087 +S1139F4026430A960A9C039D6C6104000292029DBA +S1139F506D690126B5432600F6B206402E430996E4 +S1139F60099D029E7561FA256D015F4E35605F4D56 +S1139F7029605F4E05273760346880277F02BC4222 +S1139F80FAD33360584B1960296013001C6A03002C +S1139F902340DBB2002BF8D002246B461C71554BD6 +S1139FA00693069DC826AE594B4D35406E4636790C +S1139FB03704C026B6023E402E430896089D069EEE +S1139FC0C827F55109256E46F5700593059DC826E9 +S1139FD0AD59404E2E400296029D6E46F6783702E9 +S1139FE0F02636013E402E430296029D059EC82768 +S1139FF0F55105006E46B5700493049BC8255B5962 +S113A0001025AB436D46AD782D01102635401D4318 +S113A0100795079B049DC826AB516B4658702C4D81 +S113A0206B682C4818406B465B781E02F0231B01BA +S113A030334003436B606846047024480390039CD8 +S113A0402668254C34406E4636783704C026B6025E +S113A0503E402643039C266003001B681B0E9B079F +S113A0609B0FDBB2022BF7D10B00154C0094009C24 +S113A07024680F25AC431D00EDB22D072D0F254399 +S113A0800295029C009D2C600C000568114E01E0B5 +S113A09000F005402E402500EDB22F02F0252D01E1 +S113A0A03D40354305600191019E1666064E8027AA +S113A0B0F15110B0F0BD00BF2020961900E0064019 +S113A0C000E406405245535500F0064000E80640BF +S113A0D000000240FFF0FFFFFFFFFCFFFFFCFFFF5B +S113A0E0FFFBFFFFFFC7FFFF14E000E018E000E004 +S113A0F010E000E000F80640002202604160012305 +S113A10003724272704770B504000E001500B8481F +S113A110215AB8482018FFF7EFFF7820205C012867 +S113A12006D02A0092B2310020001830FBF71EFA44 +S113A13070BDFEB505000E001400082100226F4614 +S113A1403800FAF7D7FF2000C0B2782805D0A84815 +S113A150295AA8482818FFF7CFFF7920285C00283F +S113A16014D02000C0B211280FD02000C0B2122891 +S113A1700BD02000C0B2312807D02000C0B27E2806 +S113A18003D02000C0B27F2800D10AE068467F21B6 +S113A1900170467084700322694628001830FBF76A +S113A1A0E5F9F7BDF7B5FFB085B0050000206946B5 +S113A1B0488000206946C8800026002069468880BF +S113A1C00024002069460870802189000020029044 +S113A1D004AF029A3800FAF78DFF86A80088A968B0 +S113A1E07A22AA5CD2008918497889B2884205D2B9 +S113A1F0132222212800FFF79CFFF6E086A800889E +S113A200401EC00705D5132222212800FFF791FF25 +S113A210EBE086A800884008694648806846408884 +S113A220002805D1132222212800FFF782FFDCE059 +S113A230622004A9320092B28854761C01273800A7 +S113A24086A9098880B2884200D3BEE08598390087 +S113A25089B2405C000285993A0092B28918497823 +S113A26008436946C880002001006A461170040052 +S113A2702000A98A80B2884200D3A0E02869210086 +S113A28089B214224A43805A6946C988884200D058 +S113A29093E0A8782969220092B214235343C91881 +S113A2A00979884205D0332222212800FFF741FF93 +S113A2B09BE0300080B22969220092B214235343F8 +S113A2C0C91889894018801C4B49884205DB14222F +S113A2D022212800FFF72DFF87E02869210089B299 +S113A2E014224A4380188078052809D0687829699F +S113A2F0220092B214235343C918C978884205D264 +S113A300222222212800FFF714FF6EE02869210091 +S113A31089B214224A4380188289D2B22869210062 +S113A32089B214234B43C0188168280005002B69A7 +S113A3309C4623009BB214205843634618180369B3 +S113A3402800984701206946087004A885993A00B6 +S113A35092B2895C320092B28154761C85993A009B +S113A36092B289184978320092B28154761C6846B8 +S113A37086802869210089B214224A438018808982 +S113A38003902869210089B214224A438018806806 +S113A390029004A8694689884618039A02993000F5 +S113A3A0FAF79AFE684680882969220092B214233B +S113A3B05343C9188989461801E0641C58E7684664 +S113A3C00078002801D0BF1C39E7684600780028CF +S113A3D006D0320092B204A92800FFF794FE04E0EC +S113A3E0312222212800FFF7A4FE7FB008B0F0BD7F +S113A3F08C080000A808000001020000002202608E +S113A4004160012303724272704770B504000E006C +S113A41015009D48215A9D482018FFF7EFFF78202A +S113A420205C012806D02A0092B2310020001830A6 +S113A430FBF79CF870BDFEB505000E001400082162 +S113A44000226F463800FAF755FE2000C0B2782883 +S113A45005D08D48295A8D482818FFF7CFFF792059 +S113A460285C002814D02000C0B211280FD020008E +S113A470C0B212280BD02000C0B2312807D020006F +S113A480C0B27E2803D02000C0B27F2800D10AE0E9 +S113A49068467F2101704670847003226946280053 +S113A4A01830FBF763F8F7BD704770477047704783 +S113A4B0F4B5FFB085B005000E00002738006946EA +S113A4C048803800694608703800694608710220DF +S113A4D069464870802189003A0004AC2000FAF7EC +S113A4E009FE84A80088A9687A22AA5CD200891887 +S113A4F0497889B2884205D213222F212800FFF718 +S113A5009AFFBDE06878012805D122222F21280076 +S113A510FFF791FFB4E070780002B1784018694603 +S113A5204880F078694608703C0020006946497804 +S113A530C0B2884223D256482100C9B214225143E2 +S113A540415A6A465288914217D12100C9B2142255 +S113A55051434118897800290ED02100C9B2142230 +S113A560514340188078A978884205D033222F219E +S113A5702800FFF760FF83E001E0641CD5E72000BA +S113A58069464978C0B2884205D331222F21280078 +S113A590FFF751FF74E004A86F21017071784170D6 +S113A5A0B1788170F178C17068460078002802D0D3 +S113A5B003281CD05FE036482100C9B2142251435D +S113A5C04118CF722100C9B21422514341180969BC +S113A5D000290BD02100C9B214225143401800694C +S113A5E08047042204A92800FFF70FFF48E0284F02 +S113A5F084A800882100C9B2142251437918097A29 +S113A600091D884205DA22222F212800FFF713FFB3 +S113A61036E001202100C9B2142251437918C872CE +S113A6202000C0B2142148433818007A0390301D2A +S113A63002902000C0B214214843381840680190A9 +S113A640039A02990198FAF747FD01982000C0B2D5 +S113A650142148433818C06800280BD02000C0B229 +S113A660142148433818C0688047042204A92800EC +S113A670FFF7CBFE04E031222F212800FFF7DBFE99 +S113A6807FB006B0F0BD00008C080000A8080000F0 +S113A690E407002000220260416001230372427239 +S113A6A0704770B504000E0015002548215A25484E +S113A6B02018FFF7EFFF7820205C012806D02A003D +S113A6C092B2310020001830FAF750FF70BDFEB589 +S113A6D005000E001400082100226F463800FAF726 +S113A6E009FD2000C0B2782805D01548295A15481C +S113A6F02818FFF7CFFF7920285C002814D0200009 +S113A700C0B211280FD02000C0B212280BD02000F4 +S113A710C0B2312807D02000C0B27E2803D0200068 +S113A720C0B27F2800D10AE068467F2101704670DC +S113A73084700322694628001830FAF717FFF7BD22 +S113A7408C080000A808000010B50024FCF724FDC4 +S113A750801C10BD10B5010000200300012213006D +S113A760DBB2052B0CDA04239B1ADB000C00DC4063 +S113A770002C03D005239B1A180001E0521CEEE7BD +S113A780C0B210BDF7B586B00020050001006A46CE +S113A79011700400070001006A4651700290010024 +S113A7A06A46D170060006994978012905D122220A +S113A7B034210698FFF78BFFA4E069460B8C0699B9 +S113A7C08A689446069A7A21515CC90062465118F7 +S113A7D0497889B28B4205D2132234210698FFF7B7 +S113A7E076FF8FE0079989780907090F6A46117087 +S113A7F007998978C9B209096A4691706946097846 +S113A80000290BD069460978052907D26946897859 +S113A810002903D069468978052905D331223421DA +S113A8200698FFF754FF6DE001000A006B461B78A1 +S113A830D2B29A4208D22A02079B0D00EDB25B19EC +S113A840DB78D518491CF0E7070038006946897899 +S113A850C0B288420BD2210207986A4612783B00A4 +S113A860DBB2D2188018C0780C187F1CEDE7002CDE +S113A87005D1222234210698FFF729FF42E000F097 +S113A88083F8280000F08EF8200000F08EF80120F4 +S113A89000F091F8FFF758FF02900298FFF75AFF73 +S113A8A06946487003A87421320092B28154761C20 +S113A8B0694649780901320092B28154761C69468E +S113A8C08E800126694649783200D2B291420FD374 +S113A8D002996A465278921BD200D1406A46928805 +S113A8E0815469468988491C6A469180761CE9E747 +S113A8F021002800FCF7CAFE6846828803A906984E +S113A900FFF7CFFE09B0F0BD0022026041600123D1 +S113A910037242727047FEB505000E001400082150 +S113A92000226F463800FAF7E5FB2000C0B2782811 +S113A93005D06348295A63482818FFF7E5FF7920B2 +S113A940285C002814D02000C0B211280FD02000A9 +S113A950C0B212280BD02000C0B2312807D020008A +S113A960C0B27E2803D02000C0B27F2800D10AE004 +S113A97068467F210170467084700322694628006E +S113A9801830FAF7F3FDF7BD002001004E4A1170AC +S113A99001004E4A11704E4908604E4908604E4904 +S113A9A0086070474B49086070474B49086070471E +S113A9B0494800687047494908707047474800781B +S113A9C07047434800687047F6B583B005000A2114 +S113A9D000226C462000FAF78DFB6878012805D127 +S113A9E0222236212800FFF796FF66E06846008A97 +S113A9F0A9687A22AA5CD2008918497889B2884267 +S113AA0005D2132236212800FFF785FF55E033488D +S113AA100078012802D0022844D049E02A4C039847 +S113AA2040782070294E2078317888420BD02078E5 +S113AA303178491CC9B2884205D0732236212800D6 +S113AA40FFF769FF39E0224F2348006839686A46F6 +S113AA50128A8918891E884205D27122362128005B +S113AA60FFF759FF29E020783178491CC9B28842A0 +S113AA7017D122786846018A891E89B20398801CFE +S113AA80FCF722FE012805D138686946098A401876 +S113AA90801E3860207830706846762101702178F5 +S113AAA041700AE0312236212800FFF734FF04E028 +S113AAB0242236212800FFF72EFF05B0F0BD000048 +S113AAC08C080000A8080000D8550020D9550020A3 +S113AAD0945500208C55002090550020D755002017 +S113AAE091490870704730B5010089B2142928DAF9 +S113AAF000218E4A0B000400A4B20C2565435419AE +S113AB00237103009BB20C245C4313191B1D1C7896 +S113AB10102525431D7003009BB20C245C431319BC +S113AB201B1D1C78402525431D7003009BB20C247B +S113AB305C431319D98003009BB20C245C431219A3 +S113AB40117230BD70B5010000231C001A001800FA +S113AB501C00A4B2142C10DA744C1D00ADB20C26E7 +S113AB606E43A41924796406640E22001400E4B22E +S113AB700C4200D0401C5B1CEAE780B270BDF2B509 +S113AB80010000242500230020002500ADB2142D6F +S113AB9039DA664D2600B6B20C277743EE193679BA +S113ABA033001E00F6B216422BD06E4636880700DC +S113ABB0BFB23F1DBE4223DB2600B6B20C2777434B +S113ABC0EE59360C0700BFB2CE55401C2600B6B273 +S113ABD00C277743EE59360A0700BFB2CE55401C06 +S113ABE02600B6B20C277743ED590600B6B28D5550 +S113ABF0401C5D066D0E0600B6B28D55401C00E08B +S113AC0001E0641CC1E780B2F2BDF0B5020000248B +S113AC102500230020002500ADB2142D33DA434D66 +S113AC202600B6B20C277743EE19367933000E00AE +S113AC30B6B20700BFB23F1DBE4224DB2600B6B247 +S113AC400C277743EE59360C0700BFB2D655401C8B +S113AC502600B6B20C277743EE59360A0700BFB276 +S113AC60D655401C2600B6B20C277743ED59060092 +S113AC70B6B29555401C5D066D0E0600B6B29555EC +S113AC80401C641CC7E780B2F0BD38B50400002046 +S113AC9005002100264A891A04D09D3918D02F397D +S113ACA035D03FE00500280080B214280FDA1F4891 +S113ACB0290089B20C224A438058802149038842E2 +S113ACC003D2280080B2FFF70EFF6D1CEBE729E0EA +S113ACD00500280080B2142818DA1448290089B223 +S113ACE00C224A4381588022D20391420CD329007A +S113ACF089B20C224A43805880210904884203D235 +S113AD00280080B2FFF7EFFE6D1CE2E70AE00500C1 +S113AD10280080B2142805DA280080B2FFF7E3FE89 +S113AD206D1CF5E731BD0000D4550020F406002069 +S113AD3033FFFF00010005000000000000000000D8 +S113AD4000000000090005000000000000000000F1 +S113AD500000000071720000AB7200002973000053 +S113AD6055750000217400001975000001000000F1 +S113AD7032070000DF070000B2070000AC320020F9 +S113AD8000020000AC340020200800000000000095 +S113AD90F55D0000AD5C00003200F4018813000092 +S113ADA001020304050607081A62040050000000AB +S113ADB0000000001B6304005000000000000000BD +S113ADC01603F00050000000000000001703F0001C +S113ADD050000000000000008873C0005000000014 +S113ADE0000000000100C10050000000000000004D +S113ADF00101C10050000000000000000121C10059 +S113AE0050000000000000000127C10050000000B5 +S113AE10000000000128C1005000000000000000F4 +S113AE200129C10050000000000000000131C100F0 +S113AE3050000000000000000041C100500000006C +S113AE40000000000151C10050000000000000009B +S113AE500063C10050000000000000000069C10050 +S113AE6050000000000000000181C10050000000FB +S113AE70000000000136C200500000000000000085 +S113AE800064C10050000000000000000067C10021 +S113AE90500000000000000092F0000088550020DF +S113AEA002000000A9A40000ABA4000020F00000F0 +S113AEB08A55002002000000ADA40000AFA40000E9 +S113AEC001FD0209000000006F8F0000F98F0000EF +S113AED0FB8F000002FD020900000000B990000091 +S113AEE0C9900000CB90000003FD0209000000009F +S113AEF04B9000005B9000005D90000004FD02098F +S113AF0000000000399100003B9100003D910000D9 +S113AF1086F10601000000009855002001000000A1 +S113AF209770000087F10601000000009955002089 +S113AF30080000009D70000080F106010000000080 +S113AF40A1550020080000007970000091F106016D +S113AF5000000000A955002018000000BD7000008A +S113AF6093F1060100000000C15500200400000018 +S113AF70F970000095F1060100000000C55500209D +S113AF8008000000157100000022026041600123E6 +S113AF9003724272704770B504000E0015007E48BB +S113AFA0215A7E482018FFF7EFFF7820205C012803 +S113AFB006D02A0092B2310020001830FAF7D6FAEF +S113AFC070BDFEB505000E001400082100226F4676 +S113AFD03800FAF78FF82000C0B2782805D06E4800 +S113AFE0295A6E482818FFF7CFFF7920285C0028DB +S113AFF014D02000C0B211280FD02000C0B21228F3 +S113B0000BD02000C0B2312807D02000C0B27E2867 +S113B01003D02000C0B27F2800D10AE068467F2117 +S113B0200170467084700322694628001830FAF7CC +S113B0309DFAF7BDF6B583B004000E000821002781 +S113B0403A0001AD2800FAF755F83800694648700F +S113B0506846008AA1687A22A25CD20089184978DD +S113B06089B2884205D2132228212000FFF7A9FFC4 +S113B0708EE06078012805D1222228212000FFF7E4 +S113B080A0FF85E070784006400E69460870B578E8 +S113B09001A8682101706946097841706846007802 +S113B0A0002805D0022838D01CD3032850D06AE0E9 +S113B0B02800C0B2012807D02800C0B2022803D05B +S113B0C02800C0B2032807D135480770022201A91D +S113B0D02000FFF760FF04E0312228212000FFF761 +S113B0E070FF55E02800C0B2012807D02800C0B284 +S113B0F0022803D02800C0B2032808D1012028491F +S113B1000870022201A92000FFF745FF04E0312264 +S113B11028212000FFF755FF3AE02800C0B201289B +S113B12007D02800C0B2022803D02800C0B20328E8 +S113B13008D102201A490870022201A92000FFF751 +S113B1402AFF04E0312228212000FFF73AFF1FE004 +S113B1502800C0B2012807D02800C0B2022803D0BA +S113B1602800C0B2032808D103200D490870022228 +S113B17001A92000FFF70FFF04E03122282120005D +S113B180FFF71FFF04E0122228212000FFF719FF18 +S113B19005B0F0BD000000008C080000A808000005 +S113B1A0D6550020002202604160012303724272DE +S113B1B0704770B504000E0015002548215A254833 +S113B1C02018FFF7EFFF7820205C012806D02A0022 +S113B1D092B2310020001830FAF7C8F970BDFEB5FC +S113B1E005000E001400082100226F463800F9F70C +S113B1F081FF2000C0B2782805D01548295A154887 +S113B2002818FFF7CFFF7920285C002814D02000ED +S113B210C0B211280FD02000C0B212280BD02000D9 +S113B220C0B2312807D02000C0B27E2803D020004D +S113B230C0B27F2800D10AE068467F2101704670C1 +S113B24084700322694628001830FAF78FF9F7BD95 +S113B2508C080000A8080000F6B585B005000E00B3 +S113B260002420006946088020006946488008219F +S113B270220003AF3800F9F73DFF6846008BA96848 +S113B2807A22AA5CD2008918497889B2884205D208 +S113B29013222E212800FFF7A2FF82E0707800021B +S113B2A0B17808436946088003A86E21017071785B +S113B2B04170B17881702000A98A80B288426BD233 +S113B2C02869210089B214224A43805A69460988B0 +S113B2D088425FD12869210089B214224A43801828 +S113B2E0007900280FD0A8782969220092B214238B +S113B2F05343C9180979884205D0332222212800F2 +S113B300FFF76DFF4DE06846008BC01E29692200DF +S113B31092B214235343C9188989884205D0132251 +S113B3202E212800FFF75BFF3BE02869210089B24A +S113B33014224A4380188078032809D06878296940 +S113B340220092B214235343C918C978884205D203 +S113B35022222E212800FFF742FF22E02869210043 +S113B36089B214224A43801880890290F01C01900B +S113B3702869210089B214224A4380188768029AF6 +S113B38001993800F9F7A8FE032203A92800FFF762 +S113B39010FF06E0641C8EE731222E212800FFF7FF +S113B3A01EFF07B0F0BD00000022026041600123CF +S113B3B003724272704770B504000E0015002548F0 +S113B3C0215A25482018FFF7EFFF7820205C012838 +S113B3D006D02A0092B2310020001830FAF7C6F8DD +S113B3E070BDFEB505000E001400082100226F4652 +S113B3F03800F9F77FFE2000C0B2782805D0154840 +S113B400295A15482818FFF7CFFF7920285C00280F +S113B41014D02000C0B211280FD02000C0B21228CE +S113B4200BD02000C0B2312807D02000C0B27E2843 +S113B43003D02000C0B27F2800D10AE068467F21F3 +S113B4400170467084700322694628001830FAF7A8 +S113B4508DF8F7BD8C080000A8080000F6B5FFB011 +S113B46082B0070000221000694648701000694647 +S113B470087010006946488015008021890001ACDD +S113B4802000F9F737FE82A80088B9687A22BA5CEE +S113B490D2008918497889B2884205D21322192129 +S113B4A03800FFF79EFF75E07F2681984078304092 +S113B4B06946487001AC5920207068464078607035 +S113B4C068464078012804D0022827D00A2844D0AE +S113B4D05BE082A80088032805D0132219213800D4 +S113B4E0FFF77FFF56E081988078694608706846C8 +S113B4F00078FFF727FB69464880A6700120E070BA +S113B5006846408880B2000A2071684640886071AD +S113B510062201A93800FFF74EFF3BE082A800880D +S113B520032805D0132219213800FFF75AFF31E010 +S113B5308198807869460870A67068460278FF2171 +S113B540FE31E01CFFF71BFB05002A00D21C92B25F +S113B55001A93800FFF72FFF1CE082A80088022809 +S113B56005D0132219213800FFF73BFF12E0FF2119 +S113B570FE31E01CFFF749FB05002A00D21C92B201 +S113B58001A93800FFF717FF04E01222192138003F +S113B590FFF727FF7FB004B0F0BD00000022026077 +S113B5A04160012303724272704770B504000E00BB +S113B5B015006348215A63482018FFF7EFFF7820ED +S113B5C0205C012806D02A0092B2310020001830F5 +S113B5D0F9F7CCFF70BDFEB505000E00140008217C +S113B5E000226F463800F9F785FD2000C0B27828A4 +S113B5F005D05348295A53482818FFF7CFFF79201C +S113B600285C002814D02000C0B211280FD02000DC +S113B610C0B212280BD02000C0B2312807D02000BD +S113B620C0B27E2803D02000C0B27F2800D10AE037 +S113B63068467F21017046708470032269462800A1 +S113B6401830F9F793FFF7BDF2B582B00500170083 +S113B6500821002422006E463000F9F74BFD380023 +S113B660A9687A22AA5CD2008918497880B289B282 +S113B670884205D0132210212800FFF7ACFF5EE0BA +S113B680029840784606760E68465021017046704E +S113B6902D49695A89B2090A81702B49695AC170C6 +S113B6A02A49695A89B2090A01712849695A4171BA +S113B6B0FDF748FC3000C0B2012806D03AD3032875 +S113B6C00BD018D3042827D034E0AC706E70062257 +S113B6D069462800FFF769FF31E0AC706E700622FE +S113B6E069462800FFF761FF1548295A15482818AC +S113B6F0FFF754FF23E0AC706E7006226946280001 +S113B700FFF753FF0E48295A0E482818FFF746FF43 +S113B7100120FBF75FFF12E0AC706E7006226946F1 +S113B7202800FFF742FF0648295A06482818FFF761 +S113B73035FF04E0122210212800FFF74CFFF7BD6B +S113B7408C080000A8080000880800008A0800008F +S113B750210400004D0400002D050000000000003D +S113B7604F05000045060000EF07000045080000F3 +S113B770150900006B0900003D0A0000930A00004F +S113B780610B0000B70B0000810C0000D70C000017 +S113B790A10D0000F70D0000C50E00001F0F0000F2 +S113B7A0810F0000B90F0000E90F00002310000012 +S113B7B057100000F1100000AD1100000313000049 +S113B7C069160000000000007316000097160000C0 +S113B7D0C1160000E51600000F170000000000006D +S113B7E01B1700006F170000211800004B18000001 +S113B7F0751800009F180000C9180000F318000015 +S113B8001D19000047190000711900009B19000060 +S113B810C5190000931A0000211C00008D1C0000B3 +S113B820911D0000011E0000E11E0000231F000006 +S113B8306F1F0000B11F0000012000004320000022 +S113B8408F200000D12000001D2100005F21000096 +S113B850B1210000F1210000452200006B2200000C +S113B86095220000BB220000E52200000B2300000B +S113B870352300005B23000085230000AB23000078 +S113B880D5230000FB23000025240000B32400007E +S113B890CB250000F12500001B2600007F260000B8 +S113B8A029270000000000003327000000000000EA +S113B8B03D2700000000000047270000C5270000C6 +S113B8C0AF2800002D290000172A0000512A00008B +S113B8D0AD2A0000E72A00003F2B0000672B000080 +S113B8E0002202604160012303724272704770B506 +S113B8F004000E0015002548215A25482018FFF79A +S113B900EFFF7820205C012806D02A0092B2310093 +S113B91020001830F9F72AFE70BDFEB505000E00B0 +S113B9201400082100226F463800F9F7E3FB2000D9 +S113B930C0B2782805D01548295A15482818FFF7A9 +S113B940CFFF7920285C002814D02000C0B2112831 +S113B9500FD02000C0B212280BD02000C0B2312872 +S113B96007D02000C0B27E2803D02000C0B27F28B8 +S113B97000D10AE068467F2101704670847003227A +S113B980694628001830F9F7F1FDF7BD8C0800006E +S113B990A8080000F2B582B00400160000221500C9 +S113B9A008216F463800F9F7A5FB6078012805D116 +S113B9B0222237212000FFF7B0FF40E03000A168C9 +S113B9C07A22A25CD2008918497880B289B288426E +S113B9D005D2132237212000FFF79FFF2FE07720A5 +S113B9E069462A0092B288546D1C2F00FEF7E6FFC8 +S113B9F0012802D0022814D019E0FEF7E2FF050066 +S113BA00FEF7D6FF854205D0132237212000FFF729 +S113BA1084FF11E03A0092B269462000FFF767FF05 +S113BA200AE0312237212000FFF777FF04E02422C7 +S113BA3037212000FFF771FF0020FEF7BCFFF7BDA0 +S113BA40002202604160012303724272704770B5A4 +S113BA5004000E0015002548215A25482018FFF738 +S113BA60EFFF7820205C012806D02A0092B2310032 +S113BA7020001830F9F77AFD70BDFEB505000E0000 +S113BA801400082100226F463800F9F733FB200028 +S113BA90C0B2782805D01548295A15482818FFF748 +S113BAA0CFFF7920285C002814D02000C0B21128D0 +S113BAB00FD02000C0B212280BD02000C0B2312811 +S113BAC007D02000C0B27E2803D02000C0B27F2857 +S113BAD000D10AE068467F21017046708470032219 +S113BAE0694628001830F9F741FDF7BD8C080000BD +S113BAF0A8080000FEB504000F001600082100226B +S113BB0001AD2800F9F7F6FAFF253100A0687A2282 +S113BB10A25CD2008018407889B280B2814205D0FC +S113BB20132211212000FFF7A8FF37E078784006A0 +S113BB30400E6946087001A85121017069460978D0 +S113BB404170857068460078012804D021D3032809 +S113BB5015D00AD31DE0032201A92000FFF777FFC7 +S113BB6001210120FBF748FD18E0032201A9200070 +S113BB70FFF76DFF02210120FBF73EFD0EE00322DB +S113BB8001A92000FFF763FF03210120FBF734FD27 +S113BB9004E0122211212000FFF76FFFF7BD00001F +S113BBA0002202604160012303724272704770B543 +S113BBB004000E0015002548215A25482018FFF7D7 +S113BBC0EFFF7820205C012806D02A0092B23100D1 +S113BBD020001830F9F7CAFC70BDFEB505000E0050 +S113BBE01400082100226F463800F9F783FA200078 +S113BBF0C0B2782805D01548295A15482818FFF7E7 +S113BC00CFFF7920285C002814D02000C0B211286E +S113BC100FD02000C0B212280BD02000C0B23128AF +S113BC2007D02000C0B27E2803D02000C0B27F28F5 +S113BC3000D10AE068467F210170467084700322B7 +S113BC40694628001830F9F791FCF7BD8C0800000C +S113BC50A8080000FEB504000E001500082100220B +S113BC606F463800F9F746FA2800A1687A22A25CE8 +S113BC70D2008918497880B289B2884205D2132249 +S113BC8085212000FFF7A9FF2DE06078012805D168 +S113BC90222285212000FFF7A0FF24E070784706C8 +S113BCA07F0E6846C521017047703800C0B2012874 +S113BCB002D0022809D011E00120FEF711FF022270 +S113BCC069462000FFF773FF0DE00020FEF708FF30 +S113BCD0022269462000FFF76AFF04E01222852150 +S113BCE02000FFF77AFFF7BD0022026041600123C4 +S113BCF003724272704770B504000E001500444888 +S113BD00215A44482018FFF7EFFF7820205C0128CF +S113BD1006D02A0092B2310020001830F9F726FC30 +S113BD2070BDFEB505000E001400082100226F4608 +S113BD303800F9F7DFF92000C0B2782805D034487C +S113BD40295A34482818FFF7CFFF7920285C0028A7 +S113BD5014D02000C0B211280FD02000C0B2122885 +S113BD600BD02000C0B2312807D02000C0B27E28FA +S113BD7003D02000C0B27F2800D10AE068467F21AA +S113BD800170467084700322694628001830F9F760 +S113BD90EDFBF7BDF7B504000D00002216000821E5 +S113BDA06F463800F9F7A6F968460089A1687A2237 +S113BDB0A25CD2008918497889B2884205D013223E +S113BDC014212000FFF7ADFF20E068780004304321 +S113BDD0A97809020143EE780E435420694608709D +S113BDE030000D49401A03D09D3801D02F3808D1B6 +S113BDF03000FEF74AFF012269462000FFF77BFF6F +S113BE0004E0312214212000FFF78BFFF7BD00006E +S113BE108C080000A808000033FFFF000022026025 +S113BE204160012303724272704770B504000E0032 +S113BE3015002548215A25482018FFF7EFFF7820E0 +S113BE40205C012806D02A0092B23100200018306C +S113BE50F9F78CFB70BDFEB505000E001400082137 +S113BE6000226F463800F9F745F92000C0B278285F +S113BE7005D01548295A15482818FFF7CFFF79200F +S113BE80285C002814D02000C0B211280FD0200054 +S113BE90C0B212280BD02000C0B2312807D0200035 +S113BEA0C0B27E2803D02000C0B27F2800D10AE0AF +S113BEB068467F2101704670847003226946280019 +S113BEC01830F9F753FBF7BD8C080000A8080000F0 +S113BED0FEB504000E001500082100226F4638004C +S113BEE0F9F708F92800A1687A22A25CD20089181F +S113BEF0497880B289B2884205D013223E212000BD +S113BF00FFF7A9FF15E0707847067F0E3800C0B22E +S113BF10002809D168467E210170477002226946D3 +S113BF202000FFF782FF04E012223E212000FFF7E9 +S113BF3092FFF7BDF0B587B0254802902548264901 +S113BF400691264901912649264A0592264A274BFD +S113BF500493274B0093274B274C0394069C84425D +S113BF6007D00478029D2C70029C641C0294401C2F +S113BF70F4E7059C8C4207D00C78019D2C70019C41 +S113BF80641C0194491CF4E7049C944203D00024EB +S113BF901470521CF8E7039C9C4207D01C78009D47 +S113BFA02C705B1C009C641C0094F4E70024134D6B +S113BFB0AD08AC4207D2124DA600AD59114EA700F0 +S113BFC0F551641CF3E70F4D0F4E356007B0F0BD1B +S113BFD08006002034AD000088AF0000000000207F +S113BFE01C880000988E000000200020DA550020F4 +S113BFF0000000000000000000000000000000003D +S113C000000000000000000008ED00E01002010044 +S113C01049B6000011020100F5BA00002702010030 +S113C020859600002803010035B000003E0201009F +S113C030D1BE00008502010055BC000022030000AF +S113C040A5A100002E04000059B200001404000051 +S113C05095BD0000190301005DB400002F0300002A +S113C060B1A40000310401003F9100003405000038 +S113C07085A7000036020000C9A9000037010000AE +S113C08095B9000072B60021002200230024002587 +S113C09000260027B846B946BA46BB46BC460A49FC +S113C0A00A4A521A013A05DD0020042308601944A3 +S113C0B0043AFBDA06488546064880470648804726 +S113C0C062B6F9F7ABFFFEE700000020EF5B00204B +S113C0D0F05B0020199D000035BF00000000010046 +S113C0E0320700000001080001000000FFFFFFFF0D +S113C0F001000100DF07000000010800010000004A +S113C100FFFFFFFF02000100B2070000000008006B +S113C11000000000FFFFFFFF0300010034020000E5 +S113C1200000080000000000FFFFFFFF03000113F0 +S113C13002401D010B000600070008000C001C0053 +S113C140180017040E000F4004033D0121503E5413 +S113C1503F4C3C052300240025002600270028002E +S113C16029002A002C002D002E002F003000310061 +S113C170320033002B003400000000004669727363 +S113C18074206672616D652073686F756C64206ECF +S113C1906F7420757365206D756C7469706C65209F +S113C1A06672616D65207472616E736D6973736913 +S113C1B06F6E2E004D756C74692D6672616D65200D +S113C1C0726573706F6E736520746F6F206C61722B +S113C1D0676520666F7220726563656976696E674C +S113C1E0206275666665722E000000004D657373EB +S113C1F06167652073697A6520746F6F206C617262 +S113C20067652E205365742061206C6172676572C6 +S113C2102073656E64206275666665720A000000AC +S113C22041626F72742070726576696F7573206DE8 +S113C2306573736167652C207472616E736D6973C5 +S113C24073696F6E20696E2070726F6772657373A5 +S113C2502E0A0000000000000000000000000000A2 +S113C26000000000000000000000000000000000CA +S113C27000000000000000000000000000000000BA +S113C2800000000053696E676C652D6672616D6510 +S113C290206C656E67746820746F6F20736D616CB9 +S113C2A06C206F7220746F6F206C617267652E0052 +S113C2B04669727374206672616D652073686F7568 +S113C2C06C64206265203820627974657320696E1D +S113C2D0206C656E6774682E00000000436F6E73F7 +S113C2E065637574697665206672616D6520746F27 +S113C2F06F2073686F72742E00000000466C6F77B5 +S113C30020636F6E74726F6C206672616D65207449 +S113C3106F6F2073686F72742E00000001000000BC +S113C32002000000040000000800000010000000EB +S113C33020000000400000008000000000F00DF824 +S113C340002801D000BF00BF00BF00BF002000BF15 +S113C35000BFF9F763FE00F002F80120704780B5D2 +S113C36000F002F801BD00000746384600F002F86C +S113C370FBE7000080B500BF00BF024A110018208F +S113C380ABBEFBE7260002000548014603B468463D +S113C39080F3098800BF00BF00BF00BFFFF7CEFFD6 +S113C3A0A5EDF5FE2D2D2D2D2D4A756D70546F4183 +S113C3B070702D2D2D2D2D0A000000002D2D2D2DFA +S113C3C02D494E544F20424F4F542D2D2D2D2D0AC3 +S113C3D00000000025303464203A204D5F535F4351 +S113C3E054524C203D20307825780A0030313233C5 +S113C3F03435363738394142434445465465726DC5 +S113C400696E616C000000005345474745520000C7 +S10BC410010203044D535751CE +S903C389B0 diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_dtc.c b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_dtc.c new file mode 100644 index 0000000..346c288 --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_dtc.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_dtc.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define DTCG_EMISSION_START (0x00000000ul) /* 24Bit DTC define ISO-15031-6 DTC + ISO-15031-6 Failure Type, ISO14229-1 format */ +#define DTCG_EMISSION_END (0x000FFFFFul) +#define DTCG_POWERTRAIN_START (0x00100000ul) +#define DTCG_POWERTRAIN_END (0x003FFFFFul) +#define DTCG_CHASSIS_START (0x00400000ul) +#define DTCG_CHASSIS_END (0x007FFFFFul) +#define DTCG_BODY_START (0x00800000ul) +#define DTCG_BODY_END (0x00BFFFFFul) +#define DTCG_NETWORK_START (0x00C00000ul) +#define DTCG_NETWORK_END (0x00FFFFFFul) + +#define FAULTDT_MAX (127) /* refers to ISO14229-1 D.6 */ +#define FAULTDT_MIN (-128) /* refers to ISO14229-1 D.6 */ +#define AGING_MAX (40) /* refers to ISO14229-1 D.7 */ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/* the meaning of UDS DTC value refers to ISO 15031-6 */ +static Uds_DtcType udsDtcTable[DTC_MAX_COUNT] = { + {0x04621A, 0x50, 0x00, 0x00}, /* P0462 fuel level sensor "A" circuit resistance low */ + {0x04631B, 0x50, 0x00, 0x00}, /* P0463 fuel level sensor "A" circuit resistance high */ + {0xF00316, 0x50, 0x00, 0x00}, /* U3003 battery voltage low */ + {0xF00317, 0x50, 0x00, 0x00}, /* U3003 battery voltage high */ + {0xC07388, 0x50, 0x00, 0x00}, /* U0073 control module communication bus off */ + {0xC10001, 0x50, 0x00, 0x00}, /* U0100 lost communication with ECM/PCM "A" */ + {0xC10101, 0x50, 0x00, 0x00}, /* U0101 lost communication with TCM */ + {0xC12101, 0x50, 0x00, 0x00}, /* U0121 lost communication with ABS control module */ + {0xC12701, 0x50, 0x00, 0x00}, /* U0127 lost communication with tire pressure monitor module */ + {0xC12801, 0x50, 0x00, 0x00}, /* U0128 lost communication with park brake control module */ + {0xC12901, 0x50, 0x00, 0x00}, /* U0129 lost communication with brake system control module */ + {0xC13101, 0x50, 0x00, 0x00}, /* U0131 lost communication with power sterring control module */ + {0xC14100, 0x50, 0x00, 0x00}, /* U0141 lost communication with body control module "A" */ + {0xC15101, 0x50, 0x00, 0x00}, /* U0151 lost communication with restraints control module */ + {0xC16300, 0x50, 0x00, 0x00}, /* U0163 lost communication with navigation control module */ + {0xC16900, 0x50, 0x00, 0x00}, /* U0169 lost communication with sunroof control module */ + {0xC18101, 0x50, 0x00, 0x00}, /* U0181 lost communication with headlamp leveling control module */ + {0xC23601, 0x50, 0x00, 0x00}, /* U0236 lost communication with column lock module */ + {0xC16400, 0x50, 0x00, 0x00}, /* U0164 lost communication with HVAC control module */ + {0xC16700, 0x50, 0x00, 0x00}, /* U0167 lost communication with vehicle immobilizer control module */ +}; + +static bool dtcOffCtrl = false; + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void Uds_SetDtcOffCtrl(bool val) +{ + dtcOffCtrl = val; +} + +bool Uds_GetDtcOffCtrlState(void) +{ + return dtcOffCtrl; +} + +void Uds_ClearDtcByDtcIndex(uint16_t dtcIndex) +{ + if(dtcIndex >= DTC_MAX_COUNT) + { + return; + } + + udsDtcTable[dtcIndex].dtcStatus.all = 0; + udsDtcTable[dtcIndex].dtcStatus.bit.testNcmpSlc = 1; + udsDtcTable[dtcIndex].dtcStatus.bit.testNcmpToc = 1; + + udsDtcTable[dtcIndex].faultDtCnt = 0; + udsDtcTable[dtcIndex].AgingCnt = 0; +} + +void Uds_LoadDtc(void) +{ + /* code implemented by the user */ +} + +void Uds_SaveDtc(void) +{ + /* code implemented by the user */ +} + +uint16_t Uds_GetDtcNumberByStatusMask(uint8_t mask) +{ + uint16_t dtcCnt = 0; + uint8_t dtcState = 0; + uint16_t dtcNum = 0; + + for(dtcCnt = 0; dtcCnt < DTC_MAX_COUNT; dtcCnt++) + { + dtcState = (udsDtcTable[dtcCnt].dtcStatus.all & DTC_AVAILABILITY_STATUS_MASK); + if(0 != (dtcState & mask)) + { + dtcNum++; + } + } + + return dtcNum; +} + +uint16_t Uds_GetDtcByStatusMask(uint8_t *pDtcBuf, uint16_t bufLen, uint8_t mask) +{ + uint16_t dtcCnt = 0; + uint8_t dtcState = 0; + uint16_t dtcDlc = 0; + + for(dtcCnt = 0; dtcCnt < DTC_MAX_COUNT; dtcCnt++) + { + dtcState = udsDtcTable[dtcCnt].dtcStatus.all; + if(0 != (dtcState & mask)) + { + if((dtcDlc + 4) <= bufLen) + { + pDtcBuf[dtcDlc++] = (uint8_t)(udsDtcTable[dtcCnt].dtcCode >> 16); + pDtcBuf[dtcDlc++] = (uint8_t)(udsDtcTable[dtcCnt].dtcCode >> 8); + pDtcBuf[dtcDlc++] = (uint8_t)(udsDtcTable[dtcCnt].dtcCode >> 0); + pDtcBuf[dtcDlc++] = (dtcState & DTC_AVAILABILITY_STATUS_MASK); + } + else + { + break; + } + } + } + + return dtcDlc; +} + +uint16_t Uds_GetSupportedDtc(uint8_t *pDtcBuf, uint16_t bufLen) +{ + uint16_t dtcCnt = 0; + uint8_t dtcState = 0; + uint16_t dtcDlc = 0; + + for(dtcCnt = 0; dtcCnt < DTC_MAX_COUNT; dtcCnt++) + { + dtcState = udsDtcTable[dtcCnt].dtcStatus.all; + if((dtcDlc + 4) <= bufLen) + { + pDtcBuf[dtcDlc++] = (uint8_t)(udsDtcTable[dtcCnt].dtcCode >> 16); + pDtcBuf[dtcDlc++] = (uint8_t)(udsDtcTable[dtcCnt].dtcCode >> 8); + pDtcBuf[dtcDlc++] = (uint8_t)(udsDtcTable[dtcCnt].dtcCode >> 0); + pDtcBuf[dtcDlc++] = (dtcState & DTC_AVAILABILITY_STATUS_MASK); + } + else + { + break; + } + } + + return dtcDlc; +} + +void Uds_ClearDtcByGroup(uint32_t group) +{ + uint16_t dtcCnt = 0; + + switch(group) + { + case EMISSION_SYSTEM_GROUP: + for(dtcCnt = 0; dtcCnt < DTC_MAX_COUNT; dtcCnt++) + { + if(udsDtcTable[dtcCnt].dtcCode <= DTCG_EMISSION_END) + { + Uds_ClearDtcByDtcIndex(dtcCnt); + } + } + break; + case SAFETY_SYSTEM_GROUP: + for(dtcCnt = 0; dtcCnt < DTC_MAX_COUNT; dtcCnt++) + { + if((udsDtcTable[dtcCnt].dtcCode >= DTCG_CHASSIS_START) && (udsDtcTable[dtcCnt].dtcCode <= DTCG_CHASSIS_END)) + { + Uds_ClearDtcByDtcIndex(dtcCnt); + } + } + break; + case ALL_FUNC_SYSTEM_GROUP: + for(dtcCnt = 0; dtcCnt < DTC_MAX_COUNT; dtcCnt++) + { + Uds_ClearDtcByDtcIndex(dtcCnt); + } + break; + } +} diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_dtc.h b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_dtc.h new file mode 100644 index 0000000..155c984 --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_dtc.h @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_DTC_H_ +#define _UDS_DTC_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS application + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define EMISSION_SYSTEM_GROUP (0x00FFFF33) +#define SAFETY_SYSTEM_GROUP (0x00FFFFD0) +#define ALL_FUNC_SYSTEM_GROUP (0x00FFFFFF) + +#define REPORT_DTC_NUMBER_BY_STATUS_MASK (0x01) +#define REPORT_DTC_BY_STATUS_MASK (0x02) +#define REPORT_DTC_SNOPSHOT_IDENTIFICATION (0x03) +#define REPORT_DTC_SNOPSHOT_RECORD_BY_DTC_NUMBER (0x04) +#define REPORT_DTC_STORE_DATA_BY_RECORD_NUMBER (0x05) +#define REPORT_DTC_EXT_DATA_RECORD_BY_DTC_NUMBER (0x06) +#define REPORT_DTC_NUMBER_BY_SEVERITY_MASK_RECORD (0x07) +#define REPORT_DTC_BY_SEVERITY_MASK_RECORD (0x08) +#define REPORT_SUPPORTED_DTC (0x0a) + +#define DTC_FORMAT_15031 (0x00) +#define DTC_FORMAT_14229 (0x01) +#define DTC_FORMAT_J1939 (0x02) +#define DTC_FORMAT_11992 (0x03) + +#define DTC_AVAILABILITY_STATUS_MASK (0x7F) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The DTC Index name of UDS supported + */ +typedef enum _Uds_DtcIndexNameType_ +{ + DTC_FUEL_SENSOR_BELOW = 0, + DTC_FUEL_SENSOR_ABOVE, + DTC_BATT_VOLTAG_BELOW, + DTC_BATT_VOLTAG_ABOVE, + DTC_CAN_BUS_OFF, + DTC_COM_LOST_EMS, + DTC_COM_LOST_TCU, + DTC_COM_LOST_ABS, + DTC_COM_LOST_TPMS, + DTC_COM_LOST_EPB, + DTC_COM_LOST_ESP, + DTC_COM_LOST_EPS, + DTC_COM_LOST_BCM, + DTC_COM_LOST_SRS, + DTC_COM_LOST_DVD, + DTC_COM_LOST_PDC, + DTC_COM_LOST_ALS, + DTC_COM_LOST_PEPS, + DTC_COM_LOST_AC, + DTC_COM_LOST_AVM, + DTC_MAX_COUNT +} Uds_DtcIndexNameType; + +/*! \brief The DTC status definition refers to ISO14229-1 D.2.4 + * \note Bit 0, testFailed, clear by test pass or ClearDiagnosticInformation + * Bit 1, testFailedThisOperationCycle, clear by new OC or ClearDiagnosticInformation + * Bit 2, latch, pendingDTC, clear by fault never happened in cur OC or ClearDiagnosticInformation, if test not completed, must hold. + * Bit 3, latch, confirmedDTC, clear by ClearDiagnosticInformation, one(only by normal fault) or 40 OC not detect any fault. + * Bit 4, latch, testNotCompletedSinceLastClear, set by a new OC start or ClearDiagnosticInformation + * Bit 5, latch, testFailedSinceLastClear, clear by ClearDiagnosticInformation + * Bit 6, testNotCompletedThisOperationCycle + * Bit 7, warningIndicatorRequested(unsupported) + */ +typedef union _Uds_DtcStatusType_ +{ + uint8_t all; + struct + { + uint8_t testFailed : 1; + uint8_t testFailToc : 1; + uint8_t pending : 1; + uint8_t confirmed : 1; + uint8_t testNcmpSlc : 1; + uint8_t testFailSlc : 1; + uint8_t testNcmpToc : 1; + uint8_t wnIndreq : 1; + } bit; +} Uds_DtcStatusType; + +/*! \brief The DTC definition of UDS + */ +typedef struct _Uds_DtcType_ +{ + uint32_t dtcCode; + Uds_DtcStatusType dtcStatus; + int16_t faultDtCnt; /* refers to ISO14229-1 D.6 */ + uint8_t AgingCnt; /* refers to ISO14229-1 D.7 */ +} Uds_DtcType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief control DTC status updata stop and start + */ +extern void Uds_SetDtcOffCtrl(bool val); + +/*! \brief get control DTC status + */ +extern bool Uds_GetDtcOffCtrlState(void); + +/*! \brief clear DTC by dtc index + */ +extern void Uds_ClearDtcByDtcIndex(uint16_t dtcIndex); + +/*! \brief load dtc data from EEPROM + */ +extern void Uds_LoadDtc(void); + +/*! \brief save dtc data to EEPROM + */ +extern void Uds_SaveDtc(void); + +/*! \brief get DTC counter by dtc status mask + */ +extern uint16_t Uds_GetDtcNumberByStatusMask(uint8_t mask); + +/*! \brief get DTC data by dtc status mask + */ +extern uint16_t Uds_GetDtcByStatusMask(uint8_t *pDtcBuf, uint16_t bufLen, uint8_t mask); + +/*! \brief get all supported DTC data + */ +extern uint16_t Uds_GetSupportedDtc(uint8_t *pDtcBuf, uint16_t bufLen); + +/*! \brief clear DTC by dtc group + */ +extern void Uds_ClearDtcByGroup(uint32_t group); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_DTC_H_ */ diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service14.c b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service14.c new file mode 100644 index 0000000..bd0e350 --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service14.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_service14.h" +#include "uds_dtc.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void UdsService14_ClearDiagInfo(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint32_t dtcGroup = 0; + uint8_t rspBuffer[8] = {0}; + + if(msgLen != obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x14, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + dtcGroup |= ((uint32_t)msgBuf[1]) << 16; + dtcGroup |= ((uint32_t)msgBuf[2]) << 8; + dtcGroup |= ((uint32_t)msgBuf[3]) << 0; + + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x14); + + switch(dtcGroup) + { + case EMISSION_SYSTEM_GROUP: + case SAFETY_SYSTEM_GROUP: + case ALL_FUNC_SYSTEM_GROUP: + Uds_ClearDtcByGroup(dtcGroup); + Uds_PositiveResponse(obj, rspBuffer, 1); + break; + default: + Uds_NegativeResponse(obj, 0x14, NRC_REQUEST_OUT_OF_RANGE); + break; + } +} + + + diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service14.h b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service14.h new file mode 100644 index 0000000..d01d624 --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service14.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE14_H_ +#define _UDS_SERVICE14_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 14 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 14 processing + */ +extern void UdsService14_ClearDiagInfo(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE14_H_ */ diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service19.c b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service19.c new file mode 100644 index 0000000..7787a63 --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service19.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_service19.h" +#include "uds_dtc.h" + + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void UdsService19_ReadDtcInformation(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint8_t subFunction = 0; + uint8_t dtcStatusMask = 0; + uint16_t dtcCount = 0; + uint16_t dtcDlc = 0; + uint8_t rspBuffer[UDS_RSP_LEN_MAX] = {0}; + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x19, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + subFunction = UDS_GET_SUB_FUNCTION (msgBuf[1]); + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x19); + rspBuffer[1] = subFunction; + switch(subFunction) + { + case REPORT_DTC_NUMBER_BY_STATUS_MASK: + if(msgLen != 3) + { + Uds_NegativeResponse(obj, 0x19, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + dtcStatusMask = msgBuf[2]; + dtcCount = Uds_GetDtcNumberByStatusMask(dtcStatusMask); + rspBuffer[2] = DTC_AVAILABILITY_STATUS_MASK; + rspBuffer[3] = DTC_FORMAT_14229; + rspBuffer[4] = (dtcCount >> 8) & 0xFF; + rspBuffer[5] = (dtcCount >> 0) & 0xFF; + Uds_PositiveResponse(obj, rspBuffer, 6); + break; + case REPORT_DTC_BY_STATUS_MASK: + if(msgLen != 3) + { + Uds_NegativeResponse(obj, 0x19, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + dtcStatusMask = msgBuf[2]; + rspBuffer[2] = DTC_AVAILABILITY_STATUS_MASK; + dtcDlc = Uds_GetDtcByStatusMask(&rspBuffer[3], UDS_RSP_LEN_MAX - 3, dtcStatusMask); + Uds_PositiveResponse(obj, rspBuffer, dtcDlc + 3); + break; +#if 0 + case REPORT_DTC_SNOPSHOT_IDENTIFICATION: + if(msgLen != 6) + { + UDS_negativeResponse(obj, 0x19, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + /* add user code */ + + break; + case REPORT_DTC_SNOPSHOT_RECORD_BY_DTC_NUMBER: + if(msgLen != 6) + { + UDS_negativeResponse(obj, 0x19, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + /* add user code */ + + break; + case REPORT_DTC_STORE_DATA_BY_RECORD_NUMBER: + if(msgLen != 3) + { + UDS_negativeResponse(obj, 0x19, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + /* add user code */ + + break; + case REPORT_DTC_EXT_DATA_RECORD_BY_DTC_NUMBER: + if(msgLen != 6) + { + UDS_negativeResponse(obj, 0x19, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + /* add user code */ + + break; + case REPORT_DTC_NUMBER_BY_SEVERITY_MASK_RECORD: + if(msgLen != 4) + { + UDS_negativeResponse(obj, 0x19, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + /* add user code */ + + break; + case REPORT_DTC_BY_SEVERITY_MASK_RECORD: + if(msgLen != 4) + { + UDS_negativeResponse(obj, 0x19, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + /* add user code */ + + break; +#endif + case REPORT_SUPPORTED_DTC: + if(msgLen != 2) + { + Uds_NegativeResponse(obj, 0x19, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + dtcDlc = Uds_GetSupportedDtc(&rspBuffer[3], UDS_RSP_LEN_MAX - 3); + Uds_PositiveResponse(obj, rspBuffer, dtcDlc + 3); + break; + default: + Uds_NegativeResponse(obj, 0x19, NRC_SUBFUNCTION_NOT_SUPPORTED); + break; + } +} + + diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service19.h b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service19.h new file mode 100644 index 0000000..6179d1d --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service19.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE19_H_ +#define _UDS_SERVICE19_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 19 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 19 processing + */ +extern void UdsService19_ReadDtcInformation(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE19_H_ */ diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service22.c b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service22.c new file mode 100644 index 0000000..954ad67 --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service22.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ +#include +#include "uds_service22.h" + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void UdsService22_ReadDataByIdentifier(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint16_t didNum = 0; + uint16_t didValue = 0; + uint16_t rspLen = 0; + uint16_t msgPos = 0, didIdx = 0; + bool findDid = false; + uint8_t rspBuffer[UDS_RSP_LEN_MAX] = {0}; + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x22, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + if(0 != (msgLen - 1) % sizeof(uint16_t)) + { + Uds_NegativeResponse(obj, 0x22, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + didNum = msgLen / sizeof(uint16_t); + if(0 == didNum) + { + Uds_NegativeResponse(obj, 0x22, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + rspBuffer[rspLen++] = UDS_GET_POSITIVE_RSP(0x22); + + for(msgPos = 1; msgPos < msgLen; msgPos += 2) + { + didValue = ((uint16_t)msgBuf[msgPos]) << 8; + didValue |= msgBuf[msgPos + 1]; + + findDid = false; + for(didIdx = 0; didIdx < obj->didNum; didIdx++) + { + if(obj->didTable[didIdx].did == didValue) + { + if(obj->securityLevel != obj->didTable[didIdx].securityLevel) + { + Uds_NegativeResponse(obj, 0x22, NRC_SECURITY_ACCESS_DENIED); + return; + } + else if((rspLen + 2 + obj->didTable[didIdx].length) > UDS_RSP_LEN_MAX) + { + Uds_NegativeResponse(obj, 0x22, NRC_RESPONSE_TOO_LONG); + return; + } + + if((UDS_DID_TYPE_NVM_WO == obj->didTable[didIdx].type) || (obj->session < obj->didTable[didIdx].sessionLevel)) + { + Uds_NegativeResponse(obj, 0x22, NRC_CONDITIONS_NOT_CORRECT); + return; + } + obj->didTable[didIdx].function(obj, obj->didTable[didIdx].pBytes, obj->didTable[didIdx].length); + findDid = true; + rspBuffer[rspLen++] = msgBuf[msgPos]; + rspBuffer[rspLen++] = msgBuf[msgPos + 1]; + memcpy(&rspBuffer[rspLen], obj->didTable[didIdx].pBytes, obj->didTable[didIdx].length); + rspLen += obj->didTable[didIdx].length; + break; + } + } + if(false == findDid) + { + break; + } + } + + if(true == findDid) + { + Uds_PositiveResponse(obj, rspBuffer, rspLen); + } + else + { + Uds_NegativeResponse(obj, 0x22, NRC_REQUEST_OUT_OF_RANGE); + } + +} + + diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service22.h b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service22.h new file mode 100644 index 0000000..c1d11dd --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service22.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE22_H_ +#define _UDS_SERVICE22_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 22 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 22 processing + */ +extern void UdsService22_ReadDataByIdentifier(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE22_H_ */ diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service28.c b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service28.c new file mode 100644 index 0000000..8fbcf7b --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service28.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_service28.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The uds communication type definition of UDS + */ +typedef enum _UdsComType_ +{ + UDS_CC_TYPE_NONE = 0, + UDS_CC_TYPE_NORMAL, /* normal message */ + UDS_CC_TYPE_NM, /* network management */ + UDS_CC_TYPE_NOR_NM, /* normal and network management message */ +} UdsComType; + +/*! \brief The uds communication control mode definition of UDS + */ +typedef enum _UdsComCtrlMode_ +{ + UDS_CC_MODE_RX_TX = 0, + UDS_CC_MODE_RX_NO, + UDS_CC_MODE_NO_TX, + UDS_CC_MODE_NO_NO +} UdsComCtrMode; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +static uint8_t udsComCtrlType = 0; + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +uint8_t Uds_GetCommunicationControlMode(void) +{ + return udsComCtrlType; +} + +void UdsService28_CommunicationControl(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint8_t subFunction; + uint8_t rspBuffer[8] = {0}; /* polyspace DEFECT:PARTIALLY_ACCESSED_ARRAY [No action planned:Low] "Still keep default though member2~7 is not written" */ + uint8_t ccType = 0; + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x28, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + if(obj->session == UDS_SESSION_DEFAULT) + { + Uds_NegativeResponse(obj, 0x28, NRC_CONDITIONS_NOT_CORRECT); + return; + } + + subFunction = UDS_GET_SUB_FUNCTION(msgBuf[1]); + ccType = msgBuf[2]; + + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x28); + rspBuffer[1] = subFunction; + switch(subFunction) + { + case UDS_CC_MODE_RX_TX: + if(ccType == UDS_CC_TYPE_NORMAL || ccType == UDS_CC_TYPE_NM || ccType == UDS_CC_TYPE_NOR_NM) + { + udsComCtrlType = UDS_CC_MODE_RX_TX; + + Uds_PositiveResponse(obj, rspBuffer, 2); + } + else + { + Uds_NegativeResponse(obj, 0x28, NRC_REQUEST_OUT_OF_RANGE); + } + break; + case UDS_CC_MODE_RX_NO: + if(ccType == UDS_CC_TYPE_NORMAL || ccType == UDS_CC_TYPE_NM || ccType == UDS_CC_TYPE_NOR_NM) + { + udsComCtrlType = UDS_CC_MODE_RX_NO; + + Uds_PositiveResponse(obj, rspBuffer, 2); + } + else + { + Uds_NegativeResponse(obj, 0x28, NRC_REQUEST_OUT_OF_RANGE); + } + break; + case UDS_CC_MODE_NO_TX: + if(ccType == UDS_CC_TYPE_NORMAL || ccType == UDS_CC_TYPE_NM || ccType == UDS_CC_TYPE_NOR_NM) + { + udsComCtrlType = UDS_CC_MODE_NO_TX; + + Uds_PositiveResponse(obj, rspBuffer, 2); + } + else + { + Uds_NegativeResponse(obj, 0x28, NRC_REQUEST_OUT_OF_RANGE); + } + break; + case UDS_CC_MODE_NO_NO: + if(ccType == UDS_CC_TYPE_NORMAL || ccType == UDS_CC_TYPE_NM || ccType == UDS_CC_TYPE_NOR_NM) + { + udsComCtrlType = UDS_CC_MODE_NO_NO; + + Uds_PositiveResponse(obj, rspBuffer, 2); + } + else + { + Uds_NegativeResponse(obj, 0x28, NRC_REQUEST_OUT_OF_RANGE); + } + break; + default: + Uds_NegativeResponse(obj, 0x28, NRC_SUBFUNCTION_NOT_SUPPORTED); + break; + } +} diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service28.h b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service28.h new file mode 100644 index 0000000..7e3c098 --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service28.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE28_H_ +#define _UDS_SERVICE28_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 28 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Get Communication Control Mode + */ +uint8_t Uds_GetCommunicationControlMode(void); + +/*! \brief Uds Service 28 processing + */ +extern void UdsService28_CommunicationControl(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE28_H_ */ diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service2E.c b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service2E.c new file mode 100644 index 0000000..0dcc7a0 --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service2E.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "uds_service2E.h" + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void UdsService2E_WriteDataByIdentifier(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint16_t didValue = 0; + uint16_t didIdx = 0; + uint8_t rspBuffer[8] = {0}; + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x2E, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + didValue = ((uint16_t)msgBuf[1]) << 8; + didValue |= msgBuf[2]; + + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x2E); + rspBuffer[1] = msgBuf[1]; + rspBuffer[2] = msgBuf[2]; + for(didIdx = 0; didIdx < obj->didNum; didIdx++) + { + if(obj->didTable[didIdx].did == didValue) + { + if((obj->didTable[didIdx].securityLevel != UDS_SA_NONE) && (obj->securityLevel != obj->didTable[didIdx].securityLevel)) + { + Uds_NegativeResponse(obj, 0x22, NRC_SECURITY_ACCESS_DENIED); + return; + } + else if((msgLen - 3) != obj->didTable[didIdx].length) + { + Uds_NegativeResponse(obj, 0x2E, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + if((UDS_DID_TYPE_NVM_RO == obj->didTable[didIdx].type) || (obj->session < obj->didTable[didIdx].sessionLevel)) + { + Uds_NegativeResponse(obj, 0x2E, NRC_CONDITIONS_NOT_CORRECT); + return; + } + + memcpy(obj->didTable[didIdx].pBytes, &msgBuf[3], obj->didTable[didIdx].length); + /* add user code to save data */ + + /* check save data success */ + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still reserve though it's maybe unreachable" */ + if(1) + { + Uds_PositiveResponse(obj, rspBuffer, 3); + return; + } + else + { + Uds_NegativeResponse(obj, 0x2E, NRC_GENERAL_PROGRAMMING_FAILURE); + return; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still reserve though it's maybe unreachable" */ + } + } + + Uds_NegativeResponse(obj, 0x2E, NRC_REQUEST_OUT_OF_RANGE); +} + + + diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service2E.h b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service2E.h new file mode 100644 index 0000000..f35f493 --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service2E.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE2E_H_ +#define _UDS_SERVICE2E_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 2E + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 2E processing + */ +extern void UdsService2E_WriteDataByIdentifier(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE2E_H_ */ diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service2F.c b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service2F.c new file mode 100644 index 0000000..9023068 --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service2F.c @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "uds_service2F.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The Uds IO control type + */ +typedef enum _UdsIoCtrlType_ +{ + UDS_IOCTRL_RETURN_TO_ECU = 0x00, + UDS_IOCTRL_RETSET_TO_DEFAULT = 0x01, + UDS_IOCTRL_FREEZE_CURRENT_STATE = 0x02, + UDS_IOCTRL_SHORT_ADJUSTMENT = 0x03 +} UdsIoCtrlType; + +/*! \brief The Uds IO control struct + */ +typedef struct _Uds_IoCtrl_ +{ + uint16_t did; + uint8_t securityLevel; + uint8_t *pData; + uint8_t dataLen; + uint8_t defaultValue; + uint8_t step; + bool enable; + void (*IoCtrl_Init)(void); + void (*IoCtrl_Stop)(void); +} Uds_IoCtrl; + +/*! \brief The IoControl-by-ID definition of UDS + */ +typedef struct _Uds_IoCtrlBuf_ +{ + uint8_t backlightLevel[2]; + uint8_t buzzer[2]; +} Uds_IoCtrlBuf; + +/******************************************************************************* + * the constants + ******************************************************************************/ + +static void IoCtrl_InitBackLight(void); +static void IoCtrl_StopBacklight(void); +static void IoCtrl_InitBuzzer(void); +static void IoCtrl_StopBuzzer(void); + +/******************************************************************************* + * the globals + ******************************************************************************/ + +Uds_IoCtrlBuf udsIoCtrlBuffer; + +Uds_IoCtrl udsIoCtrlTable[] = { + {0xF092, UDS_SA_NONE, udsIoCtrlBuffer.backlightLevel, 2, 0, 0, 0, &IoCtrl_InitBackLight, &IoCtrl_StopBacklight}, + {0xF020, UDS_SA_NONE, udsIoCtrlBuffer.buzzer, 2, 0, 0, 0, &IoCtrl_InitBuzzer, &IoCtrl_StopBuzzer }, +}; + +/******************************************************************************* + * the functions + ******************************************************************************/ + +static void IoCtrl_InitBackLight(void) +{ + /* user add back light control code */ +} + +static void IoCtrl_StopBacklight(void) +{ + /* user add back light stop code */ +} + +static void IoCtrl_InitBuzzer(void) +{ + /* user add buzzer control code */ +} + +static void IoCtrl_StopBuzzer(void) +{ + /* user add buzzer stop code */ +} + +void UdsService2F_InputOutputCtrlById(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint16_t ioCtrlId = 0; + uint8_t ioCtrlParam = 0; + uint8_t ioCtrlIndex = 0; + uint8_t ioCtrlNum = sizeof(udsIoCtrlTable) / sizeof(udsIoCtrlTable[0]); + uint8_t rspBuffer[UDS_RSP_LEN_MAX] = {0}; + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x2F, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + if(obj->session == UDS_SESSION_DEFAULT) + { + Uds_NegativeResponse(obj, 0x2F, NRC_CONDITIONS_NOT_CORRECT); + return; + } + + ioCtrlId = ((uint16_t)msgBuf[1] << 8) + msgBuf[2]; + ioCtrlParam = msgBuf[3]; + + for(ioCtrlIndex = 0; ioCtrlIndex < ioCtrlNum; ioCtrlIndex++) + { + if(udsIoCtrlTable[ioCtrlIndex].did == ioCtrlId) + { + if((udsIoCtrlTable[ioCtrlIndex].securityLevel != UDS_SA_NONE) && (udsIoCtrlTable[ioCtrlIndex].securityLevel != obj->securityLevel)) + { + Uds_NegativeResponse(obj, 0x2F, NRC_SECURITY_ACCESS_DENIED); + return; + } + + break; + } + } + + if(ioCtrlIndex >= ioCtrlNum) + { + Uds_NegativeResponse(obj, 0x2F, NRC_REQUEST_OUT_OF_RANGE); + return; + } + + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x2F); + rspBuffer[1] = msgBuf[1]; + rspBuffer[2] = msgBuf[2]; + rspBuffer[3] = msgBuf[3]; + switch(ioCtrlParam) + { + case UDS_IOCTRL_RETURN_TO_ECU: + /* add user code */ + udsIoCtrlTable[ioCtrlIndex].enable = false; + if(udsIoCtrlTable[ioCtrlIndex].IoCtrl_Stop != NULL) + { + udsIoCtrlTable[ioCtrlIndex].IoCtrl_Stop(); + Uds_PositiveResponse(obj, rspBuffer, 4); + } + + break; + case UDS_IOCTRL_SHORT_ADJUSTMENT: + /* add user code */ + if(msgLen < (udsIoCtrlTable[ioCtrlIndex].dataLen + 4)) + { + Uds_NegativeResponse(obj, 0x2F, NRC_CONDITIONS_NOT_CORRECT); + return; + } + + udsIoCtrlTable[ioCtrlIndex].enable = true; + memcpy(udsIoCtrlTable[ioCtrlIndex].pData, &msgBuf[4], udsIoCtrlTable[ioCtrlIndex].dataLen); + if(udsIoCtrlTable[ioCtrlIndex].IoCtrl_Init != NULL) + { + udsIoCtrlTable[ioCtrlIndex].IoCtrl_Init(); + Uds_PositiveResponse(obj, rspBuffer, 4); + } + break; + default: + Uds_NegativeResponse(obj, 0x2F, NRC_REQUEST_OUT_OF_RANGE); + break; + } +} diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service2F.h b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service2F.h new file mode 100644 index 0000000..77ea61b --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service2F.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE2F_H_ +#define _UDS_SERVICE2F_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 2F + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 2F processing + */ +extern void UdsService2F_InputOutputCtrlById(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE2F_H_ */ diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service37.c b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service37.c new file mode 100644 index 0000000..f94681d --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service37.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ +#include "uds_service36.h" +#include "uds_service37.h" + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void UdsService37_RequestTransferExit(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint16_t rspLen = 0; + uint8_t rspBuffer[8] ={0}; /* polyspace DEFECT:PARTIALLY_ACCESSED_ARRAY [No action planned:Low] "Still reserve though member1~7 is not written" */ + + if(obj->session == UDS_SESSION_DEFAULT) + { + Uds_NegativeResponse(obj, 0x37, NRC_CONDITIONS_NOT_CORRECT); + return; + } + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x37, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + rspBuffer[rspLen++] = UDS_GET_POSITIVE_RSP(0x37); + switch(Uds_GetDataTransferDirect()) + { + case UDS_TRANSFER_DIR_DOWNLOAD: + if(Uds_GetRcvDataTotalLen() != Uds_GetMemSize()) + { + Uds_NegativeResponse(obj, 0x37, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + break; + } + + /* user add process code, example data CRC */ + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still reserve though it's maybe unreachable" */ + if(1) /* result check correct */ + { + Uds_PositiveResponse(obj, rspBuffer, rspLen); + } + else + { + Uds_NegativeResponse(obj, 0x37, NRC_GENERAL_PROGRAMMING_FAILURE); + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still reserve though it's maybe unreachable" */ + break; + case UDS_TRANSFER_DIR_UPLOAD: + Uds_NegativeResponse(obj, 0x37, NRC_REQUEST_OUT_OF_RANGE); + break; + default: + Uds_NegativeResponse(obj, 0x37, NRC_REQUEST_SEQUENCE_ERROR); + break; + } + + Uds_SetDataTransferDirect(UDS_TRANSFER_DIR_NONE); +} + + + diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service37.h b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service37.h new file mode 100644 index 0000000..cd6da79 --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service37.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE37_H_ +#define _UDS_SERVICE37_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 37 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 37 processing + */ +void UdsService37_RequestTransferExit(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE37_H_ */ diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service3E.c b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service3E.c new file mode 100644 index 0000000..e371eb8 --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service3E.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_service3E.h" + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void UdsService3E_TesterPresent(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint8_t subFunction; + uint8_t rspBuffer[8] = {0}; /* polyspace DEFECT:PARTIALLY_ACCESSED_ARRAY [No action planned:Low] "Still keep default though member2~7 is not written" */ + + if(msgLen != obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x3E, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + subFunction = UDS_GET_SUB_FUNCTION (msgBuf[1]); + + if(subFunction == 0) + { + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x3E); + rspBuffer[1] = subFunction; + Uds_PositiveResponse(obj, rspBuffer, 2); + } + else + { + Uds_NegativeResponse(obj, 0x3E, NRC_SUBFUNCTION_NOT_SUPPORTED); + } + +} + + diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service3E.h b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service3E.h new file mode 100644 index 0000000..d714e26 --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service3E.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE3E_H_ +#define _UDS_SERVICE3E_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 3E + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 3E processing + */ +extern void UdsService3E_TesterPresent(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE3E_H_ */ diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service85.c b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service85.c new file mode 100644 index 0000000..570654b --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service85.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_service85.h" +#include "uds_dtc.h" + + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void UdsService85_ControlDtcSetting(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint8_t subFunction; + uint8_t rspBuffer[8] = {0}; /* polyspace DEFECT:PARTIALLY_ACCESSED_ARRAY [No action planned:Low] "Still keep default though member2~7 is not written" */ + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x85, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + if(obj->session == UDS_SESSION_DEFAULT) + { + Uds_NegativeResponse(obj, 0x85, NRC_CONDITIONS_NOT_CORRECT); + return; + } + + subFunction = UDS_GET_SUB_FUNCTION (msgBuf[1]); + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x85); + rspBuffer[1] = subFunction; + switch(subFunction) + { + case 1: + Uds_SetDtcOffCtrl(true); + Uds_PositiveResponse(obj, rspBuffer, 2); + break; + case 2: + Uds_SetDtcOffCtrl(false); + Uds_PositiveResponse(obj, rspBuffer, 2); + break; + default: + Uds_NegativeResponse(obj, 0x85, NRC_SUBFUNCTION_NOT_SUPPORTED); + break; + } + +} diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service85.h b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service85.h new file mode 100644 index 0000000..0d55da3 --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_service85.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE85_H_ +#define _UDS_SERVICE85_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 85 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 85 processing + */ +extern void UdsService85_ControlDtcSetting(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE85_H_ */ diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_user.c b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_user.c new file mode 100644 index 0000000..b29374a --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_user.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_user.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The Data-by-ID definition of UDS + */ +typedef struct _Uds_DidBuffer_ +{ + uint8_t buffer_F113[4]; + uint8_t buffer_F180[16]; + uint8_t buffer_F186[1]; + uint8_t buffer_F18A[6]; + uint8_t buffer_F195[16]; + uint8_t buffer_F1A0[8]; + uint8_t buffer_F1A1[8]; + uint8_t buffer_F1A2[8]; + uint8_t buffer_F1A5[8]; + uint8_t buffer_F1AE[16]; + uint8_t buffer_4F53[1]; + uint8_t buffer_4F80[2]; + uint8_t buffer_4F65[1]; + uint8_t buffer_4F66[1]; + uint8_t buffer_4F67[2]; + uint8_t buffer_F19E[32]; + uint8_t buffer_F1AA[8]; + uint8_t buffer_F1AB[8]; + uint8_t buffer_F112[8]; + uint8_t buffer_F190[17]; + uint8_t buffer_F191[16]; + uint8_t buffer_F193[16]; + uint8_t buffer_F197[8]; + uint8_t buffer_F198[16]; + uint8_t buffer_F199[4]; + uint8_t buffer_F19D[4]; + uint8_t buffer_DFEF[64]; + uint8_t buffer_F101[4]; + uint8_t buffer_F110[8]; + uint8_t buffer_4F51[16]; + uint8_t buffer_4F54[16]; + uint8_t buffer_F18C[24]; + uint8_t buffer_F18B[4]; + uint8_t buffer_0200[1]; + uint8_t buffer_0201[1]; + uint8_t buffer_F187[10]; + uint8_t buffer_F189[16]; + uint8_t buffer_FD01[1]; + uint8_t buffer_FD02[1]; + uint8_t buffer_FD03[1]; +} Uds_DidBuffer; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +Uds_DidBuffer udsDidBuf; + +/******************************************************************************* + * the constants + ******************************************************************************/ + +static const Uds_ServiceType udsServiceTable[UDS_SERVICE_NUM] = { + {0x10, 2, true, UdsService10_SessionControl }, + {0x11, 2, true, UdsService11_ResetEcu }, + {0x27, 2, true, UdsService27_SecurityAccess }, + {0x28, 3, true, UdsService28_CommunicationControl }, + {0x3E, 2, true, UdsService3E_TesterPresent }, + {0x85, 2, true, UdsService85_ControlDtcSetting }, + {0x22, 3, false, UdsService22_ReadDataByIdentifier }, + {0x2E, 4, false, UdsService2E_WriteDataByIdentifier}, + {0x14, 4, false, UdsService14_ClearDiagInfo }, + {0x19, 3, true, UdsService19_ReadDtcInformation }, + {0x2F, 3, false, UdsService2F_InputOutputCtrlById }, + {0x31, 4, true, UdsService31_RoutineControl }, + {0x34, 5, false, UdsService34_RequestDownload }, + {0x36, 2, false, UdsService36_TransferData }, + {0x37, 1, false, UdsService37_RequestTransferExit }, +}; + +static const bool udsSecurityTable[UDS_SERVICE_NUM][UDS_SA_LEVEL_NUM] = { + {false, false, false}, /* 0x10 */ + {false, false, false}, /* 0x11 */ + {false, false, false}, /* 0x27 */ + {false, false, false}, /* 0x28 */ + {false, false, false}, /* 0x3E */ + {false, false, false}, /* 0x85 */ + {false, false, false}, /* 0x22 */ + {false, false, false}, /* 0x2E */ + {false, false, false}, /* 0x14 */ + {false, false, false}, /* 0x19 */ + {false, false, false}, /* 0x2F */ + {false, false, false}, /* 0x31 */ + {false, false, false}, /* 0x34 */ + {false, false, false}, /* 0x36 */ + {false, false, false}, /* 0x37 */ +}; + +Uds_DidType udsDidTable[] = { + {0xF113, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F113, BYTES_OF(udsDidBuf.buffer_F113)}, + {0xF180, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F180, BYTES_OF(udsDidBuf.buffer_F180)}, + {0xF186, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F186, BYTES_OF(udsDidBuf.buffer_F186)}, + {0xF18A, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F18A, BYTES_OF(udsDidBuf.buffer_F18A)}, + {0xF195, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F195, BYTES_OF(udsDidBuf.buffer_F195)}, + {0xF1A0, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F1A0, BYTES_OF(udsDidBuf.buffer_F1A0)}, + {0xF1A1, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F1A1, BYTES_OF(udsDidBuf.buffer_F1A1)}, + {0xF1A2, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F1A2, BYTES_OF(udsDidBuf.buffer_F1A2)}, + {0xF1A5, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F1A5, BYTES_OF(udsDidBuf.buffer_F1A5)}, + {0xF1AE, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F1AE, BYTES_OF(udsDidBuf.buffer_F1AE)}, + {0x4F53, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_4F53, BYTES_OF(udsDidBuf.buffer_4F53)}, + {0x4F80, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_4F80, BYTES_OF(udsDidBuf.buffer_4F80)}, + {0x4F65, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_4F65, BYTES_OF(udsDidBuf.buffer_4F65)}, + {0x4F66, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_4F66, BYTES_OF(udsDidBuf.buffer_4F66)}, + {0x4F67, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_4F67, BYTES_OF(udsDidBuf.buffer_4F67)}, + {0xF19E, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F19E, BYTES_OF(udsDidBuf.buffer_F19E)}, + {0xF1AA, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F1AA, BYTES_OF(udsDidBuf.buffer_F1AA)}, + {0xF1AB, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F1AB, BYTES_OF(udsDidBuf.buffer_F1AB)}, + {0xF112, UDS_DID_TYPE_NVM_RW, UDS_SESSION_EXTENDED, UDS_SA_LEVEL_1, udsDidBuf.buffer_F112, BYTES_OF(udsDidBuf.buffer_F112)}, + {0xF190, UDS_DID_TYPE_NVM_RW, UDS_SESSION_EXTENDED, UDS_SA_LEVEL_1, udsDidBuf.buffer_F190, BYTES_OF(udsDidBuf.buffer_F190)}, + {0xF191, UDS_DID_TYPE_NVM_RO, UDS_SESSION_SUPPLIER, UDS_SA_LEVEL_63, udsDidBuf.buffer_F191, BYTES_OF(udsDidBuf.buffer_F191)}, + {0xF193, UDS_DID_TYPE_NVM_RO, UDS_SESSION_SUPPLIER, UDS_SA_LEVEL_63, udsDidBuf.buffer_F193, BYTES_OF(udsDidBuf.buffer_F193)}, + {0xF197, UDS_DID_TYPE_NVM_RW, UDS_SESSION_EXTENDED, UDS_SA_LEVEL_1, udsDidBuf.buffer_F197, BYTES_OF(udsDidBuf.buffer_F197)}, + {0xF198, UDS_DID_TYPE_NVM_RO, UDS_SESSION_SUPPLIER, UDS_SA_LEVEL_63, udsDidBuf.buffer_F198, BYTES_OF(udsDidBuf.buffer_F198)}, + {0xF199, UDS_DID_TYPE_NVM_RO, UDS_SESSION_SUPPLIER, UDS_SA_LEVEL_63, udsDidBuf.buffer_F199, BYTES_OF(udsDidBuf.buffer_F199)}, + {0xF19D, UDS_DID_TYPE_NVM_RW, UDS_SESSION_EXTENDED, UDS_SA_LEVEL_1, udsDidBuf.buffer_F19D, BYTES_OF(udsDidBuf.buffer_F19D)}, + {0xDFEF, UDS_DID_TYPE_NVM_RW, UDS_SESSION_EXTENDED, UDS_SA_LEVEL_1, udsDidBuf.buffer_DFEF, BYTES_OF(udsDidBuf.buffer_DFEF)}, + {0xF101, UDS_DID_TYPE_NVM_RW, UDS_SESSION_EXTENDED, UDS_SA_LEVEL_1, udsDidBuf.buffer_F101, BYTES_OF(udsDidBuf.buffer_F101)}, + {0xF110, UDS_DID_TYPE_NVM_RO, UDS_SESSION_EXTENDED, UDS_SA_LEVEL_1, udsDidBuf.buffer_F110, BYTES_OF(udsDidBuf.buffer_F110)}, + {0x4F51, UDS_DID_TYPE_NVM_WO, UDS_SESSION_EXTENDED, UDS_SA_LEVEL_1, udsDidBuf.buffer_4F51, BYTES_OF(udsDidBuf.buffer_4F51)}, + {0x4F54, UDS_DID_TYPE_NVM_WO, UDS_SESSION_EXTENDED, UDS_SA_LEVEL_1, udsDidBuf.buffer_4F54, BYTES_OF(udsDidBuf.buffer_4F54)}, + {0xF18C, UDS_DID_TYPE_NVM_RO, UDS_SESSION_SUPPLIER, UDS_SA_LEVEL_63, udsDidBuf.buffer_F18C, BYTES_OF(udsDidBuf.buffer_F18C)}, + {0xF18B, UDS_DID_TYPE_NVM_RO, UDS_SESSION_SUPPLIER, UDS_SA_LEVEL_63, udsDidBuf.buffer_F18B, BYTES_OF(udsDidBuf.buffer_F18B)}, + {0x0200, UDS_DID_TYPE_NVM_RO, UDS_SESSION_EXTENDED, UDS_SA_LEVEL_1, udsDidBuf.buffer_0200, BYTES_OF(udsDidBuf.buffer_0200)}, + {0x0201, UDS_DID_TYPE_NVM_RO, UDS_SESSION_EXTENDED, UDS_SA_LEVEL_1, udsDidBuf.buffer_0201, BYTES_OF(udsDidBuf.buffer_0201)}, + {0xF187, UDS_DID_TYPE_NVM_RO, UDS_SESSION_SUPPLIER, UDS_SA_LEVEL_63, udsDidBuf.buffer_F187, BYTES_OF(udsDidBuf.buffer_F187)}, + {0xF189, UDS_DID_TYPE_NVM_RO, UDS_SESSION_SUPPLIER, UDS_SA_LEVEL_63, udsDidBuf.buffer_F189, BYTES_OF(udsDidBuf.buffer_F189)}, + {0xFD01, UDS_DID_TYPE_NVM_RO, UDS_SESSION_SUPPLIER, UDS_SA_LEVEL_63, udsDidBuf.buffer_FD01, BYTES_OF(udsDidBuf.buffer_FD01)}, + {0xFD02, UDS_DID_TYPE_NVM_RO, UDS_SESSION_SUPPLIER, UDS_SA_LEVEL_63, udsDidBuf.buffer_FD02, BYTES_OF(udsDidBuf.buffer_FD02)}, + {0xFD03, UDS_DID_TYPE_NVM_RO, UDS_SESSION_SUPPLIER, UDS_SA_LEVEL_63, udsDidBuf.buffer_FD03, BYTES_OF(udsDidBuf.buffer_FD03)}, +}; + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void Uds_UserInit(UdsType *obj, const Uds_ParamsType *pParams) +{ + Uds_Init(obj, pParams); + + obj->seviceTable = udsServiceTable; + obj->securityTable = &udsSecurityTable[0][0]; + obj->serviceNum = UDS_SERVICE_NUM; + obj->didTable = udsDidTable; + obj->didNum = sizeof(udsDidTable) / sizeof(Uds_DidType); +} diff --git a/cva_bootloader_m0118/SDK/middleware/uds/user/uds_user.h b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_user.h new file mode 100644 index 0000000..1925d50 --- /dev/null +++ b/cva_bootloader_m0118/SDK/middleware/uds/user/uds_user.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_USER_H_ +#define _UDS_USER_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS application + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" +#include "uds_service10.h" +#include "uds_service11.h" +#include "uds_service14.h" +#include "uds_service19.h" +#include "uds_service22.h" +#include "uds_service27.h" +#include "uds_service28.h" +#include "uds_service2E.h" +#include "uds_service2F.h" +#include "uds_service31.h" +#include "uds_service34.h" +#include "uds_service36.h" +#include "uds_service37.h" +#include "uds_service3E.h" +#include "uds_service85.h" +#include "uds_dtc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the UDS object + */ +extern void Uds_UserInit(UdsType *obj, const Uds_ParamsType *pParams); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_USER_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/adc/adc_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/adc/adc_drv.c new file mode 100644 index 0000000..af1b740 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/adc/adc_drv.c @@ -0,0 +1,348 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "adc_drv.h" +#include "adc_reg.h" +#include "sim_reg.h" +#include "../cpu/cpu_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ +#define ADC_INTERLEAVE_ENABLE (1U) +#define ADC_LEN_PWR_ON_DEFAULT (11U) +#define ADC_LEN_SMPL_1ST_DEFAULT (48U) +#define ADC_LEN_SMPL_DEFAULT (4U) +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief ADC type of enable selection + */ +typedef enum +{ + ADCDRV_POWER_ON = 0x0U, + ADCDRV_POWER_DOWN = 0x1U, +} AdcDrv_PowerEnable; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void AdcDrv_Init(AdcDrvType *obj, struct _AdcRegType_ *adcReg, struct _SimRegType_ *simReg) +{ + obj->adcReg = adcReg; + obj->simReg = simReg; +} + +void AdcDrv_GetCmpCfg(AdcDrvType *obj, AdcDrv_CmpCfgType *currentConfig) +{ + bool acfe = AdcReg_GetSc2Acfe(obj->adcReg); + bool acfgt = AdcReg_GetSc2AcFgt(obj->adcReg); + bool acren = AdcReg_GetSc2AcREn(obj->adcReg); + uint16_t cv1 = AdcReg_GetCv1Cv(obj->adcReg); + uint16_t cv2 = AdcReg_GetCv2Cv(obj->adcReg); + if(acfe == false) + { + currentConfig->cmpMode = ADCDRV_CMPMODE_NO_COMPARE; + currentConfig->lowerLim = 0; + currentConfig->upperLim = 0; + } + else + { + if(acfgt == false && acren == false) + { + currentConfig->cmpMode = ADCDRV_CMPMODE_LESSTHAN; + currentConfig->lowerLim = cv1; + currentConfig->upperLim = 0; + } + else if(acfgt == true && acren == false) + { + currentConfig->cmpMode = ADCDRV_CMPMODE_GREATER_OR_EQUTHAN; + currentConfig->lowerLim = cv1; + currentConfig->upperLim = 0; + } + else if(acfgt == false && acren == true && cv1 <= cv2) + { + currentConfig->cmpMode = ADCDRV_CMPMODE_OUTSIDE_EXCLUDE_BOUNDARIES; + currentConfig->lowerLim = cv1; + currentConfig->upperLim = cv2; + } + else if(acfgt == false && acren == true && cv1 > cv2) + { + currentConfig->cmpMode = ADCDRV_CMPMODE_INSIDE_EXCLUDE_BOUNDARIES; + currentConfig->lowerLim = cv2; + currentConfig->upperLim = cv1; + } + else if(acfgt == true && acren == true && cv1 <= cv2) + { + currentConfig->cmpMode = ADCDRV_CMPMODE_INSIDE_INCLUDE_BOUNDARIES; + currentConfig->lowerLim = cv1; + currentConfig->upperLim = cv2; + } + else if(acfgt == true && acren == true && cv1 > cv2) + { + currentConfig->cmpMode = ADCDRV_CMPMODE_OUTSIDE_INCLUDE_BOUNDARIES; + currentConfig->lowerLim = cv2; + currentConfig->upperLim = cv1; + } + } +} + +void AdcDrv_CfgCompare(AdcDrvType *obj, const AdcDrv_CmpCfgType *userConfig) +{ + switch(userConfig->cmpMode) + { + case(ADCDRV_CMPMODE_NO_COMPARE): + AdcReg_SetSc2Acfe(obj->adcReg, false); + break; + case(ADCDRV_CMPMODE_LESSTHAN): + AdcReg_SetSc2Acfe(obj->adcReg, true); + AdcReg_SetSc2AcFgt(obj->adcReg, false); + AdcReg_SetSc2AcREn(obj->adcReg, false); + AdcReg_SetCv1Cv(obj->adcReg, userConfig->lowerLim); + AdcReg_SetCv2Cv(obj->adcReg, 0u); + break; + case(ADCDRV_CMPMODE_GREATER_OR_EQUTHAN): + AdcReg_SetSc2Acfe(obj->adcReg, true); + AdcReg_SetSc2AcFgt(obj->adcReg, true); + AdcReg_SetSc2AcREn(obj->adcReg, false); + AdcReg_SetCv1Cv(obj->adcReg, userConfig->lowerLim); + AdcReg_SetCv2Cv(obj->adcReg, 0u); + break; + case(ADCDRV_CMPMODE_OUTSIDE_EXCLUDE_BOUNDARIES): + AdcReg_SetSc2Acfe(obj->adcReg, true); + AdcReg_SetSc2AcFgt(obj->adcReg, false); + AdcReg_SetSc2AcREn(obj->adcReg, true); + AdcReg_SetCv1Cv(obj->adcReg, userConfig->lowerLim); + AdcReg_SetCv2Cv(obj->adcReg, userConfig->upperLim); + break; + case(ADCDRV_CMPMODE_INSIDE_EXCLUDE_BOUNDARIES): + AdcReg_SetSc2Acfe(obj->adcReg, true); + AdcReg_SetSc2AcFgt(obj->adcReg, false); + AdcReg_SetSc2AcREn(obj->adcReg, true); + AdcReg_SetCv1Cv(obj->adcReg, userConfig->upperLim); + AdcReg_SetCv2Cv(obj->adcReg, userConfig->lowerLim); + break; + case(ADCDRV_CMPMODE_INSIDE_INCLUDE_BOUNDARIES): + AdcReg_SetSc2Acfe(obj->adcReg, true); + AdcReg_SetSc2AcFgt(obj->adcReg, true); + AdcReg_SetSc2AcREn(obj->adcReg, true); + AdcReg_SetCv1Cv(obj->adcReg, userConfig->lowerLim); + AdcReg_SetCv2Cv(obj->adcReg, userConfig->upperLim); + break; + case(ADCDRV_CMPMODE_OUTSIDE_INCLUDE_BOUNDARIES): + AdcReg_SetSc2Acfe(obj->adcReg, true); + AdcReg_SetSc2AcFgt(obj->adcReg, true); + AdcReg_SetSc2AcREn(obj->adcReg, true); + AdcReg_SetCv1Cv(obj->adcReg, userConfig->upperLim); + AdcReg_SetCv2Cv(obj->adcReg, userConfig->lowerLim); + break; + default: + /* Impossible case */ + break; + } +} + +void AdcDrv_Configure(AdcDrvType *obj, const AdcDrv_ConfigType *userConfig) +{ + /* disable ADC first */ + AdcReg_SetSc3AdcPD(obj->adcReg, ADCDRV_POWER_DOWN); + + /* select the conversion conversionMode */ + AdcReg_SetCfg1Mode(obj->adcReg, (uint8_t)userConfig->conversionMode); + + /* select the ADC sample length */ + AdcReg_SetCfg2LenSmpl(obj->adcReg, userConfig->sampleLen); + + /* select the ADC sample length after the 1st cycle + * change the input channel select(ADCH) */ + AdcReg_SetCfg2LenSmpl1st(obj->adcReg, userConfig->firstSampleLen); + + /* select the ADC sample length after power on */ + AdcReg_SetCfg2LenPwrOn(obj->adcReg, userConfig->pwrOnLen); + + /* enable DMA */ + AdcReg_SetSc2DmaEn(obj->adcReg, userConfig->dmaEnable); + + /* Enable trigger */ + AdcReg_SetSc2AdTrg(obj->adcReg, 1); + + /* select hardware trigger source */ + SimReg_SetAdcTrgSrc(obj->simReg, (uint8_t)userConfig->trgSrcCfg.hwTrgSrc); + + /* select software pretrigger source */ + SimReg_SetAdcPreTrgSwSrc(obj->simReg, (uint8_t)userConfig->trgSrcCfg.swPretrgSrc); + + /* set pretrigger source */ + SimReg_SetAdcPreTrgSrc(obj->simReg, (uint8_t)userConfig->trgSrcCfg.pretrgSrc); + + /* select the continuous / one shot conversion */ + AdcReg_SetSc3Adco(obj->adcReg, (uint8_t)userConfig->continuousMode); + + /* configure the ADC compare function */ + AdcDrv_CfgCompare(obj, &(userConfig->cmpCfg)); + + /* enable hardware average sample */ + AdcReg_SetSc3AvgE(obj->adcReg, userConfig->avgEnable); + if(userConfig->avgEnable) + { + /* select the hardware average sample number */ + AdcReg_SetSc3AvgS(obj->adcReg, (uint8_t)userConfig->avgSamplesSel); + } + + /* configure for each ADC channel */ + uint8_t i; + for(i = 0; i < ADCDRV_CHANNEL_NUM; i++) + { + /* select the ADC channel input */ + AdcReg_SetScAdCh(obj->adcReg, i, (uint8_t)userConfig->chnCfg[i].chnSel); + + /* enable the interrupt for ADC channel */ + AdcReg_SetScAIEn(obj->adcReg, i, userConfig->chnCfg[i].intEnable); + } + + /* enable ADC */ + AdcReg_SetSc3AdcPD(obj->adcReg, ADCDRV_POWER_ON); +} + +void AdcDrv_GetDefaultConfig(AdcDrv_ConfigType *userConfig) +{ + uint8_t i = 0U; + + userConfig->conversionMode = ADCDRV_CONVERSION_12BIT; + userConfig->sampleLen = ADC_LEN_SMPL_DEFAULT; + userConfig->firstSampleLen = ADC_LEN_SMPL_1ST_DEFAULT; + userConfig->pwrOnLen = ADC_LEN_PWR_ON_DEFAULT; + userConfig->dmaEnable = false; + userConfig->cmpCfg.lowerLim = 0; + userConfig->cmpCfg.upperLim = 0; + userConfig->cmpCfg.cmpMode = ADCDRV_CMPMODE_NO_COMPARE; + userConfig->continuousMode = ADCDRV_ONESHOT; + userConfig->avgSamplesSel = ADCDRV_AVERAGE_4; + userConfig->avgEnable = true; + + userConfig->trgSrcCfg.hwTrgSrc = ADCDRV_HW_TRGSRC_PDB; + userConfig->trgSrcCfg.swPretrgSrc = ADCDRV_SWPRETRG_PRETRIGGER_0; + userConfig->trgSrcCfg.pretrgSrc = ADCDRV_PRETRG_PDB_PRETRIGGER; + + for(i = 0; i < ADCDRV_CHANNEL_NUM; i++) + { + userConfig->chnCfg[i].chnSel = (AdcDrv_InChnType)i; + userConfig->chnCfg[i].intEnable = false; + } +} + +void AdcDrv_ClrLockTrg(AdcDrvType *obj) +{ + AdcReg_ClrTrg(obj->adcReg); +} + +uint16_t AdcDrv_GetRn(AdcDrvType *obj, uint8_t chn) +{ + return (AdcReg_GetRData(obj->adcReg, (uint8_t)chn)); +} + +bool AdcDrv_GetCocon(AdcDrvType *obj, uint8_t chn) +{ + if(AdcReg_GetScCoCo(obj->adcReg, (uint8_t)chn) > 0) + { + return (true); + } + else + { + return (false); + } +} + +void AdcDrv_DisableAdc(AdcDrvType *obj) +{ + AdcReg_SetSc3AdcPD(obj->adcReg, ADCDRV_POWER_DOWN); +} + +void AdcDrv_EnableAdc(AdcDrvType *obj) +{ + AdcReg_SetSc3AdcPD(obj->adcReg, ADCDRV_POWER_ON); +} + +void AdcDrv_AbortChn(AdcDrvType *obj, uint8_t chn) +{ + AdcReg_AbortChn(obj->adcReg, chn); +} + +void AdcDrv_ConfigureChn(AdcDrvType *obj, uint8_t chn, AdcDrv_InChnType state) +{ + AdcReg_SetScAdCh(obj->adcReg, chn, state); +} + +void AdcDrv_GetConfig(AdcDrvType *obj, AdcDrv_ConfigType *currentConfig) +{ + /* get the conversion conversionMode */ + currentConfig->conversionMode = (AdcDrv_ConversionMode)AdcReg_GetCfg1Mode(obj->adcReg); + + /* get the ADC sample length */ + currentConfig->sampleLen = AdcReg_GetCfg2LenSmpl(obj->adcReg); + + /* get the ADC sample length after the 1st cycle + * change the input channel select(ADCH) */ + currentConfig->firstSampleLen = AdcReg_GetCfg2LenSmpl1st(obj->adcReg); + + /* get the ADC sample length after power on */ + currentConfig->pwrOnLen = AdcReg_GetCfg2LenPwrOn(obj->adcReg); + + /* get enable DMA */ + currentConfig->dmaEnable = AdcReg_GetSc2DmaEn(obj->adcReg); + + /* get hardware trigger source */ + currentConfig->trgSrcCfg.hwTrgSrc = (AdcDrv_HwTrgSrc)SimReg_GetAdcTrgSrc(obj->simReg); + + /* get software pretrigger source */ + currentConfig->trgSrcCfg.swPretrgSrc = (ADCDRV_SwPretrgSrc)SimReg_GetAdcPreTrgSwSrc(obj->simReg); + + /* get pretrigger source */ + currentConfig->trgSrcCfg.pretrgSrc = (ADCDRV_PretrgSrc)SimReg_GetAdcPreTrgSrc(obj->simReg); + + /* get the continuous mode */ + currentConfig->continuousMode = (AdcDrv_ContinuousMode)AdcReg_GetSc3Adco(obj->adcReg); + + /* get configuration the ADC compare function */ + AdcDrv_GetCmpCfg(obj, ¤tConfig->cmpCfg); + + /* get hardware average sample configuration*/ + currentConfig->avgEnable = AdcReg_GetSc3AvgE(obj->adcReg); + + /* get the hardware average sample number */ + currentConfig->avgSamplesSel = (AdcDrv_AverageMode)AdcReg_GetSc3AvgS(obj->adcReg); + + /* get configuration for each ADC channel */ + uint8_t i; + for(i = 0; i < ADCDRV_CHANNEL_NUM; i++) + { + /* get the ADC channel input */ + currentConfig->chnCfg[i].chnSel = (AdcDrv_InChnType)AdcReg_GetScAdCh(obj->adcReg, i); + + /* get the interrupt for ADC channel state*/ + currentConfig->chnCfg[i].intEnable = AdcReg_GetScAIEn(obj->adcReg, i); + } +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/adc/adc_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/adc/adc_drv.h new file mode 100644 index 0000000..3d7152e --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/adc/adc_drv.h @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _ADC_DRV_H_ +#define _ADC_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of ADC (Analog-to-digital conversion) + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup adc_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +#define ADCDRV_CHANNEL_NUM (16) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief ADC type of hardware average times selection + */ +typedef enum +{ + ADCDRV_AVERAGE_4 = 0x0U, /*!< Hardware average of 4 samples.*/ + ADCDRV_AVERAGE_8 = 0x1U, /*!< Hardware average of 8 samples.*/ + ADCDRV_AVERAGE_16 = 0x2U, /*!< Hardware average of 16 samples.*/ + ADCDRV_AVERAGE_32 = 0x3U, /*!< Hardware average of 32 samples.*/ +} AdcDrv_AverageMode; + +/*! \brief ADC type of self-test channel selection + */ +typedef enum +{ + ADCDRV_SELF_TEST_VALUE_AVSS = 0x0U, /*!< ADC self-test channel select AVSS.*/ + ADCDRV_SELF_TEST_VALUE_ONE_EIGHTH_AVSS = 0x1U, /*!< ADC self-test channel select 1/8*VREF.*/ + ADCDRV_SELF_TEST_VALUE_HALF_AVSS = 0x2U, /*!< ADC self-test channel select 1/2*VREF.*/ + ADCDRV_SELF_TEST_VALUE_SEVEN_EIGHTH_AVSS = 0x3U, /*!< ADC self-test channel select 7/8*VREF.*/ + +} AdcDrv_SelfTestValue; + +/*! \brief ADC type of resolution selection + */ +typedef enum +{ + ADCDRV_CONVERSION_8BIT = 0x0U, /*!< Selects the ADC resolution to 8-bit conversion.*/ + ADCDRV_CONVERSION_12BIT = 0x1U, /*!< Selects the ADC resolution to 12-bit conversion.*/ + ADCDRV_CONVERSION_10BIT = 0x2U, /*!< Selects the ADC resolution to 10-bit conversion.*/ + ADCDRV_CONVERSION_12BIT_2 = 0x3U, /*!< Selects the ADC resolution to 12-bit conversion.*/ +} AdcDrv_ConversionMode; + +/*! \brief ADC type of compare mode + */ +typedef enum +{ + ADCDRV_CMPMODE_NO_COMPARE = 0x0U, /*!< ADC disable compare function.*/ + ADCDRV_CMPMODE_LESSTHAN = 0x1U, /*!< Automatic compare with interrupt for less-than.*/ + ADCDRV_CMPMODE_GREATER_OR_EQUTHAN = 0x2U, /*!< Automatic compare with interrupt for greater-than or equal-to.*/ + ADCDRV_CMPMODE_OUTSIDE_EXCLUDE_BOUNDARIES = 0x3U, /*!< Automatic compare with interrupt for out-of-range(Does not contain boundaries).*/ + ADCDRV_CMPMODE_INSIDE_EXCLUDE_BOUNDARIES = 0x4U, /*!< Automatic compare with interrupt for within range(Does not contain boundaries).*/ + ADCDRV_CMPMODE_INSIDE_INCLUDE_BOUNDARIES = 0x5U, /*!< Automatic compare with interrupt for within range(Contain boundaries).*/ + ADCDRV_CMPMODE_OUTSIDE_INCLUDE_BOUNDARIES = 0x6U, /*!< Automatic compare with interrupt for out-of-range range(Contain boundaries).*/ +} AdcDrv_CmpMode; + +/*! \brief ADC type of input channel selection. + */ +typedef enum +{ + ADCDRV_INCHN_EXT0 = 0x0U, /*!< External channel 0.*/ + ADCDRV_INCHN_EXT1 = 0x1U, /*!< External channel 1.*/ + ADCDRV_INCHN_EXT3 = 0x3U, /*!< External channel 3.*/ + ADCDRV_INCHN_EXT4 = 0x4U, /*!< External channel 4.*/ + ADCDRV_INCHN_EXT5 = 0x5U, /*!< External channel 5.*/ + ADCDRV_INCHN_EXT6 = 0x6U, /*!< External channel 6.*/ + ADCDRV_INCHN_EXT7 = 0x7U, /*!< External channel 7.*/ + ADCDRV_INCHN_BG = 0x8U, /*!< Inner BG voltage.*/ + ADCDRV_INCHN_EXT9 = 0x9U, /*!< External channel 9.*/ + ADCDRV_INCHN_EXT10 = 0xAU, /*!< External channel 10.*/ + ADCDRV_INCHN_EXT11 = 0xBU, /*!< External channel 11.*/ + ADCDRV_INCHN_EXT12 = 0xCU, /*!< External channel 12.*/ + ADCDRV_INCHN_EXT13 = 0xDU, /*!< External channel 13.*/ + ADCDRV_INCHN_EXT14 = 0xEU, /*!< External channel 14.*/ + ADCDRV_INCHN_SELF_TEST = 0xFU, /*!< Inner self test voltage.*/ +} AdcDrv_InChnType; + +/*! \brief ADC type of continuous conversion mode selection. + */ +typedef enum +{ + ADCDRV_ONESHOT = 0x0U, /*!< One conversion will be performed (or one set of conversions, if AVGE is set) after a conversion is initiated.*/ + ADCDRV_CONTINUOUS = 0x1U, /*!< Continuous conversions will be performed (or continuous sets of conversions, if AVGE is set) after a conversion is initiated.*/ +} AdcDrv_ContinuousMode; + +/*! \brief ADC type of hardware trigger source selection. + */ +typedef enum +{ + ADCDRV_HW_TRGSRC_PDB = 0x0U, /*!< Select PDB output for trigger source.*/ + ADCDRV_HW_TRGSRC_TRGMUX = 0x1U, /*!< Select TRGMUX output output for trigger source.*/ +} AdcDrv_HwTrgSrc; + +/*! \brief ADC type of software pretrigger source selection. + */ +typedef enum +{ + ADCDRV_SWPRETRG_PRETRIGGER_0 = 0x4U, /*!< Select PRETRIGGER_0 for software pretrigger sources.*/ + ADCDRV_SWPRETRG_PRETRIGGER_1 = 0x5U, /*!< Select PRETRIGGER_1 for software pretrigger sources.*/ + ADCDRV_SWPRETRG_PRETRIGGER_2 = 0x6U, /*!< Select PRETRIGGER_2 for software pretrigger sources.*/ + ADCDRV_SWPRETRG_PRETRIGGER_3 = 0x7U, /*!< Select PRETRIGGER_3 for software pretrigger sources.*/ +} ADCDRV_SwPretrgSrc; + +/*! \brief ADC type of hardware pretrigger source selection. + */ +typedef enum +{ + ADCDRV_PRETRG_PDB_PRETRIGGER = 0x0U, /*!< Select PDB pretrigger for ADC pretrigger sources.*/ + ADCDRV_PRETRG_TRGMUX_PRETRIGGER = 0x1U, /*!< Select TRGMUX pretrigger for ADC pretrigger sources.*/ + ADCDRV_PRETRG_SOFTWARE_PRETRIGGER = 0x2U, /*!< Select SOFTWARE pretrigger for ADC pretrigger sources.*/ +} ADCDRV_PretrgSrc; + +/*! \brief Definition of configuration of ADC trigger/pretrigger. + */ +typedef struct _AdcDrv_TrgSrcCfgType_ +{ + AdcDrv_HwTrgSrc hwTrgSrc; /*!< Selects hardware trigger source for ADC.*/ + ADCDRV_SwPretrgSrc swPretrgSrc; /*!< Selects software pretrigger sources for ADC*/ + ADCDRV_PretrgSrc pretrgSrc; /*!< Selects pretrigger sources for ADC*/ +} AdcDrv_TrgSrcCfgType; + +/*! \brief Definition of configuration of ADC channel + */ +typedef struct _AdcDrv_ChnCfgType_ +{ + AdcDrv_InChnType chnSel; /*!< Input channel select.*/ + bool intEnable; /*!< Interrupt enable.*/ +} AdcDrv_ChnCfgType; + +/*! \brief Definition of configuration of ADC compare function + */ +typedef struct _AdcDrv_CmpCfgType_ +{ + uint16_t lowerLim; /*!< Lower limiting value in ADC compare function.*/ + uint16_t upperLim; /*!< Upper limiting value in ADC compare function.*/ + AdcDrv_CmpMode cmpMode; /*!< Select compare mode.*/ +} AdcDrv_CmpCfgType; + +/*! \brief Definition of configuration of ADC driver + */ +typedef struct _AdcDrv_ConfigType_ +{ + AdcDrv_ConversionMode conversionMode; /*!< Conversion mode select.*/ + uint8_t sampleLen; /*!< ADC sampling time.*/ + uint8_t firstSampleLen; /*!< First sample delay time.*/ + uint8_t pwrOnLen; /*!< Power on sample delay time.*/ + bool dmaEnable; /*!< Switch DMA enable.*/ + AdcDrv_CmpCfgType cmpCfg; /*!< Compare function configuration*/ + AdcDrv_ContinuousMode continuousMode; /*!< Switch continuous conversion enable*/ + AdcDrv_AverageMode avgSamplesSel; /*!< Hardware average select*/ + bool avgEnable; /*!< Switch hardware average enable*/ + AdcDrv_ChnCfgType chnCfg[ADCDRV_CHANNEL_NUM]; /*!< ADC channel configuration*/ + AdcDrv_TrgSrcCfgType trgSrcCfg; /*!< ADC trigger source configuration*/ +} AdcDrv_ConfigType; + +/* Forward declaration of ADC register */ +struct _AdcRegType_; + +/* Forward declaration of SIm register */ +struct _SimRegType_; + +/*! \brief The definition of ADC driver class + */ +typedef struct _AdcDrvType_ +{ + struct _AdcRegType_ *adcReg; + struct _SimRegType_ *simReg; +} AdcDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the ADC driver module + * + * This function initializes ADC driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to ADC driver instance + * \param[in] pdbReg : pointer to ADC register instance + * \param[in] simReg : pointer to SIM register instance + * \param[in] initParams : pointer to ADC initialization parameters + */ +extern void AdcDrv_Init(AdcDrvType *obj, struct _AdcRegType_ *adcReg, struct _SimRegType_ *simReg); + +/*! \brief Get default configures the ADC module for configuration structure + * + * This function gets default configures the ADC module for user configuration structure + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void AdcDrv_GetDefaultConfig(AdcDrv_ConfigType *userConfig); + +/*! \brief Configures the ADC module from a user configuration structure + * + * This function configures the ADC module from a user configuration structure + * + * \param[in] obj : pointer to ADC driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void AdcDrv_Configure(AdcDrvType *obj, const AdcDrv_ConfigType *userConfig); + +/*! \brief Get configures of the ADC module + * + * This function get configures of the ADC module + * + * \param[in] obj : pointer to ADC driver instance + * \param[out] currentConfig : pointer to configuration structure + */ +extern void AdcDrv_GetConfig(AdcDrvType *obj, AdcDrv_ConfigType *currentConfig); + +/*! \brief ADC clear lock trigger + * + * This function for ADC clear lock trigger + * + * \param[in] obj : pointer to ADC driver instance + */ +extern void AdcDrv_ClrLockTrg(AdcDrvType *obj); + +/*! \brief Get ADC data result + * + * This function for get ADC data result + * + * \param[in] obj : pointer to ADC driver instance + * \param[in] chn : channel number + * \return ADC data result. + */ +extern uint16_t AdcDrv_GetRn(AdcDrvType *obj, uint8_t chn); + +/*! \brief Get ADC conversion complete flag + * + * This function for get ADC conversion complete flag. + * + * \param[in] obj : pointer to ADC driver instance + * \param[in] chn : channel number + * \return ADC data result. + */ +extern bool AdcDrv_GetCocon(AdcDrvType *obj, uint8_t chn); + +/*! \brief Disable ADC + * + * This function for disable ADC + * + * \param[in] obj : pointer to ADC driver instance + */ +extern void AdcDrv_DisableAdc(AdcDrvType *obj); + +/*! \brief Enable ADC + * + * This function for enable ADC + * + * \param[in] obj : pointer to ADC driver instance + */ +extern void AdcDrv_EnableAdc(AdcDrvType *obj); + +/*! \brief Abort ADC channel n + * + * This function for abort ADC channel n + * + * \param[in] obj : pointer to ADC driver instance + * \param[in] chn : channel number + */ +extern void AdcDrv_AbortChn(AdcDrvType *obj, uint8_t chn); + +/*! \brief Selects one of the input channels. + * + * This function for selects one of the input channels. + * + * \param[in] obj : pointer to ADC driver instance + * \param[in] chn : channel number + * \param[in] state : input channel selection. + */ +extern void AdcDrv_ConfigureChn(AdcDrvType *obj, uint8_t chn, AdcDrv_InChnType state); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _ADC_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/clock/clock_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/clock/clock_drv.c new file mode 100644 index 0000000..71d31c7 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/clock/clock_drv.c @@ -0,0 +1,2596 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "clock_drv.h" +#include "rcm_reg.h" +#include "scg0_reg.h" +#include "scg1_reg.h" +#include "scg2_reg.h" +#include "pcc0_reg.h" +#include "pcc1_reg.h" +#include "../../CVM011x_features.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* Definitions for LPO frequencies */ +#define LPO_128K_FREQUENCY (128000UL) +#define LPO_32K_FREQUENCY (32000UL) +#define LPO_1K_FREQUENCY (1000UL) + +/* Definitions for all the get and set clock interface */ +#define GET_FREQ_FUNC_DEF(module) static inline bool ClockDrv_Get##module##Freq(const ClockDrvType *obj, uint32_t *frequency) +#define GET_FREQ_FUNC(module) ClockDrv_Get##module##Freq +#define CONFIG_CLOCK_FUNC_DEF(module) static inline bool ClockDrv_Set##module##Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +#define CONFIG_CLOCK_FUNC(module) ClockDrv_Set##module##Clock + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Module clock function table element definition + */ +typedef struct _ClockDrv_ModuleClkFuncType_ +{ + bool (*getFreqFunc)(const ClockDrvType *, uint32_t *); + bool (*setClockFunc)(ClockDrvType *, const ClockDrv_ModuleClkConfigType *); +} ClockDrv_ModuleClkFuncType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/* Forward decleratios for all get and set clock interface */ +GET_FREQ_FUNC_DEF(Sosc); +CONFIG_CLOCK_FUNC_DEF(Sosc); +GET_FREQ_FUNC_DEF(Sirc); +GET_FREQ_FUNC_DEF(Pll); +CONFIG_CLOCK_FUNC_DEF(Pll); +GET_FREQ_FUNC_DEF(SoscDiv); +CONFIG_CLOCK_FUNC_DEF(SoscDiv); +GET_FREQ_FUNC_DEF(SoscDivMft); +CONFIG_CLOCK_FUNC_DEF(SoscDivMft); +GET_FREQ_FUNC_DEF(SircDiv); +CONFIG_CLOCK_FUNC_DEF(SircDiv); +GET_FREQ_FUNC_DEF(SircDivMft); +CONFIG_CLOCK_FUNC_DEF(SircDivMft); +GET_FREQ_FUNC_DEF(PllDiv); +CONFIG_CLOCK_FUNC_DEF(PllDiv); +GET_FREQ_FUNC_DEF(PllDivMft); +CONFIG_CLOCK_FUNC_DEF(PllDivMft); +GET_FREQ_FUNC_DEF(Sys); +CONFIG_CLOCK_FUNC_DEF(Sys); +GET_FREQ_FUNC_DEF(Core); +CONFIG_CLOCK_FUNC_DEF(Core); +GET_FREQ_FUNC_DEF(Apb); +CONFIG_CLOCK_FUNC_DEF(Apb); +GET_FREQ_FUNC_DEF(Fls); +CONFIG_CLOCK_FUNC_DEF(Fls); +GET_FREQ_FUNC_DEF(ClkOut); +CONFIG_CLOCK_FUNC_DEF(ClkOut); +GET_FREQ_FUNC_DEF(RtcPadIn); +GET_FREQ_FUNC_DEF(Lpo1k); +CONFIG_CLOCK_FUNC_DEF(Lpo1k); +GET_FREQ_FUNC_DEF(Lpo32k); +CONFIG_CLOCK_FUNC_DEF(Lpo32k); +GET_FREQ_FUNC_DEF(Lpo128k); +CONFIG_CLOCK_FUNC_DEF(Lpo32k); +GET_FREQ_FUNC_DEF(Cmp); +CONFIG_CLOCK_FUNC_DEF(Cmp); +GET_FREQ_FUNC_DEF(PortA); +CONFIG_CLOCK_FUNC_DEF(PortA); +GET_FREQ_FUNC_DEF(PortB); +CONFIG_CLOCK_FUNC_DEF(PortB); +GET_FREQ_FUNC_DEF(PortC); +CONFIG_CLOCK_FUNC_DEF(PortC); +GET_FREQ_FUNC_DEF(PortD); +CONFIG_CLOCK_FUNC_DEF(PortD); +GET_FREQ_FUNC_DEF(PortE); +CONFIG_CLOCK_FUNC_DEF(PortE); +GET_FREQ_FUNC_DEF(Lptmr); +CONFIG_CLOCK_FUNC_DEF(Lptmr); +GET_FREQ_FUNC_DEF(Lpit); +CONFIG_CLOCK_FUNC_DEF(Lpit); +GET_FREQ_FUNC_DEF(RtcCnt); +CONFIG_CLOCK_FUNC_DEF(RtcCnt); +GET_FREQ_FUNC_DEF(PortAFlt); +CONFIG_CLOCK_FUNC_DEF(PortAFlt); +GET_FREQ_FUNC_DEF(PortBFlt); +CONFIG_CLOCK_FUNC_DEF(PortBFlt); +GET_FREQ_FUNC_DEF(PortCFlt); +CONFIG_CLOCK_FUNC_DEF(PortCFlt); +GET_FREQ_FUNC_DEF(PortDFlt); +CONFIG_CLOCK_FUNC_DEF(PortDFlt); +GET_FREQ_FUNC_DEF(PortEFlt); +CONFIG_CLOCK_FUNC_DEF(PortEFlt); +GET_FREQ_FUNC_DEF(ExtFlt); +CONFIG_CLOCK_FUNC_DEF(ExtFlt); +GET_FREQ_FUNC_DEF(Dma); +CONFIG_CLOCK_FUNC_DEF(Dma); +GET_FREQ_FUNC_DEF(Mscm); +CONFIG_CLOCK_FUNC_DEF(Mscm); +GET_FREQ_FUNC_DEF(Crc); +CONFIG_CLOCK_FUNC_DEF(Crc); +GET_FREQ_FUNC_DEF(Eim); +CONFIG_CLOCK_FUNC_DEF(Eim); +GET_FREQ_FUNC_DEF(Erm); +CONFIG_CLOCK_FUNC_DEF(Erm); +GET_FREQ_FUNC_DEF(Fhu); +CONFIG_CLOCK_FUNC_DEF(Fhu); +GET_FREQ_FUNC_DEF(Adc); +CONFIG_CLOCK_FUNC_DEF(Adc); +GET_FREQ_FUNC_DEF(Pdb); +CONFIG_CLOCK_FUNC_DEF(Pdb); +GET_FREQ_FUNC_DEF(Spi0); +CONFIG_CLOCK_FUNC_DEF(Spi0); +GET_FREQ_FUNC_DEF(Spi1); +CONFIG_CLOCK_FUNC_DEF(Spi1); +GET_FREQ_FUNC_DEF(Uart0); +CONFIG_CLOCK_FUNC_DEF(Uart0); +GET_FREQ_FUNC_DEF(Uart1); +CONFIG_CLOCK_FUNC_DEF(Uart1); +GET_FREQ_FUNC_DEF(Uart2); +CONFIG_CLOCK_FUNC_DEF(Uart2); +GET_FREQ_FUNC_DEF(I2C); +CONFIG_CLOCK_FUNC_DEF(I2C); +GET_FREQ_FUNC_DEF(I2SM); +CONFIG_CLOCK_FUNC_DEF(I2SM); +GET_FREQ_FUNC_DEF(I2SS); +CONFIG_CLOCK_FUNC_DEF(I2SS); +GET_FREQ_FUNC_DEF(PwmLite0); +CONFIG_CLOCK_FUNC_DEF(PwmLite0); +GET_FREQ_FUNC_DEF(PwmLite1); +CONFIG_CLOCK_FUNC_DEF(PwmLite1); +GET_FREQ_FUNC_DEF(Mft0); +CONFIG_CLOCK_FUNC_DEF(Mft0); +GET_FREQ_FUNC_DEF(Mft1); +CONFIG_CLOCK_FUNC_DEF(Mft1); +GET_FREQ_FUNC_DEF(Cmus); +CONFIG_CLOCK_FUNC_DEF(Cmus); +GET_FREQ_FUNC_DEF(Cmup); +CONFIG_CLOCK_FUNC_DEF(Cmup); +GET_FREQ_FUNC_DEF(Tclk0); +GET_FREQ_FUNC_DEF(Tclk1); +GET_FREQ_FUNC_DEF(Tclk2); +GET_FREQ_FUNC_DEF(ExtMft0); +CONFIG_CLOCK_FUNC_DEF(ExtMft0); +GET_FREQ_FUNC_DEF(ExtMft1); +CONFIG_CLOCK_FUNC_DEF(ExtMft1); +GET_FREQ_FUNC_DEF(FixMft0); +CONFIG_CLOCK_FUNC_DEF(FixMft0); +GET_FREQ_FUNC_DEF(FixMft1); +CONFIG_CLOCK_FUNC_DEF(FixMft1); +GET_FREQ_FUNC_DEF(Mpu); +CONFIG_CLOCK_FUNC_DEF(Mpu); + +/* Function table for all get and set clock interface */ +const ClockDrv_ModuleClkFuncType c_clockFuncTable[CLOCKDRV_CLOCK_NUM] = { + {GET_FREQ_FUNC(Sosc), CONFIG_CLOCK_FUNC(Sosc) }, /* CLOCKDRV_SOSC */ + {GET_FREQ_FUNC(Sirc), NULL }, /* CLOCKDRV_SIRC */ + {GET_FREQ_FUNC(Pll), CONFIG_CLOCK_FUNC(Pll) }, /* CLOCKDRV_PLL */ + {GET_FREQ_FUNC(SoscDiv), CONFIG_CLOCK_FUNC(SoscDiv) }, /* CLOCKDRV_SOSC_DIV */ + {GET_FREQ_FUNC(SoscDivMft), CONFIG_CLOCK_FUNC(SoscDivMft)}, /* CLOCKDRV_SOSC_DIV_MFT */ + {GET_FREQ_FUNC(SircDiv), CONFIG_CLOCK_FUNC(SircDiv) }, /* CLOCKDRV_SIRC_DIV */ + {GET_FREQ_FUNC(SircDivMft), CONFIG_CLOCK_FUNC(SircDivMft)}, /* CLOCKDRV_SIRC_DIV_MFT */ + {GET_FREQ_FUNC(PllDiv), CONFIG_CLOCK_FUNC(PllDiv) }, /* CLOCKDRV_PLL_DIV */ + {GET_FREQ_FUNC(PllDivMft), CONFIG_CLOCK_FUNC(PllDivMft) }, /* CLOCKDRV_PLL_DIV_MFT */ + {GET_FREQ_FUNC(Sys), CONFIG_CLOCK_FUNC(Sys) }, /* CLOCKDRV_SYS */ + {GET_FREQ_FUNC(Core), CONFIG_CLOCK_FUNC(Core) }, /* CLOCKDRV_CORE */ + {GET_FREQ_FUNC(Apb), CONFIG_CLOCK_FUNC(Apb) }, /* CLOCKDRV_APB */ + {GET_FREQ_FUNC(Fls), CONFIG_CLOCK_FUNC(Fls) }, /* CLOCKDRV_FLS */ + {GET_FREQ_FUNC(ClkOut), CONFIG_CLOCK_FUNC(ClkOut) }, /* CLOCKDRV_CLKOUT */ + {GET_FREQ_FUNC(RtcPadIn), NULL }, /* CLOCKDRV_RTC_PADIN */ + {GET_FREQ_FUNC(Lpo1k), CONFIG_CLOCK_FUNC(Lpo1k) }, /* CLOCKDRV_LPO_1K */ + {GET_FREQ_FUNC(Lpo32k), CONFIG_CLOCK_FUNC(Lpo32k) }, /* CLOCKDRV_LPO_32K */ + {GET_FREQ_FUNC(Lpo128k), NULL }, /* CLOCKDRV_LPO_128K */ + {GET_FREQ_FUNC(Cmp), CONFIG_CLOCK_FUNC(Cmp) }, /* CLOCKDRV_CMP */ + {GET_FREQ_FUNC(PortA), CONFIG_CLOCK_FUNC(PortA) }, /* CLOCKDRV_PORTA */ + {GET_FREQ_FUNC(PortB), CONFIG_CLOCK_FUNC(PortB) }, /* CLOCKDRV_PORTB */ + {GET_FREQ_FUNC(PortC), CONFIG_CLOCK_FUNC(PortC) }, /* CLOCKDRV_PORTC */ + {GET_FREQ_FUNC(PortD), CONFIG_CLOCK_FUNC(PortD) }, /* CLOCKDRV_PORTD */ + {GET_FREQ_FUNC(PortE), CONFIG_CLOCK_FUNC(PortE) }, /* CLOCKDRV_PORTE */ + {GET_FREQ_FUNC(Lptmr), CONFIG_CLOCK_FUNC(Lptmr) }, /* CLOCKDRV_LPTMR */ + {GET_FREQ_FUNC(Lpit), CONFIG_CLOCK_FUNC(Lpit) }, /* CLOCKDRV_LPIT */ + {GET_FREQ_FUNC(RtcCnt), CONFIG_CLOCK_FUNC(RtcCnt) }, /* CLOCKDRV_RTC_CNT */ + {GET_FREQ_FUNC(PortAFlt), CONFIG_CLOCK_FUNC(PortAFlt) }, /* CLOCKDRV_PORTA_FLT */ + {GET_FREQ_FUNC(PortBFlt), CONFIG_CLOCK_FUNC(PortBFlt) }, /* CLOCKDRV_PORTB_FLT */ + {GET_FREQ_FUNC(PortCFlt), CONFIG_CLOCK_FUNC(PortCFlt) }, /* CLOCKDRV_PORTC_FLT */ + {GET_FREQ_FUNC(PortDFlt), CONFIG_CLOCK_FUNC(PortDFlt) }, /* CLOCKDRV_PORTD_FLT */ + {GET_FREQ_FUNC(PortEFlt), CONFIG_CLOCK_FUNC(PortEFlt) }, /* CLOCKDRV_PORTE_FLT */ + {GET_FREQ_FUNC(ExtFlt), CONFIG_CLOCK_FUNC(ExtFlt) }, /* CLOCKDRV_EXT_FLT */ + {GET_FREQ_FUNC(Dma), CONFIG_CLOCK_FUNC(Dma) }, /* CLOCKDRV_DMA */ + {GET_FREQ_FUNC(Mscm), CONFIG_CLOCK_FUNC(Mscm) }, /* CLOCKDRV_MSCM */ + {GET_FREQ_FUNC(Crc), CONFIG_CLOCK_FUNC(Crc) }, /* CLOCKDRV_CRC */ + {GET_FREQ_FUNC(Eim), CONFIG_CLOCK_FUNC(Eim) }, /* CLOCKDRV_EIM */ + {GET_FREQ_FUNC(Erm), CONFIG_CLOCK_FUNC(Erm) }, /* CLOCKDRV_ERM */ + {GET_FREQ_FUNC(Fhu), CONFIG_CLOCK_FUNC(Fhu) }, /* CLOCKDRV_FHU */ + {GET_FREQ_FUNC(Adc), CONFIG_CLOCK_FUNC(Adc) }, /* CLOCKDRV_ADC */ + {GET_FREQ_FUNC(Pdb), CONFIG_CLOCK_FUNC(Pdb) }, /* CLOCKDRV_PDB */ + {GET_FREQ_FUNC(Spi0), CONFIG_CLOCK_FUNC(Spi0) }, /* CLOCKDRV_SPI0 */ + {GET_FREQ_FUNC(Spi1), CONFIG_CLOCK_FUNC(Spi1) }, /* CLOCKDRV_SPI1 */ + {GET_FREQ_FUNC(Uart0), CONFIG_CLOCK_FUNC(Uart0) }, /* CLOCKDRV_UART0 */ + {GET_FREQ_FUNC(Uart1), CONFIG_CLOCK_FUNC(Uart1) }, /* CLOCKDRV_UART1 */ + {GET_FREQ_FUNC(Uart2), CONFIG_CLOCK_FUNC(Uart2) }, /* CLOCKDRV_UART2 */ + {GET_FREQ_FUNC(I2C), CONFIG_CLOCK_FUNC(I2C) }, /* CLOCKDRV_I2C */ + {GET_FREQ_FUNC(I2SM), CONFIG_CLOCK_FUNC(I2SM) }, /* CLOCKDRV_I2SM */ + {GET_FREQ_FUNC(I2SS), CONFIG_CLOCK_FUNC(I2SS) }, /* CLOCKDRV_I2SS */ + {GET_FREQ_FUNC(PwmLite0), CONFIG_CLOCK_FUNC(PwmLite0) }, /* CLOCKDRV_PWMLITE0 */ + {GET_FREQ_FUNC(PwmLite1), CONFIG_CLOCK_FUNC(PwmLite1) }, /* CLOCKDRV_PWMLITE1 */ + {GET_FREQ_FUNC(Mft0), CONFIG_CLOCK_FUNC(Mft0) }, /* CLOCKDRV_MFT0 */ + {GET_FREQ_FUNC(Mft1), CONFIG_CLOCK_FUNC(Mft1) }, /* CLOCKDRV_MFT1 */ + {GET_FREQ_FUNC(Cmus), CONFIG_CLOCK_FUNC(Cmus) }, /* CLOCKDRV_CMUS */ + {GET_FREQ_FUNC(Cmup), CONFIG_CLOCK_FUNC(Cmup) }, /* CLOCKDRV_CMUP */ + {GET_FREQ_FUNC(Tclk0), NULL }, /* CLOCKDRV_TCLK0 */ + {GET_FREQ_FUNC(Tclk1), NULL }, /* CLOCKDRV_TCLK1 */ + {GET_FREQ_FUNC(Tclk2), NULL }, /* CLOCKDRV_TCLK2 */ + {GET_FREQ_FUNC(ExtMft0), CONFIG_CLOCK_FUNC(ExtMft0) }, /* CLOCKDRV_EXT_MFT0 */ + {GET_FREQ_FUNC(ExtMft1), CONFIG_CLOCK_FUNC(ExtMft1) }, /* CLOCKDRV_EXT_MFT1 */ + {GET_FREQ_FUNC(FixMft0), CONFIG_CLOCK_FUNC(FixMft0) }, /* CLOCKDRV_FIX_MFT0 */ + {GET_FREQ_FUNC(FixMft1), CONFIG_CLOCK_FUNC(FixMft1) }, /* CLOCKDRV_FIX_MFT1 */ + {GET_FREQ_FUNC(Mpu), CONFIG_CLOCK_FUNC(Mpu) }, /* CLOCKDRV_MPU */ +}; + +/******************************************************************************* + * the functions + ******************************************************************************/ + +static inline bool ClockDrv_GetSoscFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Scg0Reg_GetOscCtrlEnSosc(obj->scg0Reg) && Scg0Reg_GetStatusSoscRdy(obj->scg0Reg)) + { + *frequency = obj->xtalClkFreq; + return true; + } + return false; +} + +static inline bool ClockDrv_SetSoscClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + /* Disable SOSC first, before configure */ + Scg0Reg_SetOscCtrlEnSosc(obj->scg0Reg, 0); + + /* Enable SOSC if required */ + if(moduleClkConfig->gating) + { + uint8_t soscRange = obj->xtalClkFreq == 4000000 ? 0 : (obj->xtalClkFreq <= 8000000 ? 1 : (obj->xtalClkFreq <= 24000000 ? 2 : (obj->xtalClkFreq <= 40000000 ? 3 : 4))); + if(4 == soscRange) + { + return false; + } + /* Set SOSC frequency range */ + Scg0Reg_SetOscCtrlRange(obj->scg0Reg, soscRange); + /* Disable external EXTAL clock in, cannot enable at the same time */ + Scg0Reg_SetOscCtrlEnExtClk(obj->scg0Reg, 0); + /* Enable SOSC */ + Scg0Reg_SetOscCtrlEnSosc(obj->scg0Reg, 1); + while(Scg0Reg_GetStatusSoscRdy(obj->scg0Reg) == 0) + { + ; /* Wait until SOSC is locked */ + } + } + + return true; +} + +static inline bool ClockDrv_GetSircFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + /* SIRC always enabled */ + if(Scg0Reg_GetStatusSircRdy(obj->scg0Reg)) + { + *frequency = obj->sircFreq; + return true; + } + return false; +} + +static inline bool ClockDrv_GetPllFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Scg0Reg_GetPllCtrl0PllEn(obj->scg0Reg) && Scg0Reg_GetStatusPllLock(obj->scg0Reg)) + { + uint32_t freq; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Scg0Reg_GetPllCtrl1PllClkinSel(obj->scg0Reg)) + { + case 0: /* SOSC clock as source */ + retval = ClockDrv_GetSoscFreq(obj, &freq); + break; + case 1: /* SIRC clock as source */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + /* If the source clock is valid */ + if(false == retval) + { + return false; + } + + /* Get the PLL pre-divider */ + uint32_t preDiv = 1; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Scg0Reg_GetPllCtrl0PllPreDiv(obj->scg0Reg)) + { + case 0: + preDiv = 1; + break; + case 1: + preDiv = 2; + break; + case 2: + preDiv = 4; + break; + case 3: + preDiv = 8; + break; + default: + /* should not get here */ + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + /* Get the PLL feedback divider setting */ + uint32_t mult = Scg0Reg_GetPllCtrl0PllM(obj->scg0Reg); + mult = (mult == 0 ? 128 : mult); + /* Get the PLL feedback divider setting */ + uint32_t postDiv = Scg0Reg_GetPllCtrl0PllPosDiv(obj->scg0Reg); + postDiv = (postDiv == 0 ? 8 : postDiv); + /* Get the PLL Feedback clock divider pre-scaler */ + uint32_t fblSel = Scg0Reg_GetPllCtrl0PllFdkSel(obj->scg0Reg); + fblSel = fblSel + 1; + + /* Calculate the final PLL frequency */ + *frequency = (freq * mult * fblSel) / (2 * preDiv * postDiv); + + retval = true; + } + + return retval; +} + +bool ClockDrv_SetPllClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + /* Disable PLL first, before configure */ + Scg0Reg_SetPllCtrl0PllEn(obj->scg0Reg, 0); + + bool retval = true; + switch(moduleClkConfig->source) + { + case CLOCKDRV_SOSC: /* SOSC clock as source */ + Scg0Reg_SetPllCtrl1PllClkinSel(obj->scg0Reg, 0); + break; + case CLOCKDRV_SIRC: /* SIRC clock as source */ + Scg0Reg_SetPllCtrl1PllClkinSel(obj->scg0Reg, 1); + break; + default: + retval = false; + break; + } + /* If the source clock is valid */ + if(false == retval) + { + return false; + } + + /* Set the PLL pre-divider */ + uint8_t preDiv = moduleClkConfig->pllConfig.preDiv == 1 ? 0 : (moduleClkConfig->pllConfig.preDiv == 2 ? 1 : (moduleClkConfig->pllConfig.preDiv == 4 ? 2 : (moduleClkConfig->pllConfig.preDiv == 8 ? 3 : 0xff))); + /* If PLL pre-divider is valid */ + if(0xff == preDiv) + { + return false; + } + Scg0Reg_SetPllCtrl0PllPreDiv(obj->scg0Reg, preDiv); + + /* Set the PLL feedback divider */ + if(moduleClkConfig->mult >= 1 && moduleClkConfig->mult <= 128) + { + Scg0Reg_SetPllCtrl0PllM(obj->scg0Reg, moduleClkConfig->mult == 128 ? 0 : moduleClkConfig->mult); + } + else + { + return false; + } + + /* Set the post-divider */ + if(moduleClkConfig->pllConfig.postDiv >= 1 && moduleClkConfig->pllConfig.postDiv <= 8) + { + Scg0Reg_SetPllCtrl0PllPosDiv(obj->scg0Reg, moduleClkConfig->pllConfig.postDiv == 8 ? 0 : moduleClkConfig->pllConfig.postDiv); + } + else + { + return false; + } + + /* Set the feedback clock divider pre-scaler */ + if(moduleClkConfig->pllConfig.fblSel == 1 || moduleClkConfig->pllConfig.fblSel == 2) + { + Scg0Reg_SetPllCtrl0PllFdkSel(obj->scg0Reg, moduleClkConfig->pllConfig.fblSel - 1); + } + else + { + return false; + } + + /* Enable PLL if required */ + if(moduleClkConfig->gating) + { + Scg0Reg_SetPllCtrl0PllEn(obj->scg0Reg, 1); + while(Scg0Reg_GetStatusPllLock(obj->scg0Reg) == 0) + { + ; /* Wait until PLL is locked */ + } + } + + return retval; +} + +static inline bool ClockDrv_GetSoscDivFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetSoscCfgEn(obj->scg2Reg)) + { + retval = ClockDrv_GetSoscFreq(obj, &freq); + if(retval) + { + uint32_t div = ((uint32_t)1UL) << Scg2Reg_GetSoscCfgDiv(obj->scg2Reg); + if(div <= 64) + { + *frequency = freq / div; + } + else + { + retval = false; + } + } + } + + return retval; +} + +static inline bool ClockDrv_SetSoscDivClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Scg2Reg_SetSoscCfgEn(obj->scg2Reg, 0); + + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : (moduleClkConfig->div == 16 ? 4 : (moduleClkConfig->div == 32 ? 5 : (moduleClkConfig->div == 64 ? 6 : 7)))))); + if(div != 7) + { + Scg2Reg_SetSoscCfgDiv(obj->scg2Reg, div); + retval = true; + } + /* Enable if required */ + Scg2Reg_SetSoscCfgEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetSoscDivMftFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetSoscMftEn(obj->scg2Reg)) + { + retval = ClockDrv_GetSoscFreq(obj, &freq); + if(retval) + { + uint32_t div = ((uint32_t)1UL) << Scg2Reg_GetSoscMftDiv(obj->scg2Reg); + if(div <= 64) + { + *frequency = freq / div; + } + else + { + retval = false; + } + } + } + + return retval; +} + +static inline bool ClockDrv_SetSoscDivMftClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Scg2Reg_SetSoscMftEn(obj->scg2Reg, 0); + + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : (moduleClkConfig->div == 16 ? 4 : (moduleClkConfig->div == 32 ? 5 : (moduleClkConfig->div == 64 ? 6 : 7)))))); + if(div != 7) + { + Scg2Reg_SetSoscMftDiv(obj->scg2Reg, div); + retval = true; + } + /* Enable if required */ + Scg2Reg_SetSoscMftEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetSircDivFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetSircCfgEn(obj->scg2Reg)) + { + retval = ClockDrv_GetSircFreq(obj, &freq); + if(retval) + { + uint32_t div = ((uint32_t)1UL) << Scg2Reg_GetSircCfgDiv(obj->scg2Reg); + if(div <= 64) + { + *frequency = freq / div; + } + else + { + retval = false; + } + } + } + + return retval; +} + +static inline bool ClockDrv_SetSircDivClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Scg2Reg_SetSircCfgEn(obj->scg2Reg, 0); + + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : (moduleClkConfig->div == 16 ? 4 : (moduleClkConfig->div == 32 ? 5 : (moduleClkConfig->div == 64 ? 6 : 7)))))); + if(div != 7) + { + Scg2Reg_SetSircCfgDiv(obj->scg2Reg, div); + retval = true; + } + /* Enable if required */ + Scg2Reg_SetSircCfgEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetSircDivMftFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetSircMftEn(obj->scg2Reg)) + { + retval = ClockDrv_GetSircFreq(obj, &freq); + if(retval) + { + uint32_t div = ((uint32_t)1UL) << Scg2Reg_GetSircMftDiv(obj->scg2Reg); + if(div <= 64) + { + *frequency = freq / div; + } + else + { + retval = false; + } + } + } + + return retval; +} + +static inline bool ClockDrv_SetSircDivMftClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Scg2Reg_SetSircMftEn(obj->scg2Reg, 0); + + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : (moduleClkConfig->div == 16 ? 4 : (moduleClkConfig->div == 32 ? 5 : (moduleClkConfig->div == 64 ? 6 : 7)))))); + if(div != 7) + { + Scg2Reg_SetSircMftDiv(obj->scg2Reg, div); + retval = true; + } + /* Enable if required */ + Scg2Reg_SetSircMftEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetPllDivFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetPllCfgEn(obj->scg2Reg)) + { + retval = ClockDrv_GetPllFreq(obj, &freq); + if(retval) + { + uint32_t div = ((uint32_t)1UL) << Scg2Reg_GetPllCfgDiv(obj->scg2Reg); + if(div <= 64) + { + *frequency = freq / div; + } + else + { + retval = false; + } + } + } + + return retval; +} + +static inline bool ClockDrv_SetPllDivClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Scg2Reg_SetPllCfgEn(obj->scg2Reg, 0); + + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : (moduleClkConfig->div == 16 ? 4 : (moduleClkConfig->div == 32 ? 5 : (moduleClkConfig->div == 64 ? 6 : 7)))))); + if(div != 7) + { + Scg2Reg_SetPllCfgDiv(obj->scg2Reg, div); + retval = true; + } + /* Enable if required */ + Scg2Reg_SetPllCfgEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetPllDivMftFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetPllMftEn(obj->scg2Reg)) + { + retval = ClockDrv_GetPllFreq(obj, &freq); + if(retval) + { + uint32_t div = ((uint32_t)1UL) << Scg2Reg_GetPllMftDiv(obj->scg2Reg); + if(div <= 64) + { + *frequency = freq / div; + } + else + { + retval = false; + } + } + } + + return retval; +} + +static inline bool ClockDrv_SetPllDivMftClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Scg2Reg_SetPllMftEn(obj->scg2Reg, 0); + + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : (moduleClkConfig->div == 16 ? 4 : (moduleClkConfig->div == 32 ? 5 : (moduleClkConfig->div == 64 ? 6 : 7)))))); + if(div != 7) + { + Scg2Reg_SetPllMftDiv(obj->scg2Reg, div); + retval = true; + } + /* Enable if required */ + Scg2Reg_SetPllMftEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetSysFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + + /* Get system clock freq */ + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Scg2Reg_GetCsrSysSt(obj->scg2Reg)) + { + case 0: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, frequency); + break; + case 1: /* clk_sosc */ + retval = ClockDrv_GetSoscFreq(obj, frequency); + break; + case 2: /* clk_pll */ + retval = ClockDrv_GetPllFreq(obj, frequency); + break; + case 3: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, frequency); + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetSysClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL ? 2 : 0xff)); + if(select == 0xff) + { + return false; + } + + Scg2Reg_SetCsrSrcSys(obj->scg2Reg, select); + while(Scg2Reg_GetCsrSysSt(obj->scg2Reg) != select) + { + ; + } + + return true; +} + +static inline bool ClockDrv_GetCoreFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + /* Get system clock freq */ + uint32_t sysFreq; + retval = ClockDrv_GetSysFreq(obj, &sysFreq); + if(false == retval) + { + return false; + } + /* Get core clock freq */ + *frequency = sysFreq / (Scg1Reg_GetCkSrcSysDiv(obj->scg1Reg) + 1U); + + return retval; +} + +static inline bool ClockDrv_SetCoreClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + /* The clock source is clk_sys */ + if(moduleClkConfig->div >= 1 && moduleClkConfig->div <= 16) + { + Scg1Reg_SetCkSrcSysDiv(obj->scg1Reg, moduleClkConfig->div - 1); + return true; + } + return false; +} + +static inline bool ClockDrv_GetApbFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + /* Get core clock freq */ + uint32_t coreFreq; + retval = ClockDrv_GetCoreFreq(obj, &coreFreq); + if(false == retval) + { + return false; + } + /* Get APB clock freq */ + *frequency = coreFreq / (Scg2Reg_GetCsrDivAips(obj->scg2Reg) + 1U); + + return retval; +} + +static inline bool ClockDrv_SetApbClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + /* The clock source is core clock */ + if(moduleClkConfig->div >= 1 && moduleClkConfig->div <= 16) + { + Scg2Reg_SetCsrDivAips(obj->scg2Reg, moduleClkConfig->div - 1); + return true; + } + return false; +} + +static inline bool ClockDrv_GetFlsFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + /* Get core clock freq */ + uint32_t srcFreq; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetFlsCtlCntSrc(obj->pcc1Reg)) + { + case 0: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &srcFreq); + break; + case 1: /* clk_sosc */ + retval = ClockDrv_GetSoscFreq(obj, &srcFreq); + break; + case 2: /* clk_pll */ + retval = ClockDrv_GetPllFreq(obj, &srcFreq); + break; + case 3: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &srcFreq); + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + if(false == retval) + { + return false; + } + /* Get flash clock freq */ + if(Pcc1Reg_GetFlsCtlCkEn(obj->pcc1Reg)) + { + *frequency = srcFreq / (Pcc1Reg_GetFlsCtlCntDiv(obj->pcc1Reg) + 1U); + } + else + { + retval = false; + } + + return retval; +} + +static inline bool ClockDrv_SetFlsClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + /* The clock source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL ? 2 : 0xff)); + if(select == 0xff) + { + return false; + } + + if(moduleClkConfig->div >= 1 && moduleClkConfig->div <= 16) + { + Pcc1Reg_SetFlsCtlCntSrc(obj->pcc1Reg, select); + Pcc1Reg_SetFlsCtlCntDiv(obj->pcc1Reg, moduleClkConfig->div - 1); + Pcc1Reg_SetFlsCtlCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; + } + return false; +} + +static inline bool ClockDrv_GetClkOutFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Scg2Reg_GetClkOutEn(obj->scg2Reg) == 0) + { + return false; + } + + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetClkOutSrc1(obj->scg2Reg) == 0) + { + /* SCG out selected */ + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Scg2Reg_GetClkOutSrc0(obj->scg2Reg)) + { + case 0: + /* clk_cnt_fls */ + retval = ClockDrv_GetFlsFreq(obj, &freq); + break; + case 1: + /* clk_sosc */ + retval = ClockDrv_GetSoscFreq(obj, &freq); + break; + case 2: + /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + case 3: + /* clk_pll */ + retval = ClockDrv_GetPllFreq(obj, &freq); + break; + case 4: + /* clk_core */ + retval = ClockDrv_GetCoreFreq(obj, &freq); + break; + case 5: + /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, &freq); + break; + case 6: + /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, &freq); + break; + case 7: + /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, &freq); + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + } + else + { + switch(Scg2Reg_GetClkOutSrc1(obj->scg2Reg)) + { + case 1: + /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, &freq); + break; + case 2: + /* clk_lpo128, this is alway available */ + retval = ClockDrv_GetLpo128kFreq(obj, &freq); + break; + case 3: + /* clk_lpo32 */ + retval = ClockDrv_GetLpo32kFreq(obj, &freq); + break; + case 4: + /* clk_lpo1 */ + retval = ClockDrv_GetLpo1kFreq(obj, &freq); + break; + case 5: + /* clk_rtc_cnt */ + retval = ClockDrv_GetRtcCntFreq(obj, &freq); + break; + case 6: + /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + case 7: + /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + default: + break; + } + } + + if(true == retval) + { + *frequency = freq / (Scg2Reg_GetClkOutDiv(obj->scg2Reg) + 1); + } + + return retval; +} + +static inline bool ClockDrv_SetClkOutClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + + /* Disable first before configure */ + Scg2Reg_SetClkOutEn(obj->scg2Reg, 0); + + switch(moduleClkConfig->source) + { + case CLOCKDRV_FLS: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 0); + break; + case CLOCKDRV_SOSC: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 1); + break; + case CLOCKDRV_SIRC: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 2); + break; + case CLOCKDRV_PLL: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 3); + break; + case CLOCKDRV_CORE: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 4); + break; + case CLOCKDRV_APB: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 5); + break; + case CLOCKDRV_SOSC_DIV: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 6); + break; + case CLOCKDRV_SIRC_DIV: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 7); + break; + case CLOCKDRV_PLL_DIV: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 1); + break; + case CLOCKDRV_LPO_128K: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 2); + break; + case CLOCKDRV_LPO_32K: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 3); + break; + case CLOCKDRV_LPO_1K: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 4); + break; + case CLOCKDRV_RTC_CNT: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 5); + break; + default: + retval = false; + break; + } + + if(retval) + { + if(moduleClkConfig->div >= 1 && moduleClkConfig->div <= 8) + { + Scg2Reg_SetClkOutDiv(obj->scg2Reg, moduleClkConfig->div - 1); + } + else + { + retval = false; + } + } + + /* Enable if required */ + Scg2Reg_SetClkOutEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetRtcPadInFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + (void)obj; /* Unused, avoid warning */ + *frequency = obj->rtcClkInFreq; + return true; +} + +static inline bool ClockDrv_GetLpo1kFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc0Reg_GetLpo1Cken(obj->pcc0Reg)) + { + *frequency = LPO_1K_FREQUENCY; + return true; + } + return false; +} + +static inline bool ClockDrv_SetLpo1kClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetLpo1Cken(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetLpo32kFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc0Reg_GetLpo32Cken(obj->pcc0Reg)) + { + *frequency = LPO_32K_FREQUENCY; + return true; + } + return false; +} + +static inline bool ClockDrv_SetLpo32kClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetLpo32Cken(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetLpo128kFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + (void)obj; /* Unused, avoid warning */ + *frequency = LPO_128K_FREQUENCY; + return true; +} + +static inline bool ClockDrv_GetCmpFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + + /* Check if the cmp clock is enable */ + if(Pcc0Reg_GetCmpCkEn(obj->pcc0Reg) == 0) + { + return false; + } + + if(Pcc0Reg_GetCmpSrc(obj->pcc0Reg) == 0) + { /* clk_core */ + retval = ClockDrv_GetCoreFreq(obj, frequency); + } + else if(Pcc0Reg_GetCmpSrc(obj->pcc0Reg) == 1) + { /* clk_lptmr */ + retval = ClockDrv_GetLptmrFreq(obj, frequency); + } + + return retval; +} + +static inline bool ClockDrv_SetCmpClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + + /* Disable first before configure */ + Pcc0Reg_SetCmpCkEn(obj->pcc0Reg, 0); + + if(moduleClkConfig->source == CLOCKDRV_CORE) + { + Pcc0Reg_SetCmpSrc(obj->pcc0Reg, 0); + retval = true; + } + else if(moduleClkConfig->source == CLOCKDRV_LPTMR) + { + Pcc0Reg_SetCmpSrc(obj->pcc0Reg, 1); + retval = true; + } + + Pcc0Reg_SetCmpCkEn(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetPortAFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortACkEn(obj->pcc0Reg)) + { + retval = ClockDrv_GetApbFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortAClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetPortACkEn(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetPortBFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortBCkEn(obj->pcc0Reg)) + { + retval = ClockDrv_GetApbFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortBClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetPortBCkEn(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetPortCFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortCCkEn(obj->pcc0Reg)) + { + retval = ClockDrv_GetApbFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortCClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetPortCCkEn(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetPortDFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortDCkEn(obj->pcc0Reg)) + { + retval = ClockDrv_GetApbFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortDClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetPortDCkEn(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetPortEFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortECkEn(obj->pcc0Reg)) + { + retval = ClockDrv_GetApbFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortEClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetPortECkEn(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetLptmrFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + /* Check if the lptmr clock is enable */ + if(Pcc0Reg_GetLptmrCken(obj->pcc0Reg) == 0) + { + return false; + } + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc0Reg_GetLptmrSrc(obj->pcc0Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, &freq); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, &freq); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, &freq); + break; + case 3: /* clk_lpo128 */ + retval = ClockDrv_GetLpo128kFreq(obj, &freq); + break; + case 4: /* clk_lpo1 */ + retval = ClockDrv_GetLpo1kFreq(obj, &freq); + break; + case 5: /* clk_lpo32 */ + retval = ClockDrv_GetLpo32kFreq(obj, &freq); + break; + case 6: /* RTC_CLKIN from PAD_PTA7 */ + retval = ClockDrv_GetRtcPadInFreq(obj, &freq); + break; + case 7: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, &freq); + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + if(retval) + { + uint32_t div = Pcc0Reg_GetLptmrDiv(obj->pcc0Reg) + 1; + *frequency = freq / div; + } + + return retval; +} + +static inline bool ClockDrv_SetLptmrClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + + /* Disable first before configure */ + Pcc0Reg_SetLptmrCken(obj->pcc0Reg, 0); + + switch(moduleClkConfig->source) + { + case CLOCKDRV_SIRC_DIV: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 0); + /* Actually 7 also works */ + break; + case CLOCKDRV_SOSC_DIV: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 1); + break; + case CLOCKDRV_PLL_DIV: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 2); + break; + case CLOCKDRV_LPO_128K: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 3); + break; + case CLOCKDRV_LPO_1K: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 4); + break; + case CLOCKDRV_LPO_32K: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 5); + break; + case CLOCKDRV_RTC_PADIN: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 6); + break; + default: + retval = false; + break; + } + + if(moduleClkConfig->div >= 1 && moduleClkConfig->div <= 8) + { + Pcc0Reg_SetLptmrDiv(obj->pcc0Reg, moduleClkConfig->div - 1); + } + else + { + retval = false; + } + + Pcc0Reg_SetLptmrCken(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetLpitFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + + /* Check if the lpit clock is enable */ + if(Pcc0Reg_GetLpitCken(obj->pcc0Reg) == 0) + { + return false; + } + + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc0Reg_GetLpitSrc(obj->pcc0Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 2: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 3: /* clk_lpo128 */ + *frequency = LPO_128K_FREQUENCY; + retval = true; + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetLpitClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + + /* Disable first before configure */ + Pcc0Reg_SetLpitCken(obj->pcc0Reg, 0); + + switch(moduleClkConfig->source) + { + case CLOCKDRV_SIRC_DIV: + Pcc0Reg_SetLpitSrc(obj->pcc0Reg, 0); + break; + case CLOCKDRV_PLL_DIV: + Pcc0Reg_SetLpitSrc(obj->pcc0Reg, 1); + break; + case CLOCKDRV_SOSC_DIV: + Pcc0Reg_SetLpitSrc(obj->pcc0Reg, 2); + break; + case CLOCKDRV_LPO_128K: + Pcc0Reg_SetLpitSrc(obj->pcc0Reg, 3); + break; + default: + retval = false; + break; + } + + Pcc0Reg_SetLpitCken(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetRtcCntFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + + /* Check if the rtc function clock is enable */ + if(Pcc0Reg_GetRtcCntCken(obj->pcc0Reg) == 0) + { + return false; + } + + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc0Reg_GetRtcCntSrc(obj->pcc0Reg)) + { + case 0: /* clk_lpo32 */ + retval = ClockDrv_GetLpo32kFreq(obj, frequency); + break; + case 1: /* PAD RTC_CLKIN */ + retval = ClockDrv_GetRtcPadInFreq(obj, frequency); + break; + case 2: /* lpo1 */ + retval = ClockDrv_GetLpo1kFreq(obj, frequency); + break; + case 3: /* lpo1 */ + retval = ClockDrv_GetLpo1kFreq(obj, frequency); + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetRtcCntClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + + /* Disable first before configure */ + Pcc0Reg_SetRtcCntCken(obj->pcc0Reg, 0); + + if(moduleClkConfig->source == CLOCKDRV_LPO_32K) + { + Pcc0Reg_SetRtcCntSrc(obj->pcc0Reg, 0); + retval = true; + } + else if(moduleClkConfig->source == CLOCKDRV_RTC_PADIN) + { + Pcc0Reg_SetRtcCntSrc(obj->pcc0Reg, 1); + retval = true; + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_1K) + { + Pcc0Reg_SetRtcCntSrc(obj->pcc0Reg, 2); + /* Actually 3 is also workable */ + retval = true; + } + + Pcc0Reg_SetRtcCntCken(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetPortAFltFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortAFltSrc(obj->pcc0Reg) == 0) + { /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, frequency); + } + else if(Pcc0Reg_GetPortAFltSrc(obj->pcc0Reg) == 1) + { /* clk_lpo128 */ + retval = ClockDrv_GetLpo128kFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortAFltClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + if(moduleClkConfig->source == CLOCKDRV_APB) + { /* clk_apb */ + Pcc0Reg_SetPortAFltSrc(obj->pcc0Reg, 0); + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_128K) + { /* clk_lpo128 */ + Pcc0Reg_SetPortAFltSrc(obj->pcc0Reg, 1); + } + return retval; +} + +static inline bool ClockDrv_GetPortBFltFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortBFltSrc(obj->pcc0Reg) == 0) + { /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, frequency); + } + else if(Pcc0Reg_GetPortBFltSrc(obj->pcc0Reg) == 1) + { /* clk_lpo128 */ + retval = ClockDrv_GetLpo128kFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortBFltClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + if(moduleClkConfig->source == CLOCKDRV_APB) + { /* clk_apb */ + Pcc0Reg_SetPortBFltSrc(obj->pcc0Reg, 0); + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_128K) + { /* clk_lpo128 */ + Pcc0Reg_SetPortBFltSrc(obj->pcc0Reg, 1); + } + return retval; +} + +static inline bool ClockDrv_GetPortCFltFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortCFltSrc(obj->pcc0Reg) == 0) + { /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, frequency); + } + else if(Pcc0Reg_GetPortCFltSrc(obj->pcc0Reg) == 1) + { /* clk_lpo128 */ + retval = ClockDrv_GetLpo128kFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortCFltClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + if(moduleClkConfig->source == CLOCKDRV_APB) + { /* clk_apb */ + Pcc0Reg_SetPortCFltSrc(obj->pcc0Reg, 0); + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_128K) + { /* clk_lpo128 */ + Pcc0Reg_SetPortCFltSrc(obj->pcc0Reg, 1); + } + return retval; +} + +static inline bool ClockDrv_GetPortDFltFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortDFltSrc(obj->pcc0Reg) == 0) + { /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, frequency); + } + else if(Pcc0Reg_GetPortDFltSrc(obj->pcc0Reg) == 1) + { /* clk_lpo128 */ + retval = ClockDrv_GetLpo128kFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortDFltClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + if(moduleClkConfig->source == CLOCKDRV_APB) + { /* clk_apb */ + Pcc0Reg_SetPortDFltSrc(obj->pcc0Reg, 0); + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_128K) + { /* clk_lpo128 */ + Pcc0Reg_SetPortDFltSrc(obj->pcc0Reg, 1); + } + return retval; +} + +static inline bool ClockDrv_GetPortEFltFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortEFltSrc(obj->pcc0Reg) == 0) + { /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, frequency); + } + else if(Pcc0Reg_GetPortEFltSrc(obj->pcc0Reg) == 1) + { /* clk_lpo128 */ + retval = ClockDrv_GetLpo128kFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortEFltClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + if(moduleClkConfig->source == CLOCKDRV_APB) + { /* clk_apb */ + Pcc0Reg_SetPortEFltSrc(obj->pcc0Reg, 0); + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_128K) + { /* clk_lpo128 */ + Pcc0Reg_SetPortEFltSrc(obj->pcc0Reg, 1); + } + return retval; +} + +static inline bool ClockDrv_GetExtFltFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + + if(RcmReg_GetExtRstFltCk(obj->rcmReg) == 0) + { + /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, frequency); + } + else if(RcmReg_GetExtRstFltCk(obj->rcmReg) == 1) + { + /* clk_lpo128 */ + *frequency = LPO_128K_FREQUENCY; + retval = true; + } + + return retval; +} + +static inline bool ClockDrv_SetExtFltClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + + if(moduleClkConfig->source == CLOCKDRV_APB) + { + RcmReg_SetExtRstFltCk(obj->rcmReg, 0); + retval = true; + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_128K) + { + RcmReg_SetExtRstFltCk(obj->rcmReg, 1); + retval = true; + } + + return retval; +} + +static inline bool ClockDrv_GetDmaFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetDmaCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetCoreFreq(obj, frequency); +} + +static inline bool ClockDrv_SetDmaClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetDmaCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetMscmFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetMscmCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetMscmClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetMscmCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetCrcFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetCrcCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetCrcClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetCrcCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetEimFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetEimCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetEimClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetEimCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetErmFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetErmCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetCoreFreq(obj, frequency); +} + +static inline bool ClockDrv_SetErmClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetErmCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetFhuFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetFhuCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetFhuClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetFhuCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetAdcFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetAdcCkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + uint32_t freq = 0; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetAdcSrc(obj->pcc1Reg)) + { + case 0: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + case 1: /* clk_sosc */ + retval = ClockDrv_GetSoscFreq(obj, &freq); + break; + case 2: /* clk_pll */ + retval = ClockDrv_GetPllFreq(obj, &freq); + break; + case 3: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + /* Divider */ + uint32_t div = (uint32_t)(1UL << Pcc1Reg_GetAdcDiv(obj->pcc1Reg)); + *frequency = freq / div; + + return retval; +} + +static inline bool ClockDrv_SetAdcClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetAdcCkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetAdcSrc(obj->pcc1Reg, select); + retval = true; + } + + /* Divider */ + if(true == retval) + { + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : 0xff))); + if(div != 0xff) + { + Pcc1Reg_SetAdcDiv(obj->pcc1Reg, div); + } + else + { + retval = false; + } + } + + /* Enable if required */ + Pcc1Reg_SetAdcCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetPdbFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetPdbCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetPdbClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetPdbCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetSpi0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetSpi0CkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetSpi0Src(obj->pcc1Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 3: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetSpi0Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetSpi0CkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC_DIV ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC_DIV ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL_DIV ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetSpi0Src(obj->pcc1Reg, select); + retval = true; + } + + Pcc1Reg_SetSpi0CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetSpi1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetSpi1CkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetSpi1Src(obj->pcc1Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 3: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetSpi1Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetSpi1CkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC_DIV ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC_DIV ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL_DIV ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetSpi1Src(obj->pcc1Reg, select); + retval = true; + } + + Pcc1Reg_SetSpi1CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetUart0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetUart0CkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetUart0Src(obj->pcc1Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 3: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetUart0Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetUart0CkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC_DIV ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC_DIV ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL_DIV ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetUart0Src(obj->pcc1Reg, select); + retval = true; + } + + Pcc1Reg_SetUart0CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetUart1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ +#if FEATURE_UART_INSTANCE_NUM == 3 + if(Pcc1Reg_GetUart1CkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetUart1Src(obj->pcc1Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 3: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +#else + /* UART1 is not available */ + return false; +#endif +} + +static inline bool ClockDrv_SetUart1Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ +#if FEATURE_UART_INSTANCE_NUM == 3 + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetUart1CkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC_DIV ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC_DIV ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL_DIV ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetUart1Src(obj->pcc1Reg, select); + retval = true; + } + + Pcc1Reg_SetUart1CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +#else + /* UART1 is not available */ + return false; +#endif +} + +static inline bool ClockDrv_GetUart2Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetUart2CkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetUart2Src(obj->pcc1Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 3: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetUart2Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetUart2CkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC_DIV ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC_DIV ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL_DIV ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetUart2Src(obj->pcc1Reg, select); + retval = true; + } + + Pcc1Reg_SetUart2CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetI2CFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetI2CCkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetI2CSrc(obj->pcc1Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 3: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetI2CClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetI2CCkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC_DIV ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC_DIV ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL_DIV ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetI2CSrc(obj->pcc1Reg, select); + retval = true; + } + + Pcc1Reg_SetI2CCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetI2SMFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetI2SMCkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + uint32_t freq = 0; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetI2SMSrc(obj->pcc1Reg)) + { + case 0: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + case 1: /* clk_sosc */ + retval = ClockDrv_GetSoscFreq(obj, &freq); + break; + case 2: /* clk_pll */ + retval = ClockDrv_GetPllFreq(obj, &freq); + break; + case 3: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + /* Divider */ + uint32_t div = Pcc1Reg_GetI2SMDiv(obj->pcc1Reg) + 1; + if(div < 2) + { + div = 2; + } + *frequency = freq / div; + + return retval; +} + +static inline bool ClockDrv_SetI2SMClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetI2SMCkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetI2SMSrc(obj->pcc1Reg, select); + retval = true; + } + + /* Divider */ + if(true == retval) + { + if(moduleClkConfig->div >= 2 && moduleClkConfig->div <= 64) + { + Pcc1Reg_SetI2SMDiv(obj->pcc1Reg, moduleClkConfig->div - 1); + } + else + { + retval = false; + } + } + + /* Enable if required */ + Pcc1Reg_SetI2SMCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetI2SSFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + /* Can not get the frequency of I2S slave */ + return false; +} + +static inline bool ClockDrv_SetI2SSClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetI2SSCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetPwmLite0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetPwm0CkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetPwmLite0Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetPwm0CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetPwmLite1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetPwm1CkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetPwmLite1Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetPwm1CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetMft0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetMft0CkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetCoreFreq(obj, frequency); +} + +static inline bool ClockDrv_SetMft0Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetMft0CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetMft1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetMft1CkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetCoreFreq(obj, frequency); +} + +static inline bool ClockDrv_SetMft1Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetMft1CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetCmusFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetCmusCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetSoscFreq(obj, frequency); +} + +static inline bool ClockDrv_SetCmusClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetCmusCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetCmupFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetCmupCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetPllFreq(obj, frequency); +} + +static inline bool ClockDrv_SetCmupClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetCmupCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetTclk0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + (void)obj; /* Unused, avoid warning */ + *frequency = obj->tclkFreq[0]; + return true; +} + +static inline bool ClockDrv_GetTclk1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + (void)obj; /* Unused, avoid warning */ + *frequency = obj->tclkFreq[1]; + return true; +} + +static inline bool ClockDrv_GetTclk2Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + (void)obj; /* Unused, avoid warning */ + *frequency = obj->tclkFreq[2]; + return true; +} + +static inline bool ClockDrv_GetExtMft0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetExtMft0Src(obj->pcc1Reg)) + { + case 0: /* TCLK0 */ + retval = ClockDrv_GetTclk0Freq(obj, frequency); + break; + case 1: /* TCLK1 */ + retval = ClockDrv_GetTclk1Freq(obj, frequency); + break; + case 2: /* TCLK2 */ + retval = ClockDrv_GetTclk2Freq(obj, frequency); + break; + case 3: /* clk_sirc_div_mft */ + retval = ClockDrv_GetSircDivMftFreq(obj, frequency); + break; + case 4: /* clk_sosc_div_mft */ + retval = ClockDrv_GetSoscDivMftFreq(obj, frequency); + break; + case 5: /* clk_pll_div_mft */ + retval = ClockDrv_GetPllDivMftFreq(obj, frequency); + break; + case 6: /* clk_sirc_div_mft */ + case 7: /* clk_sirc_div_mft */ + retval = ClockDrv_GetSircDivMftFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetExtMft0Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + + /* Select source */ + switch(moduleClkConfig->source) + { + case CLOCKDRV_TCLK0: /* TCLK0 */ + Pcc1Reg_SetExtMft0Src(obj->pcc1Reg, 0); + break; + case CLOCKDRV_TCLK1: /* TCLK1 */ + Pcc1Reg_SetExtMft0Src(obj->pcc1Reg, 1); + break; + case CLOCKDRV_TCLK2: /* TCLK2 */ + Pcc1Reg_SetExtMft0Src(obj->pcc1Reg, 2); + break; + case CLOCKDRV_SIRC_DIV_MFT: /* clk_sirc_div_mft */ + Pcc1Reg_SetExtMft0Src(obj->pcc1Reg, 3); + /* Actually it can also be 6 or 7 */ + break; + case CLOCKDRV_SOSC_DIV_MFT: /* clk_sosc_div_mft */ + Pcc1Reg_SetExtMft0Src(obj->pcc1Reg, 4); + break; + case CLOCKDRV_PLL_DIV_MFT: /* clk_pll_div_mft */ + Pcc1Reg_SetExtMft0Src(obj->pcc1Reg, 5); + break; + default: + retval = false; + break; + } + + return retval; +} + +static inline bool ClockDrv_GetExtMft1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetExtMft1Src(obj->pcc1Reg)) + { + case 0: /* TCLK0 */ + retval = ClockDrv_GetTclk0Freq(obj, frequency); + break; + case 1: /* TCLK1 */ + retval = ClockDrv_GetTclk1Freq(obj, frequency); + break; + case 2: /* TCLK2 */ + retval = ClockDrv_GetTclk2Freq(obj, frequency); + break; + case 3: /* clk_sirc_div_mft */ + retval = ClockDrv_GetSircDivMftFreq(obj, frequency); + break; + case 4: /* clk_sosc_div_mft */ + retval = ClockDrv_GetSoscDivMftFreq(obj, frequency); + break; + case 5: /* clk_pll_div_mft */ + retval = ClockDrv_GetPllDivMftFreq(obj, frequency); + break; + case 6: /* clk_sirc_div_mft */ + case 7: /* clk_sirc_div_mft */ + retval = ClockDrv_GetSircDivMftFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetExtMft1Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + /* Select source */ + switch(moduleClkConfig->source) + { + case CLOCKDRV_TCLK0: /* TCLK0 */ + Pcc1Reg_SetExtMft1Src(obj->pcc1Reg, 0); + break; + case CLOCKDRV_TCLK1: /* TCLK1 */ + Pcc1Reg_SetExtMft1Src(obj->pcc1Reg, 1); + break; + case CLOCKDRV_TCLK2: /* TCLK2 */ + Pcc1Reg_SetExtMft1Src(obj->pcc1Reg, 2); + break; + case CLOCKDRV_SIRC_DIV_MFT: /* clk_sirc_div_mft */ + Pcc1Reg_SetExtMft1Src(obj->pcc1Reg, 3); + /* Actually it can also be 6 or 7 */ + break; + case CLOCKDRV_SOSC_DIV_MFT: /* clk_sosc_div_mft */ + Pcc1Reg_SetExtMft1Src(obj->pcc1Reg, 4); + break; + case CLOCKDRV_PLL_DIV_MFT: /* clk_pll_div_mft */ + Pcc1Reg_SetExtMft1Src(obj->pcc1Reg, 5); + break; + default: + retval = false; + break; + } + + return retval; +} + +static inline bool ClockDrv_GetFixMft0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetFixMft0Src(obj->pcc1Reg)) + { + case 0: /* clk_lpo32 */ + retval = ClockDrv_GetLpo32kFreq(obj, frequency); + break; + case 1: /* RTC_CLKIN */ + retval = ClockDrv_GetRtcPadInFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetFixMft0Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + + /* Select source */ + switch(moduleClkConfig->source) + { + case CLOCKDRV_LPO_32K: /* clk_lpo32 */ + Pcc1Reg_SetFixMft0Src(obj->pcc1Reg, 0); + break; + case CLOCKDRV_RTC_PADIN: /* RTC_CLKIN */ + Pcc1Reg_SetFixMft0Src(obj->pcc1Reg, 1); + break; + default: + retval = false; + break; + } + + return retval; +} + +static inline bool ClockDrv_GetFixMft1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetFixMft1Src(obj->pcc1Reg)) + { + case 0: /* clk_lpo32 */ + retval = ClockDrv_GetLpo32kFreq(obj, frequency); + break; + case 1: /* RTC_CLKIN */ + retval = ClockDrv_GetRtcPadInFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetFixMft1Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + + /* Select source */ + switch(moduleClkConfig->source) + { + case CLOCKDRV_LPO_32K: /* clk_lpo32 */ + Pcc1Reg_SetFixMft1Src(obj->pcc1Reg, 0); + break; + case CLOCKDRV_RTC_PADIN: /* RTC_CLKIN */ + Pcc1Reg_SetFixMft1Src(obj->pcc1Reg, 1); + break; + default: + retval = false; + break; + } + + return retval; +} + +static inline bool ClockDrv_GetMpuFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetMpuCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetCoreFreq(obj, frequency); +} + +static inline bool ClockDrv_SetMpuClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetMpuCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +void ClockDrv_Init(ClockDrvType *obj, + struct _RcmRegType_ *rcmReg, + struct _Pcc0RegType_ *pcc0Reg, + struct _Scg0RegType_ *scg0Reg, + struct _Scg1RegType_ *scg1Reg, + struct _Pcc1RegType_ *pcc1Reg, + struct _Scg2RegType_ *scg2Reg, + const ClockDrv_InitParamsType *initParams) +{ + obj->rcmReg = rcmReg; + obj->pcc0Reg = pcc0Reg; + obj->scg0Reg = scg0Reg; + obj->scg1Reg = scg1Reg; + obj->pcc1Reg = pcc1Reg; + obj->scg2Reg = scg2Reg; + obj->sircFreq = initParams->sircFreq; + obj->xtalClkFreq = initParams->xtalClkFreq; + obj->rtcClkInFreq = initParams->rtcClkInFreq; + uint8_t i = 0; + for(i = 0; i < TCLK_INPUTS_NUM; ++i) + { + obj->tclkFreq[i] = initParams->tclkFreq[i]; + } +} + +bool ClockDrv_GetFreq(const ClockDrvType *obj, ClockDrv_NamesType clockName, uint32_t *frequency) +{ + if(clockName >= CLOCKDRV_CLOCK_NUM) + { + return false; + } + + bool retval = false; + if(c_clockFuncTable[clockName].getFreqFunc != NULL) + { + retval = c_clockFuncTable[clockName].getFreqFunc(obj, frequency); + } + return retval; +} + +bool ClockDrv_ConfigureClock(ClockDrvType *obj, ClockDrv_NamesType clockName, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + if(clockName >= CLOCKDRV_CLOCK_NUM) + { + return false; + } + + bool retval = false; + if(c_clockFuncTable[clockName].setClockFunc != NULL) + { + Pcc0Reg_SetKey(obj->pcc0Reg, 0x55534552); /* Unlock PCC0, PCC1 */ + Scg0Reg_SetKey(obj->scg0Reg, 0x19962020); /* Unlock SCG0, SCG1, SCG2 */ + RcmReg_SetKey(obj->rcmReg, 0x52434D4B); /* Unlock RCM */ + retval = c_clockFuncTable[clockName].setClockFunc(obj, moduleClkConfig); + Pcc0Reg_SetKey(obj->pcc0Reg, 0); /* Lock PCC0, PCC1 again */ + Scg0Reg_SetKey(obj->scg0Reg, 0); /* Lock SCG0, SCG1, SCG2 again */ + RcmReg_SetKey(obj->rcmReg, 0); /* Lock RCM again */ + } + + return retval; +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/clock/clock_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/clock/clock_drv.h new file mode 100644 index 0000000..d29a52f --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/clock/clock_drv.h @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CLOCK_DRV_H_ +#define _CLOCK_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of Clock + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup clock_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* TCLK clock number */ +#define TCLK_INPUTS_NUM (3U) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Definition of Clock names. + */ +typedef enum +{ + /* Source clocks */ + CLOCKDRV_SOSC = 0, /* system crystal oscillator clock*/ + CLOCKDRV_SIRC, /* slow internal reference clock */ + CLOCKDRV_PLL, /* PLL clock */ + CLOCKDRV_SOSC_DIV, /* SOSC_DIV clock */ + CLOCKDRV_SOSC_DIV_MFT, /* SOSC_DIV_MFT clock */ + CLOCKDRV_SIRC_DIV, /* SIRC_DIV clock */ + CLOCKDRV_SIRC_DIV_MFT, /* SIRC_DIV_MFT clock */ + CLOCKDRV_PLL_DIV, /* PLL_DIV clock */ + CLOCKDRV_PLL_DIV_MFT, /* PLL_DIV_MFT clock */ + CLOCKDRV_SYS, /* system clock */ + CLOCKDRV_CORE, /* core clock */ + CLOCKDRV_APB, /* bus clock */ + CLOCKDRV_FLS, /* flash clock */ + CLOCKDRV_CLKOUT, /* CLKOUT clock */ + CLOCKDRV_RTC_PADIN, /* RTC pad input clock */ + CLOCKDRV_LPO_1K, /* LPO 1KHz clock */ + CLOCKDRV_LPO_32K, /* LPO 32KHz clock */ + CLOCKDRV_LPO_128K, /* LPO 128KHz clock */ + /* Always-on clocks */ + CLOCKDRV_CMP, /* CMP clock */ + CLOCKDRV_PORTA, /* PORTA clock */ + CLOCKDRV_PORTB, /* PORTB clock */ + CLOCKDRV_PORTC, /* PORTC clock */ + CLOCKDRV_PORTD, /* PORTD clock */ + CLOCKDRV_PORTE, /* PORTE clock */ + CLOCKDRV_LPTMR, /* LPTMR clock */ + CLOCKDRV_LPIT, /* LPIT clock */ + CLOCKDRV_RTC_CNT, /* RTC module clock for counter */ + CLOCKDRV_PORTA_FLT, /* PORTA digital filter clock */ + CLOCKDRV_PORTB_FLT, /* PORTB digital filter clock */ + CLOCKDRV_PORTC_FLT, /* PORTC digital filter clock */ + CLOCKDRV_PORTD_FLT, /* PORTD digital filter clock */ + CLOCKDRV_PORTE_FLT, /* PORTE digital filter clock */ + CLOCKDRV_EXT_FLT, /* External Reset pin digital Filter clock */ + /* Peripheral clocks */ + CLOCKDRV_DMA, /* DMA clock */ + CLOCKDRV_MSCM, /* MSCM clock */ + CLOCKDRV_CRC, /* CRC clock */ + CLOCKDRV_EIM, /* EIM clock */ + CLOCKDRV_ERM, /* ERM clock */ + CLOCKDRV_FHU, /* FHU clock */ + CLOCKDRV_ADC, /* ADC clock */ + CLOCKDRV_PDB, /* PDB clock */ + CLOCKDRV_SPI0, /* SPI0 clock */ + CLOCKDRV_SPI1, /* SPI1 clock */ + CLOCKDRV_UART0, /* UART0 clock */ + CLOCKDRV_UART1, /* UART1 clock */ + CLOCKDRV_UART2, /* UART2 clock */ + CLOCKDRV_I2C, /* I2C clock */ + CLOCKDRV_I2SM, /* I2S Mater clock */ + CLOCKDRV_I2SS, /* I2S Slave clock */ + CLOCKDRV_PWMLITE0, /* PWM_LITE0 clock */ + CLOCKDRV_PWMLITE1, /* PWM_LITE1 clock */ + CLOCKDRV_MFT0, /* MFT0 input clock, please note this is not MFT functional clock */ + CLOCKDRV_MFT1, /* MFT1 input clock, please note this is not MFT functional clock */ + CLOCKDRV_CMUS, /* CMUS clock */ + CLOCKDRV_CMUP, /* CMUP clock */ + CLOCKDRV_TCLK0, /* TCLK0 clock */ + CLOCKDRV_TCLK1, /* TCLK1 clock */ + CLOCKDRV_TCLK2, /* TCLK2 clock */ + CLOCKDRV_EXT_MFT0, /* EXT_MFT0 clock */ + CLOCKDRV_EXT_MFT1, /* EXT_MFT1 clock */ + CLOCKDRV_FIX_MFT0, /* FIX_MFT0 clock */ + CLOCKDRV_FIX_MFT1, /* FIX_MFT1 clock */ + CLOCKDRV_MPU, /* MPU clock */ + + CLOCKDRV_CLOCK_NUM +} ClockDrv_NamesType; + +/*! \brief module clock configuration. + */ +typedef struct _ClockDrv_ModuleClkConfigType_ +{ + bool gating; /*!< Clock gating. */ + ClockDrv_NamesType source; /*!< Clock source input (some modules don't have protocol clock) */ + uint16_t mult; /*!< Multiplier (some modules don't have fractional) */ + uint16_t div; /*!< Divider (some modules don't have divider) */ + + /* Only PLL clock has following configures */ + struct + { + uint32_t fblSel; /*!< feedback clock divider pre-scaler */ + uint32_t preDiv; /*!< pre-divider */ + uint32_t postDiv; /*!< post-divider */ + } pllConfig; /*!< PLL related config */ +} ClockDrv_ModuleClkConfigType; + +/*! \brief Initial parameters + */ +typedef struct _ClockDrv_InitParamsType_ +{ + uint32_t sircFreq; /*!< SIRC frequency */ + uint32_t xtalClkFreq; /*!< XTAL clock frequency. */ + uint32_t rtcClkInFreq; /*!< RTC_CLKIN clock frequency. */ + uint32_t tclkFreq[TCLK_INPUTS_NUM]; /*!< TCLKx clocks */ +} ClockDrv_InitParamsType; + +/* Forward declaration of related register */ +struct _RcmRegType_; +struct _Pcc0RegType_; +struct _Scg0RegType_; +struct _Scg1RegType_; +struct _Pcc1RegType_; +struct _Scg2RegType_; + +/*! \brief The definition of LPIT driver class + */ +typedef struct _ClockDrvType_ +{ + struct _RcmRegType_ *rcmReg; /*!< pointer to RCM register */ + struct _Pcc0RegType_ *pcc0Reg; /*!< pointer to PCC0 register */ + struct _Scg0RegType_ *scg0Reg; /*!< pointer to SCG0 register */ + struct _Scg1RegType_ *scg1Reg; /*!< pointer to SCG1 register */ + struct _Pcc1RegType_ *pcc1Reg; /*!< pointer to PCC1 register */ + struct _Scg2RegType_ *scg2Reg; /*!< pointer to SCG2 register */ + uint32_t sircFreq; /*!< SIRC frequency */ + uint32_t xtalClkFreq; /*!< XTAL clock frequency */ + uint32_t rtcClkInFreq; /*!< RTC_CLKIN clock frequency */ + uint32_t tclkFreq[TCLK_INPUTS_NUM]; /*!< TCLKx clocks */ +} ClockDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the Clock driver module + * + * This function initializes Clock driver by setting the register + * instances to it. + * + * \param[in] obj : pointer to Clock driver instance + * \param[in] rcmReg : pointer to RCM register instance + * \param[in] pcc0Reg : pointer to PCC0 register instance + * \param[in] scg0Reg : pointer to SCG0 register instance + * \param[in] scg1Reg : pointer to SCG1 register instance + * \param[in] pcc1Reg : pointer to PCC1 register instance + * \param[in] scg2Reg : pointer to SCG2 register instance + * \param[in] initParams : pointer to clock initialization parameters + */ +extern void ClockDrv_Init(ClockDrvType *obj, + struct _RcmRegType_ *rcmReg, + struct _Pcc0RegType_ *pcc0Reg, + struct _Scg0RegType_ *scg0Reg, + struct _Scg1RegType_ *scg1Reg, + struct _Pcc1RegType_ *pcc1Reg, + struct _Scg2RegType_ *scg2Reg, + const ClockDrv_InitParamsType *initParams); + +/*! \brief Gets the clock frequency for a specific clock name. + * + * This function checks the current clock configurations and then calculates + * the clock frequency for a specific clock name defined in ClockDrv_NamesType. + * Clock modules must be properly configured before using this function. + * If it cannot find the clock name or the clock is not enabled or + * it's not configured properly, it returns false. + * + * \note If return false, don't trust the value of out parameter "frequency" + * even if it's changed. + * + * \param[in] obj : pointer to Clock driver instance + * \param[in] clockName : Clock names defined + * \param[out] frequency : clock frequency value in Hertz + * \return The result of the operation + * - false : Failed to get the frequency + * - true : Success + */ +extern bool ClockDrv_GetFreq(const ClockDrvType *obj, ClockDrv_NamesType clockName, uint32_t *frequency); + +/*! \brief Configures module clock + * + * This function configures a module clock according to the configuration. + * + * \note If the target clock do not have mul or div, the corresponding configuration in + * moduleClkConfig will be ignored. + * + * \param[in] obj : pointer to Clock driver instance + * \param[in] clockName : Clock name of the configured module clock + * \param[in] moduleClkConfig : Pointer to the configuration structure. + * \return The result of the operation + * - false : configure failed + * - true : success + */ +extern bool ClockDrv_ConfigureClock(ClockDrvType *obj, ClockDrv_NamesType clockName, const ClockDrv_ModuleClkConfigType *moduleClkConfig); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _CLOCK_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cmp/cmp_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cmp/cmp_drv.c new file mode 100644 index 0000000..6736f6a --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cmp/cmp_drv.c @@ -0,0 +1,554 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "cmp_drv.h" +#include "cmp_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define CMP_TEST_VOLTAGE_ENABLE (0U) +#define CMP_TEST_VOLTAGE_DISABLE (1U) +#define CMP_STATE_SE_SHIFT (0U) +#define CMP_STATE_WE_SHIFT (1U) +#define CMP_STATE_EN_SHIFT (2U) + +#define CMP_TRIGGER_FALLING_SHIFT (0U) +#define CMP_TRIGGER_RISING_SHIFT (1U) +#define CMP_TRIGGER_MASK (1U) + +#define CMP_CHANNELSTATE_MASK (1U) +#define CMP_CHANNEL_PRESTATE_MASK (1U) +#define CMP_CHNF_MASK (1U) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +typedef enum +{ + CMPDRV_STATE_DISABLE0 = 0U, + CMPDRV_STATE_DISABLE1 = 1U, + CMPDRV_STATE_DISABLE2 = 2U, + CMPDRV_STATE_DISABLE3 = 3U, + CMPDRV_STATE_NOSAMPLE = 4U, + CMPDRV_STATE_SE = 5U, + CMPDRV_STATE_WE = 6U, + CMPDRV_STATE_WE_SE = 7U, +} CmpDrv_StateType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +/* Forward declaration */ +CmpDrv_TriggerType CmpDrv_GetTriggerMode(const CmpDrvType *obj); + +void CmpDrv_SetTriggerMode(CmpDrvType *obj, const CmpDrv_TriggerType mode); + +CmpDrv_ModeType CmpDrv_GetMode(const CmpDrvType *obj); + +void CmpDrv_SetMode(CmpDrvType *obj, const CmpDrv_ModeType mode, const uint8_t filter_sample_count, const uint8_t filter_sample_period); + +uint8_t CmpDrv_GetChannelState(const CmpDrvType *obj); + +void CmpDrv_SetChannelState(CmpDrvType *obj, const uint8_t channelState); + +uint8_t CmpDrv_GetChannelPreState(const CmpDrvType *obj); + +/* Forward declaration end */ + +void CmpDrv_Init(CmpDrvType *obj, struct _CmpRegType_ *reg) +{ + obj->reg = reg; +} + +void CmpDrv_ConfigureNormal(CmpDrvType *obj, const CmpDrv_ConfigType *userConfig) +{ + /* Unclock CMP */ + CmpReg_UnlockReg(obj->reg); + + /* Disable CMP */ + CmpReg_SetEnReg(obj->reg, false); + + /* Get configuration of normal modes */ + CmpReg_SetDmaenReg(obj->reg, userConfig->normalCfg.dmaEnable); + CmpDrv_SetTriggerMode(obj, userConfig->normalCfg.triggerMode); + CmpDrv_SetMode(obj, userConfig->normalCfg.mode, userConfig->normalCfg.filterSampleCount, userConfig->normalCfg.filterSamplePeriod); + CmpReg_SetPmodeReg(obj->reg, userConfig->normalCfg.powerMode); + CmpReg_SetInvtReg(obj->reg, userConfig->normalCfg.inverterState); + CmpReg_SetOpeReg(obj->reg, userConfig->normalCfg.pinState); + CmpReg_SetCosReg(obj->reg, userConfig->normalCfg.outputSelect); + CmpReg_SetHystctrReg(obj->reg, userConfig->normalCfg.hystLvl); + CmpReg_SetOffsetReg(obj->reg, userConfig->normalCfg.hystOffsetState); + CmpReg_SetLpfselReg(obj->reg, userConfig->normalCfg.lpfsel); + + /* Configuration of DAC */ + CmpReg_SetVrselReg(obj->reg, userConfig->dacCfg.dacVoltInSel); + CmpReg_SetVoselReg(obj->reg, userConfig->dacCfg.dacVoltScale); + CmpReg_SetDacenReg(obj->reg, userConfig->dacCfg.state); + + /* Configuration of analog mux */ + CmpReg_SetInpselReg(obj->reg, userConfig->muxCfg.posPortMux); + CmpReg_SetInnselReg(obj->reg, userConfig->muxCfg.negPortMux); + CmpReg_SetPselReg(obj->reg, userConfig->muxCfg.posInputMux); + CmpReg_SetMselReg(obj->reg, userConfig->muxCfg.negInputMux); + + /* Disable Round-Robin mode & disable Round-Robin interrupt */ + CmpReg_SetRreReg(obj->reg, false); + CmpReg_SetRrieReg(obj->reg, false); + + /* Clear all flags*/ + CmpDrv_ClearOutputFlags(obj); + CmpDrv_ClearInputFlags(obj); + + /* lock CMP */ + CmpReg_LockReg(obj->reg); + + /*! \note When enable CMP depend on user(use CmpDrv_SetCmpState for enable CMP) */ +} + +void CmpDrv_ConfigureTriggerMode(CmpDrvType *obj, const CmpDrv_ConfigType *userConfig) +{ + /* Unclock CMP */ + CmpReg_UnlockReg(obj->reg); + + /* Disable CMP */ + CmpReg_SetEnReg(obj->reg, false); + + /* Get configuration of normal modes*/ + CmpReg_SetDmaenReg(obj->reg, userConfig->normalCfg.dmaEnable); + CmpDrv_SetTriggerMode(obj, userConfig->normalCfg.triggerMode); + CmpDrv_SetMode(obj, CMP_CONTINUOUS, userConfig->normalCfg.filterSampleCount, userConfig->normalCfg.filterSamplePeriod); + CmpReg_SetPmodeReg(obj->reg, userConfig->normalCfg.powerMode); + CmpReg_SetInvtReg(obj->reg, userConfig->normalCfg.inverterState); + CmpReg_SetOpeReg(obj->reg, userConfig->normalCfg.pinState); + CmpReg_SetCosReg(obj->reg, userConfig->normalCfg.outputSelect); + CmpReg_SetHystctrReg(obj->reg, userConfig->normalCfg.hystLvl); + CmpReg_SetOffsetReg(obj->reg, userConfig->normalCfg.hystOffsetState); + CmpReg_SetLpfselReg(obj->reg, userConfig->normalCfg.lpfsel); + + /* Configuration of DAC */ + CmpReg_SetVrselReg(obj->reg, userConfig->dacCfg.dacVoltInSel); + CmpReg_SetVoselReg(obj->reg, userConfig->dacCfg.dacVoltScale); + CmpReg_SetDacenReg(obj->reg, userConfig->dacCfg.state); + + /* Configuration of analog mux */ + CmpReg_SetInpselReg(obj->reg, userConfig->muxCfg.posPortMux); + CmpReg_SetInnselReg(obj->reg, userConfig->muxCfg.negPortMux); + CmpReg_SetPselReg(obj->reg, userConfig->muxCfg.posInputMux); + CmpReg_SetMselReg(obj->reg, userConfig->muxCfg.negInputMux); + + /* Configuration of round robin modes(disable) */ + CmpReg_SetRreReg(obj->reg, true); + CmpReg_SetRrieReg(obj->reg, userConfig->rrCfg.intrEnable); + CmpReg_SetFxmpReg(obj->reg, userConfig->rrCfg.fixedMuxPort); + CmpReg_SetFxmxchReg(obj->reg, userConfig->rrCfg.fixedChnSel); + CmpReg_SetNsamReg(obj->reg, userConfig->rrCfg.sampleCnt); + CmpReg_SetInitmodReg(obj->reg, userConfig->rrCfg.initDelayCnt); + CmpDrv_SetChannelState(obj, userConfig->rrCfg.channelState); + CmpDrv_SetChannelPreState(obj, userConfig->rrCfg.channelPreState); + + /* Clear all flags */ + CmpDrv_ClearOutputFlags(obj); + CmpDrv_ClearInputFlags(obj); + + /* lock CMP */ + CmpReg_LockReg(obj->reg); + + /*! \note When enable CMP depend on user(use CmpDrv_SetCmpState for enable CMP)*/ +} + +void CmpDrv_GetConfig(const CmpDrvType *obj, CmpDrv_ConfigType *userConfig) +{ + /* Get configuration of normal modes */ + userConfig->normalCfg.dmaEnable = CmpReg_GetDmaenReg(obj->reg); + userConfig->normalCfg.triggerMode = CmpDrv_GetTriggerMode(obj); + userConfig->normalCfg.mode = CmpDrv_GetMode(obj); + userConfig->normalCfg.filterSamplePeriod = CmpReg_GetFprReg(obj->reg); + userConfig->normalCfg.filterSampleCount = CmpReg_GetFilterCntReg(obj->reg); + userConfig->normalCfg.powerMode = (CmpDrv_PmodeType)(CmpReg_GetPmodeReg(obj->reg)); + userConfig->normalCfg.inverterState = (CmpDrv_InvtType)(CmpReg_GetInvtReg(obj->reg)); + userConfig->normalCfg.pinState = CmpReg_GetOpeReg(obj->reg); + userConfig->normalCfg.outputSelect = (CmpDrv_CosType)(CmpReg_GetCosReg(obj->reg)); + userConfig->normalCfg.hystLvl = (CmpDrv_HystctrType)(CmpReg_GetHystctrReg(obj->reg)); + userConfig->normalCfg.hystOffsetState = (CmpDrv_OffsetType)(CmpReg_GetOffsetReg(obj->reg)); + userConfig->normalCfg.lpfsel = (CmpDrv_LpfselType)(CmpReg_GetLpfselReg(obj->reg)); + + /* Configuration of DAC */ + userConfig->dacCfg.dacVoltInSel = (CmpDrv_VrselType)(CmpReg_GetVrselReg(obj->reg)); + userConfig->dacCfg.dacVoltScale = CmpReg_GetVoselReg(obj->reg); + userConfig->dacCfg.state = CmpReg_GetDacenReg(obj->reg); + + /* Get configuration of analog mux */ + userConfig->muxCfg.posPortMux = (CmpDrv_InPortType)(CmpReg_GetInpselReg(obj->reg)); + userConfig->muxCfg.negPortMux = (CmpDrv_InPortType)(CmpReg_GetInnselReg(obj->reg)); + userConfig->muxCfg.posInputMux = (CmpDrv_ChSelType)(CmpReg_GetPselReg(obj->reg)); + userConfig->muxCfg.negInputMux = (CmpDrv_ChSelType)(CmpReg_GetMselReg(obj->reg)); + + /* Configuration of round robin modes */ + userConfig->rrCfg.intrEnable = CmpReg_GetRrieReg(obj->reg); + userConfig->rrCfg.fixedMuxPort = (CmpDrv_FxmpType)(CmpReg_GetFxmpReg(obj->reg)); + userConfig->rrCfg.fixedChnSel = (CmpDrv_ChSelType)(CmpReg_GetFxmxchReg(obj->reg)); + userConfig->rrCfg.sampleCnt = CmpReg_GetNsamReg(obj->reg); + userConfig->rrCfg.initDelayCnt = CmpReg_GetInitmodReg(obj->reg); + userConfig->rrCfg.channelState = CmpDrv_GetChannelState(obj); + userConfig->rrCfg.channelPreState = CmpDrv_GetChannelPreState(obj); +} + +void CmpDrv_GetDefaultConfig(CmpDrv_ConfigType *userConfig) +{ + /* Configuration of normal modes */ + userConfig->normalCfg.dmaEnable = false; + userConfig->normalCfg.triggerMode = CMP_BOTH_EDGES; + userConfig->normalCfg.mode = CMP_CONTINUOUS; + userConfig->normalCfg.filterSamplePeriod = 0; + userConfig->normalCfg.filterSampleCount = 0; + userConfig->normalCfg.powerMode = CMPDRV_PMODE_LS; + userConfig->normalCfg.inverterState = CMPDRV_INVT_NORMAL; + userConfig->normalCfg.pinState = false; + userConfig->normalCfg.outputSelect = CMPDRV_COS_COUT; + userConfig->normalCfg.hystLvl = CMPDRV_HYSTCTR_LEVEL_0; + userConfig->normalCfg.hystOffsetState = CMPDRV_OFFSET_LEVEL_0; + userConfig->normalCfg.lpfsel = CMPDRV_LPFSEL_10MHz; + + /* Configuration of DAC */ + userConfig->dacCfg.dacVoltInSel = CMPDRV_VRSEL_VIN1; + userConfig->dacCfg.dacVoltScale = 127U; + userConfig->dacCfg.state = true; + + /* Configuration of analog mux */ + userConfig->muxCfg.posPortMux = CMPDRV_MUX; + userConfig->muxCfg.negPortMux = CMPDRV_DAC; + + /*! \note Advise to make posInputMux = negInputMux when using DAC */ + userConfig->muxCfg.posInputMux = CMPDRV_CHANNEL_IN1; + userConfig->muxCfg.negInputMux = CMPDRV_CHANNEL_IN1; +} + +CmpDrv_TriggerType CmpDrv_GetTriggerMode(const CmpDrvType *obj) +{ + uint8_t IER = CmpReg_GetIerReg(obj->reg); + uint8_t IEF = CmpReg_GetIefReg(obj->reg); + return ((CmpDrv_TriggerType)((IER << CMP_TRIGGER_RISING_SHIFT) | (IEF << CMP_TRIGGER_FALLING_SHIFT))); +} + +void CmpDrv_SetTriggerMode(CmpDrvType *obj, const CmpDrv_TriggerType mode) +{ + uint8_t IER = (mode >> CMP_TRIGGER_RISING_SHIFT) & CMP_TRIGGER_MASK; + uint8_t IEF = (mode >> CMP_TRIGGER_FALLING_SHIFT) & CMP_TRIGGER_MASK; + CmpReg_SetIerReg(obj->reg, IER); + CmpReg_SetIefReg(obj->reg, IEF); +} + +CmpDrv_ModeType CmpDrv_GetMode(const CmpDrvType *obj) +{ + uint8_t state; + CmpDrv_ModeType mode = CMP_DISABLED; + state = CmpReg_GetEnReg(obj->reg) << CMP_STATE_EN_SHIFT; + state |= CmpReg_GetWeReg(obj->reg) << CMP_STATE_WE_SHIFT; + state |= CmpReg_GetSeReg(obj->reg) << CMP_STATE_SE_SHIFT; + uint8_t filter_sample_period = CmpReg_GetFprReg(obj->reg); + uint8_t filter_sample_count = CmpReg_GetFilterCntReg(obj->reg); + + switch(state) + { + case CMPDRV_STATE_NOSAMPLE: + if((filter_sample_period == 0U) || (filter_sample_count == 0U)) + { + mode = CMP_CONTINUOUS; + } + else if(filter_sample_count == 1U) + { + mode = CMP_SAMPLED_NONFILTRED_INT_CLK; + } + else + { + mode = CMP_SAMPLED_FILTRED_INT_CLK; + } + break; + case CMPDRV_STATE_SE: + if(filter_sample_count == 1U) + { + mode = CMP_SAMPLED_NONFILTRED_EXT_CLK; + } + else + { + mode = CMP_SAMPLED_FILTRED_EXT_CLK; + } + break; + case CMPDRV_STATE_WE: + if((filter_sample_period == 0U) || (filter_sample_count == 0U)) + { + mode = CMP_WINDOWED; + } + else if(filter_sample_count == 1U) + { + mode = CMP_WINDOWED_RESAMPLED; + } + else + { + mode = CMP_WINDOWED_FILTRED; + } + break; + case CMPDRV_STATE_WE_SE: + /*! \note If a write to this register sets both bits to 1, then ONLY SE will be treated as valid and WE is ignored*/ + if(filter_sample_count == 1U) + { + mode = CMP_SAMPLED_NONFILTRED_EXT_CLK; + } + else + { + mode = CMP_SAMPLED_FILTRED_EXT_CLK; + } + break; + default: + /* Disable case */ + break; + } + + return (mode); +} + +void CmpDrv_SetMode(CmpDrvType *obj, const CmpDrv_ModeType mode, const uint8_t filter_sample_count, const uint8_t filter_sample_period) +{ + switch(mode) + { + case CMP_DISABLED: + break; + case CMP_CONTINUOUS: + CmpReg_SetWeReg(obj->reg, false); + CmpReg_SetSeReg(obj->reg, false); + /*! \note: filter_sample_count or filter_sample_period should equal to 0*/ + CmpReg_SetFprReg(obj->reg, 0U); + CmpReg_SetFilterCntReg(obj->reg, 0U); + break; + case CMP_SAMPLED_NONFILTRED_INT_CLK: + CmpReg_SetWeReg(obj->reg, false); + CmpReg_SetSeReg(obj->reg, false); + CmpReg_SetFilterCntReg(obj->reg, 1U); + CmpReg_SetFprReg(obj->reg, filter_sample_period); + break; + case CMP_SAMPLED_NONFILTRED_EXT_CLK: + CmpReg_SetWeReg(obj->reg, false); + CmpReg_SetSeReg(obj->reg, true); + CmpReg_SetFilterCntReg(obj->reg, 1U); + CmpReg_SetFprReg(obj->reg, filter_sample_period); + break; + case CMP_SAMPLED_FILTRED_INT_CLK: + CmpReg_SetWeReg(obj->reg, false); + CmpReg_SetSeReg(obj->reg, false); + CmpReg_SetFilterCntReg(obj->reg, filter_sample_count); + CmpReg_SetFprReg(obj->reg, filter_sample_period); + break; + case CMP_SAMPLED_FILTRED_EXT_CLK: + CmpReg_SetWeReg(obj->reg, false); + CmpReg_SetSeReg(obj->reg, true); + CmpReg_SetFilterCntReg(obj->reg, filter_sample_count); + CmpReg_SetFprReg(obj->reg, filter_sample_period); + break; + case CMP_WINDOWED: + CmpReg_SetWeReg(obj->reg, true); + CmpReg_SetSeReg(obj->reg, false); + /*! \note: filter_sample_count or filter_sample_period should equal to 0*/ + CmpReg_SetFprReg(obj->reg, 0U); + CmpReg_SetFilterCntReg(obj->reg, 0U); + break; + case CMP_WINDOWED_RESAMPLED: + CmpReg_SetWeReg(obj->reg, true); + CmpReg_SetSeReg(obj->reg, false); + CmpReg_SetFilterCntReg(obj->reg, 1U); + CmpReg_SetFprReg(obj->reg, filter_sample_period); + break; + case CMP_WINDOWED_FILTRED: + CmpReg_SetWeReg(obj->reg, true); + CmpReg_SetSeReg(obj->reg, false); + CmpReg_SetFilterCntReg(obj->reg, filter_sample_count); + CmpReg_SetFprReg(obj->reg, filter_sample_period); + break; + default: + /* Impossible case*/ + break; + } +} + +uint8_t CmpDrv_GetChannelState(const CmpDrvType *obj) +{ + uint8_t tmp; + tmp = ((CmpReg_GetChn0Reg(obj->reg) & CMP_CHANNELSTATE_MASK) << CMPDRV_CHANNEL_IN0) + | ((CmpReg_GetChn1Reg(obj->reg) & CMP_CHANNELSTATE_MASK) << CMPDRV_CHANNEL_IN1) + | ((CmpReg_GetChn2Reg(obj->reg) & CMP_CHANNELSTATE_MASK) << CMPDRV_CHANNEL_IN2) + | ((CmpReg_GetChn3Reg(obj->reg) & CMP_CHANNELSTATE_MASK) << CMPDRV_CHANNEL_IN3) + | ((CmpReg_GetChn4Reg(obj->reg) & CMP_CHANNELSTATE_MASK) << CMPDRV_CHANNEL_IN4) + | ((CmpReg_GetChn5Reg(obj->reg) & CMP_CHANNELSTATE_MASK) << CMPDRV_CHANNEL_IN5) + | ((CmpReg_GetChn6Reg(obj->reg) & CMP_CHANNELSTATE_MASK) << CMPDRV_CHANNEL_IN6) + | ((CmpReg_GetChn7Reg(obj->reg) & CMP_CHANNELSTATE_MASK) << CMPDRV_CHANNEL_IN7); + return (tmp); +} + +void CmpDrv_SetChannelState(CmpDrvType *obj, const uint8_t channelState) +{ + CmpReg_SetChn0Reg(obj->reg, (channelState >> CMPDRV_CHANNEL_IN0) & CMP_CHANNELSTATE_MASK); + CmpReg_SetChn1Reg(obj->reg, (channelState >> CMPDRV_CHANNEL_IN1) & CMP_CHANNELSTATE_MASK); + CmpReg_SetChn2Reg(obj->reg, (channelState >> CMPDRV_CHANNEL_IN2) & CMP_CHANNELSTATE_MASK); + CmpReg_SetChn3Reg(obj->reg, (channelState >> CMPDRV_CHANNEL_IN3) & CMP_CHANNELSTATE_MASK); + CmpReg_SetChn4Reg(obj->reg, (channelState >> CMPDRV_CHANNEL_IN4) & CMP_CHANNELSTATE_MASK); + CmpReg_SetChn5Reg(obj->reg, (channelState >> CMPDRV_CHANNEL_IN5) & CMP_CHANNELSTATE_MASK); + CmpReg_SetChn6Reg(obj->reg, (channelState >> CMPDRV_CHANNEL_IN6) & CMP_CHANNELSTATE_MASK); + CmpReg_SetChn7Reg(obj->reg, (channelState >> CMPDRV_CHANNEL_IN7) & CMP_CHANNELSTATE_MASK); +} + +uint8_t CmpDrv_GetChannelPreState(const CmpDrvType *obj) +{ + uint8_t tmp; + tmp = ((CmpReg_GetAco0Reg(obj->reg) & CMP_CHANNEL_PRESTATE_MASK) << CMPDRV_CHANNEL_IN0) + | ((CmpReg_GetAco1Reg(obj->reg) & CMP_CHANNEL_PRESTATE_MASK) << CMPDRV_CHANNEL_IN1) + | ((CmpReg_GetAco2Reg(obj->reg) & CMP_CHANNEL_PRESTATE_MASK) << CMPDRV_CHANNEL_IN2) + | ((CmpReg_GetAco3Reg(obj->reg) & CMP_CHANNEL_PRESTATE_MASK) << CMPDRV_CHANNEL_IN3) + | ((CmpReg_GetAco4Reg(obj->reg) & CMP_CHANNEL_PRESTATE_MASK) << CMPDRV_CHANNEL_IN4) + | ((CmpReg_GetAco5Reg(obj->reg) & CMP_CHANNEL_PRESTATE_MASK) << CMPDRV_CHANNEL_IN5) + | ((CmpReg_GetAco6Reg(obj->reg) & CMP_CHANNEL_PRESTATE_MASK) << CMPDRV_CHANNEL_IN6) + | ((CmpReg_GetAco7Reg(obj->reg) & CMP_CHANNEL_PRESTATE_MASK) << CMPDRV_CHANNEL_IN7); + return (tmp); +} + +void CmpDrv_SetChannelPreState(CmpDrvType *obj, const uint8_t channelPreState) +{ + CmpReg_SetAco0Reg(obj->reg, (channelPreState >> CMPDRV_CHANNEL_IN0) & CMP_CHANNEL_PRESTATE_MASK); + CmpReg_SetAco1Reg(obj->reg, (channelPreState >> CMPDRV_CHANNEL_IN1) & CMP_CHANNEL_PRESTATE_MASK); + CmpReg_SetAco2Reg(obj->reg, (channelPreState >> CMPDRV_CHANNEL_IN2) & CMP_CHANNEL_PRESTATE_MASK); + CmpReg_SetAco3Reg(obj->reg, (channelPreState >> CMPDRV_CHANNEL_IN3) & CMP_CHANNEL_PRESTATE_MASK); + CmpReg_SetAco4Reg(obj->reg, (channelPreState >> CMPDRV_CHANNEL_IN4) & CMP_CHANNEL_PRESTATE_MASK); + CmpReg_SetAco5Reg(obj->reg, (channelPreState >> CMPDRV_CHANNEL_IN5) & CMP_CHANNEL_PRESTATE_MASK); + CmpReg_SetAco6Reg(obj->reg, (channelPreState >> CMPDRV_CHANNEL_IN6) & CMP_CHANNEL_PRESTATE_MASK); + CmpReg_SetAco7Reg(obj->reg, (channelPreState >> CMPDRV_CHANNEL_IN7) & CMP_CHANNEL_PRESTATE_MASK); +} + +void CmpDrv_SetCmpState(CmpDrvType *obj, const bool state) +{ + /* Unclock CMP */ + CmpReg_UnlockReg(obj->reg); + + /* Set CMP state */ + CmpReg_SetEnReg(obj->reg, state); + + /* lock CMP */ + CmpReg_LockReg(obj->reg); +} + +CmpDrv_TriggerType CmpDrv_GetOutputFlags(const CmpDrvType *obj) +{ + uint8_t CFF; + uint8_t CFR; + CFF = CmpReg_GetCffReg(obj->reg) & CMP_TRIGGER_MASK; + CFR = CmpReg_GetCfrReg(obj->reg) & CMP_TRIGGER_MASK; + return ((CmpDrv_TriggerType)((CFF << CMP_TRIGGER_FALLING_SHIFT) | (CFR << CMP_TRIGGER_RISING_SHIFT))); +} + +void CmpDrv_ClearOutputFlags(CmpDrvType *obj) +{ + CmpReg_ClearCffReg(obj->reg); + CmpReg_ClearCfrReg(obj->reg); +} + +uint8_t CmpDrv_GetInputFlags(const CmpDrvType *obj) +{ + uint8_t tmp; + tmp = ((CmpReg_GetCh0fReg(obj->reg) & CMP_CHNF_MASK) << CMPDRV_CHANNEL_IN0) + | ((CmpReg_GetCh1fReg(obj->reg) & CMP_CHNF_MASK) << CMPDRV_CHANNEL_IN1) + | ((CmpReg_GetCh2fReg(obj->reg) & CMP_CHNF_MASK) << CMPDRV_CHANNEL_IN2) + | ((CmpReg_GetCh3fReg(obj->reg) & CMP_CHNF_MASK) << CMPDRV_CHANNEL_IN3) + | ((CmpReg_GetCh4fReg(obj->reg) & CMP_CHNF_MASK) << CMPDRV_CHANNEL_IN4) + | ((CmpReg_GetCh5fReg(obj->reg) & CMP_CHNF_MASK) << CMPDRV_CHANNEL_IN5) + | ((CmpReg_GetCh6fReg(obj->reg) & CMP_CHNF_MASK) << CMPDRV_CHANNEL_IN6) + | ((CmpReg_GetCh7fReg(obj->reg) & CMP_CHNF_MASK) << CMPDRV_CHANNEL_IN7); + return (tmp); +} + +void CmpDrv_ClearInputFlags(CmpDrvType *obj) +{ + CmpReg_ClearCh0fReg(obj->reg); + CmpReg_ClearCh1fReg(obj->reg); + CmpReg_ClearCh2fReg(obj->reg); + CmpReg_ClearCh3fReg(obj->reg); + CmpReg_ClearCh4fReg(obj->reg); + CmpReg_ClearCh5fReg(obj->reg); + CmpReg_ClearCh6fReg(obj->reg); + CmpReg_ClearCh7fReg(obj->reg); +} + +void CmpDrv_ConfigureDac(CmpDrvType *obj, const CmpDrv_DacCfgType *userConfig) +{ + /* Unclock CMP */ + CmpReg_UnlockReg(obj->reg); + + /* Disable CMP first */ + CmpReg_SetEnReg(obj->reg, false); + + /* Configuration of DAC */ + CmpReg_SetVrselReg(obj->reg, userConfig->dacVoltInSel); + CmpReg_SetVoselReg(obj->reg, userConfig->dacVoltScale); + CmpReg_SetDacenReg(obj->reg, userConfig->state); + + /* lock CMP */ + CmpReg_LockReg(obj->reg); + + /*! \note When enable CMP depend on user(use CmpDrv_SetCmpState for enable CMP)*/ +} + +void CmpDrv_GetDacConfig(const CmpDrvType *obj, CmpDrv_DacCfgType *userConfig) +{ + userConfig->dacVoltInSel = (CmpDrv_VrselType)(CmpReg_GetVrselReg(obj->reg)); + userConfig->dacVoltScale = CmpReg_GetVoselReg(obj->reg); + userConfig->state = CmpReg_GetDacenReg(obj->reg); +} + +void CmpDrv_ConfigureMux(CmpDrvType *obj, const CmpDrv_MuxCfgType *userConfig) +{ + /* Unclock CMP */ + CmpReg_UnlockReg(obj->reg); + + /* Disable CMP */ + CmpReg_SetEnReg(obj->reg, false); + + /* Configuration of analog mux */ + CmpReg_SetInpselReg(obj->reg, userConfig->posPortMux); + CmpReg_SetInnselReg(obj->reg, userConfig->negPortMux); + CmpReg_SetPselReg(obj->reg, userConfig->posInputMux); + CmpReg_SetMselReg(obj->reg, userConfig->negInputMux); + + /* lock CMP*/ + CmpReg_LockReg(obj->reg); + + /*! \note When enable CMP depend on user(use CmpDrv_SetCmpState for enable CMP)*/ +} + +void CmpDrv_GetMuxConfig(const CmpDrvType *obj, CmpDrv_MuxCfgType *userConfig) +{ + userConfig->posPortMux = (CmpDrv_InPortType)(CmpReg_GetInpselReg(obj->reg)); + userConfig->negPortMux = (CmpDrv_InPortType)(CmpReg_GetInnselReg(obj->reg)); + userConfig->posInputMux = (CmpDrv_ChSelType)(CmpReg_GetPselReg(obj->reg)); + userConfig->negInputMux = (CmpDrv_ChSelType)(CmpReg_GetMselReg(obj->reg)); +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cmp/cmp_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cmp/cmp_drv.h new file mode 100644 index 0000000..c22bc0d --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cmp/cmp_drv.h @@ -0,0 +1,391 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CMP_DRV_H_ +#define _CMP_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of CMP module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup cmp_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + *******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief CMP type of comparator output invert selection + */ +typedef enum +{ + CMPDRV_INVT_NORMAL = 0U, /*!< Output signal isn't inverted */ + CMPDRV_INVT_INVERT = 1U, /*!< Output signal is inverted. */ +} CmpDrv_InvtType; + +/*! \brief CMP type of input channel low-pass filer cut-off frequency select signal + */ +typedef enum +{ + CMPDRV_LPFSEL_23MHz = 0U, /*!< 23MHz */ + CMPDRV_LPFSEL_16MHz = 1U, /*!< 16MHz */ + CMPDRV_LPFSEL_13MHz = 2U, /*!< 13MHz */ + CMPDRV_LPFSEL_10MHz = 3U, /*!< 10MHz */ +} CmpDrv_LpfselType; + +/*! \brief CMP type of power Mode + */ +typedef enum +{ + CMPDRV_PMODE_LS = 0U, /*!< Low Speed (LS) comparison mode is selected */ + CMPDRV_PMODE_HS = 1U, /*!< High Speed (HS) comparison mode is selected*/ +} CmpDrv_PmodeType; + +/*! \brief CMP type of comparator output + */ +typedef enum +{ + CMPDRV_COS_COUT = 0U, /*!< Set CMPO to equal COUT (filtered comparator output) */ + CMPDRV_COS_COUTA = 1U, /*!< Set CMPO to equal COUTA (unfiltered comparator output)*/ +} CmpDrv_CosType; + +/*! \brief CMP type of comparator hard block offset control + */ +typedef enum +{ + CMPDRV_OFFSET_LEVEL_0 = 0U, /*!< The comparator hard block output has level 0 offset internally*/ + CMPDRV_OFFSET_LEVEL_1 = 1U, /*!< The comparator hard block output has level 1 offset internally*/ +} CmpDrv_OffsetType; + +/*! \brief CMP type of hard block hysteresis control + */ +typedef enum +{ + CMPDRV_HYSTCTR_LEVEL_0 = 0U, /*!< The hard block output has level 0 hysteresis internally*/ + CMPDRV_HYSTCTR_LEVEL_1 = 1U, /*!< The hard block output has level 1 hysteresis internally*/ + CMPDRV_HYSTCTR_LEVEL_2 = 2U, /*!< The hard block output has level 2 hysteresis internally*/ + CMPDRV_HYSTCTR_LEVEL_3 = 3U, /*!< The hard block output has level 3 hysteresis internally*/ +} CmpDrv_HystctrType; + +/*! \brief CMP type of selection of the input to the positive or negative port of the comparator + */ +typedef enum +{ + CMPDRV_DAC = 0U, /*!< IN0, from the 8-bit DAC output*/ + CMPDRV_MUX = 1U, /*!< IN1, from the analog 8-1 mux(P/N MUX)*/ +} CmpDrv_InPortType; + +/*! \brief CMP type of channel selection. + */ +typedef enum +{ + CMPDRV_CHANNEL_IN0 = 0U, /*!< Select IN0 from the analog 8-1 mux */ + CMPDRV_CHANNEL_IN1 = 1U, /*!< Select IN1 from the analog 8-1 mux */ + CMPDRV_CHANNEL_IN2 = 2U, /*!< Select IN2 from the analog 8-1 mux */ + CMPDRV_CHANNEL_IN3 = 3U, /*!< Select IN3 from the analog 8-1 mux */ + CMPDRV_CHANNEL_IN4 = 4U, /*!< Select IN4 from the analog 8-1 mux */ + CMPDRV_CHANNEL_IN5 = 5U, /*!< Select IN5 from the analog 8-1 mux */ + CMPDRV_CHANNEL_IN6 = 6U, /*!< Select IN6 from the analog 8-1 mux */ + CMPDRV_CHANNEL_IN7 = 7U, /*!< Select IN7 from the analog 8-1 mux */ +} CmpDrv_ChSelType; + +/*! \brief CMP type of supply voltage reference source + */ +typedef enum +{ + CMPDRV_VRSEL_VIN1 = 0U, /*!< Vin1 is selected as resistor ladder network supply reference Vin*/ + CMPDRV_VRSEL_VIN2 = 1U, /*!< Vin2 is selected as resistor ladder network supply reference Vin*/ +} CmpDrv_VrselType; + +/*! \brief CMP type of fix the analog mux port for the round-robin mode + */ +typedef enum +{ + CMPDRV_FXMP_PLUS = 0U, /*!< The Plus port is fixed. Only the inputs to the Minus port are swept in each round*/ + CMPDRV_FXMP_MINUS = 1U, /*!< The Minus port is fixed. Only the inputs to the Plus port are swept in each round*/ +} CmpDrv_FxmpType; + +/*! \brief CMP type of output interrupt configuration + */ +typedef enum +{ + CMP_NO_EVENT = 0U, /*!< Comparator output interrupts are disabled OR no event occurred. */ + CMP_FALLING_EDGE = 1U, /*!< Comparator output interrupts will be generated only on falling edge OR only falling edge event occurred. */ + CMP_RISING_EDGE = 2U, /*!< Comparator output interrupts will be generated only on rising edge OR only rising edge event occurred. */ + CMP_BOTH_EDGES = 3U, /*!< Comparator output interrupts will be generated on both edges OR both edges event occurred. */ +} CmpDrv_TriggerType; + +/*! \brief CMP type of functional modes + */ +typedef enum +{ + CMP_DISABLED = 0U, /*!< CMP is disabled */ + CMP_CONTINUOUS = 1U, /*!< Continuous mode */ + CMP_SAMPLED_NONFILTRED_INT_CLK = 2U, /*!< Sampled, Non-Filtered mode with interior clock */ + CMP_SAMPLED_NONFILTRED_EXT_CLK = 3U, /*!< Sampled, Non-Filtered mode with exterior clock */ + CMP_SAMPLED_FILTRED_INT_CLK = 4U, /*!< Sampled, Filtered mode with interior clock */ + CMP_SAMPLED_FILTRED_EXT_CLK = 5U, /*!< Sampled, Filtered mode with exterior clock */ + CMP_WINDOWED = 6U, /*!< Windowed mode */ + CMP_WINDOWED_RESAMPLED = 7U, /*!< Windowed/Resampled mode */ + CMP_WINDOWED_FILTRED = 8U, /*!< Windowed/Filtered mode */ +} CmpDrv_ModeType; + +/*! \brief Definition of configuration of CMP driver in normal modes + */ +typedef struct _CmpDrv_NormalCfgType_ +{ + bool dmaEnable; /*!< Enables the DMA transfer triggered from the CMP module*/ + CmpDrv_TriggerType triggerMode; /*!< Interrupt configuration*/ + CmpDrv_ModeType mode; /*!< The comparator functional mode*/ + uint8_t filterSamplePeriod; /*!< Filter sample period */ + uint8_t filterSampleCount; /*!< Number of sample count for filtering */ + CmpDrv_PmodeType powerMode; /*!< Power mode select */ + CmpDrv_InvtType inverterState; /*!< Comparator invert */ + bool pinState; /*!< Comparator output pin enable */ + CmpDrv_CosType outputSelect; /*!< Comparator output select */ + CmpDrv_HystctrType hystLvl; /*!< Comparator hard block hysteresis control */ + CmpDrv_OffsetType hystOffsetState; /*!< Comparator hard block offset control */ + CmpDrv_LpfselType lpfsel; /*!< CMP input channel low-pass filer cut-off frequency select signal */ +} CmpDrv_NormalCfgType; + +/*! \brief Definition of configuration of CMP driver of the analog mux + */ +typedef struct _CmpDrv_MuxCfgType_ +{ + CmpDrv_InPortType posPortMux; /*!< Select positive port signal*/ + CmpDrv_InPortType negPortMux; /*!< Select negative port signal*/ + CmpDrv_ChSelType posInputMux; /*!< Select which channel is selected for the plus mux*/ + CmpDrv_ChSelType negInputMux; /*!< Select which channel is selected for the minus mux*/ +} CmpDrv_MuxCfgType; + +/*! \brief Definition of configuration of CMP driver in round robin modes + */ +typedef struct _CmpDrv_RoundRobinCfgType_ +{ + bool intrEnable; /*!< Round - Robin interrupt enable*/ + CmpDrv_FxmpType fixedMuxPort; /*!< Fixed the analog mux port for the round-robin mode*/ + CmpDrv_ChSelType fixedChnSel; /*!< Select channel in the mux port is fixed in a given round-robin mode*/ + uint8_t sampleCnt; /*!< Select number of round-robin clock cycles for a given channel*/ + uint8_t initDelayCnt; /*!< Comparator and DAC initialization delay modulus*/ + uint8_t channelState; /*!< One bit for each channel state*/ + /*!< |---------|---------|-----|---------|---------|*/ + /*!< |CH7_state|CH6_state|.....|CH1_state|CH0_state|*/ + /*!< |---------|---------|-----|---------|---------|*/ + uint8_t channelPreState; /*!< One bit for each channel pre-set state*/ +} CmpDrv_RoundRobinCfgType; + +/*! \brief Definition of configuration of DAC + */ +typedef struct _CmpDrv_DacCfgType_ +{ + CmpDrv_VrselType dacVoltInSel; /*!< Supply Voltage Reference Source Select*/ + uint8_t dacVoltScale; /*!< DAC Output Voltage Select*/ + bool state; /*!< DAC Enable*/ +} CmpDrv_DacCfgType; + +/*! \brief Definition of configuration of CMP driver + */ +typedef struct _CmpDrv_ConfigType_ +{ + CmpDrv_NormalCfgType normalCfg; + CmpDrv_RoundRobinCfgType rrCfg; + CmpDrv_DacCfgType dacCfg; + CmpDrv_MuxCfgType muxCfg; +} CmpDrv_ConfigType; + +/* Forward declaration of CMP register */ +struct _CmpRegType_; + +/*! \brief The definition of CMP driver class + */ +typedef struct _CmpDrvType_ +{ + struct _CmpRegType_ *reg; +} CmpDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the CMP driver module + * + * This function initializes CMP driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to CMP driver instance + * \param[in] reg : pointer to CMP register instance + */ +extern void CmpDrv_Init(CmpDrvType *obj, struct _CmpRegType_ *reg); + +/*! \brief Configures the CMP normal module from a user configuration structure + * + * This function configures the CMP normal module from a user configuration structure + * + * \param[in] obj : pointer to CMP driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void CmpDrv_ConfigureNormal(CmpDrvType *obj, const CmpDrv_ConfigType *userConfig); + +/*! \brief Configures the CMP round robin module from a user configuration structure + * + * This function configures the CMP round robin module from a user configuration structure + * + * \param[in] obj : pointer to CMP driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void CmpDrv_ConfigureTriggerMode(CmpDrvType *obj, const CmpDrv_ConfigType *userConfig); + +/*! \brief Get configures of the CMP module currently + * + * This function gets configures of the CMP module currently + * + * \param[in] obj : pointer to CMP driver instance + * \param[out] userConfig : pointer to configuration structure + */ +extern void CmpDrv_GetConfig(const CmpDrvType *obj, CmpDrv_ConfigType *userConfig); + +/*! \brief Get default configures the CMP module for configuration structure + * + * This function gets default configures the CMP module for user configuration structure + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void CmpDrv_GetDefaultConfig(CmpDrv_ConfigType *userConfig); + +/*! \brief Set state for CMP + * + * This function for enable or disable CMP + * + * \param[in] obj : pointer to CMP driver instance + * \param[in] state : state for CMP + */ +extern void CmpDrv_SetCmpState(CmpDrvType *obj, const bool state); + +/*! \brief Get state from CMP + * + * This function for get state from CMP + * + * \param[in] obj : pointer to CMP driver instance + * \param[out] bool : CMP current state + */ +extern bool CmpDrv_GetCmpState(const CmpDrvType *obj); + +/*! \brief Get CMP output flags + * + * This function for get CMP output flags + * + * \param[in] obj : pointer to CMP driver instance + * \param[out] CmpDrv_TriggerType : CMP current output flags + */ +extern CmpDrv_TriggerType CmpDrv_GetOutputFlags(const CmpDrvType *obj); + +/*! \brief Clear CMP output flags + * + * This function for clear CMP output flags + * + * \param[in] obj : pointer to CMP driver instance + */ +extern void CmpDrv_ClearOutputFlags(CmpDrvType *obj); + +/*! \brief Clear CMP input flags + * + * This function for clear CMP input flags + * + * \param[in] obj : pointer to CMP driver instance + */ +extern void CmpDrv_ClearInputFlags(CmpDrvType *obj); + +/*! \brief Get CMP input flags + * + * This function for get CMP input flags + * + * \param[in] obj : pointer to CMP driver instance + * \param[out] uint8_t : CMP input flags + */ +extern uint8_t CmpDrv_GetInputFlags(const CmpDrvType *obj); + +/*! \brief Configures the CMP DAC from a user configuration structure + * + * This function configures the CMP DAC from a user configuration structure + * + * \param[in] obj : pointer to CMP driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void CmpDrv_ConfigureDac(CmpDrvType *obj, const CmpDrv_DacCfgType *userConfig); + +/*! \brief Get configuration the CMP DAC from a user configuration structure + * + * This function configures the CMP DAC from a user configuration structure + * + * \param[in] obj : pointer to CMP driver instance + * \param[out] userConfig : pointer to configuration structure + */ +extern void CmpDrv_GetDacConfig(const CmpDrvType *obj, CmpDrv_DacCfgType *userConfig); + +/*! \brief Configures the CMP analog mux from a user configuration structure + * + * This function configures the CMP analog mux from a user configuration structure + * + * \param[in] obj : pointer to CMP driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void CmpDrv_ConfigureMux(CmpDrvType *obj, const CmpDrv_MuxCfgType *userConfig); + +/*! \brief Get configuration the CMP analog mux from a user configuration structure + * + * This function configures the CMP analog mux from a user configuration structure + * + * \param[in] obj : pointer to CMP driver instance + * \param[out] userConfig : pointer to configuration structure + */ +extern void CmpDrv_GetMuxConfig(const CmpDrvType *obj, CmpDrv_MuxCfgType *userConfig); + +/*! \brief Configures the CMP ACO from a user configuration structure + * + * This function configures the CMP ACO from a user configuration structure + * + * \param[in] obj : pointer to CMP driver instance + * \param[in] channelPreState : defines the pre-set state of channel n. + */ +extern void CmpDrv_SetChannelPreState(CmpDrvType *obj, const uint8_t channelPreState); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _CMP_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cmu/cmu_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cmu/cmu_drv.c new file mode 100644 index 0000000..e4aa971 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cmu/cmu_drv.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "cmu_drv.h" +#include "cmu_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void CmuDrv_Init(CmuDrvType *obj, struct _CmuRegType_ *reg) +{ + obj->reg = reg; +} + +void CmuDrv_Configure(CmuDrvType *obj, const CmuDrv_ConfigType *userConfig) +{ + /* Set referency frequency cnt */ + CmuReg_SetRefCnt(obj->reg, userConfig->refClkCnt); + /* Set the high threshold value */ + CmuReg_SetFreqHighRefValue(obj->reg, userConfig->highRefFreq); + /* Set the low threshold value */ + CmuReg_SetFreqLowRefValue(obj->reg, userConfig->lowRefFreq); + /* Set high event state */ + CmuReg_SetFreqHighEventState(obj->reg, (uint8_t)userConfig->highFreqEventSt); + /* Set low event state */ + CmuReg_SetFreqLowEventState(obj->reg, (uint8_t)userConfig->lowFreqEventSt); +} + +void CmuDrv_GetConfig(const CmuDrvType *obj, CmuDrv_ConfigType *userConfig) +{ + /* Get referency frequency cnt */ + userConfig->refClkCnt = CmuReg_GetRefCnt(obj->reg); + /* Get the high threshold value */ + userConfig->highRefFreq = CmuReg_GetFreqHighRefValue(obj->reg); + /* Get the low threshold value */ + userConfig->lowRefFreq = CmuReg_GetFreqLowRefValue(obj->reg); + /* Get high event state */ + userConfig->highFreqEventSt = (CmuDrv_EventStateType)CmuReg_GetFreqHighEventState(obj->reg); + /* Get low event state */ + userConfig->lowFreqEventSt = (CmuDrv_EventStateType)CmuReg_GetFreqLowEventState(obj->reg); +} + +void CmuDrv_GetDefaultConfig(CmuDrv_ConfigType *userConfig) +{ + /* Get referency frequency cnt */ + userConfig->refClkCnt = 0U; + /* Get the high threshold value */ + userConfig->highRefFreq = 0U; + /* Get the low threshold value */ + userConfig->lowRefFreq = 0U; + /* Get high event state */ + userConfig->highFreqEventSt = CMUDRV_DISABLE_INT_AND_RST; + /* Get low event state */ + userConfig->lowFreqEventSt = CMUDRV_DISABLE_INT_AND_RST; +} + +bool CmuDrv_IsFreqCheckEnable(const CmuDrvType *obj) +{ + /* Get CMU enable state */ + return (bool)(CmuReg_GetEnable(obj->reg)); +} + +void CmuDrv_EnableFreqCheck(const CmuDrvType *obj, bool enable) +{ + /* Set CMU enable state */ + CmuReg_SetEnable(obj->reg, enable); +} + +bool CmuDrv_IsCmuRun(const CmuDrvType *obj) +{ + /* Get CMU run state */ + return (bool)(CmuReg_GetRunStatus(obj->reg)); +} + +bool CmuDrv_IsFreqHighEventAcvt(const CmuDrvType *obj) +{ + /* Get the frequency high event flag */ + return (bool)(CmuReg_GetFreqHighEventFlag(obj->reg)); +} + +void CmuDrv_ClearFreqHighEventFlag(CmuDrvType *obj) +{ + /* Clear the frequency high event flag */ + CmuReg_ClearFreqHighEventFlag(obj->reg); +} + +bool CmuDrv_IsFreqLowEventAcvt(const CmuDrvType *obj) +{ + /* Get the frequency low event flag */ + return (bool)(CmuReg_GetFreqLowEventFlag(obj->reg)); +} + +void CmuDrv_ClearFreqLowEventFlag(CmuDrvType *obj) +{ + /* Clear the frequency low event flag */ + CmuReg_ClearFreqLowEventFlag(obj->reg); +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cmu/cmu_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cmu/cmu_drv.h new file mode 100644 index 0000000..7373e7e --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cmu/cmu_drv.h @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CMU_DRV_H_ +#define _CMU_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of CMU module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup cmu_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief CMU type of interrupt or reset enable + */ +typedef enum +{ + CMUDRV_DISABLE_INT_AND_RST = 0, /*!< disable interrupt, disable reset */ + CMUDRV_ENABLE_INT_DISABLE_RST = 1, /*!< enable interrupt, disable reset */ + CMUDRV_DISABLE_INT_ENABLE_RST = 2, /*!< disable interrupt, enable reset */ +} CmuDrv_EventStateType; + +/*! \brief Definition of configuration of CMU driver + */ +typedef struct _CmuDrv_ConfigType_ +{ + uint32_t refClkCnt; /*!< Reference frequency cnt Max Value. */ + uint32_t highRefFreq; /*!< high frequency threshod value. */ + uint32_t lowRefFreq; /*!< low frequency threshod value. */ + CmuDrv_EventStateType highFreqEventSt; /*!< State of high interrupt or reset enable. */ + CmuDrv_EventStateType lowFreqEventSt; /*!< State of low interrupt or reset enable. */ +} CmuDrv_ConfigType; + +/* Forward declaration of CMU register */ +struct _CmuRegType_; + +/*! \brief The definition of CMU driver class + */ +typedef struct _CmuDrvType_ +{ + struct _CmuRegType_ *reg; +} CmuDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the CMU driver module + * + * This function initializes CMU driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to CMU driver instance + * \param[in] reg : pointer to CMU register instance + */ +extern void CmuDrv_Init(CmuDrvType *obj, struct _CmuRegType_ *reg); + +/*! \brief Configures the CMU module from a user configuration structure + * + * This function configures the CMU module from a user configuration structure + * + * \param[in] obj : pointer to CMU driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void CmuDrv_Configure(CmuDrvType *obj, const CmuDrv_ConfigType *userConfig); + +/*! \brief Get configures of the CMU module currently + * + * This function gets configures of the CMU module currently + * + * \param[in] obj : pointer to CMU driver instance + * \param[out] userConfig : pointer to configuration structure + */ +extern void CmuDrv_GetConfig(const CmuDrvType *obj, CmuDrv_ConfigType *userConfig); + +/*! \brief Get default configures the CMU module for configuration structure + * + * This function gets default configures the CMU module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void CmuDrv_GetDefaultConfig(CmuDrv_ConfigType *userConfig); + +/*! \brief Get the state of frequency check enable + * + * This function gets the state of frequency check enable + * + * \param[in] obj : pointer to CMU driver instance + * \return state of frequency check enable + */ +extern bool CmuDrv_IsFreqCheckEnable(const CmuDrvType *obj); + +/*! \brief Set the state of frequency check enable + * + * This function sets the state of frequency check enable + * + * \param[in] obj : pointer to frequency check driver instance + * \param[in] state of CMU enable + */ +extern void CmuDrv_EnableFreqCheck(const CmuDrvType *obj, bool enable); + +/*! \brief Get the state of CMU run + * + * This function gets the state of CMU run + * + * \param[in] obj : pointer to CMU driver instance + * \return state of CMU run + */ +extern bool CmuDrv_IsCmuRun(const CmuDrvType *obj); + +/*! \brief Get the flag of frequency high + * + * This function gets the flag of frequency high + * + * \param[in] obj : pointer to CMU driver instance + * \return the flag of frequency high + */ +extern bool CmuDrv_IsFreqHighEventAcvt(const CmuDrvType *obj); + +/*! \brief Clear the flag of frequency high + * + * This function clears the flag of frequency high + * + * \param[in] obj : pointer to CMU driver instance + * \return none + */ +extern void CmuDrv_ClearFreqHighEventFlag(CmuDrvType *obj); + +/*! \brief Get the flag of frequency low + * + * This function gets the flag of frequency low + * + * \param[in] obj : pointer to CMU driver instance + * \return the flag of frequency low + */ +extern bool CmuDrv_IsFreqLowEventAcvt(const CmuDrvType *obj); + +/*! \brief Clear the flag of frequency low + * + * This function clears the flag of frequency low + * + * \param[in] obj : pointer to CMU driver instance + * \return none + */ +extern void CmuDrv_ClearFreqLowEventFlag(CmuDrvType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _CMU_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/arm_common_tables.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/arm_common_tables.h new file mode 100644 index 0000000..8742a56 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/arm_common_tables.h @@ -0,0 +1,136 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2014 ARM Limited. All rights reserved. +* +* $Date: 19. October 2015 +* $Revision: V.1.4.5 a +* +* Project: CMSIS DSP Library +* Title: arm_common_tables.h +* +* Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions +* +* Target Processor: Cortex-M4/Cortex-M3 +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* - Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* - Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* - Neither the name of ARM LIMITED nor the names of its contributors +* may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* -------------------------------------------------------------------- */ + +#ifndef _ARM_COMMON_TABLES_H +#define _ARM_COMMON_TABLES_H + +#include "arm_math.h" + +extern const uint16_t armBitRevTable[1024]; +extern const q15_t armRecipTableQ15[64]; +extern const q31_t armRecipTableQ31[64]; +/* extern const q31_t realCoefAQ31[1024]; */ +/* extern const q31_t realCoefBQ31[1024]; */ +extern const float32_t twiddleCoef_16[32]; +extern const float32_t twiddleCoef_32[64]; +extern const float32_t twiddleCoef_64[128]; +extern const float32_t twiddleCoef_128[256]; +extern const float32_t twiddleCoef_256[512]; +extern const float32_t twiddleCoef_512[1024]; +extern const float32_t twiddleCoef_1024[2048]; +extern const float32_t twiddleCoef_2048[4096]; +extern const float32_t twiddleCoef_4096[8192]; +#define twiddleCoef twiddleCoef_4096 +extern const q31_t twiddleCoef_16_q31[24]; +extern const q31_t twiddleCoef_32_q31[48]; +extern const q31_t twiddleCoef_64_q31[96]; +extern const q31_t twiddleCoef_128_q31[192]; +extern const q31_t twiddleCoef_256_q31[384]; +extern const q31_t twiddleCoef_512_q31[768]; +extern const q31_t twiddleCoef_1024_q31[1536]; +extern const q31_t twiddleCoef_2048_q31[3072]; +extern const q31_t twiddleCoef_4096_q31[6144]; +extern const q15_t twiddleCoef_16_q15[24]; +extern const q15_t twiddleCoef_32_q15[48]; +extern const q15_t twiddleCoef_64_q15[96]; +extern const q15_t twiddleCoef_128_q15[192]; +extern const q15_t twiddleCoef_256_q15[384]; +extern const q15_t twiddleCoef_512_q15[768]; +extern const q15_t twiddleCoef_1024_q15[1536]; +extern const q15_t twiddleCoef_2048_q15[3072]; +extern const q15_t twiddleCoef_4096_q15[6144]; +extern const float32_t twiddleCoef_rfft_32[32]; +extern const float32_t twiddleCoef_rfft_64[64]; +extern const float32_t twiddleCoef_rfft_128[128]; +extern const float32_t twiddleCoef_rfft_256[256]; +extern const float32_t twiddleCoef_rfft_512[512]; +extern const float32_t twiddleCoef_rfft_1024[1024]; +extern const float32_t twiddleCoef_rfft_2048[2048]; +extern const float32_t twiddleCoef_rfft_4096[4096]; + + +/* floating-point bit reversal tables */ +#define ARMBITREVINDEXTABLE__16_TABLE_LENGTH ((uint16_t)20 ) +#define ARMBITREVINDEXTABLE__32_TABLE_LENGTH ((uint16_t)48 ) +#define ARMBITREVINDEXTABLE__64_TABLE_LENGTH ((uint16_t)56 ) +#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208 ) +#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440 ) +#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448 ) +#define ARMBITREVINDEXTABLE1024_TABLE_LENGTH ((uint16_t)1800) +#define ARMBITREVINDEXTABLE2048_TABLE_LENGTH ((uint16_t)3808) +#define ARMBITREVINDEXTABLE4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE__16_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE__32_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE__64_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE1024_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE2048_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE4096_TABLE_LENGTH]; + +/* fixed-point bit reversal tables */ +#define ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH ((uint16_t)12 ) +#define ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH ((uint16_t)24 ) +#define ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH ((uint16_t)56 ) +#define ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH ((uint16_t)112 ) +#define ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH ((uint16_t)240 ) +#define ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH ((uint16_t)480 ) +#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992 ) +#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984) +#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH]; + +/* Tables for Fast Math Sine and Cosine */ +extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1]; +extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1]; +extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1]; + +#endif /* ARM_COMMON_TABLES_H */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/arm_const_structs.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/arm_const_structs.h new file mode 100644 index 0000000..726d06e --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/arm_const_structs.h @@ -0,0 +1,79 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2014 ARM Limited. All rights reserved. +* +* $Date: 19. March 2015 +* $Revision: V.1.4.5 +* +* Project: CMSIS DSP Library +* Title: arm_const_structs.h +* +* Description: This file has constant structs that are initialized for +* user convenience. For example, some can be given as +* arguments to the arm_cfft_f32() function. +* +* Target Processor: Cortex-M4/Cortex-M3 +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* - Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* - Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* - Neither the name of ARM LIMITED nor the names of its contributors +* may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* -------------------------------------------------------------------- */ + +#ifndef _ARM_CONST_STRUCTS_H +#define _ARM_CONST_STRUCTS_H + +#include "arm_math.h" +#include "arm_common_tables.h" + + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096; + + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096; + + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096; + +#endif diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/arm_math.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/arm_math.h new file mode 100644 index 0000000..d33f8a9 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/arm_math.h @@ -0,0 +1,7154 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2015 ARM Limited. All rights reserved. +* +* $Date: 20. October 2015 +* $Revision: V1.4.5 b +* +* Project: CMSIS DSP Library +* Title: arm_math.h +* +* Description: Public header file for CMSIS DSP Library +* +* Target Processor: Cortex-M7/Cortex-M4/Cortex-M3/Cortex-M0 +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* - Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* - Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* - Neither the name of ARM LIMITED nor the names of its contributors +* may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. + * -------------------------------------------------------------------- */ + +/** + \mainpage CMSIS DSP Software Library + * + * Introduction + * ------------ + * + * This user manual describes the CMSIS DSP software library, + * a suite of common signal processing functions for use on Cortex-M processor based devices. + * + * The library is divided into a number of functions each covering a specific category: + * - Basic math functions + * - Fast math functions + * - Complex math functions + * - Filters + * - Matrix functions + * - Transforms + * - Motor control functions + * - Statistical functions + * - Support functions + * - Interpolation functions + * + * The library has separate functions for operating on 8-bit integers, 16-bit integers, + * 32-bit integer and 32-bit floating-point values. + * + * Using the Library + * ------------ + * + * The library installer contains prebuilt versions of the libraries in the Lib folder. + * - arm_cortexM7lfdp_math.lib (Little endian and Double Precision Floating Point Unit on Cortex-M7) + * - arm_cortexM7bfdp_math.lib (Big endian and Double Precision Floating Point Unit on Cortex-M7) + * - arm_cortexM7lfsp_math.lib (Little endian and Single Precision Floating Point Unit on Cortex-M7) + * - arm_cortexM7bfsp_math.lib (Big endian and Single Precision Floating Point Unit on Cortex-M7) + * - arm_cortexM7l_math.lib (Little endian on Cortex-M7) + * - arm_cortexM7b_math.lib (Big endian on Cortex-M7) + * - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4) + * - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4) + * - arm_cortexM4l_math.lib (Little endian on Cortex-M4) + * - arm_cortexM4b_math.lib (Big endian on Cortex-M4) + * - arm_cortexM3l_math.lib (Little endian on Cortex-M3) + * - arm_cortexM3b_math.lib (Big endian on Cortex-M3) + * - arm_cortexM0l_math.lib (Little endian on Cortex-M0 / CortexM0+) + * - arm_cortexM0b_math.lib (Big endian on Cortex-M0 / CortexM0+) + * + * The library functions are declared in the public file arm_math.h which is placed in the Include folder. + * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single + * public header file arm_math.h for Cortex-M7/M4/M3/M0/M0+ with little endian and big endian. Same header file will be used for floating point unit(FPU) variants. + * Define the appropriate pre processor MACRO ARM_MATH_CM7 or ARM_MATH_CM4 or ARM_MATH_CM3 or + * ARM_MATH_CM0 or ARM_MATH_CM0PLUS depending on the target processor in the application. + * + * Examples + * -------- + * + * The library ships with a number of examples which demonstrate how to use the library functions. + * + * Toolchain Support + * ------------ + * + * The library has been developed and tested with MDK-ARM version 5.14.0.0 + * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. + * + * Building the Library + * ------------ + * + * The library installer contains a project file to re build libraries on MDK-ARM Tool chain in the CMSIS\\DSP_Lib\\Source\\ARM folder. + * - arm_cortexM_math.uvprojx + * + * + * The libraries can be built by opening the arm_cortexM_math.uvprojx project in MDK-ARM, selecting a specific target, and defining the optional pre processor MACROs detailed above. + * + * Pre-processor Macros + * ------------ + * + * Each library project have differant pre-processor macros. + * + * - UNALIGNED_SUPPORT_DISABLE: + * + * Define macro UNALIGNED_SUPPORT_DISABLE, If the silicon does not support unaligned memory access + * + * - ARM_MATH_BIG_ENDIAN: + * + * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. + * + * - ARM_MATH_MATRIX_CHECK: + * + * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices + * + * - ARM_MATH_ROUNDING: + * + * Define macro ARM_MATH_ROUNDING for rounding on support functions + * + * - ARM_MATH_CMx: + * + * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target + * and ARM_MATH_CM0 for building library on Cortex-M0 target, ARM_MATH_CM0PLUS for building library on Cortex-M0+ target, and + * ARM_MATH_CM7 for building the library on cortex-M7. + * + * - __FPU_PRESENT: + * + * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for M4bf and M4lf libraries + * + *
+ * CMSIS-DSP in ARM::CMSIS Pack + * ----------------------------- + * + * The following files relevant to CMSIS-DSP are present in the ARM::CMSIS Pack directories: + * |File/Folder |Content | + * |------------------------------|------------------------------------------------------------------------| + * |\b CMSIS\\Documentation\\DSP | This documentation | + * |\b CMSIS\\DSP_Lib | Software license agreement (license.txt) | + * |\b CMSIS\\DSP_Lib\\Examples | Example projects demonstrating the usage of the library functions | + * |\b CMSIS\\DSP_Lib\\Source | Source files for rebuilding the library | + * + *
+ * Revision History of CMSIS-DSP + * ------------ + * Please refer to \ref ChangeLog_pg. + * + * Copyright Notice + * ------------ + * + * Copyright (C) 2010-2015 ARM Limited. All rights reserved. + */ + + +/** + * @defgroup groupMath Basic Math Functions + */ + +/** + * @defgroup groupFastMath Fast Math Functions + * This set of functions provides a fast approximation to sine, cosine, and square root. + * As compared to most of the other functions in the CMSIS math library, the fast math functions + * operate on individual values and not arrays. + * There are separate functions for Q15, Q31, and floating-point data. + * + */ + +/** + * @defgroup groupCmplxMath Complex Math Functions + * This set of functions operates on complex data vectors. + * The data in the complex arrays is stored in an interleaved fashion + * (real, imag, real, imag, ...). + * In the API functions, the number of samples in a complex array refers + * to the number of complex values; the array contains twice this number of + * real values. + */ + +/** + * @defgroup groupFilters Filtering Functions + */ + +/** + * @defgroup groupMatrix Matrix Functions + * + * This set of functions provides basic matrix math operations. + * The functions operate on matrix data structures. For example, + * the type + * definition for the floating-point matrix structure is shown + * below: + *
+ *     typedef struct
+ *     {
+ *       uint16_t numRows;     // number of rows of the matrix.
+ *       uint16_t numCols;     // number of columns of the matrix.
+ *       float32_t *pData;     // points to the data of the matrix.
+ *     } arm_matrix_instance_f32;
+ * 
+ * There are similar definitions for Q15 and Q31 data types. + * + * The structure specifies the size of the matrix and then points to + * an array of data. The array is of size numRows X numCols + * and the values are arranged in row order. That is, the + * matrix element (i, j) is stored at: + *
+ *     pData[i*numCols + j]
+ * 
+ * + * \par Init Functions + * There is an associated initialization function for each type of matrix + * data structure. + * The initialization function sets the values of the internal structure fields. + * Refer to the function arm_mat_init_f32(), arm_mat_init_q31() + * and arm_mat_init_q15() for floating-point, Q31 and Q15 types, respectively. + * + * \par + * Use of the initialization function is optional. However, if initialization function is used + * then the instance structure cannot be placed into a const data section. + * To place the instance structure in a const data + * section, manually initialize the data structure. For example: + *
+ * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
+ * 
+ * where nRows specifies the number of rows, nColumns + * specifies the number of columns, and pData points to the + * data array. + * + * \par Size Checking + * By default all of the matrix functions perform size checking on the input and + * output matrices. For example, the matrix addition function verifies that the + * two input matrices and the output matrix all have the same number of rows and + * columns. If the size check fails the functions return: + *
+ *     ARM_MATH_SIZE_MISMATCH
+ * 
+ * Otherwise the functions return + *
+ *     ARM_MATH_SUCCESS
+ * 
+ * There is some overhead associated with this matrix size checking. + * The matrix size checking is enabled via the \#define + *
+ *     ARM_MATH_MATRIX_CHECK
+ * 
+ * within the library project settings. By default this macro is defined + * and size checking is enabled. By changing the project settings and + * undefining this macro size checking is eliminated and the functions + * run a bit faster. With size checking disabled the functions always + * return ARM_MATH_SUCCESS. + */ + +/** + * @defgroup groupTransforms Transform Functions + */ + +/** + * @defgroup groupController Controller Functions + */ + +/** + * @defgroup groupStats Statistics Functions + */ +/** + * @defgroup groupSupport Support Functions + */ + +/** + * @defgroup groupInterpolation Interpolation Functions + * These functions perform 1- and 2-dimensional interpolation of data. + * Linear interpolation is used for 1-dimensional data and + * bilinear interpolation is used for 2-dimensional data. + */ + +/** + * @defgroup groupExamples Examples + */ +#ifndef _ARM_MATH_H +#define _ARM_MATH_H + +/* ignore some GCC warnings */ +#if defined ( __GNUC__ ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +#define __CMSIS_GENERIC /* disable NVIC and Systick functions */ + +#if defined(ARM_MATH_CM7) + #include "core_cm7.h" +#elif defined (ARM_MATH_CM4) + #include "core_cm4.h" +#elif defined (ARM_MATH_CM3) + #include "core_cm3.h" +#elif defined (ARM_MATH_CM0) + #include "core_cm0.h" + #define ARM_MATH_CM0_FAMILY +#elif defined (ARM_MATH_CM0PLUS) + #include "core_cm0plus.h" + #define ARM_MATH_CM0_FAMILY +#else + #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS or ARM_MATH_CM0" +#endif + +#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */ +#include "string.h" +#include "math.h" +#ifdef __cplusplus +extern "C" +{ +#endif + + + /** + * @brief Macros required for reciprocal calculation in Normalized LMS + */ + +#define DELTA_Q31 (0x100) +#define DELTA_Q15 0x5 +#define INDEX_MASK 0x0000003F +#ifndef PI +#define PI 3.14159265358979f +#endif + + /** + * @brief Macros required for SINE and COSINE Fast math approximations + */ + +#define FAST_MATH_TABLE_SIZE 512 +#define FAST_MATH_Q31_SHIFT (32 - 10) +#define FAST_MATH_Q15_SHIFT (16 - 10) +#define CONTROLLER_Q31_SHIFT (32 - 9) +#define TABLE_SIZE 256 +#define TABLE_SPACING_Q31 0x400000 +#define TABLE_SPACING_Q15 0x80 + + /** + * @brief Macros required for SINE and COSINE Controller functions + */ + /* 1.31(q31) Fixed value of 2/360 */ + /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ +#define INPUT_SPACING 0xB60B61 + + /** + * @brief Macro for Unaligned Support + */ +#ifndef UNALIGNED_SUPPORT_DISABLE + #define ALIGN4 +#else + #if defined (__GNUC__) + #define ALIGN4 __attribute__((aligned(4))) + #else + #define ALIGN4 __align(4) + #endif +#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */ + + /** + * @brief Error status returned by some functions in the library. + */ + + typedef enum + { + ARM_MATH_SUCCESS = 0, /**< No error */ + ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ + ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ + ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */ + ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ + ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */ + ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ + } arm_status; + + /** + * @brief 8-bit fractional data type in 1.7 format. + */ + typedef int8_t q7_t; + + /** + * @brief 16-bit fractional data type in 1.15 format. + */ + typedef int16_t q15_t; + + /** + * @brief 32-bit fractional data type in 1.31 format. + */ + typedef int32_t q31_t; + + /** + * @brief 64-bit fractional data type in 1.63 format. + */ + typedef int64_t q63_t; + + /** + * @brief 32-bit floating-point type definition. + */ + typedef float float32_t; + + /** + * @brief 64-bit floating-point type definition. + */ + typedef double float64_t; + + /** + * @brief definition to read/write two 16 bit values. + */ +#if defined __CC_ARM + #define __SIMD32_TYPE int32_t __packed + #define CMSIS_UNUSED __attribute__((unused)) + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED __attribute__((unused)) + +#elif defined __GNUC__ + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED __attribute__((unused)) + +#elif defined __ICCARM__ + #define __SIMD32_TYPE int32_t __packed + #define CMSIS_UNUSED + +#elif defined __CSMC__ + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED + +#elif defined __TASKING__ + #define __SIMD32_TYPE __unaligned int32_t + #define CMSIS_UNUSED + +#else + #error Unknown compiler +#endif + +#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) +#define __SIMD32_CONST(addr) ((__SIMD32_TYPE *)(addr)) +#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE *) (addr)) +#define __SIMD64(addr) (*(int64_t **) & (addr)) + +#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) + /** + * @brief definition to pack two 16 bit values. + */ +#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ + (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) +#define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ + (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) + +#endif + + + /** + * @brief definition to pack four 8 bit values. + */ +#ifndef ARM_MATH_BIG_ENDIAN + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) +#else + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) + +#endif + + + /** + * @brief Clips Q63 to Q31 values. + */ + static __INLINE q31_t clip_q63_to_q31( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; + } + + /** + * @brief Clips Q63 to Q15 values. + */ + static __INLINE q15_t clip_q63_to_q15( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); + } + + /** + * @brief Clips Q31 to Q7 values. + */ + static __INLINE q7_t clip_q31_to_q7( + q31_t x) + { + return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? + ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; + } + + /** + * @brief Clips Q31 to Q15 values. + */ + static __INLINE q15_t clip_q31_to_q15( + q31_t x) + { + return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? + ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; + } + + /** + * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. + */ + + static __INLINE q63_t mult32x64( + q63_t x, + q31_t y) + { + return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + + (((q63_t) (x >> 32) * y))); + } + +/* + #if defined (ARM_MATH_CM0_FAMILY) && defined ( __CC_ARM ) + #define __CLZ __clz + #endif + */ +/* note: function can be removed when all toolchain support __CLZ for Cortex-M0 */ +#if defined (ARM_MATH_CM0_FAMILY) && ((defined (__ICCARM__)) ) + static __INLINE uint32_t __CLZ( + q31_t data); + + static __INLINE uint32_t __CLZ( + q31_t data) + { + uint32_t count = 0; + uint32_t mask = 0x80000000; + + while((data & mask) == 0) + { + count += 1u; + mask = mask >> 1u; + } + + return (count); + } +#endif + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type. + */ + + static __INLINE uint32_t arm_recip_q31( + q31_t in, + q31_t * dst, + q31_t * pRecipTable) + { + q31_t out; + uint32_t tempVal; + uint32_t index, i; + uint32_t signBits; + + if(in > 0) + { + signBits = ((uint32_t) (__CLZ( in) - 1)); + } + else + { + signBits = ((uint32_t) (__CLZ(-in) - 1)); + } + + /* Convert input sample to 1.31 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 24); + index = (index & INDEX_MASK); + + /* 1.31 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0u; i < 2u; i++) + { + tempVal = (uint32_t) (((q63_t) in * out) >> 31); + tempVal = 0x7FFFFFFFu - tempVal; + /* 1.31 with exp 1 */ + /* out = (q31_t) (((q63_t) out * tempVal) >> 30); */ + out = clip_q63_to_q31(((q63_t) out * tempVal) >> 30); + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1u); + } + + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type. + */ + static __INLINE uint32_t arm_recip_q15( + q15_t in, + q15_t * dst, + q15_t * pRecipTable) + { + q15_t out = 0; + uint32_t tempVal = 0; + uint32_t index = 0, i = 0; + uint32_t signBits = 0; + + if(in > 0) + { + signBits = ((uint32_t)(__CLZ( in) - 17)); + } + else + { + signBits = ((uint32_t)(__CLZ(-in) - 17)); + } + + /* Convert input sample to 1.15 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 8); + index = (index & INDEX_MASK); + + /* 1.15 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0u; i < 2u; i++) + { + tempVal = (uint32_t) (((q31_t) in * out) >> 15); + tempVal = 0x7FFFu - tempVal; + /* 1.15 with exp 1 */ + out = (q15_t) (((q31_t) out * tempVal) >> 14); + /* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */ + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1); + } + + + /* + * @brief C custom defined intrinisic function for only M0 processors + */ +#if defined(ARM_MATH_CM0_FAMILY) + static __INLINE q31_t __SSAT( + q31_t x, + uint32_t y) + { + int32_t posMax, negMin; + uint32_t i; + + posMax = 1; + for (i = 0; i < (y - 1); i++) + { + posMax = posMax * 2; + } + + if(x > 0) + { + posMax = (posMax - 1); + + if(x > posMax) + { + x = posMax; + } + } + else + { + negMin = -posMax; + + if(x < negMin) + { + x = negMin; + } + } + return (x); + } +#endif /* end of ARM_MATH_CM0_FAMILY */ + + + /* + * @brief C custom defined intrinsic function for M3 and M0 processors + */ +#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) + + /* + * @brief C custom defined QADD8 for M3 and M0 processors + */ + static __INLINE uint32_t __QADD8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) + (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) + (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) + (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) + (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QSUB8 for M3 and M0 processors + */ + static __INLINE uint32_t __QSUB8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) - (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) - (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) - (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) - (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QADD16 for M3 and M0 processors + */ + static __INLINE uint32_t __QADD16( + uint32_t x, + uint32_t y) + { +/* q31_t r, s; without initialisation 'arm_offset_q15 test' fails but 'intrinsic' tests pass! for armCC */ + q31_t r = 0, s = 0; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHADD16 for M3 and M0 processors + */ + static __INLINE uint32_t __SHADD16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSUB16 for M3 and M0 processors + */ + static __INLINE uint32_t __QSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSUB16 for M3 and M0 processors + */ + static __INLINE uint32_t __SHSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QASX for M3 and M0 processors + */ + static __INLINE uint32_t __QASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHASX for M3 and M0 processors + */ + static __INLINE uint32_t __SHASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSAX for M3 and M0 processors + */ + static __INLINE uint32_t __QSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSAX for M3 and M0 processors + */ + static __INLINE uint32_t __SHSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SMUSDX for M3 and M0 processors + */ + static __INLINE uint32_t __SMUSDX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + /* + * @brief C custom defined SMUADX for M3 and M0 processors + */ + static __INLINE uint32_t __SMUADX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + + /* + * @brief C custom defined QADD for M3 and M0 processors + */ + static __INLINE int32_t __QADD( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x + (q31_t)y))); + } + + + /* + * @brief C custom defined QSUB for M3 and M0 processors + */ + static __INLINE int32_t __QSUB( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x - (q31_t)y))); + } + + + /* + * @brief C custom defined SMLAD for M3 and M0 processors + */ + static __INLINE uint32_t __SMLAD( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLADX for M3 and M0 processors + */ + static __INLINE uint32_t __SMLADX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLSDX for M3 and M0 processors + */ + static __INLINE uint32_t __SMLSDX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALD for M3 and M0 processors + */ + static __INLINE uint64_t __SMLALD( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + ((q15_t) x * (q15_t) y)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALDX for M3 and M0 processors + */ + static __INLINE uint64_t __SMLALDX( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + ((q15_t) x * (q15_t) (y >> 16)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMUAD for M3 and M0 processors + */ + static __INLINE uint32_t __SMUAD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SMUSD for M3 and M0 processors + */ + static __INLINE uint32_t __SMUSD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SXTB16 for M3 and M0 processors + */ + static __INLINE uint32_t __SXTB16( + uint32_t x) + { + return ((uint32_t)(((((q31_t)x << 24) >> 24) & (q31_t)0x0000FFFF) | + ((((q31_t)x << 8) >> 8) & (q31_t)0xFFFF0000) )); + } + +#endif /* defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ + + + /** + * @brief Instance structure for the Q7 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q7; + + /** + * @brief Instance structure for the Q15 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_f32; + + + /** + * @brief Processing function for the Q7 FIR filter. + * @param[in] S points to an instance of the Q7 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q7( + const arm_fir_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 FIR filter. + * @param[in,out] S points to an instance of the Q7 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed. + */ + void arm_fir_init_q7( + arm_fir_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR filter. + * @param[in] S points to an instance of the Q15 FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR filter. + * @param[in,out] S points to an instance of the Q15 FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if + * numTaps is not a supported value. + */ + arm_status arm_fir_init_q15( + arm_fir_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR filter. + * @param[in] S points to an instance of the Q31 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR filter. + * @param[in,out] S points to an instance of the Q31 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_q31( + arm_fir_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR filter. + * @param[in] S points to an instance of the floating-point FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_f32( + const arm_fir_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR filter. + * @param[in,out] S points to an instance of the floating-point FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_f32( + arm_fir_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 Biquad cascade filter. + */ + typedef struct + { + int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q15; + + /** + * @brief Instance structure for the Q31 Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q31; + + /** + * @brief Instance structure for the floating-point Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_casd_df1_inst_f32; + + + /** + * @brief Processing function for the Q15 Biquad cascade filter. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q15( + arm_biquad_casd_df1_inst_q15 * S, + uint8_t numStages, + q15_t * pCoeffs, + q15_t * pState, + int8_t postShift); + + + /** + * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 Biquad cascade filter + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q31( + arm_biquad_casd_df1_inst_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q31_t * pState, + int8_t postShift); + + + /** + * @brief Processing function for the floating-point Biquad cascade filter. + * @param[in] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_f32( + const arm_biquad_casd_df1_inst_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point Biquad cascade filter. + * @param[in,out] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df1_init_f32( + arm_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float32_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f32; + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float64_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f64; + + /** + * @brief Instance structure for the Q15 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q15_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q15; + + /** + * @brief Instance structure for the Q31 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q31_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q31; + + + /** + * @brief Floating-point matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pScratch); + + + /** + * @brief Q31, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_f32( + const arm_matrix_instance_f32 * pSrc, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_q15( + const arm_matrix_instance_q15 * pSrc, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_q31( + const arm_matrix_instance_q31 * pSrc, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + + /** + * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_fast_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + + /** + * @brief Q31 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_fast_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix scaling. + * @param[in] pSrc points to the input matrix + * @param[in] scale scale factor + * @param[out] pDst points to the output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_f32( + const arm_matrix_instance_f32 * pSrc, + float32_t scale, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_q15( + const arm_matrix_instance_q15 * pSrc, + q15_t scaleFract, + int32_t shift, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_q31( + const arm_matrix_instance_q31 * pSrc, + q31_t scaleFract, + int32_t shift, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Q31 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_q31( + arm_matrix_instance_q31 * S, + uint16_t nRows, + uint16_t nColumns, + q31_t * pData); + + + /** + * @brief Q15 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_q15( + arm_matrix_instance_q15 * S, + uint16_t nRows, + uint16_t nColumns, + q15_t * pData); + + + /** + * @brief Floating-point matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_f32( + arm_matrix_instance_f32 * S, + uint16_t nRows, + uint16_t nColumns, + float32_t * pData); + + + + /** + * @brief Instance structure for the Q15 PID Control. + */ + typedef struct + { + q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ +#ifdef ARM_MATH_CM0_FAMILY + q15_t A1; + q15_t A2; +#else + q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/ +#endif + q15_t state[3]; /**< The state array of length 3. */ + q15_t Kp; /**< The proportional gain. */ + q15_t Ki; /**< The integral gain. */ + q15_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q15; + + /** + * @brief Instance structure for the Q31 PID Control. + */ + typedef struct + { + q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + q31_t A2; /**< The derived gain, A2 = Kd . */ + q31_t state[3]; /**< The state array of length 3. */ + q31_t Kp; /**< The proportional gain. */ + q31_t Ki; /**< The integral gain. */ + q31_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q31; + + /** + * @brief Instance structure for the floating-point PID Control. + */ + typedef struct + { + float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + float32_t A2; /**< The derived gain, A2 = Kd . */ + float32_t state[3]; /**< The state array of length 3. */ + float32_t Kp; /**< The proportional gain. */ + float32_t Ki; /**< The integral gain. */ + float32_t Kd; /**< The derivative gain. */ + } arm_pid_instance_f32; + + + + /** + * @brief Initialization function for the floating-point PID Control. + * @param[in,out] S points to an instance of the PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_f32( + arm_pid_instance_f32 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + */ + void arm_pid_reset_f32( + arm_pid_instance_f32 * S); + + + /** + * @brief Initialization function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q31( + arm_pid_instance_q31 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q31 PID Control structure + */ + + void arm_pid_reset_q31( + arm_pid_instance_q31 * S); + + + /** + * @brief Initialization function for the Q15 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q15( + arm_pid_instance_q15 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q15 PID Control. + * @param[in,out] S points to an instance of the q15 PID Control structure + */ + void arm_pid_reset_q15( + arm_pid_instance_q15 * S); + + + /** + * @brief Instance structure for the floating-point Linear Interpolate function. + */ + typedef struct + { + uint32_t nValues; /**< nValues */ + float32_t x1; /**< x1 */ + float32_t xSpacing; /**< xSpacing */ + float32_t *pYData; /**< pointer to the table of Y values */ + } arm_linear_interp_instance_f32; + + /** + * @brief Instance structure for the floating-point bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + float32_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_f32; + + /** + * @brief Instance structure for the Q31 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q31_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q31; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q15_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q15; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q7_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q7; + + + /** + * @brief Q7 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q15( + arm_cfft_radix2_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q15( + const arm_cfft_radix2_instance_q15 * S, + q15_t * pSrc); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q15( + arm_cfft_radix4_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_q15( + const arm_cfft_radix4_instance_q15 * S, + q15_t * pSrc); + + /** + * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q31; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q31( + arm_cfft_radix2_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q31( + const arm_cfft_radix2_instance_q31 * S, + q31_t * pSrc); + + /** + * @brief Instance structure for the Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q31; + +/* Deprecated */ + void arm_cfft_radix4_q31( + const arm_cfft_radix4_instance_q31 * S, + q31_t * pSrc); + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q31( + arm_cfft_radix4_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix2_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_f32( + arm_cfft_radix2_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_f32( + const arm_cfft_radix2_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix4_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_f32( + arm_cfft_radix4_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_f32( + const arm_cfft_radix4_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q15_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_q15; + +void arm_cfft_q15( + const arm_cfft_instance_q15 * S, + q15_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_q31; + +void arm_cfft_q31( + const arm_cfft_instance_q31 * S, + q31_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_f32; + + void arm_cfft_f32( + const arm_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the Q15 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q15; + + arm_status arm_rfft_init_q15( + arm_rfft_instance_q15 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q15( + const arm_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + /** + * @brief Instance structure for the Q31 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q31; + + arm_status arm_rfft_init_q31( + arm_rfft_instance_q31 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q31( + const arm_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint16_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_f32; + + arm_status arm_rfft_init_f32( + arm_rfft_instance_f32 * S, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_f32( + const arm_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ +typedef struct + { + arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ + uint16_t fftLenRFFT; /**< length of the real sequence */ + float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ + } arm_rfft_fast_instance_f32 ; + +arm_status arm_rfft_fast_init_f32 ( + arm_rfft_fast_instance_f32 * S, + uint16_t fftLen); + +void arm_rfft_fast_f32( + arm_rfft_fast_instance_f32 * S, + float32_t * p, float32_t * pOut, + uint8_t ifftFlag); + + /** + * @brief Instance structure for the floating-point DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + float32_t normalize; /**< normalizing factor. */ + float32_t *pTwiddle; /**< points to the twiddle factor table. */ + float32_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_f32; + + + /** + * @brief Initialization function for the floating-point DCT4/IDCT4. + * @param[in,out] S points to an instance of floating-point DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of floating-point RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of floating-point CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. + */ + arm_status arm_dct4_init_f32( + arm_dct4_instance_f32 * S, + arm_rfft_instance_f32 * S_RFFT, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint16_t N, + uint16_t Nby2, + float32_t normalize); + + + /** + * @brief Processing function for the floating-point DCT4/IDCT4. + * @param[in] S points to an instance of the floating-point DCT4/IDCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_f32( + const arm_dct4_instance_f32 * S, + float32_t * pState, + float32_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q31 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q31_t normalize; /**< normalizing factor. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + q31_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q31; + + + /** + * @brief Initialization function for the Q31 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q31 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q31 RFFT/RIFFT structure + * @param[in] S_CFFT points to an instance of Q31 CFFT/CIFFT structure + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q31( + arm_dct4_instance_q31 * S, + arm_rfft_instance_q31 * S_RFFT, + arm_cfft_radix4_instance_q31 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q31_t normalize); + + + /** + * @brief Processing function for the Q31 DCT4/IDCT4. + * @param[in] S points to an instance of the Q31 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q31( + const arm_dct4_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q15 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q15_t normalize; /**< normalizing factor. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + q15_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q15; + + + /** + * @brief Initialization function for the Q15 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q15 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q15 RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of Q15 CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q15( + arm_dct4_instance_q15 * S, + arm_rfft_instance_q15 * S_RFFT, + arm_cfft_radix4_instance_q15 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q15_t normalize); + + + /** + * @brief Processing function for the Q15 DCT4/IDCT4. + * @param[in] S points to an instance of the Q15 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q15( + const arm_dct4_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer); + + + /** + * @brief Floating-point vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a floating-point vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scale scale factor to be applied + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_f32( + float32_t * pSrc, + float32_t scale, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q7 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q7( + q7_t * pSrc, + q7_t scaleFract, + int8_t shift, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q15 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q15( + q15_t * pSrc, + q15_t scaleFract, + int8_t shift, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q31 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q31( + q31_t * pSrc, + q31_t scaleFract, + int8_t shift, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Dot product of floating-point vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t blockSize, + float32_t * result); + + + /** + * @brief Dot product of Q7 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q7( + q7_t * pSrcA, + q7_t * pSrcB, + uint32_t blockSize, + q31_t * result); + + + /** + * @brief Dot product of Q15 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Dot product of Q31 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Shifts the elements of a Q7 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q7( + q7_t * pSrc, + int8_t shiftBits, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q15 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q15( + q15_t * pSrc, + int8_t shiftBits, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q31 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q31( + q31_t * pSrc, + int8_t shiftBits, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_f32( + float32_t * pSrc, + float32_t offset, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q7( + q7_t * pSrc, + q7_t offset, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q15( + q15_t * pSrc, + q15_t offset, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q31( + q31_t * pSrc, + q31_t offset, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a floating-point vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q7 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a floating-point vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_f32( + float32_t value, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q7 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q7( + q7_t value, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q15 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q15( + q15_t value, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q31 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q31( + q31_t value, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + void arm_conv_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + void arm_conv_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Partial convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q7 sequences + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Instance structure for the Q15 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_f32; + + + /** + * @brief Processing function for the floating-point FIR decimator. + * @param[in] S points to an instance of the floating-point FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_f32( + const arm_fir_decimate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR decimator. + * @param[in,out] S points to an instance of the floating-point FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_f32( + arm_fir_decimate_instance_f32 * S, + uint16_t numTaps, + uint8_t M, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR decimator. + * @param[in,out] S points to an instance of the Q15 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q15( + arm_fir_decimate_instance_q15 * S, + uint16_t numTaps, + uint8_t M, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR decimator. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q31( + const arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q31( + arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR decimator. + * @param[in,out] S points to an instance of the Q31 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q31( + arm_fir_decimate_instance_q31 * S, + uint16_t numTaps, + uint8_t M, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ + } arm_fir_interpolate_instance_f32; + + + /** + * @brief Processing function for the Q15 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q15( + const arm_fir_interpolate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR interpolator. + * @param[in,out] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q15( + arm_fir_interpolate_instance_q15 * S, + uint8_t L, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q31( + const arm_fir_interpolate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR interpolator. + * @param[in,out] S points to an instance of the Q31 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q31( + arm_fir_interpolate_instance_q31 * S, + uint8_t L, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR interpolator. + * @param[in] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_f32( + const arm_fir_interpolate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR interpolator. + * @param[in,out] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_f32( + arm_fir_interpolate_instance_f32 * S, + uint8_t L, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the high precision Q31 Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ + } arm_biquad_cas_df1_32x64_ins_q31; + + + /** + * @param[in] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cas_df1_32x64_q31( + const arm_biquad_cas_df1_32x64_ins_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @param[in,out] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cas_df1_32x64_init_q31( + arm_biquad_cas_df1_32x64_ins_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q63_t * pState, + uint8_t postShift); + + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_stereo_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f64; + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f32( + const arm_biquad_cascade_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_stereo_df2T_f32( + const arm_biquad_cascade_stereo_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f64( + const arm_biquad_cascade_df2T_instance_f64 * S, + float64_t * pSrc, + float64_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_stereo_df2T_init_f32( + arm_biquad_cascade_stereo_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f64( + arm_biquad_cascade_df2T_instance_f64 * S, + uint8_t numStages, + float64_t * pCoeffs, + float64_t * pState); + + + /** + * @brief Instance structure for the Q15 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_f32; + + + /** + * @brief Initialization function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q15( + arm_fir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pCoeffs, + q15_t * pState); + + + /** + * @brief Processing function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q15( + const arm_fir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q31( + arm_fir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pCoeffs, + q31_t * pState); + + + /** + * @brief Processing function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q31( + const arm_fir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_f32( + arm_fir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Processing function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_f32( + const arm_fir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_f32; + + + /** + * @brief Processing function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_f32( + const arm_iir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize-1. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_init_f32( + arm_iir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pkCoeffs, + float32_t * pvCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q31( + const arm_iir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_init_q31( + arm_iir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pkCoeffs, + q31_t * pvCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the Q15 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q15( + const arm_iir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the fixed-point Q15 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process per call. + */ + void arm_iir_lattice_init_q15( + arm_iir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pkCoeffs, + q15_t * pvCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the floating-point LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that controls filter coefficient updates. */ + } arm_lms_instance_f32; + + + /** + * @brief Processing function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_f32( + const arm_lms_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_init_f32( + arm_lms_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q15; + + + /** + * @brief Initialization function for the Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q15( + arm_lms_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Processing function for Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q15( + const arm_lms_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q31; + + + /** + * @brief Processing function for Q31 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q31( + const arm_lms_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 LMS filter. + * @param[in] S points to an instance of the Q31 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q31( + arm_lms_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Instance structure for the floating-point normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that control filter coefficient updates. */ + float32_t energy; /**< saves previous frame energy. */ + float32_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_f32; + + + /** + * @brief Processing function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_f32( + arm_lms_norm_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_init_f32( + arm_lms_norm_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q31_t *recipTable; /**< points to the reciprocal initial value table. */ + q31_t energy; /**< saves previous frame energy. */ + q31_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q31; + + + /** + * @brief Processing function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q31( + arm_lms_norm_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q31( + arm_lms_norm_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Instance structure for the Q15 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< Number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q15_t *recipTable; /**< Points to the reciprocal initial value table. */ + q15_t energy; /**< saves previous frame energy. */ + q15_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q15; + + + /** + * @brief Processing function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q15( + arm_lms_norm_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q15( + arm_lms_norm_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Correlation of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Correlation of Q15 sequences + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ + void arm_correlate_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + + void arm_correlate_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + + void arm_correlate_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ + void arm_correlate_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_correlate_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Instance structure for the floating-point sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_f32; + + /** + * @brief Instance structure for the Q31 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q31; + + /** + * @brief Instance structure for the Q15 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q15; + + /** + * @brief Instance structure for the Q7 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q7; + + + /** + * @brief Processing function for the floating-point sparse FIR filter. + * @param[in] S points to an instance of the floating-point sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_f32( + arm_fir_sparse_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + float32_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point sparse FIR filter. + * @param[in,out] S points to an instance of the floating-point sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_f32( + arm_fir_sparse_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 sparse FIR filter. + * @param[in] S points to an instance of the Q31 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q31( + arm_fir_sparse_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + q31_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 sparse FIR filter. + * @param[in,out] S points to an instance of the Q31 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q31( + arm_fir_sparse_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 sparse FIR filter. + * @param[in] S points to an instance of the Q15 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q15( + arm_fir_sparse_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + q15_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 sparse FIR filter. + * @param[in,out] S points to an instance of the Q15 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q15( + arm_fir_sparse_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q7 sparse FIR filter. + * @param[in] S points to an instance of the Q7 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q7( + arm_fir_sparse_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + q7_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 sparse FIR filter. + * @param[in,out] S points to an instance of the Q7 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q7( + arm_fir_sparse_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Floating-point sin_cos function. + * @param[in] theta input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cos output. + */ + void arm_sin_cos_f32( + float32_t theta, + float32_t * pSinVal, + float32_t * pCosVal); + + + /** + * @brief Q31 sin_cos function. + * @param[in] theta scaled input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cosine output. + */ + void arm_sin_cos_q31( + q31_t theta, + q31_t * pSinVal, + q31_t * pCosVal); + + + /** + * @brief Floating-point complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup PID PID Motor Control + * + * A Proportional Integral Derivative (PID) controller is a generic feedback control + * loop mechanism widely used in industrial control systems. + * A PID controller is the most commonly used type of feedback controller. + * + * This set of functions implements (PID) controllers + * for Q15, Q31, and floating-point data types. The functions operate on a single sample + * of data and each call to the function returns a single processed value. + * S points to an instance of the PID control data structure. in + * is the input sample value. The functions return the output value. + * + * \par Algorithm: + *
+   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+   *    A0 = Kp + Ki + Kd
+   *    A1 = (-Kp ) - (2 * Kd )
+   *    A2 = Kd  
+ * + * \par + * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant + * + * \par + * \image html PID.gif "Proportional Integral Derivative Controller" + * + * \par + * The PID controller calculates an "error" value as the difference between + * the measured output and the reference input. + * The controller attempts to minimize the error by adjusting the process control inputs. + * The proportional value determines the reaction to the current error, + * the integral value determines the reaction based on the sum of recent errors, + * and the derivative value determines the reaction based on the rate at which the error has been changing. + * + * \par Instance Structure + * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. + * A separate instance structure must be defined for each PID Controller. + * There are separate instance structure declarations for each of the 3 supported data types. + * + * \par Reset Functions + * There is also an associated reset function for each data type which clears the state array. + * + * \par Initialization Functions + * There is also an associated initialization function for each data type. + * The initialization function performs the following operations: + * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. + * - Zeros out the values in the state buffer. + * + * \par + * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. + * + * \par Fixed-Point Behavior + * Care must be taken when using the fixed-point versions of the PID Controller functions. + * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup PID + * @{ + */ + + /** + * @brief Process function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + */ + static __INLINE float32_t arm_pid_f32( + arm_pid_instance_f32 * S, + float32_t in) + { + float32_t out; + + /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ + out = (S->A0 * in) + + (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + + /** + * @brief Process function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q31 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 64-bit accumulator. + * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. + * Thus, if the accumulator result overflows it wraps around rather than clip. + * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. + * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. + */ + static __INLINE q31_t arm_pid_q31( + arm_pid_instance_q31 * S, + q31_t in) + { + q63_t acc; + q31_t out; + + /* acc = A0 * x[n] */ + acc = (q63_t) S->A0 * in; + + /* acc += A1 * x[n-1] */ + acc += (q63_t) S->A1 * S->state[0]; + + /* acc += A2 * x[n-2] */ + acc += (q63_t) S->A2 * S->state[1]; + + /* convert output to 1.31 format to add y[n-1] */ + out = (q31_t) (acc >> 31u); + + /* out += y[n-1] */ + out += S->state[2]; + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + + /** + * @brief Process function for the Q15 PID Control. + * @param[in,out] S points to an instance of the Q15 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using a 64-bit internal accumulator. + * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. + * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. + * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. + * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. + * Lastly, the accumulator is saturated to yield a result in 1.15 format. + */ + static __INLINE q15_t arm_pid_q15( + arm_pid_instance_q15 * S, + q15_t in) + { + q63_t acc; + q15_t out; + +#ifndef ARM_MATH_CM0_FAMILY + __SIMD32_TYPE *vstate; + + /* Implementation of PID controller */ + + /* acc = A0 * x[n] */ + acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in); + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + vstate = __SIMD32_CONST(S->state); + acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)*vstate, (uint64_t)acc); +#else + /* acc = A0 * x[n] */ + acc = ((q31_t) S->A0) * in; + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc += (q31_t) S->A1 * S->state[0]; + acc += (q31_t) S->A2 * S->state[1]; +#endif + + /* acc += y[n-1] */ + acc += (q31_t) S->state[2] << 15; + + /* saturate the output */ + out = (q15_t) (__SSAT((acc >> 15), 16)); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + /** + * @} end of PID group + */ + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f32( + const arm_matrix_instance_f32 * src, + arm_matrix_instance_f32 * dst); + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f64( + const arm_matrix_instance_f64 * src, + arm_matrix_instance_f64 * dst); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup clarke Vector Clarke Transform + * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. + * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents + * in the two-phase orthogonal stator axis Ialpha and Ibeta. + * When Ialpha is superposed with Ia as shown in the figure below + * \image html clarke.gif Stator current space vector and its components in (a,b). + * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta + * can be calculated using only Ia and Ib. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeFormula.gif + * where Ia and Ib are the instantaneous stator phases and + * pIalpha and pIbeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup clarke + * @{ + */ + + /** + * + * @brief Floating-point Clarke transform + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + */ + static __INLINE void arm_clarke_f32( + float32_t Ia, + float32_t Ib, + float32_t * pIalpha, + float32_t * pIbeta) + { + /* Calculate pIalpha using the equation, pIalpha = Ia */ + *pIalpha = Ia; + + /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ + *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); + } + + + /** + * @brief Clarke transform for Q31 version + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + static __INLINE void arm_clarke_q31( + q31_t Ia, + q31_t Ib, + q31_t * pIalpha, + q31_t * pIbeta) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIalpha from Ia by equation pIalpha = Ia */ + *pIalpha = Ia; + + /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); + + /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ + product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); + + /* pIbeta is calculated by adding the intermediate products */ + *pIbeta = __QADD(product1, product2); + } + + /** + * @} end of clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q31( + q7_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_clarke Vector Inverse Clarke Transform + * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeInvFormula.gif + * where pIa and pIb are the instantaneous stator phases and + * Ialpha and Ibeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_clarke + * @{ + */ + + /** + * @brief Floating-point Inverse Clarke transform + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] pIa points to output three-phase coordinate a + * @param[out] pIb points to output three-phase coordinate b + */ + static __INLINE void arm_inv_clarke_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pIa, + float32_t * pIb) + { + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ + *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta; + } + + + /** + * @brief Inverse Clarke transform for Q31 version + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] pIa points to output three-phase coordinate a + * @param[out] pIb points to output three-phase coordinate b + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the subtraction, hence there is no risk of overflow. + */ + static __INLINE void arm_inv_clarke_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pIa, + q31_t * pIb) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); + + /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); + + /* pIb is calculated by subtracting the products */ + *pIb = __QSUB(product2, product1); + } + + /** + * @} end of inv_clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q15( + q7_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup park Vector Park Transform + * + * Forward Park transform converts the input two-coordinate vector to flux and torque components. + * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents + * from the stationary to the moving reference frame and control the spatial relationship between + * the stator vector current and rotor flux vector. + * If we consider the d axis aligned with the rotor flux, the diagram below shows the + * current vector and the relationship from the two reference frames: + * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkFormula.gif + * where Ialpha and Ibeta are the stator vector components, + * pId and pIq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup park + * @{ + */ + + /** + * @brief Floating-point Park transform + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * The function implements the forward Park transform. + * + */ + static __INLINE void arm_park_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pId, + float32_t * pIq, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ + *pId = Ialpha * cosVal + Ibeta * sinVal; + + /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ + *pIq = -Ialpha * sinVal + Ibeta * cosVal; + } + + + /** + * @brief Park transform for Q31 version + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition and subtraction, hence there is no risk of overflow. + */ + static __INLINE void arm_park_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pId, + q31_t * pIq, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Ialpha * cosVal) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * sinVal) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Ialpha * sinVal) */ + product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * cosVal) */ + product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); + + /* Calculate pId by adding the two intermediate products 1 and 2 */ + *pId = __QADD(product1, product2); + + /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ + *pIq = __QSUB(product4, product3); + } + + /** + * @} end of park group + */ + + /** + * @brief Converts the elements of the Q7 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q7_to_float( + q7_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_park Vector Inverse Park transform + * Inverse Park transform converts the input flux and torque components to two-coordinate vector. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkInvFormula.gif + * where pIalpha and pIbeta are the stator vector components, + * Id and Iq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_park + * @{ + */ + + /** + * @brief Floating-point Inverse Park transform + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + */ + static __INLINE void arm_inv_park_f32( + float32_t Id, + float32_t Iq, + float32_t * pIalpha, + float32_t * pIbeta, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ + *pIalpha = Id * cosVal - Iq * sinVal; + + /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ + *pIbeta = Id * sinVal + Iq * cosVal; + } + + + /** + * @brief Inverse Park transform for Q31 version + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + static __INLINE void arm_inv_park_q31( + q31_t Id, + q31_t Iq, + q31_t * pIalpha, + q31_t * pIbeta, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Id * cosVal) */ + product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Iq * sinVal) */ + product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Id * sinVal) */ + product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Iq * cosVal) */ + product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); + + /* Calculate pIalpha by using the two intermediate products 1 and 2 */ + *pIalpha = __QSUB(product1, product2); + + /* Calculate pIbeta by using the two intermediate products 3 and 4 */ + *pIbeta = __QADD(product4, product3); + } + + /** + * @} end of Inverse park group + */ + + + /** + * @brief Converts the elements of the Q31 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_float( + q31_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup LinearInterpolate Linear Interpolation + * + * Linear interpolation is a method of curve fitting using linear polynomials. + * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line + * + * \par + * \image html LinearInterp.gif "Linear interpolation" + * + * \par + * A Linear Interpolate function calculates an output value(y), for the input(x) + * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) + * + * \par Algorithm: + *
+   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+   *       where x0, x1 are nearest values of input x
+   *             y0, y1 are nearest values to output y
+   * 
+ * + * \par + * This set of functions implements Linear interpolation process + * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single + * sample of data and each call to the function returns a single processed value. + * S points to an instance of the Linear Interpolate function data structure. + * x is the input sample value. The functions returns the output value. + * + * \par + * if x is outside of the table boundary, Linear interpolation returns first value of the table + * if x is below input range and returns last value of table if x is above range. + */ + + /** + * @addtogroup LinearInterpolate + * @{ + */ + + /** + * @brief Process function for the floating-point Linear Interpolation Function. + * @param[in,out] S is an instance of the floating-point Linear Interpolation structure + * @param[in] x input sample to process + * @return y processed output sample. + * + */ + static __INLINE float32_t arm_linear_interp_f32( + arm_linear_interp_instance_f32 * S, + float32_t x) + { + float32_t y; + float32_t x0, x1; /* Nearest input values */ + float32_t y0, y1; /* Nearest output values */ + float32_t xSpacing = S->xSpacing; /* spacing between input values */ + int32_t i; /* Index variable */ + float32_t *pYData = S->pYData; /* pointer to output table */ + + /* Calculation of index */ + i = (int32_t) ((x - S->x1) / xSpacing); + + if(i < 0) + { + /* Iniatilize output for below specified range as least output value of table */ + y = pYData[0]; + } + else if((uint32_t)i >= S->nValues) + { + /* Iniatilize output for above specified range as last output value of table */ + y = pYData[S->nValues - 1]; + } + else + { + /* Calculation of nearest input values */ + x0 = S->x1 + i * xSpacing; + x1 = S->x1 + (i + 1) * xSpacing; + + /* Read of nearest output values */ + y0 = pYData[i]; + y1 = pYData[i + 1]; + + /* Calculation of output */ + y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); + + } + + /* returns output value */ + return (y); + } + + + /** + * + * @brief Process function for the Q31 Linear Interpolation Function. + * @param[in] pYData pointer to Q31 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + static __INLINE q31_t arm_linear_interp_q31( + q31_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q31_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (q31_t)0xFFF00000) >> 20); + + if(index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if(index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* shift left by 11 to keep fract in 1.31 format */ + fract = (x & 0x000FFFFF) << 11; + + /* Read two nearest output values from the index in 1.31(q31) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 2.30 format */ + y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); + + /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ + y += ((q31_t) (((q63_t) y1 * fract) >> 32)); + + /* Convert y to 1.31 format */ + return (y << 1u); + } + } + + + /** + * + * @brief Process function for the Q15 Linear Interpolation Function. + * @param[in] pYData pointer to Q15 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + static __INLINE q15_t arm_linear_interp_q15( + q15_t * pYData, + q31_t x, + uint32_t nValues) + { + q63_t y; /* output */ + q15_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (int32_t)0xFFF00000) >> 20); + + if(index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if(index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 13.35 format */ + y = ((q63_t) y0 * (0xFFFFF - fract)); + + /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ + y += ((q63_t) y1 * (fract)); + + /* convert y to 1.15 format */ + return (q15_t) (y >> 20); + } + } + + + /** + * + * @brief Process function for the Q7 Linear Interpolation Function. + * @param[in] pYData pointer to Q7 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + */ + static __INLINE q7_t arm_linear_interp_q7( + q7_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q7_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + uint32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + if (x < 0) + { + return (pYData[0]); + } + index = (x >> 20) & 0xfff; + + if(index >= (nValues - 1)) + { + return (pYData[nValues - 1]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index and are in 1.7(q7) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ + y = ((y0 * (0xFFFFF - fract))); + + /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ + y += (y1 * fract); + + /* convert y to 1.7(q7) format */ + return (q7_t) (y >> 20); + } + } + + /** + * @} end of LinearInterpolate group + */ + + /** + * @brief Fast approximation to the trigonometric sine function for floating-point data. + * @param[in] x input value in radians. + * @return sin(x). + */ + float32_t arm_sin_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q31_t arm_sin_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q15_t arm_sin_q15( + q15_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for floating-point data. + * @param[in] x input value in radians. + * @return cos(x). + */ + float32_t arm_cos_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q31_t arm_cos_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q15_t arm_cos_q15( + q15_t x); + + + /** + * @ingroup groupFastMath + */ + + + /** + * @defgroup SQRT Square Root + * + * Computes the square root of a number. + * There are separate functions for Q15, Q31, and floating-point data types. + * The square root function is computed using the Newton-Raphson algorithm. + * This is an iterative algorithm of the form: + *
+   *      x1 = x0 - f(x0)/f'(x0)
+   * 
+ * where x1 is the current estimate, + * x0 is the previous estimate, and + * f'(x0) is the derivative of f() evaluated at x0. + * For the square root function, the algorithm reduces to: + *
+   *     x0 = in/2                         [initial guess]
+   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
+   * 
+ */ + + + /** + * @addtogroup SQRT + * @{ + */ + + /** + * @brief Floating-point square root function. + * @param[in] in input value. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + static __INLINE arm_status arm_sqrt_f32( + float32_t in, + float32_t * pOut) + { + if(in >= 0.0f) + { + +#if (__FPU_USED == 1) && defined ( __CC_ARM ) + *pOut = __sqrtf(in); +#elif (__FPU_USED == 1) && (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) + *pOut = __builtin_sqrtf(in); +#elif (__FPU_USED == 1) && defined(__GNUC__) + *pOut = __builtin_sqrtf(in); +#elif (__FPU_USED == 1) && defined ( __ICCARM__ ) && (__VER__ >= 6040000) + __ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(in)); +#else + *pOut = sqrtf(in); +#endif + + return (ARM_MATH_SUCCESS); + } + else + { + *pOut = 0.0f; + return (ARM_MATH_ARGUMENT_ERROR); + } + } + + + /** + * @brief Q31 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q31( + q31_t in, + q31_t * pOut); + + + /** + * @brief Q15 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q15( + q15_t in, + q15_t * pOut); + + /** + * @} end of SQRT group + */ + + + /** + * @brief floating-point Circular write function. + */ + static __INLINE void arm_circularWrite_f32( + int32_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const int32_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + + /** + * @brief floating-point Circular Read function. + */ + static __INLINE void arm_circularRead_f32( + int32_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + int32_t * dst, + int32_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (int32_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q15 Circular write function. + */ + static __INLINE void arm_circularWrite_q15( + q15_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q15_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q15 Circular Read function. + */ + static __INLINE void arm_circularRead_q15( + q15_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q15_t * dst, + q15_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (q15_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update wOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q7 Circular write function. + */ + static __INLINE void arm_circularWrite_q7( + q7_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q7_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q7 Circular Read function. + */ + static __INLINE void arm_circularRead_q7( + q7_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q7_t * dst, + q7_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (q7_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Sum of the squares of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q31( + q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q15( + q15_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q7( + q7_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult); + + + /** + * @brief Mean value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Mean value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Variance of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Standard deviation of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Floating-point complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t numSamples, + q31_t * realResult, + q31_t * imagResult); + + + /** + * @brief Q31 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t numSamples, + q63_t * realResult, + q63_t * imagResult); + + + /** + * @brief Floating-point complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t numSamples, + float32_t * realResult, + float32_t * imagResult); + + + /** + * @brief Q15 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q15( + q15_t * pSrcCmplx, + q15_t * pSrcReal, + q15_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q31( + q31_t * pSrcCmplx, + q31_t * pSrcReal, + q31_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_f32( + float32_t * pSrcCmplx, + float32_t * pSrcReal, + float32_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Minimum value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] result is output pointer + * @param[in] index is the array index of the minimum value in the input buffer. + */ + void arm_min_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * result, + uint32_t * index); + + + /** + * @brief Minimum value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[in] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q7 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q15 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q31 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a floating-point vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Q15 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Converts the elements of the floating-point vector to Q31 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q31 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q31( + float32_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q15 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q15( + float32_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q7 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q7 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q7( + float32_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q15 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q15( + q31_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q7( + q31_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_float( + q15_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q31 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q31( + q15_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q7( + q15_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup BilinearInterpolate Bilinear Interpolation + * + * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. + * The underlying function f(x, y) is sampled on a regular grid and the interpolation process + * determines values between the grid points. + * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. + * Bilinear interpolation is often used in image processing to rescale images. + * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. + * + * Algorithm + * \par + * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. + * For floating-point, the instance structure is defined as: + *
+   *   typedef struct
+   *   {
+   *     uint16_t numRows;
+   *     uint16_t numCols;
+   *     float32_t *pData;
+   * } arm_bilinear_interp_instance_f32;
+   * 
+ * + * \par + * where numRows specifies the number of rows in the table; + * numCols specifies the number of columns in the table; + * and pData points to an array of size numRows*numCols values. + * The data table pTable is organized in row order and the supplied data values fall on integer indexes. + * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers. + * + * \par + * Let (x, y) specify the desired interpolation point. Then define: + *
+   *     XF = floor(x)
+   *     YF = floor(y)
+   * 
+ * \par + * The interpolated output point is computed as: + *
+   *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
+   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
+   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
+   * 
+ * Note that the coordinates (x, y) contain integer and fractional components. + * The integer components specify which portion of the table to use while the + * fractional components control the interpolation processor. + * + * \par + * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. + */ + + /** + * @addtogroup BilinearInterpolate + * @{ + */ + + + /** + * + * @brief Floating-point bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate. + * @param[in] Y interpolation coordinate. + * @return out interpolated value. + */ + static __INLINE float32_t arm_bilinear_interp_f32( + const arm_bilinear_interp_instance_f32 * S, + float32_t X, + float32_t Y) + { + float32_t out; + float32_t f00, f01, f10, f11; + float32_t *pData = S->pData; + int32_t xIndex, yIndex, index; + float32_t xdiff, ydiff; + float32_t b1, b2, b3, b4; + + xIndex = (int32_t) X; + yIndex = (int32_t) Y; + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 || yIndex > (S->numCols - 1)) + { + return (0); + } + + /* Calculation of index for two nearest points in X-direction */ + index = (xIndex - 1) + (yIndex - 1) * S->numCols; + + + /* Read two nearest points in X-direction */ + f00 = pData[index]; + f01 = pData[index + 1]; + + /* Calculation of index for two nearest points in Y-direction */ + index = (xIndex - 1) + (yIndex) * S->numCols; + + + /* Read two nearest points in Y-direction */ + f10 = pData[index]; + f11 = pData[index + 1]; + + /* Calculation of intermediate values */ + b1 = f00; + b2 = f01 - f00; + b3 = f10 - f00; + b4 = f00 - f01 - f10 + f11; + + /* Calculation of fractional part in X */ + xdiff = X - xIndex; + + /* Calculation of fractional part in Y */ + ydiff = Y - yIndex; + + /* Calculation of bi-linear interpolated output */ + out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; + + /* return to application */ + return (out); + } + + + /** + * + * @brief Q31 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + static __INLINE q31_t arm_bilinear_interp_q31( + arm_bilinear_interp_instance_q31 * S, + q31_t X, + q31_t Y) + { + q31_t out; /* Temporary output */ + q31_t acc = 0; /* output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q31_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q31_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* shift left xfract by 11 to keep 1.31 format */ + xfract = (X & 0x000FFFFF) << 11u; + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + (int32_t)nCols * (cI) ]; + x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1]; + + /* 20 bits for the fractional part */ + /* shift left yfract by 11 to keep 1.31 format */ + yfract = (Y & 0x000FFFFF) << 11u; + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + (int32_t)nCols * (cI + 1) ]; + y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ + out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); + acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); + + /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); + + /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* Convert acc to 1.31(q31) format */ + return ((q31_t)(acc << 2)); + } + + + /** + * @brief Q15 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + static __INLINE q15_t arm_bilinear_interp_q15( + arm_bilinear_interp_instance_q15 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q15_t x1, x2, y1, y2; /* Nearest output values */ + q31_t xfract, yfract; /* X, Y fractional parts */ + int32_t rI, cI; /* Row and column indices */ + q15_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ + + /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ + /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ + out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u); + acc = ((q63_t) out * (0xFFFFF - yfract)); + + /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u); + acc += ((q63_t) out * (xfract)); + + /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u); + acc += ((q63_t) out * (yfract)); + + /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u); + acc += ((q63_t) out * (yfract)); + + /* acc is in 13.51 format and down shift acc by 36 times */ + /* Convert out to 1.15 format */ + return ((q15_t)(acc >> 36)); + } + + + /** + * @brief Q7 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + static __INLINE q7_t arm_bilinear_interp_q7( + arm_bilinear_interp_instance_q7 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q7_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q7_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ + out = ((x1 * (0xFFFFF - xfract))); + acc = (((q63_t) out * (0xFFFFF - yfract))); + + /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ + out = ((x2 * (0xFFFFF - yfract))); + acc += (((q63_t) out * (xfract))); + + /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y1 * (0xFFFFF - xfract))); + acc += (((q63_t) out * (yfract))); + + /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y2 * (yfract))); + acc += (((q63_t) out * (xfract))); + + /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ + return ((q7_t)(acc >> 40)); + } + + /** + * @} end of BilinearInterpolate group + */ + + +/* SMMLAR */ +#define multAcc_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMLSR */ +#define multSub_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMULR */ +#define mult_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32) + +/* SMMLA */ +#define multAcc_32x32_keep32(a, x, y) \ + a += (q31_t) (((q63_t) x * y) >> 32) + +/* SMMLS */ +#define multSub_32x32_keep32(a, x, y) \ + a -= (q31_t) (((q63_t) x * y) >> 32) + +/* SMMUL */ +#define mult_32x32_keep32(a, x, y) \ + a = (q31_t) (((q63_t) x * y ) >> 32) + + +#if defined ( __CC_ARM ) + /* Enter low optimization region - place directly above function definition */ + #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("push") \ + _Pragma ("O1") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) + #define LOW_OPTIMIZATION_EXIT \ + _Pragma ("pop") + #else + #define LOW_OPTIMIZATION_EXIT + #endif + + /* Enter low optimization region - place directly above function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__GNUC__) + #define LOW_OPTIMIZATION_ENTER __attribute__(( optimize("-O1") )) + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__ICCARM__) + /* Enter low optimization region - place directly above function definition */ + #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define LOW_OPTIMIZATION_EXIT + + /* Enter low optimization region - place directly above function definition */ + #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__CSMC__) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__TASKING__) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#endif + + +#ifdef __cplusplus +} +#endif + + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic pop +#endif + +#endif /* _ARM_MATH_H */ + +/** + * + * End of file. + */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_armcc.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_armcc.h new file mode 100644 index 0000000..4d9d064 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_armcc.h @@ -0,0 +1,865 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use Arm Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \ + (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) ) + #define __ARM_ARCH_6M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1)) + #define __ARM_ARCH_7M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) + #define __ARM_ARCH_7EM__ 1 +#endif + + /* __ARM_ARCH_8M_BASE__ not applicable */ + /* __ARM_ARCH_8M_MAIN__ not applicable */ + + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE static __forceinline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT __packed struct +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION __packed union +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); */ + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xFFU); +} + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 0xFFU); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1U); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() do {\ + __schedule_barrier();\ + __isb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() do {\ + __schedule_barrier();\ + __dsb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() do {\ + __schedule_barrier();\ + __dmb(0xF);\ + __schedule_barrier();\ + } while (0U) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + return result; +} +#endif + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32U) ) >> 32U)) + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_H */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_armclang.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_armclang.h new file mode 100644 index 0000000..162a400 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_armclang.h @@ -0,0 +1,1869 @@ +/**************************************************************************//** + * @file cmsis_armclang.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +#ifndef __ARM_COMPAT_H +#include /* Compatibility header for Arm Compiler 5 intrinsics */ +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); see arm_compat.h */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); see arm_compat.h */ + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq /* see arm_compat.h */ + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq /* see arm_compat.h */ + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF); + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF); + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF); + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ (uint8_t)__builtin_clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#if 0 +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_compiler.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_compiler.h new file mode 100644 index 0000000..617fab3 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_compiler.h @@ -0,0 +1,266 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include "cmsis_iccarm.h" + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed)) + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_gcc.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_gcc.h new file mode 100644 index 0000000..0a745fb --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_gcc.h @@ -0,0 +1,2085 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.0.4 + * @date 09. April 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_GCC_H +#define __CMSIS_GCC_H +/* polyspace-begin MISRA2012:* */ +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) :: "memory"); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) :: "memory"); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#endif +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI() __ASM volatile ("wfi") + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE() __ASM volatile ("wfe") + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV() __ASM volatile ("sev") + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return result; +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ (uint8_t)__builtin_clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ + __extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#if 0 +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop +/* polyspace-end MISRA2012:* */ +#endif /* __CMSIS_GCC_H */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_iccarm.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_iccarm.h new file mode 100644 index 0000000..11c4af0 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_iccarm.h @@ -0,0 +1,935 @@ +/**************************************************************************//** + * @file cmsis_iccarm.h + * @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file + * @version V5.0.7 + * @date 19. June 2018 + ******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017-2018 IAR Systems +// +// Licensed under the Apache License, Version 2.0 (the "License") +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//------------------------------------------------------------------------------ + + +#ifndef __CMSIS_ICCARM_H__ +#define __CMSIS_ICCARM_H__ + +#ifndef __ICCARM__ + #error This file should only be compiled by ICCARM +#endif + +#pragma system_include + +#define __IAR_FT _Pragma("inline=forced") __intrinsic + +#if (__VER__ >= 8000000) + #define __ICCARM_V8 1 +#else + #define __ICCARM_V8 0 +#endif + +#ifndef __ALIGNED + #if __ICCARM_V8 + #define __ALIGNED(x) __attribute__((aligned(x))) + #elif (__VER__ >= 7080000) + /* Needs IAR language extensions */ + #define __ALIGNED(x) __attribute__((aligned(x))) + #else + #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. + #define __ALIGNED(x) + #endif +#endif + + +/* Define compiler macros for CPU architecture, used in CMSIS 5. + */ +#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__ +/* Macros already defined */ +#else + #if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M' + #if __ARM_ARCH == 6 + #define __ARM_ARCH_6M__ 1 + #elif __ARM_ARCH == 7 + #if __ARM_FEATURE_DSP + #define __ARM_ARCH_7EM__ 1 + #else + #define __ARM_ARCH_7M__ 1 + #endif + #endif /* __ARM_ARCH */ + #endif /* __ARM_ARCH_PROFILE == 'M' */ +#endif + +/* Alternativ core deduction for older ICCARM's */ +#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \ + !defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__) + #if defined(__ARM6M__) && (__CORE__ == __ARM6M__) + #define __ARM_ARCH_6M__ 1 + #elif defined(__ARM7M__) && (__CORE__ == __ARM7M__) + #define __ARM_ARCH_7M__ 1 + #elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__) + #define __ARM_ARCH_7EM__ 1 + #elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #else + #error "Unknown target." + #endif +#endif + + + +#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1 + #define __IAR_M0_FAMILY 1 +#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1 + #define __IAR_M0_FAMILY 1 +#else + #define __IAR_M0_FAMILY 0 +#endif + + +#ifndef __ASM + #define __ASM __asm +#endif + +#ifndef __INLINE + #define __INLINE inline +#endif + +#ifndef __NO_RETURN + #if __ICCARM_V8 + #define __NO_RETURN __attribute__((__noreturn__)) + #else + #define __NO_RETURN _Pragma("object_attribute=__noreturn") + #endif +#endif + +#ifndef __PACKED + #if __ICCARM_V8 + #define __PACKED __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED __packed + #endif +#endif + +#ifndef __PACKED_STRUCT + #if __ICCARM_V8 + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_STRUCT __packed struct + #endif +#endif + +#ifndef __PACKED_UNION + #if __ICCARM_V8 + #define __PACKED_UNION union __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_UNION __packed union + #endif +#endif + +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +#ifndef __FORCEINLINE + #define __FORCEINLINE _Pragma("inline=forced") +#endif + +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE +#endif + +#ifndef __UNALIGNED_UINT16_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint16_t __iar_uint16_read(void const *ptr) +{ + return *(__packed uint16_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) +#endif + + +#ifndef __UNALIGNED_UINT16_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) +{ + *(__packed uint16_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint32_t __iar_uint32_read(void const *ptr) +{ + return *(__packed uint32_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) +{ + *(__packed uint32_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32 /* deprecated */ +#pragma language=save +#pragma language=extended +__packed struct __iar_u32 { uint32_t v; }; +#pragma language=restore +#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) +#endif + +#ifndef __USED + #if __ICCARM_V8 + #define __USED __attribute__((used)) + #else + #define __USED _Pragma("__root") + #endif +#endif + +#ifndef __WEAK + #if __ICCARM_V8 + #define __WEAK __attribute__((weak)) + #else + #define __WEAK _Pragma("__weak") + #endif +#endif + + +#ifndef __ICCARM_INTRINSICS_VERSION__ + #define __ICCARM_INTRINSICS_VERSION__ 0 +#endif + +#if __ICCARM_INTRINSICS_VERSION__ == 2 + + #if defined(__CLZ) + #undef __CLZ + #endif + #if defined(__REVSH) + #undef __REVSH + #endif + #if defined(__RBIT) + #undef __RBIT + #endif + #if defined(__SSAT) + #undef __SSAT + #endif + #if defined(__USAT) + #undef __USAT + #endif + + #include "iccarm_builtin.h" + + #define __disable_fault_irq __iar_builtin_disable_fiq + #define __disable_irq __iar_builtin_disable_interrupt + #define __enable_fault_irq __iar_builtin_enable_fiq + #define __enable_irq __iar_builtin_enable_interrupt + #define __arm_rsr __iar_builtin_rsr + #define __arm_wsr __iar_builtin_wsr + + + #define __get_APSR() (__arm_rsr("APSR")) + #define __get_BASEPRI() (__arm_rsr("BASEPRI")) + #define __get_CONTROL() (__arm_rsr("CONTROL")) + #define __get_FAULTMASK() (__arm_rsr("FAULTMASK")) + + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #define __get_FPSCR() (__arm_rsr("FPSCR")) + #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE))) + #else + #define __get_FPSCR() ( 0 ) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #define __get_IPSR() (__arm_rsr("IPSR")) + #define __get_MSP() (__arm_rsr("MSP")) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __get_MSPLIM() (0U) + #else + #define __get_MSPLIM() (__arm_rsr("MSPLIM")) + #endif + #define __get_PRIMASK() (__arm_rsr("PRIMASK")) + #define __get_PSP() (__arm_rsr("PSP")) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __get_PSPLIM() (0U) + #else + #define __get_PSPLIM() (__arm_rsr("PSPLIM")) + #endif + + #define __get_xPSR() (__arm_rsr("xPSR")) + + #define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE))) + #define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE))) + #define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE))) + #define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE))) + #define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __set_MSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE))) + #endif + #define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE))) + #define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE))) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __set_PSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE))) + #endif + + #define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS")) + #define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE))) + #define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS")) + #define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE))) + #define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS")) + #define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE))) + #define __TZ_get_SP_NS() (__arm_rsr("SP_NS")) + #define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE))) + #define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS")) + #define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE))) + #define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS")) + #define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE))) + #define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS")) + #define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __TZ_get_PSPLIM_NS() (0U) + #define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE)) + #else + #define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS")) + #define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE))) + #endif + + #define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS")) + #define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE))) + + #define __NOP __iar_builtin_no_operation + + #define __CLZ __iar_builtin_CLZ + #define __CLREX __iar_builtin_CLREX + + #define __DMB __iar_builtin_DMB + #define __DSB __iar_builtin_DSB + #define __ISB __iar_builtin_ISB + + #define __LDREXB __iar_builtin_LDREXB + #define __LDREXH __iar_builtin_LDREXH + #define __LDREXW __iar_builtin_LDREX + + #define __RBIT __iar_builtin_RBIT + #define __REV __iar_builtin_REV + #define __REV16 __iar_builtin_REV16 + + __IAR_FT int16_t __REVSH(int16_t val) + { + return (int16_t) __iar_builtin_REVSH(val); + } + + #define __ROR __iar_builtin_ROR + #define __RRX __iar_builtin_RRX + + #define __SEV __iar_builtin_SEV + + #if !__IAR_M0_FAMILY + #define __SSAT __iar_builtin_SSAT + #endif + + #define __STREXB __iar_builtin_STREXB + #define __STREXH __iar_builtin_STREXH + #define __STREXW __iar_builtin_STREX + + #if !__IAR_M0_FAMILY + #define __USAT __iar_builtin_USAT + #endif + + #define __WFE __iar_builtin_WFE + #define __WFI __iar_builtin_WFI + + #if __ARM_MEDIA__ + #define __SADD8 __iar_builtin_SADD8 + #define __QADD8 __iar_builtin_QADD8 + #define __SHADD8 __iar_builtin_SHADD8 + #define __UADD8 __iar_builtin_UADD8 + #define __UQADD8 __iar_builtin_UQADD8 + #define __UHADD8 __iar_builtin_UHADD8 + #define __SSUB8 __iar_builtin_SSUB8 + #define __QSUB8 __iar_builtin_QSUB8 + #define __SHSUB8 __iar_builtin_SHSUB8 + #define __USUB8 __iar_builtin_USUB8 + #define __UQSUB8 __iar_builtin_UQSUB8 + #define __UHSUB8 __iar_builtin_UHSUB8 + #define __SADD16 __iar_builtin_SADD16 + #define __QADD16 __iar_builtin_QADD16 + #define __SHADD16 __iar_builtin_SHADD16 + #define __UADD16 __iar_builtin_UADD16 + #define __UQADD16 __iar_builtin_UQADD16 + #define __UHADD16 __iar_builtin_UHADD16 + #define __SSUB16 __iar_builtin_SSUB16 + #define __QSUB16 __iar_builtin_QSUB16 + #define __SHSUB16 __iar_builtin_SHSUB16 + #define __USUB16 __iar_builtin_USUB16 + #define __UQSUB16 __iar_builtin_UQSUB16 + #define __UHSUB16 __iar_builtin_UHSUB16 + #define __SASX __iar_builtin_SASX + #define __QASX __iar_builtin_QASX + #define __SHASX __iar_builtin_SHASX + #define __UASX __iar_builtin_UASX + #define __UQASX __iar_builtin_UQASX + #define __UHASX __iar_builtin_UHASX + #define __SSAX __iar_builtin_SSAX + #define __QSAX __iar_builtin_QSAX + #define __SHSAX __iar_builtin_SHSAX + #define __USAX __iar_builtin_USAX + #define __UQSAX __iar_builtin_UQSAX + #define __UHSAX __iar_builtin_UHSAX + #define __USAD8 __iar_builtin_USAD8 + #define __USADA8 __iar_builtin_USADA8 + #define __SSAT16 __iar_builtin_SSAT16 + #define __USAT16 __iar_builtin_USAT16 + #define __UXTB16 __iar_builtin_UXTB16 + #define __UXTAB16 __iar_builtin_UXTAB16 + #define __SXTB16 __iar_builtin_SXTB16 + #define __SXTAB16 __iar_builtin_SXTAB16 + #define __SMUAD __iar_builtin_SMUAD + #define __SMUADX __iar_builtin_SMUADX + #define __SMMLA __iar_builtin_SMMLA + #define __SMLAD __iar_builtin_SMLAD + #define __SMLADX __iar_builtin_SMLADX + #define __SMLALD __iar_builtin_SMLALD + #define __SMLALDX __iar_builtin_SMLALDX + #define __SMUSD __iar_builtin_SMUSD + #define __SMUSDX __iar_builtin_SMUSDX + #define __SMLSD __iar_builtin_SMLSD + #define __SMLSDX __iar_builtin_SMLSDX + #define __SMLSLD __iar_builtin_SMLSLD + #define __SMLSLDX __iar_builtin_SMLSLDX + #define __SEL __iar_builtin_SEL + #define __QADD __iar_builtin_QADD + #define __QSUB __iar_builtin_QSUB + #define __PKHBT __iar_builtin_PKHBT + #define __PKHTB __iar_builtin_PKHTB + #endif + +#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #define __CLZ __cmsis_iar_clz_not_active + #define __SSAT __cmsis_iar_ssat_not_active + #define __USAT __cmsis_iar_usat_not_active + #define __RBIT __cmsis_iar_rbit_not_active + #define __get_APSR __cmsis_iar_get_APSR_not_active + #endif + + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #define __get_FPSCR __cmsis_iar_get_FPSR_not_active + #define __set_FPSCR __cmsis_iar_set_FPSR_not_active + #endif + + #ifdef __INTRINSICS_INCLUDED + #error intrinsics.h is already included previously! + #endif + + #include + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #undef __CLZ + #undef __SSAT + #undef __USAT + #undef __RBIT + #undef __get_APSR + + __STATIC_INLINE uint8_t __CLZ(uint32_t data) + { + if (data == 0U) { return 32U; } + + uint32_t count = 0U; + uint32_t mask = 0x80000000U; + + while ((data & mask) == 0U) + { + count += 1U; + mask = mask >> 1U; + } + return count; + } + + __STATIC_INLINE uint32_t __RBIT(uint32_t v) + { + uint8_t sc = 31U; + uint32_t r = v; + for (v >>= 1U; v; v >>= 1U) + { + r <<= 1U; + r |= v & 1U; + sc--; + } + return (r << sc); + } + + __STATIC_INLINE uint32_t __get_APSR(void) + { + uint32_t res; + __asm("MRS %0,APSR" : "=r" (res)); + return res; + } + + #endif + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #undef __get_FPSCR + #undef __set_FPSCR + #define __get_FPSCR() (0) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #pragma diag_suppress=Pe940 + #pragma diag_suppress=Pe177 + + #define __enable_irq __enable_interrupt + #define __disable_irq __disable_interrupt + #define __NOP __no_operation + + #define __get_xPSR __get_PSR + + #if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0) + + __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) + { + return __LDREX((unsigned long *)ptr); + } + + __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) + { + return __STREX(value, (unsigned long *)ptr); + } + #endif + + + /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + #if (__CORTEX_M >= 0x03) + + __IAR_FT uint32_t __RRX(uint32_t value) + { + uint32_t result; + __ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc"); + return(result); + } + + __IAR_FT void __set_BASEPRI_MAX(uint32_t value) + { + __asm volatile("MSR BASEPRI_MAX,%0"::"r" (value)); + } + + + #define __enable_fault_irq __enable_fiq + #define __disable_fault_irq __disable_fiq + + + #endif /* (__CORTEX_M >= 0x03) */ + + __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) + { + return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); + } + + #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + __IAR_FT uint32_t __get_MSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,MSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_MSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR MSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __get_PSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_PSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_CONTROL_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,CONTROL_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_CONTROL_NS(uint32_t value) + { + __asm volatile("MSR CONTROL_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PSP_NS(uint32_t value) + { + __asm volatile("MSR PSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_MSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSP_NS(uint32_t value) + { + __asm volatile("MSR MSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_SP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,SP_NS" : "=r" (res)); + return res; + } + __IAR_FT void __TZ_set_SP_NS(uint32_t value) + { + __asm volatile("MSR SP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PRIMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PRIMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value) + { + __asm volatile("MSR PRIMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_BASEPRI_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,BASEPRI_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value) + { + __asm volatile("MSR BASEPRI_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value) + { + __asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSPLIM_NS(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM_NS" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM_NS,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_MSPLIM_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSPLIM_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value) + { + __asm volatile("MSR MSPLIM_NS,%0" :: "r" (value)); + } + + #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + +#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) + +#if __IAR_M0_FAMILY + __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) + { + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; + } + + __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) + { + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; + } +#endif + +#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + + __IAR_FT uint8_t __LDRBT(volatile uint8_t *addr) + { + uint32_t res; + __ASM("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDRHT(volatile uint16_t *addr) + { + uint32_t res; + __ASM("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDRT(volatile uint32_t *addr) + { + uint32_t res; + __ASM("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return res; + } + + __IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr) + { + __ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr) + { + __ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr) + { + __ASM("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory"); + } + +#endif /* (__CORTEX_M >= 0x03) */ + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + + __IAR_FT uint8_t __LDAB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDA(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr) + { + __ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr) + { + __ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr) + { + __ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + +#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#undef __IAR_FT +#undef __IAR_M0_FAMILY +#undef __ICCARM_V8 + +#pragma diag_default=Pe940 +#pragma diag_default=Pe177 + +#endif /* __CMSIS_ICCARM_H__ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_version.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_version.h new file mode 100644 index 0000000..660f612 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/cmsis_version.h @@ -0,0 +1,39 @@ +/**************************************************************************//** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.2 + * @date 19. April 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_VERSION_H +#define __CMSIS_VERSION_H + +/* CMSIS Version definitions */ +#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ +#define __CM_CMSIS_VERSION_SUB ( 1U) /*!< [15:0] CMSIS Core(M) sub version */ +#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ + __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ +#endif diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/core_cm0plus.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/core_cm0plus.h new file mode 100644 index 0000000..47032b2 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/core_cm0plus.h @@ -0,0 +1,1083 @@ +/**************************************************************************//** + * @file core_cm0plus.h + * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File + * @version V5.0.6 + * @date 28. May 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0PLUS_H_GENERIC +#define __CORE_CM0PLUS_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ +/* polyspace-begin DEFECT:* MISRA2012:* */ + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex-M0+ + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM0+ definitions */ +#define __CM0PLUS_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0PLUS_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \ + __CM0PLUS_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (0U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0PLUS_H_DEPENDANT +#define __CORE_CM0PLUS_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0PLUS_REV + #define __CM0PLUS_REV 0x0000U + #warning "__CM0PLUS_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex-M0+ */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0+ header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0+ */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; + +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + +/* polyspace-end DEFECT:* MISRA2012:* */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/mpu_armv7.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/mpu_armv7.h new file mode 100644 index 0000000..0142203 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cmsis/mpu_armv7.h @@ -0,0 +1,270 @@ +/****************************************************************************** + * @file mpu_armv7.h + * @brief CMSIS MPU API for Armv7-M MPU + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV7_H +#define ARM_MPU_ARMV7_H + +#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes +#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes +#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes +#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes +#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes +#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte +#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes +#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes +#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes +#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes +#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes +#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes +#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes +#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes +#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes +#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte +#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes +#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes +#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes +#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes +#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes +#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes +#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes +#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes +#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes +#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte +#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes +#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes + +#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access +#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only +#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only +#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access +#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only +#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access + +/** MPU Region Base Address Register Value +* +* \param Region The region to be configured, number 0 to 15. +* \param BaseAddress The base address for the region. +*/ +#define ARM_MPU_RBAR(Region, BaseAddress) \ + (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ + ((Region) & MPU_RBAR_REGION_Msk) | \ + (MPU_RBAR_VALID_Msk)) + +/** +* MPU Memory Access Attributes +* +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +*/ +#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ + ((((TypeExtField ) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ + (((IsShareable ) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ + (((IsCacheable ) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ + (((IsBufferable ) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ + ((((DisableExec ) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ + (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ + (((AccessAttributes) ) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ + ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) + +/** +* MPU Memory Access Attribute for strongly ordered memory. +* - TEX: 000b +* - Shareable +* - Non-cacheable +* - Non-bufferable +*/ +#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) + +/** +* MPU Memory Access Attribute for device memory. +* - TEX: 000b (if non-shareable) or 010b (if shareable) +* - Shareable or non-shareable +* - Non-cacheable +* - Bufferable (if shareable) or non-bufferable (if non-shareable) +* +* \param IsShareable Configures the device memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) + +/** +* MPU Memory Access Attribute for normal memory. +* - TEX: 1BBb (reflecting outer cacheability rules) +* - Shareable or non-shareable +* - Cacheable or non-cacheable (reflecting inner cacheability rules) +* - Bufferable or non-bufferable (reflecting inner cacheability rules) +* +* \param OuterCp Configures the outer cache policy. +* \param InnerCp Configures the inner cache policy. +* \param IsShareable Configures the memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) & 2U), ((InnerCp) & 1U)) + +/** +* MPU Memory Access Attribute non-cacheable policy. +*/ +#define ARM_MPU_CACHEP_NOCACHE 0U + +/** +* MPU Memory Access Attribute write-back, write and read allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_WRA 1U + +/** +* MPU Memory Access Attribute write-through, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WT_NWA 2U + +/** +* MPU Memory Access Attribute write-back, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_NWA 3U + + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; //!< The region base address register value (RBAR) + uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DSB(); + __ISB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DSB(); + __ISB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + MPU->RNR = rnr; + MPU->RASR = 0U; +} + +/** Configure an MPU region. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) +{ + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) +{ + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + while (cnt > MPU_TYPE_RALIASES) { + orderedCpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); + table += MPU_TYPE_RALIASES; + cnt -= MPU_TYPE_RALIASES; + } + orderedCpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); +} + +#endif diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cpu_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cpu_drv.h new file mode 100644 index 0000000..1128406 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cpu_drv.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CPU_DRV_H_ +#define _CPU_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the CPU + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "cva/CVM011x.h" +#include "irq/irq_drv.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************************* + * the defines + ******************************************************************************/ + + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + + +/******************************************************************************* + * the globals + ******************************************************************************/ + + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Enter supervisor mode + * + * This function convert CPU into supervisor mode. + * + */ +static inline void CpuDrv_EnterSupervisorMode(void) +{ + /* if CPU in user mode */ + if ((__get_CONTROL() & 0x1) == 1) + { + /* change to privilege mode */ + __asm("svc #0x32"); + } +} + +/*! \brief Change to supervisor mode + * + * This function change the CPU into supervisor mode. + * + */ +static inline void CpuDrv_ChangeToSupervisorMode(void) +{ + __asm(" MOVS R0, #0x0 "); + __asm(" MSR CONTROL, R0 "); + __asm("DSB"); + __asm("ISB"); +} + +/*! \brief Enter user mode + * + * This function change the CPU into user mode. + * + */ +static inline void CpuDrv_EnterUserMode(void) +{ + __asm(" MOVS R0, #0x1 "); + __asm(" MSR CONTROL, R0 "); + __asm("DSB"); + __asm("ISB"); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + + +#endif /* _CPU_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cva/CVM011x.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cva/CVM011x.h new file mode 100644 index 0000000..0ee19f4 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/cva/CVM011x.h @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CVM011X_H_ +#define _CVM011X_H_ + +/*! \brief Contains public interface to various functions related + * to all the registers of CVM011x series chips + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the Interrupt Number Definition + ******************************************************************************/ + +typedef enum +{ + /* Core interrupts */ + NonMaskableInt_IRQn = -14, /**< Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< Cortex-M0 SV Hard Fault Interrupt */ + SVCall_IRQn = -5, /**< Cortex-M0 SV Call Interrupt */ + PendSV_IRQn = -2, /**< Cortex-M0 Pend SV Interrupt */ + SysTick_IRQn = -1, /**< Cortex-M0 System Tick Interrupt */ + + /* CVM011x specific interrupts */ + DMA01_IRQn = 0u, /**< DMA channel 0,1 transfer complete */ + DMA23_IRQn = 1u, /**< DMA channel 2,3 transfer complete */ + DMA_Error_IRQn = 2u, /**< DMA error interrupt channels 0-3 */ + FHU_IRQn = 3u, /**< FHU Interrupt, ERM single bit error correction */ + RTC_Alarm_IRQn = 4u, /**< RTC alarm interrupt */ + RTC_Seconds_IRQn = 5u, /**< RTC seconds interrupt */ + LPTMR_IRQn = 6u, /**< LPTIMER interrupt request */ + PORT_IRQn = 7u, /**< Port ABCDE pin detect interrupt */ + CAN_ORed_IRQn = 8u, /**< CAN OR'ed [BusOff\BusOffDone\TransWarning\ReceiveWarning\..... ] */ + CAN_ORed_0_31_MB_IRQn = 9u, /**< CAN OR'ed Message buffer (0-31) */ + CAN_ORed_32_63_MB_IRQn = 10u, /**< CAN OR'ed Message buffer (32-63) */ + MFT0_Ch0_Ch7_IRQn = 11u, /**< MFT0 Channel 0 to 7 interrupt */ + MFT0_Fault_IRQn = 12u, /**< MFT0 Fault interrupt */ + MFT0_Ovf_Reload_IRQn = 13u, /**< MFT0 Counter overflow and Reload interrupt */ + MFT1_Ch0_Ch7_IRQn = 14u, /**< MFT1 Channel 0 to 7 interrupt */ + MFT1_Fault_IRQn = 15u, /**< MFT1 Fault interrupt */ + MFT1_Ovf_Reload_IRQn = 16u, /**< MFT1 Counter overflow and Reload interrupt */ + FTFC_IRQn = 17u, /**< FTFC Command done,read collision,err response interrupt */ + PDB_IRQn = 18u, /**< PDB interrupt */ + LPIT_IRQn = 19u, /**< LPIT interrupt */ + CMU_IRQn = 20u, /**< CMU PLL,SOSC interrupt */ + WDOG_IRQn = 21u, /**< Interrupt request out before wdg reset out */ + RCM_IRQn = 22u, /**< RCM Asynchronous Interrupt, Reset interrutpt */ + I2C_IRQn = 23u, /**< I2C Interrupt */ + SPI0_IRQn = 24u, /**< SPI0 Interrupt */ + SPI1_IRQn = 25u, /**< SPI1 Interrupt */ + ADC_IRQn = 26u, /**< ADC interrupt request. */ + CMP_IRQn = 27u, /**< CMP interrupt request */ + I2S_SLV_MST_IRQn = 28u, /**< I2S Slave and Master interrupt */ + UART0_RxTx_IRQn = 29u, /**< UART0 Transmit / Receive Interrupt */ + UART1_RxTx_IRQn = 30u, /**< UART1 Transmit / Receive Interrupt */ + UART2_RxTx_IRQn = 31u, /**< UART2 Transmit / Receive Interrupt */ +} IRQn_Type; + +/******************************************************************************* + * the Processor and Core Peripheral Section + ******************************************************************************/ + +#define __NVIC_PRIO_BITS 2 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +/* ToDo: define __FPU_PRESENT if your devise is a CORTEX-M4 */ +#define __FPU_PRESENT 0 /*!< FPU present or not */ + +#define __VTOR_PRESENT 1 + +#include "../cmsis/core_cm0plus.h" + +/******************************************************************************* + * the Device Specific Peripheral registers structures + ******************************************************************************/ + +#include "mscm_reg.h" +#include "cmu_reg.h" +#include "fhu_reg.h" +#include "edma_reg.h" +#include "crc_reg.h" +#include "mpu_reg.h" +#include "erm_reg.h" +#include "eim_reg.h" +#include "ftfc_reg.h" +#include "dmamux_reg.h" +#include "axbs_reg.h" +#include "adc_reg.h" +#include "pdb_reg.h" +#include "spi_reg.h" +#include "mft_reg.h" +#include "gpio_reg.h" +#include "flexcan_reg.h" +#include "pwmlite_reg.h" +#include "trgmux_reg.h" +#include "sim_reg.h" +#include "port_reg.h" +#include "i2c_reg.h" +#include "uart_reg.h" +#include "scg0_reg.h" +#include "scg1_reg.h" +#include "scg2_reg.h" +#include "pcc0_reg.h" +#include "pcc1_reg.h" +#include "i2sm_reg.h" +#include "i2ss_reg.h" +#include "cmp_reg.h" +#include "lptmr_reg.h" +#include "lpit_reg.h" +#include "rtc_reg.h" +#include "wdg_reg.h" +#include "pmc_reg.h" +#include "rcm_reg.h" + +/******************************************************************************* + * the Peripheral memory map + ******************************************************************************/ + +/* MSCM module */ +#define MSCM_BASE (0x40001000u) +#define MSCM ((MscmRegType *)MSCM_BASE) + +/* CMU module */ +#define CMU_PLL_BASE (0x40003000u) +#define CMU_PLL ((CmuRegType *)CMU_PLL_BASE) +#define CMU_SOSC_BASE (0x40004000u) +#define CMU_SOSC ((CmuRegType *)CMU_SOSC_BASE) + +/* FHU module */ +#define FHU_BASE (0x40005000u) +#define FHU ((FhuRegType *)FHU_BASE) + +/* DMA module */ +#define DMA_BASE (0x40008000u) +#define DMA ((EDmaRegType *)DMA_BASE) + +/* CRC module */ +#define CRC_BASE (0x4000C000u) +#define CRC ((CrcRegType *)CRC_BASE) + +/* MPU module */ +#define MPU_BASE (0x4000D000u) +#define MPU ((MpuRegType *)MPU_BASE) + +/* ERM module */ +#define ERM_BASE (0x40018000u) +#define ERM ((ErmRegType *)ERM_BASE) + +/* EIM module */ +#define EIM_BASE (0x40019000u) +#define EIM ((EimRegType *)EIM_BASE) + +/* FTFC module */ +#define FTFC_BASE (0x40020000u) +#define FTFC ((FtfcRegType *)FTFC_BASE) + +/* DMAMUX module */ +#define DMAMUX_BASE (0x40021000u) +#define DMAMUX ((DmamuxRegType *)DMAMUX_BASE) + +/* AXBS module */ +#define AXBS_BASE (0x40022000u) +#define AXBS ((AxbsRegType *)AXBS_BASE) + +/* ADC modules */ +#define ADC_BASE (0x40024000u) +#define ADC ((AdcRegType *)ADC_BASE) + +/* PDB modules */ +#define PDB_BASE (0x40026000u) +#define PDB ((PdbRegType *)PDB_BASE) + +/* SPI modules */ +#define SPI0_BASE (0x4002C000u) +#define SPI0 ((SpiRegType *)SPI0_BASE) +#define SPI1_BASE (0x4002D000u) +#define SPI1 ((SpiRegType *)SPI1_BASE) + +/* MFT modules */ +#define MFT0_BASE (0x40030000u) +#define MFT0 ((MftRegType *)MFT0_BASE) +#define MFT1_BASE (0x40031000u) +#define MFT1 ((MftRegType *)MFT1_BASE) + +/* GPIO modules */ +#define GPIOA_BASE (0x40035000u) +#define GPIOA ((GpioRegType *)GPIOA_BASE) +#define GPIOB_BASE (0x40035040u) +#define GPIOB ((GpioRegType *)GPIOB_BASE) +#define GPIOC_BASE (0x40035080u) +#define GPIOC ((GpioRegType *)GPIOC_BASE) +#define GPIOD_BASE (0x400350C0u) +#define GPIOD ((GpioRegType *)GPIOD_BASE) +#define GPIOE_BASE (0x40035100u) +#define GPIOE ((GpioRegType *)GPIOE_BASE) + +/* CAN modules */ +#define CAN_BASE (0x40038000u) +#define CAN ((FlexCanRegType *)CAN_BASE) + +/* PWMLITE modules */ +#define PWMLITE0_BASE (0x40058000u) +#define PWMLITE0 ((PwmLiteRegType *)PWMLITE0_BASE) +#define PWMLITE1_BASE (0x40059000u) +#define PWMLITE1 ((PwmLiteRegType *)PWMLITE1_BASE) + +/* TRGMUX module */ +#define TRGMUX_BASE (0x4005E000u) +#define TRGMUX ((TrgMuxRegType *)TRGMUX_BASE) + +/* SIM module */ +#define SIM_BASE (0x4005F000u) +#define SIM ((SimRegType *)SIM_BASE) + +/* PORT modules */ +#define PORTA_BASE (0x40060000u) +#define PORTA ((PortRegType *)PORTA_BASE) +#define PORTB_BASE (0x40061000u) +#define PORTB ((PortRegType *)PORTB_BASE) +#define PORTC_BASE (0x40062000u) +#define PORTC ((PortRegType *)PORTC_BASE) +#define PORTD_BASE (0x40063000u) +#define PORTD ((PortRegType *)PORTD_BASE) +#define PORTE_BASE (0x40064000u) +#define PORTE ((PortRegType *)PORTE_BASE) + +/* I2C modules */ +#define I2C_BASE (0x40066000u) +#define I2C ((I2cRegType *)I2C_BASE) + +/* UART module */ +#define UART0_BASE (0x4006A000u) +#define UART0 ((UartRegType *)UART0_BASE) +#define UART1_BASE (0x4006B000u) +#define UART1 ((UartRegType *)UART1_BASE) +#define UART2_BASE (0x4006C000u) +#define UART2 ((UartRegType *)UART2_BASE) + +/* SCG0 module */ +#define SCG0_BASE (0x4006E000u) +#define SCG0 ((Scg0RegType *)SCG0_BASE) +/* SCG1 module */ +#define SCG1_BASE (0x4006E400u) +#define SCG1 ((Scg1RegType *)SCG1_BASE) +/* SCG2 module */ +#define SCG2_BASE (0x4006E800u) +#define SCG2 ((Scg2RegType *)SCG2_BASE) + +/* PCC0 module */ +#define PCC0_BASE (0x4006F000u) +#define PCC0 ((Pcc0RegType *)PCC0_BASE) +/* PCC1 module */ +#define PCC1_BASE (0x4006F800u) +#define PCC1 ((Pcc1RegType *)PCC1_BASE) + +/* I2SM module */ +#define I2SM_BASE (0x40072000u) +#define I2SM ((I2smRegType *)I2SM_BASE) + +/* I2SS module */ +#define I2SS_BASE (0x40073000u) +#define I2SS ((I2ssRegType *)I2SS_BASE) + +/* CMP module */ +#define CMP_BASE (0x40074000u) +#define CMP ((CmpRegType *)CMP_BASE) + +/* LPTMR module */ +#define LPTMR_BASE (0x40075000u) +#define LPTMR ((LptmrRegType *)LPTMR_BASE) + +/* LPIT module */ +#define LPIT_BASE (0x40077000u) +#define LPIT ((LpitRegType *)LPIT_BASE) + +/* RTC module */ +#define RTC_BASE (0x40078000u) +#define RTC ((RtcRegType *)RTC_BASE) + +/* WDG module */ +#define WDG_BASE (0x4007A000u) +#define WDG ((WdgRegType *)WDG_BASE) + +/* PMC module */ +#define PMC_BASE (0x4007D000u) +#define PMC ((PmcRegType *)PMC_BASE) + +/* RCM module */ +#define RCM_BASE (0x4007F000u) +#define RCM ((RcmRegType *)RCM_BASE) + +/* GPIO_IOP modules */ +#define GPIOA_IOP_BASE (0xF8000000u) +#define GPIOA_IOP ((GpioRegType *)GPIOA_IOP_BASE) +#define GPIOB_IOP_BASE (0xF8000040u) +#define GPIOB_IOP ((GpioRegType *)GPIOB_IOP_BASE) +#define GPIOC_IOP_BASE (0xF8000080u) +#define GPIOC_IOP ((GpioRegType *)GPIOC_IOP_BASE) +#define GPIOD_IOP_BASE (0xF80000C0u) +#define GPIOD_IOP ((GpioRegType *)GPIOD_IOP_BASE) +#define GPIOE_IOP_BASE (0xF8000100u) +#define GPIOE_IOP ((GpioRegType *)GPIOE_IOP_BASE) + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _CVM011X_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/irq/irq_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/irq/irq_drv.c new file mode 100644 index 0000000..3193ce7 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/irq/irq_drv.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "irq_drv.h" +#include "../cva/CVM011x.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* The last IRQn defined by this chip */ +#define LAST_IRQn (UART2_RxTx_IRQn) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/*! Those symbols are defined in the startup code */ +#if defined(__ARMCC_VERSION) +extern uint32_t __VECTOR_RAM; +extern uint32_t __VECTOR_ROM; +extern uint32_t __DATA_ROM; +extern uint32_t __RAM_START; +#else +#if defined(__ICCARM__) +extern uint32_t __RAM_START[]; +#pragma section = "__CODE_ROM" +extern uint32_t CODE_ROM_SECTION_START = (uint32_t)__section_begin("__CODE_ROM"); +#endif +extern uint32_t __VECTOR_RAM[((uint32_t)(LAST_IRQn)) + 16U + 1U]; +extern uint32_t __VECTOR_TABLE[((uint32_t)(LAST_IRQn)) + 16U + 1U]; +extern uint32_t __DATA_ROM[]; +extern uint32_t __DATA_END[]; +#endif + +/*! Counter to manage the nested callings of global disable/enable interrupt. */ +static int32_t s_interruptDisableCount = 0; + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void IrqDrv_InstallHandler(uint16_t irqNumber, IrqHandlerType newHandler, IrqHandlerType *oldHandler) +{ + const uint32_t *aVectorRam = (uint32_t *)__VECTOR_RAM; +#if defined(__ARMCC_VERSION) + const uint32_t *aVectorTable = (uint32_t *)__VECTOR_ROM; +#else + const uint32_t *aVectorTable = (uint32_t *)__VECTOR_TABLE; +#endif + + /* Check whether there is vector table in RAM */ +#if defined(__ARMCC_VERSION) + if((aVectorRam != aVectorTable) || (__DATA_ROM > __RAM_START)) /* polyspace DEFECT:USELESS_IF [No action planned:Low] "Depend on link script" */ +#elif(defined(__ICCARM__)) + if((aVectorRam != aVectorTable) || ((uint32_t)CODE_ROM_SECTION_START > (uint32_t)__RAM_START)) /* polyspace DEFECT:USELESS_IF [No action planned:Low] "Depend on link script" */ +#else + const uint32_t *aDataRom = (uint32_t *)__DATA_ROM; + const uint32_t *aDataRam = (uint32_t *)__DATA_END; + if((aVectorRam != aVectorTable) || (aDataRom == aDataRam)) /* polyspace DEFECT:USELESS_IF [No action planned:Low] "Depend on link script" */ +#endif + { + uint32_t *pVectorRam = (uint32_t *)__VECTOR_RAM; + /* Save the former handler pointer */ + if(oldHandler != (IrqHandlerType *)0) + { + *oldHandler = (IrqHandlerType)pVectorRam[((int32_t)irqNumber) + 16]; + } + /* Set handler into vector table */ + pVectorRam[((int32_t)irqNumber) + 16] = (uint32_t)newHandler; + } +} + +void IrqDrv_EnableGlobalInterrupt(void) +{ + /* Check and update */ + if(s_interruptDisableCount > 0) + { + s_interruptDisableCount--; + if(s_interruptDisableCount <= 0) + { +/* Enable the global interrupt*/ +#if defined(__GNUC__) + __asm volatile("cpsie i" + : + : + : "memory"); +#else + __asm("cpsie i"); +#endif + } + } +} + +void IrqDrv_DisableGlobalInterrupt(void) +{ +/* Disable the global interrupt */ +#if defined(__GNUC__) + __asm volatile("cpsid i" + : + : + : "memory"); +#else + __asm("cpsid i"); +#endif + /* Update counter*/ + s_interruptDisableCount++; +} + +void IrqDrv_EnableIrq(uint16_t irqNumber) +{ + NVIC_EnableIRQ((IRQn_Type)irqNumber); +} + +void IrqDrv_DisableIrq(uint16_t irqNumber) +{ + NVIC_DisableIRQ((IRQn_Type)irqNumber); +} + +void IrqDrv_SetPriority(uint16_t irqNumber, uint32_t preemptPriority, uint32_t subPriority) +{ + NVIC_SetPriority((IRQn_Type)irqNumber, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), preemptPriority, subPriority)); +} + +void IrqDrv_GetPriority(uint16_t irqNumber, uint32_t *pPreemptPriority, uint32_t *pSubPriority) +{ + NVIC_DecodePriority(NVIC_GetPriority((IRQn_Type)irqNumber), NVIC_GetPriorityGrouping(), pPreemptPriority, pSubPriority); +} + +void IrqDrv_ClearPending(uint16_t irqNumber) +{ + NVIC_ClearPendingIRQ((IRQn_Type)irqNumber); +} + +void IrqDrv_SetPending(uint16_t irqNumber) +{ + NVIC_SetPendingIRQ((IRQn_Type)irqNumber); +} + +bool IrqDrv_IsPending(uint16_t irqNumber) +{ + return NVIC_GetPendingIRQ((IRQn_Type)irqNumber) == 1; +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/irq/irq_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/irq/irq_drv.h new file mode 100644 index 0000000..152b219 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/irq/irq_drv.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _IRQ_DRV_H_ +#define _IRQ_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of interrupt requests + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup irq_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Interrupt handler type */ +typedef void (*IrqHandlerType)(void); + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Installs an interrupt handler routine for a given IRQ number. + * + * This function lets the application register/replace the interrupt + * handler for a specified IRQ number. See a chip-specific reference + * manual for details and the startup_.s file for each chip + * family to find out the default interrupt handler for each device. + * + * \note This method is applicable only if interrupt vector is copied in RAM. + * + * \param[in] irqNumber : IRQ number + * \param[in] newHandler : New interrupt handler routine address pointer + * \param[in] oldHandler : Pointer to a location to store current interrupt handler + */ +extern void IrqDrv_InstallHandler(uint16_t irqNumber, IrqHandlerType newHandler, IrqHandlerType *oldHandler); + +/*! \brief Enables system interrupt. + * + * This function enables the global interrupt by calling the core API. + * + */ +extern void IrqDrv_EnableGlobalInterrupt(void); + +/*! \brief Disable system interrupt. + * + * This function disables the global interrupt by calling the core API. + * + */ +extern void IrqDrv_DisableGlobalInterrupt(void); + +/*! \brief Enables an interrupt for a given IRQ number. + * + * This function enables the individual interrupt for a specified IRQ number. + * + * \param[in] irqNumber : IRQ number + */ +extern void IrqDrv_EnableIrq(uint16_t irqNumber); + +/*! \brief Disables an interrupt for a given IRQ number. + * + * This function disables the individual interrupt for a specified IRQ number. + * + * \param[in] irqNumber : IRQ number + */ +extern void IrqDrv_DisableIrq(uint16_t irqNumber); + +/*! \brief Set Interrupt Priority + * + * The function sets the priority of an interrupt. + * + * \param[in] irqNumber : Interrupt number + * \param[in] preemptPriority : Preemptive priority value (starting from 0). + * \param[in] subPriority : Subpriority value (starting from 0). + */ +extern void IrqDrv_SetPriority(uint16_t irqNumber, uint32_t preemptPriority, uint32_t subPriority); + +/*! \brief Get Interrupt Priority + * + * The function gets the priority of an interrupt. + * + * \param[in] irqNumber : Interrupt number. + * \param[out] pPreemptPriority : Preemptive priority value (starting from 0). + * \param[out] pSubPriority : Subpriority value (starting from 0). + */ +extern void IrqDrv_GetPriority(uint16_t irqNumber, uint32_t *pPreemptPriority, uint32_t *pSubPriority); + +/*! \brief Clear Pending Interrupt + * + * The function clears the pending bit of a peripheral interrupt + * or a directed interrupt to this CPU (if available). + * + * \param[in] irqNumber : IRQ number + */ +extern void IrqDrv_ClearPending(uint16_t irqNumber); + +/*! \brief Set Pending Interrupt + * + * The function configures the pending bit of a peripheral interrupt. + * + * \param[in] irqNumber : IRQ number + */ +extern void IrqDrv_SetPending(uint16_t irqNumber); + +/*! \brief Whether the Interrupt is Pending + * + * The function gets the pending bit of a peripheral interrupt + * or a directed interrupt to this CPU (if available). + * + * \param[in] irqNumber : IRQ number + * \return pending status + * - false : Interrupt status is not pending. + * - true : Interrupt status is pending. + */ +extern bool IrqDrv_IsPending(uint16_t irqNumber); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _IRQ_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/startup.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/startup.c new file mode 100644 index 0000000..259a5eb --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/startup.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "startup.h" +#include +#include "../cva/CVM011x.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void init_data_bss(void) +{ + uint32_t n; +/* For ARMC we are using the library method of initializing DATA, Custom Section and + * Code RAM sections so the below variables are not needed */ +#if !defined(__ARMCC_VERSION) + /* Declare pointers for various data sections. These pointers + * are initialized using values pulled in from the linker file */ + uint8_t* data_ram; + uint8_t* code_ram; + uint8_t* bss_start; + uint8_t* custom_ram; + const uint8_t *data_rom, *data_rom_end; + const uint8_t *code_rom, *code_rom_end; + const uint8_t* bss_end; + const uint8_t *custom_rom, *custom_rom_end; +#endif + /* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */ + +#if defined(__ARMCC_VERSION) + extern uint32_t __RAM_VECTOR_TABLE_SIZE; + extern uint32_t __VECTOR_ROM; + extern uint32_t __VECTOR_RAM; +#else + extern uint32_t __RAM_VECTOR_TABLE_SIZE[]; + extern uint32_t __VECTOR_TABLE[]; + extern uint32_t __VECTOR_RAM[]; +#endif + /* Get section information from linker files */ +#if defined(__ICCARM__) + /* Data */ + data_ram = __section_begin(".data"); + data_rom = __section_begin(".data_init"); + data_rom_end = __section_end(".data_init"); + +/* CODE RAM */ +#pragma section = "__CODE_ROM" +#pragma section = "__CODE_RAM" + code_ram = __section_begin("__CODE_RAM"); + code_rom = __section_begin("__CODE_ROM"); + code_rom_end = __section_end("__CODE_ROM"); + + /* BSS */ + bss_start = __section_begin(".bss"); + bss_end = __section_end(".bss"); + + custom_ram = __section_begin(".customSection"); + custom_rom = __section_begin(".customSection_init"); + custom_rom_end = __section_end(".customSection_init"); + +#elif defined(__ARMCC_VERSION) + /* VECTOR TABLE*/ + uint8_t *vector_table_size = (uint8_t *)__RAM_VECTOR_TABLE_SIZE; + uint32_t *vector_rom = (uint32_t *)__VECTOR_ROM; + uint32_t *vector_ram = (uint32_t *)__VECTOR_RAM; +#else + extern uint32_t __DATA_ROM[]; + extern uint32_t __DATA_RAM[]; + extern uint32_t __DATA_END[]; + + extern uint32_t __CODE_RAM[]; + extern uint32_t __CODE_ROM[]; + extern uint32_t __CODE_END[]; + + extern uint32_t __BSS_START[]; + extern uint32_t __BSS_END[]; + + extern uint32_t __CUSTOM_ROM[]; + extern uint32_t __CUSTOM_END[]; + + /* Data */ + data_ram = (uint8_t *)__DATA_RAM; + data_rom = (uint8_t *)__DATA_ROM; + data_rom_end = (uint8_t *)__DATA_END; + /* CODE RAM */ + code_ram = (uint8_t *)__CODE_RAM; + code_rom = (uint8_t *)__CODE_ROM; + code_rom_end = (uint8_t *)__CODE_END; + /* BSS */ + bss_start = (uint8_t *)__BSS_START; + bss_end = (uint8_t *)__BSS_END; + + /* Custom section */ + custom_ram = CUSTOMSECTION_SECTION_START; + custom_rom = (uint8_t *)__CUSTOM_ROM; + custom_rom_end = (uint8_t *)__CUSTOM_END; + +#endif + +#if !defined(__ARMCC_VERSION) + /* Copy initialized data from ROM to RAM */ + while(data_rom_end != data_rom) + { + *data_ram = *data_rom; + data_ram++; + data_rom++; + } + + /* Copy functions from ROM to RAM */ + while(code_rom_end != code_rom) + { + *code_ram = *code_rom; + code_ram++; + code_rom++; + } + + /* Clear the zero-initialized data section */ + while(bss_end != bss_start) + { + *bss_start = 0; + bss_start++; + } + + /* Copy customsection rom to ram */ + while(custom_rom_end != custom_rom) + { + *custom_ram = *custom_rom; + custom_rom++; + custom_ram++; + } +#endif +#if defined(__ARMCC_VERSION) + /* Copy the vector table from ROM to RAM */ + /* Workaround */ + if(vector_ram != vector_rom) + { + for(n = 0; n < (((uint32_t)(vector_table_size)) / sizeof(uint32_t)); n++) + { + vector_ram[n] = vector_rom[n]; + } + /* Point the VTOR to the position of vector table */ + SCB->VTOR = (uint32_t)__VECTOR_RAM; + } + else + { + /* Point the VTOR to the position of vector table */ + SCB->VTOR = (uint32_t)__VECTOR_ROM; + } +#else + /* Check if VECTOR_TABLE copy is needed */ + if(__VECTOR_RAM != __VECTOR_TABLE) /* polyspace DEFECT:DEAD_CODE [No action planned:Low] "Depend on link script" */ + { + /* Copy the vector table from ROM to RAM */ + for(n = 0; n < (((uint32_t)__RAM_VECTOR_TABLE_SIZE) / sizeof(uint32_t)); n++) + { + __VECTOR_RAM[n] = __VECTOR_TABLE[n]; + } + /* Point the VTOR to the position of vector table */ + SCB->VTOR = (uint32_t)__VECTOR_RAM; + } + else + { + /* Point the VTOR to the position of vector table */ + SCB->VTOR = (uint32_t)__VECTOR_TABLE; + } +#endif +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/startup.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/startup.h new file mode 100644 index 0000000..4d0e3c6 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/startup.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _STARTUP_H_ +#define _STARTUP_H_ + +#include + +/*! \brief Contains public interface to various functions related + * to the startup of this chip + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/*! \brief define symbols that specific start and end addres of some basic sections. + */ +#if(defined(__ICCARM__)) +#define INTERRUPTS_SECTION_START __section_begin(".intvec") +#define INTERRUPTS_SECTION_END __section_end(".intvec") +#define BSS_SECTION_START __section_begin(".bss") +#define BSS_SECTION_END __section_end(".bss") +#define DATA_SECTION_START __section_begin(".data") +#define DATA_SECTION_END __section_end(".data") +#define CUSTOMSECTION_SECTION_START __section_begin(".customSection") +#define CUSTOMSECTION_SECTION_END __section_end(".customSection") +#define CODE_RAM_SECTION_START __section_begin("__CODE_RAM") +#define CODE_RAM_SECTION_END __section_end("__CODE_RAM") +#define DATA_INIT_SECTION_START __section_begin(".data_init") +#define DATA_INIT_SECTION_END __section_end(".data_init") +#define CODE_ROM_SECTION_START __section_begin("__CODE_ROM") +#define CODE_ROM_SECTION_END __section_end("__CODE_ROM") + +#elif(defined(__ARMCC_VERSION)) +#define INTERRUPTS_SECTION_START (uint8_t *)__VECTOR_ROM_START +#define INTERRUPTS_SECTION_END (uint8_t *)__VECTOR_ROM_END +#define BSS_SECTION_START (uint8_t *)__BSS_START +#define BSS_SECTION_END (uint8_t *)__BSS_END +#define DATA_SECTION_START (uint8_t *)__DATA_RAM_START +#define DATA_SECTION_END (uint8_t *)__DATA_RAM_END +#define CUSTOMSECTION_SECTION_START (uint8_t *)__CUSTOM_SECTION_START +#define CUSTOMSECTION_SECTION_END (uint8_t *)__CUSTOM_SECTION_END +#define CODE_RAM_SECTION_START (uint8_t *)__CODE_RAM_START +#define CODE_RAM_SECTION_END (uint8_t *)__CODE_RAM_END + +extern uint32_t __VECTOR_ROM_START; +extern uint32_t __VECTOR_ROM_END; +extern uint32_t __BSS_START; +extern uint32_t __BSS_END; +extern uint32_t __DATA_RAM_START; +extern uint32_t __DATA_RAM_END; +extern uint32_t __CUSTOM_SECTION_START; +extern uint32_t __CUSTOM_SECTION_END; +extern uint32_t __CODE_RAM_START; +extern uint32_t __CODE_RAM_END; +#else +#define INTERRUPTS_SECTION_START (uint8_t *)&__interrupts_start__ +#define INTERRUPTS_SECTION_END (uint8_t *)&__interrupts_end__ +#define BSS_SECTION_START (uint8_t *)&__bss_start__ +#define BSS_SECTION_END (uint8_t *)&__bss_end__ +#define DATA_SECTION_START (uint8_t *)&__data_start__ +#define DATA_SECTION_END (uint8_t *)&__data_end__ +#define CUSTOMSECTION_SECTION_START (uint8_t *)&__customSection_start__ +#define CUSTOMSECTION_SECTION_END (uint8_t *)&__customSection_end__ +#define CODE_RAM_SECTION_START (uint8_t *)&__code_ram_start__ +#define CODE_RAM_SECTION_END (uint8_t *)&__code_ram_end__ + +extern uint32_t __interrupts_start__; +extern uint32_t __interrupts_end__; +extern uint32_t __bss_start__; +extern uint32_t __bss_end__; +extern uint32_t __data_start__; +extern uint32_t __data_end__; +extern uint32_t __customSection_start__; +extern uint32_t __customSection_end__; +extern uint32_t __code_ram_start__; +extern uint32_t __code_ram_end__; +#endif + +#if(defined(__ICCARM__)) +#pragma section = ".data" +#pragma section = ".data_init" +#pragma section = ".bss" +#pragma section = ".intvec" +#pragma section = ".customSection" +#pragma section = ".customSection_init" +#pragma section = "__CODE_RAM" +#pragma section = "__CODE_ROM" +#endif + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Make necessary initializations for RAM. + * + * - Copy initialized data from ROM to RAM. + * - Clear the zero-initialized data section. + * - Copy the vector table from ROM to RAM. This could be an option. + */ +void init_data_bss(void); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _STARTUP_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/startup_M011x.S b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/startup_M011x.S new file mode 100644 index 0000000..0fb0063 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/startup_M011x.S @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/*****************************************************************************/ +/* Version: GNU Compiler Collection */ +/*****************************************************************************/ + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:ROOT(2) + + EXTERN main + EXTERN SystemInit + EXTERN init_data_bss + PUBLIC __vector_table + PUBLIC __vector_table_0x1c + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA + +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; Non Maskable Interrupt + DCD HardFault_Handler ; Cortex-M0 SV Hard Fault Interrupt + DCD 0 + DCD 0 + DCD 0 +__vector_table_0x1c + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD SVC_Handler ; Cortex-M0 SV Call Interrupt + DCD 0 + DCD 0 + DCD PendSV_Handler ; Cortex-M0 Pend SV Interrupt + DCD SysTick_Handler ; Cortex-M0 System Tick Interrupt + + + DCD DMA01_Handler /* 0 (040H) DMA channel 0,1 transfer complete*/ + DCD DMA23_Handler /* 1 (044H) DMA channel 2,3 transfer complete*/ + DCD DMA_Error_Handler /* 2 (048H) DMA error interrupt channels 0-3*/ + DCD FHU_Handler /* 3 (04CH) FHU Interrupt, ERM single bit error correction*/ + DCD RTC_Alarm_Handler /* 4 (050H) RTC alarm interrupt*/ + DCD RTC_Seconds_Handler /* 5 (054H) RTC seconds interrupt*/ + DCD LPTMR_Handler /* 6 (058H) LPTIMER interrupt request*/ + DCD PORT_Handler /* 7 (05CH) Port ABCDE pin detect interrupt */ + DCD CAN_ORed_Handler /* 8 (060H) CAN OR'ed [BusOff\BusOffDone\TransWarning\ReceiveWarning\..... ] */ + DCD CAN_ORed_0_31_MB_Handler /* 9 (064H) CAN OR'ed Message buffer (0-31) */ + DCD CAN_ORed_32_63_MB_Handler /* 10 (068H) CAN OR'ed Message buffer (32-63) */ + DCD MFT0_Ch0_Ch7_Handler /* 11 (06CH) MFT0 Channel 0 to 7 interrupt */ + DCD MFT0_Fault_Handler /* 12 (070H) MFT0 Fault interrupt */ + DCD MFT0_Ovf_Reload_Handler /* 13 (074H) MFT0 Counter overflow and Reload interrupt */ + DCD MFT1_Ch0_Ch7_Handler /* 14 (078H) MFT1 Channel 0 to 7 interrupt */ + DCD MFT1_Fault_Handler /* 15 (07CH) MFT1 Fault interrupt */ + DCD MFT1_Ovf_Reload_Handler /* 16 (080H) MFT1 Counter overflow and Reload interrupt */ + DCD FTFC_Handler /* 17 (084H) FTFC Command done,read collision,err response interrupt */ + DCD PDB_Handler /* 18 (088H) PDB interrupt */ + DCD LPIT_Handler /* 19 (08CH) LPIT interrupt */ + DCD CMU_Handler /* 20 (090H) CMU PLL,SOSC interrupt */ + DCD WDOG_Handler /* 21 (094H) Interrupt request out before wdg reset out */ + DCD RCM_Handler /* 22 (098H) RCM Asynchronous Interrupt, Reset interrutpt */ + DCD I2C_Handler /* 23 (09CH) I2C Interrupt */ + DCD SPI0_Handler /* 24 (0A0H) SPI0 Interrupt */ + DCD SPI1_Handler /* 25 (0A4H) SPI1 Interrupt */ + DCD ADC_Handler /* 26 (0A8H) ADC interrupt request. */ + DCD CMP_Handler /* 27 (0ACH) CMP interrupt request */ + DCD I2S_SLV_MST_Handler /* 28 (0B0H) I2S Slave and Master interrupt */ + DCD UART0_RxTx_Handler /* 29 (0B4H) UART0 Transmit / Receive Interrupt */ + DCD UART1_RxTx_Handler /* 30 (0B8H) UART1 Transmit / Receive Interrupt */ + DCD UART2_RxTx_Handler /* 31 (0BCH) UART2 Transmit / Receive Interrupt */ +__Vectors_End + + SECTION FlashConfig:CODE +__FlashConfig + DCD 0xD28FC027 + DCD 0xDC4DD3A0 + DCD 0x00000000 + DCD 0xFFFF0000 + DCD 0xFFFFFFBF + DCD 0xFFFFFFFF + DCD 0xBEE688FE + DCD 0x8E5BA230 +__FlashConfig_End + +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:REORDER:NOROOT(2) +Reset_Handler + CPSID I ; Mask interrupts + ;; Init the rest of the registers + LDR R1,=0 + LDR R2,=0 + LDR R3,=0 + LDR R4,=0 + LDR R5,=0 + LDR R6,=0 + LDR R7,=0 + MOV R8,R7 + MOV R9,R7 + MOV R10,R7 + MOV R11,R7 + MOV R12,R7 + +#ifdef START_FROM_FLASH + IMPORT __RAM_START, __RAM_END + ;; INIT ECC RAM + + LDR R1, =__RAM_START + LDR R2, =__RAM_END + + SUBS R2, R2, R1 + SUBS R2, #1 + BLE .LC5 + + MOVS R0, #0 + MOVS R3, #4 + .LC4: + STR R0, [R1] + ADD R1, R1, R3 + SUBS R2, #4 + BGE .LC4 + .LC5: +#endif + ;; Initialize the stack pointer + LDR R0, =sfe(CSTACK) + MOV R13,R0 + +#ifndef __NO_SYSTEM_INIT + ;; Call the CMSIS system init routine + LDR R0, =SystemInit + BLX R0 +#endif + + ;; Init .data and .bss sections + LDR R0, =init_data_bss + BLX R0 + CPSIE I ; Unmask interrupts + BL main +JumpToSelf + B JumpToSelf + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler + B . + + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +HardFault_Handler + B . + + + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SVC_Handler + B . + + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +PendSV_Handler + B . + + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SysTick_Handler + B . + + PUBWEAK DMA01_Handler + PUBWEAK DMA23_Handler + PUBWEAK DMA_Error_Handler + PUBWEAK FHU_Handler + PUBWEAK RTC_Alarm_Handler + PUBWEAK RTC_Seconds_Handler + PUBWEAK LPTMR_Handler + PUBWEAK PORT_Handler + PUBWEAK CAN_ORed_Handler + PUBWEAK CAN_ORed_0_31_MB_Handler + PUBWEAK CAN_ORed_32_63_MB_Handler + PUBWEAK MFT0_Ch0_Ch7_Handler + PUBWEAK MFT0_Fault_Handler + PUBWEAK MFT0_Ovf_Reload_Handler + PUBWEAK MFT1_Ch0_Ch7_Handler + PUBWEAK MFT1_Fault_Handler + PUBWEAK MFT1_Ovf_Reload_Handler + PUBWEAK FTFC_Handler + PUBWEAK PDB_Handler + PUBWEAK LPIT_Handler + PUBWEAK CMU_Handler + PUBWEAK WDOG_Handler + PUBWEAK RCM_Handler + PUBWEAK I2C_Handler + PUBWEAK SPI0_Handler + PUBWEAK SPI1_Handler + PUBWEAK ADC_Handler + PUBWEAK CMP_Handler + PUBWEAK I2S_SLV_MST_Handler + PUBWEAK UART0_RxTx_Handler + PUBWEAK UART1_RxTx_Handler + PUBWEAK UART2_RxTx_Handler + PUBWEAK DefaultISR + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler +HardFault_Handler +SVC_Handler +PendSV_Handler +SysTick_Handler +DMA01_Handler +DMA23_Handler +DMA_Error_Handler +FHU_Handler +RTC_Alarm_Handler +RTC_Seconds_Handler +LPTMR_Handler +PORT_Handler +CAN_ORed_Handler +CAN_ORed_0_31_MB_Handler +CAN_ORed_32_63_MB_Handler +MFT0_Ch0_Ch7_Handler +MFT0_Fault_Handler +MFT0_Ovf_Reload_Handler +MFT1_Ch0_Ch7_Handler +MFT1_Fault_Handler +MFT1_Ovf_Reload_Handler +FTFC_Handler +PDB_Handler +LPIT_Handler +CMU_Handler +WDOG_Handler +RCM_Handler +I2C_Handler +SPI0_Handler +SPI1_Handler +ADC_Handler +CMP_Handler +I2S_SLV_MST_Handler +UART0_RxTx_Handler +UART1_RxTx_Handler +UART2_RxTx_Handler +DefaultISR + + END diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/system_M011x.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/system_M011x.c new file mode 100644 index 0000000..c6c23c1 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/system_M011x.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "system_M011x.h" +#include "../cpu_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void SystemInit(void) +{ + /* PFLASH prefetch */ + SimReg_SetFlashPFlsFlushEn(SIM, 1); /* Enable Flush PFLASH pre-fetch */ + SimReg_SetFlashPFlsPfbEn(SIM, 1); /* Enable PFLASH pre-fetch*/ + SimReg_SetFlashPFlsFlushEn(SIM, 0); /* Disable Flush PFLASH prefetch */ + + /* Unlock SCG */ + Scg0Reg_SetKey(SCG0, 0x19962020); + Scg1Reg_SetCkSrcSysDiv(SCG1, 1); + + /* Unlock PCC */ + Pcc0Reg_SetKey(PCC0, 0x55534552); + + /* Switch system clock to default clock */ + if(Scg2Reg_GetCsrSysSt(SCG2) == 2) + { + /* Flash AHB bus read access time configure */ + FtfcReg_SetFcnfgBusReadTm(FTFC, 0); /* 1T required */ + Scg2Reg_SetCsrSrcSys(SCG2, 0); + while(Scg2Reg_GetCsrSysSt(SCG2) != 0) + { + ; + } + } + +#ifdef _USE_EXT_OSC_ + /* Use External oscillator */ + Scg0Reg_SetOscCtrlRange(SCG0, 1); /* set SOSC frequency range(use max value when SOSC as the clock source of the PLL) */ + Scg0Reg_SetOscCtrlEnSosc(SCG0, 1); /* enable SOSC */ + while(Scg0Reg_GetStatusSoscRdy(SCG0) == 0) + { + ; /* wait until SOSC is ready */ + } + + /* Disable PLL */ + Scg0Reg_SetPllCtrl0PllEn(SCG0, 0); + /* PLL configuration: + * - PLL input clock source : SOSC + * - PLL pre-divider : 1 + * - feedback divider : 80 + * - PLL Feedback clock divider pre-scaler : 1 + * - PLL post-divider setting : 4 + * Final PLL output frequency is 8M(SOSC) * 80 / 4 / 2 = 80M + */ + Scg0Reg_SetPllCtrl1PllClkinSel(SCG0, 0); + Scg0Reg_SetPllCtrl0PllPreDiv(SCG0, 0); + Scg0Reg_SetPllCtrl0PllM(SCG0, 80); + Scg0Reg_SetPllCtrl0PllFdkSel(SCG0, 0); + Scg0Reg_SetPllCtrl0PllPosDiv(SCG0, 4); + /* Enable PLL */ + Scg0Reg_SetPllCtrl0PllEn(SCG0, 1); + + /* Use systick for delay */ + SysTick->LOAD = 8000U; + SysTick->VAL = 0U; + SysTick->CTRL = 5U; /* SysTick uses the processor clock and enable sysTick */ + while(SysTick->CTRL < 0x10000) + { + ; /* wait for COUNTFLAG setting*/ + } + /*recover sysTick register*/ + SysTick->CTRL = 4U; + SysTick->LOAD = 0U; + SysTick->VAL = 0U; + + while(Scg0Reg_GetStatusPllLock(SCG0) == 0) + { + ; + } + + /* Set the Flash cnt clock source same as system clock and at 8M */ + Pcc1Reg_SetFlsCtlCntSrc(PCC1, 2); + Pcc1Reg_SetFlsCtlCntDiv(PCC1, 9); + Pcc1Reg_SetFlsCtlCkEn(PCC1, 1); + + /* Flash AHB bus read access time configure */ + FtfcReg_SetFcnfgBusReadTm(FTFC, 1); /* 2T required for 80M AHB */ + + /* Set clk_pll as system clock */ + Scg2Reg_SetCsrSrcSys(SCG2, 2); + while(Scg2Reg_GetCsrSysSt(SCG2) != 2) + { + ; + } +#else + /* Disable PLL */ + Scg0Reg_SetPllCtrl0PllEn(SCG0, 0); + /* PLL configuration: + * - PLL input clock source : SIRC + * - PLL pre-divider : 1 + * - feedback divider : 80 + * - PLL Feedback clock divider pre-scaler : 1 + * - PLL post-divider setting : 4 + * Final PLL output frequency is 8M(SIRC) * 80 / 4 / 2 = 80M + */ + Scg0Reg_SetPllCtrl1PllClkinSel(SCG0, 1); + Scg0Reg_SetPllCtrl0PllPreDiv(SCG0, 0); + Scg0Reg_SetPllCtrl0PllM(SCG0, 80); + Scg0Reg_SetPllCtrl0PllFdkSel(SCG0, 0); + Scg0Reg_SetPllCtrl0PllPosDiv(SCG0, 4); + /* Enable PLL */ + Scg0Reg_SetPllCtrl0PllEn(SCG0, 1); + while(Scg0Reg_GetStatusPllLock(SCG0) == 0) + { + ; + } + + /* Set the Flash cnt clock source same as system clock and at 8M */ + Pcc1Reg_SetFlsCtlCntSrc(PCC1, 2); + Pcc1Reg_SetFlsCtlCntDiv(PCC1, 9); + Pcc1Reg_SetFlsCtlCkEn(PCC1, 1); + + /* Flash AHB bus read access time configure */ + FtfcReg_SetFcnfgBusReadTm(FTFC, 1); /* 2T required for 80M AHB */ + + /* Set clk_pll as system clock */ + Scg2Reg_SetCsrSrcSys(SCG2, 2); + while(Scg2Reg_GetCsrSysSt(SCG2) != 2) + { + ; + } +#endif + + /* Set Core and APB clock source divider */ + Scg1Reg_SetCkSrcSysDiv(SCG1, 0); /* Divide-by-1 */ + Scg2Reg_SetCsrDivAips(SCG2, 0); /* Divide-by-1 */ + + /* Finish setting up the clock */ + Scg0Reg_SetKey(SCG0, 0); /* lock SCG again */ + Pcc0Reg_SetKey(PCC0, 0); /* lock PCC again */ +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/system_M011x.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/system_M011x.h new file mode 100644 index 0000000..7f8d62c --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/cpu/startup/system_M011x.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _SYSTEM_M011X_H_ +#define _SYSTEM_M011X_H_ + +/*! \brief Contains public interface to various functions related + * to the System module of CVM011x series chips + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* Value of the external crystal or oscillator clock frequency in Hz */ +#define CPU_XTAL_CLK_HZ (8000000u) +#if (CPU_XTAL_CLK_HZ > 40000000) || (CPU_XTAL_CLK_HZ < 4000000) +#error "The external crystal or oscillator clock frequency is out of range." +#endif + +/* Value of the slow internal oscillator clock frequency in Hz */ +#define CPU_INT_SLOW_CLK_HZ (8000000u) + +/* Default System clock value for the user code after SystemInit called */ +#define DEFAULT_SYSTEM_CLOCK (80000000u) + + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + + +/******************************************************************************* + * the globals + ******************************************************************************/ + + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Setup the SoC. + * + * This function disables the watchdog, enables FPU. + * if the corresponding feature macro is enabled. + * SystemInit is called from startup_device file. + */ +extern void SystemInit(void); + + +#ifdef __cplusplus +} +#endif /* extern "C" */ + + +#endif /* _SYSTEM_M011X_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/crc/crc_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/crc/crc_drv.c new file mode 100644 index 0000000..01878e0 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/crc/crc_drv.c @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "crc_drv.h" +#include "crc_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define CRCDRV_FIFO_MAX (4) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void CrcDrv_Init(CrcDrvType *obj, struct _CrcRegType_ *reg) +{ + obj->reg = reg; +} + +void CrcDrv_Configure(CrcDrvType *obj, const CrcDrv_ConfigType *userConfig) +{ + /* Set CRC mode */ + CrcReg_SetCrProtocolWidth(obj->reg, (uint8_t)userConfig->crcWidth); + /* Set transposes options */ + CrcReg_SetCrReverseOut(obj->reg, (uint8_t)userConfig->readTranspose); + /* Set CRC polynomial */ + CrcReg_SetPolyReg(obj->reg, userConfig->polynomial); + /* Set writes transposes */ + CrcReg_SetCrReverseIn(obj->reg, (uint8_t)userConfig->writeTranspose); + /* Sets complement or inversion checksum */ + CrcReg_SetCrFXor(obj->reg, userConfig->complementChecksum); + /* Write a seed - initial checksum */ + CrcReg_SetInitReg(obj->reg, userConfig->seed); +} + +void CrcDrv_GetConfig(const CrcDrvType *obj, CrcDrv_ConfigType *userConfig) +{ + /* Gets CRC mode */ + userConfig->crcWidth = (CrcDrv_BitWidthType)CrcReg_GetCrProtocolWidth(obj->reg); + /* Gets transposes and complement options */ + userConfig->readTranspose = (CrcDrv_TransposeType)CrcReg_GetCrReverseOut(obj->reg); + /* Get a polynomial */ + userConfig->polynomial = CrcReg_GetPolyReg(obj->reg); + /* Gets transposes options */ + userConfig->writeTranspose = (CrcDrv_TransposeType)CrcReg_GetCrReverseIn(obj->reg); + /* Gets complement or inversion checksum */ + userConfig->complementChecksum = CrcReg_GetCrFXor(obj->reg); + /* Get a seed - initial checksum */ + userConfig->seed = CrcReg_GetInitReg(obj->reg); +} + +void CrcDrv_GetDefaultConfig(CrcDrv_ConfigType *userConfig) +{ + /* Gets CRC mode default is 16 bit */ + userConfig->crcWidth = CRCDRV_BITWIDTH_16; + /* Gets default a polynomial default is reset value */ + userConfig->polynomial = 0x1021U; + /* Gets default read transposes none */ + userConfig->readTranspose = CRCDRV_TRANSPOSE_NONE; + /* Gets default write transpose none */ + userConfig->writeTranspose = CRCDRV_TRANSPOSE_NONE; + /* Gets default no complement or inversion checksum */ + userConfig->complementChecksum = false; + /* Gets default a seed - initial checksum */ + userConfig->seed = 0xFFFFFFFFU; +} + +void CrcDrv_SetNewSeed(CrcDrvType *obj, uint32_t seed) +{ + /* Write a seed - initial checksum */ + CrcReg_SetInitReg(obj->reg, seed); +} + +void CrcDrv_CrcReset(CrcDrvType *obj) +{ + /* execute CRC rsset */ + CrcReg_SetCrReset(obj->reg); + + /* wait until CRC rsset execute completely */ + while(CrcReg_GetCrReset(obj->reg) != 0) + { + } +} + +uint32_t CrcDrv_GetCrcResult(CrcDrvType *obj) +{ + CrcDrv_BitWidthType width = (CrcDrv_BitWidthType)(CrcReg_GetCrProtocolWidth(obj->reg)); + CrcDrv_TransposeType transpose; + uint32_t result; + + if(width == CRCDRV_BITWIDTH_16) + { + transpose = (CrcDrv_TransposeType)(CrcReg_GetCrReverseOut(obj->reg)); + if((transpose == CRCDRV_TRANSPOSE_BITS_AND_BYTES) || (transpose == CRCDRV_TRANSPOSE_BYTES)) + { + /* Wait until no remaining data in FIFO */ + while(CrcReg_GetDataNumInFifo(obj->reg) != 0) + { + } + /* Returns upper 16 bits of CRC because of transposition in 16-bit mode */ + result = (uint32_t)((CrcReg_GetDataReg(obj->reg) >> 16) & 0xFFFF); + } + else + { + /* Wait until no remaining data in FIFO */ + while(CrcReg_GetDataNumInFifo(obj->reg) != 0) + { + } + /* Get the lower 16 bits */ + result = (uint32_t)(CrcReg_GetDataReg(obj->reg) & 0xFFFF); + } + } + else + { + /* Wait until no remaining data in FIFO */ + while(CrcReg_GetDataNumInFifo(obj->reg) != 0) + { + } + result = CrcReg_GetDataReg(obj->reg); + } + + return result; +} + +void CrcDrv_WriteData8(CrcDrvType *obj, const uint8_t *data, uint32_t dataSize) +{ + uint32_t group = 0; + uint32_t groupNum = dataSize / CRCDRV_FIFO_MAX; + uint32_t left = dataSize - groupNum * CRCDRV_FIFO_MAX; + uint32_t i = 0; + + /* 8-bit writes till end of data buffer */ + for(group = 0; group < groupNum; ++group) + { + /* Wait until no remaining data in FIFO */ + while(CrcReg_GetDataNumInFifo(obj->reg) != 0) + { + } + /* Write as many as possible until FIFO is full */ + for(i = 0; i < CRCDRV_FIFO_MAX; ++i) + { + CrcReg_SetData8Reg(obj->reg, data[group * CRCDRV_FIFO_MAX + i]); + } + } + /* If still data buffering, wait until no remaining data in FIFO */ + while(left != 0 && CrcReg_GetDataNumInFifo(obj->reg) != 0) + { + } + for(i = 0; i < left; ++i) + { + CrcReg_SetData8Reg(obj->reg, data[dataSize - left + i]); + } +} + +void CrcDrv_WriteData16(CrcDrvType *obj, const uint16_t *data, uint32_t dataSize) +{ + uint32_t group = 0; + uint32_t groupNum = dataSize / CRCDRV_FIFO_MAX; + uint32_t left = dataSize - groupNum * CRCDRV_FIFO_MAX; + uint32_t i = 0; + + /* 8-bit writes till end of data buffer */ + for(group = 0; group < groupNum; ++group) + { + /* Wait until no remaining data in FIFO */ + while(CrcReg_GetDataNumInFifo(obj->reg) != 0) + { + } + /* Write as many as possible until FIFO is full */ + for(i = 0; i < CRCDRV_FIFO_MAX; ++i) + { + CrcReg_SetData16Reg(obj->reg, data[group * CRCDRV_FIFO_MAX + i]); + } + } + /* If still data buffering, wait until no remaining data in FIFO */ + while(left != 0 && CrcReg_GetDataNumInFifo(obj->reg) != 0) + { + } + for(i = 0; i < left; ++i) + { + CrcReg_SetData16Reg(obj->reg, data[dataSize - left + i]); + } +} + +void CrcDrv_WriteData32(CrcDrvType *obj, const uint32_t *data, uint32_t dataSize) +{ + uint32_t group = 0; + uint32_t groupNum = dataSize / CRCDRV_FIFO_MAX; + uint32_t left = dataSize - groupNum * CRCDRV_FIFO_MAX; + uint32_t i = 0; + + /* 8-bit writes till end of data buffer */ + for(group = 0; group < groupNum; ++group) + { + /* Wait until no remaining data in FIFO */ + while(CrcReg_GetDataNumInFifo(obj->reg) != 0) + { + } + /* Write as many as possible until FIFO is full */ + for(i = 0; i < CRCDRV_FIFO_MAX; ++i) + { + CrcReg_SetDataReg(obj->reg, data[group * CRCDRV_FIFO_MAX + i]); + } + } + /* If still data buffering, wait until no remaining data in FIFO */ + while(left != 0 && CrcReg_GetDataNumInFifo(obj->reg) != 0) + { + } + for(i = 0; i < left; ++i) + { + CrcReg_SetDataReg(obj->reg, data[dataSize - left + i]); + } +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/crc/crc_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/crc/crc_drv.h new file mode 100644 index 0000000..d522d56 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/crc/crc_drv.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CRC_DRV_H_ +#define _CRC_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of CRC module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup crc_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief CRC type of transpose of read write data + */ +typedef enum +{ + CRCDRV_TRANSPOSE_NONE = 0, /*!< No transpose */ + CRCDRV_TRANSPOSE_BITS = 1, /*!< Transpose bits in bytes */ + CRCDRV_TRANSPOSE_BITS_AND_BYTES = 2, /*!< Transpose bytes and bits in bytes */ + CRCDRV_TRANSPOSE_BYTES = 3, /*!< Transpose bytes */ +} CrcDrv_TransposeType; + +/*! \brief CRC bit width + */ +typedef enum +{ + CRCDRV_BITWIDTH_16 = 0, /*!< No transpose */ + CRCDRV_BITWIDTH_32 = 1, /*!< Transpose bits in bytes */ +} CrcDrv_BitWidthType; + +/*! \brief Definition of configuration of CRC driver + */ +typedef struct _CrcDrv_ConfigType_ +{ + CrcDrv_BitWidthType crcWidth; /*!< Selects 16-bit or 32-bit CRC protocol. */ + uint32_t polynomial; /*!< CRC Polynomial, MSBit first. */ + CrcDrv_TransposeType readTranspose; /*!< Type of transpose when reading CRC result. */ + CrcDrv_TransposeType writeTranspose; /*!< Type of transpose when writing CRC input data. */ + bool complementChecksum; /*!< True if the result shall be complement of the actual checksum. */ + uint32_t seed; /*!< Starting checksum value. */ +} CrcDrv_ConfigType; + +/* Forward declaration of CRC register */ +struct _CrcRegType_; + +/*! \brief The definition of CRC driver class + */ +typedef struct _CrcDrvType_ +{ + struct _CrcRegType_ *reg; +} CrcDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the CRC driver module + * + * This function initializes CRC driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to CRC driver instance + * \param[in] reg : pointer to CRC register instance + */ +extern void CrcDrv_Init(CrcDrvType *obj, struct _CrcRegType_ *reg); + +/*! \brief Configures the CRC module from a user configuration structure + * + * This function configures the CRC module from a user configuration structure + * + * \param[in] obj : pointer to CRC driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void CrcDrv_Configure(CrcDrvType *obj, const CrcDrv_ConfigType *userConfig); + +/*! \brief Get configures of the CRC module currently + * + * This function gets configures of the CRC module currently + * + * \param[in] obj : pointer to CRC driver instance + * \param[out] userConfig : pointer to configuration structure + */ +extern void CrcDrv_GetConfig(const CrcDrvType *obj, CrcDrv_ConfigType *userConfig); + +/*! \brief Get default configures the CRC module for configuration structure + * + * This function gets default configures the CRC module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void CrcDrv_GetDefaultConfig(CrcDrv_ConfigType *userConfig); + +/*! \brief Sets a new seed to register CRC_INIT + * + * This function sets a new seed to register CRC_INIT + * This operation will cause the value of register CRC_DR to be updated to the value of register CRC_INIT + * + * \param[in] obj : pointer to CRC driver instance + * \param[in] seed : new seed will writed to CRC_INIT + */ +extern void CrcDrv_SetNewSeed(CrcDrvType *obj, uint32_t seed); + +/*! \brief Executes CRC reset operation + * + * This function executes CRC reset operation + * This opration will cause the value of register CRC_DR to be updated to the value of register CRC_INIT + * + * \param[in] obj : pointer to CRC driver instance + */ +extern void CrcDrv_CrcReset(CrcDrvType *obj); + +/*! \brief Get the current result of the CRC calculation. + * + * This function returns the current result of the CRC calculation. + * + * \param[in] obj : pointer to CRC register instance + * \return the current CRC calculation result + */ +extern uint32_t CrcDrv_GetCrcResult(CrcDrvType *obj); + +/*! \brief Appends a block of 8 bits data to the current CRC calculation + * + * This function appends a block of 8 bits data to the current CRC calculation + * + * \param[in] obj : pointer to CRC driver instance + * \param[in] data : pointer to input data for CRC calculation + * \param[in] dataSize : length of 8 bits data to be calculated + */ +extern void CrcDrv_WriteData8(CrcDrvType *obj, const uint8_t *data, uint32_t dataSize); + +/*! \brief Appends a block of 16 bits data to the current CRC calculation + * + * This function appends a block of 16 bits data to the current CRC calculation + * + * \param[in] obj : pointer to CRC driver instance + * \param[in] data : pointer to input data for CRC calculation + * \param[in] dataSize : length of 16 bits data to be calculated + */ +extern void CrcDrv_WriteData16(CrcDrvType *obj, const uint16_t *data, uint32_t dataSize); + +/*! \brief Appends a block of 32 bits data to the current CRC calculation + * + * This function appends a block of 32 bits data to the current CRC calculation + * + * \param[in] obj : pointer to CRC driver instance + * \param[in] data : pointer to input data for CRC calculation + * \param[in] dataSize : length of 32 bits data to be calculated + */ +extern void CrcDrv_WriteData32(CrcDrvType *obj, const uint32_t *data, uint32_t dataSize); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _CRC_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/edma/edma_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/edma/edma_drv.c new file mode 100644 index 0000000..d89c367 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/edma/edma_drv.c @@ -0,0 +1,893 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "dmamux_reg.h" +#include "edma_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static void EDmaDrv_ClearIntStatus(EDmaDrvType *obj, uint8_t channel); +static void EDmaDrv_ClearSoftwareTCD(EDmaDrv_SoftwareTcdType *stcd); +static void EDmaDrv_ClearStructure(uint8_t *sructPtr, size_t size); + +/******************************************************************************* + * Code + ******************************************************************************/ +void EDmaDrv_BaseInit(EDmaDrvType *obj) +{ + uint8_t i; + /* Clear the bit of CR register */ + uint32_t regValTemp; + regValTemp = obj->edmaReg->CR; + regValTemp &= ~(EDMA_CR_CLM_MASK); + regValTemp &= ~(EDMA_CR_CX_MASK); + regValTemp &= ~(EDMA_CR_ECX_MASK); + regValTemp &= ~(EDMA_CR_EDBG_MASK); + regValTemp &= ~(EDMA_CR_EMLM_MASK); + regValTemp &= ~(EDMA_CR_ERCA_MASK); + obj->edmaReg->CR = regValTemp; + + for(i = 0; i < EDMA_CHANNELS; i++) + { + EDmaReg_ClearTcdReg(obj->edmaReg, i); + } +} + +void EDmaDrv_Init(EDmaDrvType *obj, struct _EDmaRegType_ *dmaReg, struct _DmamuxRegType_ *dmamuxReg) +{ + obj->edmaReg = dmaReg; + obj->dmamuxReg = dmamuxReg; +} + +void EDmaDrv_GetDefaultConfigure(EDmaDrv_ModuleConfigType *userConfig) +{ + userConfig->chnArbitration = EDMADRV_ARBITRATION_FIXED_PRIORITY; + userConfig->haltOnError = false; + userConfig->channelPriority[0] = EDMADRV_CHN_PRIORITY_0; + userConfig->channelPriority[1] = EDMADRV_CHN_PRIORITY_1; + userConfig->channelPriority[2] = EDMADRV_CHN_PRIORITY_2; + userConfig->channelPriority[3] = EDMADRV_CHN_PRIORITY_3; +} + +void EDmaDrv_GetDefaultChannelConfigure(EDmaDrv_ChannelConfigType *channelConfig) +{ + channelConfig->channelPriority = EDMADRV_CHN_DEFAULT_PRIORITY; + channelConfig->chnConfig = 0; + channelConfig->source = EDMA_REQ_DISABLED; + channelConfig->callback = NULL; + channelConfig->callbackParam = NULL; + channelConfig->enableTrigger = false; +} + +EDmaDrv_Status EDmaDrv_Configure(EDmaDrvType *obj, EDmaDrv_StateType *edmaState, const EDmaDrv_ModuleConfigType *userConfig) +{ + uint32_t index = 0U; + + EDmaDrv_Status edmaStatus = STATUS_SUCCESS; + + obj->dmaState = edmaState; + +#ifdef DMAMUX_AVAILABLE + /* Initialize all DMAMUX instances */ + DmamuxReg_Init(obj->dmamuxReg); +#endif + + /* Clear the state structure. */ + EDmaDrv_ClearStructure((uint8_t *)obj->dmaState, sizeof(EDmaDrv_StateType)); + + /* Init eDMA module on hardware level. */ + EDmaDrv_BaseInit(obj); + + /* Set arbitration mode */ + EDmaReg_SetChannelArbitrationMode(obj->edmaReg, userConfig->chnArbitration); + + if(EDmaReg_GetChannelArbitrationMode(obj->edmaReg) == EDMADRV_ARBITRATION_FIXED_PRIORITY) + { + for(index = 0U; index < EDMA_CHANNELS_INTERRUPT_LINES; index++) + { + EDmaReg_SetChannelPriority(obj->edmaReg, index, (userConfig->channelPriority[index])); + } + } + + /* Set 'Halt on error' configuration */ + EDmaReg_SetHaltOnErrorCmd(obj->edmaReg, userConfig->haltOnError); + + return edmaStatus; +} + +EDmaDrv_Status EDmaDrv_ConfigureChannel(EDmaDrvType *obj, + EDmaDrv_ChnStateType *const chnStateArray[], + const EDmaDrv_ChannelConfigType *const chnConfig) +{ + EDmaDrv_Status edmaStatus = STATUS_SUCCESS; + + /* Initialize the channels based on configuration list */ + if((chnStateArray != NULL) && (chnConfig != NULL)) + { + edmaStatus = EDmaDrv_ChannelInit(obj, chnStateArray[chnConfig->chnConfig], chnConfig); + } + else + { + edmaStatus = STATUS_ERROR; + } + return edmaStatus; +} + +EDmaDrv_Status EDmaDrv_Deinit(EDmaDrvType *obj) +{ + uint32_t index = 0U; + + if(obj->dmaState != NULL) + { + /* Release all edma channel. */ + for(index = 0U; index < (uint32_t)EDMA_CHANNELS; index++) + { + /* Release all channels. */ + if(obj->dmaState->chnState[index] != NULL) + { + (void)EDmaDrv_ReleaseChannel(obj, index); + } + } + } + + obj->dmaState = NULL; + + return STATUS_SUCCESS; +} + +EDmaDrv_Status EDmaDrv_ChannelInit(EDmaDrvType *obj, + EDmaDrv_ChnStateType *edmaChannelState, + const EDmaDrv_ChannelConfigType *edmaChannelConfig) +{ + uint8_t channel = edmaChannelConfig->chnConfig; + + /* Get status */ + EDmaDrv_Status retStatus = STATUS_SUCCESS; + /* Reset the channel state structure to default value. */ + EDmaDrv_ClearStructure((uint8_t *)(edmaChannelState), sizeof(EDmaDrv_ChnStateType)); + +#ifdef DMAMUX_AVAILABLE + if(edmaChannelConfig->source != EDMA_REQ_DISABLED) + { + retStatus = EDmaDrv_SetChannelRequestAndTrigger(obj, + edmaChannelConfig->chnConfig, + (uint8_t)edmaChannelConfig->source, + edmaChannelConfig->enableTrigger); + } +#endif + + /* Clear the TCD registers for this channel */ + EDmaReg_ClearTcdReg(obj->edmaReg, channel); + + /* polyspace-begin DEFECT:USELESS_IF [ Not a defect: Low ] "Still keep this if statement." */ + if(retStatus == STATUS_SUCCESS) + { + obj->dmaState->chnState[channel] = edmaChannelState; + obj->dmaState->chnState[channel]->chn = channel; + obj->dmaState->chnState[channel]->status = DMA_CHN_NORMAL; + + /* Set the channel priority, as defined in the configuration, only if fixed arbitration mode is selected */ + if((EDmaReg_GetChannelArbitrationMode(obj->edmaReg) == EDMADRV_ARBITRATION_FIXED_PRIORITY) + && (edmaChannelConfig->channelPriority != EDMADRV_CHN_DEFAULT_PRIORITY)) + { + EDmaReg_SetChannelPriority(obj->edmaReg, channel, edmaChannelConfig->channelPriority); + } + /* Install the user callback */ + obj->dmaState->chnState[channel]->callback = edmaChannelConfig->callback; + obj->dmaState->chnState[channel]->parameter = edmaChannelConfig->callbackParam; + } + /* polyspace-end DEFECT:USELESS_IF [ Not a defect: Low ] "Still keep this if statement." */ + + return retStatus; +} + +EDmaDrv_Status EDmaDrv_InstallCallback(EDmaDrvType *obj, uint8_t channel, EDmaDrv_CallBackType callback, void *parameter) +{ + obj->dmaState->chnState[channel]->callback = callback; + obj->dmaState->chnState[channel]->parameter = parameter; + return STATUS_SUCCESS; +} + +EDmaDrv_Status EDmaDrv_ReleaseChannel(EDmaDrvType *obj, uint8_t channel) +{ + /* Stop edma channel. */ + EDmaReg_SetDmaRequestCmd(obj->edmaReg, channel, false); + + /* Reset the channel state structure to default value. */ + EDmaDrv_ClearStructure((uint8_t *)obj->dmaState->chnState[channel], sizeof(EDmaDrv_ChnStateType)); + + obj->dmaState->chnState[channel] = NULL; + + return STATUS_SUCCESS; +} + +static void EDmaDrv_ClearIntStatus(EDmaDrvType *obj, uint8_t channel) +{ + EDmaReg_ClearDoneStatusFlag(obj->edmaReg, channel); + EDmaReg_ClearIntStatusFlag(obj->edmaReg, channel); +} + +static void EDmaDrv_ClearSoftwareTCD(EDmaDrv_SoftwareTcdType *stcd) +{ + EDmaDrv_ClearStructure((uint8_t *)stcd, sizeof(EDmaDrv_SoftwareTcdType)); +} + +void EDmaDrv_IRQHandler(EDmaDrvType *obj, uint8_t channel) +{ + const EDmaDrv_ChnStateType *chnState = obj->dmaState->chnState[channel]; + + EDmaDrv_ClearIntStatus(obj, channel); + + if(chnState != NULL) + { + if(chnState->callback != NULL) + { + chnState->callback(chnState->parameter, chnState->status); + } + } +} + +void EDmaDrv_ErrorIRQHandler(EDmaDrvType *obj, uint8_t channel) +{ + EDmaReg_SetDmaRequestCmd(obj->edmaReg, channel, false); + EDmaDrv_ChnStateType *chnState = obj->dmaState->chnState[channel]; + if(chnState != NULL) + { + EDmaDrv_ClearIntStatus(obj, channel); + EDmaReg_ClearErrorIntStatusFlag(obj->edmaReg, channel); + chnState->status = DMA_CHN_ERROR; + if(chnState->callback != NULL) + { + chnState->callback(chnState->parameter, chnState->status); + } + } +} + +EDmaDrv_Status EDmaDrv_ConfigSingleBlockTransfer(EDmaDrvType *obj, + uint8_t channel, + EDmaDrv_TransferType type, + uint32_t srcAddr, + uint32_t destAddr, + EDmaDrv_TransferSizeType transferSize, + uint32_t dataBufferSize, + bool enableHwClrDone) +{ + EDmaDrv_Status retStatus = STATUS_SUCCESS; + + /* Compute the transfer offset, based on transfer size. + * The number of bytes transferred in each source read/destination write + * is obtained with the following formula: + * source_read_size = 2^SSIZE + * destination_write_size = 2^DSIZE + */ + uint8_t transferOffset = (uint8_t)(1U << ((uint8_t)transferSize)); + + /* The number of bytes to be transferred (buffer size) must + * be a multiple of the source read/destination write size + */ + if((dataBufferSize % transferOffset) != 0U) + { + retStatus = STATUS_ERROR; + } + + if(retStatus == STATUS_SUCCESS) + { + /* Clear transfer control descriptor for the current channel */ + EDmaReg_ClearTcdReg(obj->edmaReg, channel); + + EDmaReg_SetMinorLoopMappingCmd(obj->edmaReg, true); + + /* Configure source and destination addresses */ + EDmaReg_SetTcdSrcAddr(obj->edmaReg, channel, srcAddr); + EDmaReg_SetTcdDestAddr(obj->edmaReg, channel, destAddr); + + /* Set transfer size (1B/2B/4B/16B/32B) */ + EDmaReg_SetTcdAttribute(obj->edmaReg, channel, EDMADRV_MODULO_OFF, EDMADRV_MODULO_OFF, transferSize); + + /* Configure source/destination offset. */ + switch(type) + { + case EDMADRV_TRANSFER_PERIPH2MEM: + EDmaReg_SetTcdSrcOffset(obj->edmaReg, channel, 0); + EDmaReg_SetTcdDestOffset(obj->edmaReg, channel, (int8_t)transferOffset); + break; + case EDMADRV_TRANSFER_MEM2PERIPH: + EDmaReg_SetTcdSrcOffset(obj->edmaReg, channel, (int8_t)transferOffset); + EDmaReg_SetTcdDestOffset(obj->edmaReg, channel, 0); + break; + case EDMADRV_TRANSFER_MEM2MEM: + EDmaReg_SetTcdSrcOffset(obj->edmaReg, channel, (int8_t)transferOffset); + EDmaReg_SetTcdDestOffset(obj->edmaReg, channel, (int8_t)transferOffset); + break; + case EDMADRV_TRANSFER_PERIPH2PERIPH: + EDmaReg_SetTcdSrcOffset(obj->edmaReg, channel, 0); + EDmaReg_SetTcdDestOffset(obj->edmaReg, channel, 0); + break; + default: + /* This should never be reached - all the possible values have been handled. */ + break; + } + + /* Set the total number of bytes to be transfered */ + EDmaReg_SetTcdNbytes(obj->edmaReg, channel, dataBufferSize); + + /* Set major iteration count to 1 (single block mode) */ + EDmaReg_SetTcdMajorCount(obj->edmaReg, channel, 1U); + + /* Enable interrupt when the transfer completes */ + EDmaReg_SetTcdMajorCompleteIntCmd(obj->edmaReg, channel, true); + + EDmaReg_SetTcdHardClrDoneCmd(obj->edmaReg, channel, enableHwClrDone); + /* Set channel status to normal */ + obj->dmaState->chnState[channel]->status = DMA_CHN_NORMAL; + } + + return retStatus; +} + +EDmaDrv_Status EDmaDrv_ConfigMultiBlockTransfer(EDmaDrvType *obj, + uint8_t channel, + EDmaDrv_TransferType type, + uint32_t srcAddr, + uint32_t destAddr, + EDmaDrv_TransferSizeType transferSize, + uint32_t blockSize, + uint32_t blockCount, + bool enableHwClrDone, + bool disableReqOnCompletion) +{ + EDmaDrv_Status retStatus = STATUS_SUCCESS; + + /* Configure the transfer for one data block */ + retStatus = EDmaDrv_ConfigSingleBlockTransfer(obj, channel, type, srcAddr, destAddr, transferSize, blockSize, enableHwClrDone); + + if(retStatus == STATUS_SUCCESS) + { + /* Set the number of data blocks */ + EDmaReg_SetTcdMajorCount(obj->edmaReg, channel, blockCount); + + /* Enable/disable requests upon completion */ + EDmaReg_SetTcdDisableDmaRequestAfterTcdDoneCmd(obj->edmaReg, channel, disableReqOnCompletion); + } + + return retStatus; +} + +EDmaDrv_Status EDmaDrv_ConfigLoopTransfer(EDmaDrvType *obj, uint8_t channel, const EDmaDrv_TransferConfigType *transferConfig) +{ + EDmaReg_SetMinorLoopMappingCmd(obj->edmaReg, true); + + /* Write the configuration in the transfer control descriptor registers */ + EDmaDrv_PushConfigToReg(obj, channel, transferConfig); + + /* Set channel status to normal */ + obj->dmaState->chnState[channel]->status = DMA_CHN_NORMAL; + + return STATUS_SUCCESS; +} + +EDmaDrv_Status EDmaDrv_ConfigScatterGatherTransfer(EDmaDrvType *obj, + uint8_t channel, + EDmaDrv_SoftwareTcdType *stcd, + EDmaDrv_TransferSizeType transferSize, + uint32_t bytesOnEachRequest, + bool hardClrDone, + const EDmaDrv_ScatterGatherListType *srcList, + const EDmaDrv_ScatterGatherListType *destList, + const EDmaDrv_LoopTransferConfigType *loopTransferList, + uint8_t tcdCount) +{ + uint8_t i = 0U; + uint16_t transferOffset = 0U; + uint32_t stcdAlignedAddr = STCD_ADDR(stcd); + EDmaDrv_SoftwareTcdType *edmaSwTcdAddr = (EDmaDrv_SoftwareTcdType *)stcdAlignedAddr; + EDmaDrv_LoopTransferConfigType edmaLoopConfig; + EDmaDrv_TransferConfigType edmaTransferConfig; + EDmaDrv_Status retStatus = STATUS_SUCCESS; + + /* Set channel status to normal */ + obj->dmaState->chnState[channel]->status = DMA_CHN_NORMAL; + + /* Compute the transfer offset, based on transfer size. + * The number of bytes transferred in each source read/destination write + * is obtained with the following formula: + * source_read_size = 2^SSIZE + * destination_write_size = 2^DSIZE + */ + transferOffset = (uint16_t)(1UL << ((uint16_t)transferSize)); + + /* The number of bytes to be transferred on each request must + * be a multiple of the source read/destination write size + */ + if((bytesOnEachRequest % transferOffset) != 0U) + { + retStatus = STATUS_ERROR; + } + + /* Clear the configuration structures before initializing them. */ + EDmaDrv_ClearStructure((uint8_t *)(&edmaTransferConfig), sizeof(EDmaDrv_TransferConfigType)); + EDmaDrv_ClearStructure((uint8_t *)(&edmaLoopConfig), sizeof(EDmaDrv_LoopTransferConfigType)); + + /* Configure the transfer for scatter/gather mode. */ + edmaTransferConfig.srcLastAddrAdjust = 0; + edmaTransferConfig.destLastAddrAdjust = 0; + edmaTransferConfig.srcModulo = EDMADRV_MODULO_OFF; + edmaTransferConfig.destModulo = EDMADRV_MODULO_OFF; + edmaTransferConfig.srcDestTransferSize = transferSize; + edmaTransferConfig.minorByteTransferCount = bytesOnEachRequest; + edmaTransferConfig.interruptEnable = true; + edmaTransferConfig.scatterGatherEnable = true; + edmaTransferConfig.hardClrDone = hardClrDone; + edmaTransferConfig.loopTransferConfig = &edmaLoopConfig; + edmaTransferConfig.loopTransferConfig->srcOffsetEnable = false; + edmaTransferConfig.loopTransferConfig->dstOffsetEnable = false; + + + /* Copy scatter/gather lists to transfer configuration*/ + for(i = 0U; (i < tcdCount) && (retStatus == STATUS_SUCCESS); i++) + { + if(loopTransferList != NULL) + { + edmaTransferConfig.loopTransferConfig->minorLoopChnLinkEnable = loopTransferList[i].minorLoopChnLinkEnable; + edmaTransferConfig.loopTransferConfig->majorLoopChnLinkEnable = loopTransferList[i].majorLoopChnLinkEnable; + edmaTransferConfig.loopTransferConfig->minorLoopChnLinkNumber = loopTransferList[i].minorLoopChnLinkNumber; + edmaTransferConfig.loopTransferConfig->majorLoopChnLinkNumber = loopTransferList[i].majorLoopChnLinkNumber; + } + else + { + edmaTransferConfig.loopTransferConfig->minorLoopChnLinkEnable = false; + edmaTransferConfig.loopTransferConfig->majorLoopChnLinkEnable = false; + edmaTransferConfig.loopTransferConfig->minorLoopChnLinkNumber = 0; + edmaTransferConfig.loopTransferConfig->majorLoopChnLinkNumber = 0; + } + + edmaTransferConfig.srcAddr = srcList[i].address; + edmaTransferConfig.destAddr = destList[i].address; + if((srcList[i].length != destList[i].length) || (srcList[i].type != destList[i].type)) + { + retStatus = STATUS_ERROR; + break; + } + edmaTransferConfig.loopTransferConfig->majorLoopIterationCount = srcList[i].length / bytesOnEachRequest; + + switch(srcList[i].type) + { + case EDMADRV_TRANSFER_PERIPH2MEM: + /* Configure Source Read. */ + edmaTransferConfig.srcOffset = 0; + /* Configure Dest Write. */ + edmaTransferConfig.destOffset = (int16_t)transferOffset; + break; + case EDMADRV_TRANSFER_MEM2PERIPH: + /* Configure Source Read. */ + edmaTransferConfig.srcOffset = (int16_t)transferOffset; + /* Configure Dest Write. */ + edmaTransferConfig.destOffset = 0; + break; + case EDMADRV_TRANSFER_MEM2MEM: + /* Configure Source Read. */ + edmaTransferConfig.srcOffset = (int16_t)transferOffset; + /* Configure Dest Write. */ + edmaTransferConfig.destOffset = (int16_t)transferOffset; + break; + case EDMADRV_TRANSFER_PERIPH2PERIPH: + /* Configure Source Read. */ + edmaTransferConfig.srcOffset = 0; + /* Configure Dest Write. */ + edmaTransferConfig.destOffset = 0; + break; + default: + /* This should never be reached - all the possible values have been handled. */ + break; + } + + /* Configure the pointer to next software TCD structure; for the last one, this address should be 0 */ + EDmaDrv_SoftwareTcdType *ptNextAddr; + + if(i == ((uint8_t)(tcdCount - 1U))) + { + ptNextAddr = &edmaSwTcdAddr[0]; + } + else + { + ptNextAddr = &edmaSwTcdAddr[i + 1]; + } + edmaTransferConfig.scatterGatherNextDescAddr = ((uint32_t)ptNextAddr); + + if(i == 0U) + { + /* Push the configuration for the first descriptor to registers */ + EDmaDrv_PushConfigToReg(obj, channel, &edmaTransferConfig); + } + EDmaDrv_PushConfigToSTcd(&edmaTransferConfig, &edmaSwTcdAddr[i]); + } + + return retStatus; +} + +EDmaDrv_Status EDmaDrv_StartChannel(EDmaDrvType *obj, uint8_t channel) +{ + /* Enable requests for current channel */ + EDmaReg_SetDmaRequestCmd(obj->edmaReg, channel, true); + + return STATUS_SUCCESS; +} + +EDmaDrv_Status EDmaDrv_StopChannel(EDmaDrvType *obj, uint8_t channel) +{ + /* Disable requests for current channel */ + EDmaReg_SetDmaRequestCmd(obj->edmaReg, channel, false); + + return STATUS_SUCCESS; +} + +EDmaDrv_Status EDmaDrv_SetChannelRequestAndTrigger(EDmaDrvType *obj, uint8_t channel, uint8_t request, bool enableTrigger) +{ +#ifdef DMAMUX_AVAILABLE + /* Get request index for the corresponding DMAMUX instance */ + uint8_t dmaMuxRequest = (uint8_t)request; + + /* Set request and trigger */ + DmamuxReg_SetChannelCmd(obj->dmamuxReg, channel, false); + DmamuxReg_SetChannelSource(obj->dmamuxReg, channel, dmaMuxRequest); +#ifdef DMAMUX_HAS_TRIG + DmamuxReg_SetChannelTrigger(obj->dmamuxReg, channel, enableTrigger); +#else + (void)enableTrigger; +#endif + DmamuxReg_SetChannelCmd(obj->dmamuxReg, channel, true); + + return STATUS_SUCCESS; +#else + (void)channel; + (void)request; + (void)enableTrigger; + return STATUS_UNSUPPORTED; +#endif +} + +void EDmaDrv_ClearTcd(EDmaDrvType *obj, uint8_t channel) +{ + /* Clear the TCD memory */ + EDmaReg_ClearTcdReg(obj->edmaReg, channel); +} + +void EDmaDrv_SetSrcAddr(EDmaDrvType *obj, uint8_t channel, uint32_t address) +{ + /* Set channel TCD source address */ + EDmaReg_SetTcdSrcAddr(obj->edmaReg, channel, address); +} + +void EDmaDrv_SetSrcOffset(EDmaDrvType *obj, uint8_t channel, int16_t offset) +{ + /* Set channel TCD source offset */ + EDmaReg_SetTcdSrcOffset(obj->edmaReg, channel, (uint16_t)offset); +} + +void EDmaDrv_SetSrcReadDestWriteChunkSize(EDmaDrvType *obj, uint8_t channel, EDmaDrv_TransferSizeType size) +{ + /* Set channel TCD source transfer size */ + EDmaReg_SetTcdSrcDesTransferSize(obj->edmaReg, channel, size); +} + +void EDmaDrv_SetSrcLastAddrAdjustment(EDmaDrvType *obj, uint8_t channel, int32_t adjust) +{ + /* Set channel TCD source last adjustment */ + EDmaReg_SetTcdSrcLastAdjust(obj->edmaReg, channel, (uint32_t)adjust); +} + +void EDmaDrv_SetDestLastAddrAdjustment(EDmaDrvType *obj, uint8_t channel, int32_t adjust) +{ + /* Set channel TCD source last adjustment */ + EDmaReg_SetTcdDestLastAdjust(obj->edmaReg, channel, (uint32_t)adjust); +} + +void EDmaDrv_SetDestAddr(EDmaDrvType *obj, uint8_t channel, uint32_t address) +{ + /* Set channel TCD destination address */ + EDmaReg_SetTcdDestAddr(obj->edmaReg, channel, address); +} + +void EDmaDrv_SetDestOffset(EDmaDrvType *obj, uint8_t channel, int16_t offset) +{ + /* Set channel TCD destination offset */ + EDmaReg_SetTcdDestOffset(obj->edmaReg, channel, (uint16_t)offset); +} + +void EDmaDrv_SetMinorLoopBlockSize(EDmaDrvType *obj, uint8_t channel, uint32_t nbytes) +{ + /* Set channel TCD minor loop block size */ + EDmaReg_SetTcdNbytes(obj->edmaReg, channel, nbytes); +} + +void EDmaDrv_SetMajorLoopIterationCount(EDmaDrvType *obj, uint8_t channel, uint32_t majorLoopCount) +{ + /* Set the major loop iteration count */ + EDmaReg_SetTcdMajorCount(obj->edmaReg, channel, majorLoopCount); +} + +uint32_t EDmaDrv_GetRemainingMajorIterationsCount(EDmaDrvType *obj, uint8_t channel) +{ + /* Retrieve the number of minor loops yet to be triggered */ + uint32_t count = EDmaReg_GetTcdCurrentMajorCount(obj->edmaReg, channel); + + return count; +} + +void EDmaDrv_SetScatterGatherLink(EDmaDrvType *obj, uint8_t channel, uint32_t nextTCDAddr) +{ + /* Configures the memory address of the next TCD */ + EDmaReg_SetTcdScatterGatherLink(obj->edmaReg, channel, nextTCDAddr); +} + +void EDmaDrv_DisableRequestsOnTransferComplete(EDmaDrvType *obj, uint8_t channel, bool disable) +{ + /* Disables/Enables the DMA request upon TCD completion */ + EDmaReg_SetTcdDisableDmaRequestAfterTcdDoneCmd(obj->edmaReg, channel, disable); +} + +void EDmaDrv_ConfigureInterrupt(EDmaDrvType *obj, uint8_t channel, EDmaDrv_ChannelInterruptType intSrc, bool enable) +{ + /* Disables/Enables the channel interrupt requests. */ + switch(intSrc) + { + case EDMADRV_CHN_ERR_INT: + /* Enable channel interrupt request when error conditions occur */ + EDmaReg_SetErrorIntCmd(obj->edmaReg, channel, enable); + break; + case EDMADRV_CHN_HALF_MAJOR_LOOP_INT: + /* Enable channel interrupt request when major iteration count reaches halfway point */ + EDmaReg_SetTcdMajorHalfCompleteIntCmd(obj->edmaReg, channel, enable); + break; + case EDMADRV_CHN_MAJOR_LOOP_INT: + /* Enable channel interrupt request when major iteration count reaches zero */ + EDmaReg_SetTcdMajorCompleteIntCmd(obj->edmaReg, channel, enable); + break; + default: + /* This branch should never be reached if driver API is used properly */ + break; + } +} + +void EDmaDrv_CancelTransfer(EDmaDrvType *obj, bool error) +{ + /* Cancel the running transfer. */ + if(error) + { + EDmaReg_CancelTransferWithError(obj->edmaReg); + } + else + { + EDmaReg_CancelTransfer(obj->edmaReg); + } +} + +void EDmaDrv_TriggerSwRequest(EDmaDrvType *obj, uint8_t channel) +{ + /* Trigger the channel transfer. */ + EDmaReg_SetChannelStartFlag(obj->edmaReg, channel); +} + +void EDmaDrv_PushConfigToSTcd(const EDmaDrv_TransferConfigType *config, EDmaDrv_SoftwareTcdType *stcd) +{ + if((config != NULL) && (stcd != NULL)) + { + /* Clear the array of software TCDs passed by the user */ + EDmaDrv_ClearSoftwareTCD(stcd); + + /* Set the software TCD fields */ + stcd->ATTR = (uint16_t)(EDMA_TCD_ATTR_SMOD(config->srcModulo) | EDMA_TCD_ATTR_SDSIZE(config->srcDestTransferSize) + | EDMA_TCD_ATTR_DMOD(config->destModulo)); + stcd->SADDR = config->srcAddr; + stcd->SOFF = config->srcOffset; + stcd->NBYTES = config->minorByteTransferCount; + stcd->SLAST = config->srcLastAddrAdjust; + stcd->DADDR = config->destAddr; + stcd->DOFF = config->destOffset; + stcd->CITER = (uint16_t)config->loopTransferConfig->majorLoopIterationCount; + stcd->BITER = (uint16_t)config->loopTransferConfig->majorLoopIterationCount; + if(config->scatterGatherEnable) + { + stcd->DLAST_SGA = (int32_t)config->scatterGatherNextDescAddr; + } + else + { + stcd->DLAST_SGA = config->destLastAddrAdjust; + } + stcd->CSR = (uint16_t)(((config->interruptEnable ? 1UL : 0UL) << EDMA_TCD_CSR_INTMAJOR_SHIFT) + | ((config->scatterGatherEnable ? 1UL : 0UL) << EDMA_TCD_CSR_ESG_SHIFT)); + + if (config->hardClrDone) + { + stcd->CSR |= EDMA_TCD_CSR_HARD_CLR_DONE_MASK; + } + else + { + stcd->CSR &= ~EDMA_TCD_CSR_HARD_CLR_DONE_MASK; + } + + + if(config->loopTransferConfig->majorLoopChnLinkEnable) + { + stcd->CSR |= (uint16_t)((EDMA_TCD_CSR_MAJORELINK_MASK) + | (config->loopTransferConfig->majorLoopChnLinkNumber << EDMA_TCD_CSR_MAJORLINKCH_SHIFT)); + } + else + { + stcd->CSR &= ~((uint16_t)EDMA_TCD_CSR_MAJORELINK_MASK); + stcd->CSR &= ~((uint16_t)EDMA_TCD_CSR_MAJORLINKCH_MASK); + } + + if(config->loopTransferConfig->minorLoopChnLinkEnable) + { + uint16_t biterElinkTemp; + biterElinkTemp = stcd->CITER; + biterElinkTemp |= EDMA_TCD_BITER_ELINKYES_ELINK_MASK; + biterElinkTemp &= (uint16_t) ~(EDMA_TCD_BITER_ELINKYES_LINKCH_MASK); + biterElinkTemp |= (((uint16_t)(((uint16_t)(config->loopTransferConfig->minorLoopChnLinkNumber)) << EDMA_TCD_BITER_ELINKYES_LINKCH_SHIFT)) & EDMA_TCD_BITER_ELINKYES_LINKCH_MASK); + stcd->CITER = biterElinkTemp; + stcd->BITER = biterElinkTemp; + } + else + { + stcd->CITER &= (uint16_t) ~(EDMA_TCD_BITER_ELINKYES_LINKCH_MASK); + stcd->BITER &= (uint16_t) ~(EDMA_TCD_BITER_ELINKYES_LINKCH_MASK); + stcd->CITER &= ~EDMA_TCD_BITER_ELINKYES_ELINK_MASK; + stcd->BITER &= ~EDMA_TCD_BITER_ELINKYES_ELINK_MASK; + } + } +} + +void EDmaDrv_PushConfigToReg(EDmaDrvType *obj, uint8_t channel, const EDmaDrv_TransferConfigType *tcd) +{ + /* Clear TCD registers */ + EDmaReg_ClearTcdReg(obj->edmaReg, channel); + + /* Set source and destination addresses */ + EDmaReg_SetTcdSrcAddr(obj->edmaReg, channel, tcd->srcAddr); + EDmaReg_SetTcdDestAddr(obj->edmaReg, channel, tcd->destAddr); + /* Set source/destination modulo feature and transfer size */ + EDmaReg_SetTcdAttribute(obj->edmaReg, channel, tcd->srcModulo, tcd->destModulo, tcd->srcDestTransferSize); + /* Set source/destination offset and last adjustment; for scatter/gather operation, destination + * last adjustment is the address of the next TCD structure to be loaded by the eDMA engine */ + EDmaReg_SetTcdSrcOffset(obj->edmaReg, channel, (uint16_t)tcd->srcOffset); + EDmaReg_SetTcdDestOffset(obj->edmaReg, channel, (uint16_t)tcd->destOffset); + EDmaReg_SetTcdSrcLastAdjust(obj->edmaReg, channel, (uint32_t)tcd->srcLastAddrAdjust); + + if(tcd->scatterGatherEnable) + { + EDmaReg_SetTcdScatterGatherCmd(obj->edmaReg, channel, true); + EDmaReg_SetTcdScatterGatherLink(obj->edmaReg, channel, tcd->scatterGatherNextDescAddr); + } + else + { + EDmaReg_SetTcdScatterGatherCmd(obj->edmaReg, channel, false); + EDmaReg_SetTcdDestLastAdjust(obj->edmaReg, channel, (uint32_t)tcd->destLastAddrAdjust); + } + + /* Configure channel interrupt */ + EDmaReg_SetTcdMajorCompleteIntCmd(obj->edmaReg, channel, tcd->interruptEnable); + + /* Configure channel clear done automatically*/ + EDmaReg_SetTcdHardClrDoneCmd(obj->edmaReg, channel, tcd->hardClrDone); + + /* If loop configuration is available, copy minor/major loop setup to registers */ + if(tcd->loopTransferConfig != NULL) + { + EDmaReg_SetTcdSrcMinorLoopOffsetCmd(obj->edmaReg, channel, tcd->loopTransferConfig->srcOffsetEnable); + EDmaReg_SetTcdDestMinorLoopOffsetCmd(obj->edmaReg, channel, tcd->loopTransferConfig->dstOffsetEnable); + EDmaReg_SetTcdMinorLoopOffset(obj->edmaReg, channel, tcd->loopTransferConfig->minorLoopOffset); + EDmaReg_SetTcdNbytes(obj->edmaReg, channel, tcd->minorByteTransferCount); + + EDmaReg_SetTcdChannelMinorLink(obj->edmaReg, + channel, + tcd->loopTransferConfig->minorLoopChnLinkNumber, + tcd->loopTransferConfig->minorLoopChnLinkEnable); + EDmaReg_SetTcdChannelMajorLink(obj->edmaReg, + channel, + tcd->loopTransferConfig->majorLoopChnLinkNumber, + tcd->loopTransferConfig->majorLoopChnLinkEnable); + + EDmaReg_SetTcdMajorCount(obj->edmaReg, channel, tcd->loopTransferConfig->majorLoopIterationCount); + } + else + { + EDmaReg_SetTcdNbytes(obj->edmaReg, channel, tcd->minorByteTransferCount); + } + + if (EDmaReg_GetChannelErrorStatusFlag(obj->edmaReg, channel)) + { + EDmaReg_ClearErrorIntStatusFlag(obj->edmaReg, channel); + } +} + +#if defined(CUSTOM_DEVASSERT) || defined(DEV_ERROR_DETECT) +/*FUNCTION********************************************************************** + * + * Function Name : EDMA_DRV_ValidTransferSize + * Description : Check if the transfer size value is legal (0/1/2/4/5). + * + *END**************************************************************************/ +static bool EDmaDrv_ValidTransferSize(edma_transfer_size_t size) +{ + bool isValid; + switch(size) + { + case EDMA_TRANSFER_SIZE_1B: + case EDMA_TRANSFER_SIZE_2B: + case EDMA_TRANSFER_SIZE_4B: +#ifdef FEATURE_DMA_TRANSFER_SIZE_8B + case EDMA_TRANSFER_SIZE_8B: +#endif +#ifdef FEATURE_DMA_TRANSFER_SIZE_16B + case EDMA_TRANSFER_SIZE_16B: +#endif +#ifdef FEATURE_DMA_TRANSFER_SIZE_32B + case EDMA_TRANSFER_SIZE_32B: +#endif +#ifdef FEATURE_DMA_TRANSFER_SIZE_64B + case EDMA_TRANSFER_SIZE_64B: +#endif + isValid = true; + break; + default: + isValid = false; + break; + } + return isValid; +} +#endif + +EDmaDrv_ChnStatusType EDmaDrv_GetChannelStatus(EDmaDrvType *obj, uint8_t channel) +{ + return obj->dmaState->chnState[channel]->status; +} + +static void EDmaDrv_ClearStructure(uint8_t *sructPtr, size_t size) +{ + while(size > 0U) + { + *sructPtr = 0; + sructPtr++; + size--; + } +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/edma/edma_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/edma/edma_drv.h new file mode 100644 index 0000000..9aadead --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/edma/edma_drv.h @@ -0,0 +1,835 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _DMA_DRV_H_ +#define _DMA_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the DMA (Direct Memory Access) module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "edma_reg.h" + +/*! \addtogroup edma_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +/*! \brief Macro for the memory size needed for the software TCD. + * + * Software TCD is aligned to 32 bytes. We don't need a software TCD structure for the first + * descriptor, since the configuration is pushed directly to registers. + * To make sure the software TCD can meet the eDMA module requirement regarding alignment, + * allocate memory for the remaining descriptors with extra 31 bytes. + */ +#define STCD_SIZE(number) (((number)*32U) - 1U) +#define STCD_ADDR(address) (((uint32_t)address + 31UL) & ~0x1FUL) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +/*! \brief Status return codes. + * Common error codes will be a unified enumeration (C enum) that will contain all error codes + * (common and specific). There will be separate "error values spaces" (or slots), each of 256 + * positions, allocated per functionality. + */ +typedef enum +{ + /* Generic error codes */ + STATUS_SUCCESS = 0x000U, /*!< Generic operation success status */ + STATUS_ERROR = 0x001U, /*!< Generic operation failure status */ + STATUS_BUSY = 0x002U, /*!< Generic operation busy status */ + STATUS_TIMEOUT = 0x003U, /*!< Generic operation timeout status */ + STATUS_UNSUPPORTED = 0x004U, /*!< Generic operation unsupported status */ +} EDmaDrv_Status; + +/*! \brief eDMA channel priority setting + */ +typedef enum +{ + EDMADRV_CHN_PRIORITY_0 = 0U, + EDMADRV_CHN_PRIORITY_1 = 1U, + EDMADRV_CHN_PRIORITY_2 = 2U, + EDMADRV_CHN_PRIORITY_3 = 3U, +#ifndef FEATURE_DMA_4_CH_PRIORITIES + EDMADRV_CHN_PRIORITY_4 = 4U, + EDMADRV_CHN_PRIORITY_5 = 5U, + EDMADRV_CHN_PRIORITY_6 = 6U, + EDMADRV_CHN_PRIORITY_7 = 7U, +#ifndef FEATURE_DMA_8_CH_PRIORITIES + EDMADRV_CHN_PRIORITY_8 = 8U, + EDMADRV_CHN_PRIORITY_9 = 9U, + EDMADRV_CHN_PRIORITY_10 = 10U, + EDMADRV_CHN_PRIORITY_11 = 11U, + EDMADRV_CHN_PRIORITY_12 = 12U, + EDMADRV_CHN_PRIORITY_13 = 13U, + EDMADRV_CHN_PRIORITY_14 = 14U, + EDMADRV_CHN_PRIORITY_15 = 15U, +#endif +#endif + EDMADRV_CHN_DEFAULT_PRIORITY = 255U +} EDmaDrv_ChannelPriorityType; + +/*! \brief eDMA channel interrupts. + */ +typedef enum +{ + EDMADRV_CHN_ERR_INT = 0U, /*!< Error interrupt */ + EDMADRV_CHN_HALF_MAJOR_LOOP_INT, /*!< Half major loop interrupt. */ + EDMADRV_CHN_MAJOR_LOOP_INT /*!< Complete major loop interrupt. */ +} EDmaDrv_ChannelInterruptType; + +/*! \brief eDMA channel arbitration mode used for selection among channels. + */ +typedef enum +{ + EDMADRV_ARBITRATION_FIXED_PRIORITY = 0U, /*!< Fixed Priority */ + EDMADRV_ARBITRATION_ROUND_ROBIN /*!< Round-Robin arbitration */ +} EDmaDrv_ArbitrationModeType; + +/*! \brief eDMA modulo configuration + */ +typedef enum +{ + EDMADRV_MODULO_OFF = 0U, + EDMADRV_MODULO_2B, + EDMADRV_MODULO_4B, + EDMADRV_MODULO_8B, + EDMADRV_MODULO_16B, + EDMADRV_MODULO_32B, + EDMADRV_MODULO_64B, + EDMADRV_MODULO_128B, + EDMADRV_MODULO_256B, + EDMADRV_MODULO_512B, + EDMADRV_MODULO_1KB, + EDMADRV_MODULO_2KB, + EDMADRV_MODULO_4KB +} EDmaDrv_ModuloType; + +/*! \brief eDMA transfer configuration + */ +typedef enum +{ + EDMADRV_TRANSFER_SIZE_1B = 0x0U, + EDMADRV_TRANSFER_SIZE_2B = 0x1U, + EDMADRV_TRANSFER_SIZE_4B = 0x2U, + EDMADRV_TRANSFER_SIZE_16B = 0x4U, + EDMADRV_TRANSFER_SIZE_32B = 0x5U +} EDmaDrv_TransferSizeType; + +/*! \brief eDMA loop transfer configuration. + * + * This structure configures the basic minor/major loop attributes. + */ +typedef struct _EDmaDrv_LoopTransferConfigType_ +{ + uint32_t majorLoopIterationCount; /*!< Number of major loop iterations. */ + bool srcOffsetEnable; /*!< Selects whether the minor loop offset is applied to the + source address upon minor loop completion. */ + bool dstOffsetEnable; /*!< Selects whether the minor loop offset is applied to the + destination address upon minor loop completion. */ + int32_t minorLoopOffset; /*!< Sign-extended offset applied to the source or destination address + to form the next-state value after the minor loop completes. */ + bool minorLoopChnLinkEnable; /*!< Enables channel-to-channel linking on minor loop complete. */ + uint8_t minorLoopChnLinkNumber; /*!< The number of the next channel to be started by DMA + engine when minor loop completes. */ + bool majorLoopChnLinkEnable; /*!< Enables channel-to-channel linking on major loop complete. */ + uint8_t majorLoopChnLinkNumber; /*!< The number of the next channel to be started by DMA + engine when major loop completes. */ +} EDmaDrv_LoopTransferConfigType; + +/*! \brief eDMA transfer size configuration. + * + * This structure configures the basic source/destination transfer attribute. + */ +typedef struct _EDmaDrv_TransferConfigType_ +{ + uint32_t srcAddr; /*!< Memory address pointing to the source data. */ + uint32_t destAddr; /*!< Memory address pointing to the destination data. */ + EDmaDrv_TransferSizeType srcDestTransferSize; /*!< Source/Destination data transfer size. */ + int16_t srcOffset; /*!< Sign-extended offset applied to the current source address + to form the next-state value as each source read/write + is completed. */ + int16_t destOffset; /*!< Sign-extended offset applied to the current destination + address to form the next-state value as each source + read/write is completed. */ + int32_t srcLastAddrAdjust; /*!< Last source address adjustment. */ + int32_t destLastAddrAdjust; /*!< Last destination address adjustment. Note here it is only + valid when scatter/gather feature is not enabled. */ + EDmaDrv_ModuloType srcModulo; /*!< Source address modulo. */ + EDmaDrv_ModuloType destModulo; /*!< Destination address modulo. */ + uint32_t minorByteTransferCount; /*!< Number of bytes to be transferred in each service request + of the channel. */ + bool scatterGatherEnable; /*!< Enable scatter gather feature. */ + uint32_t scatterGatherNextDescAddr; /*!< The address of the next descriptor to be used, when + scatter/gather feature is enabled. + Note: this value is not used when scatter/gather + feature is disabled. */ + bool interruptEnable; /*!< Enable the interrupt request when the major loop + count completes */ + bool hardClrDone; /*!< Enable Hard clear Done*/ + EDmaDrv_LoopTransferConfigType *loopTransferConfig; /*!< Pointer to loop transfer configuration structure + (defines minor/major loop attributes) + Note: this field is only used when minor loop mapping is + enabled from DMA configuration. */ +} EDmaDrv_TransferConfigType; + +typedef struct _EDmaDrv_SoftwareTcdType_ +{ + uint32_t SADDR; + int16_t SOFF; + uint16_t ATTR; + uint32_t NBYTES; + int32_t SLAST; + uint32_t DADDR; + int16_t DOFF; + uint16_t CITER; + int32_t DLAST_SGA; + uint16_t CSR; + uint16_t BITER; +} EDmaDrv_SoftwareTcdType; + +/*! \brief The user configuration structure for the eDMA driver. + * + * Use an instance of this structure with the EDmaDrv_Init() function. This allows the user to configure + * settings of the EDMA peripheral with a single function call. + */ +typedef struct _EDmaDrv_UserConfigType_ +{ + EDmaDrv_ChannelPriorityType channelPriority[EDMA_CHANNELS_INTERRUPT_LINES]; + EDmaDrv_ArbitrationModeType chnArbitration; /*!< eDMA channel arbitration. */ + bool haltOnError; /*!< Any error causes the HALT bit to set. Subsequently, all + service requests are ignored until the HALT bit is cleared. */ +} EDmaDrv_ModuleConfigType; + +/*! \brief Channel status for eDMA channel. + * + * A structure describing the eDMA channel status. The user can get the status by callback parameter + * or by calling EDmaDrv_getStatus() function. + */ +typedef enum +{ + DMA_CHN_NORMAL = 0U, /*!< eDMA channel normal state. */ + DMA_CHN_ERROR /*!< An error occurred in the eDMA channel. */ +} EDmaDrv_ChnStatusType; + +/*! \brief Definition for the eDMA channel callback function. + * + * Prototype for the callback function registered in the eDMA driver. + */ +typedef void (*EDmaDrv_CallBackType)(void *parameter, EDmaDrv_ChnStatusType status); + +/*! \brief Data structure for the eDMA channel state. + */ +typedef struct _DmaDrv_ChnStateType_ +{ + uint8_t chn; /*!< Channel number. */ + EDmaDrv_CallBackType callback; /*!< Callback function pointer for the eDMA channel. It will + be called at the eDMA channel complete and eDMA channel + error. */ + void *parameter; /*!< Parameter for the callback function pointer. */ + volatile EDmaDrv_ChnStatusType status; /*!< eDMA channel status. */ +} EDmaDrv_ChnStateType; + +/*! \brief Runtime state structure for the eDMA driver. + * + * This structure holds data that is used by the eDMA peripheral driver to manage + * multi eDMA channels. + * The user passes the memory for this run-time state structure and the eDMA + * driver populates the members. + */ +typedef struct _EDmaDrv_StateType_ +{ + EDmaDrv_ChnStateType *volatile chnState[(uint32_t)EDMA_CHANNELS]; /*!< Pointer array storing channel state. */ +} EDmaDrv_StateType; + +/*! \brief Definition of configuration of Dma driver + */ +typedef struct _EDmaDrv_ChannelConfigType_ +{ + uint8_t chnConfig; /*!< eDMA channel number */ + EDmaDrv_ChannelPriorityType channelPriority; /*!< eDMA channel priority - only used when channel + arbitration mode is 'Fixed priority'. */ + EDma_RequestSourceType source; /*!< Selects the source of the DMA request for this channel */ + EDmaDrv_CallBackType callback; /*!< Callback that will be registered for this channel */ + void *callbackParam; /*!< Parameter passed to the channel callback */ + bool enableTrigger; /*!< Enables the periodic trigger capability for the DMA channel. */ +} EDmaDrv_ChannelConfigType; + +/*! \brief Transfer type for the DMA transfer. + */ +typedef enum +{ + EDMADRV_TRANSFER_PERIPH2MEM = 0U, /*!< Transfer from peripheral to memory */ + EDMADRV_TRANSFER_MEM2PERIPH, /*!< Transfer from memory to peripheral */ + EDMADRV_TRANSFER_MEM2MEM, /*!< Transfer from memory to memory */ + EDMADRV_TRANSFER_PERIPH2PERIPH /*!< Transfer from peripheral to peripheral */ +} EDmaDrv_TransferType; + +/*! \brief Data structure for configuring a discrete memory transfer. + */ +typedef struct _EDmaDrv_ScatterGatherListType_ +{ + uint32_t address; /*!< Address of buffer. */ + uint32_t length; /*!< Length of buffer. */ + EDmaDrv_TransferType type; /*!< Type of the DMA transfer */ +} EDmaDrv_ScatterGatherListType; + +/* Forward declaration of DMA register */ +struct _EDmaRegType_; + +/* Forward declaration of DMAMUX register */ +struct _DmamuxRegType_; + +/*! \brief The definition of DMA driver class + */ +typedef struct _EDmaDrvType_ +{ + EDmaDrv_StateType *dmaState; + struct _EDmaRegType_ *edmaReg; + struct _DmamuxRegType_ *dmamuxReg; +} EDmaDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ +/*! \brief Initializes the eDMA driver module + * + * This function initializes eDMA driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] dmaReg : pointer to eDMA register instance + * \param[in] dmaReg : pointer to DMAMUX register instance + */ +extern void EDmaDrv_Init(EDmaDrvType *obj, struct _EDmaRegType_ *dmaReg, struct _DmamuxRegType_ *dmamuxReg); + +/*! \brief Configures the eDMA module from a module configuration structure + * + * This function configures the eDMA module from a module configuration structure + * + * \param[out] moduleConfig : pointer to configuration structure + */ +extern void EDmaDrv_GetDefaultConfigure(EDmaDrv_ModuleConfigType *moduleConfig); + +/*! \brief Configures the eDMA module from a channel configuration structure + * + * This function configures the eDMA module from a channel configuration structure + * + * \param[out] channelConfig : pointer to configuration structure + */ +extern void EDmaDrv_GetDefaultChannelConfigure(EDmaDrv_ChannelConfigType *channelConfig); + +/*! \brief Configure the eDMA module. + * + * This function initializes the run-time state structure to provide the eDMA channel allocation + * release, protect, and track the state for channels. This function also resets the eDMA modules, + * initializes the module to user-defined settings and default settings. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] edmaState: The pointer to the eDMA peripheral driver state structure. The user passes + * the memory for this run-time state structure and the eDMA peripheral driver populates the + * members. This run-time state structure keeps track of the eDMA channels status. The memory must + * be kept valid before calling the EDmaDrv_DeInit. + * \param[in] moduleConfig: User configuration structure for eDMA peripheral drivers. The user populates the + * members of this structure and passes the pointer of this structure into the function. + * + * \return STATUS_ERROR or STATUS_SUCCESS. + */ +extern EDmaDrv_Status EDmaDrv_Configure(EDmaDrvType *obj, EDmaDrv_StateType *edmaState, const EDmaDrv_ModuleConfigType *moduleConfig); + +/*! \brief Configure the eDMA module. + * + * This function initializes the run-time state structure to provide the eDMA channel allocation + * release, protect, and track the state for channels. This function also resets the eDMA modules, + * initializes the module to user-defined settings and default settings. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] chnStateArray : Array of pointers to run-time state structures for eDMA channels; + * will populate the state structures inside the eDMA driver state structure. + * \param[in] chnConfig : pointers to channel initialization structures. + * + * \return STATUS_ERROR or STATUS_SUCCESS. + */ +extern EDmaDrv_Status EDmaDrv_ConfigureChannel(EDmaDrvType *obj, + EDmaDrv_ChnStateType *const chnStateArray[], + const EDmaDrv_ChannelConfigType *const chnConfig); + +/*! \brief De-initializes the eDMA module. + * + * This function resets the eDMA module to reset state and disables the interrupt to the core. + * + * \param[in] obj : pointer to eDMA driver instance + * \return STATUS_ERROR or STATUS_SUCCESS. + */ +extern EDmaDrv_Status EDmaDrv_Deinit(EDmaDrvType *obj); + +/*! \brief Initializes an eDMA channel. + * + * This function initializes the run-time state structure for a eDMA channel, based on user + * configuration. It will request the channel, set up the channel priority and install the + * callback. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] edmaChannelState : Pointer to the eDMA channel state structure. The user passes + * the memory for this run-time state structure and the eDMA peripheral driver populates the + * members. This run-time state structure keeps track of the eDMA channel status. The memory must + * be kept valid before calling the EDmaDrv_ReleaseChannel. + * \param[in] edmaChannelConfig : User configuration structure for eDMA channel. The user populates the + * members of this structure and passes the pointer of this structure into the function. + * + * \return STATUS_ERROR or STATUS_SUCCESS. + */ +extern EDmaDrv_Status EDmaDrv_ChannelInit(EDmaDrvType *obj, + EDmaDrv_ChnStateType *edmaChannelState, + const EDmaDrv_ChannelConfigType *edmaChannelConfig); + +/*! \brief Releases an eDMA channel. + * + * This function stops the eDMA channel and disables the interrupt of this channel. The channel state + * structure can be released after this function is called. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * + * \return STATUS_ERROR or STATUS_SUCCESS. + */ +extern EDmaDrv_Status EDmaDrv_ReleaseChannel(EDmaDrvType *obj, uint8_t channel); + +/*! \brief Copies the channel configuration to the TCD registers. + * + * \param[in] channel : eDMA channel number + * \param[in] tcd Pointer to the channel configuration structure. + */ +void EDmaDrv_PushConfigToReg(EDmaDrvType *obj, uint8_t channel, const EDmaDrv_TransferConfigType *tcd); + +/*! \brief Copies the channel configuration to the software TCD structure. + * + * This function copies the properties from the channel configuration to the software TCD structure; the address + * of the software TCD can be used to enable scatter/gather operation (pointer to the next TCD). + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] config : Pointer to the channel configuration structure. + * \param[in] stcd : Pointer to the software TCD structure. + */ +void EDmaDrv_PushConfigToSTcd(const EDmaDrv_TransferConfigType *config, EDmaDrv_SoftwareTcdType *stcd); + +/*! \brief Configures a simple single block data transfer with DMA. + * + * This function configures the descriptor for a single block transfer. + * The function considers contiguous memory blocks, thus it configures the TCD + * source/destination offset fields to cover the data buffer without gaps, + * according to "transferSize" parameter (the offset is equal to the number of + * bytes transferred in a source read/destination write). + * + * NOTE: For memory-to-peripheral or peripheral-to-memory transfers, make sure + * the transfer size is equal to the data buffer size of the peripheral used, + * otherwise only truncated chunks of data may be transferred (e.g. for a + * communication IP with an 8-bit data register the transfer size should be 1B, + * whereas for a 32-bit data register, the transfer size should be 4B). The + * rationale of this constraint is that, on the peripheral side, the address + * offset is set to zero, allowing to read/write data from/to the peripheral + * in a single source read/destination write operation. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] type : Transfer type (M->M, P->M, M->P, P->P). + * \param[in] srcAddr : A source register address or a source memory address. + * \param[in] destAddr : A destination register address or a destination memory address. + * \param[in] transferSize : The number of bytes to be transferred on every DMA write/read. + * Source/Dest share the same write/read size. + * \param[in] dataBufferSize : The total number of bytes to be transferred. + * + * \return STATUS_ERROR or STATUS_SUCCESS + */ +extern EDmaDrv_Status EDmaDrv_ConfigSingleBlockTransfer(EDmaDrvType *obj, + uint8_t channel, + EDmaDrv_TransferType type, + uint32_t srcAddr, + uint32_t destAddr, + EDmaDrv_TransferSizeType transferSize, + uint32_t dataBufferSize, + bool enableHwClrDone); + +/*! \brief Configures a multiple block data transfer with DMA. + * + * This function configures the descriptor for a multi-block transfer. + * The function considers contiguous memory blocks, thus it configures the TCD + * source/destination offset fields to cover the data buffer without gaps, + * according to "transferSize" parameter (the offset is equal to the number of + * bytes transferred in a source read/destination write). The buffer is divided + * in multiple block, each block being transferred upon a single DMA request. + * + * NOTE: For transfers to/from peripherals, make sure + * the transfer size is equal to the data buffer size of the peripheral used, + * otherwise only truncated chunks of data may be transferred (e.g. for a + * communication IP with an 8-bit data register the transfer size should be 1B, + * whereas for a 32-bit data register, the transfer size should be 4B). The + * rationale of this constraint is that, on the peripheral side, the address + * offset is set to zero, allowing to read/write data from/to the peripheral + * in a single source read/destination write operation. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] type : Transfer type (M->M, P->M, M->P, P->P). + * \param[in] srcAddr : A source register address or a source memory address. + * \param[in] destAddr : A destination register address or a destination memory address. + * \param[in] transferSize : The number of bytes to be transferred on every DMA write/read. + * Source/Dest share the same write/read size. + * \param[in] blockSize : The total number of bytes inside a block. + * \param[in] blockCount : The total number of data blocks (one block is transferred upon a DMA request). + * \param[in] disableReqOnCompletion : This parameter specifies whether the DMA channel should + * be disabled when the transfer is complete (further requests will remain untreated). + * + * \return STATUS_ERROR or STATUS_SUCCESS + */ +extern EDmaDrv_Status EDmaDrv_ConfigMultiBlockTransfer(EDmaDrvType *obj, + uint8_t channel, + EDmaDrv_TransferType type, + uint32_t srcAddr, + uint32_t destAddr, + EDmaDrv_TransferSizeType transferSize, + uint32_t blockSize, + uint32_t blockCount, + bool enableHwClrDone, + bool disableReqOnCompletion); + +/*! \brief Configures the DMA transfer in loop mode. + * + * This function configures the DMA transfer in a loop chain. The user passes a block of memory into this + * function that configures the loop transfer properties (minor/major loop count, address offsets, channel linking). + * The DMA driver copies the configuration to TCD registers, only when the loop properties are set up correctly + * and minor loop mapping is enabled for the eDMA module. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] transferConfig : Pointer to the transfer configuration strucutre; this structure defines fields for setting + * up the basic transfer and also a pointer to a memory strucure that defines the loop chain properties (minor/major). + * + * \return STATUS_ERROR or STATUS_SUCCESS + */ +extern EDmaDrv_Status EDmaDrv_ConfigLoopTransfer(EDmaDrvType *obj, uint8_t channel, const EDmaDrv_TransferConfigType *transferConfig); + +/*! \brief Configures the DMA transfer in a scatter-gather mode. + * + * This function configures the descriptors into a single-ended chain. The user passes blocks of memory into + * this function. The interrupt is triggered only when the last memory block is completed. The memory block + * information is passed with the edma_scatter_gather_list_t data structure, which can tell + * the memory address and length. + * The DMA driver configures the descriptor for each memory block, transfers the descriptor from the + * first one to the last one, and stops. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] stcd : Array of empty software TCD structures. The user must prepare this memory block. We don't need a + * software TCD structure for the first descriptor, since the configuration is pushed directly to registers.The "stcd" + * buffer must align with 32 bytes; if not, an error occurs in the eDMA driver. Thus, the required + * memory size for "stcd" is equal to tcdCount * size_of(edma_software_tcd_t) - 1; the driver will take + * care of the memory alignment if the provided memory buffer is big enough. For proper allocation of the + * "stcd" buffer it is recommended to use STCD_SIZE macro. + * \param[in] transferSize : The number of bytes to be transferred on every DMA write/read. + * \param[in] bytesOnEachRequest Bytes to be transferred in each DMA request. + * \param[in] srcList : Data structure storing the address, length and type of transfer (M->M, M->P, P->M, P->P) for + * the bytes to be transferred for source memory blocks. If the source memory is peripheral, the length + * is not used. + * \param[in] destList : Data structure storing the address, length and type of transfer (M->M, M->P, P->M, P->P) for + * the bytes to be transferred for destination memory blocks. In the memory-to-memory transfer mode, the + * user must ensure that the length of the destination scatter gather list is equal to the source + * scatter gather list. If the destination memory is a peripheral register, the length is not used. + * \param[in] tcdCount : The number of TCD memory blocks contained in the scatter gather list. + * + * \return STATUS_ERROR or STATUS_SUCCESS + */ +extern EDmaDrv_Status EDmaDrv_ConfigScatterGatherTransfer(EDmaDrvType *obj, + uint8_t channel, + EDmaDrv_SoftwareTcdType *stcd, + EDmaDrv_TransferSizeType transferSize, + uint32_t bytesOnEachRequest, + bool hardClrDone, + const EDmaDrv_ScatterGatherListType *srcList, + const EDmaDrv_ScatterGatherListType *destList, + const EDmaDrv_LoopTransferConfigType *loopTransferList, + uint8_t tcdCount); + +/*! \brief Cancel the running transfer. + * + * This function cancels the current transfer, optionally signalling an error. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] bool : error If true, an error will be logged for the current transfer. + */ +void EDmaDrv_CancelTransfer(EDmaDrvType *obj, bool error); + +/*! \brief Starts an eDMA channel. + * + * This function enables the eDMA channel DMA request. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * + * \return STATUS_ERROR or STATUS_SUCCESS. + */ +extern EDmaDrv_Status EDmaDrv_StartChannel(EDmaDrvType *obj, uint8_t channel); + +/*! \brief Stops the eDMA channel. + * + * This function disables the eDMA channel DMA request. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * + * \return STATUS_ERROR or STATUS_SUCCESS. + */ +extern EDmaDrv_Status EDmaDrv_StopChannel(EDmaDrvType *obj, uint8_t channel); + +/*! \brief Configures the DMA request for the eDMA channel. + * + * Selects which DMA source is routed to a DMA channel. The DMA sources are defined in the file + * _Features.h + * Configures the periodic trigger capability for the triggered DMA channel. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] request : DMA request source. + * \param[in] enableTrigger : DMA channel periodic trigger. + * + * \return STATUS_SUCCESS or STATUS_UNSUPPORTED. + */ +extern EDmaDrv_Status EDmaDrv_SetChannelRequestAndTrigger(EDmaDrvType *obj, uint8_t channel, uint8_t request, bool enableTrigger); + +/*! \brief Clears all registers to 0 for the channel's TCD. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + */ +extern void EDmaDrv_ClearTcd(EDmaDrvType *obj, uint8_t channel); + +/*! \brief Configures the source address for the eDMA channel. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] address : The pointer to the source memory address. + */ +extern void EDmaDrv_SetSrcAddr(EDmaDrvType *obj, uint8_t channel, uint32_t address); + +/*! \brief Configures the source address signed offset for the eDMA channel. + * + * Sign-extended offset applied to the current source address to form the next-state value as each + * source read is complete. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] offset : Signed-offset for source address. + */ +extern void EDmaDrv_SetSrcOffset(EDmaDrvType *obj, uint8_t channel, int16_t offset); + +/*! \brief Configures the source data chunk size (transferred in a read sequence). + * + * Source data read transfer size (1/2/4/16/32 bytes). + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] size : Source transfer size. + */ +extern void EDmaDrv_SetSrcReadDestWriteChunkSize(EDmaDrvType *obj, uint8_t channel, EDmaDrv_TransferSizeType size); + +/*! \brief Configures the source address last adjustment. + * + * Adjustment value added to the source address at the completion of the major iteration count. This + * value can be applied to restore the source address to the initial value, or adjust the address to + * reference the next data structure. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] adjust : Adjustment value. + */ +extern void EDmaDrv_SetSrcLastAddrAdjustment(EDmaDrvType *obj, uint8_t channel, int32_t adjust); + +/*! \brief Configures the destination address for the eDMA channel. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] address : The pointer to the destination memory address. + */ +extern void EDmaDrv_SetDestAddr(EDmaDrvType *obj, uint8_t channel, uint32_t address); + +/*! \brief Configures the destination address signed offset for the eDMA channel. + * + * Sign-extended offset applied to the current destination address to form the next-state value as each + * destination write is complete. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] offset : signed-offset + */ +extern void EDmaDrv_SetDestOffset(EDmaDrvType *obj, uint8_t channel, int16_t offset); + +/*! \brief Configures the destination address last adjustment. + * + * Adjustment value added to the destination address at the completion of the major iteration count. This + * value can be applied to restore the destination address to the initial value, or adjust the address to + * reference the next data structure. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] adjust : Adjustment value. + */ +extern void EDmaDrv_SetDestLastAddrAdjustment(EDmaDrvType *obj, uint8_t channel, int32_t adjust); + +/*! \brief Configures the number of bytes to be transferred in each service request of the channel. + * + * Sets the number of bytes to be transferred each time a request is received (one major loop iteration). + * This number needs to be a multiple of the source/destination transfer size, as the data block will be + * transferred within multiple read/write sequences (minor loops). + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] nbytes : Number of bytes to be transferred in each service request of the channel + */ +extern void EDmaDrv_SetMinorLoopBlockSize(EDmaDrvType *obj, uint8_t channel, uint32_t nbytes); + +/*! \brief Configures the number of major loop iterations. + * + * Sets the number of major loop iterations; each major loop iteration will be served upon a request + * for the current channel, transferring the data block configured for the minor loop (NBYTES). + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] majorLoopCount : Number of major loop iterations. + */ +extern void EDmaDrv_SetMajorLoopIterationCount(EDmaDrvType *obj, uint8_t channel, uint32_t majorLoopCount); + +/*! \brief Returns the remaining major loop iteration count. + * + * Gets the number minor loops yet to be triggered (major loop iterations). + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \return number of major loop iterations yet to be triggered + */ +extern uint32_t EDmaDrv_GetRemainingMajorIterationsCount(EDmaDrvType *obj, uint8_t channel); + +/*! \brief Configures the memory address of the next TCD, in scatter/gather mode. + * + * This function configures the address of the next TCD to be loaded form memory, when scatter/gather + * feature is enabled. This address points to the beginning of a 0-modulo-32 byte region containing + * the next transfer TCD to be loaded into this channel. The channel reload is performed as the + * major iteration count completes. The scatter/gather address must be 0-modulo-32-byte. Otherwise, + * a configuration error is reported. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] nextTCDAddr : The address of the next TCD to be linked to this TCD. + */ +extern void EDmaDrv_SetScatterGatherLink(EDmaDrvType *obj, uint8_t channel, uint32_t nextTCDAddr); + +/*! \brief Disables/Enables the DMA request after the major loop completes for the TCD. + * + * If disabled, the eDMA hardware automatically clears the corresponding DMA request when the + * current major iteration count reaches zero. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] disable : Disable (true)/Enable (false) DMA request after TCD complete. + */ +extern void EDmaDrv_DisableRequestsOnTransferComplete(EDmaDrvType *obj, uint8_t channel, bool disable); + +/*! \brief Disables/Enables the channel interrupt requests. + * + * This function enables/disables error, half major loop and complete major loop interrupts + * for the current channel. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + * \param[in] interrupt : Interrupt event (error/half major loop/complete major loop). + * \param[in] enable : Enable (true)/Disable (false) interrupts for the current channel. + */ +extern void EDmaDrv_ConfigureInterrupt(EDmaDrvType *obj, uint8_t channel, EDmaDrv_ChannelInterruptType intSrc, bool enable); + +/*! \brief Triggers a sw request for the current channel. + * + * This function starts a transfer using the current channel (sw request). + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number + */ +extern void EDmaDrv_TriggerSwRequest(EDmaDrvType *obj, uint8_t channel); + +/*! \brief Registers the callback function and the parameter for eDMA channel. + * + * This function registers the callback function and the parameter into the eDMA channel state structure. + * The callback function is called when the channel is complete or a channel error occurs. The eDMA + * driver passes the channel status to this callback function to indicate whether it is caused by the + * channel complete event or the channel error event. + * + * To un-register the callback function, set the callback function to "NULL" and call this + * function. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number. + * \param[in] callback : The pointer to the callback function. + * \param[in] parameter : The pointer to the callback function's parameter. + * + * \return STATUS_ERROR or STATUS_SUCCESS. + */ +extern EDmaDrv_Status EDmaDrv_InstallCallback(EDmaDrvType *obj, uint8_t channel, EDmaDrv_CallBackType callback, void *parameter); + +/*! \brief Gets the eDMA channel status. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number. + * + * \return Channel status. + */ +extern EDmaDrv_ChnStatusType EDmaDrv_GetChannelStatus(EDmaDrvType *obj, uint8_t channel); + +/*! \brief DMA channel interrupt handler, implemented in driver c file. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number. + */ +extern void EDmaDrv_IRQHandler(EDmaDrvType *obj, uint8_t Channel); + +/*! \brief DMA error interrupt handler, implemented in driver c file. + * + * \param[in] obj : pointer to eDMA driver instance + * \param[in] channel : eDMA channel number. + */ +extern void EDmaDrv_ErrorIRQHandler(EDmaDrvType *obj, uint8_t channel); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _DMA_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/eim/eim_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/eim/eim_drv.c new file mode 100644 index 0000000..b3fb7dc --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/eim/eim_drv.c @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "eim_drv.h" +#include "eim_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +#define EIM_LENGTH_CHK (8) +#define EIM_LENGTH_DATA (32) +#define EIM_LENGTH_ADDR (32) + + +uint8_t arr_data2reg_chk[EIM_LENGTH_CHK] = { + 0, 1, 3, 7, 15, 31, /* REG_DATA */ + 31, /* REG_ADDR */ + 7 /* REG_CHK */ +}; + +uint8_t arr_data2reg_data[EIM_LENGTH_DATA] = { + 2, 4, 5, 6, 8, 9, 10, 11, 12, /* REG_DATA */ + 13, 14, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, + 0, 1, 2, 3, 4, 5 /* REG_ADDR */ + +}; + +uint8_t arr_data2reg_addr[EIM_LENGTH_ADDR] = { + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* REG_ADDR */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, + 0, 1, 2, 3, 4, 5, 6 /* REG_CHK */ +}; + + + +uint8_t arr_reg2data_chk[EIM_LENGTH_CHK] = { + 25, 26, 27, 28, 29, 30, 31, /* REG_ADDR */ + 7 /* REG_CHK */ +}; + +uint8_t arr_reg2data_data[EIM_LENGTH_DATA] = { + 0, 1, /* REG_CHK */ + 0, /* REG_DATA */ + 2, /* REG_CHK */ + 1, 2, 3, /* REG_DATA */ + 3, /* REG_CHK */ + 4, 5, 6, 7, 8, 9, 10, /* REG_DATA */ + 4, /* REG_CHK */ + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, /* REG_DATA */ + 5 /* REG_CHK */ + +}; + +uint8_t arr_reg2data_addr[EIM_LENGTH_ADDR] = { + 26, 27, 28, 29, 30, 31, /* REG_DATA */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* REG_ADDR */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, + 6 /* REG_CHK */ +}; + +static void EimDrv_RegToDataConvert(EimDrv_SramType *sramType, EimDrv_SramType *sramType_temp) +{ + uint8_t i; + uint8_t length = EIM_LENGTH_CHK; + + for (i = 0; i < length; i++) + { + if ((sramType_temp->data_h >> i) & 0x01) + { + if ( i <= 6 ) sramType->data_m |= 1 << arr_reg2data_chk[i]; + if (i > 6 && i < length ) sramType->data_h |= 1 << arr_reg2data_chk[i]; + } + } + + length = EIM_LENGTH_DATA; + for (i = 0; i < length; i++) + { + if ((sramType_temp->data_l >> i) & 0x01) + { + if (i <= 1 ) sramType->data_h |= 1 << arr_reg2data_data[i]; + if (i == 2 ) sramType->data_l |= 1 << arr_reg2data_data[i]; + if (i == 3 ) sramType->data_h |= 1 << arr_reg2data_data[i]; + if (i > 3 && i <= 6 ) sramType->data_l |= 1 << arr_reg2data_data[i]; + if (i == 7 ) sramType->data_h |= 1 << arr_reg2data_data[i]; + if (i > 7 && i <= 14 ) sramType->data_l |= 1 << arr_reg2data_data[i]; + if (i == 15 ) sramType->data_h |= 1 << arr_reg2data_data[i]; + if (i > 16 && i <= 30 ) sramType->data_l |= 1 << arr_reg2data_data[i]; + if (i == 31 ) sramType->data_h |= 1 << arr_reg2data_data[i]; + } + } + + length = EIM_LENGTH_ADDR; + for (i = 0; i < length; i++) + { + if ((sramType_temp->data_m >> i) & 0x01) + { + if (i <= 5 ) sramType->data_l |= 1 << arr_reg2data_addr[i]; + if (i > 5 && i <= 30 ) sramType->data_m |= 1 << arr_reg2data_addr[i]; + if (i == 31 ) sramType->data_h |= 1 << arr_reg2data_addr[i]; + } + } +} + +static void EimDrv_DataToRegConvert(EimDrv_SramType *sramType, EimDrv_SramType *sramType_temp) +{ + uint8_t i; + uint8_t length = EIM_LENGTH_CHK; + + for (i = 0; i < length; i++) + { + if ((sramType->data_h >> i) & 0x01) + { + if (i <= 5 ) sramType_temp->data_l |= 1 << arr_data2reg_chk[i]; + if (i > 5 && i <= 6 ) sramType_temp->data_m |= 1 << arr_data2reg_chk[i]; + if (i > 6 && i < length ) sramType_temp->data_h |= 1 << arr_data2reg_chk[i]; + } + } + + length = EIM_LENGTH_DATA; + for (i = 0; i < length; i++) + { + if ((sramType->data_l >> i) & 0x01) + { + if (i <= 26 ) sramType_temp->data_l |= 1 << arr_data2reg_data[i]; + if (i > 26 && i < length ) sramType_temp->data_m |= 1 << arr_data2reg_data[i]; + } + } + + length = EIM_LENGTH_ADDR; + for (i = 0; i < length; i++) + { + if ((sramType->data_m >> i) & 0x01) + { + if (i <= 24 ) sramType_temp->data_m |= 1 << arr_data2reg_addr[i]; + if (i > 24 && i < length ) sramType_temp->data_h |= 1 << arr_data2reg_addr[i]; + } + } +} + +void EimDrv_Init(EimDrvType *obj, struct _EimRegType_ *eimReg) +{ + obj->reg = eimReg; +} + +void EimDrv_GetDefaultConfig(EimDrv_ChnCfgType *userConfig) +{ + /* Get Error in global enable status, default: false */ + userConfig->globalEnable = false; + + /* Get Error in channel num enable status, default: false */ + userConfig->chnNumStatus = false; + + /* Get Error in sram data high, default: 0 */ + userConfig->accSramCfg.data_h = 0; + /* Get Error in sram data middle, default: 0 */ + userConfig->accSramCfg.data_m = 0; + /* Get Error in sram data low, default: 0 */ + userConfig->accSramCfg.data_l = 0; +} + +bool EimDrv_GetChnGlobalEnable(EimDrvType *obj) +{ + /* Get Error in global enable */ + return EimReg_GetCrGeiEn(obj->reg); +} + +void EimDrv_EnableGlobalChn(EimDrvType *obj, bool enable) +{ + /* Config Error in global enable */ + EimReg_SetCrGeiEn(obj->reg, (uint8_t)enable); +} + +bool EimDrv_GetChnNumEnable(EimDrvType *obj) +{ + /* Get Error in channel num enable */ + return (bool)EimReg_GetChEnCh0(obj->reg); +} + +void EimDrv_EnableChannel(EimDrvType *obj, bool enable) +{ + /* Set Error in channel num enable */ + EimReg_SetChEnCh0(obj->reg, (uint8_t)enable); +} + +void EimDrv_GetSramErrInStatus(EimDrvType *obj, EimDrv_SramType *sramType) +{ + EimDrv_SramType sramType_temp = {0}; + + /* get error in access sram data high */ + sramType_temp.data_h = EimReg_GetCh0DataH(obj->reg); + /* get error in access sram data middle */ + sramType_temp.data_m = EimReg_GetCh0DataM(obj->reg); + /* get error in access sram low */ + sramType_temp.data_l = EimReg_GetCh0DataL(obj->reg); + + EimDrv_RegToDataConvert(sramType, &sramType_temp); +} + +void EimDrv_SetSramErrInStatus(EimDrvType *obj, EimDrv_SramType *sramType) +{ + EimDrv_SramType sramType_temp = {0}; + + EimDrv_DataToRegConvert(sramType, &sramType_temp); + + /* set error in access sram data high */ + EimReg_SetCh0DataH(obj->reg, sramType_temp.data_h); + /* set error in access sram data middle */ + EimReg_SetCh0DataM(obj->reg, sramType_temp.data_m); + /* set error in access sram low */ + EimReg_SetCh0DataL(obj->reg, sramType_temp.data_l); +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/eim/eim_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/eim/eim_drv.h new file mode 100644 index 0000000..0f3cdea --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/eim/eim_drv.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _EIM_DRV_H_ +#define _EIM_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of EIM + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup eim_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/* Forward declaration of related register */ +struct _EimRegType_; + +/*! \brief The definition of EIM driver class + */ +typedef struct _EimDrvType_ +{ + struct _EimRegType_ *reg; /*!< pointer to EIM register */ +} EimDrvType; + +/*! \brief struct of EIM Sram channel control + */ +typedef struct _EimDrv_ErrInSramType_ +{ + uint8_t data_h; /*!< Access Sram Error in data high */ + uint32_t data_m; /*!< Access Sram Error in data middle */ + uint32_t data_l; /*!< Access Sram Error in data low */ +} EimDrv_SramType; + +/*! \brief struct of EIM Config + */ +typedef struct _EimDrv_ChnCfgType_ +{ + bool globalEnable; /*!< Eim global enable status */ + bool chnNumStatus; /*!< Eim channel num enable status */ + EimDrv_SramType accSramCfg; /*!< Access Sram Error in config */ +} EimDrv_ChnCfgType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the EIM driver module + * + * This function initializes EIM driver by setting the register + * instances to it. + * + * \param[in] obj : pointer to EIM driver instance + * \param[in] eimReg : pointer to EIM register instance + */ +extern void EimDrv_Init(EimDrvType *obj, struct _EimRegType_ *eimReg); + +/*! \brief Get EIM Default config paramter + * + * This function get EIM config paramter. + * + * \param[in] userConfig : pointer to default parameter + */ +extern void EimDrv_GetDefaultConfig(EimDrv_ChnCfgType *userConfig); + +/*! \brief Get EIM Global Channel Enable Status + * + * This function get global Channel enable status. + * + * \param[in] obj : pointer to EIM driver instance + */ +extern bool EimDrv_GetChnGlobalEnable(EimDrvType *obj); + +/*! \brief Set EIM Global Channel Enable Status + * + * This function set global Channel enable status. + * + * \param[in] obj : pointer to EIM driver instance + * \param[in] enable : + * - true : enable global channel + * - false : disable global channel + * + */ +extern void EimDrv_EnableGlobalChn(EimDrvType *obj, bool enable); + +/*! \brief Get EIM Channel Number Enable Status + * + * This function get global Channel number enable status. + * + * \param[in] obj : pointer to EIM driver instance + */ +extern bool EimDrv_GetChnNumEnable(EimDrvType *obj); + +/*! \brief Set EIM Channel Number Enable Status + * + * This function set global Channel number enable status. + * + * \param[in] obj : pointer to EIM driver instance + * \param[in] chnNum : select the channel set status + * \param[in] enable : + * - true : enable selected channel + * - false : disable selected channel + */ +extern void EimDrv_EnableChannel(EimDrvType *obj, bool enable); + +/*! \brief Get Access Sram EIM Config + * + * This function get access sram EIM config parameter + * + * \param[in] obj : pointer to EIM driver instance + * \param[in] sramType : pointer to get access sram paramter chk/data/addr + */ +extern void EimDrv_GetSramErrInStatus(EimDrvType *obj, EimDrv_SramType *sramType); + +/*! \brief Set Access Sram EIM Config + * + * This function set access sram EIM config parameter + * + * \param[in] obj : pointer to EIM driver instance + * \param[in] sramType : pointer to set access sram paramter chk/data/addr + */ +extern void EimDrv_SetSramErrInStatus(EimDrvType *obj, EimDrv_SramType *sramType); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _EIM_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/erm/erm_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/erm/erm_drv.c new file mode 100644 index 0000000..d241d62 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/erm/erm_drv.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "erm_drv.h" +#include "erm_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void ErmDrv_Init(ErmDrvType *obj, struct _ErmRegType_ *ermReg) +{ + obj->reg = ermReg; +} + +void ErmDrv_GetDefaultConfig(ErmDrv_ChnErrConfigType *userConfig) +{ + uint8_t chnNum; + uint8_t ctrlChnNum; + + for(chnNum = 0; chnNum < ERMDRV_CH_TOTAL_NUM; chnNum++) + { + /* ERM channel Irq enable, default: false */ + userConfig->chnIrq[chnNum] = false; + /* ERM channel error status, default: false */ + userConfig->chnEvent[chnNum] = false; + } + + for(ctrlChnNum = 0; ctrlChnNum < ERMDRV_CH_CTRL_TOTAL_NUM; ctrlChnNum++) + { + /* ERM channel 0~3 control error address, default: 0 */ + userConfig->chnStatus[ctrlChnNum].errAddr = 0; + /* ERM channel 0~3 control error position, default: 0 */ + userConfig->chnStatus[ctrlChnNum].errPos = 0; + /* ERM channel 0~3 control recover error num, default: 0 */ + userConfig->chnStatus[ctrlChnNum].errRecoverNum = 0; + } +} + +void ErmDrv_SetChnErrIrqEnable(ErmDrvType *obj, ErmDrv_ChnNumType chnNum, bool enable) +{ + switch(chnNum) + { + case ERMDRV_CH0_RECOVER_SRAM_IRQ: + /* set ERM enable SRAM single bit recover channel */ + ErmReg_SetCr0Escie0(obj->reg, (uint8_t)enable); + break; + case ERMDRV_CH0_NONRECOVER_SRAM_IRQ: + /* set ERM enable SRAM multi bits non-recover channel */ + ErmReg_SetCr0Encie0(obj->reg, (uint8_t)enable); + break; + case ERMDRV_CH1_RECOVER_FTFC_IRQ: + /* set ERM enable FTFC single bit recover channel */ + ErmReg_SetCr0Escie1(obj->reg, (uint8_t)enable); + break; + case ERMDRV_CH1_NONRECOVER_FTFC_IRQ: + /* set ERM enable FTFC multi bits non-recover channel */ + ErmReg_SetCr0Encie1(obj->reg, (uint8_t)enable); + break; + default: + break; + } +} + +bool ErmDrv_GetChnErrIrqEnable(ErmDrvType *obj, ErmDrv_ChnNumType chnNum) +{ + switch(chnNum) + { + case ERMDRV_CH0_RECOVER_SRAM_IRQ: + /* get ERM enable SRAM single bit recover channel status */ + return (bool)ErmReg_GetCr0Escie0(obj->reg); + case ERMDRV_CH0_NONRECOVER_SRAM_IRQ: + /* get ERM enable SRAM multi bits non-recover channel status */ + return (bool)ErmReg_GetCr0Encie0(obj->reg); + case ERMDRV_CH1_RECOVER_FTFC_IRQ: + /* get ERM enable FTFC single bit recover channel status */ + return (bool)ErmReg_GetCr0Escie1(obj->reg); + case ERMDRV_CH1_NONRECOVER_FTFC_IRQ: + /* get ERM enable FTFC multi bits non-recover channel status */ + return (bool)ErmReg_GetCr0Encie1(obj->reg); + default: + return ERMDRV_CH_TOTAL_NUM; + } +} + +bool ErmDrv_GetChnErrInfoStatus(ErmDrvType *obj, ErmDrv_ChnNumType chnNum) +{ + switch(chnNum) + { + case ERMDRV_CH0_RECOVER_SRAM_IRQ: + /* get ERM enable SRAM single bit recover channel status */ + return (bool)ErmReg_GetSrSbc0(obj->reg); + case ERMDRV_CH0_NONRECOVER_SRAM_IRQ: + /* get ERM enable SRAM multi bits non-recover channel status */ + return (bool)ErmReg_GetSrNce0(obj->reg); + case ERMDRV_CH1_RECOVER_FTFC_IRQ: + /* get ERM enable FTFC single bit recover channel status */ + return (bool)ErmReg_GetSrSbc1(obj->reg); + case ERMDRV_CH1_NONRECOVER_FTFC_IRQ: + /* get ERM enable FTFC multi bits non-recover channel status */ + return (bool)ErmReg_GetSrNce1(obj->reg); + default: + return ERMDRV_CH_TOTAL_NUM; + } +} + +void ErmDrv_ClrChnErrInfoStatus(ErmDrvType *obj, ErmDrv_ChnNumType chnNum) +{ + switch(chnNum) + { + case ERMDRV_CH0_RECOVER_SRAM_IRQ: + /* clear ERM enable SRAM single bit recover channel */ + ErmReg_SetSrSbc0(obj->reg, 0x01); + break; + case ERMDRV_CH0_NONRECOVER_SRAM_IRQ: + /* clear ERM enable SRAM multi bits non-recover channel */ + ErmReg_SetSrNce0(obj->reg, 0x01); + break; + case ERMDRV_CH1_RECOVER_FTFC_IRQ: + /* clear ERM enable FTFC single bit recover channel */ + ErmReg_SetSrSbc1(obj->reg, 0x01); + break; + case ERMDRV_CH1_NONRECOVER_FTFC_IRQ: + /* clear ERM enable FTFC multi bits non-recover channel */ + ErmReg_SetSrNce1(obj->reg, 0x01); + break; + default: + break; + } +} + +void ErmDrv_GetChnNumCfg(ErmDrvType *obj, ErmDrv_ChnNumInfoType *chnNumInfo, ErmDrv_CtrlChnNumType ctrlChnNum) +{ + if(ctrlChnNum == ERMDRV_CH0) + { + /* Get channel 0 error address */ + chnNumInfo->errAddr = ErmReg_GetCh0St0Adr0(obj->reg); + /* Get channel 0 error position */ + chnNumInfo->errPos = ErmReg_GetCh0St1Syn0(obj->reg); + /* Get channel 0 error total num */ + chnNumInfo->errRecoverNum = ErmReg_GetCh0St2CorrCnt0(obj->reg); + } + else if(ctrlChnNum == ERMDRV_CH1) + { + /* Get channel 0 error address */ + chnNumInfo->errAddr = ErmReg_GetCh1St0Adr1(obj->reg); + /* Get channel 0 error position */ + chnNumInfo->errPos = ErmReg_GetCh1St1Syn1(obj->reg); + /* Get channel 0 error total num */ + chnNumInfo->errRecoverNum = ErmReg_GetCh1St2CorrCnt1(obj->reg); + } + else + { + return; + } +} + +void ErmDrv_ClrChnNumCfg(ErmDrvType *obj, ErmDrv_CtrlChnNumType ctrlChnNum) +{ + if(ctrlChnNum == ERMDRV_CH0) + { + /* Clear channel 0 error total num */ + ErmReg_SetCh0St2CorrCnt0(obj->reg, ERMDRV_RECOVER_ERRNUM_CLR); + } + else if(ctrlChnNum == ERMDRV_CH1) + { + /* Clear channel 1 error total num */ + ErmReg_SetCh1St2CorrCnt1(obj->reg); + } + else + { + return; + } +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/erm/erm_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/erm/erm_drv.h new file mode 100644 index 0000000..c94db87 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/erm/erm_drv.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _ERM_DRV_H_ +#define _ERM_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of ERM + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup erm_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* ERM error clear */ +#define ERMDRV_RECOVER_ERRNUM_CLR (0) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Definition ERM channel number + */ +typedef enum +{ + ERMDRV_CH0_RECOVER_SRAM_IRQ = 0U, /*!< ERM channel0 SRAM single recover Irq enable */ + ERMDRV_CH0_NONRECOVER_SRAM_IRQ = 1U, /*!< ERM channel0 SRAM single non-recover Irq enable */ + ERMDRV_CH1_RECOVER_FTFC_IRQ = 2U, /*!< ERM channel1 FTFC single recover Irq enable */ + ERMDRV_CH1_NONRECOVER_FTFC_IRQ = 3U, /*!< ERM channel1 FTFC single non-recover Irq enabl */ + ERMDRV_CH_TOTAL_NUM = 4U /*!< ERM channel total num */ +} ErmDrv_ChnNumType; + +/*! \brief Definition ERM channel number + */ +typedef enum +{ + ERMDRV_CH0 = 0U, /*!< ERM channel0 SRAM */ + ERMDRV_CH1 = 1U, /*!< ERM channel1 FTFC */ + ERMDRV_CH_CTRL_TOTAL_NUM = 2U /*!< ERM channel total num */ +} ErmDrv_CtrlChnNumType; + +/* Forward declaration of related register */ +struct _ErmRegType_; + +/*! \brief The definition of ERM driver class + */ +typedef struct _ErmDrvType_ +{ + struct _ErmRegType_ *reg; /*!< pointer to ERM register */ +} ErmDrvType; + +/*! \brief ERM channel status config + */ +typedef struct _ErmDrv_ChnNumInfoType_ +{ + uint32_t errAddr; /*!< error report address */ + uint32_t errPos; /*!< error report position */ + uint32_t errRecoverNum; /*!< error report recover */ +} ErmDrv_ChnNumInfoType; + +/*! \brief channel status and channel num error info + */ +typedef struct _ErmDrv_ChnErrConfigType_ +{ + bool chnEvent[ERMDRV_CH_TOTAL_NUM]; /*!< channel correction event status get */ + bool chnIrq[ERMDRV_CH_TOTAL_NUM]; /*!< channel interrupt notification set */ + ErmDrv_ChnNumInfoType chnStatus[ERMDRV_CH_CTRL_TOTAL_NUM]; /*!< channel status info */ +} ErmDrv_ChnErrConfigType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the ERM driver module + * + * This function initializes ERM driver by setting the register + * instances to it. + * + * \param[in] obj : pointer to ERM driver instance + * \param[in] ermReg : pointer to ERM register instance + */ +extern void ErmDrv_Init(ErmDrvType *obj, struct _ErmRegType_ *ermReg); + +/*! \brief Get ERM Default Config Parameter + * + * This function initializes ERM config parameter + * + * \param[in] userConfig : pointer to get ERM default config parameter + */ +extern void ErmDrv_GetDefaultConfig(ErmDrv_ChnErrConfigType *userConfig); + +/*! \brief Set ERM Channel Error Irq Enable + * + * This function set channel error interrupt enable + * + * \param[in] obj : pointer to ERM driver instance + * \param[in] chnNum : select config channel + * \param[in] enable : + * - true : enable select channel + * - false : disable select channel + */ +extern void ErmDrv_SetChnErrIrqEnable(ErmDrvType *obj, ErmDrv_ChnNumType chnNum, bool enable); + +/*! \brief Get ERM Channel Error Irq Enable + * + * This function get channel error interrupt enable + * + * \param[in] obj : pointer to ERM driver instance + * \param[in] chnNum : select config channel + * + * \return The result of configuring channel + * - true : enable select channel + * - false : disable select channel + */ +extern bool ErmDrv_GetChnErrIrqEnable(ErmDrvType *obj, ErmDrv_ChnNumType chnNum); + +/*! \brief Get ERM Channel Error Status + * + * This function get channel error status + * + * \param[in] obj : pointer to ERM driver instance + * \param[in] chnNum : select config channel + * + * \return The result of configuring channel + * - true : select channel error happened + * - false : select channel none error + */ +extern bool ErmDrv_GetChnErrInfoStatus(ErmDrvType *obj, ErmDrv_ChnNumType chnNum); + +/*! \brief Clear ERM Channel Error Status + * + * This function clear channel error status + * + * \param[in] obj : pointer to ERM driver instance + * \param[in] chnNum : clear select config channel + * + * \return none + */ +extern void ErmDrv_ClrChnErrInfoStatus(ErmDrvType *obj, ErmDrv_ChnNumType chnNum); + +/*! \brief Get ERM Channel Config Parameter + * + * This function get channel error config parameter + * + * \param[in] obj : pointer to ERM driver instance + * \param[in] chnNumInfo : pointer to current channel config info + * \param[in] chnNum : select config channel + */ +extern void ErmDrv_GetChnNumCfg(ErmDrvType *obj, ErmDrv_ChnNumInfoType *chnNumInfo, ErmDrv_CtrlChnNumType ctrlChnNum); + +/*! \brief Clear ERM Channel Config Parameter + * + * This function clear channel error config parameter + * + * \param[in] obj : pointer to ERM driver instance + * \param[in] chnNumInfo : pointer to current channel config info + * \param[in] chnNum : select config channel + */ +extern void ErmDrv_ClrChnNumCfg(ErmDrvType *obj, ErmDrv_CtrlChnNumType ctrlChnNum); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _ERM_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/fhu/fhu_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/fhu/fhu_drv.c new file mode 100644 index 0000000..cbbd4f2 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/fhu/fhu_drv.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "fhu_drv.h" +#include "fhu_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void FhuDrv_Init(FhuDrvType *obj, struct _FhuRegType_ *fhuReg) +{ + obj->reg = fhuReg; +} + +void FhuDrv_GetDefaultConfig(FhuDrv_ConfigType *cfg) +{ + cfg->chnEn = 0; + cfg->irqEn = 0; + cfg->rstEn = 0; + cfg->nmiEn = 0; +} + +bool FhuDrv_GetUserLockSts(FhuDrvType *obj) +{ + return (bool)FhuReg_GetUserLock(obj->reg); +} + +void FhuDrv_Config(FhuDrvType *obj, const FhuDrv_ConfigType *cfg) +{ + FhuReg_SetUserKey(obj->reg, FHUDRV_USER_KEY_UNLOCK); + + FhuReg_SetChCtl(obj->reg, cfg->chnEn); + FhuReg_SetIntCtl(obj->reg, cfg->irqEn); + FhuReg_SetRstCtl(obj->reg, cfg->rstEn); + FhuReg_SetNmiCtl(obj->reg, cfg->nmiEn); + + FhuReg_SetUserKey(obj->reg, ~FHUDRV_USER_KEY_UNLOCK); +} + +uint16_t FhuDrv_GetChnSts(FhuDrvType *obj) +{ + return FhuReg_GetChnRcd(obj->reg); +} + +void FhuDrv_ClearChnSts(FhuDrvType *obj, uint16_t clrValue) +{ + FhuReg_SetUserKey(obj->reg, FHUDRV_USER_KEY_UNLOCK); + FhuReg_SetChnRcd(obj->reg, clrValue); +} + +uint8_t FhuDrv_AnalogRealTimeChnSts(FhuDrvType *obj) +{ + return FhuReg_GetAdRcd(obj->reg); +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/fhu/fhu_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/fhu/fhu_drv.h new file mode 100644 index 0000000..daa8d02 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/fhu/fhu_drv.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FHU_DRV_H_ +#define _FHU_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of FHU + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup fhu_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +#define FHUDRV_USER_KEY_UNLOCK (0x97D356BA) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +typedef enum +{ + FHUDRV_CHNID_AD_LVD = 0x0U, /*!< fault channel low voltage detection */ + FHUDRV_CHNID_AD_LVW = 0x1U, /*!< fault channel low voltage warning */ + FHUDRV_CHNID_AD_FLDO_RDY = 0x2U, /*!< fault channel Flash LDO ready */ + FHUDRV_CHNID_AD_FLDO_LVD = 0x3U, /*!< fault channel Flash LDO Low voltage */ + FHUDRV_CHNID_AD_OTP = 0x4U, /*!< fault channel Flash LDO over tempreture */ + FHUDRV_CHNID_SRAM_SEC = 0x5U, /*!< fault channel sram single bit error */ + FHUDRV_CHNID_SRAM_DED = 0x6U, /*!< fault channel sram multi bits error */ + FHUDRV_CHNID_FLS_SEC = 0x7U, /*!< fault channel falsh single bit error */ + FHUDRV_CHNID_FLS_DED = 0x8U, /*!< fault channel falsh multi bits error */ + FHUDRV_CHNID_NUM = 0x9U +}FhuDrv_ChnIdType; + +typedef struct _FhuDrv_ConfigType_ +{ + uint16_t chnEn; /*!< fault channel enable config */ + uint16_t irqEn; /*!< fault channel interrupt config */ + uint16_t rstEn; /*!< fault channel reset config */ + uint16_t nmiEn; /*!< fault channel NMI config */ +}FhuDrv_ConfigType; + +/* Forward declaration of related register */ +struct _FhuRegType_; + +/*! \brief The definition of FHU driver class + */ +typedef struct _FhuDrvType_ +{ + struct _FhuRegType_ *reg; /*!< pointer to FHU register */ +} FhuDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the FHU driver module + * + * This function initializes FHU driver by setting the register + * instances to it. + * + * \param[in] obj : pointer to FHU driver instance + * \param[in] fhuReg : pointer to FHU register instance + */ +extern void FhuDrv_Init(FhuDrvType *obj, struct _FhuRegType_ *fhuReg); + +/*! \brief Get FHU Module default config + * + * This function Get FHU default config from registers. + * + * \param[in] *cfg : pointer to get FHU register default value + */ +extern void FhuDrv_GetDefaultConfig(FhuDrv_ConfigType *cfg); + +/*! \brief Get FHU user lock status + * + * This function get FHU user lock status + * + * \param[in] obj : pointer to FHU driver instance + */ +extern bool FhuDrv_GetUserLockSts(FhuDrvType *obj); + +/*! \brief Set FHU initial config + * + * This function FHU initial user config + * + * \param[in] obj : pointer to FHU driver instance + * \param[in] *cfg : pointer to set FHU register default value + */ +extern void FhuDrv_Config(FhuDrvType *obj, const FhuDrv_ConfigType *cfg); + +/*! \brief Get FHU channel status + * + * This function Get FHU channel status + * + * \param[in] obj : pointer to FHU driver instance + */ +extern uint16_t FhuDrv_GetChnSts(FhuDrvType *obj); + +/*! \brief clear FHU channel error status + * + * This function clear FHU channel error in status + * + * \param[in] obj : pointer to FHU driver instance + * \param[in] clrValue : corresponding bit set 1 to clear + * corresponding bit set 0 to reserve + */ +extern void FhuDrv_ClearChnSts(FhuDrvType *obj, uint16_t clrValue); + +/*! \brief get FHU analog channel error status + * + * This function get FHU analog channel error in status + * for real time. + * + * \param[in] obj : pointer to FHU driver instance + */ +extern uint8_t FhuDrv_AnalogRealTimeChnSts(FhuDrvType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _FHU_DRV_H_ */ + diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/flash/flash_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/flash/flash_drv.c new file mode 100644 index 0000000..0caf47a --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/flash/flash_drv.c @@ -0,0 +1,924 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#include "scg0_reg.h" +#include "ftfc_reg.h" +#include "flash_drv.h" +#include "../../CVM011x_features.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +static void FlashDrv_ClearCommandState(FlashDrvType *obj); +static FlashDrv_Status FlashDrv_CommandSequence(FlashDrvType *obj); +static void FlashDrv_EeeUpdateSequence(FlashDrvType *obj); + +/******************************************************************************* + * Code + ******************************************************************************/ + +void FlashDrv_Init(FlashDrvType *obj, struct _FtfcRegType_ *reg, struct _Scg0RegType_ *scg0Reg) +{ + obj->reg = reg; + obj->scg0Reg = scg0Reg; + obj->pflashbase = 0x0; + obj->pflashsize = FEATURE_PFLASH_SIZE; + obj->dflashbase = 0x10000000; + obj->dflashsize = FEATURE_DFLASH_SIZE; + obj->eeevld = FlashDrv_GetEeeEn(obj); + obj->callback = NULL; + if(obj->eeevld) + { + obj->dflashsize = 0x0; + } + + FlashDrv_ClearCommandState(obj); +} + +void FlashDrv_GetDefaultConfig(FlashDrv_ConfigType *userconfig) +{ + userconfig->pflashbase = 0x0; + userconfig->pflashsize = FEATURE_PFLASH_SIZE; + userconfig->dflashbase = 0x10000000; + userconfig->dflashsize = FEATURE_DFLASH_SIZE; + userconfig->eeevld = false; + userconfig->callback = NULL; +} + +void FlashDrv_Configure(FlashDrvType *obj, + const FlashDrv_ConfigType *userconfig) +{ + obj->pflashbase = 0x0; + obj->pflashsize = FEATURE_PFLASH_SIZE; + obj->dflashbase = 0x10000000; + obj->dflashsize = FEATURE_DFLASH_SIZE; + /* DFlash size only has one fixed configuration */ + obj->eeevld = FlashDrv_GetEeeEn(obj); + obj->callback = userconfig->callback; + if(obj->eeevld) + { + obj->dflashsize = 0x0; + } + + FlashDrv_ClearCommandState(obj); +} + +void FlashDrv_GetConfig(const FlashDrvType *obj, + FlashDrv_ConfigType *userconfig) +{ + userconfig->pflashbase = obj->pflashbase; + userconfig->pflashsize = obj->pflashsize; + userconfig->dflashbase = obj->dflashbase; + userconfig->dflashsize = obj->dflashsize; + userconfig->eeevld = obj->eeevld; + userconfig->callback = obj->callback; +} + +static void FlashDrv_ClearCommandState(FlashDrvType *obj) +{ + FtfcReg_SetFstatRspErrF(obj->reg, 1); + FtfcReg_SetFstatProtViolF(obj->reg, 1); + FtfcReg_SetFstatAccErrF(obj->reg, 1); + FtfcReg_SetFstatRdColF(obj->reg, 1); + FtfcReg_SetFstatSecF(obj->reg, 1); + FtfcReg_SetFstatDedF(obj->reg, 1); +} + +static FlashDrv_Status FlashDrv_CommandSequence(FlashDrvType *obj) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + + FtfcReg_SetFstatCcif(obj->reg, 1); + + while(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + } + + if(FtfcReg_GetFstatAccErrF(obj->reg) || FtfcReg_GetFstatProtViolF(obj->reg) || FtfcReg_GetFstatMgStat(obj->reg)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + return ret; +} + +static void FlashDrv_EeeUpdateSequence(FlashDrvType *obj) +{ + while(0 == FtfcReg_GetFstatEeeRamRdy(obj->reg)) + { + } + if(FtfcReg_GetFstatEeeTlov(obj->reg) == 1) + { + FlashDrv_SetFlexRam(obj, false); + FlashDrv_SetEeeAutoGcEn(obj, true); + FlashDrv_SetFlexRam(obj, true); + FlashDrv_SetEeeAutoGcEn(obj, false); + } +} + +FlashDrv_Status FlashDrv_Read1sBlock(FlashDrvType *obj, uint32_t *destaddr) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t dest = (uint32_t)destaddr; + + dest = ALIGNED(dest, 8); + + if((dest >= (obj->pflashbase + obj->pflashsize) && dest < obj->dflashbase) || (obj->dflashsize > 0 && dest >= (obj->dflashbase + obj->dflashsize)) || (dest >= obj->dflashbase && obj->eeevld)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_BLKRD1S); + FtfcReg_SetFccob(obj->reg, 1, FCCOBADDRLOW(dest)); + FtfcReg_SetFccob(obj->reg, 2, FCCOBADDRMDLOW(dest)); + FtfcReg_SetFccob(obj->reg, 3, FCCOBADDRMDHIG(dest)); + FtfcReg_SetFccob(obj->reg, 4, FCCOBADDRHIG(dest)); + + ret = FlashDrv_CommandSequence(obj); + } + } + + return ret; +} + +FlashDrv_Status FlashDrv_Read1sSection(FlashDrvType *obj, uint32_t *destaddr, uint32_t rdsize) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t dest = (uint32_t)destaddr; + + if(!IS_ALIGNED(dest, 8) || !IS_ALIGNED(rdsize, 8)) + { + ret = FLASHDRV_STATUS_ERROR; + } + if(ALIGNED(dest + rdsize - 1, FLASHDRV_SECTOR_SIZE) > ALIGNED(dest, FLASHDRV_SECTOR_SIZE)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if((dest >= (obj->pflashbase + obj->pflashsize) && dest < obj->dflashbase) || (obj->dflashsize > 0 && dest >= (obj->dflashbase + obj->dflashsize)) || (dest >= obj->dflashbase && obj->eeevld)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_SCTRD1S); + FtfcReg_SetFccob(obj->reg, 1, FCCOBADDRLOW(dest)); + FtfcReg_SetFccob(obj->reg, 2, FCCOBADDRMDLOW(dest)); + FtfcReg_SetFccob(obj->reg, 3, FCCOBADDRMDHIG(dest)); + FtfcReg_SetFccob(obj->reg, 4, FCCOBADDRHIG(dest)); + FtfcReg_SetFccob(obj->reg, 5, (rdsize / FLASHDRV_PHRASE_SIZE) - 1); + + ret = FlashDrv_CommandSequence(obj); + } + } + + return ret; +} + +FlashDrv_Status FlashDrv_CheckPhrase(FlashDrvType *obj, uint32_t *destaddr, uint8_t *expdata) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t dest = (uint32_t)destaddr; + uint32_t i = 0; + + if(!IS_ALIGNED(dest, 8)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if((dest >= (obj->pflashbase + obj->pflashsize) && dest < obj->dflashbase) || (obj->dflashsize > 0 && dest >= (obj->dflashbase + obj->dflashsize)) || (dest >= obj->dflashbase && obj->eeevld)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(expdata == NULL) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_PRSCHK); + FtfcReg_SetFccob(obj->reg, 1, FCCOBADDRLOW(dest)); + FtfcReg_SetFccob(obj->reg, 2, FCCOBADDRMDLOW(dest)); + FtfcReg_SetFccob(obj->reg, 3, FCCOBADDRMDHIG(dest)); + FtfcReg_SetFccob(obj->reg, 4, FCCOBADDRHIG(dest)); + + for(i = 0; i < FLASHDRV_PHRASE_SIZE; i++) + { + FtfcReg_SetFccob(obj->reg, 5 + i, expdata[i]); + } + ret = FlashDrv_CommandSequence(obj); + } + } + return ret; +} + +FlashDrv_Status FlashDrv_CheckEccState(FlashDrvType *obj, uint32_t *destaddr) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t dest = (uint32_t)destaddr; + uint32_t i = 0; + + if(!IS_ALIGNED(dest, 8)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if((dest >= (obj->pflashbase + obj->pflashsize) && dest < obj->dflashbase) || (obj->dflashsize > 0 && dest >= (obj->dflashbase + obj->dflashsize)) || (dest >= obj->dflashbase && obj->eeevld)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_PRSCHK); + FtfcReg_SetFccob(obj->reg, 1, FCCOBADDRLOW(dest)); + FtfcReg_SetFccob(obj->reg, 2, FCCOBADDRMDLOW(dest)); + FtfcReg_SetFccob(obj->reg, 3, FCCOBADDRMDHIG(dest)); + FtfcReg_SetFccob(obj->reg, 4, FCCOBADDRHIG(dest)); + + for(i = 0; i < FLASHDRV_PHRASE_SIZE; i++) + { + FtfcReg_SetFccob(obj->reg, 5 + i, 0xFF); + } + FlashDrv_CommandSequence(obj); + ret = ((FtfcReg_GetFstatSecF(obj->reg) | FtfcReg_GetFstatDedF(obj->reg)) == 1) ? FLASHDRV_STATUS_ERROR : FLASHDRV_STATUS_SUCCESS; + } + } + return ret; +} + +FlashDrv_Status FlashDrv_ProgramPhrase(FlashDrvType *obj, uint32_t *destaddr, uint8_t *expdata, bool hweccen) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t dest = (uint32_t)destaddr; + uint32_t i = 0; + + if(!IS_ALIGNED(dest, 8)) + { + ret = FLASHDRV_STATUS_ERROR; + } + if((dest >= (obj->pflashbase + obj->pflashsize) && dest < obj->dflashbase) || (obj->dflashsize > 0 && dest >= (obj->dflashbase + obj->dflashsize)) || (dest >= obj->dflashbase && obj->eeevld)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(expdata == NULL) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_PRSPGM); + FtfcReg_SetFccob(obj->reg, 1, FCCOBADDRLOW(dest)); + FtfcReg_SetFccob(obj->reg, 2, FCCOBADDRMDLOW(dest)); + FtfcReg_SetFccob(obj->reg, 3, FCCOBADDRMDHIG(dest)); + FtfcReg_SetFccob(obj->reg, 4, FCCOBADDRHIG(dest)); + FtfcReg_SetFccob(obj->reg, 5, (hweccen ? 1 : 0)); + for(i = 0; i < FLASHDRV_PHRASE_SIZE; i++) + { + FtfcReg_SetFccob(obj->reg, 6 + i, expdata[i]); + } + if(!hweccen) + { + FtfcReg_SetFccob(obj->reg, 14, expdata[8]); + } + + ret = FlashDrv_CommandSequence(obj); + } + } + return ret; +} + +FlashDrv_Status FlashDrv_EraseBlock(FlashDrvType *obj, uint32_t *destaddr, FlashDrv_SectorErase_t erasetype) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t dest = (uint32_t)destaddr; + + dest = ALIGNED(dest, 8); + + if((dest >= (obj->pflashbase + obj->pflashsize) && dest < obj->dflashbase) || (obj->dflashsize > 0 && dest >= (obj->dflashbase + obj->dflashsize)) || (dest >= obj->dflashbase && obj->eeevld)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_BLKERS); + FtfcReg_SetFccob(obj->reg, 1, FCCOBADDRLOW(dest)); + FtfcReg_SetFccob(obj->reg, 2, FCCOBADDRMDLOW(dest)); + FtfcReg_SetFccob(obj->reg, 3, FCCOBADDRMDHIG(dest)); + FtfcReg_SetFccob(obj->reg, 4, FCCOBADDRHIG(dest)); + FtfcReg_SetFccob(obj->reg, 5, erasetype); + + ret = FlashDrv_CommandSequence(obj); + } + } + + return ret; +} + +FlashDrv_Status FlashDrv_EraseSector(FlashDrvType *obj, uint32_t *destaddr, FlashDrv_SectorErase_t erasetype) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t dest = (uint32_t)destaddr; + + dest = ALIGNED(dest, 8); + + if((dest >= (obj->pflashbase + obj->pflashsize) && dest < obj->dflashbase) || (obj->dflashsize > 0 && dest >= (obj->dflashbase + obj->dflashsize)) || (dest >= obj->dflashbase && obj->eeevld)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_SCTERS); + FtfcReg_SetFccob(obj->reg, 1, FCCOBADDRLOW(dest)); + FtfcReg_SetFccob(obj->reg, 2, FCCOBADDRMDLOW(dest)); + FtfcReg_SetFccob(obj->reg, 3, FCCOBADDRMDHIG(dest)); + FtfcReg_SetFccob(obj->reg, 4, FCCOBADDRHIG(dest)); + FtfcReg_SetFccob(obj->reg, 5, erasetype); + ret = FlashDrv_CommandSequence(obj); + } + } + + return ret; +} + +FlashDrv_Status FlashDrv_ProgramSection(FlashDrvType *obj, uint32_t *destaddr, uint32_t len, uint8_t *databuf) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t dest = (uint32_t)destaddr; + uint32_t i = 0, offset = 0; + bool eeeramrdy = false; + uint8_t *pfastram, *pdata; + + if(!IS_ALIGNED(dest, 256) || !IS_ALIGNED(len, 256)) + { + ret = FLASHDRV_STATUS_ERROR; + } + if(ALIGNED(dest + len - 1, FLASHDRV_SECTOR_SIZE) > ALIGNED(dest, FLASHDRV_SECTOR_SIZE)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if((dest >= (obj->pflashbase + obj->pflashsize) && dest < obj->dflashbase) || (obj->dflashsize > 0 && dest >= (obj->dflashbase + obj->dflashsize)) || (dest >= obj->dflashbase && obj->eeevld)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + eeeramrdy = (FtfcReg_GetFstatEeeRamRdy(obj->reg) == 1); + + if(eeeramrdy) + { + FlashDrv_SetFlexRam(obj, false); + } + + offset = dest & (FLASHDRV_SECTOR_SIZE - 1); + pfastram = (uint8_t *)(FLASHDRV_FLEXRAM_ADDR + offset); + pdata = databuf; + for(i = 0; i < len; i++) + { + *pfastram = *pdata; + pfastram++; + pdata++; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_SCTPGM); + FtfcReg_SetFccob(obj->reg, 1, FCCOBADDRLOW(dest)); + FtfcReg_SetFccob(obj->reg, 2, FCCOBADDRMDLOW(dest)); + FtfcReg_SetFccob(obj->reg, 3, FCCOBADDRMDHIG(dest)); + FtfcReg_SetFccob(obj->reg, 4, FCCOBADDRHIG(dest)); + FtfcReg_SetFccob(obj->reg, 5, (len / FLASHDRV_PHRASE_SIZE) - 1); + ret = FlashDrv_CommandSequence(obj); + } + } + + if(eeeramrdy) + { + FlashDrv_SetFlexRam(obj, true); + } + return ret; +} + +FlashDrv_Status FlashDrv_ProgramSectionFast(FlashDrvType *obj, uint32_t *destaddr, uint32_t len) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t dest = (uint32_t)destaddr; + + if(!IS_ALIGNED(dest, 256) || !IS_ALIGNED(len, 256)) + { + ret = FLASHDRV_STATUS_ERROR; + } + if(ALIGNED(dest + len - 1, FLASHDRV_SECTOR_SIZE) > ALIGNED(dest, FLASHDRV_SECTOR_SIZE)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if((dest >= (obj->pflashbase + obj->pflashsize) && dest < obj->dflashbase) || (obj->dflashsize > 0 && dest >= (obj->dflashbase + obj->dflashsize)) || (dest >= obj->dflashbase && obj->eeevld)) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_SCTPGM); + FtfcReg_SetFccob(obj->reg, 1, FCCOBADDRLOW(dest)); + FtfcReg_SetFccob(obj->reg, 2, FCCOBADDRMDLOW(dest)); + FtfcReg_SetFccob(obj->reg, 3, FCCOBADDRMDHIG(dest)); + FtfcReg_SetFccob(obj->reg, 4, FCCOBADDRHIG(dest)); + FtfcReg_SetFccob(obj->reg, 5, (len / FLASHDRV_PHRASE_SIZE) - 1); + ret = FlashDrv_CommandSequence(obj); + } + } + + return ret; +} + +FlashDrv_Status FlashDrv_Read1sAllBlock(FlashDrvType *obj) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_ALBLKRD1S); + ret = FlashDrv_CommandSequence(obj); + } + return ret; +} + +FlashDrv_Status FlashDrv_ReadInfoRegion(FlashDrvType *obj, + FlashDrv_InfoRegion_t regionid, + uint8_t phraseid, + uint8_t *databuf) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t i = 0; + + if(phraseid >= 64) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(databuf == NULL) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_RDINFORG); + FtfcReg_SetFccob(obj->reg, 1, phraseid); + + ret = FlashDrv_CommandSequence(obj); + } + } + if(ret == FLASHDRV_STATUS_SUCCESS) + { + for(i = 0; i < FLASHDRV_PHRASE_SIZE; i++) + { + databuf[i] = FtfcReg_GetFccob(obj->reg, 7 + i); + } + } + return ret; +} + +FlashDrv_Status FlashDrv_ProgramInfoRegion(FlashDrvType *obj, + FlashDrv_InfoRegion_t regionid, + uint32_t phraseid, + uint8_t *databuf) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t i = 0; + + if(phraseid >= 64) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(databuf == NULL) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_PGMINFORG); + FtfcReg_SetFccob(obj->reg, 1, (uint8_t)phraseid); + + for(i = 0; i < FLASHDRV_PHRASE_SIZE; i++) + { + FtfcReg_SetFccob(obj->reg, (uint8_t)(2 + i), databuf[i]); + } + + ret = FlashDrv_CommandSequence(obj); + } + } + + return ret; +} + +FlashDrv_Status FlashDrv_EraseAllBlock(FlashDrvType *obj) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_ALBLKERS); + ret = FlashDrv_CommandSequence(obj); + } + return ret; +} + +FlashDrv_Status FlashDrv_EraseAllBlockUnsecure(FlashDrvType *obj) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, (uint8_t)FLASHDRV_OPCMD_ALBLKUERS); + ret = FlashDrv_CommandSequence(obj); + } + return ret; +} + +FlashDrv_Status FlashDrv_VerifyUserKey(FlashDrvType *obj, uint8_t *expdata) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + uint32_t i = 0; + + if(expdata == NULL) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS) + { + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_VRFYKEY); + + for(i = 0; i < FLASHDRV_PHRASE_SIZE; i++) + { + FtfcReg_SetFccob(obj->reg, 1 + i, expdata[i]); + } + ret = FlashDrv_CommandSequence(obj); + } + } + return ret; +} + +void FlashDrv_IrqHandler(FlashDrvType *obj) +{ + FtfcReg_SetFstatCcifClr(obj->reg, 1); + if(obj->callback != NULL) + { + obj->callback(); + } +} + +void FlashDrv_SetCmdDoneIrqEn(FlashDrvType *obj, bool en) +{ + FtfcReg_SetFcnfgCcifIE(obj->reg, en ? 1 : 0); +} + +FlashDrv_Status FlashDrv_SetFlexRam(FlashDrvType *obj, bool eeeramen) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + bool gctrg = false; + + if(FtfcReg_GetFstatEeeRamRdy(obj->reg) == 0 && eeeramen == true && Scg0Reg_GetTrimAutoGcEn(obj->scg0Reg) == 1) + { + gctrg = true; + } + + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLASHDRV_STATUS_BUSY; + } + else + { + FlashDrv_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_SETFRAM); + FtfcReg_SetFccob(obj->reg, 1, eeeramen ? 1 : 0); + ret = FlashDrv_CommandSequence(obj); + + if(eeeramen && !FtfcReg_GetFstatEeeRamRdy(obj->reg)) + { + ret |= FLASHDRV_STATUS_ERROR; + } + + if(!eeeramen && !FtfcReg_GetFstatRamRdy(obj->reg)) + { + ret |= FLASHDRV_STATUS_ERROR; + } + + if(ret == FLASHDRV_STATUS_SUCCESS && gctrg == true) + { + FtfcReg_SetFstatEeeTlov(obj->reg, 1); + } + } + + return ret; +} + +FlashDrv_Status FlashDrv_UpdateEeeRam(FlashDrvType *obj, uint32_t offset, uint8_t *srcdata, uint32_t sz) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + + uint8_t *pdsteram8 = 0; + uint16_t *pdsteram16 = 0; + uint32_t *pdsteram32 = 0; + uint8_t *psrc8 = 0; + uint16_t *psrc16 = 0; + uint32_t *psrc32 = 0; + uint32_t i = 0, cnt = 0; + + if(!(obj->eeevld) || FtfcReg_GetFstatRamRdy(obj->reg) == 1 || FtfcReg_GetEfProtecion(obj->reg) != 0x0) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(offset + sz > FLASHDRV_FLEXRAM_SIZE) + { + ret = FLASHDRV_STATUS_ERROR; + } + + if(ret != FLASHDRV_STATUS_SUCCESS) + { + return ret; + } + + if(FlashDrv_GetEeeAutoGcEn(obj)) + { + FlashDrv_SetEeeAutoGcEn(obj, false); + } + + while(0 == FtfcReg_GetFstatEeeRamRdy(obj->reg)) + { + } + + pdsteram8 = (uint8_t *)(FLASHDRV_FLEXRAM_ADDR + offset); + if(IS_ALIGNED(offset, (uint32_t)4) && IS_ALIGNED(sz, (uint32_t)4)) + { + pdsteram32 = (uint32_t *)pdsteram8; + psrc32 = (uint32_t *)srcdata; + cnt = sz / 4; + for(i = 0; i < cnt; i++) + { + pdsteram32[i] = psrc32[i]; + FlashDrv_EeeUpdateSequence(obj); + } + } + else if(IS_ALIGNED(offset, (uint32_t)2) && IS_ALIGNED(sz, (uint32_t)2)) + { + pdsteram16 = (uint16_t *)pdsteram8; + psrc16 = (uint16_t *)srcdata; + cnt = sz / 2; + for(i = 0; i < cnt; i++) + { + pdsteram16[i] = psrc16[i]; + FlashDrv_EeeUpdateSequence(obj); + } + } + else + { + psrc8 = (uint8_t *)srcdata; + cnt = sz; + for(i = 0; i < cnt; i++) + { + pdsteram8[i] = psrc8[i]; + FlashDrv_EeeUpdateSequence(obj); + } + } + + if(FtfcReg_GetFstatEeeFlov(obj->reg) == 1) + { + ret = FLASHDRV_STATUS_ERROR; + } + + return ret; +} + +bool FlashDrv_GetEeeAutoGcEn(FlashDrvType *obj) +{ + bool eeegcen = false; + + eeegcen = (Scg0Reg_GetTrimAutoGcEn(obj->scg0Reg) == 1); + + return eeegcen; +} + +void FlashDrv_SetEeeAutoGcEn(FlashDrvType *obj, bool eeegcen) +{ + Scg0Reg_SetKey(obj->scg0Reg, 0x19962020); + Scg0Reg_SetTrimAutoGcEn(obj->scg0Reg, eeegcen ? 1 : 0); + Scg0Reg_SetKey(obj->scg0Reg, 0); +} + +bool FlashDrv_GetEeeEn(FlashDrvType *obj) +{ + uint8_t data[8] = {0x0}; + bool eeeen = false; + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + + data[0] = 0xFF; + ret = FlashDrv_ReadInfoRegion(obj, FLASHDRV_INFORG0, 0, data); + + if(ret == FLASHDRV_STATUS_SUCCESS && (data[0] & 0x2) == 0x0) + { + eeeen = true; + } + return eeeen; +} + +bool FlashDrv_GetEeeRamRdy(FlashDrvType *obj) +{ + bool eeeramrdy = false; + + eeeramrdy = (FtfcReg_GetFstatEeeRamRdy(obj->reg) == 1); + + return eeeramrdy; +} + +FlashDrv_Status FlashDrv_GetEeeRamProtection(FlashDrvType *obj, uint8_t *protectstatus) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + + if(!(obj->eeevld)) + { + ret = FLASHDRV_STATUS_UNSUPPORTED; + } + else + { + *protectstatus = FtfcReg_GetEfProtecion(obj->reg); + } + + return ret; +} + +FlashDrv_Status FlashDrv_GetPFlashProtection(FlashDrvType *obj, uint32_t *protectstatus) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + + *protectstatus = FtfcReg_GetPfProtecion(obj->reg); + + return ret; +} + +FlashDrv_Status FlashDrv_GetDFlashProtection(FlashDrvType *obj, uint8_t *protectstatus) +{ + FlashDrv_Status ret = FLASHDRV_STATUS_SUCCESS; + + if(obj->dflashsize == 0x0) + { + ret = FLASHDRV_STATUS_UNSUPPORTED; + } + else + { + *protectstatus = FtfcReg_GetDfProtecion(obj->reg); + } + + return ret; +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/flash/flash_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/flash/flash_drv.h new file mode 100644 index 0000000..5fadda8 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/flash/flash_drv.h @@ -0,0 +1,582 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FLASH_DRV_H_ +#define _FLASH_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of FLASH + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +/*! \brief Macro for high and low position separation of the memory address. + * + * The 32-bit address need to be sperated to 8-bit and then programmed to + * specific fccob registers. + */ +#define FCCOBADDRLOW(addr) ((uint8_t)(((uint32_t)(addr)) & 0xFFU)) +#define FCCOBADDRMDLOW(addr) ((uint8_t)((((uint32_t)(addr)) >> 8) & 0xFFU)) +#define FCCOBADDRMDHIG(addr) ((uint8_t)((((uint32_t)(addr)) >> 16) & 0xFFU)) +#define FCCOBADDRHIG(addr) ((uint8_t)(((uint32_t)(addr)) >> 24)) + +/*! \brief Macro for the alignment requirement. + * + * The address need to be aligned. + */ +#define ALIGNED(val, alncnt) (((uint32_t)val) & ~(alncnt - 1)) +#define IS_ALIGNED(val, alncnt) ((((uint32_t)val) & (alncnt - 1)) == 0x0 ? true : false) + +/*! \brief Macro for sector size + * + * Sector size is 1024. + */ +#define FLASHDRV_SECTOR_SIZE (1024U) + +/*! \brief Macro for the byte count of phrase-write and phrase-read + * + * phrase-write/phrase-read size + */ +#define FLASHDRV_PHRASE_SIZE (8U) + +/*! \brief Macro for the flexram address + * + * flexram address + */ +#define FLASHDRV_FLEXRAM_ADDR (0x14000000UL) + +/*! \brief Macro for the flexram size + * + * flexram size + */ +#define FLASHDRV_FLEXRAM_SIZE (2048U) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Status return codes. + * Common error codes will be a unified enumeration (C enum) that will contain + * all error codes (common and specific). There will be separate "error values + * spaces" (or slots), each of 256 positions, allocated per functionality. + */ +typedef enum +{ + /* Generic error codes */ + FLASHDRV_STATUS_SUCCESS = 0x000U, /*!< Generic operation success status */ + FLASHDRV_STATUS_ERROR = 0x001U, /*!< Generic operation failure status */ + FLASHDRV_STATUS_BUSY = 0x002U, /*!< Generic operation busy status */ + FLASHDRV_STATUS_TIMEOUT = 0x003U, /*!< Generic operation timeout status */ + FLASHDRV_STATUS_UNSUPPORTED = 0x004U, /*!< Generic operation unsupported status */ +} FlashDrv_Status; + +/*! \brief FLASH type of operation cmd + */ +typedef enum +{ + FLASHDRV_OPCMD_BLKRD1S = 0x00, /*!< Block Read 1s command*/ + FLASHDRV_OPCMD_SCTRD1S = 0x01, /*!< Section Read 1s command*/ + FLASHDRV_OPCMD_PRSCHK = 0x02, /*!< Phrase check command*/ + FLASHDRV_OPCMD_PRSPGM = 0x03, /*!< Phrase Program command*/ + FLASHDRV_OPCMD_BLKERS = 0x04, /*!< Block Erase command*/ + FLASHDRV_OPCMD_SCTERS = 0x05, /*!< Sector Erase command*/ + FLASHDRV_OPCMD_SCTPGM = 0x06, /*!< Program section command*/ + FLASHDRV_OPCMD_ALBLKRD1S = 0x07, /*!< Read 1s ALL Blocks command*/ + FLASHDRV_OPCMD_RDINFORG = 0x08, /*!< Read once command: for info region*/ + FLASHDRV_OPCMD_PGMINFORG = 0x09, /*!< Program once command: for info region*/ + FLASHDRV_OPCMD_ALBLKERS = 0x0A, /*!< Erase ALL blocks command*/ + FLASHDRV_OPCMD_VRFYKEY = 0x0B, /*!< Verify backdoor access key command*/ + FLASHDRV_OPCMD_ALBLKUERS = 0x0C, /*!< Erase All Blocks unsecure command*/ + FLASHDRV_OPCMD_SETFRAM = 0x0D, /*!< Set Flexram command*/ +} FlashDrv_Opcmd_t; + +/*! \brief FLASH info region type + */ +typedef enum +{ + FLASHDRV_INFORG0 = 0x00, /*!< info region,512bytes, phrase_index: 0~ 63, no erase cmd*/ +} FlashDrv_InfoRegion_t; + +/*! \brief FLASH sector erase type + */ +typedef enum +{ + FLASHDRV_SCTERS_ONEPULSE = 0x00, /*!< one-pulse erase */ + FLASHDRV_SCTERS_RETRY = 0x01, /*!< retry erase */ +} FlashDrv_SectorErase_t; + +/*! \brief Definition for the flash cmd done callback function. + * + * Prototype for the callback function registered in the flash driver. + */ +typedef void (*FlashDrv_CallBackType)(void); + +/*! \brief Definition of configuration of FLASH driver + */ +typedef struct _FlashDrv_ConfigType_ +{ + uint32_t pflashbase; /*!< The base address of P-Flash memory */ + uint32_t pflashsize; /*!< The size in byte of P-Flash memory */ + uint32_t dflashbase; /*!< The base address of D-Flash memory */ + uint32_t dflashsize; /*!< The size in byte of P-Flash memory */ + bool eeevld; /*!< emualted ee function valid flag*/ + FlashDrv_CallBackType callback; /*!< Call back function to service the time critical events. Any code reachable from this function + * must not be placed in a Flash block targeted for a program/erase operation */ +} FlashDrv_ConfigType; + +/* Forward declaration of flash ftfc register */ +struct _FtfcRegType_; +/* Forward declaration of Scg0 register */ +struct _Scg0RegType_; + +/*! \brief The definition of flash driver class + */ +typedef struct _FlashDrvType_ +{ + struct _FtfcRegType_ *reg; + struct _Scg0RegType_ *scg0Reg; + uint32_t pflashbase; /*!< The base address of P-Flash memory */ + uint32_t pflashsize; /*!< The size in byte of P-Flash memory */ + uint32_t dflashbase; /*!< The base address of D-Flash memory */ + uint32_t dflashsize; /*!< The size in byte of P-Flash memory */ + bool eeevld; /*!< emualted ee function valid flag*/ + FlashDrv_CallBackType callback; /*!< Call back function to service the time critical events. Any code reachable from this function + * must not be placed in a Flash block targeted for a program/erase operation */ +} FlashDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the Flash driver module + * + * This function initializes Flash driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] reg : pointer to Flash register instance + * \param[in] scg0Reg : pointer to SCG0 register instance + */ +extern void FlashDrv_Init(FlashDrvType *obj, struct _FtfcRegType_ *reg, struct _Scg0RegType_ *scg0Reg); + +/*! \brief Get configures of the Flash module currently + * + * This function gets configures of the Flash module currently + * + * \param[in] obj : pointer to Flash driver instance + * \param[out] userConfig : pointer to configuration structure + */ +extern void FlashDrv_GetConfig(const FlashDrvType *obj, + FlashDrv_ConfigType *userconfig); + +/*! \brief Get default configures the Flash module for configuration structure + * + * This function gets default configures the Flash module for user configuration + * structure + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void FlashDrv_GetDefaultConfig(FlashDrv_ConfigType *userconfig); + +/*! \brief Configures the Flash module from a user configuration structure + * + * This function configures the Flash module from a user configuration structure + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void FlashDrv_Configure(FlashDrvType *obj, + const FlashDrv_ConfigType *userconfig); + +/*! \brief Verify the Pflash or Dfalsh(keysector included) erased + * + * This function verify pflash or dflash is erased. + * + * NOTE:if targeted block is the eee backup region, + * the read1s seqeunce will be aborted + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] destaddr : pointer to a memory address in pflash/dflash + */ +extern FlashDrv_Status FlashDrv_Read1sBlock(FlashDrvType *obj, + uint32_t *destaddr); + +/*! \brief Verify a section erased + * + * This function verify a section erased. The section should located in a sector + * or should be a total sector. Both the start addr and the size of the section + * are supposed to be 8-aligned. + * + * NOTE:if targeted section is in the eee backup region, the + * erase sequence will be aborted. + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] destaddr : pointer to a memory address in pflash or dflash:8-aligned. + * \param[in] rdsize : length of read/verified memory in bytes:8-aligned. + */ +extern FlashDrv_Status FlashDrv_Read1sSection(FlashDrvType *obj, + uint32_t *destaddr, + uint32_t rdsize); + +/*! \brief Check a phrase programmed as expected value + * + * This function checked a phrase-data[8bytes] progrmmed as expected value. + * The phrase addr is supposed to be 8-aligned. + * + * NOTE:if targeted phrase is in the eee backup region, the + * checkphrase sequence will be aborted. + * + * \param[in] obj : pointer to Flash driver instance. + * \param[in] destaddr : pointer to a phrase address in pflash or dflash,8-aligned. + * \param[in] expdata : pointor to expected data, 8 bytes + */ +extern FlashDrv_Status FlashDrv_CheckPhrase(FlashDrvType *obj, + uint32_t *destaddr, + uint8_t *expdata); + +/*! \brief Check a phrase has ecc error + * + * This function checked a phrase-data[8bytes] has ecc error. + * + * + * \param[in] obj : pointer to Flash driver instance. + * \param[in] destaddr : pointer to a memory address in pflash or dflash, 8-aligned. + */ +extern FlashDrv_Status FlashDrv_CheckEccState(FlashDrvType *obj, + uint32_t *destaddr); + +/*! \brief Program a phrase as expected value + * + * This function checked a phrase-data[8bytes/9bytes] progrmmed as expected + * value. The phrase addr is supposed to be 8-aligned. + * + * NOTE: 1.make sure targeted phrase is erased and not proteted before + * programmed; 2.if the target section is in the eee backup region, + * the program sequence will be aborted. + * + * \param[in] obj : pointer to Flash driver instance. + * \param[in] destaddr : pointer to a memory address in pflash or dflash,8-aligned. + * \param[in] expdata : pointor to expected data, 8 bytes or 9 bytes + * \param[in] hweccen : true: first 8 bytes will be programmed,ecc byte programmed by hardware; + * false: 9 bytes(ecc byte included) will be programmed; + */ +extern FlashDrv_Status FlashDrv_ProgramPhrase(FlashDrvType *obj, + uint32_t *destaddr, + uint8_t *expdata, + bool hweccen); + +/*! \brief Erase Pflash or Dfalsh + * + * This function erase pflash or dflash. + * + * NOTE: + * 1.Any code reachable from this function must not be placed in a Flash + * block targeted for this erase operation. 2.Between the POR and Pflash-erased + * operations, remind to program pflash-cfg-feild[0x400~0x41f] to proper + * value.Otherwise, system will enter security state, swd cannot be connected. + * 3.if there is protection region in targeted block, the erase + * sequence will be aborted; 4.if targeted flash is the eee backup region, + * the erase sequence will be aborted. + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] destaddr : pointer to a address in pflash or dflash, 8-aligned + * \param[in] erasetype: erase type + */ +extern FlashDrv_Status FlashDrv_EraseBlock(FlashDrvType *obj, + uint32_t *destaddr, + FlashDrv_SectorErase_t erasetype); + +/*! \brief Erases a sector + * + * This function erases a sector located in pflash or dflash. + * + * NOTE: + * 1.Any code reachable from this function must not be placed in the targeted setcor. + * 2.if the sector[address:0x400~0x7ff] erased, before the POR, remind to program + * pflash-cfg-feild[0x400~0x41f] to proper value.Otherwise, system will enter security state, + * swd cannot be connected anymore + * 3.if the sector is in the eee backup region, the erase sequence will + * be aborted. + * 4.if the targeted sector is in protection region,the erase sequence will be aborted + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] destaddr : pointer to a address in the targeted sector + * \param[in] erasetype: erase type + */ +extern FlashDrv_Status FlashDrv_EraseSector(FlashDrvType *obj, + uint32_t *destaddr, + FlashDrv_SectorErase_t erasetype); + +/*! \brief Programs a section + * + * This function programs a section. The section should located in a sector or + * should be a total sector. Both the start addr and the size of the section are + * supposed to be 256-aligned. + * + * NOTE: 1.make sure targeted section is erased and not proteted before + * programmed; 2.if the target section is in the eee backup region, + * the program sequence will be aborted. + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] destaddr : pointer to a memory address in the targeted sector,256-aligned + * \param[in] len : length of programmed data in bytes, 256-aligned + * \param[in] databuf : pointer to source data + */ +extern FlashDrv_Status FlashDrv_ProgramSection(FlashDrvType *obj, + uint32_t *destaddr, + uint32_t len, + uint8_t *databuf); + +/*! \brief Programs a section + * + * This function programs a section fastly. The section should located in a sector or + * should be a total sector. Both the start addr and the size of the section are + * supposed to be 256-aligned. The programmed data is supposed to be prepared already in the flexram. + * + * NOTE: 1.make sure targeted section is erased and not proteted before + * programmed; 2.if the target section is in the eee backup region, + * the program sequence will be aborted.3.the programmed data has been placed in the flexram with + * correct offset(offset = dest & (FLASHDRV_SECTOR_SIZE - 1)) while ram ready. + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] destaddr : pointer to a memory address in the targeted sector,256-aligned + * \param[in] len : length of programmed data in bytes, 256-aligned + */ +extern FlashDrv_Status FlashDrv_ProgramSectionFast(FlashDrvType *obj, + uint32_t *destaddr, + uint32_t len); + +/*! \brief verify all blocks(pflash,dflash/e-flash) erased. + * + * This function verify all blocks [pflash,dflash]erased. + * + * NOTE: 1.make sure no proteted region in flash, otherwise the read1s sequence will + * be aborted; + * + * \param[in] obj : pointer to Flash driver instance + */ +extern FlashDrv_Status FlashDrv_Read1sAllBlock(FlashDrvType *obj); + +/*! \brief Reads a phrase(8 bytes) from flash info_region + * + * This function Read a phrase(8 bytes) from pflash info region or dflash info + * region. + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] regionid : FLASHDRV_INFORGN0 + * \param[in] phraseid : index of the phrase in the info region sector, 0 ~ 63 + * \param[in] databuf : pointer to a 8-byte-len buffer which data read from info region and write to + */ +extern FlashDrv_Status FlashDrv_ReadInfoRegion(FlashDrvType *obj, + FlashDrv_InfoRegion_t regionid, + uint8_t phraseid, + uint8_t *databuf); + +/*! \brief Programs a phrase(8 bytes) into flash info_region + * + * This function programs a phrase(8 bytes) into flash info_region + * + * NOTE: 1.make sure the targeted phrase can be programmed only one time through the lifecycle; + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] regionid : FLASHDRV_INFORGN0 + * \param[in] phraseid : index of the phrase in the info region sector, 0 ~ 63 + * \param[in] databuf : pointer to a 8-byte-len buffer which data read from info region and write to + */ +extern FlashDrv_Status FlashDrv_ProgramInfoRegion(FlashDrvType *obj, + FlashDrv_InfoRegion_t regionid, + uint32_t phraseid, + uint8_t *databuf); + +/*! \brief Erases all blocks(pflash, dflash/eflash, info-region). + * + * This function erases pflash, dflash/eflash, info-region. + * + * NOTE: + * 1.Any code reachable from this function must not be placed in a Flash + * block targeted for this erase operation. 2.Between the POR and + * allblock-erased operations, remind to program pflash-cfg-feild[0x400~0x41f] + * to proper value.Otherwise, system will enter security state, swd cannot be + * connected anymore. 3.if there is protection region in flash, the erase sequence + * will be aborted + * + * \param[in] obj : pointer to Flash driver instance + */ +extern FlashDrv_Status FlashDrv_EraseAllBlock(FlashDrvType *obj); + +/*! \brief Erases all blocks and update security bit in flash security info + * field. + * + * This function erase pflash,dflash/eflash, flash-info region ,and then program + * the security bit in flash security info field. + * + * NOTE: + * 1.Any code reachable from this function must not be placed in a Flash + * block targeted for this erase operation. 2.if MEEN disbled, the erase sequence + * will be aborted + * + * \param[in] obj : pointer to Flash driver instance + */ +extern FlashDrv_Status FlashDrv_EraseAllBlockUnsecure(FlashDrvType *obj); + +/*! \brief Verify the user backdoor key and make the system enter unsecurity + * state if pass. + * + * This function verify the user backdoor key stored in 0x400 with expected + * data.If the verified pass,the system will enter un-security state. + * + * NOTE: 1.if the KEY-EN disabled, this sequence will be aborted; + * + * \param[in] obj : pointer to Flash driver instance. + * \param[in] expdata : pointor to expected key-value, 8 bytes, supposed not to + * be all-0s or all-1s. + */ +extern FlashDrv_Status FlashDrv_VerifyUserKey(FlashDrvType *obj, + uint8_t *expdata); + +/*! \brief flash command done interrupt handler. + * + * \param[in] obj : pointer to Flash driver instance. + */ +extern void FlashDrv_IrqHandler(FlashDrvType *obj); + +/*! \brief flash command done interrupt enable in flash driver side. + * + * \param[in] obj : pointer to Flash driver instance. + * \param[in] en : control flag for the flash command done interrupter enable or disable + */ +extern void FlashDrv_SetCmdDoneIrqEn(FlashDrvType *obj, bool en); + +/*! \brief Get eee enable state + * + * This function gets the eee enable state + * + * \param[in] obj : pointer to Flash driver instance + * \return eee enable state + * - false : eee not enabled in Eeprom Cfg field.If EEE enable expected, progroram InfoRegion with correct data and then POR + * - true : eee enabled in Eeprom Cfg field + */ +extern bool FlashDrv_GetEeeEn(FlashDrvType *obj); + +/*! \brief Get eee_ram ready state + * + * This function gets the eeerst enable state + * + * \param[in] obj : pointer to Flash driver instance + * \return Eee_ram ready state + * - false : eee_ram not ready. + * - true : eee_ram ready. + */ +extern bool FlashDrv_GetEeeRamRdy(FlashDrvType *obj); + +/*! \brief sets the flexram as eee_ram or system_ram. + * + * \param[in] obj : pointer to Flash driver instance. + * \param[in] eeeramen : control eee_ram enabled or disabled, + * -false : the flex_ram will be used as system_ram + * -true : the flex_ram will be used as eeeram, UpdateEeeRam will take effect + */ +extern FlashDrv_Status FlashDrv_SetFlexRam(FlashDrvType *obj, bool eeeramen); + +/*! \brief updates eee_ram, data will be stored in flash. + * + *NOTE: 1.makesure the auto_gc(SCG0_Inst:TRIM_AUTO_GC_EN) enabled before this function called to + * avoid data overflowing and lost + * 2.makesure the eee_ram is enabled otherwise the new data will be lost + * + * \param[in] obj : pointer to Flash driver instance. + * \param[in] offset : indicates the targeted position in the eee_ram, range is [0 ~ 2048] + * \param[in] srcdata : pointer to srcdata which will be wrote into eee_ram + * \param[in] sz: len of srcdata in byte + */ +extern FlashDrv_Status FlashDrv_UpdateEeeRam(FlashDrvType *obj, uint32_t offset, uint8_t *srcdata, uint32_t sz); + +/*! \brief Gets eee auto GC enable state + * + * This function gets the eee auto GC enable state + * + * \param[in] obj : pointer to Flash driver instance + * \return eee auto GC enable state + * - false : eee auto GC disabled + * - true : eee auto GC enabled + */ +extern bool FlashDrv_GetEeeAutoGcEn(FlashDrvType *obj); + +/*! \brief Sets eee auto GC enable + * + * This function sets the eee auto GC enabled or disabled + * + * \param[in] obj : pointer to Flash driver instance + * \param[in] eeegcen : control eee auto gc enabled or disabled, + * -false : the eee auto gc disabled + * -true : the eee auto gc enabled + */ +extern void FlashDrv_SetEeeAutoGcEn(FlashDrvType *obj, bool eeegcen); + +/*! \brief Gets eee_ram protection property + * + * This function gets the eee_ram protection property + * + * \param[in] obj : pointer to Flash driver instance + * \param[out] protectStatus : pointer to protection status + * - 0b : unprotect + * - 1b : protect + */ +extern FlashDrv_Status FlashDrv_GetEeeRamProtection(FlashDrvType *obj, uint8_t *protectstatus); + +/*! \brief Gets PFlash protection property + * + * This function gets the PFlash protection property + * + * \param[in] obj : pointer to Flash driver instance + * \param[out] protectStatus : pointer to protection status + * - 0b : unprotect + * - 1b : protect + */ +extern FlashDrv_Status FlashDrv_GetPFlashProtection(FlashDrvType *obj, uint32_t *protectstatus); + +/*! \brief Gets DFlash protection property + * + * This function gets the DFlash protection property + * + * \param[in] obj : pointer to Flash driver instance + * \param[out] protectStatus : pointer to protection status + * - 0b : unprotect + * - 1b : protect + */ +extern FlashDrv_Status FlashDrv_GetDFlashProtection(FlashDrvType *obj, uint8_t *protectstatus); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _FLASH_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/flexcan/flexcan_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/flexcan/flexcan_drv.c new file mode 100644 index 0000000..bbc753f --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/flexcan/flexcan_drv.c @@ -0,0 +1,1253 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "flexcan_drv.h" +#include "flexcan_reg.h" +#include "pcc0_reg.h" +#include "pcc1_reg.h" +#include "scg0_reg.h" +#include "scg2_reg.h" +#include "sim_reg.h" +#include "../../CVM011x_features.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define FLEXCAN_DRV_CAN_RAM_SIZE (512U) + +#define RX_FIFO_FILT_TABLE_ADD_OFFSET (0xE0U) + +#define TX_PENDING_ABORT_SUCCESS 1 +#define TX_PENDING_ABORT_NO_TRANSFER 0 +#define TX_PENDING_ABORT_FAILED (0xFFU) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +static inline uint8_t FlexCanDrv_ConvertMsgBufSizeSel(uint8_t MBSizeCode) +{ + uint8_t result = 0; + + switch(MBSizeCode) + { + case FLEXCANDRV_MB_SIZE_BYTE_8: + result = 16; + break; + case FLEXCANDRV_MB_SIZE_BYTE_16: + result = 24; + break; + case FLEXCANDRV_MB_SIZE_BYTE_32: + result = 40; + break; + case FLEXCANDRV_MB_SIZE_BYTE_64: + result = 72; + break; + } + + return result; +} + +static inline uint32_t FlexCanDrv_GetMsgBufStartAddr(FlexCanDrvType *obj, uint16_t msgBufId) +{ + /* get the first message buffer start address */ + uint32_t addr = FlexCanReg_GetMsgBufferStartAddr(obj->flexCanReg); + uint8_t msgBufSize = 0; + + /* get the message buffer size */ +#if FEATURE_CAN_FD_INSTANCE_NUM == 0 && FEATURE_CAN_2_0_INSTANCE_NUM == 1 + uint8_t msgBufSizeSel = FLEXCANDRV_MB_SIZE_BYTE_8; +#elif FEATURE_CAN_FD_INSTANCE_NUM == 1 && FEATURE_CAN_2_0_INSTANCE_NUM == 0 + uint8_t msgBufSizeSel = FlexCanReg_GetRegionDataSizeSel(obj->flexCanReg, 0); +#else +#error "Not matching CVM011x chip definition." +#endif + msgBufSize = FlexCanDrv_ConvertMsgBufSizeSel(msgBufSizeSel) / 4; + + if(msgBufSizeSel == FLEXCANDRV_MB_SIZE_BYTE_8) + { + addr += (msgBufSize * msgBufId) * 4; + } + else if(msgBufSizeSel == FLEXCANDRV_MB_SIZE_BYTE_16) + { + addr += (msgBufSize * msgBufId + (2 * (msgBufId / 21))) * 4; + } + else if(msgBufSizeSel == FLEXCANDRV_MB_SIZE_BYTE_32) + { + addr += (msgBufSize * msgBufId + (8 * (msgBufId / 12))) * 4; + } + else + { + addr += (msgBufSize * msgBufId + (2 * (msgBufId / 7))) * 4; + } + + return addr; +} + +static inline uint8_t FlexCanDrv_DLC2DataLen(FlexCanDrv_DLCType dlc) +{ + uint8_t dataLen = 0; + + switch(dlc) + { + case DLC_BYTE_0: + case DLC_BYTE_1: + case DLC_BYTE_2: + case DLC_BYTE_3: + case DLC_BYTE_4: + case DLC_BYTE_5: + case DLC_BYTE_6: + case DLC_BYTE_7: + case DLC_BYTE_8: + dataLen = (uint8_t)dlc; + break; + case DLC_BYTE_12: + dataLen = 12; + break; + case DLC_BYTE_16: + dataLen = 16; + break; + case DLC_BYTE_20: + dataLen = 20; + break; + case DLC_BYTE_24: + dataLen = 24; + break; + case DLC_BYTE_32: + dataLen = 32; + break; + case DLC_BYTE_48: + dataLen = 48; + break; + case DLC_BYTE_64: + dataLen = 64; + break; + default: + break; + } + + return dataLen; +} + +static inline uint8_t FlexCanDrv_GetMsgBufDataLen(FlexCanDrvType *obj, uint16_t msgBufId) +{ + uint32_t *msgBufPtr; + uint8_t dlc = 0; + uint8_t dataLen = 0; + + /* get current message buffer start address */ + msgBufPtr = (uint32_t *)FlexCanDrv_GetMsgBufStartAddr(obj, msgBufId); + + /* get DLC code from message buffer */ + dlc = (*msgBufPtr & MESSAGE_BUFFER_CS_DLC_MASK) >> MESSAGE_BUFFER_CS_DLC_SHIFT; + + /* convert DLC code to data length */ + dataLen = FlexCanDrv_DLC2DataLen((FlexCanDrv_DLCType)dlc); + + return dataLen; +} + +static inline void FlexCanDrv_SetMsgId(uint32_t *msgBufPtr, uint32_t msgId, bool isExt) +{ + uint32_t tempVar = 0; + + if(isExt) + { + /* set extended message ID bit (IDE) */ + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] |= (MESSAGE_BUFFER_CS_IDE_MASK | MESSAGE_BUFFER_CS_SRR_MASK); + + /* set extended message ID */ + tempVar = msgBufPtr[MESSAGE_BUFFER_ID_WORD_NUM]; + tempVar &= ~(MESSAGE_BUFFER_ID_EXT_ID_MASK); + tempVar |= ((msgId << MESSAGE_BUFFER_ID_EXT_ID_SHIFT) & MESSAGE_BUFFER_ID_EXT_ID_MASK); + msgBufPtr[MESSAGE_BUFFER_ID_WORD_NUM] = tempVar; + } + else + { + /* clear extended message ID bit (IDE) */ + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] &= ~(MESSAGE_BUFFER_CS_IDE_MASK | MESSAGE_BUFFER_CS_SRR_MASK); + + /* load standard message ID */ + tempVar = msgBufPtr[MESSAGE_BUFFER_ID_WORD_NUM]; + tempVar &= ~(MESSAGE_BUFFER_ID_STD_ID_MASK); + tempVar |= ((msgId << MESSAGE_BUFFER_ID_STD_ID_SHIFT) & MESSAGE_BUFFER_ID_STD_ID_MASK); + msgBufPtr[MESSAGE_BUFFER_ID_WORD_NUM] = tempVar; + } +} + +static inline void FlexCanDrv_SetMsgDLC(uint32_t *msgBufPtr, FlexCanDrv_DLCType dlc) +{ + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] &= (~MESSAGE_BUFFER_CS_DLC_MASK); + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] |= (((uint32_t)dlc) << MESSAGE_BUFFER_CS_DLC_SHIFT & MESSAGE_BUFFER_CS_DLC_MASK); +} + +static inline void FlexCanDrv_SetFDEnable(uint32_t *msgBufPtr, bool fdEnable) +{ + /* clear EDL bit */ + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] &= (~MESSAGE_BUFFER_CS_EDL_MASK); + /* clear BRS bit */ + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] &= (~MESSAGE_BUFFER_CS_BRS_MASK); + + if(fdEnable) + { + /* set EDL bit */ + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] |= MESSAGE_BUFFER_CS_EDL_MASK; + /* set BRS bit */ + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] |= MESSAGE_BUFFER_CS_BRS_MASK; + } + else + { + /* non CAN-FD keep EDL, BRS bit clear */ + } +} + +static inline void FlexCanDrv_SetMsgType(uint32_t *msgBufPtr, FlexCanDrv_MsgType_t msgType) +{ + if(msgType == FLEXCANDRV_MSGTYPE_TX) + { + /* tx message set CODE as INACTIVE */ + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] &= (~MESSAGE_BUFFER_CS_CODE_MASK); + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] |= ((FLEXCANDRV_MSG_BUF_CODE_INACTIVE << MESSAGE_BUFFER_CS_CODE_SHIFT) & MESSAGE_BUFFER_CS_CODE_MASK); + } + else if(msgType == FLEXCANDRV_MSGTYPE_RX) + { + /* rx message set CODE as RX_ACTIVE */ + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] &= (~MESSAGE_BUFFER_CS_CODE_MASK); + msgBufPtr[MESSAGE_BUFFER_CS_WORD_NUM] |= ((FLEXCANDRV_MSG_BUF_CODE_RX_ACTIVE << MESSAGE_BUFFER_CS_CODE_SHIFT) & MESSAGE_BUFFER_CS_CODE_MASK); + } + else + { + } +} + +static inline void FlexCanDrv_InitCanRAM(FlexCanDrvType *obj) +{ + uint32_t *u32Ptr = (uint32_t *)FlexCanReg_GetMsgBufferStartAddr(obj->flexCanReg); + uint32_t *tempPtr; + uint32_t i = 0; + + /* 0x80 - 0x480: message buffer 512 byte * 2 region */ + for(i = 0; i < 128 * obj->initHwPar.canRamNum; i++) + { + tempPtr = (u32Ptr + i); + *tempPtr = 0; + } +} + +static inline void FlexCanDrv_EnableCanCfgClk(FlexCanDrvType *obj) +{ + /* unlock PCC key */ + Pcc0Reg_SetKey(obj->pcc0Reg, 0x55534552); + /* enable CAN CFG clock */ + Pcc1Reg_SetCanCfgCkEn(obj->pcc1Reg, 1); + /* lock PCC key again */ + Pcc0Reg_SetKey(obj->pcc0Reg, 0); +} + +static inline void FlexCanDrv_EnableCanOperationClk(FlexCanDrvType *obj) +{ + /* unlock PCC key */ + Pcc0Reg_SetKey(obj->pcc0Reg, 0x55534552); + /* enable CAN operation clock */ + Pcc1Reg_SetCanCkEn(obj->pcc1Reg, 1); + /* lock PCC key again */ + Pcc0Reg_SetKey(obj->pcc0Reg, 0); +} + +void FlexCanDrv_Init(FlexCanDrvType *obj, + struct _FlexCanRegType_ *flexCanReg, + struct _Pcc1RegType_ *pcc1Reg, + struct _Pcc0RegType_ *pcc0Reg, + struct _Scg0RegType_ *scg0Reg, + struct _Scg2RegType_ *scg2Reg, + struct _SimRegType_ *simReg, + FlexCanDrv_InitHwParType *initHwPar) +{ + obj->initHwPar.canRamNum = initHwPar->canRamNum; + obj->flexCanReg = flexCanReg; + obj->pcc1Reg = pcc1Reg; + obj->pcc0Reg = pcc0Reg; + obj->scg0Reg = scg0Reg; + obj->scg2Reg = scg2Reg; + obj->simReg = simReg; +} + +void FlexCanDrv_GetDefaultCfg(FlexCanDrv_ControllerCfgType *controllerCfg) +{ + uint8_t i = 0; + + controllerCfg->bitTiming.prescalerDiv = 0; + controllerCfg->bitTiming.propSeg = 0; + controllerCfg->bitTiming.phaseSeg1 = 0; + controllerCfg->bitTiming.phaseSeg2 = 0; + controllerCfg->bitTiming.resyncJumpWidth = 0; + controllerCfg->fdBitTiming.prescalerDiv = 0; + controllerCfg->fdBitTiming.propSeg = 0; + controllerCfg->fdBitTiming.phaseSeg1 = 0; + controllerCfg->fdBitTiming.phaseSeg2 = 0; + controllerCfg->fdBitTiming.resyncJumpWidth = 0; + controllerCfg->clkSrc = FLEXCANDRV_CLKSRC_CHICLK; + controllerCfg->fifoEnable = 0; + controllerCfg->dmaEnable = 0; + controllerCfg->rxMBGlobalMask = 0xFFFFFFFF; + controllerCfg->rxMB14Mask = 0xFFFFFFFF; + controllerCfg->rxMB15Mask = 0xFFFFFFFF; + controllerCfg->rxFifoGlobalMask = 0xFFFFFFFF; + controllerCfg->rxFifoFiltFormat = FLEXCANDRV_RXFIFO_FILTFORMAT_A; + controllerCfg->rxFifoFilterNum = 0; + controllerCfg->individualMaskEnable = 0; + controllerCfg->rxFifoIndivMskNum = 8; + for(i = 0; i < 32; i ++) + { + controllerCfg->rxFifoIndivMsk[i] = 0xFFFFFFFF; + } + controllerCfg->fdEnable = 0; + controllerCfg->fdISOEnable = 0; + controllerCfg->msgBufDataLenSel = FLEXCANDRV_MB_SIZE_BYTE_8; + controllerCfg->loopbackEnable = 0; + controllerCfg->tdcEnable = 0; + controllerCfg->tdcOffset = 0; + controllerCfg->txAbortEnable = 0; + controllerCfg->edgeWkupEnable = 0; + controllerCfg->busoffIntEnable = 0; + controllerCfg->errorIntEnable = 0; + controllerCfg->msgNum = 0; + controllerCfg->msgCfg = (void *)0; +} + +void FlexCanDrv_Start(FlexCanDrvType *obj) +{ + /* set freeze mode disable */ + FlexCanReg_SetFreezeMode(obj->flexCanReg, false); + /* set halt mode disable */ + FlexCanReg_SetHaltMode(obj->flexCanReg, false); + + /* wait for synchronization */ + while(FlexCanReg_GetFreezeAck(obj->flexCanReg)) + { + } +} + +void FlexCanDrv_SoftReset(FlexCanDrvType *obj) +{ + /* check for low power mode */ + if(FlexCanReg_GetLowPowerAck(obj->flexCanReg)) + { + /* Enable clock */ + FlexCanReg_SetModuleDisable(obj->flexCanReg, false); + /* wait until enabled */ + while(FlexCanReg_GetLowPowerAck(obj->flexCanReg)) + { + /* enable CAN operation clock */ + FlexCanDrv_EnableCanOperationClk(obj); + } + } + + /* Reset the CAN module */ + FlexCanReg_SetSoftResetRequest(obj->flexCanReg, true); + /* Wait for reset cycle to complete */ + while(FlexCanReg_GetSoftResetRequest(obj->flexCanReg)) + { + } + + /* set freeze mode enable */ + FlexCanReg_SetFreezeMode(obj->flexCanReg, true); + /* set halt mode enable */ + FlexCanReg_SetHaltMode(obj->flexCanReg, true); + + /* check for freeze Ack */ + while((FlexCanReg_GetFreezeAck(obj->flexCanReg) == 0) || (FlexCanReg_GetNotReadyFlag(obj->flexCanReg) == 0)) + { + /* soft reset failed */ + } +} + +void FlexCanDrv_CfgMsgObj(FlexCanDrvType *obj, const FlexCanDrv_MsgCfgType *msgCfg, uint8_t msgBufId) +{ + FlexCanDrv_MsgObjType msgObj; + uint32_t *msgBufPtr; + + /* get current message buffer start address */ + msgBufPtr = (uint32_t *)FlexCanDrv_GetMsgBufStartAddr(obj, msgBufId); + + /* set message ID */ + FlexCanDrv_SetMsgId(msgBufPtr, msgCfg->msgId, msgCfg->isExtMsgId); + + /* set message DLC */ + FlexCanDrv_SetMsgDLC(msgBufPtr, msgCfg->dlc); + + /* set FD configures */ + FlexCanDrv_SetFDEnable(msgBufPtr, msgCfg->isFd); + + /* set message type */ + FlexCanDrv_SetMsgType(msgBufPtr, msgCfg->msgType); + + if(msgCfg->intEnable) + { + msgObj.msgBufId = msgBufId; + /* set message buffer interrupt enable */ + FlexCanDrv_EnableMsgObjInterrupt(obj, &msgObj); + } + else + { + /* message buffer interrupt disable, do nothing */ + } + + if(msgCfg->msgType == FLEXCANDRV_MSGTYPE_RX) + { + /* set message buffer individual mask */ + FlexCanReg_SetRxIndividualMask(obj->flexCanReg, msgBufId, msgCfg->individualMask); + } + else + { + /* current message buffer is Tx message no need to configure individual mask */ + } +} + +void FlexCanDrv_Configure(FlexCanDrvType *obj, const FlexCanDrv_ControllerCfgType *controllerCfg) +{ + uint8_t msgBufSize; + uint8_t msgBufNum = 0; + uint8_t i = 0; + + /* enable CAN CFG clock */ + FlexCanDrv_EnableCanCfgClk(obj); + + /* disable FlexCan module */ + FlexCanReg_SetModuleDisable(obj->flexCanReg, true); + + /* make sure that the module has enter into low power mode successfully */ + while(FlexCanReg_GetLowPowerAck(obj->flexCanReg) == 0) + { + + } + + /* configure FlexCan clock source */ + FlexCanReg_SetClockSource(obj->flexCanReg, controllerCfg->clkSrc); + + /* reset CAN internal status */ + FlexCanDrv_SoftReset(obj); + + /* switch to supervisor mode */ + FlexCanReg_SetAccessMode(obj->flexCanReg, FLEXCANDRV_CAN_ACCESS_MODE_SUP); + + /* enable write access in freeze mode */ + FlexCanReg_SetFreezeModeWriteAcc(obj->flexCanReg, true); + + /* initial can ram */ + FlexCanDrv_InitCanRAM(obj); + + /* calculate the total message number according to the message + * buffer size per region */ + msgBufSize = FlexCanDrv_ConvertMsgBufSizeSel(controllerCfg->msgBufDataLenSel); + if(msgBufSize != 0) + { + msgBufNum = (FLEXCAN_DRV_CAN_RAM_SIZE / msgBufSize) * obj->initHwPar.canRamNum; + } + /* set message buffer maximum number */ + FlexCanReg_SetMaxMsgBufferNum(obj->flexCanReg, msgBufNum); + + /* + * set standard CAN bit timing + */ + /* enable CAN extended bit timing */ + FlexCanReg_SetExtendedBitTimingEnable(obj->flexCanReg, true); + /* set prescaler division */ + FlexCanReg_SetExtPresalerDivision(obj->flexCanReg, controllerCfg->bitTiming.prescalerDiv - 1); + /* set resync jump width */ + FlexCanReg_SetExtResyncJumpWidth(obj->flexCanReg, controllerCfg->bitTiming.resyncJumpWidth - 1); + /* set propagation segment */ + FlexCanReg_SetExtPorpSeg(obj->flexCanReg, controllerCfg->bitTiming.propSeg - 1); + /* set phase segment 1 */ + FlexCanReg_SetExtPhaseSeg1(obj->flexCanReg, controllerCfg->bitTiming.phaseSeg1 - 1); + /* set phase segment 2 */ + FlexCanReg_SetExtPhaseSeg2(obj->flexCanReg, controllerCfg->bitTiming.phaseSeg2 - 1); + + if(controllerCfg->fifoEnable) + { + /* set Rx FIFO enable */ + FlexCanReg_SetRxFIFOEnalbe(obj->flexCanReg, true); + /* set Rx FIFO DMA enable */ + FlexCanReg_SetRxFIFODmaEnable(obj->flexCanReg, controllerCfg->dmaEnable); + /* set Rx FIFO global mask */ + FlexCanReg_SetRxFifoGlobalMask(obj->flexCanReg, controllerCfg->rxFifoGlobalMask); + /* set Rx FIFO ID filter format */ + FlexCanReg_SetRxFifoFiltMode(obj->flexCanReg, controllerCfg->rxFifoFiltFormat); + /* set Rx FIFO filter number code */ + FlexCanReg_SetRxFifoFilterNum(obj->flexCanReg, controllerCfg->rxFifoFilterNum); + /* set Rx Individual mask dedicated for Rx FIFO */ + if(controllerCfg->individualMaskEnable == true) + { + for(i = 0; i < controllerCfg->rxFifoIndivMskNum; i ++) + { + FlexCanReg_SetRxIndividualMask(obj->flexCanReg, i, controllerCfg->rxFifoIndivMsk[i]); + } + } + } + else + { + /* set Rx FIFO disable */ + FlexCanReg_SetRxFIFOEnalbe(obj->flexCanReg, false); + /* disable Rx FIFO DMA */ + FlexCanReg_SetRxFIFODmaEnable(obj->flexCanReg, false); + } + +#if FEATURE_CAN_FD_INSTANCE_NUM == 1 && FEATURE_CAN_2_0_INSTANCE_NUM == 0 + if(controllerCfg->fdEnable) + { + /* set CAN FD operation enable */ + FlexCanReg_SetFdEnable(obj->flexCanReg, controllerCfg->fdEnable); + /* enable FD rate switch */ + FlexCanReg_SetFdRateSwitch(obj->flexCanReg, true); + + /* set FD prescaler division */ + FlexCanReg_SetFdPrescalerDivision(obj->flexCanReg, controllerCfg->fdBitTiming.prescalerDiv - 1); + /* set FD resync jump width */ + FlexCanReg_SetFdResyncJumpWidth(obj->flexCanReg, controllerCfg->fdBitTiming.resyncJumpWidth - 1); + /* set FD propagation segment */ + FlexCanReg_SetFdPorpSeg(obj->flexCanReg, controllerCfg->fdBitTiming.propSeg); + /* set FD phase segment 1 */ + FlexCanReg_SetFdPhaseSeg1(obj->flexCanReg, controllerCfg->fdBitTiming.phaseSeg1 - 1); + /* set FD phase segment 2 */ + FlexCanReg_SetFdPhaseSeg2(obj->flexCanReg, controllerCfg->fdBitTiming.phaseSeg2 - 1); + + /* set region 0 data size selection */ + FlexCanReg_SetRegionDataSizeSel(obj->flexCanReg, 0, controllerCfg->msgBufDataLenSel); + /* set region 1 data size selection */ + FlexCanReg_SetRegionDataSizeSel(obj->flexCanReg, 1, controllerCfg->msgBufDataLenSel); + /* set region 2 data size selection */ + FlexCanReg_SetRegionDataSizeSel(obj->flexCanReg, 2, controllerCfg->msgBufDataLenSel); + /* set region 3 data size selection */ + FlexCanReg_SetRegionDataSizeSel(obj->flexCanReg, 3, controllerCfg->msgBufDataLenSel); + + /* set TDC enable */ + FlexCanReg_SetTdcEnable(obj->flexCanReg, controllerCfg->tdcEnable); + /* set TDC offset */ + FlexCanReg_SetTdcOffset(obj->flexCanReg, controllerCfg->tdcOffset); + + /* set CAN-FD ISO enable */ + FlexCanReg_SetIsoFdEnalbe(obj->flexCanReg, controllerCfg->fdISOEnable); + } +#endif + + /* set rx mailbox global mask */ + FlexCanReg_SetRxMailboxGlobalMask(obj->flexCanReg, controllerCfg->rxMBGlobalMask); + /* set rx mailbox 14 mask */ + FlexCanReg_SetRxMailbox14Mask(obj->flexCanReg, controllerCfg->rxMB14Mask); + /* set rx mailbox 15 mask */ + FlexCanReg_SetRxMailbox15Mask(obj->flexCanReg, controllerCfg->rxMB15Mask); + /* set individual Rx masking and queue enable */ + FlexCanReg_SetIndividualMaskEnable(obj->flexCanReg, controllerCfg->individualMaskEnable); + + /* loopback mode configuration */ + if(controllerCfg->loopbackEnable) + { + FlexCanReg_SetSelfReceptionDisable(obj->flexCanReg, false); /* enable self reception (0) */ + FlexCanReg_SetLoopbackMode(obj->flexCanReg, true); /* enable loop-back */ + } + else + { + FlexCanReg_SetSelfReceptionDisable(obj->flexCanReg, true); /* disable self reception (1) */ + FlexCanReg_SetLoopbackMode(obj->flexCanReg, false); /* disable loop-back */ + } + + /* edge wakeup configuration */ + if(controllerCfg->edgeWkupEnable) + { + /* enable edge(self) wakeup */ + FlexCanReg_SetSelfWakeupEnable(obj->flexCanReg, 1U); + /* enable edge(self) wakeup interrupt */ + FlexCanReg_SetWakeupIntMask(obj->flexCanReg, 1U); + /* enable doze mode request */ + FlexCanReg_SetDozeMode(obj->flexCanReg, 1U); + /* enable sleep wakeup in SIM */ + SimReg_SetCanWkupSrcSel(obj->simReg, 1); + } + else + { + /* disable edge(self) wakeup */ + FlexCanReg_SetSelfWakeupEnable(obj->flexCanReg, 0U); + /* disable edge(self) wakeup interrupt */ + FlexCanReg_SetWakeupIntMask(obj->flexCanReg, 0U); + /* disable doze mode request */ + FlexCanReg_SetDozeMode(obj->flexCanReg, 0U); + /* disable sleep wakeup in SIM */ + SimReg_SetCanWkupSrcSel(obj->simReg, 0); + } + + /* set Tx message abort enable */ + FlexCanReg_SetTxAbortEnable(obj->flexCanReg, controllerCfg->txAbortEnable); + + /* set busoff interrupt enable mask */ + FlexCanReg_SetBusOffIntEnable(obj->flexCanReg, controllerCfg->busoffIntEnable); + /* set error interrupt enable mask */ + FlexCanReg_SetErrorIntEnable(obj->flexCanReg, controllerCfg->errorIntEnable); + + /* configure messages */ + for(i = 0; i < controllerCfg->msgNum; i++) + { + uint16_t j = 0; + /* configure messages according to the message buffer Id and message buffer length parameters */ + for(j = controllerCfg->msgCfg[i].msgBufId; j < controllerCfg->msgCfg[i].msgBufId + controllerCfg->msgCfg[i].msgBufLen; j++) + { + FlexCanDrv_CfgMsgObj(obj, &controllerCfg->msgCfg[i], j); + } + } + + /* clear all message buffer flags */ + FlexCanDrv_ClearAllMsgObjFlags(obj); + + /* enable FlexCan module */ + FlexCanDrv_Start(obj); + + /* switch to user mode */ + FlexCanReg_SetAccessMode(obj->flexCanReg, FLEXCANDRV_CAN_ACCESS_MODE_USER); +} + +void FlexCanDrv_TransmitMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj) +{ + uint32_t *msgBufPtr; + + /* get current message buffer start address */ + msgBufPtr = (uint32_t *)FlexCanDrv_GetMsgBufStartAddr(obj, msgObj->msgBufId); + + /* set transmit code for the message buffer and start transmitting */ + *msgBufPtr |= (((uint32_t)FLEXCANDRV_MSG_BUF_CODE_TX_REQUEST) << FLEXCANDRV_MSG_BUF_CODE_SHIFT); +} + +void FlexCanDrv_SetTxMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj) +{ + uint32_t *msgBufPtr; + uint32_t dataLen; + + /* get current message buffer start address */ + msgBufPtr = (uint32_t *)FlexCanDrv_GetMsgBufStartAddr(obj, msgObj->msgBufId); + /* add data field address offset (2 * 32 bit) */ + msgBufPtr += 2; + + /* get data length from message buffer DLC */ + dataLen = FlexCanDrv_GetMsgBufDataLen(obj, msgObj->msgBufId); + + /* load the data into message buffer */ + uint8_t i = 0; + for(i = 0; i < dataLen; i++) + { + /* load the data in byte length */ + if((i % 4) == 0) + { + /* clean the old data */ + *msgBufPtr = 0; + + /* lowest byte in 32-bit */ + *msgBufPtr |= (((uint32_t)msgObj->data[i]) << 24); + } + else if((i % 4) == 1) + { + /* 2nd byte in 32-bit */ + *msgBufPtr |= (((uint32_t)msgObj->data[i]) << 16); + } + else if((i % 4) == 2) + { + /* 3rd byte in 32-bit */ + *msgBufPtr |= (((uint32_t)msgObj->data[i]) << 8); + } + else if((i % 4) == 3) + { + /* highest byte in 32-bit */ + *msgBufPtr |= ((uint32_t)msgObj->data[i]); + + /* increment the 32-bit data pointer */ + msgBufPtr++; + } + } +} + +void FlexCanDrv_GetRxMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj) +{ + uint32_t *msgBufPtr; + uint8_t dataLen; + bool isExtMsgId; + + /* get current message buffer start address */ + msgBufPtr = (uint32_t *)FlexCanDrv_GetMsgBufStartAddr(obj, msgObj->msgBufId); + + /* get the rx message DLC */ + msgObj->dlc = FlexCanDrv_DLC2DataLen((FlexCanDrv_DLCType)((*msgBufPtr & MESSAGE_BUFFER_CS_DLC_MASK) >> MESSAGE_BUFFER_CS_DLC_SHIFT)); + /* get extended message ID bit (CS.IDE) */ + isExtMsgId = (*msgBufPtr & MESSAGE_BUFFER_CS_IDE_MASK) >> MESSAGE_BUFFER_CS_IDE_SHIFT; + + /* set message buffer pointer to ID field */ + msgBufPtr++; + + /* get message ID */ + if(isExtMsgId == true) + { + msgObj->msgId = (*msgBufPtr & MESSAGE_BUFFER_ID_EXT_ID_MASK) >> MESSAGE_BUFFER_ID_EXT_ID_SHIFT; + } + else + { + msgObj->msgId = (*msgBufPtr & MESSAGE_BUFFER_ID_STD_ID_MASK) >> MESSAGE_BUFFER_ID_STD_ID_SHIFT; + } + + /* set the message buffer pointer to data field */ + msgBufPtr++; + + /* get data length from message buffer DLC */ + dataLen = FlexCanDrv_GetMsgBufDataLen(obj, msgObj->msgBufId); + + /* load the data from message buffer to data array */ + uint8_t i = 0; + for(i = 0; i < dataLen; i++) + { + if((i % 4) == 0) + { + /* load 1 byte data from highest byte in 32-bit */ + msgObj->data[i] = (*msgBufPtr >> 24); + } + else if((i % 4) == 1) + { + /* load 1 byte data from 2nd highest byte in 32-bit */ + msgObj->data[i] = (*msgBufPtr >> 16); + } + else if((i % 4) == 2) + { + /* load 1 byte data from 3nd highest byte in 32-bit */ + msgObj->data[i] = (*msgBufPtr >> 8); + } + /* when (i % 4) == 3 */ + else + { + /* load 1 byte data from lowest byte in 32-bit */ + msgObj->data[i] = (*msgBufPtr >> 0); + + /* increment message buffer 32-bit data pointer */ + msgBufPtr++; + } + } + + /* unlock mailbox globally */ + FlexCanReg_GetFreeRunningTimer(obj->flexCanReg); +} + +void FlexCanDrv_GetRxFifoMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj) +{ + bool isExtMsgId; + FlexCanDrv_MsgObjType tempMsgObj; + + /* get Rx FIFO out port start address (message buffer 0) */ + uint32_t *msgBufPtr = (uint32_t *)FlexCanDrv_GetMsgBufStartAddr(obj, 0); + + /* get the rx message DLC */ + msgObj->dlc = FlexCanDrv_DLC2DataLen((FlexCanDrv_DLCType)((*msgBufPtr & MESSAGE_BUFFER_CS_DLC_MASK) >> MESSAGE_BUFFER_CS_DLC_SHIFT)); + /* get extended message ID bit (CS.IDE) */ + isExtMsgId = (*msgBufPtr & MESSAGE_BUFFER_CS_IDE_MASK) >> MESSAGE_BUFFER_CS_IDE_SHIFT; + + /* set message buffer pointer to ID field */ + msgBufPtr++; + + /* get message ID */ + if(isExtMsgId == true) + { + msgObj->msgId = (*msgBufPtr & MESSAGE_BUFFER_ID_EXT_ID_MASK) >> MESSAGE_BUFFER_ID_EXT_ID_SHIFT; + } + else + { + msgObj->msgId = (*msgBufPtr & MESSAGE_BUFFER_ID_STD_ID_MASK) >> MESSAGE_BUFFER_ID_STD_ID_SHIFT; + } + + /* set message buffer pointer to DATA field */ + msgBufPtr++; + + /* load the data from message buffer to data array */ + uint8_t i = 0; + for(i = 0; i < 8; i++) + { + if((i % 4) == 0) + { + /* load 1 byte data from highest byte in 32-bit */ + msgObj->data[i] = (*msgBufPtr >> 24); + } + else if((i % 4) == 1) + { + /* load 1 byte data from 2nd highest byte in 32-bit */ + msgObj->data[i] = (*msgBufPtr >> 16); + } + else if((i % 4) == 2) + { + /* load 1 byte data from 3nd highest byte in 32-bit */ + msgObj->data[i] = (*msgBufPtr >> 8); + } + /* when (i % 4) == 3 */ + else + { + /* load 1 byte data from lowest byte in 32-bit */ + msgObj->data[i] = (*msgBufPtr >> 0); + + /* increment message buffer 32-bit data pointer */ + msgBufPtr++; + } + } + + /* clear Rx FIFO available flag to update Rx FIFO */ + tempMsgObj.msgBufId = 5; + FlexCanDrv_ClearMsgObjFlag(obj, &tempMsgObj); +} + +void FlexCanDrv_ClearMsgObjFlag(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj) +{ + uint32_t temp, temp1 = 0; + + temp1 = msgObj->msgBufId % 32; + temp = 0x00000001 << temp1; + + if(msgObj->msgBufId > 63) + { + FlexCanReg_SetMsgBufInterruptFlagReg(obj->flexCanReg, 2, temp); + } + else if(msgObj->msgBufId > 31) + { + FlexCanReg_SetMsgBufInterruptFlagReg(obj->flexCanReg, 1, temp); + } + else + { + FlexCanReg_SetMsgBufInterruptFlagReg(obj->flexCanReg, 0, temp); + } +} + +uint8_t FlexCanDrv_GetMsgObjFlag(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj) +{ + uint32_t temp, temp1 = 0; + temp1 = msgObj->msgBufId % 32; + temp = 0x00000001 << temp1; + + if(msgObj->msgBufId > 63) + { + temp &= FlexCanReg_GetMsgBufInterruptFlagReg(obj->flexCanReg, 2); + } + else if(msgObj->msgBufId > 31) + { + temp &= FlexCanReg_GetMsgBufInterruptFlagReg(obj->flexCanReg, 1); + } + else + { + temp &= FlexCanReg_GetMsgBufInterruptFlagReg(obj->flexCanReg, 0); + } + + if(temp) + { + return (1); + } + else + { + return (0); + } +} + +void FlexCanDrv_ClearAllMsgObjFlags(FlexCanDrvType *obj) +{ + if(obj->initHwPar.canRamNum == 3) + { + FlexCanReg_SetMsgBufInterruptFlagReg(obj->flexCanReg, 2, 0xFFFFFFFF); + FlexCanReg_SetMsgBufInterruptFlagReg(obj->flexCanReg, 1, 0xFFFFFFFF); + FlexCanReg_SetMsgBufInterruptFlagReg(obj->flexCanReg, 0, 0xFFFFFFFF); + } + else if(obj->initHwPar.canRamNum == 2) + { + FlexCanReg_SetMsgBufInterruptFlagReg(obj->flexCanReg, 1, 0xFFFFFFFF); + FlexCanReg_SetMsgBufInterruptFlagReg(obj->flexCanReg, 0, 0xFFFFFFFF); + } + else if(obj->initHwPar.canRamNum == 1) + { + FlexCanReg_SetMsgBufInterruptFlagReg(obj->flexCanReg, 0, 0xFFFFFFFF); + } +} + +void FlexCanDrv_EnableMsgObjInterrupt(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj) +{ + uint32_t temp, temp1 = 0; + temp1 = msgObj->msgBufId % 32; + temp = 0x00000001 << temp1; + if(msgObj->msgBufId > 63) + { + FlexCanReg_SetMsgBufInterruptEnable(obj->flexCanReg, 2, temp); + } + else if(msgObj->msgBufId > 31) + { + FlexCanReg_SetMsgBufInterruptEnable(obj->flexCanReg, 1, temp); + } + else + { + FlexCanReg_SetMsgBufInterruptEnable(obj->flexCanReg, 0, temp); + } +} + +void FlexCanDrv_DisableMsgObjInterrupt(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj) +{ + uint32_t temp, temp1 = 0; + temp1 = msgObj->msgBufId % 32; + temp = ~(0x00000001 << temp1); + if(msgObj->msgBufId > 63) + { + FlexCanReg_SetMsgBufInterruptDisable(obj->flexCanReg, 2, temp); + } + else if(msgObj->msgBufId > 31) + { + FlexCanReg_SetMsgBufInterruptDisable(obj->flexCanReg, 1, temp); + } + else + { + FlexCanReg_SetMsgBufInterruptDisable(obj->flexCanReg, 0, temp); + } +} + +FlexCanDrv_NodeStatType FlexCanDrv_GetNodeStatus(FlexCanDrvType *obj) +{ + FlexCanDrv_NodeStatType ret; + + if(FlexCanReg_GetTxState(obj->flexCanReg)) + { + ret = FLEXCANDRV_NODESTAT_TRANSMITTING; + } + else if(FlexCanReg_GetRxState(obj->flexCanReg)) + { + ret = FLEXCANDRV_NODESTAT_RECEIVING; + } + else if(FlexCanReg_GetIdleState(obj->flexCanReg)) + { + ret = FLEXCANDRV_NODESTAT_IDLE; + } + else + { + } + + return ret; +} + +void FlexCanDrv_GetErrorStates(FlexCanDrvType *obj, FlexCanDrv_ErrStsType *errSts) +{ + uint8_t tempSts; + + tempSts = FlexCanReg_GetFltConfinementState(obj->flexCanReg); + if(tempSts & 0x2) + { + errSts->fltConfSts = FLEXCANDRV_FLTCONFSTS_BUSOFF; + } + else + { + errSts->fltConfSts = (FlexCanDrv_FltConfStsType)tempSts; + } + + errSts->bit1Err = FlexCanReg_GetBit1Error(obj->flexCanReg); + errSts->bit0Err = FlexCanReg_GetBit0Error(obj->flexCanReg); + errSts->ackErr = FlexCanReg_GetAckError(obj->flexCanReg); + errSts->crcErr = FlexCanReg_GetCrcError(obj->flexCanReg); + errSts->formErr = FlexCanReg_GetFormError(obj->flexCanReg); + errSts->stuffErr = FlexCanReg_GetStuffError(obj->flexCanReg); +#if FEATURE_CAN_FD_INSTANCE_NUM == 1 && FEATURE_CAN_2_0_INSTANCE_NUM == 0 + errSts->bit1FastErr = FlexCanReg_GetBit1FastError(obj->flexCanReg); + errSts->bit0FastErr = FlexCanReg_GetBit0FastError(obj->flexCanReg); + errSts->crcFastErr = FlexCanReg_GetCrcFastError(obj->flexCanReg); + errSts->formFastErr = FlexCanReg_GetFormFastError(obj->flexCanReg); + errSts->stuffFastErr = FlexCanReg_GetStuffFastError(obj->flexCanReg); +#endif +} + +void FlexCanDrv_EnterLowPwrMode(FlexCanDrvType *obj, FlexCanDrv_LowPwrModeType lowPwrMode) +{ + /* set FlexCan into low power mode in SIM */ + if(lowPwrMode == FLEXCANDRV_LOWPWRMODE_DOZE) + { + SimReg_SetCanIpgDoze(obj->simReg, 1); + } + else if(lowPwrMode == FLEXCANDRV_LOWPWRMODE_STOP) + { + SimReg_SetCanIpgStop(obj->simReg, 1); + } + else + { + } +} + +void FlexCanDrv_ExitLowPwrMode(FlexCanDrvType *obj, FlexCanDrv_LowPwrModeType lowPwrMode) +{ + /* Clear FlexCan into low power mode in SIM */ + if(lowPwrMode == FLEXCANDRV_LOWPWRMODE_DOZE) + { + SimReg_SetCanIpgDoze(obj->simReg, 0); + } + else if(lowPwrMode == FLEXCANDRV_LOWPWRMODE_STOP) + { + SimReg_SetCanIpgStop(obj->simReg, 0); + } + else + { + } +} + +uint8_t FlexCanDrv_AbortPendingTxMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj) +{ + uint32_t *msgBufPtr; + volatile uint32_t msgBufCode; + uint8_t ret; + + /* disable message buffer interrupt */ + FlexCanDrv_DisableMsgObjInterrupt(obj, msgObj); + + /* clear message buffer flag */ + FlexCanDrv_ClearMsgObjFlag(obj, msgObj); + + /* get current message buffer start address */ + msgBufPtr = (uint32_t *)FlexCanDrv_GetMsgBufStartAddr(obj, msgObj->msgBufId); + /* clear message buffer CS.CODE field */ + *msgBufPtr &= (~FLEXCANDRV_MSG_BUF_CODE_MASK << FLEXCANDRV_MSG_BUF_CODE_SHIFT); + /* set the message buffer code as TX ABORT */ + *msgBufPtr |= (((uint32_t)FLEXCANDRV_MSG_BUF_CODE_ABORT) << FLEXCANDRV_MSG_BUF_CODE_SHIFT); + + /* wait until message buffer flag assert */ + while(FlexCanDrv_GetMsgObjFlag(obj, msgObj) == 0) + { + } + + msgBufCode = (*msgBufPtr >> FLEXCANDRV_MSG_BUF_CODE_SHIFT) & FLEXCANDRV_MSG_BUF_CODE_MASK; + + /* check the tx pending message abort result */ + if(msgBufCode == FLEXCANDRV_MSG_BUF_CODE_ABORT) + { + ret = TX_PENDING_ABORT_SUCCESS; + } + else if(msgBufCode == FLEXCANDRV_MSG_BUF_CODE_TX_INACTIVE) + { + ret = TX_PENDING_ABORT_NO_TRANSFER; + } + else + { + ret = TX_PENDING_ABORT_FAILED; + } + + /* clear message buffer flag */ + FlexCanDrv_ClearMsgObjFlag(obj, msgObj); + + return ret; +} + +void FlexCanDrv_BitTimingCalc(FlexCanDrv_BitTimingType *bitTimingPara, + uint32_t moduleFreq, + uint32_t baudrate, + uint16_t samplePoint, + uint16_t sjw, + uint8_t isFd) +{ + int32_t maxPrescaler, maxTseg1, minTseg1, maxTseg2, maxNumTq, minNumTq; + int32_t tempPrescaler, tempSjw, tempTseg1, tempNumTq; + float bestErr = 0; + + /* set default best value for all bit timing parameters */ + int32_t bestPrescaler = 1, bestSjw = 1, bestNumTq = 8, bestTseg1 = 3, bestTseg2 = 2; + + /* set the optimal value for baudrate error, number of time quatna */ + const int32_t optNumTq = 20; + const float optBaudrateErr = 0.1; + const float optSamplePntToler = 0.25; + + /* set the maximum & minimum value for all bit timing parameters */ + if(isFd == false) + { + maxPrescaler = FLEXCAN_CBT_EPRESDIV_MASK >> FLEXCAN_CBT_EPRESDIV_SHIFT; + maxTseg1 = (FLEXCAN_CBT_EPROPSEG_MASK >> FLEXCAN_CBT_EPROPSEG_SHIFT) + (FLEXCAN_CBT_EPSEG1_MASK >> FLEXCAN_CBT_EPSEG1_SHIFT); + minTseg1 = 3; + maxTseg2 = FLEXCAN_CBT_EPSEG2_MASK >> FLEXCAN_CBT_EPSEG2_SHIFT; + + maxNumTq = maxTseg1 + maxTseg2 + 1; + minNumTq = 8; + } + else + { + maxPrescaler = FLEXCAN_FDCBT_FPRESDIV_MASK >> FLEXCAN_FDCBT_FPRESDIV_SHIFT; + maxTseg1 = (FLEXCAN_FDCBT_FPROPSEG_MASK >> FLEXCAN_FDCBT_FPROPSEG_SHIFT) + (FLEXCAN_FDCBT_FPSEG1_MASK >> FLEXCAN_FDCBT_FPSEG1_SHIFT); + minTseg1 = 3; + maxTseg2 = FLEXCAN_FDCBT_FPSEG2_MASK >> FLEXCAN_FDCBT_FPSEG2_SHIFT; + + maxNumTq = maxTseg1 + maxTseg2 + 1; + minNumTq = 8; + } + + /* calculate prescaler, number of Tq */ + bestErr = (float)baudrate; + for(tempPrescaler = 1; tempPrescaler <= maxPrescaler; tempPrescaler++) + { + /* get the quanta frequency */ + float Fq = (float)moduleFreq / tempPrescaler; + /* get the number of time quanta */ + tempNumTq = (int32_t)(Fq / baudrate); + + /* To avoid division by 0 and number of Tq less than minmum number of Tq */ + if((tempNumTq == 0) || (tempNumTq < minNumTq)) + { + break; + } + + /* calculate temp baudrate */ + float tempBaudrate = Fq / tempNumTq; + /* calculate temp baudrate error */ + float tempErr = ((tempBaudrate - baudrate) > 0) ? (tempBaudrate - baudrate) : (baudrate - tempBaudrate); + + if((tempNumTq <= maxNumTq) && (tempErr <= bestErr)) + { + /* set temporary prescaler, number of Tq, baudrate error as the best value */ + bestPrescaler = tempPrescaler; + bestNumTq = tempNumTq; + bestErr = tempErr; + + /* check if get the optimal condition */ + if((tempNumTq <= optNumTq) && tempErr < optBaudrateErr) + { + break; + } + } + } + + /* calculate sample point (time segment 1) */ + bestErr = samplePoint * optSamplePntToler; + + /* saturate max time segment 1 value */ + if(bestNumTq < maxTseg1) + { + maxTseg1 = bestNumTq; + } + for(tempTseg1 = maxTseg1; tempTseg1 >= minTseg1; tempTseg1--) + { + /* get the temporary sample point */ + int32_t tempSamplePnt = ((tempTseg1 + 1) * 10000) / bestNumTq; + /* get the temporary sample point error */ + int32_t tempErr = (tempSamplePnt - samplePoint) > 0 ? (tempSamplePnt - samplePoint) : (samplePoint - tempSamplePnt); + + /* break the for loop if the temporary sample point less + than the user required sample point */ + if(tempSamplePnt < samplePoint) + { + break; + } + + /* update the best T_seg1 and best error if met the tolerance */ + if(tempErr < bestErr) + { + bestTseg1 = tempTseg1; + bestErr = tempErr; + } + } + + /* calculate time segment 2 */ + bestTseg2 = bestNumTq - bestTseg1 - 1; + + /* calculate best SJW */ + bestErr = 10000; + for(tempSjw = 1; tempSjw <= bestTseg2; tempSjw++) + { + /* get the temporary synchronize jump width percentage */ + int32_t tempSjwPercent = (tempSjw * 10000) / bestNumTq; + int32_t tempErr = ((tempSjwPercent - sjw) > 0) ? (tempSjwPercent - sjw) : (sjw - tempSjwPercent); + + /* */ + if(tempErr < bestErr) + { + bestSjw = tempSjw; + bestErr = tempErr; + } + } + + bitTimingPara->prescalerDiv = bestPrescaler; + bitTimingPara->propSeg = (uint32_t)(bestTseg1 * 0.6); + bitTimingPara->phaseSeg1 = bestTseg1 - bitTimingPara->propSeg; + bitTimingPara->phaseSeg2 = bestTseg2; + bitTimingPara->resyncJumpWidth = bestSjw; +} + +void FlexCanDrv_SetRxFifoFlitElement(FlexCanDrvType *obj, uint8_t filtEleId, bool isExtId, uint32_t filtId) +{ + /* get the rx fifo filter format mode */ + FlexCanDrv_RxFifoFiltFormatType filtFormat = FlexCanReg_GetRxFifoFiltMode(obj->flexCanReg); + /* get the rx fifo filter table start address */ + uint32_t *rxFifoFiltTable = (uint32_t *)(((uint32_t)obj->flexCanReg) + RX_FIFO_FILT_TABLE_ADD_OFFSET); + uint32_t temp = 0; + uint8_t tempFiltEleId = 0; + uint8_t tempOffset = 0; + + + if(filtFormat == FLEXCANDRV_RXFIFO_FILTFORMAT_A) + { + /* clear the rx fifo filter element */ + rxFifoFiltTable[filtEleId] = 0; + /* set the rx fifo filter element bit 1 to 29 as filter ID */ + rxFifoFiltTable[filtEleId] |= filtId << (isExtId ? 1 : 19); + /* set the rx fifo filter element bit 30 as IDE */ + rxFifoFiltTable[filtEleId] |= ((uint32_t)isExtId) << 30; + } + else if (filtFormat == FLEXCANDRV_RXFIFO_FILTFORMAT_B) + { + /* get the filter element ID and offset counter based on 16-bit width */ + tempFiltEleId = filtEleId / 2; + tempOffset = (filtEleId % 2) * 16 ; + + /* get the existing value from the current two filter element */ + temp = rxFifoFiltTable[tempFiltEleId]; + /* clear the target filter element 16-bit */ + temp &= ~(0xFFFFUL << tempOffset); + + /* set the ID to the filter element */ + temp |= ((isExtId ? (filtId >> 15) : (filtId << 3)) << tempOffset); + /* set the IDE bit to the filter element */ + temp |= (((uint32_t)isExtId) << 14 << tempOffset); + + /* set the 16-bit value to the target filter element ID */ + rxFifoFiltTable[tempFiltEleId] = temp; + } + else if (filtFormat == FLEXCANDRV_RXFIFO_FILTFORMAT_C) + { + /* get the filter element ID and offset counter based on 8-bit width */ + tempFiltEleId = filtEleId / 4; + tempOffset = (filtEleId % 4) * 8 ; + + /* get the existing value from the current 4 filter element */ + temp = rxFifoFiltTable[tempFiltEleId]; + /* clear the target filter element 8-bit */ + temp &= ~(0xFFUL << tempOffset); + + /* set the first rx filter Id to rx fifo filter element */ + temp |= ((isExtId ? (filtId >> 21) : (filtId >> 3)) << tempOffset); + + /* set the 8-bit value to the target filter element ID */ + rxFifoFiltTable[tempFiltEleId] = temp; + } + else + { + + } +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/flexcan/flexcan_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/flexcan/flexcan_drv.h new file mode 100644 index 0000000..5acd91f --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/flexcan/flexcan_drv.h @@ -0,0 +1,536 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FLEXCAN_DRV_H_ +#define _FLEXCAN_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the FlexCAN (Flex Controller Area Network) module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup flexcan_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +/*! \brief Macro for select message buffer data size for CAN message buffer region + * + * The size of each message buffer data will affect the total message buffer number + */ +#define FLEXCANDRV_MB_SIZE_BYTE_8 (0) +#define FLEXCANDRV_MB_SIZE_BYTE_16 (1) +#define FLEXCANDRV_MB_SIZE_BYTE_32 (2) +#define FLEXCANDRV_MB_SIZE_BYTE_64 (3) + +/*! \brief Macro for message buffer code + * + * The code field was located in message buffer and can be accessed by CPU and by FlexCAN + * module as part of the message buffer matching and arbitration process. + */ +#define FLEXCANDRV_MSG_BUF_CODE_INACTIVE (0x0U) +#define FLEXCANDRV_MSG_BUF_CODE_RX_ACTIVE (0x4U) +#define FLEXCANDRV_MSG_BUF_CODE_TX_REQUEST (0xCU) +#define FLEXCANDRV_MSG_BUF_CODE_TX_INACTIVE (0x8U) +#define FLEXCANDRV_MSG_BUF_CODE_ABORT (0x9U) +#define FLEXCANDRV_MSG_BUF_CODE_MASK (0xFU) +#define FLEXCANDRV_MSG_BUF_CODE_SHIFT (24U) + +/*! \brief Macro for FlexCan access mode + * + * The access mode will affect the some of the FlexCan registers access permission + */ +#define FLEXCANDRV_CAN_ACCESS_MODE_USER (0) +#define FLEXCANDRV_CAN_ACCESS_MODE_SUP (1) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +/*! \brief type for data length code (DLC) + */ +typedef enum +{ + DLC_BYTE_0 = 0x00, /*!< 0 byte(s) data length code */ + DLC_BYTE_1 = 0x01, /*!< 1 byte(s) data length code */ + DLC_BYTE_2 = 0x02, /*!< 2 byte(s) data length code */ + DLC_BYTE_3 = 0x03, /*!< 3 byte(s) data length code */ + DLC_BYTE_4 = 0x04, /*!< 4 byte(s) data length code */ + DLC_BYTE_5 = 0x05, /*!< 5 byte(s) data length code */ + DLC_BYTE_6 = 0x06, /*!< 6 byte(s) data length code */ + DLC_BYTE_7 = 0x07, /*!< 7 byte(s) data length code */ + DLC_BYTE_8 = 0x08, /*!< 8 byte(s) data length code */ + DLC_BYTE_12 = 0x09, /*!< 12 byte(s) data length code */ + DLC_BYTE_16 = 0x0A, /*!< 16 byte(s) data length code */ + DLC_BYTE_20 = 0x0B, /*!< 20 byte(s) data length code */ + DLC_BYTE_24 = 0x0C, /*!< 24 byte(s) data length code */ + DLC_BYTE_32 = 0x0D, /*!< 32 byte(s) data length code */ + DLC_BYTE_48 = 0x0E, /*!< 48 byte(s) data length code */ + DLC_BYTE_64 = 0x0F /*!< 64 byte(s) data length code */ +} FlexCanDrv_DLCType; + +/*! \brief type for FlexCan clock source + */ +typedef enum +{ + FLEXCANDRV_CLKSRC_OSC = 0x00, /*!< oscillator clock source */ + FLEXCANDRV_CLKSRC_CHICLK = 0x01 /*!< peripherial clock source */ +} FlexCanDrv_ClkSrcType; + +/*! \brief type for FlexCan message type + */ +typedef enum +{ + FLEXCANDRV_MSGTYPE_TX, /*!< Tx message type */ + FLEXCANDRV_MSGTYPE_RX /*!< Rx message type */ +} FlexCanDrv_MsgType_t; + +/*! \brief type for FlexCan node state type + */ +typedef enum +{ + FLEXCANDRV_NODESTAT_IDLE, /*!< idle bus state */ + FLEXCANDRV_NODESTAT_RECEIVING, /*!< receving bus state */ + FLEXCANDRV_NODESTAT_TRANSMITTING, /*!< transmitting bus state*/ +} FlexCanDrv_NodeStatType; + +/*! \brief type for FlexCan fault confinment state type + */ +typedef enum +{ + FLEXCANDRV_FLTCONFSTS_ERRACTIVE = 0, /*!< error active state */ + FLEXCANDRV_FLTCONFSTS_ERRPASSIVE = 1, /*!< error passive state */ + FLEXCANDRV_FLTCONFSTS_BUSOFF = 2, /*!< bus off state */ +} FlexCanDrv_FltConfStsType; + +/*! \brief type for FlexCan low power mode + */ +typedef enum +{ + FLEXCANDRV_LOWPWRMODE_DOZE, /*!< Doze mode */ + FLEXCANDRV_LOWPWRMODE_STOP, /*!< Stop mode */ +} FlexCanDrv_LowPwrModeType; + +/*! \brief type for FlexCan Rx FIFO filer format */ +typedef enum +{ + FLEXCANDRV_RXFIFO_FILTFORMAT_A, /*!< Format A - One full ID (standard and extended) per ID Filter Table element */ + FLEXCANDRV_RXFIFO_FILTFORMAT_B, /*!< Format B - Two full standard IDs or two partial 14-bit (standard and extended) IDs per ID filter table element */ + FLEXCANDRV_RXFIFO_FILTFORMAT_C, /*!< Format C - Four partial 8-bit standard IDs per ID filter table element */ + FLEXCANDRV_RXFIFO_FILTFORMAT_D, /*!< Format D - All frames rejected */ +} FlexCanDrv_RxFifoFiltFormatType; + +/*! \brief FlexCan message configuration data structure + * + * This structure configures the static attributes for a generic CAN message + */ +typedef struct _FlexCanDrv_MsgCfgType_ +{ + uint16_t msgBufId; /*!< Message buffer index to handle this message object */ + uint16_t msgBufLen; /*!< Defines number of message buffer to handle this specific + message object configuration, if msgBufLen = 1, then only + single message buffer allocated to this message object, + which is also a common use case, if msgBuf > 1, then multiple + message buffer will allocated to this message object, which + will operating as a software message buffer with depth n */ + uint32_t msgId; /*!< Message ID can be either 11-bit or 29-bit depends on the + configuration of isExtMsgId */ + bool isExtMsgId; /*!< Select extended message ID (29-bit) or standard message + ID (11-bit) */ + FlexCanDrv_MsgType_t msgType; /*!< Select message type as Tx message or Rx message */ + FlexCanDrv_DLCType dlc; /*!< Message data length code */ + bool isFd; /*!< Select message as classic CAN message or flexible data rate + message */ + bool intEnable; /*!< Message Tx / Rx complete interrupt enable */ + uint32_t individualMask; /*!< Rx indivudual mask for mailbox n */ +} FlexCanDrv_MsgCfgType; + +/*! \brief FlexCan message object data structure + * + * This structure configures the dynamic attributes for a CAN message which can + * be varied at runtime + */ +typedef struct _FlexCanDrv_MsgObjType_ +{ + uint8_t msgBufId; /*!< Unique ID for message where it located in message buffer */ + uint32_t msgId; /*!< 11-bit or 29-bit message ID */ + uint8_t data[64]; /*!< Message data field. Maximum 64 bytes, the valid length was + determined by message DLC */ + uint8_t dlc; /*!< Message DLC get from the latest received message */ +} FlexCanDrv_MsgObjType; + +/*! \brief FlexCan bit timing configure data structure (CAN / CANFD) + * + * This structure configures the CAN / CANFD bit timing parameters + */ +typedef struct _FlexCanDrv_BitTimingType_ +{ + uint32_t prescalerDiv; /*!< Pre-scaler division factor, defines the ratio between CAN module + clock frequency and the serial clock frequency in the data bit + rate portion */ + uint32_t resyncJumpWidth; /*!< Re-sync jump width, the maximum number of time quanta that a bit + time can be changed by one re-synchronization */ + uint32_t propSeg; /*!< Propagation segment, defines the length of propagation segment in + the bit time */ + uint32_t phaseSeg1; /*!< Phase segment 1, defines the length of phase segment 1 in bit time */ + uint32_t phaseSeg2; /*!< Phase segment 2, defines the length of phase segment 2 in bit time */ +} FlexCanDrv_BitTimingType; + +typedef struct _FlexCanDrv_InitHwParType_ +{ + uint8_t canRamNum; /*!< CAN message buffer RAM number (each RAM block has 512 bytes) */ +} FlexCanDrv_InitHwParType; + +/*! \brief FlexCan controller (node) configuration data structure + * + * This structure configures static attributes for a FlexCAN controller + */ +typedef struct _FlexCanDrv_ControllerCfgType_ +{ + FlexCanDrv_ClkSrcType clkSrc; /*!< Select the clock source for CAN module */ + bool fdEnable; /*!< Flexible data rate enable */ + bool fdISOEnable; /*!< ISO CAN FD enable */ + bool fifoEnable; /*!< Rx FIFO enable */ + bool dmaEnable; /*!< Rx FIFO DMA enable */ + FlexCanDrv_BitTimingType bitTiming; /*!< nominal CAN bit timing struct */ + FlexCanDrv_BitTimingType fdBitTiming; /*!< FD CAN bit timing struct */ + uint8_t msgBufDataLenSel; /*!< Message buffer data size selection */ + uint32_t rxMBGlobalMask; /*!< Rx mailbox global mask */ + uint32_t rxMB14Mask; /*!< Rx mailbox 14 mask (only effect in global mask mode) */ + uint32_t rxMB15Mask; /*!< Rx mailbox 15 mask (only effect in global mask mode) */ + uint32_t rxFifoGlobalMask; /*!< Rx fifo global mask */ + FlexCanDrv_RxFifoFiltFormatType rxFifoFiltFormat; /*!< Rx fifo filter format */ + uint8_t rxFifoFilterNum; /*!< Rx fifo filter number code */ + uint8_t rxFifoIndivMskNum; /*!< Rx fifo individual mask valid number */ + uint32_t rxFifoIndivMsk[32]; /*!< Rx fifo individual mask arrary */ + bool individualMaskEnable; /*!< Rx individual mask enable */ + bool loopbackEnable; /*!< Loopback mode enable */ + bool tdcEnable; /*!< Transceiver delay compensation enable */ + uint8_t tdcOffset; /*!< Transceiver delay compensation offset */ + uint8_t msgNum; /*!< number of messages */ + const FlexCanDrv_MsgCfgType * msgCfg; /*!< message configuration array */ + bool edgeWkupEnable; /*!< CAN edge wakeup enable */ + bool txAbortEnable; /*!< Tx pending message abort mechanism enable */ + bool busoffIntEnable; /*!< Busoff interrupt enable */ + bool errorIntEnable; /*!< Error interrupt enable */ +} FlexCanDrv_ControllerCfgType; + +/*! \brief FlexCan error states data structure + * + * This structure indicating the error states for a FlexCAN controller + */ +typedef struct _FlexCanDrv_ErrStsType_ +{ + FlexCanDrv_FltConfStsType fltConfSts; /*!< fault confinement state */ + uint8_t bit1FastErr; /*!< bit 1 error in FD message data phase */ + uint8_t bit0FastErr; /*!< bit 0 error in FD message data phase */ + uint8_t crcFastErr; /*!< crc error in FD message data phase */ + uint8_t formFastErr; /*!< form error in FD message data phase */ + uint8_t stuffFastErr; /*!< stuff error in FD message data phase */ + uint8_t bit1Err; /*!< bit 1 error */ + uint8_t bit0Err; /*!< bit 0 error */ + uint8_t ackErr; /*!< acknowledgement error */ + uint8_t crcErr; /*!< crc error */ + uint8_t formErr; /*!< form error */ + uint8_t stuffErr; /*!< stuff error */ +} FlexCanDrv_ErrStsType; + +struct _FlexCanRegType_; + +typedef struct _FlexCanDrvType_ +{ + struct _FlexCanRegType_ *flexCanReg; + struct _Pcc1RegType_ *pcc1Reg; + struct _Pcc0RegType_ *pcc0Reg; + struct _Scg0RegType_ *scg0Reg; + struct _Scg2RegType_ *scg2Reg; + struct _SimRegType_ *simReg; + FlexCanDrv_InitHwParType initHwPar; +} FlexCanDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the flexCan driver module + * + * This function initializes flexCan driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to FlexCan driver instance + * \param[in] reg : pointer to FlexCan register instance + * \param[in] initHwPar: pointer to FlexCan hardware init parameter struct + */ +extern void FlexCanDrv_Init(FlexCanDrvType *obj, + struct _FlexCanRegType_ *flexCanReg, + struct _Pcc1RegType_ *pcc1Reg, + struct _Pcc0RegType_ *pcc0Reg, + struct _Scg0RegType_ *scg0Reg, + struct _Scg2RegType_ *scg2Reg, + struct _SimRegType_ *simReg, + FlexCanDrv_InitHwParType *initHwPar); +/*! \brief Soft reset FlexCAN module + * + * This function issues a softreset to FlexCAN module + * + * \param[in] obj : pointer to FlexCAN driver instance + */ +extern void FlexCanDrv_SoftReset(FlexCanDrvType *obj); + +/*! \brief Start FlexCAN module + * + * This function starts the specified FlexCAN device + * + * \param[in] obj : pointer to FlexCAN driver instance + */ +extern void FlexCanDrv_Start(FlexCanDrvType *obj); + +/*! \brief Configure and initialize FlexCAN controller from user configuration + * + * This function configure and initialize the FlexCAN controller from user + * configuration, it also init FlexCAN RAM area, disable FlexCAN RAM ECC feature + * and enable the entire FlexCAN module + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] controllerCfg : pointer to FlexCAN controller configuration structure + */ +extern void FlexCanDrv_Configure(FlexCanDrvType *obj, const FlexCanDrv_ControllerCfgType *controllerCfg); + +/*! \brief Configure message object and register the specified CAN message buffer + * + * This function configure and initialize the CAN message object for its' message ID + * direction, DLC, FD properties and message buffer interrupt enable. All the above + * configuration will be stored in the specified message buffer located in CAN RAM + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgCfg : pointer to message object configuration + * \param[in] msgBufId : message buffer index to store the message object + */ +extern void FlexCanDrv_CfgMsgObj(FlexCanDrvType *obj, const FlexCanDrv_MsgCfgType *msgCfg, uint8_t msgBufId); + +/*! \brief Transmit the message unconditionally once + * + * This function transmit message unconditionally once by the set the CODE in CS field, + * this operation shall be performed after message object initialized in message buffer + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgObj : message buffer object pointer + */ +extern void FlexCanDrv_TransmitMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj); + +/*! \brief Set the transmit message object into message buffer + * + * This function load the transmit message object into message buffer data field, the data byte order + * will be re-odered to adapt the message buffer data field format. The data length to load + * will retrieved from the DLC stored in the specified message buffer + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgObj : message buffer object pointer + */ +extern void FlexCanDrv_SetTxMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj); + +/*! \brief Get the message object from message buffer + * + * This function load the message buffer received data and DLC into message object data buffer. + * The data length to load will retrieved from the DLC stored in the specified message buffer + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgObj : message buffer object pointer + */ +extern void FlexCanDrv_GetRxMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj); + +/*! \brief Get the message object from Rx FIFO + * + * This function load the Rx FIFO received data and DLC into message object data buffer. + * The data length to load will retrieved from the DLC stored in the specified message buffer + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgObj : message buffer object pointer + */ +extern void FlexCanDrv_GetRxFifoMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj); + +/*! \brief Get message object flag, indicating a successful Rx / Tx operation completed + * + * This function returns the flag to indicating a successful Rx / Tx operation completed. + * A clear operation need to be done once the flag is asserted. + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgObj : message buffer object pointer + * \return message buffer Tx / Rx operation complete flag + * - 0: the corresponding buffer has no occurrence of successfully + * completed transmission or reception + * - 1: the corresponding buffer has successfully completed transmission + * or reception + */ +extern uint8_t FlexCanDrv_GetMsgObjFlag(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj); + +/*! \brief Get the message object from Rx FIFO + * + * This function load the Rx FIFO received data and DLC into message object data buffer. + * The data length to load will retrieved from the DLC stored in the specified message buffer + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgObj : message buffer object pointer + */ +extern void FlexCanDrv_GetRxFifoMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj); + +/*! \brief Clear message object flag + * + * This function clear the correspongding message object flag + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgObj : message buffer object pointer + */ +extern void FlexCanDrv_ClearMsgObjFlag(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj); + +/*! \brief Clear all message object flags + * + * This function clear all message object flags + * + * \param[in] obj : pointer to FlexCAN driver instance + */ +extern void FlexCanDrv_ClearAllMsgObjFlags(FlexCanDrvType *obj); + +/*! \brief Enable interrupt for the corresponding message buffer + * + * This function enable interrupt for the corresponding message buffer + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgObj : message buffer object pointer + */ +extern void FlexCanDrv_EnableMsgObjInterrupt(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj); + +/*! \brief Disable interrupt for the corresponding message buffer + * + * This function disable interrupt for the corresponding message buffer + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgObj : message buffer object pointer + */ +extern void FlexCanDrv_DisableMsgObjInterrupt(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj); + +/*! \brief Get the default FlexCan controller configuration parameters + * + * This function get the default FlexCan controller configuration parameters + * + * \param[in] controllerCfg : controller configure pointer + */ +extern void FlexCanDrv_GetDefaultCfg(FlexCanDrv_ControllerCfgType *controllerCfg); + +/*! \brief Calculate the CAN bit timing parameters + * + * This function calculate the CAN bit timing parameters for both classic and FD CAN + * + * \param[out] bitTimingPara : pointer to bit timing parameter group + * \param[in] clkFreq : FlexCan module frequency + * \param[in] samplePoint : Can bit sample point (0 - 10000 -> 0 - 100%) + * \param[in] sjw : Synchronize jump width (0 - 10000 -> 0 - 100%) + * \param[in] isFd : Is the bit timing parameter group for CAN-FD + */ +extern void FlexCanDrv_BitTimingCalc(FlexCanDrv_BitTimingType *bitTimingPara, + uint32_t clkFreq, + uint32_t baudrate, + uint16_t samplePoint, + uint16_t sjw, + uint8_t isFd); + +/*! \brief Get FlexCan error states + * + * This function get the FlexCan error states + * + * \param[in] obj : pointer to FlexCAN driver instance + * \return : node status + * + */ +FlexCanDrv_NodeStatType FlexCanDrv_GetNodeStatus(FlexCanDrvType *obj); + +/*! \brief Get FlexCan error states + * + * This function get the FlexCan error states + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[out] errSts: pointer to FlexCan error states + * + */ +void FlexCanDrv_GetErrorStates(FlexCanDrvType *obj, FlexCanDrv_ErrStsType *errSts); + +/*! \brief Enter FlexCan controller low power mode + * + * This function enter FlexCan controller low power mode + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] lowPwrMode: low power mode to be entered + * + */ +void FlexCanDrv_EnterLowPwrMode(FlexCanDrvType *obj, FlexCanDrv_LowPwrModeType lowPwrMode); + +/*! \brief Exit FlexCan controller low power mode + * + * This function exit FlexCan controller low power mode + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] lowPwrMode: low power mode to be exited + * + */ +void FlexCanDrv_ExitLowPwrMode(FlexCanDrvType *obj, FlexCanDrv_LowPwrModeType lowPwrMode); + +/*! \brief Abort pending Tx message + * + * This function abort the pending Tx message + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] msgObj: message buffer object pointer + * \return Pending Tx message abort result + * - 0: no Tx message transfer pending + * - 1: pending Tx message abort success + * + */ +extern uint8_t FlexCanDrv_AbortPendingTxMsg(FlexCanDrvType *obj, FlexCanDrv_MsgObjType *msgObj); + +/*! \brief Set Rx Fifo filter element + * + * This function set the fields of the rx fifo flter element according to the filter format configuration + * + * \param[in] obj : pointer to FlexCAN driver instance + * \param[in] filtEleId: rx fifo filter element ID, this ID calcualtion according to the filter format (32, 16, 8 bit) + * \param[in] isExtId: extended frame indicator + * \param[in] filtId: filter message ID + * + */ +extern void FlexCanDrv_SetRxFifoFlitElement(FlexCanDrvType *obj, uint8_t filtEleId, bool isExtId, uint32_t filtId); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* #ifndef _FLEXCAN_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/i2c/i2c_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/i2c/i2c_drv.c new file mode 100644 index 0000000..6f09502 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/i2c/i2c_drv.c @@ -0,0 +1,627 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/****************************************************************************** + * the includes + *****************************************************************************/ + +#include "i2c_drv.h" + +/****************************************************************************** + * the defines + *****************************************************************************/ + +#define I2CDRV_MILLI_RATE (1000ul) + +/****************************************************************************** + * the typedefs + *****************************************************************************/ + +/****************************************************************************** + * the globals + *****************************************************************************/ + +/****************************************************************************** + * the static function declarations + *****************************************************************************/ +static void I2cDrv_InitBasicParameters(I2cRegType *pReg, const I2cDrv_BasicParametersType *pBasicParameters); +static void I2cDrv_InitExtendParameters(I2cRegType *pReg, const I2cDrv_ExtendFeaturesType *pExtendFeatures, const I2cDrv_ExtendParametersType *pExtendParameters, uint32_t busClockFreq); + +/****************************************************************************** + * the functions + *****************************************************************************/ + +/*! \brief Config the basic parameter and features + * + * This function initialize the basic features with the parameters + * + * \param[in] pReg: pointer to I2C driver instance + * \param[in] pBasicParameters: the conbination of basic parameters + * \return: void + */ +static void I2cDrv_InitBasicParameters(I2cRegType *pReg, const I2cDrv_BasicParametersType *pBasicParameters) +{ + if(pBasicParameters->nodeMode == I2CDRV_NODE_MODE_AS_MASTER) + { + /* Node as Master */ + I2cReg_SetMasterMode(pReg, true); + + /* Set address mode: 7bits or 10bits */ + I2cReg_SetMasterAddressMode(pReg, pBasicParameters->addressMode); + + /* Set target address */ + I2cReg_SetTargetAddress(pReg, pBasicParameters->targetAddress); + + I2cReg_SetMasterRestartEnable(pReg, pBasicParameters->restartBitEn); + + I2cReg_SetSlaveModeDisable(pReg, true); + } + else + { + I2cReg_SetMasterMode(pReg, false); + + I2cReg_SetSlaveAddressMode(pReg, pBasicParameters->addressMode); + + I2cReg_SetSlaveAddress(pReg, pBasicParameters->ownAddress); + + I2cReg_SetSlaveModeDisable(pReg, false); + } + + I2cReg_SetSpeedMode(pReg, pBasicParameters->speedMode); + + if(pBasicParameters->speedMode == I2CDRV_SPEED_MODE_STANDARD_100KBIT) + { + if(pBasicParameters->sclFreq <= I2CDRV_STANDARDSPEED_UPPER_FREQ_VALUE) + { + uint16_t tCnt = 0; + + tCnt = (uint16_t)(pBasicParameters->busClockFreq / pBasicParameters->sclFreq); + + /* 50% + 50% */ + tCnt >>= 1; + + I2cReg_SetStandardModeHighLevelCount(pReg, tCnt); + + I2cReg_SetStandardModeLowLevelCount(pReg, tCnt); + } + } + else if(pBasicParameters->speedMode == I2CDRV_SPEED_MODE_FAST_400KBIT_1000KBIT) + { + if(pBasicParameters->sclFreq <= I2CDRV_FASTSPEED_UPPER_FREQ_VALUE) + { + uint16_t tCnt = 0; + + tCnt = (uint16_t)(pBasicParameters->busClockFreq / pBasicParameters->sclFreq); + + /* 50% + 50% */ + tCnt >>= 1; + + I2cReg_SetFastModeHighLevelCount(pReg, tCnt); + + I2cReg_SetFastModeLowLevelCount(pReg, tCnt); + } + } + else + { + /* Not support high-speed mode feature */ + } +} + +/*! \brief Config the module extend parameters and features + * + * This function initializes the extend features with the parameters + * + * \param[in] pReg: pointer to I2C driver instance + * \param[in] pExtendFeatures: the conbination of extend parameters + * \param[in] pExtendParameters: the conbination of extendFeatures + * \param[in] busClockFreq: the bus clock for i2c module + * \return: void + */ +static void I2cDrv_InitExtendParameters(I2cRegType *pReg, const I2cDrv_ExtendFeaturesType *pExtendFeatures, const I2cDrv_ExtendParametersType *pExtendParameters, uint32_t busClockFreq) +{ + if(pExtendFeatures->dmaRxEn == true) + { + I2cReg_SetDmaRxLevel(pReg, pExtendParameters->dmaRxDataLevel); + } + + I2cReg_SetRxDmaEnable(pReg, pExtendFeatures->dmaRxEn); + + if(pExtendFeatures->dmaTxEn == true) + { + I2cReg_SetDmaTxLevel(pReg, pExtendParameters->dmaTxDataLevel); + } + + I2cReg_SetTxDmaEnable(pReg, pExtendFeatures->dmaTxEn); + + /* Special cmd selection config */ + I2cReg_SetSpecialCommand(pReg, pExtendFeatures->specialCmdEn); + + if(pExtendFeatures->specialCmdEn == true) + { + I2cReg_SetSpecialCmdType(pReg, pExtendParameters->specialCmdType); + } + + I2cReg_SetAckForGeneralCall(pReg, pExtendFeatures->ackForGeneralCallEn); + + I2cReg_SetTxEmptyCtrl(pReg, pExtendParameters->txEmptyCtrl); + + { + /* Spike suppression */ + uint32_t tSpikCnt = 0; + + tSpikCnt = ((uint32_t)pExtendParameters->spikeSuppressionTime_ns / ((I2CDRV_MILLI_RATE * I2CDRV_MILLI_RATE) / (busClockFreq / I2CDRV_MILLI_RATE))); + I2cReg_SetSpikeLen(pReg, (tSpikCnt & 0xFF)); + } + + { + uint16_t tCnt = 0; + uint16_t tHighLevelCnt = 0; + uint16_t tLowLevelCnt = 0; + uint8_t tSpkLen = 0; + I2cDrv_SpeedModeType tSpeedMode; + + tSpeedMode = (I2cDrv_SpeedModeType)I2cReg_GetSpeedMode(pReg); + + tSpkLen = I2cReg_GetSpikeLen(pReg); + + if(tSpeedMode == I2CDRV_SPEED_MODE_STANDARD_100KBIT) + { + tHighLevelCnt = I2cReg_GetStandardModeHighLevelCount(pReg); + tLowLevelCnt = I2cReg_GetStandardModeLowLevelCount(pReg); + + /* modify the high counter, accord to the datasheet */ + if(tHighLevelCnt > (tSpkLen + 3u)) + { + I2cReg_SetStandardModeHighLevelCount(pReg, tHighLevelCnt - tSpkLen - 3u); + tHighLevelCnt = I2cReg_GetStandardModeHighLevelCount(pReg); + } + } + else if(tSpeedMode == I2CDRV_SPEED_MODE_FAST_400KBIT_1000KBIT) + { + tHighLevelCnt = I2cReg_GetFastModeHighLevelCount(pReg); + tLowLevelCnt = I2cReg_GetFastModeLowLevelCount(pReg); + + /* modify the high counter, accord to the datasheet */ + if(tHighLevelCnt > (tSpkLen + 3u)) + { + I2cReg_SetFastModeHighLevelCount(pReg, tHighLevelCnt - tSpkLen - 3u); + + tHighLevelCnt = I2cReg_GetFastModeHighLevelCount(pReg); + } + } + else + { + /* Not support high-speed mode */ + } + + if(I2cReg_GetModuleAsMaster(pReg) == true) + { + /* Rx Hold time */ + tCnt = (uint16_t)((uint32_t)pExtendParameters->rxHoldTime_ns / ((I2CDRV_MILLI_RATE * I2CDRV_MILLI_RATE) / (busClockFreq / I2CDRV_MILLI_RATE))); + if(tCnt <= (tHighLevelCnt - tSpkLen - 3u)) + { + I2cReg_SetRxDataHoldTime(pReg, tCnt); + } + + /* Tx Hold time */ + tCnt = (uint16_t)((uint32_t)pExtendParameters->txHoldTime_ns / ((I2CDRV_MILLI_RATE * I2CDRV_MILLI_RATE) / (busClockFreq / I2CDRV_MILLI_RATE))); + if(tCnt < (tLowLevelCnt - 2u)) + { + I2cReg_SetTxDataHoldTime(pReg, tCnt); + } + } + else + { + /* TODO: Rx Hold time, < tf (scl from high to low duration ) */ + tCnt = (uint16_t)((uint32_t)pExtendParameters->rxHoldTime_ns / ((I2CDRV_MILLI_RATE * I2CDRV_MILLI_RATE) / (busClockFreq / I2CDRV_MILLI_RATE))); + if(tCnt < (tHighLevelCnt - tSpkLen - 3u)) + { + I2cReg_SetRxDataHoldTime(pReg, tCnt); + } + + /* Tx Hold time */ + tCnt = (uint16_t)((uint32_t)pExtendParameters->txHoldTime_ns / ((I2CDRV_MILLI_RATE * I2CDRV_MILLI_RATE) / (busClockFreq / I2CDRV_MILLI_RATE))); + if((tCnt >= (tSpkLen + 7u)) && (tCnt < (tLowLevelCnt - 2u))) + { + I2cReg_SetTxDataHoldTime(pReg, tCnt); + } + else + { + I2cReg_SetTxDataHoldTime(pReg, (tSpkLen + 7u)); + } + + I2cReg_SetSlaveDetectStopBitMode(pReg, pExtendParameters->slaveDetectStopBitCondition); + } + } + + if(I2cReg_GetModuleAsMaster(pReg) == false) + { + uint16_t tCnt = 0; + + /* Data setup time,The IC_SDA_SETUP register is only used by the DW_apb_i2c when operating as a slave transmitter */ + tCnt = (uint16_t)((uint32_t)pExtendParameters->dataSetUpTime_ns / ((I2CDRV_MILLI_RATE * I2CDRV_MILLI_RATE) / (busClockFreq / I2CDRV_MILLI_RATE))); + + I2cReg_SetDataSetUpTime(pReg, (uint8_t)(tCnt + 1u)); + } +} + +/*! \brief Enable or Disable one or more than one interrupt source + * + * This function set the interrupt request action if condition matched + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] isrSrc :can used the more than one interrupt source once + * \param[in] isrEn :True(Enable) or false(Disable) + * \return: void + */ +void I2cDrv_SetInterruptReq(I2cDrvType *obj, uint32_t isrSrc, bool isrEn) +{ + if(isrSrc > I2CDRV_ISR_SRC_ALL) + { + return; + } + I2cReg_SetInterruptMask(obj->reg, isrSrc, isrEn); +} + +/*! \brief Clear one interrupt flag + * + * This function clear the interrupt flag if condition matched + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] isrSrc :can use one interrupt source once + * \return: void + */ +void I2cDrv_ClrInterruptFlag(I2cDrvType *obj, uint32_t isrSrc) +{ + if(isrSrc > I2CDRV_ISR_SRC_ALL) + { + return; + } + switch(isrSrc) + { + case I2CDRV_ISR_SRC_ALL: + I2cReg_ClearAllInterruptStatus(obj->reg); + break; + case I2CDRV_ISR_SRC_RX_UNDER: + I2cReg_ClearRxUnderStatus(obj->reg); + break; + case I2CDRV_ISR_SRC_RX_OVER: + I2cReg_ClearRxOverStatus(obj->reg); + break; + case I2CDRV_ISR_SRC_TX_OVER: + I2cReg_ClearTxOverStatus(obj->reg); + break; + case I2CDRV_ISR_SRC_RD_REQ: + I2cReg_ClearReadReqStatus(obj->reg); + break; + case I2CDRV_ISR_SRC_TX_ABRT: + I2cReg_ClearTxAbortStatus(obj->reg); + break; + case I2CDRV_ISR_SRC_RX_DONE: + I2cReg_ClearRxDoneStatus(obj->reg); + break; + case I2CDRV_ISR_SRC_ACTIVITY: + I2cReg_ClearActivityStatus(obj->reg); + break; + case I2CDRV_ISR_SRC_STOP_DET: + I2cReg_ClearStopBitDetectStatus(obj->reg); + break; + case I2CDRV_ISR_SRC_START_DET: + I2cReg_ClearStartBitDetectStatus(obj->reg); + break; + case I2CDRV_ISR_SRC_GEN_CALL: + I2cReg_ClearGeneralCallStatus(obj->reg); + break; + + default: + break; + } +} + +/*! \brief Get the current interrupt status + * + * This function get the current inyrttupy is enabled or disabled + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] isrSrc: Interrupt source + * \return: bool + * true: is enabled + * false: is disabled + */ +bool I2cDrv_GetInterruptIsEnabled(I2cDrvType *obj, I2cDrv_IsrSrcType isrSrc) +{ + return I2cReg_GetInterruptIsEnabled(obj->reg, isrSrc); +} + +/*! \brief Get I2C interrupt status + * + * this function get the special interrupt status + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] isrSrc: Interrupt source + * \return: bool + * 0h: inactive + * 1h: active + */ +bool I2cDrv_GetInterruptStatus(I2cDrvType *obj, I2cDrv_IsrSrcType isrSrc) +{ + return I2cReg_GetInterruptStatus(obj->reg, isrSrc); +} + +/*! \brief Get I2C raw interrupt status + * + * this function get the interrupt raw status + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] isrSrc: Interrupt source + * \return: bool + * 0h: inactive + * 1h: active + */ +bool I2cDrv_GetInterruptRawStatus(I2cDrvType *obj, I2cDrv_IsrSrcType isrSrc) +{ + return I2cReg_GetInterruptRawStatus(obj->reg, isrSrc); +} + +/*! \brief Contains the number of valid data entries in the receive FIFO. + * + * this function get the number of valid data entries in the receive FIFO. + * + * \param[in] obj :pointer to I2C driver instance + * \return: the number of valid data entries in the receive FIFO. + */ +uint8_t I2cDrv_GetRxFifoLevel(I2cDrvType *obj) +{ + return I2cReg_GetRxFifoLevel(obj->reg); +} + +/*! \brief Set RX FIFO threshold + * + * I2C RX FIFO threshold FIFO depth is 16 + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] rxFifoThreshold: RX FIFO threshold value + * \return: void + */ +void I2cDrv_SetRxFifoThreshold(I2cDrvType *obj, uint8_t rxFifoThreshold) +{ + I2cReg_SetRxFifoThreshold(obj->reg, rxFifoThreshold); +} + +/*! \brief Set TX FIFO threshold + * + * I2C TX FIFO threshold FIFO depth is 16 + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] txFifoThreshold: TX FIFO threshold value + * \return: void + */ +void I2cDrv_SetTxFifoThreshold(I2cDrvType *obj, uint8_t txFifoThreshold) +{ + I2cReg_SetTxFifoThreshold(obj->reg, txFifoThreshold); +} + +/*! \brief Get default configures the I2C module for configuration structure + * + * This function gets default configures the I2C module for user configuration structure + * + * \param[in] pInitCfg: pointer to configuration structure + * \return: void + */ +void I2cDrv_GetDefaultConfig(I2cDrv_InitCfgType *pInitCfg) +{ + pInitCfg->basicParameters.busClockFreq = 48000000ul; + pInitCfg->basicParameters.sclFreq = 20000; + pInitCfg->basicParameters.addressMode = I2CDRV_ADDR_MODE_7BIT; + pInitCfg->basicParameters.nodeMode = I2CDRV_NODE_MODE_AS_MASTER; + pInitCfg->basicParameters.ownAddress = 0x75; + pInitCfg->basicParameters.targetAddress = 0x28; + pInitCfg->basicParameters.restartBitEn = true; + pInitCfg->basicParameters.speedMode = I2CDRV_SPEED_MODE_STANDARD_100KBIT; + + pInitCfg->extendFeatures.dmaRxEn = false; + pInitCfg->extendFeatures.dmaTxEn = false; + pInitCfg->extendFeatures.ackForGeneralCallEn = false; + pInitCfg->extendFeatures.specialCmdEn = false; + + pInitCfg->extendParameters.spikeSuppressionTime_ns = 50; + pInitCfg->extendParameters.rxHoldTime_ns = 2; + pInitCfg->extendParameters.txHoldTime_ns = 100; + pInitCfg->extendParameters.dataSetUpTime_ns = 100; + pInitCfg->extendParameters.dmaTxDataLevel = 0; + pInitCfg->extendParameters.dmaRxDataLevel = 0; + pInitCfg->extendParameters.specialCmdType = I2CDRV_SPECIAL_CMD_GENERAL_CALL; + pInitCfg->extendParameters.slaveDetectStopBitCondition = I2CDRV_SLAVE_DETECT_STOPBIT_CONDITION_IN_ADDR_MATCH; + pInitCfg->extendParameters.txEmptyCtrl = I2CDRV_TX_EMPTY_AT_TXFIFO_LESSTHAN_TXTL; +} + +/*! \brief Set the module function with the configuration + * + * This function initializes the run-time state structure to provide for module configuration + * + * \param[in] obj : pointer to I2C driver instance + * \param[in] pInitCfg : point to the I2C initialize configuration + * \return: void + */ +void I2cDrv_SetConfig(I2cDrvType *obj, const I2cDrv_InitCfgType *pInitCfg) +{ + I2cReg_SetModuleEnable(obj->reg, false); + + /* Disable all interrupt req */ + I2cReg_SetInterruptMask(obj->reg, 0xFFFFFFFF, false); + + /* Clear all status that can be cleared by software except be cleared by hardware */ + I2cReg_ClearAllInterruptStatus(obj->reg); + + if(pInitCfg->basicParameters.nodeMode == I2CDRV_NODE_MODE_AS_SLAVE) + { + /* Disable slave mode */ + I2cReg_SetSlaveModeDisable(obj->reg, true); + } + + I2cDrv_InitBasicParameters(obj->reg, &pInitCfg->basicParameters); + + I2cDrv_InitExtendParameters(obj->reg, &pInitCfg->extendFeatures, &pInitCfg->extendParameters, pInitCfg->basicParameters.busClockFreq); + + I2cReg_SetModuleEnable(obj->reg, true); +} + +/*! \brief Resets the I2C internal logic and registers to their default settings + * + * This function initializes I2C driver by setting the register instance to it. + * + * \param[in] obj: pointer to I2C driver instance + * \param[in] pReg: pointer to I2C register instance + * \return: void + */ +void I2cDrv_Init(I2cDrvType *obj, I2cRegType *pReg) +{ + obj->reg = pReg; + + /* Disable module to make sure some register have been configurated successfully */ + I2cReg_SetModuleEnable(obj->reg, false); + + /* Clear all status that can be cleared by software except be cleared by hardware */ + I2cReg_ClearAllInterruptStatus(obj->reg); +} + +/*! \brief Deinit module into default state + * + * Call back in the usage of low power or sleep requirements + * + * \param[in] obj: pointer to I2C driver instance + * \return: void + */ +void I2cDrv_DeInit(I2cDrvType *obj) +{ + /* Disable module to make sure some register have been configurated successfully */ + I2cReg_SetModuleEnable(obj->reg, false); +} + +/*! \brief transmit data to other node + * + * This function request data to be sent + * + * \param[in] obj: pointer to I2C driver instance + * \param[in] pTxBuf: the pointer tx data + * \param[in] txBytesNum: how many bytes to be sent + * \return: bool + * true: request successful + * false: no enouth space for the current tx request + */ +bool I2cDrv_RequestWriteData(I2cDrvType *obj, const uint8_t *pTxBuf, uint8_t txBytesNum) +{ + bool tRtn = true; + + uint8_t i = 0; + + if((I2CDRV_TX_FIFO_DEPTH - I2cReg_GetTxFifoLevel(obj->reg)) >= txBytesNum) + { + for(i = 0; i < txBytesNum; i++) + { + I2cReg_SetDataAndCmd(obj->reg, pTxBuf[i], false); + } + } + else + { + tRtn = false; + } + + return tRtn; +} + +/*! \brief Receive data from other node + * + * This function request to received data + * + * \param[in] obj: pointer to I2C driver instance + * \param[in] rxBytesNum: how many bytes to be read out + * \return: void + */ +bool I2cDrv_RequestReadData(I2cDrvType *obj, uint8_t rxBytesNum) +{ + bool tRtn = true; + uint8_t i = 0; + + if((I2CDRV_TX_FIFO_DEPTH - I2cReg_GetTxFifoLevel(obj->reg)) >= rxBytesNum) + { + for(i = 0; i < rxBytesNum; i++) + { + I2cReg_SetDataAndCmd(obj->reg, 0u, true); + } + } + else + { + tRtn = false; + } + + return tRtn; +} + +/*! \brief Read received data from rx fifo + * + * This function read data from rx fifo + * + * \param[in] obj: pointer to I2C driver instance + * \param[in] pRxBuf : the space for read-out data + * \return: return how many bytes are received + */ +uint8_t I2cDrv_GetReceivedData(const I2cDrvType *obj, uint8_t *pRxBuf) +{ + uint8_t tRxBytesNum = 0, i = 0; + + tRxBytesNum = I2cReg_GetRxFifoLevel(obj->reg); + + if(tRxBytesNum > 0u) + { + for(i = 0; i < tRxBytesNum; i++) + { + pRxBuf[i] = I2cReg_GetData(obj->reg); + } + } + + return tRxBytesNum; +} + +/*! \brief Master request to abort current transfer + * + * This function request to abort the current transfer process + * + * \param[in] obj: pointer to I2C driver instance + * \return: void + */ +void I2cDrv_MasterAbortTransfer(I2cDrvType *obj) +{ + if(I2cReg_GetDmaTxIsEnabled(obj->reg) == true) + { + I2cReg_SetTxDmaEnable(obj->reg, false); + } + + /* TODO: Generate an interrupt event after abort operation? */ + I2cReg_SetInterruptMask(obj->reg, I2C_INTR_MASK_TX_ABRT_MASK, false); + + I2cReg_SetAbortReq(obj->reg); + + /* Wait tx abort status set to 1 */ + while(I2cReg_GetInterruptRawStatus(obj->reg, I2C_INTR_STAT_TX_ABRT_MASK) == false) + { + } + + /* Check the current abort request is from master request */ + if(I2cReg_GetTxAbortInfo(obj->reg, I2C_TX_ABRT_SOURCE_ABRT_USER_ABRT_MASK) == true) + { + } +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/i2c/i2c_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/i2c/i2c_drv.h new file mode 100644 index 0000000..53fb061 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/i2c/i2c_drv.h @@ -0,0 +1,352 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _I2C_DRV_H +#define _I2C_DRV_H + +/*! \brief Contains public interface to various functions related + * to the driver of I2C module + */ + +/****************************************************************************** + * the includes + *****************************************************************************/ + +#include +#include +#include "i2c_reg.h" + +/*! \addtogroup i2c_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * the defines + *****************************************************************************/ +#define I2CDRV_STANDARDSPEED_UPPER_FREQ_VALUE (100000ul) /* Hz */ +#define I2CDRV_FASTSPEED_UPPER_FREQ_VALUE (1000000ul) /* Hz */ + +#define I2CDRV_TX_FIFO_DEPTH (16u) +#define I2CDRV_RX_FIFO_DEPTH (16u) + +/****************************************************************************** + * the typedefs + *****************************************************************************/ +/*! \brief I2C node cosplayer */ +typedef enum +{ + I2CDRV_NODE_MODE_AS_SLAVE = 0u, + I2CDRV_NODE_MODE_AS_MASTER +} I2cDrv_NodeModeType; + +/*! \brief I2C address bit type */ +typedef enum +{ + I2CDRV_ADDR_MODE_7BIT = 0u, + I2CDRV_ADDR_MODE_10BIT +} I2cDrv_AddressModeType; + +/*! \brief I2C speed mode selection */ +typedef enum +{ + I2CDRV_SPEED_MODE_STANDARD_100KBIT = 1u, + I2CDRV_SPEED_MODE_FAST_400KBIT_1000KBIT, + I2CDRV_SPEED_MODE_HIGH /* Not support in the current IP */ +} I2cDrv_SpeedModeType; + +/*! \brief I2C APB data width type */ +typedef enum +{ + I2CDRV_APB_DATA_WIDTH_8BIT = 0u, + I2CDRV_APB_DATA_WIDTH_16BIT, + I2CDRV_APB_DATA_WIDTH_32BIT +} I2cDrv_ApbDataWidthType; + +/*! \brief I2C special command selection */ +typedef enum +{ + I2CDRV_SPECIAL_CMD_GENERAL_CALL = 0u, + I2CDRV_SPECIAL_CMD_START_BYTE +} I2cDrv_SpecialCmdType; + +/*! \brief I2C detect stop bit condition */ +typedef enum +{ + I2CDRV_SLAVE_DETECT_STOPBIT_CONDITION_IN_ANYTIME = 0u, + I2CDRV_SLAVE_DETECT_STOPBIT_CONDITION_IN_ADDR_MATCH +} I2cDrv_SlaveDetectStopBitConditionType; + +/*! \brief I2C tx empty control selection */ +typedef enum +{ + I2CDRV_TX_EMPTY_AT_TXFIFO_LESSTHAN_TXTL = 0u, + I2CDRV_TX_EMPTY_AT_LAST_DATA_TRANSFERED +} I2cDrv_TxEmptyCtrlType; + +/*! \brief Interrupt source */ +typedef enum +{ + I2CDRV_ISR_SRC_RX_UNDER = I2C_INTR_STAT_RX_UNDER_MASK, + I2CDRV_ISR_SRC_RX_OVER = I2C_INTR_STAT_RX_OVER_MASK, + I2CDRV_ISR_SRC_RX_FULL = I2C_INTR_STAT_RX_FULL_MASK, + I2CDRV_ISR_SRC_TX_OVER = I2C_INTR_STAT_TX_OVER_MASK, + I2CDRV_ISR_SRC_TX_EMPTY = I2C_INTR_STAT_TX_EMPTY_MASK, + I2CDRV_ISR_SRC_RD_REQ = I2C_INTR_STAT_RD_REQ_MASK, + I2CDRV_ISR_SRC_TX_ABRT = I2C_INTR_STAT_TX_ABRT_MASK, + I2CDRV_ISR_SRC_RX_DONE = I2C_INTR_STAT_RX_DONE_MASK, + I2CDRV_ISR_SRC_ACTIVITY = I2C_INTR_STAT_ACTIVITY_MASK, + I2CDRV_ISR_SRC_STOP_DET = I2C_INTR_STAT_STOP_DET_MASK, + I2CDRV_ISR_SRC_START_DET = I2C_INTR_STAT_START_DET_MASK, + I2CDRV_ISR_SRC_GEN_CALL = I2C_INTR_STAT_GEN_CALL_MASK, + I2CDRV_ISR_SRC_ALL = 0XFFF +} I2cDrv_IsrSrcType; + +/*! \brief I2C basic parameter information */ +typedef struct _I2cDrv_BasicParametersType_ +{ + uint32_t busClockFreq; + uint32_t sclFreq; + I2cDrv_NodeModeType nodeMode; + uint16_t ownAddress; + uint16_t targetAddress; + I2cDrv_AddressModeType addressMode; + bool restartBitEn; + I2cDrv_SpeedModeType speedMode; +} I2cDrv_BasicParametersType; + +/*! \brief I2C extend parameter information */ +typedef struct _I2cDrv_ExtendParametersType_ +{ + uint16_t spikeSuppressionTime_ns; + uint16_t rxHoldTime_ns; + uint16_t txHoldTime_ns; + uint16_t dataSetUpTime_ns; + uint8_t dmaTxDataLevel; + uint8_t dmaRxDataLevel; + I2cDrv_SpecialCmdType specialCmdType; + I2cDrv_SlaveDetectStopBitConditionType slaveDetectStopBitCondition; + I2cDrv_TxEmptyCtrlType txEmptyCtrl; +} I2cDrv_ExtendParametersType; + +/*! \brief I2C extend feature information */ +typedef struct _I2cDrv_ExtendFeaturesType_ +{ + bool dmaTxEn; + bool dmaRxEn; + bool ackForGeneralCallEn; + bool specialCmdEn; +} I2cDrv_ExtendFeaturesType; + +/*! \brief I2C initialize configuration information */ +typedef struct _I2cDrv_InitCfgType_ +{ + I2cDrv_BasicParametersType basicParameters; + I2cDrv_ExtendParametersType extendParameters; + I2cDrv_ExtendFeaturesType extendFeatures; +} I2cDrv_InitCfgType; + +/*! \brief I2C instance pointer */ +typedef struct _I2cDrvType_ +{ + I2cRegType *reg; +} I2cDrvType; + +/****************************************************************************** + * the globals + *****************************************************************************/ + +/****************************************************************************** + * the function prototypes + *****************************************************************************/ + +/*! \brief Get default configures the I2C module for configuration structure + * + * Note: This function gets default configures the I2C module for user configuration structure + * + * \param[in] pInitCfg: pointer to configuration structure + * \return: void + */ +extern void I2cDrv_GetDefaultConfig(I2cDrv_InitCfgType *pInitCfg); + +/*! \brief Set the module function with the configuration + * + * Note: This function initializes the run-time state structure to provide for module configuration + * + * \param[in] obj : pointer to I2C driver instance + * \param[in] pInitCfg : point to the I2C initialize configuration + * \return: void + */ +extern void I2cDrv_SetConfig(I2cDrvType *obj, const I2cDrv_InitCfgType *pInitCfg); + +/*! \brief Resets the I2C internal logic and registers to their default settings + * + * Note: This function initializes I2C driver by setting the register instance to it. + * + * \param[in] obj: pointer to I2C driver instance + * \param[in] pReg: pointer to I2C register instance + * \return: void + */ +extern void I2cDrv_Init(I2cDrvType *obj, I2cRegType *pReg); + +/*! \brief Deinit module into default state + * + * Note: Call back in the usage of low power or sleep requirements + * + * \param[in] obj: pointer to I2C driver instance + * \return: void + */ +extern void I2cDrv_DeInit(I2cDrvType *obj); + +/*! \brief Enable or Disable one or more than one interrupt source + * + * This function set the interrupt request action if condition matched + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] isrSrc :can used the more than one interrupt source once + * \param[in] isrEn :True(Enable) or false(Disable) + * \return: void + */ +extern void I2cDrv_SetInterruptReq(I2cDrvType *obj, uint32_t isrSrc, bool isrEn); + +/*! \brief Clear one interrupt flag + * + * This function clear the interrupt flag if condition matched + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] isrSrc :can use one interrupt source once + * \return: void + */ +extern void I2cDrv_ClrInterruptFlag(I2cDrvType *obj, uint32_t isrSrc); + +/*! \brief Get the current interrupt status + * + * This function get the current inyrttupy is enabled or disabled + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] interruptSource: Interrupt source + * \return: bool + * true: is enabled + * false: is disabled + */ +bool I2cDrv_GetInterruptIsEnabled(I2cDrvType *obj, I2cDrv_IsrSrcType interruptSource); + +/*! \brief Get I2C interrupt status + * + * this function get the special interrupt status + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] interruptSource: Interrupt source + * \return: bool + * 0h: inactive + * 1h: active + */ +bool I2cDrv_GetInterruptStatus(I2cDrvType *obj, I2cDrv_IsrSrcType interruptSource); + +/*! \brief Get I2C raw interrupt status + * + * this function get the interrupt raw status + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] isrSrc: Interrupt source + * \return: bool + * 0h: inactive + * 1h: active + */ +bool I2cDrv_GetInterruptRawStatus(I2cDrvType *obj, I2cDrv_IsrSrcType isrSrc); + +/*! \brief Contains the number of valid data entries in the receive FIFO. + * + * this function get the number of valid data entries in the receive FIFO. + * + * \param[in] obj :pointer to I2C driver instance + * \return: the number of valid data entries in the receive FIFO. + */ +uint8_t I2cDrv_GetRxFifoLevel(I2cDrvType *obj); + +/*! \brief Set RX FIFO threshold + * + * I2C RX FIFO threshold FIFO depth is 16 + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] rxFifoThreshold: RX FIFO threshold value + * \return: void + */ +void I2cDrv_SetRxFifoThreshold(I2cDrvType *obj, uint8_t rxFifoThreshold); + +/*! \brief Set TX FIFO threshold + * + * I2C TX FIFO threshold FIFO depth is 16 + * + * \param[in] obj :pointer to I2C driver instance + * \param[in] txFifoThreshold: TX FIFO threshold value + * \return: void + */ +void I2cDrv_SetTxFifoThreshold(I2cDrvType *obj, uint8_t txFifoThreshold); + +/*! \brief transmit data to other node + * + * Note: This function request data to be sent + * + * \param[in] obj: pointer to I2C driver instance + * \param[in] pTxBuf: the pointer tx data + * \param[in] txBytesNum: how many bytes to be sent + * \return: bool + * true: request successful + * false: no enouth space for the current tx request + */ +extern bool I2cDrv_RequestWriteData(I2cDrvType *obj, const uint8_t *pTxBuf, uint8_t txBytesNum); + +/*! \brief Receive data from other node + * + * Note: This function request to received data + * + * \param[in] obj: pointer to I2C driver instance + * \param[in] pRxBuf: the read-out data to be filled in + * \param[in] rxBytesNum: how many bytes to be read out + * \return: void + */ +extern bool I2cDrv_RequestReadData(I2cDrvType *obj, uint8_t rxBytesNum); + +/*! \brief Read received data from rx fifo + * + * Note: This function read data from rx fifo + * + * \param[in] obj: pointer to I2C driver instance + * \param[in] pRxBuf : the space for read-out data + * \return: return how many bytes are received + */ +extern uint8_t I2cDrv_GetReceivedData(const I2cDrvType *obj, uint8_t *pRxBuf); + +/*! \brief Master request to abort current transfer + * + * Note: This function request to abort the current transfer process + * + * \param[in] obj: pointer to I2C driver instance + * \return: void + */ +extern void I2cDrv_MasterAbortTransfer(I2cDrvType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _I2C_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/i2sm/i2sm_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/i2sm/i2sm_drv.c new file mode 100644 index 0000000..4a05df1 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/i2sm/i2sm_drv.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "sim_reg.h" +#include "i2sm_drv.h" +#include "i2sm_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +void I2smDrv_Init(I2smDrvType *obj, struct _I2smRegType_ *reg1, struct _SimRegType_ *reg2) +{ + obj->regI2sm = reg1; + obj->regSim = reg2; +} + +void I2smDrv_GetDefaultConfig(I2smDrv_ConfigType *userConfig) +{ + userConfig->txFifoTriggerLevel = 3; + userConfig->wsCycle = I2SMDRV_CLOCK_CYCLES_32; + userConfig->sclkGateCycle = I2SMDRV_NO_CLOCK_GATE; + userConfig->dataResolution = I2SMDRV_RESOLUTION_32; + userConfig->txFifoEmptyIntMask = 1; + userConfig->txFifoOverrunIntMask = 1; +} + +void I2smDrv_Config(I2smDrvType *obj, const I2smDrv_ConfigType *userConfig) +{ + /* select I2S as master mode */ + SimReg_SetI2sMode(obj->regSim, 1); + /* enable I2S module */ + I2smReg_SetIerEn(obj->regI2sm, 1); + /* set FIFO threshold */ + I2smReg_SetTfcr0Tfcr0(obj->regI2sm, userConfig->txFifoTriggerLevel); + /* set ws cycle */ + I2smReg_SetCcrWss(obj->regI2sm, userConfig->wsCycle); + /* set clock gate cycle */ + I2smReg_SetCcrSclkg(obj->regI2sm, userConfig->sclkGateCycle); + /* set data resolution */ + I2smReg_SetTcr0TxWLen(obj->regI2sm, userConfig->dataResolution); + /* config interrupt mask for fifo empty */ + I2smReg_SetImr0TxFem(obj->regI2sm, userConfig->txFifoEmptyIntMask); + /* config interrupt mask for fifo overrun */ + I2smReg_SetImr0TxFom(obj->regI2sm, userConfig->txFifoOverrunIntMask); + /* enable tx block */ + I2smReg_SetIterTxEn(obj->regI2sm, 1); + /* enable tx channel0 */ + I2smReg_SetTer0TxChEn0(obj->regI2sm, 1); +} + +void I2smDrv_FillFifoByDma(I2smDrvType *obj, uint32_t *data, uint8_t len) +{ + for(uint8_t i = 0; i < len; i++) + { + I2smReg_SetTxDmaTxDma(obj->regI2sm, data[i]); + } +} + +void I2smDrv_FillFifoByBuffer(I2smDrvType *obj, uint32_t *data, uint8_t len) +{ + for(uint8_t i = 0; i < len; i += 2) + { + I2smReg_SetLthr0Lthr0(obj->regI2sm, data[i]); + I2smReg_SetRthr0Rthr0(obj->regI2sm, data[i + 1]); + } +} + +void I2smDrv_StartTransmit(I2smDrvType *obj) +{ + /* enable the clock */ + I2smReg_SetCerClkEn(obj->regI2sm, 1); +} + +void I2smDrv_StopTransmit(I2smDrvType *obj) +{ + /* disable the clock */ + I2smReg_SetCerClkEn(obj->regI2sm, 0); +} + +void I2smDrv_FlushTxFifo(I2smDrvType *obj) +{ + /* flush tx fifo 0 */ + I2smReg_SetTff0TxChfr0(obj->regI2sm, 1); +} + +bool I2smDrv_GetFifoOverrunFlag(I2smDrvType *obj) +{ + bool flag = 0; + flag = I2smReg_GetIsr0TxFO(obj->regI2sm); + return flag; +} + +bool I2smDrv_GetFifoLevelTrigFlag(I2smDrvType *obj) +{ + bool flag = 0; + flag = I2smReg_GetIsr0TxFE(obj->regI2sm); + return flag; +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/i2sm/i2sm_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/i2sm/i2sm_drv.h new file mode 100644 index 0000000..287036f --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/i2sm/i2sm_drv.h @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _I2SM_DRV_H_ +#define _I2SM_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of I2SM (I2S Master) + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup i2sm_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +#define TX_FIFO_DEPTH (16U) /*!< the tx fifo depth */ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +typedef enum +{ + I2SMDRV_CLOCK_CYCLES_16 = 0x0U, /*!< word select line stays 16 sclk cycles for left or right sample */ + I2SMDRV_CLOCK_CYCLES_24 = 0x1U, /*!< word select line stays 24 sclk cycles for left or right sample */ + I2SMDRV_CLOCK_CYCLES_32 = 0x2U /*!< word select line stays 32 sclk cycles for left or right sample */ +} I2smDrvWssType; + +typedef enum +{ + I2SMDRV_NO_CLOCK_GATE = 0x0U, /*!< clock gate is disabled */ + I2SMDRV_CLOCK_GATE_12 = 0x1U, /*!< clock gate is setting at 12 cycles */ + I2SMDRV_CLOCK_GATE_16 = 0x2U, /*!< clock gate is setting at 16 cycles */ + I2SMDRV_CLOCK_GATE_20 = 0x3U, /*!< clock gate is setting at 20 cycles */ + I2SMDRV_CLOCK_GATE_24 = 0x4U /*!< clock gate is setting at 24 cycles */ +} I2smDrvSclkGateType; + +typedef enum +{ + I2SMDRV_IGNORE_WORD_LEN = 0x0U, /*!< Ignore the word length */ + I2SMDRV_RESOLUTION_12 = 0x1U, /*!< data resolution is 12 bits */ + I2SMDRV_RESOLUTION_16 = 0x2U, /*!< data resolution is 16 bits */ + I2SMDRV_RESOLUTION_20 = 0x3U, /*!< data resolution is 20 bits */ + I2SMDRV_RESOLUTION_24 = 0x4U, /*!< data resolution is 24 bits */ + I2SMDRV_RESOLUTION_32 = 0x5U /*!< data resolution is 32 bits */ +} I2smDrvDataResolutionType; + +/*! \brief The definition of I2SM driver class + */ +typedef struct _I2smDrvType_ +{ + struct _I2smRegType_ *regI2sm; + struct _SimRegType_ *regSim; +} I2smDrvType; + +typedef struct _I2smDrv_ConfigType_ +{ + I2smDrvWssType wsCycle; /*!< number of clk cyles for ws line in left or right sample mode */ + I2smDrvSclkGateType sclkGateCycle; /*!< clock gate of the sclk */ + I2smDrvDataResolutionType dataResolution; /*!< data resolution of the transmitter */ + uint8_t txFifoTriggerLevel; /*!< the threshold level of the tx fifo trigger */ + bool txFifoEmptyIntMask; /*!< TXFE interrupt mask */ + bool txFifoOverrunIntMask; /*!< TXFO interrupt mask */ +} I2smDrv_ConfigType; +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the I2SM reg + * + * + * \param[in] obj : pointer to I2SM driver instance + * \param[in] reg1 : pointer to I2SM register instance + * \param[in] reg2 : pointer to SIM register instance + */ +extern void I2smDrv_Init(I2smDrvType *obj, struct _I2smRegType_ *reg1, struct _SimRegType_ *reg2); + +/*! \brief Get default configures the I2SM module for configuration structure + * + * + * \param[in] userConfig : pointer to user config sturcture + */ +extern void I2smDrv_GetDefaultConfig(I2smDrv_ConfigType *userConfig); + +/*! \brief config the I2SM module as userConfig + * + * + * \param[in] obj : pointer to I2SM driver instance + * \param[in] userConfig : pointer to user config sturcture + */ +extern void I2smDrv_Config(I2smDrvType *obj, const I2smDrv_ConfigType *userConfig); + +/*! \brief fill the tx FIFO via DMA + * + * + * \param[in] obj : pointer to I2SM driver instance + * \param[in] data : pointer to user data + * \param[in] len : the data length to transfer + */ +extern void I2smDrv_FillFifoByDma(I2smDrvType *obj, uint32_t *data, uint8_t len); + +/*! \brief fill the tx FIFO via buffer + * + * + * \param[in] obj : pointer to I2SM driver instance + * \param[in] data : pointer to user data + * \param[in] len : the data length to transfer + */ +extern void I2smDrv_FillFifoByBuffer(I2smDrvType *obj, uint32_t *data, uint8_t len); + +/*! \brief start transmit data + * + * + * \param[in] obj : pointer to I2SM driver instance + */ +extern void I2smDrv_StartTransmit(I2smDrvType *obj); + +/*! \brief stop transmit data + * + * + * \param[in] obj : pointer to I2SM driver instance + */ +extern void I2smDrv_StopTransmit(I2smDrvType *obj); + +/*! \brief flush the tx fifo + * + * + * \param[in] obj : pointer to I2SM driver instance + */ +extern void I2smDrv_FlushTxFifo(I2smDrvType *obj); + +/*! \brief get the status flag of fifo overrun + * + * + * \param[in] obj : pointer to I2SM driver instance + * \param[out] bool : flag status + * - false : not overrun + * - true : overrun + */ +extern bool I2smDrv_GetFifoOverrunFlag(I2smDrvType *obj); + +/*! \brief get the status flag of fifo level trig + * + * + * \param[in] obj : pointer to I2SM driver instance + * \param[out] bool : flag status + * - false : not reach the trig level + * - true : reach the trig level + */ +extern bool I2smDrv_GetFifoLevelTrigFlag(I2smDrvType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _I2SM_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/i2ss/i2ss_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/i2ss/i2ss_drv.c new file mode 100644 index 0000000..f5c8cfd --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/i2ss/i2ss_drv.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ +#include "sim_reg.h" +#include "i2ss_drv.h" +#include "i2ss_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +void I2ssDrv_Init(I2ssDrvType *obj, struct _I2ssRegType_ *reg1, struct _SimRegType_ *reg2) +{ + obj->regI2ss = reg1; + obj->regSim = reg2; +} + +void I2ssDrv_GetDefaultConfig(I2ssDrv_ConfigType *userConfig) +{ + userConfig->rxFifoTriggerLevel = 3; + userConfig->rxFifoEmptyIntMask = 1; + userConfig->rxFifoOverrunIntMask = 1; +} + +void I2ssDrv_Config(I2ssDrvType *obj, const I2ssDrv_ConfigType *userConfig) +{ + /* select I2S as master mode */ + SimReg_SetI2sMode(obj->regSim, 0); + /* enable I2S module */ + I2ssReg_SetIerEn(obj->regI2ss, 1); + /* set FIFO threshold */ + I2ssReg_SetRff0RxChfr0(obj->regI2ss, userConfig->rxFifoTriggerLevel); + /* config interrupt mask for fifo empty */ + I2ssReg_SetImr0RxDam(obj->regI2ss, userConfig->rxFifoEmptyIntMask); + /* config interrupt mask for fifo overrun */ + I2ssReg_SetImr0RxFom(obj->regI2ss, userConfig->rxFifoOverrunIntMask); + /* enable rx block */ + I2ssReg_SetIrerRxEn(obj->regI2ss, 1); + /* enable rx channel0 */ + I2ssReg_SetRer0Ch0(obj->regI2ss, 1); +} + +void I2ssDrv_ReadFifoByDma(I2ssDrvType *obj, uint32_t *data, uint8_t len) +{ + for(uint8_t i = 0; i < len; i++) + { + data[i] = I2ssReg_GetRxDmaRxDma(obj->regI2ss); + } +} + +void I2ssDrv_ReadFifoByBuffer(I2ssDrvType *obj, uint32_t *data, uint8_t len) +{ + for(uint8_t i = 0; i < len; i += 2) + { + data[i] = I2ssReg_GetLrbr0Lrbr0(obj->regI2ss); + data[i + 1] = I2ssReg_GetRrbr0Rrbr0(obj->regI2ss); + } +} + +void I2ssDrv_FlushRxFifo(I2ssDrvType *obj) +{ + /* flush rx fifo 0 */ + I2ssReg_SetRff0RxChfr0(obj->regI2ss, 1); +} + +bool I2ssDrv_GetFifoOverrunFlag(I2ssDrvType *obj) +{ + bool flag = 0; + flag = I2ssReg_GetIsr0RxFo(obj->regI2ss); + return flag; +} + +bool I2ssDrv_GetFifoLevelTrigFlag(I2ssDrvType *obj) +{ + bool flag = 0; + flag = I2ssReg_GetIsr0RxDa(obj->regI2ss); + return flag; +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/i2ss/i2ss_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/i2ss/i2ss_drv.h new file mode 100644 index 0000000..a1d179a --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/i2ss/i2ss_drv.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _I2SS_DRV_H_ +#define _I2SS_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of I2SS (I2S Slave) + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup i2ss_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +#define RX_FIFO_DEPTH (16U) /*!< the rx fifo depth */ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +typedef enum +{ + I2SSDRV_IGNORE_WORD_LEN = 0x0U, /*!< Ignore the word length */ + I2SSDRV_RESOLUTION_12 = 0x1U, /*!< data resolution is 12 bits */ + I2SSDRV_RESOLUTION_16 = 0x2U, /*!< data resolution is 16 bits */ + I2SSDRV_RESOLUTION_20 = 0x3U, /*!< data resolution is 20 bits */ + I2SSDRV_RESOLUTION_24 = 0x4U, /*!< data resolution is 24 bits */ + I2SSDRV_RESOLUTION_32 = 0x5U /*!< data resolution is 32 bits */ +} I2ssDrvDataResolutionType; + +/*! \brief The definition of I2SS driver class + */ +typedef struct _I2ssDrvType_ +{ + struct _I2ssRegType_ *regI2ss; + struct _SimRegType_ *regSim; +} I2ssDrvType; + +typedef struct _I2ssDrv_ConfigType_ +{ + I2ssDrvDataResolutionType dataResolution; /*!< data resolution of the receiver */ + uint8_t rxFifoTriggerLevel; /*!< the threshold level of the rx fifo trigger */ + bool rxFifoEmptyIntMask; /*!< RXFE interrupt mask */ + bool rxFifoOverrunIntMask; /*!< RXFO interrupt mask */ +} I2ssDrv_ConfigType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the I2SS reg + * + * + * \param[in] obj : pointer to I2SS driver instance + * \param[in] reg1 : pointer to I2SS register instance + * \param[in] reg2 : pointer to SIM register instance + */ +extern void I2ssDrv_Init(I2ssDrvType *obj, struct _I2ssRegType_ *reg1, struct _SimRegType_ *reg2); + +/*! \brief Get default configures the I2SS module for configuration structure + * + * + * \param[in] userConfig : pointer to user config sturcture + */ +extern void I2ssDrv_GetDefaultConfig(I2ssDrv_ConfigType *userConfig); + +/*! \brief config the I2SS module as userConfig + * + * + * \param[in] obj : pointer to I2SS driver instance + * \param[in] userConfig : pointer to user config sturcture + */ +extern void I2ssDrv_Config(I2ssDrvType *obj, const I2ssDrv_ConfigType *userConfig); + +/*! \brief read data from rx FIFO via DMA + * + * + * \param[in] obj : pointer to I2SS driver instance + * \param[in] data : pointer to user data + * \param[in] len : the data length to transfer + */ +extern void I2ssDrv_ReadFifoByDma(I2ssDrvType *obj, uint32_t *data, uint8_t len); + +/*! \brief read data from rx FIFO via buffer + * + * + * \param[in] obj : pointer to I2SS driver instance + * \param[in] data : pointer to user data + * \param[in] len : the data length to transfer + */ +extern void I2ssDrv_ReadFifoByBuffer(I2ssDrvType *obj, uint32_t *data, uint8_t len); + +/*! \brief flush the rx fifo + * + * + * \param[in] obj : pointer to I2SS driver instance + */ +extern void I2ssDrv_FlushRxFifo(I2ssDrvType *obj); + +/*! \brief get the status flag of fifo overrun + * + * + * \param[in] obj : pointer to I2SS driver instance + * \param[out] bool : flag status + * - false : not overrun + * - true : overrun + */ +extern bool I2ssDrv_GetFifoOverrunFlag(I2ssDrvType *obj); + +/*! \brief get the status flag of fifo level trig + * + * + * \param[in] obj : pointer to I2SS driver instance + * \param[out] bool : flag status + * - false : not reach the trig level + * - true : reach the trig level + */ +extern bool I2ssDrv_GetFifoLevelTrigFlag(I2ssDrvType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _I2SS_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/lpit/lpit_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/lpit/lpit_drv.c new file mode 100644 index 0000000..af11313 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/lpit/lpit_drv.c @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "lpit_drv.h" +#include "lpit_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* Max period in count of all operation mode except for dual 16 bit periodic counter mode */ +#define MAX_PERIOD_COUNT (0xFFFFFFFFU) + +/* Max period in count of dual 16 bit periodic counter mode */ +#define MAX_PERIOD_COUNT_IN_DUAL_16BIT_MODE (0x1FFFEU) + +/* Max count of 16 bit */ +#define MAX_PERIOD_COUNT_16_BIT (0xFFFFU) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void LpitDrv_Init(LpitDrvType *obj, struct _LpitRegType_ *reg) +{ + obj->reg = reg; +} + +void LpitDrv_GetDefaultConfig(LpitDrv_ConfigType *userConfig) +{ + userConfig->enableRunInDebug = false; + userConfig->enableRunInLowPower = false; +} + +void LpitDrv_Configure(LpitDrvType *obj, const LpitDrv_ConfigType *userConfig) +{ + /* Enables functional clock of LPIT module*/ + LpitReg_Enable(obj->reg); + /* Sets LPIT operation in Debug and LowPower mode*/ + LpitReg_SetDebugModeCmd(obj->reg, userConfig->enableRunInDebug ? 1 : 0); + LpitReg_SetLpModeCmd(obj->reg, userConfig->enableRunInLowPower ? 1 : 0); +} + +void LpitDrv_GetDefaultChannelConfig(LpitDrv_ChannelConfigType *userChannelConfig) +{ + userChannelConfig->timerMode = LPITDRV_PERIODIC_COUNTER; + userChannelConfig->period = 1000000U; + userChannelConfig->triggerSource = LPITDRV_TRIGGERSOURCE_EXTERNAL; + userChannelConfig->triggerSelect = 0U; + userChannelConfig->enableReloadOnTrigger = false; + userChannelConfig->enableStopOnInterrupt = false; + userChannelConfig->enableStartOnTrigger = false; + userChannelConfig->chainChannel = false; + userChannelConfig->isInterruptEnabled = true; +} + +bool LpitDrv_ConfigureChannel(LpitDrvType *obj, uint8_t channel, const LpitDrv_ChannelConfigType *userChannelConfig) +{ + /* Checks channel range */ + if(channel >= LPIT_TMR_COUNT) + { + return false; + } + + /* Setups the timer channel chaining */ + LpitReg_SetTimerChannelChainCmd(obj->reg, channel, (uint8_t)userChannelConfig->chainChannel); + /* Setups the timer channel operation mode */ + LpitReg_SetTimerChannelModeCmd(obj->reg, channel, (uint8_t)userChannelConfig->timerMode); + + /* Setups timer channel period in count unit */ + LpitReg_SetTimerPeriodByCount(obj->reg, channel, userChannelConfig->period); + + /* Setups the timer channel trigger source, trigger select, reload on trigger, + stop on timeout, start on trigger and channel chaining */ + LpitReg_SetTriggerSourceCmd(obj->reg, channel, userChannelConfig->triggerSource); + LpitReg_SetTriggerSelectCmd(obj->reg, channel, userChannelConfig->triggerSelect); + LpitReg_SetReloadOnTriggerCmd(obj->reg, channel, userChannelConfig->enableReloadOnTrigger ? 1 : 0); + LpitReg_SetStopOnInterruptCmd(obj->reg, channel, userChannelConfig->enableStopOnInterrupt ? 1 : 0); + LpitReg_SetStartOnTriggerCmd(obj->reg, channel, userChannelConfig->enableStartOnTrigger ? 1 : 0); + /* Setups interrupt generation for timer channel */ + if(userChannelConfig->isInterruptEnabled) + { + /* Enables interrupt generation */ + LpitReg_EnableInterruptTimerChannels(obj->reg, (uint32_t)1U << channel); + } + else + { + /* Disables interrupt generation */ + LpitReg_DisableInterruptTimerChannels(obj->reg, (uint32_t)1U << channel); + } + + return true; +} + +void LpitDrv_StartTimerChannels(LpitDrvType *obj, uint32_t mask) +{ + /* Checks the mask range */ + if(mask >= (1UL << LPIT_TMR_COUNT)) + { + return; + } + /* Start timer channels */ + LpitReg_StartTimerChannels(obj->reg, mask); +} + +void LpitDrv_StopTimerChannels(LpitDrvType *obj, uint32_t mask) +{ + /* Checks the mask range */ + if(mask >= (1UL << LPIT_TMR_COUNT)) + { + return; + } + /* Stop timer channels */ + LpitReg_StopTimerChannels(obj->reg, mask); +} + +void LpitDrv_SetTimerPeriodByCount(LpitDrvType *obj, uint8_t channel, uint32_t count) +{ + /* Checks the channel range */ + if(channel >= LPIT_TMR_COUNT) + { + return; + } + + LpitReg_SetTimerPeriodByCount(obj->reg, channel, count); +} + +void LpitDrv_SetTimerPeriodInDual16ModeByCount(LpitDrvType *obj, uint8_t channel, uint16_t periodHigh, uint16_t periodLow) +{ + /* Checks the channel range */ + if(channel >= LPIT_TMR_COUNT) + { + return; + } + + uint32_t period = ((uint32_t)periodHigh << 16U) | periodLow; + /* Sets the timer channel period in count unit */ + LpitReg_SetTimerPeriodByCount(obj->reg, channel, period); +} + +bool LpitDrv_GetTimerPeriodByCount(const LpitDrvType *obj, uint8_t channel, uint32_t *period) +{ + /* Checks the channel range */ + if(channel >= LPIT_TMR_COUNT) + { + return false; + } + + /* Gets current timer channel period by count.*/ + uint32_t currentPeriod = LpitReg_GetTimerPeriodByCount(obj->reg, channel); + /* Gets current timer channel operation mode */ + if(LpitReg_GetTimerChannelModeCmd(obj->reg, channel) == LPITDRV_DUAL_PERIODIC_COUNTER) + { + /* Calculates the period for dual 16 bit periodic counter mode */ + currentPeriod = (currentPeriod >> 16U) + (currentPeriod & MAX_PERIOD_COUNT_16_BIT); + } + + *period = currentPeriod; + return true; +} + +bool LpitDrv_GetCurrentTimerCount(const LpitDrvType *obj, uint8_t channel, uint32_t *time) +{ + /* Checks the channel range */ + if(channel >= LPIT_TMR_COUNT) + { + return false; + } + + /* Gets current timer channel counting value */ + uint32_t currentTime = LpitReg_GetCurrentTimerCount(obj->reg, channel); + /* Gets current timer channel operation mode */ + if(LpitReg_GetTimerChannelModeCmd(obj->reg, channel) == LPITDRV_DUAL_PERIODIC_COUNTER) + { + /* Calculates the current counting value for dual 16 bit periodic counter mode */ + currentTime = (currentTime >> 16U) + (currentTime & MAX_PERIOD_COUNT_16_BIT); + } + *time = currentTime; + return true; +} + +void LpitDrv_EnableTimerChannelInterrupt(LpitDrvType *obj, uint32_t mask) +{ + /* Checks the mask range */ + if(mask >= (1UL << LPIT_TMR_COUNT)) + { + return; + } + /* Enable interrupt of timer channels */ + LpitReg_EnableInterruptTimerChannels(obj->reg, mask); +} + +void LpitDrv_DisableTimerChannelInterrupt(LpitDrvType *obj, uint32_t mask) +{ + /* Checks the mask range */ + if(mask >= (1UL << LPIT_TMR_COUNT)) + { + return; + } + /* Enable interrupt of timer channels */ + LpitReg_DisableInterruptTimerChannels(obj->reg, mask); +} + +uint32_t LpitDrv_GetInterruptFlagTimerChannels(const LpitDrvType *obj, uint32_t mask) +{ + /* Checks the mask range */ + if(mask >= (1UL << LPIT_TMR_COUNT)) + { + return 0; + } + /* Gets the interrupt flag for timer channels */ + return LpitReg_GetInterruptFlag(obj->reg, mask); +} + +void LpitDrv_ClearInterruptFlagTimerChannels(LpitDrvType *obj, uint32_t mask) +{ + /* Checks the mask range */ + if(mask >= (1UL << LPIT_TMR_COUNT)) + { + return; + } + /* Clears the interrupt flag for timer channels */ + LpitReg_ClearInterruptFlag(obj->reg, mask); +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/lpit/lpit_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/lpit/lpit_drv.h new file mode 100644 index 0000000..14eb324 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/lpit/lpit_drv.h @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _LPIT_DRV_H_ +#define _LPIT_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of LPIT (Low Power Interrupt Timer) + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Definition of mode options available for the LPIT timer + */ +typedef enum +{ + LPITDRV_PERIODIC_COUNTER = 0x00U, /*!< 32-bit Periodic Counter */ + LPITDRV_DUAL_PERIODIC_COUNTER = 0x01U, /*!< Dual 16-bit Periodic Counter */ + LPITDRV_TRIGGER_ACCUMULATOR = 0x02U, /*!< 32-bit Trigger Accumulator */ + LPITDRV_INPUT_CAPTURE = 0x03U /*!< 32-bit Trigger Input Capture */ +} LpitDrv_TimerModesType; + +/*! \brief Definition of trigger source options. + */ +typedef enum +{ + LPITDRV_TRIGGERSOURCE_EXTERNAL = 0x00U, /*!< Use external trigger */ + LPITDRV_TRIGGERSOURCE_INTERNAL = 0x01U /*!< Use internal trigger */ +} LpitDrv_TriggerSourceType; + +/*! \brief Definition of configuration of LPIT timer channel + */ +typedef struct _LpitDrv_ChannelConfigType_ +{ + LpitDrv_TimerModesType timerMode; /*!< Operation mode of timer channel */ + uint32_t period; /*!< Period of timer channel */ + LpitDrv_TriggerSourceType triggerSource; /*!< Selects between internal and external trigger sources */ + uint32_t triggerSelect; /*!< Selects one trigger from the internal trigger sources + this field makes sense if trigger source is internal */ + bool enableReloadOnTrigger; /*!< True: Timer channel will reload on selected trigger + False: Timer channel will not reload on selected trigger */ + bool enableStopOnInterrupt; /*!< True: Timer will stop after timeout + False: Timer channel does not stop after timeout */ + bool enableStartOnTrigger; /*!< True: Timer channel starts to decrement when rising edge + on selected trigger is detected. + False: Timer starts to decrement immediately based on + restart condition */ + bool chainChannel; /*!< Channel chaining enable */ + bool isInterruptEnabled; /*!< Timer channel interrupt generation enable */ +} LpitDrv_ChannelConfigType; + +/*! \brief Definition of configuration of LPIT driver + */ +typedef struct _LpitDrv_ConfigType_ +{ + bool enableRunInDebug; /*!< True: Timer channels continue to run in debug mode + False: Timer channels stop in debug mode */ + bool enableRunInLowPower; /*!< True: Timer channels continue to run in low power mode + False: Timer channels stop in low power mode */ +} LpitDrv_ConfigType; + +/* Forward declaration of LPIT register */ +struct _LpitRegType_; + +/*! \brief The definition of LPIT driver class + */ +typedef struct _LpitDrvType_ +{ + struct _LpitRegType_ *reg; +} LpitDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the LPIT driver module + * + * This function initializes LPIT driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] reg : pointer to LPIT register instance + */ +extern void LpitDrv_Init(LpitDrvType *obj, struct _LpitRegType_ *reg); + +/*! \brief Get default configures the LPIT module for configuration structure + * + * This function gets default configures the LPIT module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void LpitDrv_GetDefaultConfig(LpitDrv_ConfigType *userConfig); + +/*! \brief Configures the LPIT module from a user configuration structure + * + * This function resets LPIT module, enables the LPIT module, configures LPIT + * module operation in Debug and LowPower mode. The LPIT configuration structure shall + * be passed as arguments. + * This configuration structure affects all timer channels. + * This function should be called before calling any other LPIT driver function. + * + * This is an example demonstrating how to define a LPIT configuration structure: + \code + LpitDrv_ConfigType lpitConfig = + { + .enableRunInDebug = false, + .enableRunInLowPower = true + }; + \endcode + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void LpitDrv_Configure(LpitDrvType *obj, const LpitDrv_ConfigType *userConfig); + +/*! \brief Gets the default timer channel configuration + * + * This function gets the default timer channel configuration structure, with the following settings: + * - Timer mode: 32-bit Periodic Counter + * - Period: 1000000 + * - Trigger sources: External trigger + * - Trigger select: Trigger from channel 0 + * - Reload on trigger: Disable + * - Stop on interrupt : Disable + * - Start on trigger: Disable + * - Channel chaining: Disable + * - Interrupt generating: Enable + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userChannelConfig : pointer to channel configuration structure + */ +extern void LpitDrv_GetDefaultChannelConfig(LpitDrv_ChannelConfigType *userChannelConfig); + +/*! \brief Initializes the LPIT channel. + * + * This function initializes the LPIT timers by using a channel, this function + * configures timer channel chaining, timer channel mode, timer channel period, + * interrupt generation, trigger source, trigger select, reload on trigger, + * stop on interrupt and start on trigger. + * The timer channel number and its configuration structure shall be passed as arguments. + * Timer channels do not start counting by default after calling this function. + * + * The function 'StartTimerChannels' must be called to start the timer channel counting. + * In order to re-configures the period, call the 'SetTimerPeriodByCount'. + * + * This is an example demonstrating how to define a LPIT channel configuration structure: + \code + LpitDrv_ChannelConfigType lpitInitConfig = + { + .timerMode = LPITDRV_PERIODIC_COUNTER, + .period = 1000000U, + .triggerSource = LPITDRV_TRIGGERSOURCE_INTERNAL, + .triggerSelect = 1U, + .enableReloadOnTrigger = false, + .enableStopOnInterrupt = false, + .enableStartOnTrigger = false, + .chainChannel = false, + .isInterruptEnabled = true + }; + \endcode + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] channel : timer channel number + * \param[in] userChannelConfig : pointer to configuration structure + * \return The result of configuring channel + * - false : failed + * - true : success + */ +extern bool LpitDrv_ConfigureChannel(LpitDrvType *obj, uint8_t channel, const LpitDrv_ChannelConfigType *userChannelConfig); + +/*! \brief Starts the timer channel counting. + * + * This function allows starting timer channels simultaneously . + * After calling this function, timer channels are going operate depend on mode and + * control bits which controls timer channel start, reload and restart. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] mask : timer channels starting mask that decides which channels will be started + * For example: + * - with mask = 0x01U then channel 0 will be started + * - with mask = 0x02U then channel 1 will be started + * - with mask = 0x03U then channel 0 and channel 1 will be started + */ +extern void LpitDrv_StartTimerChannels(LpitDrvType *obj, uint32_t mask); + +/*! \brief Stops the timer channel counting. + * + * This function allows stop timer channels simultaneously from counting. + * Timer channels reload their periods respectively after the next time + * they call the LPIT_DRV_StartTimerChannels. Note that: In 32-bit Trigger Accumulator + * mode, the counter will load on the first trigger rising edge. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] mask : timer channels stopping mask that decides which channels will be stopped + * For example: + * - with mask = 0x01U then channel 0 will be stopped + * - with mask = 0x02U then channel 1 will be stopped + * - with mask = 0x03U then channel 0 and channel 1 will be stopped + */ +extern void LpitDrv_StopTimerChannels(LpitDrvType *obj, uint32_t mask); + +/*! \brief Sets the timer channel period in count unit. + * + * This function sets the timer channel period in count unit. + * The counter period of a running timer channel can be modified by first setting + * a new load value, the value will be loaded after the timer channel expires. + * To abort the current cycle and start a timer channel period with the new value, + * the timer channel must be disabled and enabled again. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] channel : timer channel number + * \param[in] count : timer channel period in count unit + */ +extern void LpitDrv_SetTimerPeriodByCount(LpitDrvType *obj, uint8_t channel, uint32_t count); + +/*! \brief Sets the timer channel period in count unit. + * + * This function sets the timer channel period in count unit when timer channel + * mode is dual 16 periodic counter mode. + * The counter period of a running timer channel can be modified by first setting + * a new load value, the value will be loaded after the timer channel expires. + * To abort the current cycle and start a timer channel period with the new value, + * the timer channel must be disabled and enabled again. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] channel : timer channel number + * \param[in] periodHigh : period of higher 16 bit in count unit + * \param[in] periodLow : period of lower 16 bit in count unit + */ +extern void LpitDrv_SetTimerPeriodInDual16ModeByCount(LpitDrvType *obj, uint8_t channel, uint16_t periodHigh, uint16_t periodLow); + +/*! \brief Gets the current timer channel period in count unit. + * + * This function returns current period of timer channel given as argument. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] channel : timer channel number + * \param[out] period : pointer to the timer channel period in count unit + * \return the result of getting period + * - false : failed + * - true : success + */ +extern bool LpitDrv_GetTimerPeriodByCount(const LpitDrvType *obj, uint8_t channel, uint32_t *period); + +/*! \brief Gets the current timer channel counting value in count. + * + * This function returns the real-time timer channel counting value, the value in + * a range from 0 to timer channel period. + * Need to make sure the running time does not exceed the timer channel period. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] channel : timer channel number + * \param[out] time : current timer channel counting value in count + * \return the result of getting counting value + * - false : failed + * - true : success + */ +extern bool LpitDrv_GetCurrentTimerCount(const LpitDrvType *obj, uint8_t channel, uint32_t *time); + +/*! \brief Enables the interrupt generation of timer channel. + * + * This function allows enabling interrupt generation of timer channel + * when timeout occurs or input trigger occurs. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] mask : the mask that decides which channels will be enabled interrupt. + * For example: + * - with mask = 0x01u then the interrupt of channel 0 will be enabled + * - with mask = 0x02u then the interrupt of channel 1 will be enabled + * - with mask = 0x03u then the interrupt of channel 0 and channel 1 will be enabled + */ +extern void LpitDrv_EnableTimerChannelInterrupt(LpitDrvType *obj, uint32_t mask); + +/*! \brief Disables the interrupt generation of timer channel. + * + * This function allows disabling interrupt generation of timer channel + * when timeout occurs or input trigger occurs. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] mask : the mask that decides which channels will be disable interrupt. + * For example: + * - with mask = 0x01u then the interrupt of channel 0 will be disable + * - with mask = 0x02u then the interrupt of channel 1 will be disable + * - with mask = 0x03u then the interrupt of channel 0 and channel 1 will be disable + */ +extern void LpitDrv_DisableTimerChannelInterrupt(LpitDrvType *obj, uint32_t mask); + +/*! \brief Gets the current interrupt flag of timer channels. + * + * This function gets the current interrupt flag of timer channels. + * In compare modes, the flag sets to 1 at the end of the timer period. + * In capture modes, the flag sets to 1 when the trigger asserts. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] mask : the interrupt flag getting mask that decides which channels will be got interrupt flag. + * For example: + * - with mask = 0x01u then the interrupt flag of channel 0 only will be got + * - with mask = 0x02u then the interrupt flag of channel 1 only will be got + * - with mask = 0x03u then the interrupt flags of channel 0 and channel 1 will be got + * \return current interrupt flag of timer channels + * \note return 0 if mask is invalid + */ +extern uint32_t LpitDrv_GetInterruptFlagTimerChannels(const LpitDrvType *obj, uint32_t mask); + +/*! \brief Clears the interrupt flag of timer channels. + * + * This function clears the interrupt flag of timer channels after + * their interrupt event occurred. + * + * \param[in] obj : pointer to LPIT driver instance + * \param[in] mask : the interrupt flag clearing mask that decides which channels will be cleared interrupt flag + * For example: + * - with mask = 0x01u then the interrupt flag of channel 0 only will be cleared + * - with mask = 0x02u then the interrupt flag of channel 1 only will be cleared + * - with mask = 0x03u then the interrupt flags of channel 0 and channel 1 will be cleared + */ +extern void LpitDrv_ClearInterruptFlagTimerChannels(LpitDrvType *obj, uint32_t mask); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _LPIT_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/lptmr/lptmr_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/lptmr/lptmr_drv.c new file mode 100644 index 0000000..f9a1d46 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/lptmr/lptmr_drv.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "lptmr_drv.h" +#include "lptmr_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void LptmrDrv_Init(LptmrDrvType *obj, struct _LptmrRegType_ *reg) +{ + obj->reg = reg; +} + +void LptmrDrv_GetConfigure(LptmrDrvType *obj, LptmrDrv_ConfigType *userConfig) +{ + /* Get the work mode of LPTMR */ + userConfig->workMode = (LptmrDrv_WorkModeType)LptmrReg_GetWorkMode(obj->reg); + /* Get the Free Running state */ + userConfig->freeRun = LptmrReg_GetFreeRunning(obj->reg); + /* Get Pin Polarity for Pulse Counter Mode */ + userConfig->pinPolarity = (LptmrDrv_PinPolarityType)LptmrReg_GetPinPolarity(obj->reg); + /* Get the Pin selection for Pulse Counter Mode */ + userConfig->pinSelect = (LptmrDrv_PinSelectType)LptmrReg_GetPinSelect(obj->reg); + /* Get the Interrupt Enable state */ + userConfig->interruptEnable = LptmrReg_GetInterruptEnable(obj->reg); + /* Get the DMA Request Enable Flag state */ + userConfig->dmaRequest = LptmrReg_GetDmaRequest(obj->reg); + /* Get the Prescaler/Glitch Filter Bypass enable state */ + userConfig->bypassPrescaler = LptmrReg_GetBypass(obj->reg); + /* Get the Prescaler/Glitch Filter divider value */ + userConfig->prescaler = (LptmrDrv_PrescaleType)LptmrReg_GetPrescaler(obj->reg); + /* Get the Prescaler/Glitch Filter Bypass enable state */ + userConfig->compareValue = LptmrReg_GetCompareValue(obj->reg); +} + +void LptmrDrv_GetDefaultConfig(LptmrDrv_ConfigType *userConfig) +{ + /* General parameters */ + userConfig->dmaRequest = false; + userConfig->interruptEnable = false; + userConfig->freeRun = false; + userConfig->workMode = LPTMRDRV_WORKMODE_TIMER; + + /* Counter parameters */ + userConfig->prescaler = LPTMRDRV_PRESCALE_2; + userConfig->bypassPrescaler = false; + userConfig->compareValue = 0u; + + /* Pulse Counter specific parameters */ + userConfig->pinSelect = LPTMRDRV_PINSELECT_INPUT0; + userConfig->pinPolarity = LPTMRDRV_PINPOLARITY_RISING; +} + +void LptmrDrv_Configure(LptmrDrvType *obj, const LptmrDrv_ConfigType *userConfig) +{ + /* Disable LPTMR before configure */ + LptmrReg_SetEnable(obj->reg, false); + /* Set the work mode of LPTMR */ + LptmrReg_SetWorkMode(obj->reg, (uint8_t)userConfig->workMode); + /* Set the Free Running state */ + LptmrReg_SetFreeRunning(obj->reg, userConfig->freeRun); + /* Set Pin Polarity for Pulse Counter Mode */ + LptmrReg_SetPinPolarity(obj->reg, (uint8_t)userConfig->pinPolarity); + /* Set the Pin selection for Pulse Counter Mode */ + LptmrReg_SetPinSelect(obj->reg, (uint8_t)userConfig->pinSelect); + /* Set the Interrupt Enable state */ + LptmrReg_SetInterrupt(obj->reg, userConfig->interruptEnable); + /* Set the DMA Request Enable Flag state */ + LptmrReg_SetDmaRequest(obj->reg, userConfig->dmaRequest); + /* Set the Prescaler/Glitch Filter Bypass enable state */ + LptmrReg_SetBypass(obj->reg, userConfig->bypassPrescaler); + /* Set the Prescaler/Glitch Filter divider value */ + LptmrReg_SetPrescaler(obj->reg, (uint8_t)userConfig->prescaler); + /* Set the Prescaler/Glitch Filter Bypass enable state */ + LptmrReg_SetCompareValue(obj->reg, userConfig->compareValue); +} + +bool LptmrDrv_IsEnable(LptmrDrvType *obj) +{ + /* Get the Enable state */ + return (bool)(LptmrReg_GetEnable(obj->reg)); +} + +void LptmrDrv_Enable(LptmrDrvType *obj, bool enable) +{ + /* Set the Enable state */ + LptmrReg_SetEnable(obj->reg, enable); +} + +bool LptmrDrv_IsCompareEventAcvt(LptmrDrvType *obj) +{ + /* Get the Compare Flag state */ + return (bool)(LptmrReg_GetCompareFlag(obj->reg)); +} + +void LptmrDrv_ClearCompareFlag(LptmrDrvType *obj) +{ + /* Clear the Compare Flag */ + LptmrReg_ClearCompareFlag(obj->reg); +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/lptmr/lptmr_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/lptmr/lptmr_drv.h new file mode 100644 index 0000000..d9680db --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/lptmr/lptmr_drv.h @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _LPTMR_DRV_H_ +#define _LPTMR_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of LPTMR (Low Power Timer) module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup lptmr_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Pulse Counter Input selection + */ +typedef enum +{ + LPTMRDRV_PINSELECT_INPUT0 = 0x00u, /*!< Pulse counter input 0 is selected */ + LPTMRDRV_PINSELECT_INPUT1 = 0x01u, /*!< Pulse counter input 1 is selected */ + LPTMRDRV_PINSELECT_INPUT2 = 0x02u, /*!< Pulse counter input 2 is selected */ +} LptmrDrv_PinSelectType; + +/*! \brief Pulse Counter input polarity + */ +typedef enum +{ + LPTMRDRV_PINPOLARITY_RISING = 0x00u, /*!< Count pulse on rising edge */ + LPTMRDRV_PINPOLARITY_FALLING = 0x01u, /*!< Count pulse on falling edge */ +} LptmrDrv_PinPolarityType; + +/*! \brief Work Mode + */ +typedef enum +{ + LPTMRDRV_WORKMODE_TIMER = 0u, /*!< Timer */ + LPTMRDRV_WORKMODE_PULSECOUNTER = 1u, /*!< Pulse counter */ +} LptmrDrv_WorkModeType; + +/*! \brief Prescaler Selection + */ +typedef enum +{ + LPTMRDRV_PRESCALE_2 = 0x00u, /*!< Timer mode: prescaler 2, Glitch filter mode: invalid */ + LPTMRDRV_PRESCALE_4_GLITCHFILTER_2 = 0x01u, /*!< Timer mode: prescaler 4, Glitch filter mode: 2 clocks */ + LPTMRDRV_PRESCALE_8_GLITCHFILTER_4 = 0x02u, /*!< Timer mode: prescaler 8, Glitch filter mode: 4 clocks */ + LPTMRDRV_PRESCALE_16_GLITCHFILTER_8 = 0x03u, /*!< Timer mode: prescaler 16, Glitch filter mode: 8 clocks */ + LPTMRDRV_PRESCALE_32_GLITCHFILTER_16 = 0x04u, /*!< Timer mode: prescaler 32, Glitch filter mode: 16 clocks */ + LPTMRDRV_PRESCALE_64_GLITCHFILTER_32 = 0x05u, /*!< Timer mode: prescaler 64, Glitch filter mode: 32 clocks */ + LPTMRDRV_PRESCALE_128_GLITCHFILTER_64 = 0x06u, /*!< Timer mode: prescaler 128, Glitch filter mode: 64 clocks */ + LPTMRDRV_PRESCALE_256_GLITCHFILTER_128 = 0x07u, /*!< Timer mode: prescaler 256, Glitch filter mode: 128 clocks */ + LPTMRDRV_PRESCALE_512_GLITCHFILTER_256 = 0x08u, /*!< Timer mode: prescaler 512, Glitch filter mode: 256 clocks */ + LPTMRDRV_PRESCALE_1024_GLITCHFILTER_512 = 0x09u, /*!< Timer mode: prescaler 1024, Glitch filter mode: 512 clocks */ + LPTMRDRV_PRESCALE_2048_GLITCHFILTER_1024 = 0x0Au, /*!< Timer mode: prescaler 2048, Glitch filter mode: 1024 clocks */ + LPTMRDRV_PRESCALE_4096_GLITCHFILTER_2048 = 0x0Bu, /*!< Timer mode: prescaler 4096, Glitch filter mode: 2048 clocks */ + LPTMRDRV_PRESCALE_8192_GLITCHFILTER_4096 = 0x0Cu, /*!< Timer mode: prescaler 8192, Glitch filter mode: 4096 clocks */ + LPTMRDRV_PRESCALE_16384_GLITCHFILTER_8192 = 0x0Du, /*!< Timer mode: prescaler 16384, Glitch filter mode: 8192 clocks */ + LPTMRDRV_PRESCALE_32768_GLITCHFILTER_16384 = 0x0Eu, /*!< Timer mode: prescaler 32768, Glitch filter mode: 16384 clocks */ + LPTMRDRV_PRESCALE_65536_GLITCHFILTER_32768 = 0x0Fu, /*!< Timer mode: prescaler 65536, Glitch filter mode: 32768 clocks */ +} LptmrDrv_PrescaleType; + +/*! \brief Definition of configuration of LPTMR driver + */ +typedef struct _LptmrDrv_ConfigType_ +{ + /* General parameters */ + bool dmaRequest; /*!< Enable/Disable DMA requests */ + bool interruptEnable; /*!< Enable/Disable Interrupt */ + bool freeRun; /*!< Enable/Disable Free Running Mode */ + LptmrDrv_WorkModeType workMode; /*!< Time/Pulse Counter Mode */ + + /* Counter parameters */ + LptmrDrv_PrescaleType prescaler; /*!< Prescaler Selection */ + bool bypassPrescaler; /*!< Enable/Disable prescaler bypass */ + uint16_t compareValue; /*!< Compare value */ + + /* Pulse Counter specific parameters */ + LptmrDrv_PinSelectType pinSelect; /*!< Pin selection for Pulse-Counter */ + LptmrDrv_PinPolarityType pinPolarity; /*!< Pin Polarity for Pulse-Counter */ +} LptmrDrv_ConfigType; + +/* Forward declaration of LPTMR register */ +struct _LptmrRegType_; + +/*! \brief The definition of LPTMR driver class + */ +typedef struct _LptmrDrvType_ +{ + struct _LptmrRegType_ *reg; +} LptmrDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the LPTMR driver module + * + * This function initializes LPTMR driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to LPTMR driver instance + * \param[in] reg : pointer to LPTMR register instance + */ +extern void LptmrDrv_Init(LptmrDrvType *obj, struct _LptmrRegType_ *reg); + +/*! \brief Get currunt configures of the LPTMR module for configuration structure + * + * This function gets currunt configures of the LPTMR module for user configuration structure + * + * \param[in] obj : pointer to LPTMR driver instance + * \param[out] userConfig : pointer to configuration structure + */ +extern void LptmrDrv_GetConfigure(LptmrDrvType *obj, LptmrDrv_ConfigType *userConfig); + +/*! \brief Get default configures the LPTMR module for configuration structure + * + * This function gets default configures the LPTMR module for user configuration structure + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void LptmrDrv_GetDefaultConfig(LptmrDrv_ConfigType *userConfig); + +/*! \brief Configures the LPTMR module from a user configuration structure + * + * This function Configures the LPTMR module from a user configuration structure + * + * \param[in] obj : pointer to LPTMR driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void LptmrDrv_Configure(LptmrDrvType *obj, const LptmrDrv_ConfigType *userConfig); + +/*! \brief Get the state of LPTMR enable + * + * This function gets the state of LPTMR enable + * + * \param[in] obj : pointer to LPTMR driver instance + * \return state of LPTMR enable + */ +extern bool LptmrDrv_IsEnable(LptmrDrvType *obj); + +/*! \brief Set the state of LPTMR enable + * + * This function sets the state of LPTMR enable + * + * \param[in] obj : pointer to lptmr LPTMR instance + * \param[in] state of LPTMR enable + */ +extern void LptmrDrv_Enable(LptmrDrvType *obj, bool enable); + +/*! \brief Get the flag of LPTMR compare flag + * + * This function gets the flag of LPTMR compare flag + * + * \param[in] obj : pointer to LPTMR driver instance + * \return the flag of LPTMR compare flag + */ +extern bool LptmrDrv_IsCompareEventAcvt(LptmrDrvType *obj); + +/*! \brief Clear the flag of LPTMR compare flag + * + * This function clears the flag of LPTMR compare flag + * + * \param[in] obj : pointer to LPTMR driver instance + */ +extern void LptmrDrv_ClearCompareFlag(LptmrDrvType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _LPTMR_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_ch.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_ch.c new file mode 100644 index 0000000..b04ec50 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_ch.c @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "mft_cap_ch.h" +#include "mft_cap_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void MftCapCh_Init(MftCapChType *obj, struct _MftCapDrvType_ *capDrv) +{ + obj->capDrv = capDrv; +} + +void MftCapCh_GetDefaultConfig(MftCapCh_ConfigType *userConfig) +{ + userConfig->hwChannelId = 0; /* Channel Id */ + userConfig->inputMode = MFTCAPCH_EDGE_DETECT; /* Input capture operation Mode */ + userConfig->edgeAlignement = MFTCAPCH_RISING_EDGE; /* Edge alignment Mode */ + userConfig->measurementType = MFTCAPCH_NO_MEASUREMENT; /* Signal measurement operation type */ + userConfig->filterValue = 0; /* Filter value */ + userConfig->filterEn = false; /* Filter disabled */ + userConfig->continuousModeEn = true; /* Continuous mode measurement */ + userConfig->callbacksParams = NULL; /* Callback parameters for channel events */ + userConfig->callbackFunc = NULL; /* Callback function for channels events */ +} + +void MftCapCh_Config(MftCapChType *obj, const MftCapCh_ConfigType *userConfig) +{ + /* Check Channel Id */ + if(userConfig->hwChannelId >= MFT_CHANNEL_NUM) + { + return; + } + + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->capDrv->base->reg, 1); + + /* Filter Mode, only availabe for channel 0, 1, 2, 3 */ + uint16_t filterValue = userConfig->filterEn ? userConfig->filterValue : 0; + switch(userConfig->hwChannelId) + { + case 0: + MftReg_SetFilterCh0FVal(obj->capDrv->base->reg, filterValue); + break; + case 1: + MftReg_SetFilterCh1FVal(obj->capDrv->base->reg, filterValue); + break; + case 2: + MftReg_SetFilterCh2FVal(obj->capDrv->base->reg, filterValue); + break; + case 3: + MftReg_SetFilterCh3FVal(obj->capDrv->base->reg, filterValue); + break; + default: + /* Nothing to do, not available for other channels */ + break; + } + + /* Input capture operation Mode, Edge alignment Mode, Signal measurement operation type */ + if(MFTCAPCH_EDGE_DETECT == userConfig->inputMode) + { + /* DECAPEN = 0 */ + MftDrv_SetDualEdgeCaptureCmd(obj->capDrv->base, userConfig->hwChannelId >> 1, false); + /* MSB:MSA = 0:0 */ + MftReg_SetCscMsb(obj->capDrv->base->reg, userConfig->hwChannelId, 0); + MftReg_SetCscMsa(obj->capDrv->base->reg, userConfig->hwChannelId, 0); + /* ELSnB:ELSnA = 0:0 */ + MftReg_SetCscElsb(obj->capDrv->base->reg, userConfig->hwChannelId, (userConfig->edgeAlignement >> 1) & 0x01U); + MftReg_SetCscElsa(obj->capDrv->base->reg, userConfig->hwChannelId, userConfig->edgeAlignement & 0x01U); + /* Enable interrupt request for the current channel */ + MftReg_SetCscChie(obj->capDrv->base->reg, userConfig->hwChannelId, 1); + } + else if(MFTCAPCH_SIGNAL_MEASUREMENT == userConfig->inputMode) + { + /* DECAPEN = 1 */ + MftDrv_SetDualEdgeCaptureCmd(obj->capDrv->base, userConfig->hwChannelId >> 1, true); + /* DECAP = 1 */ + MftDrv_SetDualChannelDecap(obj->capDrv->base, userConfig->hwChannelId >> 1, true); + /* If continuous mode is set */ + if(true == userConfig->continuousModeEn) + { + /* MSB:MSA = 1:1 */ + MftReg_SetCscMsb(obj->capDrv->base->reg, userConfig->hwChannelId, 1); + MftReg_SetCscMsa(obj->capDrv->base->reg, userConfig->hwChannelId, 1); + } + else + { + /* MSB:MSA = 1:0 */ + MftReg_SetCscMsb(obj->capDrv->base->reg, userConfig->hwChannelId, 1); + MftReg_SetCscMsa(obj->capDrv->base->reg, userConfig->hwChannelId, 0); + } + /* Check If want to measure a pulse width or period of the signal */ + if((MFTCAPCH_PERIOD_ON_MEASUREMENT == userConfig->measurementType) + || (MFTCAPCH_RISING_EDGE_PERIOD_MEASUREMENT == userConfig->measurementType)) + { + /* ELSnB:ELSnA = 0:1 (rising edge) */ + MftReg_SetCscElsb(obj->capDrv->base->reg, userConfig->hwChannelId, 0); + MftReg_SetCscElsa(obj->capDrv->base->reg, userConfig->hwChannelId, 1); + if(MFTCAPCH_PERIOD_ON_MEASUREMENT == userConfig->measurementType) + { + /* Measure time between rising and falling edge - positive duty */ + /* ELSnB:ELSnA = 1:0 (falling edge) for channel (n+1)*/ + MftReg_SetCscElsb(obj->capDrv->base->reg, userConfig->hwChannelId + 1, 1); + MftReg_SetCscElsa(obj->capDrv->base->reg, userConfig->hwChannelId + 1, 0); + } + else + { + /* If channel (n) is configured to capture falling edges (ELS(n)B:ELS(n)A = 0:1) + * then channel (n+1) also captures falling edges (ELS(n+1)B:ELS(n+1)A = 0:1) */ + MftReg_SetCscElsb(obj->capDrv->base->reg, userConfig->hwChannelId + 1, 0); + MftReg_SetCscElsa(obj->capDrv->base->reg, userConfig->hwChannelId + 1, 1); + } + } + else if((MFTCAPCH_PERIOD_OFF_MEASUREMENT == userConfig->measurementType) + || (MFTCAPCH_FALLING_EDGE_PERIOD_MEASUREMENT == userConfig->measurementType)) + { + /* ELSnB:ELSnA = 1:0 (falling edge) */ + MftReg_SetCscElsb(obj->capDrv->base->reg, userConfig->hwChannelId, 1); + MftReg_SetCscElsa(obj->capDrv->base->reg, userConfig->hwChannelId, 0); + if(MFTCAPCH_PERIOD_OFF_MEASUREMENT == userConfig->measurementType) + { + /* Measure time between falling and rising edge - negative duty */ + /* ELSnB:ELSnA = 0:1 (rising edge) for channel (n+1) */ + MftReg_SetCscElsb(obj->capDrv->base->reg, userConfig->hwChannelId + 1, 0); + MftReg_SetCscElsa(obj->capDrv->base->reg, userConfig->hwChannelId + 1, 1); + } + else + { + /* If channel (n) is configured to capture rising edges (ELS(n)B:ELS(n)A = 1:0) than + * channel (n+1) is setup to capture also raising edges (ELS(n+1)B:ELS(n+1)A = 1:0) */ + MftReg_SetCscElsb(obj->capDrv->base->reg, userConfig->hwChannelId + 1, 1); + MftReg_SetCscElsa(obj->capDrv->base->reg, userConfig->hwChannelId + 1, 0); + } + } + + /* Enable the interrupt request for the channel which will indicate that the measurement is done. */ + MftReg_SetCscChie(obj->capDrv->base->reg, userConfig->hwChannelId + 1, 1); + } + + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->capDrv->base->reg, 1); + + /* Remember the configuration */ + obj->config = *userConfig; +} + +void MftCapCh_Disarm(MftCapChType *obj) +{ + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->capDrv->base->reg, 1); + + /* Filter Mode, only availabe for channel 0, 1, 2, 3 */ + switch(obj->config.hwChannelId) + { + case 0: + MftReg_SetFilterCh0FVal(obj->capDrv->base->reg, 0); + break; + case 1: + MftReg_SetFilterCh1FVal(obj->capDrv->base->reg, 0); + break; + case 2: + MftReg_SetFilterCh2FVal(obj->capDrv->base->reg, 0); + break; + case 3: + MftReg_SetFilterCh3FVal(obj->capDrv->base->reg, 0); + break; + default: + /* Nothing to do, not available for other channels */ + break; + } + + /* Clear combine mode */ + MftReg_SetCombineCombine0(obj->capDrv->base->reg, 0); + MftReg_SetCombineCombine1(obj->capDrv->base->reg, 0); + MftReg_SetCombineCombine2(obj->capDrv->base->reg, 0); + MftReg_SetCombineCombine3(obj->capDrv->base->reg, 0); + MftDrv_SetDualEdgeCaptureCmd(obj->capDrv->base, obj->config.hwChannelId >> 1, false); + /* ELSnB:ELSnA = 0:0 (no edge) */ + MftReg_SetCscElsb(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + MftReg_SetCscElsa(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + /* Disable interrupt */ + MftReg_SetCscChie(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + /* Clear channel event flag */ + MftReg_SetCscChf(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + /* Disarm for channel (n+1) */ + /* ELSnB:ELSnA = 0:0 (no edge) */ + MftReg_SetCscElsb(obj->capDrv->base->reg, (obj->config.hwChannelId | 1U), 0); + MftReg_SetCscElsa(obj->capDrv->base->reg, (obj->config.hwChannelId | 1U), 0); + /* Disable interrupt */ + MftReg_SetCscChie(obj->capDrv->base->reg, (obj->config.hwChannelId | 1U), 0); + /* Clear channel event flag */ + MftReg_SetCscChf(obj->capDrv->base->reg, (obj->config.hwChannelId | 1U), 0); + + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->capDrv->base->reg, 1); +} + +bool MftCapCh_StartNewSignalMeasurement(MftCapChType *obj) +{ + bool retval = false; + /* Check if the channel is in single-shot mode */ + if(MftReg_GetCscMsa(obj->capDrv->base->reg, obj->config.hwChannelId) == 0 + && MftReg_GetCscMsb(obj->capDrv->base->reg, obj->config.hwChannelId) == 1) + { + if(MftDrv_GetDualEdgeCaptureCmd(obj->capDrv->base, obj->config.hwChannelId >> 1)) + { + /* Clear event flags for channel n and n + 1 */ + MftReg_SetCscChf(obj->capDrv->base->reg, obj->config.hwChannelId + 1, 0); + MftReg_SetCscChf(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + /* Set DECAP bit to start measurement */ + MftDrv_SetDualChannelDecap(obj->capDrv->base, obj->config.hwChannelId >> 1, true); + retval = true; + } + } + + return retval; +} + +void MftCapCh_SetChannelMode(MftCapChType *obj, MftCapCh_OpModeType inputMode, bool enableContinuousCapture) +{ + uint8_t level = 1U; + uint8_t nextChnlevel = 1U; + uint8_t channelPair = (uint8_t)(obj->config.hwChannelId >> 1U); + + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->capDrv->base->reg, 1); + + if(MFTCAPCH_DISABLE_OPERATION == inputMode) + { + /* Set the edge level to disable operation on the channel input */ + /* ELSnB:ELSnA = 0:0 (no edge) */ + MftReg_SetCscElsb(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + MftReg_SetCscElsa(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + } + else if((MFTCAPCH_TIMESTAMP_RISING_EDGE == inputMode) || (MFTCAPCH_TIMESTAMP_FALLING_EDGE == inputMode) || (MFTCAPCH_TIMESTAMP_BOTH_EDGES == inputMode)) + { + /* Disable the dual edge mode */ + MftDrv_SetDualEdgeCaptureCmd(obj->capDrv->base, channelPair, false); + /* Set input capture mode, MSB:MSA = 0:0 */ + MftReg_SetCscMsb(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + MftReg_SetCscMsa(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + /* Set the event which will generate the interrupt */ + MftReg_SetCscElsb(obj->capDrv->base->reg, obj->config.hwChannelId, (inputMode >> 1) & 0x01U); + MftReg_SetCscElsa(obj->capDrv->base->reg, obj->config.hwChannelId, inputMode & 0x01U); + /* Enable interrupt request for the current channel */ + MftReg_SetCscChie(obj->capDrv->base->reg, obj->config.hwChannelId, 1); + } + else + { + /* Check the channel is even number */ + if((obj->config.hwChannelId % 2U) != 0U) + { + return; + } + /* Enable the dual edge mode */ + MftDrv_SetDualEdgeCaptureCmd(obj->capDrv->base, channelPair, true); + /* Enable dual edge input capture */ + MftDrv_SetDualChannelDecap(obj->capDrv->base, channelPair, true); + /* If continuous mode is set*/ + if(true == enableContinuousCapture) + { + /* MSB:MSA = 1:1 */ + MftReg_SetCscMsb(obj->capDrv->base->reg, obj->config.hwChannelId, 1); + MftReg_SetCscMsa(obj->capDrv->base->reg, obj->config.hwChannelId, 1); + } + else + { + /* MSB:MSA = 1:0 */ + MftReg_SetCscMsb(obj->capDrv->base->reg, obj->config.hwChannelId, 1); + MftReg_SetCscMsa(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + } + + /* Check If want to measure a pulse width or period of the signal */ + if((MFTCAPCH_MEASURE_PULSE_HIGH == inputMode) || (MFTCAPCH_MEASURE_RISING_EDGE_PERIOD == inputMode)) + { + if(MFTCAPCH_MEASURE_PULSE_HIGH == inputMode) + { + /* Measure time between rising and falling edge - positive duty */ + nextChnlevel = 2U; + } + } + else + { + level = 2U; + if(MFTCAPCH_MEASURE_FALLING_EDGE_PERIOD == inputMode) + { + /* If channel (n) is configured to capture rising edges (ELS(n)B:ELS(n)A = 1:0) than + * channel (n+1) is setup to capture also raising edges (ELS(n+1)B:ELS(n+1)A = 1:0) */ + nextChnlevel = 2U; + } + } + /* Edge selection for channel (n) */ + MftReg_SetCscElsb(obj->capDrv->base->reg, obj->config.hwChannelId, (level >> 1) & 0x01U); + MftReg_SetCscElsa(obj->capDrv->base->reg, obj->config.hwChannelId, level & 0x01U); + /* Edge selection for channel (n+1) */ + MftReg_SetCscElsb(obj->capDrv->base->reg, obj->config.hwChannelId + 1, (nextChnlevel >> 1) & 0x01U); + MftReg_SetCscElsa(obj->capDrv->base->reg, obj->config.hwChannelId + 1, nextChnlevel & 0x01U); + + /* Disable interrupt request for the current channel */ + MftReg_SetCscChie(obj->capDrv->base->reg, obj->config.hwChannelId, 0); + MftReg_SetCscChie(obj->capDrv->base->reg, obj->config.hwChannelId + 1, 1); + } + + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->capDrv->base->reg, 1); +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_ch.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_ch.h new file mode 100644 index 0000000..7734bb1 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_ch.h @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MFT_CAP_CH_H_ +#define _MFT_CAP_CH_H_ + +/*! \brief Contains public interface to various functions related + * to the Capture channel of MFT + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup mft_cap_ch + * \ingroup mft_cap_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Selects mode operation in the input capture + */ +typedef enum +{ + MFTCAPCH_EDGE_DETECT = 0U, /*!< MFT edge detect */ + MFTCAPCH_SIGNAL_MEASUREMENT = 1U, /*!< MFT signal measurement */ + MFTCAPCH_NO_OPERATION = 2U /*!< MFT no operation */ +} MftCapCh_InputOpModeType; + +/*! \brief MFT input capture measurement type for dual edge input capture + */ +typedef enum +{ + MFTCAPCH_NO_MEASUREMENT = 0x00U, /*!< No measurement */ + MFTCAPCH_RISING_EDGE_PERIOD_MEASUREMENT = 0x01U, /*!< Period measurement between two consecutive rising edges */ + MFTCAPCH_FALLING_EDGE_PERIOD_MEASUREMENT = 0x02U, /*!< Period measurement between two consecutive falling edges */ + MFTCAPCH_PERIOD_ON_MEASUREMENT = 0x03U, /*!< The time measurement taken for the pulse to remain ON or HIGH state */ + MFTCAPCH_PERIOD_OFF_MEASUREMENT = 0x04U /*!< The time measurement taken for the pulse to remain OFF or LOW state */ +} MftCapCh_SignalMeasurementModeType; + +/*! \brief MFT input capture edge mode as rising edge or falling edge + */ +typedef enum +{ + MFTCAPCH_NO_PIN_CONTROL = 0x00U, /*!< No trigger */ + MFTCAPCH_RISING_EDGE = 0x01U, /*!< Rising edge trigger */ + MFTCAPCH_FALLING_EDGE = 0x02U, /*!< Falling edge trigger */ + MFTCAPCH_BOTH_EDGES = 0x03U /*!< Rising and falling edge trigger */ +} MftCapCh_EdgeAlignmentModeType; + +/*! \brief The measurement type for input capture mode + */ +typedef enum +{ + MFTCAPCH_DISABLE_OPERATION = 0x00U, /*!< Have no operation */ + MFTCAPCH_TIMESTAMP_RISING_EDGE = 0x01U, /*!< Rising edge trigger */ + MFTCAPCH_TIMESTAMP_FALLING_EDGE = 0x02U, /*!< Falling edge trigger */ + MFTCAPCH_TIMESTAMP_BOTH_EDGES = 0x03U, /*!< Rising and falling edge trigger */ + MFTCAPCH_MEASURE_RISING_EDGE_PERIOD = 0x04U, /*!< Period measurement between two consecutive rising edges */ + MFTCAPCH_MEASURE_FALLING_EDGE_PERIOD = 0x05U, /*!< Period measurement between two consecutive falling edges */ + MFTCAPCH_MEASURE_PULSE_HIGH = 0x06U, /*!< The time measurement taken for the pulse to remain ON or HIGH state */ + MFTCAPCH_MEASURE_PULSE_LOW = 0x07U /*!< The time measurement taken for the pulse to remain OFF or LOW state */ +} MftCapCh_OpModeType; + +/*! \brief MFT driver Input capture callback function prototype + */ +typedef void (*MftCapCh_CallbackType)(uint8_t event, void *params); + +/*! \brief MFT driver Input capture parameters for each channel + */ +typedef struct _MftCapCh_ConfigType_ +{ + uint8_t hwChannelId; /*!< Physical hardware channel ID*/ + MftCapCh_InputOpModeType inputMode; /*!< FlexTimer module mode of operation */ + MftCapCh_EdgeAlignmentModeType edgeAlignement; /*!< Edge alignment Mode for signal measurement*/ + MftCapCh_SignalMeasurementModeType measurementType; /*!< Measurement Mode for signal measurement*/ + uint16_t filterValue; /*!< Filter Value */ + bool filterEn; /*!< Input capture filter state */ + bool continuousModeEn; /*!< Continuous measurement state */ + void *callbacksParams; /*!< The parameters of callback functions for channels events */ + MftCapCh_CallbackType callbackFunc; /*!< The callback function for channels events */ +} MftCapCh_ConfigType; + +/* Forward declaration of MFT Capture driver */ +struct _MftCapDrvType_; + +/*! \brief The definition of MFT capture channel prototype + */ +typedef struct _MftCapChType_ +{ + struct _MftCapDrvType_ *capDrv; + MftCapCh_ConfigType config; +} MftCapChType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the MFT CAP channel + * + * This function initializes MFT CAP channel + * + * \param[in] obj : pointer to MFT CAP channel instance + * \param[in] base : pointer to MFT driver instance + */ +extern void MftCapCh_Init(MftCapChType *obj, struct _MftCapDrvType_ *capDrv); + +/*! \brief Get default configuration of the MFT capture channel + * + * This function gets default configures the MFT capture module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void MftCapCh_GetDefaultConfig(MftCapCh_ConfigType *userConfig); + +/*! \brief Configure the MFT capture channel + * + * This function configures the channel in the Input Capture mode for either getting + * time-stamps on edge detection or on signal measurement. When the edge specified in the capture Mode + * argument occurs on the channel and then the MFT counter is captured into the CnV register. + * The user have to read the CnV register separately to get this value. The filter + * function is disabled if the filterVal argument passed as 0. The filter feature + * is available only on channels 0,1,2,3. + * + * \param[in] obj : pointer to MFT CAP channel instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void MftCapCh_Config(MftCapChType *obj, const MftCapCh_ConfigType *userConfig); + +/*! \brief Disarm the MFT capture channel + * + * This function disables input capture mode and clears MFT timer configuration + * + * \param[in] obj : pointer to MFT CAP channel instance + */ +extern void MftCapCh_Disarm(MftCapChType *obj); + +/*! \brief Starts a new single-shot signal measurement of the given channel. + * + * This function starts the new single-shot signal measurement of the given channel. + * + * \param[in] obj : pointer to MFT CAP channel instance + * \return The result of the operation + * - true : succeed + * - false : failed + */ +extern bool MftCapCh_StartNewSignalMeasurement(MftCapChType *obj); + +/*! \brief Set mode operation for channel in the input capture mode + * + * This function will change the channel mode at run time or + * when stopping channel. The channel mode is selected in the MftCapCh_OpModeType + * enumeration type. + * + * \param[in] obj : pointer to MFT CAP channel instance + * \param[in] inputMode : The channel operation mode. + * \param[in] enableContinuousCapture : Enable/disable the continuous capture mode. + */ +extern void MftCapCh_SetChannelMode(MftCapChType *obj, MftCapCh_OpModeType inputMode, bool enableContinuousCapture); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _MFT_CAP_CH_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_drv.c new file mode 100644 index 0000000..77622e1 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_drv.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "mft_cap_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void MftCapDrv_Init(MftCapDrvType *obj, MftDrvType *base) +{ + obj->base = base; + + uint8_t i = 0; + for(i = 0; i < MFT_CHANNEL_NUM; ++i) + { + MftCapCh_Init(&obj->channel[i], obj); + } +} + +void MftCapDrv_GetDefaultConfig(MftCapDrv_ConfigType *userConfig) +{ + userConfig->maxCountValue = 65535; +} + +void MftCapDrv_Config(MftCapDrvType *obj, const MftCapDrv_ConfigType *userConfig) +{ + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->base->reg, 1); + + /* CNTIN = 0 */ + MftReg_SetCntInCntInit(obj->base->reg, 0U); + /* Set MOD */ + MftReg_SetModuloMod(obj->base->reg, userConfig->maxCountValue); + /* CPWMS = 0 */ + MftReg_SetScCPwms(obj->base->reg, 0); + + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->base->reg, 1); +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_drv.h new file mode 100644 index 0000000..e059a22 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_cap/mft_cap_drv.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MFT_CAP_DRV_H_ +#define _MFT_CAP_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the input Capture driver of MFT + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../mft_drv.h" +#include "mft_cap_ch.h" + +/*! \addtogroup mft_cap_drv + * \ingroup mft_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief MFT Input capture driver configuration + */ +typedef struct _MftCapDrv_ConfigType_ +{ + uint16_t maxCountValue; /*!< Maximum counter value. Minimum value is 0 for this mode */ +} MftCapDrv_ConfigType; + +/*! \brief The definition of MFT capture driver prototype + * \details Derived from MFT driver + */ +typedef struct _MftCapDrvType_ +{ + MftDrvType *base; /*!< base class of capture driver */ + MftCapChType channel[MFT_CHANNEL_NUM]; /*!< channels of the capture mode */ +} MftCapDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the MFT CAP module + * + * This function initializes MFT CAP driver by setting the MFT driver + * instance to it. + * + * \param[in] obj : pointer to MFT CAP channel instance + * \param[in] base : pointer to MFT driver instance + */ +extern void MftCapDrv_Init(MftCapDrvType *obj, MftDrvType *base); + +/*! \brief Get default configures the MFT capture module for configuration structure + * + * This function gets default configures the MFT capture module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void MftCapDrv_GetDefaultConfig(MftCapDrv_ConfigType *userConfig); + +/*! \brief Configure the MFT capture module + * + * This function configures the MFT capture module. + * + * \param[in] obj : pointer to MFT CAP channel instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void MftCapDrv_Config(MftCapDrvType *obj, const MftCapDrv_ConfigType *userConfig); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _MFT_CAP_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_drv.c new file mode 100644 index 0000000..317758e --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_drv.c @@ -0,0 +1,661 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "mft_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +/*! \brief Reset the MFT all registers + * + * This function resets MFT all registers. + * + * \param[in] obj : pointer to MFT driver instance + */ +void MftDrv_Reset(MftDrvType *obj) +{ + uint8_t channel = 0; + uint8_t pairIndex = 0; + + /* WPDIS is set when WPEN bit is read as a 1 and then 1 is written to WPDIS */ + obj->reg->FMS &= 0U; + /* This is the reset value for MODE register. WPDIS bit is set to disable write protection */ + obj->reg->MODE = 0x00000004U; + obj->reg->CNT = 0U; + obj->reg->SC &= 0U; + obj->reg->MODULO = 0U; + obj->reg->CNTIN = 0U; + obj->reg->STATUS &= 0U; + obj->reg->SYNC = 0U; + obj->reg->OUTINIT = 0U; + obj->reg->OUTMASK = 0U; + obj->reg->COMBINE = 0U; + obj->reg->DEADTIME = 0U; + obj->reg->EXTTRIG &= 0U; + obj->reg->POL = 0U; + obj->reg->FILTER = 0U; + obj->reg->FLTCTRL = 0U; + obj->reg->QDCTRL = 0U; + obj->reg->CONF = 0U; + obj->reg->FLTPOL = 0U; + obj->reg->SYNCONF = 0U; + obj->reg->INVCTRL = 0U; + obj->reg->SWOCTRL = 0U; + obj->reg->PWMLOAD = 0U; + obj->reg->HCR = 0U; + obj->reg->MOD_MIRROR = 0U; + obj->reg->SIM_OBE = 0U; + + for(channel = 0; channel < MFT_CHANNEL_NUM; ++channel) + { + obj->reg->CH[channel].CSC = 0; + obj->reg->CH[channel].CV = 0; + obj->reg->MIRROR[channel].CV = 0; + } + for(pairIndex = 0; pairIndex < MFT_DEADTIME_PAIR; ++pairIndex) + { + obj->reg->PAIR[pairIndex].DEADTIME = 0; + } +} + +void MftDrv_Init(MftDrvType *obj, struct _MftRegType_ *reg) +{ + obj->reg = reg; +} + +void MftDrv_GetDefaultConfig(MftDrv_ConfigType *userConfig) +{ + userConfig->clockSource = MFTDRV_CLOCK_SOURCE_SYSTEMCLK; + userConfig->countingMode = MFTDRV_UP_COUNTING; + userConfig->prescaler = MFTDRV_PRESCALE_DIV_BY_1; + userConfig->bdmMode = MFTDRV_BDM_MODE_11; +} + +void MftDrv_Config(MftDrvType *obj, const MftDrv_ConfigType *userConfig) +{ + /* Reset the MFT module */ + MftDrv_Reset(obj); + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->reg, 1); + /* Enable MFT */ + MftReg_SetModeMftEn(obj->reg, 1); + /* Set clock source */ + MftReg_SetScClks(obj->reg, userConfig->clockSource); + /* Set the clock prescale */ + MftReg_SetScPs(obj->reg, userConfig->prescaler); + /* Set BDM mode */ + MftReg_SetConfBdmMode(obj->reg, userConfig->bdmMode); + /* Set Counting mode */ + MftReg_SetScCPwms(obj->reg, userConfig->countingMode == MFTDRV_UP_COUNTING ? 0 : 1); + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->reg, 1); +} + +void MftDrv_MaskOutputChannels(MftDrvType *obj, uint32_t channelsMask, bool softWareTrigger) +{ + obj->reg->OUTMASK = channelsMask; + MftReg_SetSyncSwSync(obj->reg, softWareTrigger ? 1 : 0); +} + +void MftDrv_SetInitialCounterValue(MftDrvType *obj, uint16_t counterValue, bool softWareTrigger) +{ + MftReg_SetCntInCntInit(obj->reg, counterValue); + MftReg_SetSyncSwSync(obj->reg, softWareTrigger ? 1 : 0); +} + +uint16_t MftDrv_GetChnCounterValue(MftDrvType *obj, uint8_t channel) +{ + return MftReg_GetCvVal(obj->reg, channel); +} + +void MftDrv_SetHalfCycleReloadPoint(MftDrvType *obj, uint16_t reloadPoint, bool softWareTrigger) +{ + MftReg_SetHcrHCVal(obj->reg, reloadPoint); + MftReg_SetSyncSwSync(obj->reg, softWareTrigger ? 1 : 0); +} + +void MftDrv_SetSoftOutChnValue(MftDrvType *obj, uint8_t channelsValues, bool softWareTrigger) +{ + uint8_t channelsMask = channelsValues ^ (uint8_t)obj->reg->POL; + uint32_t mask = MFT_SWOCTRL_CH0OCV_MASK | MFT_SWOCTRL_CH1OCV_MASK | MFT_SWOCTRL_CH2OCV_MASK | MFT_SWOCTRL_CH3OCV_MASK | MFT_SWOCTRL_CH4OCV_MASK | MFT_SWOCTRL_CH5OCV_MASK | MFT_SWOCTRL_CH6OCV_MASK | MFT_SWOCTRL_CH7OCV_MASK; + obj->reg->SWOCTRL = ((obj->reg->SWOCTRL) & (~(mask))) | ((uint32_t)channelsMask << MFT_SWOCTRL_CH0OCV_SHIFT); + + MftReg_SetSyncSwSync(obj->reg, softWareTrigger ? 1 : 0); +} + +void MftDrv_SetSoftwareOutputChannelControl(MftDrvType *obj, uint8_t channelsMask, bool softWareTrigger) +{ + uint32_t mask = MFT_SWOCTRL_CH0OC_MASK | MFT_SWOCTRL_CH1OC_MASK | MFT_SWOCTRL_CH2OC_MASK | MFT_SWOCTRL_CH3OC_MASK | MFT_SWOCTRL_CH4OC_MASK | MFT_SWOCTRL_CH5OC_MASK | MFT_SWOCTRL_CH6OC_MASK | MFT_SWOCTRL_CH7OC_MASK; + obj->reg->SWOCTRL = ((obj->reg->SWOCTRL) & (~(mask))) | channelsMask; + + MftReg_SetSyncSwSync(obj->reg, softWareTrigger ? 1 : 0); +} + +void MftDrv_SetAllChnSoftwareOutputControl(MftDrvType *obj, uint8_t channelMask, uint8_t channelValueMask, bool softWareTrigger) +{ + uint16_t value = 0U; + + value = (uint16_t)(((uint16_t)channelValueMask ^ (uint16_t)obj->reg->POL) << (uint16_t)8U) | (uint16_t)channelMask; + obj->reg->SWOCTRL = value; + + MftReg_SetSyncSwSync(obj->reg, softWareTrigger ? 1 : 0); +} + +void MftDrv_SetInvertingControl(MftDrvType *obj, uint8_t channelsPairMask, bool softWareTrigger) +{ + obj->reg->INVCTRL = channelsPairMask; + MftReg_SetSyncSwSync(obj->reg, softWareTrigger ? 1 : 0); +} + +void MftDrv_SetModuloCounterValue(MftDrvType *obj, uint16_t counterValue, bool softWareTrigger) +{ + MftReg_SetModuloMod(obj->reg, counterValue); + MftReg_SetSyncSwSync(obj->reg, softWareTrigger ? 1 : 0); +} + +void MftDrv_SetOutputlevel(MftDrvType *obj, uint8_t channel, uint8_t level) +{ + MftReg_SetCscElsa(obj->reg, channel, (level & 0x01U)); + MftReg_SetCscElsb(obj->reg, channel, (level & 0x02U) >> 1U); +} + +void MftDrv_EnableInterrupts(MftDrvType *obj, uint32_t interruptMask) +{ + uint32_t chnlInts = (interruptMask & 0x000000FFU); + uint8_t channel = 0U; + + /* Enable the timer overflow interrupt */ + if((interruptMask & (uint32_t)MFTDRV_TIME_OVERFLOW_INT_ENABLE) != 0x0U) + { + MftReg_SetScToie(obj->reg, 1); + } + + /* Enable the fault interrupt */ + if((interruptMask & (uint32_t)MFTDRV_FAULT_INT_ENABLE) != 0x0U) + { + MftReg_SetModeFaultIE(obj->reg, 1); + } + + /* Enable the reload interrupt */ + if((interruptMask & (uint32_t)MFTDRV_RELOAD_INT_ENABLE) != 0x0U) + { + MftReg_SetScRie(obj->reg, 1); + } + + /* Enable the channel interrupts */ + while(chnlInts != 0U) + { + if((chnlInts & 0x1U) != 0x0U) + { + MftReg_SetCscChie(obj->reg, channel, 1); + } + channel++; + chnlInts = chnlInts >> 1U; + } +} + +void MftDrv_DisableInterrupts(MftDrvType *obj, uint32_t InterruptMask) +{ + uint32_t chnlInts = (InterruptMask & 0x000000FFU); + uint8_t channel = 0U; + + /* Disable the timer overflow interrupt */ + if((InterruptMask & (uint32_t)MFTDRV_TIME_OVERFLOW_INT_ENABLE) != 0x0U) + { + MftReg_SetScToie(obj->reg, 0); + } + + /* Disable the fault interrupt */ + if((InterruptMask & (uint32_t)MFTDRV_FAULT_INT_ENABLE) != 0x0U) + { + MftReg_SetModeFaultIE(obj->reg, 0); + } + + /* Disable the reload interrupt */ + if((InterruptMask & (uint32_t)MFTDRV_RELOAD_INT_ENABLE) != 0x0U) + { + MftReg_SetScRie(obj->reg, 0); + } + + /* Disable the channel interrupts */ + while(chnlInts != 0U) + { + if((chnlInts & 0x1U) != 0x0U) + { + MftReg_SetCscChie(obj->reg, channel, 0); + } + channel++; + chnlInts = chnlInts >> 1U; + } +} + +uint32_t MftDrv_GetEnabledInterrupts(MftDrvType *obj) +{ + uint32_t enabledInterrupts = 0U; + uint8_t channel = 0; + + /* Check if timer overflow interrupt is enabled */ + if(MftReg_GetScToie(obj->reg) == 1) + { + enabledInterrupts |= (uint32_t)MFTDRV_TIME_OVERFLOW_INT_ENABLE; + } + + /* Check if fault interrupt is enabled */ + if(MftReg_GetModeFaultIE(obj->reg) == 1) + { + enabledInterrupts |= (uint32_t)MFTDRV_FAULT_INT_ENABLE; + } + + /* Check if the reload interrupt is enabled */ + if(MftReg_GetScRie(obj->reg) == 1) + { + enabledInterrupts |= (uint32_t)MFTDRV_RELOAD_INT_ENABLE; + } + + /* Check if the channel interrupts are enabled */ + for(channel = 0U; channel < MFT_CHANNEL_NUM; channel++) + { + if(MftReg_GetCscChie(obj->reg, channel) == 1) + { + enabledInterrupts |= (1UL << (uint32_t)channel); + } + } + + return enabledInterrupts; +} + +uint32_t MftDrv_GetStatusFlags(MftDrvType *obj) +{ + uint8_t channel = 0U; + uint32_t statusFlags = 0U; + + /* Check the timer flag */ + if(MftReg_GetScTof(obj->reg) == 1) + { + statusFlags |= (uint32_t)MFTDRV_TIME_OVER_FLOW_FLAG; + } + + /* Check fault flag */ + if(MftReg_GetFmsFaultF(obj->reg) == 1) + { + statusFlags |= (uint32_t)MFTDRV_FAULT_FLAG; + } + + /* Check reload flag */ + if(MftReg_GetScRf(obj->reg) == 1) + { + statusFlags |= (uint32_t)MFTDRV_RELOAD_FLAG; + } + + /* Check channel trigger flag */ + if(MftReg_GetExtTrigTrigF(obj->reg) == 1) + { + statusFlags |= (uint32_t)MFTDRV_CHANNEL_TRIGGER_FLAG; + } + + /* Lower 8 bits contain the channel status flags */ + for(channel = 0U; channel < MFT_CHANNEL_NUM; channel++) + { + if(MftReg_GetCscChf(obj->reg, channel) == 1) + { + statusFlags |= (1UL << (uint32_t)channel); + } + } + + return statusFlags; +} + +void MftDrv_ClearStatusFlags(MftDrvType *obj, uint32_t flagMask) +{ + /* Clear the timer overflow flag by writing a 0 to the bit while it is set */ + if((flagMask & (uint32_t)MFTDRV_TIME_OVER_FLOW_FLAG) != 0x0U) + { + MftReg_SetScTof(obj->reg, 0); + } + + /* Clear fault flag by writing a 0 to the bit while it is set */ + if((flagMask & (uint32_t)MFTDRV_FAULT_FLAG) != 0x0U) + { + MftReg_SetFmsFaultF0(obj->reg, 0); + MftReg_SetFmsFaultF1(obj->reg, 0); + MftReg_SetFmsFaultF2(obj->reg, 0); + MftReg_SetFmsFaultF3(obj->reg, 0); + /* FAULTF is also cleared when FAULTF bit of each enabled fault input is cleared */ + MftReg_SetFmsFaultF(obj->reg, 0); + } + + /* Check reload flag by writing a 0 to the bit while it is set */ + if((flagMask & (uint32_t)MFTDRV_RELOAD_FLAG) != 0x0U) + { + MftReg_SetScRf(obj->reg, 0); + } + + /* Clear channel trigger flag */ + if((flagMask & (uint32_t)MFTDRV_CHANNEL_TRIGGER_FLAG) != 0x0U) + { + MftReg_SetExtTrigTrigF(obj->reg, 0); + } + + /* Clear the channel status flags by writing a 0 to the bit */ + if((flagMask & (uint32_t)MFTDRV_CHANNEL7_FLAG) != 0x0U) + { + MftReg_SetStatusCh7F(obj->reg, 0); + } + if((flagMask & (uint32_t)MFTDRV_CHANNEL6_FLAG) != 0x0U) + { + MftReg_SetStatusCh6F(obj->reg, 0); + } + if((flagMask & (uint32_t)MFTDRV_CHANNEL5_FLAG) != 0x0U) + { + MftReg_SetStatusCh5F(obj->reg, 0); + } + if((flagMask & (uint32_t)MFTDRV_CHANNEL4_FLAG) != 0x0U) + { + MftReg_SetStatusCh4F(obj->reg, 0); + } + if((flagMask & (uint32_t)MFTDRV_CHANNEL3_FLAG) != 0x0U) + { + MftReg_SetStatusCh3F(obj->reg, 0); + } + if((flagMask & (uint32_t)MFTDRV_CHANNEL2_FLAG) != 0x0U) + { + MftReg_SetStatusCh2F(obj->reg, 0); + } + if((flagMask & (uint32_t)MFTDRV_CHANNEL1_FLAG) != 0x0U) + { + MftReg_SetStatusCh1F(obj->reg, 0); + } + if((flagMask & (uint32_t)MFTDRV_CHANNEL0_FLAG) != 0x0U) + { + MftReg_SetStatusCh0F(obj->reg, 0); + } +} + +void MftDrv_CounterReset(MftDrvType *obj, bool softWareTrigger) +{ + /* Updates the counter with its initial value */ + MftReg_SetCntCount(obj->reg, 0U); + /* Set a software trigger or waiting a hardware trigger */ + MftReg_SetSyncSwSync(obj->reg, softWareTrigger ? 1 : 0); +} + +void MftDrv_SetDualEdgeCaptureCmd(MftDrvType *obj, uint8_t pairNum, bool enable) +{ + uint8_t enableValue = enable ? 1 : 0; + switch(pairNum) + { + case 0: + MftReg_SetCombineDecapEn0(obj->reg, enableValue); + break; + case 1: + MftReg_SetCombineDecapEn1(obj->reg, enableValue); + break; + case 2: + MftReg_SetCombineDecapEn2(obj->reg, enableValue); + break; + case 3: + MftReg_SetCombineDecapEn3(obj->reg, enableValue); + break; + default: + break; + } +} + +void MftDrv_SetDualChannelDecap(MftDrvType *obj, uint8_t pairNum, bool enable) +{ + uint8_t enableValue = enable ? 1 : 0; + switch(pairNum) + { + case 0: + MftReg_SetCombineDecap0(obj->reg, enableValue); + break; + case 1: + MftReg_SetCombineDecap1(obj->reg, enableValue); + break; + case 2: + MftReg_SetCombineDecap2(obj->reg, enableValue); + break; + case 3: + MftReg_SetCombineDecap3(obj->reg, enableValue); + break; + default: + break; + } +} + +bool MftDrv_GetDualEdgeCaptureCmd(MftDrvType *obj, uint8_t pairNum) +{ + bool retval = false; + switch(pairNum) + { + case 0: + retval = MftReg_GetCombineDecapEn0(obj->reg) == 1; + break; + case 1: + retval = MftReg_GetCombineDecapEn1(obj->reg) == 1; + break; + case 2: + retval = MftReg_GetCombineDecapEn2(obj->reg) == 1; + break; + case 3: + retval = MftReg_GetCombineDecapEn3(obj->reg) == 1; + break; + default: + break; + } + + return retval; +} + +void MftDrv_SetDualChannelComp(MftDrvType *obj, uint8_t pairNum, bool enable) +{ + uint8_t enableValue = enable ? 1 : 0; + switch(pairNum) + { + case 0: + MftReg_SetCombineComp0(obj->reg, enableValue); + break; + case 1: + MftReg_SetCombineComp1(obj->reg, enableValue); + break; + case 2: + MftReg_SetCombineComp2(obj->reg, enableValue); + break; + case 3: + MftReg_SetCombineComp3(obj->reg, enableValue); + break; + default: + break; + } +} + +void MftDrv_SetDualChannelCombine(MftDrvType *obj, uint8_t pairNum, bool enable) +{ + uint8_t enableValue = enable ? 1 : 0; + switch(pairNum) + { + case 0: + MftReg_SetCombineCombine0(obj->reg, enableValue); + break; + case 1: + MftReg_SetCombineCombine1(obj->reg, enableValue); + break; + case 2: + MftReg_SetCombineCombine2(obj->reg, enableValue); + break; + case 3: + MftReg_SetCombineCombine3(obj->reg, enableValue); + break; + default: + break; + } +} + +void MftDrv_SetDualChannelModifiedCombine(MftDrvType *obj, uint8_t pairNum, bool enable) +{ + uint8_t enableValue = enable ? 1 : 0; + switch(pairNum) + { + case 0: + MftReg_SetCombineMCombine0(obj->reg, enableValue); + break; + case 1: + MftReg_SetCombineMCombine1(obj->reg, enableValue); + break; + case 2: + MftReg_SetCombineMCombine2(obj->reg, enableValue); + break; + case 3: + MftReg_SetCombineMCombine3(obj->reg, enableValue); + break; + default: + break; + } +} + +void MftDrv_SetDualChannelFault(MftDrvType *obj, uint8_t pairNum, bool enable) +{ + uint8_t enableValue = enable ? 1 : 0; + switch(pairNum) + { + case 0: + MftReg_SetCombineFaultEn0(obj->reg, enableValue); + break; + case 1: + MftReg_SetCombineFaultEn1(obj->reg, enableValue); + break; + case 2: + MftReg_SetCombineFaultEn2(obj->reg, enableValue); + break; + case 3: + MftReg_SetCombineFaultEn3(obj->reg, enableValue); + break; + default: + break; + } +} + +void MftDrv_SetDualChannelPwmSync(MftDrvType *obj, uint8_t pairNum, bool enable) +{ + uint8_t enableValue = enable ? 1 : 0; + switch(pairNum) + { + case 0: + MftReg_SetCombineSyncEn0(obj->reg, enableValue); + break; + case 1: + MftReg_SetCombineSyncEn1(obj->reg, enableValue); + break; + case 2: + MftReg_SetCombineSyncEn2(obj->reg, enableValue); + break; + case 3: + MftReg_SetCombineSyncEn3(obj->reg, enableValue); + break; + default: + break; + } +} + +void MftDrv_EnablePwmChannelOutputs(MftDrvType *obj, uint8_t channel, bool enable) +{ + uint8_t enableValue = enable ? 1 : 0; + switch(channel) + { + case 0: + MftReg_SetScPwmEn0(obj->reg, enableValue); + break; + case 1: + MftReg_SetScPwmEn1(obj->reg, enableValue); + break; + case 2: + MftReg_SetScPwmEn2(obj->reg, enableValue); + break; + case 3: + MftReg_SetScPwmEn3(obj->reg, enableValue); + break; + case 4: + MftReg_SetScPwmEn4(obj->reg, enableValue); + break; + case 5: + MftReg_SetScPwmEn5(obj->reg, enableValue); + break; + case 6: + MftReg_SetScPwmEn6(obj->reg, enableValue); + break; + case 7: + MftReg_SetScPwmEn7(obj->reg, enableValue); + break; + default: + break; + } +} + +void MftDrv_SetChannelTriggerCmd(MftDrvType *obj, uint8_t channel, bool enable) +{ + uint8_t enableValue = enable ? 1 : 0; + switch(channel) + { + case 0: + MftReg_SetExtTrigCh0Trig(obj->reg, enableValue); + break; + case 1: + MftReg_SetExtTrigCh1Trig(obj->reg, enableValue); + break; + case 2: + MftReg_SetExtTrigCh2Trig(obj->reg, enableValue); + break; + case 3: + MftReg_SetExtTrigCh3Trig(obj->reg, enableValue); + break; + case 4: + MftReg_SetExtTrigCh4Trig(obj->reg, enableValue); + break; + case 5: + MftReg_SetExtTrigCh5Trig(obj->reg, enableValue); + break; + case 6: + MftReg_SetExtTrigCh6Trig(obj->reg, enableValue); + break; + case 7: + MftReg_SetExtTrigCh7Trig(obj->reg, enableValue); + break; + default: + break; + } +} + +void MftDrv_SoftWareTrigger(MftDrvType *obj) +{ + MftReg_SetSyncSwSync(obj->reg, 1); +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_drv.h new file mode 100644 index 0000000..8ce58c2 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_drv.h @@ -0,0 +1,534 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MFT_DRV_H_ +#define _MFT_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of MFT (Multi Functional Timer) + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "mft_reg.h" + +/*! \addtogroup mft_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief MFT counting mode + */ +typedef enum +{ + MFTDRV_UP_COUNTING, /*!< up counting mode */ + MFTDRV_UP_DOWN_COUNTING, /*!< up-down counting mode */ +} MftDrv_CountingModeType; + +/*! \brief MFT clock source selection + */ +typedef enum +{ + MFTDRV_CLOCK_SOURCE_NONE = 0x00U, /*!< None use clock for MFT */ + MFTDRV_CLOCK_SOURCE_SYSTEMCLK = 0x01U, /*!< System clock */ + MFTDRV_CLOCK_SOURCE_FIXEDCLK = 0x02U, /*!< Fixed clock */ + MFTDRV_CLOCK_SOURCE_EXTERNALCLK = 0x03U /*!< External clock */ +} MftDrv_ClockSrcType; + +/*! \brief MFT pre-scaler factor selection for the clock source + */ +typedef enum +{ + MFTDRV_PRESCALE_DIV_BY_1 = 0x00U, /*!< Divide by 1 */ + MFTDRV_PRESCALE_DIV_BY_2 = 0x01U, /*!< Divide by 2 */ + MFTDRV_PRESCALE_DIV_BY_4 = 0x02U, /*!< Divide by 4 */ + MFTDRV_PRESCALE_DIV_BY_8 = 0x03U, /*!< Divide by 8 */ + MFTDRV_PRESCALE_DIV_BY_16 = 0x04U, /*!< Divide by 16 */ + MFTDRV_PRESCALE_DIV_BY_32 = 0x05U, /*!< Divide by 32 */ + MFTDRV_PRESCALE_DIV_BY_64 = 0x06U, /*!< Divide by 64 */ + MFTDRV_PRESCALE_DIV_BY_128 = 0x07U /*!< Divide by 128 */ +} MftDrv_PrescaleType; + +/*! \brief List of MFT interrupts + */ +typedef enum +{ + MFTDRV_CHANNEL0_INT_ENABLE = 0x00000001U, /*!< Channel 0 interrupt */ + MFTDRV_CHANNEL1_INT_ENABLE = 0x00000002U, /*!< Channel 1 interrupt */ + MFTDRV_CHANNEL2_INT_ENABLE = 0x00000004U, /*!< Channel 2 interrupt */ + MFTDRV_CHANNEL3_INT_ENABLE = 0x00000008U, /*!< Channel 3 interrupt */ + MFTDRV_CHANNEL4_INT_ENABLE = 0x00000010U, /*!< Channel 4 interrupt */ + MFTDRV_CHANNEL5_INT_ENABLE = 0x00000020U, /*!< Channel 5 interrupt */ + MFTDRV_CHANNEL6_INT_ENABLE = 0x00000040U, /*!< Channel 6 interrupt */ + MFTDRV_CHANNEL7_INT_ENABLE = 0x00000080U, /*!< Channel 7 interrupt */ + MFTDRV_FAULT_INT_ENABLE = 0x00000100U, /*!< Fault interrupt */ + MFTDRV_TIME_OVERFLOW_INT_ENABLE = 0x00000200U, /*!< Time overflow interrupt */ + MFTDRV_RELOAD_INT_ENABLE = 0x00000400U /*!< Reload interrupt */ +} MftDrv_InterruptOptionType; + +/*! \brief List of MFT flags + */ +typedef enum +{ + MFTDRV_CHANNEL0_FLAG = 0x00000001U, /*!< Channel 0 Flag */ + MFTDRV_CHANNEL1_FLAG = 0x00000002U, /*!< Channel 1 Flag */ + MFTDRV_CHANNEL2_FLAG = 0x00000004U, /*!< Channel 2 Flag */ + MFTDRV_CHANNEL3_FLAG = 0x00000008U, /*!< Channel 3 Flag */ + MFTDRV_CHANNEL4_FLAG = 0x00000010U, /*!< Channel 4 Flag */ + MFTDRV_CHANNEL5_FLAG = 0x00000020U, /*!< Channel 5 Flag */ + MFTDRV_CHANNEL6_FLAG = 0x00000040U, /*!< Channel 6 Flag */ + MFTDRV_CHANNEL7_FLAG = 0x00000080U, /*!< Channel 7 Flag */ + MFTDRV_FAULT_FLAG = 0x00000100U, /*!< Fault Flag */ + MFTDRV_TIME_OVER_FLOW_FLAG = 0x00000200U, /*!< Time overflow Flag */ + MFTDRV_RELOAD_FLAG = 0x00000400U, /*!< Reload Flag */ + MFTDRV_CHANNEL_TRIGGER_FLAG = 0x00000800U /*!< Channel trigger Flag */ +} MftDrv_StatusFlagType; + +/*! \brief List of MFT BDM Mode + */ +typedef enum +{ + MFTDRV_BDM_MODE_00 = 0x00U, /*!< MFT counter stopped */ + MFTDRV_BDM_MODE_01 = 0x01U, /*!< MFT counter stopped */ + MFTDRV_BDM_MODE_10 = 0x02U, /*!< MFT counter stopped */ + MFTDRV_BDM_MODE_11 = 0x03U /*!< MFT counter in functional mode*/ +} MftDrv_BdmModeType; + +/*! \brief MFT configuration structure + */ +typedef struct _MftDrv_ConfigType_ +{ + MftDrv_ClockSrcType clockSource; /*!< Clock source */ + MftDrv_CountingModeType countingMode; /*!< Counting mode */ + MftDrv_PrescaleType prescaler; /*!< Register pre-scaler options */ + MftDrv_BdmModeType bdmMode; /*!< Select MFT behavior in BDM mode */ +} MftDrv_ConfigType; + +/*! \brief The definition of MFT driver prototype + */ +typedef struct _MftDrvType_ +{ + struct _MftRegType_ *reg; /*!< MFT register */ +} MftDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the MFT reg and state + * + * This function initializes MFT driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] reg : pointer to MFT register instance + */ +extern void MftDrv_Init(MftDrvType *obj, struct _MftRegType_ *reg); + +/*! \brief Get default configures the MFT module for configuration structure + * + * This function gets default configures the MFT module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void MftDrv_GetDefaultConfig(MftDrv_ConfigType *userConfig); + +/*! \brief Configure the MFT driver + * + * This function resets MFT module, enables the MFT module, configures MFT + * module. The MFT configuration structure shall + * be passed as arguments. + * This function should be called before calling any other MFT driver function. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] userConfig : pointer to MFT config instance + */ +extern void MftDrv_Config(MftDrvType *obj, const MftDrv_ConfigType *userConfig); + +/*! \brief Mask the output of channels + * + * This function will mask the output of the channels and at match events will be ignored + * by the masked channels. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] channelsMask : channels mask + * \param[in] softWareTrigger : whether to enable softWare trigger + * - false : disable software trigger + * - true : enable software trigger + */ +extern void MftDrv_MaskOutputChannels(MftDrvType *obj, uint32_t channelsMask, bool softWareTrigger); + +/*! \brief Initializes the Mft module counter value + * + * This function configure the initial counter value. The counter will get this + * value after an overflow event. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] counterValue : counter Value + * \param[in] softWareTrigger : whether to enable softWare trigger + * - false : disable software trigger + * - true : enable software trigger + */ +extern void MftDrv_SetInitialCounterValue(MftDrvType *obj, uint16_t counterValue, bool softWareTrigger); + +/*! \brief Get the Mft module channel counter value + * + * This function get the counter value. Captured MFT counter value of the input modes or + * the match value for the output modes + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] channel : channel number + * \return Channel counter value + */ +extern uint16_t MftDrv_GetChnCounterValue(MftDrvType *obj, uint8_t channel); + +/*! \brief Configure the value of the counter which will generates an reload point + * + * This function configure the value of the counter which will + * generates an reload point. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] reloadPoint : reload Point + * \param[in] softWareTrigger : whether to enable softWare trigger + * - false : disable software trigger + * - true : enable software trigger + */ +extern void MftDrv_SetHalfCycleReloadPoint(MftDrvType *obj, uint16_t reloadPoint, bool softWareTrigger); + +/*! \brief Set soft out channel value + * + * This function will force the output value of a channel to a specific value. + * Before using this function it's mandatory to mask the match events using + * MftDrv_MaskOutputChannels and to enable software output control using + * MftDrv_SetSoftwareOutputChannelControl. + * + * \note When the PWM signal is configured with LOW/HIGH polarity on the channel (n). + * It should be set the safe state as LOW level state. However, We will have an issue + * with COMP bit is zero and CH(n)OCV is HIGH and CH(n+1)OCV is LOW. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] channelsValues : The values which will be software configured for channels. + * \param[in] softWareTrigger : whether to enable softWare trigger + * - false : disable software trigger + * - true : enable software trigger + */ +extern void MftDrv_SetSoftOutChnValue(MftDrvType *obj, uint8_t channelsValues, bool softWareTrigger); + +/*! \brief Set software output channel Control + * + * This function will configure which output channel can be software controlled. + * Software output control forces the following values on channels (n) and (n+1) when the + * COMP bit is zero and POL bit is zero. + * CH(n)OC|CH(n+1)OC|CH(n)OCV|CH(n+1)OCV|Channel (n) Output | Channel (n+1) Output + * 0 | 0 | X | X | is not modified by SWOC| is not modified by SWOC + * 1 | 1 | 0 | 0 | is forced to zero | is forced to zero + * 1 | 1 | 0 | 1 | is forced to zero | is forced to one + * 1 | 1 | 1 | 0 | is forced to one | is forced to zero + * 1 | 1 | 1 | 1 | is forced to one | is forced to one + * + * Software output control forces the following values on channels (n) and (n+1) when the + * COMP bit is one and POL bit is zero. + * CH(n)OC|CH(n+1)OC|CH(n)OCV|CH(n+1)OCV|Channel (n) Output | Channel (n+1) Output + * 0 | 0 | X | X | is not modified by SWOC| is not modified by SWOC + * 1 | 1 | 0 | 0 | is forced to zero | is forced to zero + * 1 | 1 | 0 | 1 | is forced to zero | is forced to one + * 1 | 1 | 1 | 0 | is forced to one | is forced to zero + * 1 | 1 | 1 | 1 | is forced to one | is forced to zero + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] channelsMask : The mask which will configure the channels which can be software controlled + * \param[in] softWareTrigger : whether to enable softWare trigger + * - false : disable software trigger + * - true : enable software trigger + */ +extern void MftDrv_SetSoftwareOutputChannelControl(MftDrvType *obj, uint8_t channelsMask, bool softWareTrigger); + +/*! \brief This function will control list of channels by software to force the output to specified value. + * + * Despite the odd channels are configured as HIGH/LOW, they will be inverted in the following + * configuration: COMP bit = 1 and CH(n)OCV and CH(n+1)OCV are HIGH. + * Please check software output control behavior chapter from reference manual. + * + * \note When the PWM signal is configured with LOW/HIGH polarity on the channel (n). + * It should be set the safe state as LOW level state. However, We will have an issue + * with COMP bit is zero and CH(n)OCV is HIGH and CH(n+1)OCV is LOW. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] channelsMask : The mask which will configure the channels which can be software controlled. + * \param[in] channelValueMask : The values which will be software configured for channels. + * \param[in] softWareTrigger : whether to enable softWare trigger + * - false : disable software trigger + * - true : enable software trigger + */ +extern void MftDrv_SetAllChnSoftwareOutputControl(MftDrvType *obj, uint8_t channelMask, uint8_t channelValueMask, bool softWareTrigger); + +/*! \brief Set inverting control + * + * This function will configure if the second channel of a pair will be inverted or not. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] channelsPairMask : The mask which will configure which channel pair will invert the second channel. + * \param[in] softWareTrigger : whether to enable softWare trigger + * - false : disable software trigger + * - true : enable software trigger + */ +extern void MftDrv_SetInvertingControl(MftDrvType *obj, uint8_t channelsPairMask, bool softWareTrigger); + +/*! \brief Set Modulo Counter Value + * + * This function configure the maximum counter value. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] counterValue : Maximum counter value + * \param[in] softWareTrigger : whether to enable softWare trigger + * - false : disable software trigger + * - true : enable software trigger + */ +extern void MftDrv_SetModuloCounterValue(MftDrvType *obj, uint16_t counterValue, bool softWareTrigger); + +/*! \brief Set Output level + * + * This function will set the channel edge or level on the selection + * of the channel mode. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] channel : channel number + * \param[in] level : the level or edge selection for channel mode. + */ +extern void MftDrv_SetOutputlevel(MftDrvType *obj, uint8_t channel, uint8_t level); + +/*! \brief Enable interrupts + * + * This function will enable the generation a list of interrupts. + * It includes the MFT overflow interrupts, the reload point interrupt, the fault + * interrupt and the channel (n) interrupt. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] interruptMask : interrupt Mask. This is the logical OR of members of the MftDrv_InterruptOptionType + */ +extern void MftDrv_EnableInterrupts(MftDrvType *obj, uint32_t interruptMask); + +/*! \brief Disable interrupts + * + * This function is used to disable some interrupts. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] interruptMask : interrupt Mask. This is the logical OR of members of the MftDrv_InterruptOptionType + */ +extern void MftDrv_DisableInterrupts(MftDrvType *obj, uint32_t interruptMask); + +/*! \brief Get enabled interrupts + * + * This function will get the enabled MFT interrupts. + * + * \param[in] obj : pointer to MFT driver instance + * \return The enabled interrupts. This is the logical OR of members of the MftDrv_InterruptOptionType + */ +extern uint32_t MftDrv_GetEnabledInterrupts(MftDrvType *obj); + +/*! \brief Get status flags + * + * This function will get the MFT status flags. + * + * \note Regarding the duty cycle is 100% at the channel output, the match interrupt + * has no event due to the C(n)V and C(n+1)V value are not between CNTIN value and MOD value. + * + * \param[in] obj : pointer to MFT driver instance + * \return The status flags. This is the logical OR of members of the MftDrv_StatusFlagType + */ +extern uint32_t MftDrv_GetStatusFlags(MftDrvType *obj); + +/*! \brief Clear status flags + * + * This function is used to clear the MFT status flags. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] flagMask : The status flags to clear. This is a logical OR of members of the MftDrv_StatusFlagType + */ +extern void MftDrv_ClearStatusFlags(MftDrvType *obj, uint32_t flagMask); + +/*! \brief Reset the counter + * + * This function will allow the MFT to restart the counter to + * its initial counting value in the register. + * + * \note The configuration is set in the MftDrv_SetSync() function to make + * sure that the MFT registers are updated by software trigger or hardware trigger. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] softwareTrigger : Selects the software trigger or hardware trigger to update COUNT register. + * - true: A software trigger is generate to update register + * - false: A software trigger is not implemented and need to update later or + * select a hardware trigger and waiting an external trigger for updating register. + */ +extern void MftDrv_CounterReset(MftDrvType *obj, bool softWareTrigger); + +/*! \brief Enables or disables the MFT dual edge capture mode. + * + * This function enables or disables the MFT dual edge capture mode. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] pairNum : The MFT peripheral channel pair number + * \param[in] enable : State of dual edge capture mode + * - true : To enable dual edge capture + * - false : To disable + */ +extern void MftDrv_SetDualEdgeCaptureCmd(MftDrvType *obj, uint8_t pairNum, bool enable); + +/*! \brief Enables or disables the MFT channel dual edge capture. + * + * This function enables or disables the MFT channel dual edge capture. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] pairNum : The MFT peripheral channel pair number + * \param[in] enable : State of dual edge capture mode + * - true : To enable dual edge capture + * - false : To disable + */ +extern void MftDrv_SetDualChannelDecap(MftDrvType *obj, uint8_t pairNum, bool enable); + +/*! \brief Enables or disables the MFT dual edge capture mode. + * + * This function enables or disables the MFT dual edge capture mode. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] pairNum : The MFT peripheral channel pair number + * \return Dual edge capture mode status + * - true : To enable dual edge capture + * - false: To disable + */ +extern bool MftDrv_GetDualEdgeCaptureCmd(MftDrvType *obj, uint8_t pairNum); + +/*! \brief Enables or disables the MFT complementary mode + * + * This function enables or disables the MFT complementary mode + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] pairNum : The MFT peripheral channel pair number + * \param[in] enable : State of complementary mode + * - true : To enable complementary + * - false : To disable + */ +extern void MftDrv_SetDualChannelComp(MftDrvType *obj, uint8_t pairNum, bool enable); + +/*! \brief Enables or disables the MFT combine mode + * + * This function enables or disables the MFT combine mode + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] pairNum : The MFT peripheral channel pair number + * \param[in] enable : State of combine mode + * - true : To enable combine + * - false : To disable + */ +extern void MftDrv_SetDualChannelCombine(MftDrvType *obj, uint8_t pairNum, bool enable); + +/*! \brief Enables or disables the MFT modified combine mode + * + * This function enables or disables the MFT modified combine mode + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] pairNum : The MFT peripheral channel pair number + * \param[in] enable : State of modified combine mode + * - true : To enable modified combine + * - false : To disable + */ +extern void MftDrv_SetDualChannelModifiedCombine(MftDrvType *obj, uint8_t pairNum, bool enable); + +/*! \brief Enables or disables the MFT dual channel fault + * + * This function enables or disables the MFT dual channel fault + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] pairNum : The MFT peripheral channel pair number + * \param[in] enable : State of dual channel fault + * - true : To enable dual channel fault + * - false : To disable + */ +extern void MftDrv_SetDualChannelFault(MftDrvType *obj, uint8_t pairNum, bool enable); + +/*! \brief Enables or disables the MFT dual channel PWM sync + * + * This function enables or disables the MFT dual channel PWM sync + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] pairNum : The MFT peripheral channel pair number + * \param[in] enable : State of dual channel PWM sync + * - true : To enable dual channel PWM sync + * - false : To disable + */ +extern void MftDrv_SetDualChannelPwmSync(MftDrvType *obj, uint8_t pairNum, bool enable); + +/*! \brief Enables or disables PWM channel Outputs + * + * This function enables or disables PWM channel Outputs + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] channel : The MFT peripheral channel number + * \param[in] enable : whether to enable PWM channel output + * - true : enable PWM channel output + * - false : disable PWM channel output + */ +extern void MftDrv_EnablePwmChannelOutputs(MftDrvType *obj, uint8_t channel, bool enable); + +/*! \brief Enables or disables the generation of the MFT peripheral timer channel trigger + * + * This function enables or disables the generation of the MFT peripheral timer channel trigger + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] channel : The MFT peripheral channel number + * \param[in] enable : State of trigger command + * - true : enable external trigger + * - false : disable external trigger + */ +extern void MftDrv_SetChannelTriggerCmd(MftDrvType *obj, uint8_t channel, bool enable); + +/*! \brief Sets the PWM Synchronization Software Trigger + * + * This function sets the PWM Synchronization Software Trigger + * + * \param[in] obj : pointer to MFT driver instance + */ +extern void MftDrv_SoftWareTrigger(MftDrvType *obj); + +/*! @}*/ + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _MFT_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_ch.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_ch.c new file mode 100644 index 0000000..e075780 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_ch.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "mft_oc_ch.h" +#include "mft_oc_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void MftOcCh_Init(MftOcChType *obj, struct _MftOcDrvType_ *ocDrv) +{ + obj->ocDrv = ocDrv; +} + +void MftOcCh_GetDefaultConfig(MftOcCh_ConfigType *userConfig) +{ + userConfig->hwChannelId = 0; /* Channel Id */ + userConfig->outputMode = MFTOCCH_TOGGLE_ON_MATCH; /* Output toggle on match */ + userConfig->enableExternalTrigger = false; /* Disable the generation of a trigger */ + userConfig->callbacksParams = NULL; /* Callback parameters for channel events */ + userConfig->callbackFunc = NULL; /* Callback function for channels events */ +} + +void MftOcCh_Config(MftOcChType *obj, const MftOcCh_ConfigType *userConfig) +{ + uint8_t hwChannel = 0U; + uint8_t chnlPairNum = 0U; + /* Check Channel Id */ + if(userConfig->hwChannelId >= MFT_CHANNEL_NUM) + { + return; + } + hwChannel = userConfig->hwChannelId; + + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->ocDrv->base->reg, 1); + + /* MSB:MSA = 0:1 set output compare mode*/ + MftReg_SetCscMsb(obj->ocDrv->base->reg, hwChannel, 0); + MftReg_SetCscMsa(obj->ocDrv->base->reg, hwChannel, 1); + + chnlPairNum = (uint8_t)(hwChannel >> 1U); + MftDrv_SetDualChannelComp(obj->ocDrv->base, chnlPairNum, false); + MftDrv_SetDualChannelCombine(obj->ocDrv->base, chnlPairNum, false); + MftDrv_SetDualEdgeCaptureCmd(obj->ocDrv->base, chnlPairNum, false); + /* Set Channel Output mode */ + MftDrv_SetOutputlevel(obj->ocDrv->base, hwChannel, userConfig->outputMode); + + /* Write initial count value for channel */ + MftReg_SetCvVal(obj->ocDrv->base->reg, hwChannel, userConfig->comparedValue); + /* Enable channel output */ + MftDrv_EnablePwmChannelOutputs(obj->ocDrv->base, hwChannel, true); + /* External trigger */ + MftDrv_SetChannelTriggerCmd(obj->ocDrv->base, hwChannel, userConfig->enableExternalTrigger); + /* Enable interrupt request for the current channel */ + MftReg_SetCscChie(obj->ocDrv->base->reg, userConfig->hwChannelId, 1); + + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->ocDrv->base->reg, 1); + + /* Remember the configuration */ + obj->config = *userConfig; +} + +void MftOcCh_Disarm(MftOcChType *obj) +{ + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->ocDrv->base->reg, 1); + + /* Clear combine mode */ + MftReg_SetCombineCombine0(obj->ocDrv->base->reg, 0); + MftReg_SetCombineCombine1(obj->ocDrv->base->reg, 0); + MftReg_SetCombineCombine2(obj->ocDrv->base->reg, 0); + MftReg_SetCombineCombine3(obj->ocDrv->base->reg, 0); + MftDrv_SetDualEdgeCaptureCmd(obj->ocDrv->base, obj->config.hwChannelId >> 1, false); + /* ELSnB:ELSnA = 0:0 (no edge) */ + MftReg_SetCscElsb(obj->ocDrv->base->reg, obj->config.hwChannelId, 0); + MftReg_SetCscElsa(obj->ocDrv->base->reg, obj->config.hwChannelId, 0); + /* Disable interrupt */ + MftReg_SetCscChie(obj->ocDrv->base->reg, obj->config.hwChannelId, 0); + /* Clear channel event flag */ + MftReg_SetCscChf(obj->ocDrv->base->reg, obj->config.hwChannelId, 0); + /* Disarm for channel (n+1) */ + /* ELSnB:ELSnA = 0:0 (no edge) */ + MftReg_SetCscElsb(obj->ocDrv->base->reg, (obj->config.hwChannelId | 1U), 0); + MftReg_SetCscElsa(obj->ocDrv->base->reg, (obj->config.hwChannelId | 1U), 0); + /* Disable interrupt */ + MftReg_SetCscChie(obj->ocDrv->base->reg, (obj->config.hwChannelId | 1U), 0); + /* Clear channel event flag */ + MftReg_SetCscChf(obj->ocDrv->base->reg, (obj->config.hwChannelId | 1U), 0); + + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->ocDrv->base->reg, 1); +} + +bool MftOcCh_UpdateOutputCompare(MftOcChType *obj, + uint16_t nextCompareMatchValue, + MftOcCh_OutputCompareUpdateType update, + bool softWareTrigger) +{ + bool retval = false; + uint16_t counterValue = MftReg_GetCntCount(obj->ocDrv->base->reg); + uint16_t compareValue = 0U; + uint16_t maxCounterValue = MftReg_GetModuloMod(obj->ocDrv->base->reg); + + if(update == MFTOCCH_RELATIVE_VALUE) + { + /* Configure channel compare register */ + if(nextCompareMatchValue > (maxCounterValue - counterValue)) + { + compareValue = (uint16_t)(nextCompareMatchValue - (maxCounterValue - counterValue)); + } + else + { + compareValue = (uint16_t)(counterValue + nextCompareMatchValue); + } + } + else + { + compareValue = nextCompareMatchValue; + } + /* Set CnV value and use software trigger for sync */ + MftReg_SetCvVal(obj->ocDrv->base->reg, obj->config.hwChannelId, compareValue); + MftReg_SetSyncSwSync(obj->ocDrv->base->reg, softWareTrigger); + return retval; +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_ch.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_ch.h new file mode 100644 index 0000000..22d6e81 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_ch.h @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MFT_OC_CH_H_ +#define _MFT_OC_CH_H_ + +/*! \brief Contains public interface to various functions related + * to the Output Compare channel of MFT + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup mft_oc_ch + * \ingroup mft_oc_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Selects mode operation int the output compare mode + */ +typedef enum +{ + MFTOCCH_DISABLE_OUTPUT = 0x00U, /*!< No action on output pin */ + MFTOCCH_TOGGLE_ON_MATCH = 0x01U, /*!< Toggle on match */ + MFTOCCH_CLEAR_ON_MATCH = 0x02U, /*!< Clear on match */ + MFTOCCH_SET_ON_MATCH = 0x03U /*!< Set on match */ +} MftOcCh_OutputCompareModeType; + +/*! \brief MFT output compare type of the next output compare value + */ +typedef enum +{ + MFTOCCH_RELATIVE_VALUE = 0x00U, /*!< Next compared value is relative to current value */ + MFTOCCH_ABSOLUTE_VALUE = 0x01U /*!< Next compared value is absolute */ +} MftOcCh_OutputCompareUpdateType; + +/*! \brief MFT driver output compare callback function prototype + */ +typedef void (*MftOcCh_CallbackType)(uint8_t event, void *params); + +/*! \brief MFT driver output compare parameters for each channel + */ +typedef struct _MftOcpCh_ConfigType_ +{ + uint8_t hwChannelId; /*!< Physical hardware channel ID*/ + MftOcCh_OutputCompareModeType outputMode; /*!< Channel output mode */ + uint16_t comparedValue; /*!< The compared value */ + bool enableExternalTrigger; /*!< true: enable the generation of a trigger is used for on-chip modules + * false: disable the generation of a trigger */ + void *callbacksParams; /*!< The parameters of callback functions for channels events */ + MftOcCh_CallbackType callbackFunc; /*!< The callback function for channels events */ +} MftOcCh_ConfigType; + +/* Forward declaration of MFT Output Compare driver */ +struct _MftOcDrvType_; + +/*! \brief The definition of MFT output compare channel prototype + */ +typedef struct _MftOcChType_ +{ + struct _MftOcDrvType_ *ocDrv; + MftOcCh_ConfigType config; +} MftOcChType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the MFT OC channel + * + * This function initializes MFT OC channel + * + * \param[in] obj : pointer to MFT OC channel instance + * \param[in] base : pointer to MFT driver instance + */ +extern void MftOcCh_Init(MftOcChType *obj, struct _MftOcDrvType_ *capDrv); + +/*! \brief Get default configuration of the MFT output compare channel + * + * This function gets default configures the MFT output compare module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void MftOcCh_GetDefaultConfig(MftOcCh_ConfigType *userConfig); + +/*! \brief Configure the MFT output compare channel + * + * This function configures the channel in the output compare mode for generate timed pulses. + * When the MFT counter matches the value of CnV, the channel output is changed based on what + * is specified in the output mode argument. + * + * \param[in] obj : pointer to MFT CAP channel instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void MftOcCh_Config(MftOcChType *obj, const MftOcCh_ConfigType *userConfig); + +/*! \brief Disarm the MFT Output Compare channel + * + * This function disables output compare mode and clears MFT timer configuration + * + * \param[in] obj : pointer to MFT OC channel instance + */ +extern void MftOcCh_Disarm(MftOcChType *obj); + +/*! \brief Sets the next compare match value based on the current counter value + * + * \param[in] obj : pointer to MFT OC channel instance + * \param[in] nextCompareMatchValue : Timer value in ticks until the next compare match event should appear + * \param[in] update : + * - MFTOCCH_RELATIVE_VALUE : nextComparemantchValue will be added to current counter value + * - MFTOCCH_ABSOLUTE_VALUE : nextComparemantchValue will be written in counter register as it is + * \param[in] softwareTrigger : This parameter will be true if software trigger sync is enabled and the user + * want to generate a software trigger (the value from buffer will be moved to register immediate or at next + * loading point depending on the sync configuration). Otherwise this parameter must be false and the next + * compared value will be stored in buffer untill a trigger signal will be received. + */ +extern bool MftOcCh_UpdateOutputCompare(MftOcChType *obj, + uint16_t nextCompareMatchValue, + MftOcCh_OutputCompareUpdateType update, + bool softwareTrigger); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _MFT_OC_CH_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_drv.c new file mode 100644 index 0000000..d767650 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_drv.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "mft_oc_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void MftOcDrv_Init(MftOcDrvType *obj, MftDrvType *base) +{ + obj->base = base; + + uint8_t i = 0; + for(i = 0; i < MFT_CHANNEL_NUM; ++i) + { + MftOcCh_Init(&obj->channel[i], obj); + } +} + +void MftOcDrv_GetDefaultConfig(MftOcDrv_ConfigType *userConfig) +{ + userConfig->maxCountValue = 65535; +} + +void MftOcDrv_Config(MftOcDrvType *obj, const MftOcDrv_ConfigType *userConfig) +{ + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->base->reg, 1); + + /* CNTIN = 0 */ + MftReg_SetCntInCntInit(obj->base->reg, 0U); + /* Set MOD */ + MftReg_SetModuloMod(obj->base->reg, userConfig->maxCountValue); + + /* Configure sync for OUTMASK register */ + MftReg_SetSynConfSwOM(obj->base->reg, 1); + /* Configure sync for INVCTRL register */ + MftReg_SetSynConfSwInvC(obj->base->reg, 1); + /* Configure sync for SWOCTRL register */ + MftReg_SetSynConfSwSoc(obj->base->reg, 1); + /* Configure sync for MOD, HCR, CNTIN, and CnV registers */ + MftReg_SetSynConfSwWrbuf(obj->base->reg, 1); + /* Configure synchronization method (waiting next loading point or now) */ + MftReg_SetSynConfSwRstCnt(obj->base->reg, 1); + /* Enhanced PWM sync is used */ + MftReg_SetSynConfSyncMode(obj->base->reg, 1); + /* Configure sync for CNTIN register updated with its buffer value at system_clock*/ + MftReg_SetSynConfCntInC(obj->base->reg, 0); + + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->base->reg, 1); +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_drv.h new file mode 100644 index 0000000..ec420cf --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_oc/mft_oc_drv.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MFT_OC_DRV_H_ +#define _MFT_OC_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the Output Compare driver of MFT + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../mft_drv.h" +#include "mft_oc_ch.h" + +/*! \addtogroup mft_oc_drv + * \ingroup mft_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +/*! \brief MFT Output compare driver configuration + */ +typedef struct _MftOcDrv_ConfigType_ +{ + uint16_t maxCountValue; /*!< Maximum counter value. Minimum value is 0 for this mode */ +} MftOcDrv_ConfigType; + +/*! \brief The definition of MFT output compare driver prototype + * \details Derived from MFT driver + */ +typedef struct _MftOcDrvType_ +{ + MftDrvType *base; /*!< base class of capture driver */ + MftOcChType channel[MFT_CHANNEL_NUM]; /*!< channels of the capture mode */ +} MftOcDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the MFT OC module + * + * This function initializes MFT OC driver by setting the MFT driver + * instance to it. + * + * \param[in] obj : pointer to MFT OC channel instance + * \param[in] base : pointer to MFT driver instance + */ +extern void MftOcDrv_Init(MftOcDrvType *obj, MftDrvType *base); + +/*! \brief Get default configures the MFT output compare module for configuration structure + * + * This function gets default configures the MFT output compare module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void MftOcDrv_GetDefaultConfig(MftOcDrv_ConfigType *userConfig); + +/*! \brief Configure the MFT output compare module + * + * This function configures the MFT output compare module. + * + * \param[in] obj : pointer to MFT OC channel instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void MftOcDrv_Config(MftOcDrvType *obj, const MftOcDrv_ConfigType *userConfig); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _MFT_OC_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_ch.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_ch.c new file mode 100644 index 0000000..edb0a11 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_ch.c @@ -0,0 +1,353 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "mft_pwm_ch.h" +#include "mft_pwm_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +/*! \brief Set the polarity of the channel + * + * This function sets the polarity of the channel + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] channel : The MFT peripheral channel number + * \param[in] polarity : the polarity of the channel + */ +static inline void MftPwmCh_SetPolarity(MftPwmChType *obj, uint8_t channel, MftPwmCh_PolarityType polarity) +{ + switch(channel) + { + case 0: + MftReg_SetPolPol0(obj->pwmDrv->base->reg, (uint8_t)polarity); + break; + case 1: + MftReg_SetPolPol1(obj->pwmDrv->base->reg, (uint8_t)polarity); + break; + case 2: + MftReg_SetPolPol2(obj->pwmDrv->base->reg, (uint8_t)polarity); + break; + case 3: + MftReg_SetPolPol3(obj->pwmDrv->base->reg, (uint8_t)polarity); + break; + case 4: + MftReg_SetPolPol4(obj->pwmDrv->base->reg, (uint8_t)polarity); + break; + case 5: + MftReg_SetPolPol5(obj->pwmDrv->base->reg, (uint8_t)polarity); + break; + case 6: + MftReg_SetPolPol6(obj->pwmDrv->base->reg, (uint8_t)polarity); + break; + case 7: + MftReg_SetPolPol7(obj->pwmDrv->base->reg, (uint8_t)polarity); + break; + default: + break; + } +} + +/*! \brief Enables or disables PWM channel pair deadtime insertion. + * + * This function enables or disables PWM channel pair deadtime insertion. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] pairNum : The MFT peripheral channel number + * \param[in] enable : whether to enable PWM channel pair deadtime insertion. + * - true : enable PWM channel pair deadtime insertion. + * - false : disable PWM channel pair deadtime insertion. + */ +static inline void MftPwmCh_SetDualChannelDeadtimeCmd(MftPwmChType *obj, uint8_t pairNum, bool enable) +{ + uint8_t enableValue = enable ? 1 : 0; + switch(pairNum) + { + case 0: + MftReg_SetCombineDtEn0(obj->pwmDrv->base->reg, enableValue); + break; + case 1: + MftReg_SetCombineDtEn1(obj->pwmDrv->base->reg, enableValue); + break; + case 2: + MftReg_SetCombineDtEn2(obj->pwmDrv->base->reg, enableValue); + break; + case 3: + MftReg_SetCombineDtEn3(obj->pwmDrv->base->reg, enableValue); + break; + default: + break; + } +} + +void MftPwmCh_Init(MftPwmChType *obj, struct _MftPwmDrvType_ *pwmDrv) +{ + obj->pwmDrv = pwmDrv; +} + +void MftPwmCh_GetDefaultConfig(MftPwmCh_ConfigType *userConfig) +{ + userConfig->hwChannelId = 0; + userConfig->pulseMode = MFTPWMCH_SET_ON_MATCH_UP; + userConfig->mainChannelPolarity = MFTPWMCH_ACTIVE_HIGH; + userConfig->enableExternalTrigger = false; + userConfig->enableFaultCtrl = false; + userConfig->enableSecondChannelOutput = false; + userConfig->enableComplementary = false; + userConfig->enableCombine = false; + userConfig->enableModifiedCombine = false; + userConfig->deadTime = false; + userConfig->secondChannelPolarity = MFTPWMCH_ACTIVE_HIGH; + userConfig->enableExternalTriggerOnNextChn = false; +} + +bool MftPwmCh_Config(MftPwmChType *obj, const MftPwmCh_ConfigType *userConfig) +{ + bool status = true; + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->pwmDrv->base->reg, 1); + + obj->config.hwChannelId = userConfig->hwChannelId; + /* MSB:MSA = 1:1 */ + MftReg_SetCscMsb(obj->pwmDrv->base->reg, obj->config.hwChannelId, 1); + MftReg_SetCscMsa(obj->pwmDrv->base->reg, obj->config.hwChannelId, 1); + + if(false == userConfig->enableSecondChannelOutput) + { + /* Independent channel */ + /* Set Polarity */ + MftPwmCh_SetPolarity(obj, userConfig->hwChannelId, userConfig->mainChannelPolarity); + /* Set pulse mode */ + if(MFTPWMCH_CLEAR_ON_MATCH_UP == userConfig->pulseMode) + { + /* ELSnB:ELSnA = 1:0 */ + MftReg_SetCscElsb(obj->pwmDrv->base->reg, userConfig->hwChannelId, 1); + MftReg_SetCscElsa(obj->pwmDrv->base->reg, userConfig->hwChannelId, 0); + } + else if(MFTPWMCH_SET_ON_MATCH_UP == userConfig->pulseMode) + { + /* ELSnB:ELSnA = 0:1 */ + MftReg_SetCscElsb(obj->pwmDrv->base->reg, userConfig->hwChannelId, 0); + MftReg_SetCscElsa(obj->pwmDrv->base->reg, userConfig->hwChannelId, 1); + } + uint8_t pairNum = userConfig->hwChannelId >> 1; + /* COMP = 0 */ + MftDrv_SetDualChannelComp(obj->pwmDrv->base, pairNum, false); + /* COMBINE = 0 */ + MftDrv_SetDualChannelCombine(obj->pwmDrv->base, pairNum, false); + /* MCOMBINE = 0 */ + MftDrv_SetDualChannelModifiedCombine(obj->pwmDrv->base, pairNum, false); + /* DECAP = 0 */ + MftDrv_SetDualChannelDecap(obj->pwmDrv->base, pairNum, false); + /* FAULTEN */ + MftDrv_SetDualChannelFault(obj->pwmDrv->base, pairNum, userConfig->enableFaultCtrl); + /* PWMSYNC */ + MftDrv_SetDualChannelPwmSync(obj->pwmDrv->base, pairNum, true); + /* External trigger */ + MftDrv_SetChannelTriggerCmd(obj->pwmDrv->base, userConfig->hwChannelId, userConfig->enableExternalTrigger); + /* Enable PWM output on channel (n) */ + MftDrv_EnablePwmChannelOutputs(obj->pwmDrv->base, userConfig->hwChannelId, true); + } + else + { + if(userConfig->hwChannelId % 2 != 0) + { + /* Must be even */ + return false; + } + /* MSB:MSA = 1:1 */ + MftReg_SetCscMsb(obj->pwmDrv->base->reg, userConfig->hwChannelId + 1, 1); + MftReg_SetCscMsa(obj->pwmDrv->base->reg, userConfig->hwChannelId + 1, 1); + + /* Dual channel modes */ + uint8_t pairNum = userConfig->hwChannelId >> 1; + /* DECAP = 0 */ + MftDrv_SetDualChannelDecap(obj->pwmDrv->base, pairNum, false); + /* PWMSYNC */ + MftDrv_SetDualChannelPwmSync(obj->pwmDrv->base, pairNum, true); + /* Set Polarity */ + MftPwmCh_SetPolarity(obj, userConfig->hwChannelId, userConfig->mainChannelPolarity); + MftPwmCh_SetPolarity(obj, userConfig->hwChannelId + 1, userConfig->secondChannelPolarity); + /* External trigger */ + MftDrv_SetChannelTriggerCmd(obj->pwmDrv->base, userConfig->hwChannelId, userConfig->enableExternalTrigger); + MftDrv_SetChannelTriggerCmd(obj->pwmDrv->base, userConfig->hwChannelId + 1, userConfig->enableExternalTriggerOnNextChn); + /* Enable PWM output on channel (n) and channel (n+1) */ + MftDrv_EnablePwmChannelOutputs(obj->pwmDrv->base, userConfig->hwChannelId, true); + MftDrv_EnablePwmChannelOutputs(obj->pwmDrv->base, userConfig->hwChannelId + 1, true); + /* FAULTEN */ + MftDrv_SetDualChannelFault(obj->pwmDrv->base, pairNum, userConfig->enableFaultCtrl); + if(true == userConfig->enableComplementary) + { + /* Complementary Mode, this configure has higher priority than combined/mcombined mode */ + /* COMP = 1 */ + MftDrv_SetDualChannelComp(obj->pwmDrv->base, pairNum, true); + + /* MCOMBINE = 0 */ + MftDrv_SetDualChannelModifiedCombine(obj->pwmDrv->base, pairNum, false); + /* Dead time */ + MftPwmCh_SetDualChannelDeadtimeCmd(obj, pairNum, userConfig->deadTime); + + if(MftReg_GetScCPwms(obj->pwmDrv->base->reg)) + { + /* COMBINE = 0 */ + MftDrv_SetDualChannelCombine(obj->pwmDrv->base, pairNum, false); + /* Set pulse mode */ + if(MFTPWMCH_CLEAR_ON_MATCH_UP == userConfig->pulseMode) + { + /* ELSnB:ELSnA = 1:0 */ + /* ELSnB:ELSnA of channel (n+1) not used */ + MftReg_SetCscElsb(obj->pwmDrv->base->reg, userConfig->hwChannelId, 1); + MftReg_SetCscElsa(obj->pwmDrv->base->reg, userConfig->hwChannelId, 0); + } + else if(MFTPWMCH_SET_ON_MATCH_UP == userConfig->pulseMode) + { + /* ELSnB:ELSnA = 0:1 */ + /* ELSnB:ELSnA of channel (n+1) not used */ + MftReg_SetCscElsb(obj->pwmDrv->base->reg, userConfig->hwChannelId, 0); + MftReg_SetCscElsa(obj->pwmDrv->base->reg, userConfig->hwChannelId, 1); + } + } + else + { + /* COMBINE = 1 */ + MftDrv_SetDualChannelCombine(obj->pwmDrv->base, pairNum, true); + + /* Set pulse mode */ + if(MFTPWMCH_SET_ON_MATCH_UP == userConfig->pulseMode) + { + /* ELSnB:ELSnA = 1:0 */ + /* ELSnB:ELSnA of channel (n+1) not used */ + MftReg_SetCscElsb(obj->pwmDrv->base->reg, userConfig->hwChannelId, 1); + MftReg_SetCscElsa(obj->pwmDrv->base->reg, userConfig->hwChannelId, 0); + } + else if(MFTPWMCH_CLEAR_ON_MATCH_UP == userConfig->pulseMode) + { + /* ELSnB:ELSnA = 0:1 */ + /* ELSnB:ELSnA of channel (n+1) not used */ + MftReg_SetCscElsb(obj->pwmDrv->base->reg, userConfig->hwChannelId, 0); + MftReg_SetCscElsa(obj->pwmDrv->base->reg, userConfig->hwChannelId, 1); + } + } + } + else if(false == userConfig->enableModifiedCombine + && true == userConfig->enableCombine) + { + if(MftReg_GetScCPwms(obj->pwmDrv->base->reg)) + { + /* CPWM does not support Combine mode*/ + status = false; + } + else + { + /* Combine Mode */ + /* COMP = 0 */ + MftDrv_SetDualChannelComp(obj->pwmDrv->base, pairNum, false); + /* COMBINE = 1 */ + MftDrv_SetDualChannelCombine(obj->pwmDrv->base, pairNum, true); + /* MCOMBINE = 0 */ + MftDrv_SetDualChannelModifiedCombine(obj->pwmDrv->base, pairNum, false); + /* Set pulse mode */ + if(MFTPWMCH_SET_ON_MATCH_UP == userConfig->pulseMode) + { + /* ELSnB:ELSnA = 1:0 */ + /* ELSnB:ELSnA of channel (n+1) not used */ + MftReg_SetCscElsb(obj->pwmDrv->base->reg, userConfig->hwChannelId, 1); + MftReg_SetCscElsa(obj->pwmDrv->base->reg, userConfig->hwChannelId, 0); + } + else if(MFTPWMCH_CLEAR_ON_MATCH_UP == userConfig->pulseMode) + { + /* ELSnB:ELSnA = 0:1 */ + /* ELSnB:ELSnA of channel (n+1) not used */ + MftReg_SetCscElsb(obj->pwmDrv->base->reg, userConfig->hwChannelId, 0); + MftReg_SetCscElsa(obj->pwmDrv->base->reg, userConfig->hwChannelId, 1); + } + } + } + else if(true == userConfig->enableModifiedCombine + && true == userConfig->enableCombine) + { + if(MftReg_GetScCPwms(obj->pwmDrv->base->reg)) + { + /* CPWM does not support Combine mode */ + status = false; + } + else + { + /* Modified combine Mode */ + /* COMP = 0 */ + MftDrv_SetDualChannelComp(obj->pwmDrv->base, pairNum, false); + /* COMBINE = 1 */ + MftDrv_SetDualChannelCombine(obj->pwmDrv->base, pairNum, true); + /* MCOMBINE = 1 */ + MftDrv_SetDualChannelModifiedCombine(obj->pwmDrv->base, pairNum, true); + /* Set pulse mode */ + if(MFTPWMCH_SET_ON_MATCH_UP == userConfig->pulseMode) + { + /* ELSnB:ELSnA = 1:0 */ + /* ELSnB:ELSnA of channel (n+1) not used */ + MftReg_SetCscElsb(obj->pwmDrv->base->reg, userConfig->hwChannelId, 1); + MftReg_SetCscElsa(obj->pwmDrv->base->reg, userConfig->hwChannelId, 0); + } + else if(MFTPWMCH_CLEAR_ON_MATCH_UP == userConfig->pulseMode) + { + /* ELSnB:ELSnA = 0:1 */ + /* ELSnB:ELSnA of channel (n+1) not used */ + MftReg_SetCscElsb(obj->pwmDrv->base->reg, userConfig->hwChannelId, 0); + MftReg_SetCscElsa(obj->pwmDrv->base->reg, userConfig->hwChannelId, 1); + } + } + } + } + + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->pwmDrv->base->reg, 1); + + obj->config = *userConfig; + + return status; +} + +void MftPwmCh_SetChannelValue(MftPwmChType *obj, uint16_t firstValue, uint16_t secondValue) +{ + MftReg_SetCvVal(obj->pwmDrv->base->reg, obj->config.hwChannelId, firstValue); + if(obj->config.enableSecondChannelOutput) + { + MftReg_SetCvVal(obj->pwmDrv->base->reg, obj->config.hwChannelId + 1, secondValue); + } +} + +void MftPwmCh_EnableOutput(MftPwmChType *obj, bool enable) +{ + MftDrv_EnablePwmChannelOutputs(obj->pwmDrv->base, obj->config.hwChannelId, enable); +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_ch.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_ch.h new file mode 100644 index 0000000..872c614 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_ch.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MFT_PWM_CH_H_ +#define _MFT_PWM_CH_H_ + +/*! \brief Contains public interface to various functions related + * to the PWM output channel of MFT + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup mft_pwm_ch + * \ingroup mft_pwm_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The polarity of the channel output is configured in PWM signal + */ +typedef enum +{ + MFTPWMCH_ACTIVE_HIGH = 0x00U, /*!< The channel polarity is active HIGH */ + MFTPWMCH_ACTIVE_LOW = 0x01U /*!< The channel polarity is active LOW */ +} MftPwmCh_PolarityType; + +/*! \brief The pulse mode of PWM + */ +typedef enum +{ + MFTPWMCH_SET_ON_MATCH_UP, /*!< The channel set when counter matches CV in up-counting */ + MFTPWMCH_CLEAR_ON_MATCH_UP /*!< The channel clear when counter matches CV in up-counting */ +} MftPwmCh_PulseModeType; + +/*! \brief MFT driver combined PWM parameter + */ +typedef struct +{ + /* Independent channel configuration */ + uint8_t hwChannelId; /*!< Physical hardware channel ID for channel (n) */ + MftPwmCh_PulseModeType pulseMode; /*!< The mode of pulse */ + MftPwmCh_PolarityType mainChannelPolarity; /*!< Polarity of the PWM signal generated on MCU pin for channel n.*/ + bool enableExternalTrigger; /*!< The generation of the channel (n) trigger */ + bool enableFaultCtrl; /*!< Enable/disable fault control for this pair */ + /* Dual channels configuration */ + bool enableSecondChannelOutput; /*!< Select if channel (n+1) output is enabled/disabled for the complementary mode */ + bool enableComplementary; /*!< Enable the complementary mode for channels (n) and (n+1) */ + bool enableCombine; /*!< Enable the combine mode for channels (n) and (n+1) */ + bool enableModifiedCombine; /*!< Enable the modified combine mode for channels (n) and (n+1) */ + bool deadTime; /*!< Enable/disable dead time for channel */ + MftPwmCh_PolarityType secondChannelPolarity; /*!< Select channel (n+1) polarity relative to channel (n) in the complementary mode */ + bool enableExternalTriggerOnNextChn; /*!< The generation of the channel (n+1) trigger */ +} MftPwmCh_ConfigType; + +/* Forward declaration of MFT PWM driver */ +struct _MftPwmDrvType_; + +/*! \brief The definition of MFT PWM channel prototype + */ +typedef struct _MftPwmChType_ +{ + struct _MftPwmDrvType_ *pwmDrv; /*!< pointer to the PWM driver instance */ + MftPwmCh_ConfigType config; /*!< configuration of this channel */ +} MftPwmChType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the MFT PWM channel + * + * This function initializes MFT PWM channel. + * + * \param[in] obj : pointer to MFT PWM channel instance + * \param[in] base : pointer to MFT driver instance + */ +extern void MftPwmCh_Init(MftPwmChType *obj, struct _MftPwmDrvType_ *pwmDrv); + +/*! \brief Get default configures the MFT PWM module for configuration structure + * + * This function gets default configures the MFT PWM module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void MftPwmCh_GetDefaultConfig(MftPwmCh_ConfigType *userConfig); + +/*! \brief Configure the MFT PWM channel + * + * This function configures the channel in the PWM mode. The channel can + * be both independent mode or combined mode. + * + * \param[in] obj : pointer to MFT PWM channel instance + * \param[in] userConfig : pointer to configuration structure + * \return The result of the operation + * - true : success + * - false : failed + */ +extern bool MftPwmCh_Config(MftPwmChType *obj, const MftPwmCh_ConfigType *userConfig); + +/*! \brief Set the MFT PWM channel value + * + * This function set the MFT channel value. + * + * \note If the channel is independent, the second value has no effect. + * If the channel is in complementary mode, the second value also + * has no effect. + * + * \param[in] obj : pointer to MFT PWM channel instance + * \param[in] firstValue : the value of first channel + * \param[in] secondValue : the value of second channel + * if the first channel is independent, this value has no effect + */ +extern void MftPwmCh_SetChannelValue(MftPwmChType *obj, uint16_t firstValue, uint16_t secondValue); + +/*! \brief Enables or disables the channel output + * + * This function enables or disables the channel output + * + * \param[in] obj : pointer to MFT PWM channel instance + * \param[in] enable : whether to enable channel output + * - true : enable PWM output + * - false : disable PWM output + */ +extern void MftPwmCh_EnableOutput(MftPwmChType *obj, bool enable); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _MFT_PWM_CH_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_drv.c new file mode 100644 index 0000000..acf79b0 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_drv.c @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "mft_pwm_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +/*! \brief This function configures sync mechanism for some MFT registers + * + * This function configure the synchronization for PWM register (CnV, MOD, CINT, HCR, OUTMASK). + * If this function is used whit wrong parameters it's possible to generate wrong waveform. + * Registers synchronization need to be configured for PWM and output compare mode. + * + * \param[in] obj : pointer to MFT driver instance + * \param[in] param : pwm sync config + * \return The result of the operation + * - true : success + * - false : failed + */ +bool MftPwmDrv_SetSync(MftPwmDrvType *obj, const MftPwmDrv_SyncType *param) +{ + bool hardwareSync = param->hardwareSync0 || param->hardwareSync1 || param->hardwareSync2; + + /* Software and hardware triggers are not allowed in the same time */ + if((param->softwareSync && hardwareSync) || (true != (param->softwareSync || hardwareSync))) + { + return false; + } + + if(param->softwareSync) + { + /* Configure sync for OUTMASK register */ + MftReg_SetSynConfSwOM(obj->base->reg, 1); + /* Configure sync for INVCTRL register */ + MftReg_SetSynConfSwInvC(obj->base->reg, 1); + /* Configure sync for SWOCTRL register */ + MftReg_SetSynConfSwSoc(obj->base->reg, 1); + /* Configure sync for MOD, HCR, CNTIN, and CnV registers */ + MftReg_SetSynConfSwWrbuf(obj->base->reg, 1); + /* Configure synchronization method (waiting next loading point or now) */ + MftReg_SetSynConfSwRstCnt(obj->base->reg, param->syncPoint); + } + else + { + /* Configure sync for OUTMASK register */ + MftReg_SetSynConfHwOM(obj->base->reg, 1); + /* Configure sync for INVCTRL register */ + MftReg_SetSynConfHwInvC(obj->base->reg, 1); + /* Configure sync for SWOCTRL register */ + MftReg_SetSynConfHwSoc(obj->base->reg, 1); + /* Configure sync for MOD, HCR, CNTIN, and CnV registers */ + MftReg_SetSynConfHwWrbuf(obj->base->reg, 1); + /* Configure synchronization method (waiting next loading point or now) */ + MftReg_SetSynConfHwRstCnt(obj->base->reg, param->syncPoint); + } + + /* Enhanced PWM sync is used */ + MftReg_SetSynConfSyncMode(obj->base->reg, 1); + /* Configure trigger source for sync */ + MftReg_SetSyncTrig0(obj->base->reg, param->hardwareSync0 ? 1 : 0); + MftReg_SetSyncTrig1(obj->base->reg, param->hardwareSync1 ? 1 : 0); + MftReg_SetSyncTrig2(obj->base->reg, param->hardwareSync2 ? 1 : 0); + /* Configure loading points */ + MftReg_SetSyncCntMax(obj->base->reg, param->maxLoadingPoint); + MftReg_SetSyncCntMin(obj->base->reg, param->minLoadingPoint); + /* Configure sync for OUTMASK register */ + MftReg_SetSyncSynchOM(obj->base->reg, (bool)param->maskRegSync); + /* Configure sync for INVCTRL register */ + MftReg_SetSynConfInvC(obj->base->reg, param->inverterSync); + /* Configure sync for SWOCTRL register */ + MftReg_SetSynConfSwOC(obj->base->reg, param->outRegSync); + /* Configure sync for CNTIN register */ + MftReg_SetSynConfCntInC(obj->base->reg, param->initCounterSync); + /* Configure hardware trigger mode */ + MftReg_SetSynConfHwTrigMode(obj->base->reg, param->autoClearTrigger); + + return true; +} + +void MftPwmDrv_Init(MftPwmDrvType *obj, MftDrvType *base) +{ + obj->base = base; + + uint8_t i = 0; + for(i = 0; i < MFT_CHANNEL_NUM; ++i) + { + MftPwmCh_Init(&obj->channel[i], obj); + } +} + +void MftPwmDrv_GetDefaultConfig(MftPwmDrv_ConfigType *userConfig) +{ + userConfig->periodValue = 65536; + + userConfig->syncMethod.softwareSync = true; + userConfig->syncMethod.hardwareSync0 = false; + userConfig->syncMethod.hardwareSync1 = false; + userConfig->syncMethod.hardwareSync2 = false; + userConfig->syncMethod.maxLoadingPoint = false; + userConfig->syncMethod.minLoadingPoint = false; + userConfig->syncMethod.inverterSync = MFTPWMDRV_SYSTEM_CLOCK; + userConfig->syncMethod.outRegSync = MFTPWMDRV_SYSTEM_CLOCK; + userConfig->syncMethod.maskRegSync = MFTPWMDRV_SYSTEM_CLOCK; + userConfig->syncMethod.initCounterSync = MFTPWMDRV_SYSTEM_CLOCK; + userConfig->syncMethod.autoClearTrigger = true; + userConfig->syncMethod.syncPoint = MFTPWMDRV_WAIT_LOADING_POINTS; + + userConfig->faultConfig.enableTriStateOnFault = false; + userConfig->faultConfig.faultFilterValue = 0; + userConfig->faultConfig.faultMode = MFTPWMDRV_FAULT_CTRL_DISABLED; + uint8_t i = 0; + for(i = 0; i < MFT_FAULT_INPUT_NUM; ++i) + { + userConfig->faultConfig.faultInput[i].enabled = false; + userConfig->faultConfig.faultInput[i].filterEnabled = false; + userConfig->faultConfig.faultInput[i].inputPolarity = MFTPWMDRV_FAULT_ACTIVE_HIGH; + } + + userConfig->deadTimeCount = 0; + userConfig->deadTimePrescaler = MFTPWMDRV_DEADTIME_DIVID_BY_1; +} + +void MftPwmDrv_Config(MftPwmDrvType *obj, const MftPwmDrv_ConfigType *userConfig) +{ + /* Configure MFT PWM module */ + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->base->reg, 1); + + /* In PWM mode CNTIN is to be set 0*/ + MftReg_SetCntInCntInit(obj->base->reg, 0U); + /* Set period */ + MftReg_SetModuloMod(obj->base->reg, userConfig->periodValue); + /* Sync config */ + MftPwmDrv_SetSync(obj, &userConfig->syncMethod); + + /* Enable faults (if faults were configured) */ + if(userConfig->faultConfig.faultMode != MFTPWMDRV_FAULT_CTRL_DISABLED) + { + /* Configure PWM Output behavior */ + MftReg_SetFltCtrlFstate(obj->base->reg, userConfig->faultConfig.enableTriStateOnFault ? 1 : 0); + /* Configure fault filter value */ + MftReg_SetFltCtrlFFVal(obj->base->reg, userConfig->faultConfig.faultFilterValue); + uint8_t i = 0; + for(i = 0; i < MFT_FAULT_INPUT_NUM; ++i) + { + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(i) + { + case 0: + MftReg_SetFltCtrlFault0En(obj->base->reg, userConfig->faultConfig.faultInput[0].enabled ? 1 : 0); + MftReg_SetFltCtrlFFltr0En(obj->base->reg, userConfig->faultConfig.faultInput[0].filterEnabled ? 1 : 0); + MftReg_SetFltPolFlt0Pol(obj->base->reg, userConfig->faultConfig.faultInput[0].inputPolarity); + break; + case 1: + MftReg_SetFltCtrlFault1En(obj->base->reg, userConfig->faultConfig.faultInput[1].enabled ? 1 : 0); + MftReg_SetFltCtrlFFltr1En(obj->base->reg, userConfig->faultConfig.faultInput[1].filterEnabled ? 1 : 0); + MftReg_SetFltPolFlt1Pol(obj->base->reg, userConfig->faultConfig.faultInput[1].inputPolarity); + break; + case 2: + MftReg_SetFltCtrlFault2En(obj->base->reg, userConfig->faultConfig.faultInput[2].enabled ? 1 : 0); + MftReg_SetFltCtrlFFltr2En(obj->base->reg, userConfig->faultConfig.faultInput[2].filterEnabled ? 1 : 0); + MftReg_SetFltPolFlt2Pol(obj->base->reg, userConfig->faultConfig.faultInput[2].inputPolarity); + break; + case 3: + MftReg_SetFltCtrlFault3En(obj->base->reg, userConfig->faultConfig.faultInput[3].enabled ? 1 : 0); + MftReg_SetFltCtrlFFltr3En(obj->base->reg, userConfig->faultConfig.faultInput[3].filterEnabled ? 1 : 0); + MftReg_SetFltPolFlt3Pol(obj->base->reg, userConfig->faultConfig.faultInput[3].inputPolarity); + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + } + MftReg_SetModeFaultM(obj->base->reg, userConfig->faultConfig.faultMode); + } + + MftReg_SetDeadTimeDtPs(obj->base->reg, userConfig->deadTimePrescaler); + MftReg_SetDeadTimeDtVal(obj->base->reg, userConfig->deadTimeCount); + + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->base->reg, 1); +} + +void MftPwmDrv_SetInitOutputCmd(MftPwmDrvType *obj, bool enable) +{ + /* Set enable outputs to be set to Initial/default value */ + MftReg_SetModeInit(obj->base->reg, 1); +} + +void MftPwmDrv_SetPeriod(MftPwmDrvType *obj, uint16_t value) +{ + MftReg_SetModuloMod(obj->base->reg, value); +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_drv.h new file mode 100644 index 0000000..8bf4801 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_pwm/mft_pwm_drv.h @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MFT_PWM_DRV_H_ +#define _MFT_PWM_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the PWM driver of MFT + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../mft_drv.h" +#include "mft_pwm_ch.h" + +/*! \addtogroup mft_pwm_drv + * \ingroup mft_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief MFT fault control mode + */ +typedef enum +{ + MFTPWMDRV_FAULT_CTRL_DISABLED = 0x00U, /*!< Fault control is disabled for all channels */ + MFTPWMDRV_FAULT_CTRL_MAN_EVEN = 0x01U, /*!< Fault control is enabled for even channels + * only (channels 0, 2, 4, and 6), and the selected + * mode is the manual fault clearing */ + MFTPWMDRV_FAULT_CTRL_MAN_ALL = 0x02U, /*!< Fault control is enabled for all channels, + * and the selected mode is the manual fault clearing */ + MFTPWMDRV_FAULT_CTRL_AUTO_ALL = 0x03U /*!< Fault control is enabled for all channels, and + * the selected mode is the automatic fault clearing */ +} MftPwmDrv_FaultModeType; + +/*! \brief MFT PWM Fault channel polarity + */ +typedef enum +{ + MFTPWMDRV_FAULT_ACTIVE_HIGH = 0x00U, /*!< The fault occurs on the input (n) when it's HIGH, the input is LOW when no fault */ + MFTPWMDRV_FAULT_ACTIVE_LOW = 0x01U /*!< The fault occurs on the input (n) when it's LOW, the input is HIGH when no fault */ +} MftPwmDrv_FaultChannelPolarityType; + +/*! \brief MFT PWM Fault channel parameters + */ +typedef struct +{ + bool enabled; /*!< Fault channel state */ + bool filterEnabled; /*!< Fault channel filter state */ + MftPwmDrv_FaultChannelPolarityType inputPolarity; /*!< Fault channel input polarity */ +} MftPwmDrv_FaultChannelConfigType; + +/*! \brief FlexTimer driver PWM Fault parameter + */ +typedef struct +{ + bool enableTriStateOnFault; /*!< Output pin state on fault (safe state or tri-state) */ + uint8_t faultFilterValue; /*!< Fault filter value */ + MftPwmDrv_FaultModeType faultMode; /*!< Fault mode */ + MftPwmDrv_FaultChannelConfigType faultInput[MFT_FAULT_INPUT_NUM]; /*!< fault channels */ +} MftPwmDrv_FaultConfigType; + +/*! \brief MFT sync source + */ +typedef enum +{ + MFTPWMDRV_SYSTEM_CLOCK = 0U, /*!< Register is updated with its buffer value at all rising edges of system clock */ + MFTPWMDRV_PWM_SYNC = 1U /*!< Register is updated with its buffer value at the MFT synchronization */ +} MftPwmDrv_UpdateConfigType; + +/*! \brief MFT updated config + */ +typedef enum +{ + MFTPWMDRV_WAIT_LOADING_POINTS = 0U, /*!< MFT register is updated at first loading point */ + MFTPWMDRV_UPDATE_NOW = 1U /*!< MFT register is updated immediately */ +} MftPwmDrv_SyncModeConfigType; + +/*! \brief MFT pwm sync structure + */ +typedef struct _MftPwmDrv_SyncType_ +{ + bool softwareSync; /*!< True - enable software sync, False - disable software sync */ + bool hardwareSync0; /*!< True - enable hardware 0 sync, False - disable hardware 0 sync */ + bool hardwareSync1; /*!< True - enable hardware 1 sync, False - disable hardware 1 sync */ + bool hardwareSync2; /*!< True - enable hardware 2 sync, False - disable hardware 2 sync */ + bool maxLoadingPoint; /*!< True - enable maximum loading point, False - disable maximum loading point */ + bool minLoadingPoint; /*!< True - enable minimum loading point, False - disable minimum loading point */ + MftPwmDrv_UpdateConfigType inverterSync; /*!< Configures INVCTRL sync */ + MftPwmDrv_UpdateConfigType outRegSync; /*!< Configures SWOCTRL sync */ + MftPwmDrv_UpdateConfigType maskRegSync; /*!< Configures OUTMASK sync */ + MftPwmDrv_UpdateConfigType initCounterSync; /*!< Configures CNTIN sync */ + bool autoClearTrigger; /*!< Available only for hardware trigger */ + MftPwmDrv_SyncModeConfigType syncPoint; /*!< Configure synchronization method(waiting next loading point or immediate) */ +} MftPwmDrv_SyncType; + +/*! \brief MFT pre-scaler factor for the dead-time insertion + */ +typedef enum +{ + MFTPWMDRV_DEADTIME_DIVID_BY_1 = 0x01U, /*!< Divide by 1 */ + MFTPWMDRV_DEADTIME_DIVID_BY_4 = 0x02U, /*!< Divide by 4 */ + MFTPWMDRV_DEADTIME_DIVID_BY_16 = 0x03U /*!< Divide by 16 */ +} MftPwmDrv_DeadTimePrescalerType; + +/*! \brief MFT PWM driver parameters + */ +typedef struct _MftPwmDrv_ConfigType_ +{ + uint32_t periodValue; /*!< PWM period ticks */ + MftPwmDrv_SyncType syncMethod; /*!< Register sync options */ + MftPwmDrv_FaultConfigType faultConfig; /*!< Fault configuration */ + uint8_t deadTimeCount; /*!< Dead time value in [ticks], only available in complementary mode */ + MftPwmDrv_DeadTimePrescalerType deadTimePrescaler; /*!< Dead time pre-scaler value, only available in complementary mode */ +} MftPwmDrv_ConfigType; + +/*! \brief The definition of MFT PWM driver prototype + * \details Derived from MFT driver + */ +typedef struct _MftPwmDrvType_ +{ + MftDrvType *base; /*!< base class pointer */ + MftPwmChType channel[MFT_CHANNEL_NUM]; /*!< channels of the PWM mode */ +} MftPwmDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the MFT PWM channel instance + * + * This function initializes MFT PWM channel instance by setting the MFT driver + * instance to it. + * + * \param[in] obj : pointer to MFT PWM driver instance + * \param[in] base : pointer to MFT driver instance + */ +extern void MftPwmDrv_Init(MftPwmDrvType *obj, MftDrvType *base); + +/*! \brief Get default configuration of the MFT PWM module + * + * This function gets default configuration of the MFT PWM module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void MftPwmDrv_GetDefaultConfig(MftPwmDrv_ConfigType *userConfig); + +/*! \brief Configure the MFT PWM module + * + * This function configures the MFT PWM module. + * + * \param[in] obj : pointer to MFT PWM driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void MftPwmDrv_Config(MftPwmDrvType *obj, const MftPwmDrv_ConfigType *userConfig); + +/*! \brief Initializes the channels output. + * + * This function initializes the channels output. + * + * \note Normally it should be called after setup of channels + * + * \param[in] obj : pointer to MFT PWM driver instance + * \param[in] enable : Initialize the channels output + * - true : The channels output is initialized according to the state of OUTINIT reg + * - false: No effect + */ +extern void MftPwmDrv_SetInitOutputCmd(MftPwmDrvType *obj, bool enable); + +/*! \brief Configure the MFT PWM module + * + * This function configures the MFT PWM module. + * + * \param[in] obj : pointer to MFT PWM driver instance + * \param[in] value : the period value in ticks + */ +extern void MftPwmDrv_SetPeriod(MftPwmDrvType *obj, uint16_t value); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _MFT_PWM_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_qd/mft_qd_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_qd/mft_qd_drv.c new file mode 100644 index 0000000..e3f85ab --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_qd/mft_qd_drv.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "mft_qd_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void MftQdDrv_Init(MftQdDrvType *obj, MftDrvType *base) +{ + obj->base = base; + obj->isStarted = false; +} + +void MftQdDrv_GetDefaultConfig(MftQdDrv_ConfigType *userConfig) +{ + userConfig->mode = MFTQDDRV_PHASE_ENCODE; + userConfig->initialVal = 0U; + userConfig->maxVal = 65535U; + userConfig->phaseAConfig.phaseInputFilter = false; + userConfig->phaseAConfig.phaseFilterVal = 0U; + userConfig->phaseAConfig.phasePolarity = MFTQDDRV_PHASE_NORMAL; + userConfig->phaseBConfig.phaseInputFilter = false; + userConfig->phaseBConfig.phaseFilterVal = 0U; + userConfig->phaseBConfig.phasePolarity = MFTQDDRV_PHASE_NORMAL; +} + +void MftQdDrv_ConfigAndStart(MftQdDrvType *obj, const MftQdDrv_ConfigType *userConfig) +{ + if(false == obj->isStarted) + { + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->base->reg, 1); + + /* Disable Quadrature Decoder */ + MftReg_SetQDCtrlQuadEn(obj->base->reg, 0); + MftReg_SetScClks(obj->base->reg, 0); + /* Configure Quadrature Decoder */ + /* Set decoder mode Speed and direction or Phase A and Phase B encoding */ + MftReg_SetQDCtrlQuadMode(obj->base->reg, (uint8_t)userConfig->mode); + /* Set filter state for Phase A (enable/disable) */ + MftReg_SetQDCtrlPhaFltrEn(obj->base->reg, userConfig->phaseAConfig.phaseInputFilter ? 1 : 0); + /* Set Phase A filter value if phase filter is enabled */ + if(userConfig->phaseAConfig.phaseInputFilter) + { + MftReg_SetFilterCh0FVal(obj->base->reg, userConfig->phaseAConfig.phaseFilterVal); + } + + /* Set filter state for Phase B (enable/disable) */ + MftReg_SetQDCtrlPhbFltrEn(obj->base->reg, userConfig->phaseBConfig.phaseInputFilter ? 1 : 0); + /* Set Phase B filter value if phase filter is enabled */ + if(userConfig->phaseBConfig.phaseInputFilter) + { + MftReg_SetFilterCh1FVal(obj->base->reg, userConfig->phaseBConfig.phaseFilterVal); + } + + /* Set polarity for Phase A and Phase B */ + MftReg_SetQDCtrlPhaPol(obj->base->reg, (uint8_t)userConfig->phaseAConfig.phasePolarity); + MftReg_SetQDCtrlPhbPol(obj->base->reg, (uint8_t)userConfig->phaseBConfig.phasePolarity); + /* Configure counter (initial value and maximum value) */ + MftReg_SetCntInCntInit(obj->base->reg, userConfig->initialVal); + MftReg_SetModuloMod(obj->base->reg, userConfig->maxVal); + MftReg_SetCntCount(obj->base->reg, userConfig->initialVal); + /* Enable Quadrature Decoder */ + MftReg_SetQDCtrlQuadEn(obj->base->reg, 1); + + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->base->reg, 1); + + obj->isStarted = true; + } +} + +void MftQdDrv_QuadDecodeStop(MftQdDrvType *obj) +{ + /* WPDIS = 1, disable write protection */ + MftReg_SetModeWpDis(obj->base->reg, 1); + /* Disable Quadrature decoder */ + MftReg_SetQDCtrlQuadEn(obj->base->reg, 0); + /* WPEN = 1, enable write protection */ + MftReg_SetFmsWpEn(obj->base->reg, 1); + obj->isStarted = false; +} + +void MftQdDrv_GetState(MftQdDrvType *obj, MftQdDrv_StateType *state) +{ + state->counterDirection = MftReg_GetQDCtrlQuaDir(obj->base->reg) == 1; + state->overflowDirection = MftReg_GetQDCtrlTorDir(obj->base->reg) == 1; + state->overflowFlag = MftReg_GetScTof(obj->base->reg) == 1; + state->counter = MftReg_GetCntCount(obj->base->reg); +} \ No newline at end of file diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_qd/mft_qd_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_qd/mft_qd_drv.h new file mode 100644 index 0000000..d036006 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mft/mft_qd/mft_qd_drv.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MFT_QD_DRV_H_ +#define _MFT_QD_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the quadrature decode mode driver of MFT + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../mft_drv.h" + +/*! \addtogroup mft_qd_drv + * \ingroup mft_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief MFT quadrature decode modes, phase encode or count and direction mode + */ +typedef enum +{ + MFTQDDRV_PHASE_ENCODE = 0x00U, /*!< Phase encoding mode */ + MFTQDDRV_COUNT_AND_DIR = 0x01U /*!< Counter and direction encoding mode */ +} MftQdDrv_ModeType; + +/*! \brief MFT quadrature phase polarities, normal or inverted polarity + */ +typedef enum +{ + MFTQDDRV_PHASE_NORMAL = 0x00U, /*!< Phase input signal is not inverted before identifying + * the rising and falling edges of this signal */ + MFTQDDRV_PHASE_INVERT = 0x01U /*!< Phase input signal is inverted before identifying + * the rising and falling edges of this signal */ +} MftQdDrv_PhasePolarityType; + +/*! \brief MFT quadrature decoder channel parameters + */ +typedef struct +{ + bool phaseInputFilter; /*!< false: disable phase filter, true: enable phase filter */ + uint8_t phaseFilterVal; /*!< Filter value (if input filter is enabled)*/ + MftQdDrv_PhasePolarityType phasePolarity; /*!< Phase polarity */ +} MftQdDrv_PhaseParamsType; + +/*! \brief MFT driver Input capture parameters for each channel + */ +typedef struct _MftQdDrv_ConfigType_ +{ + MftQdDrv_ModeType mode; /*!< Mode of quadrature decoder */ + uint16_t initialVal; /*!< Initial counter value*/ + uint16_t maxVal; /*!< Maximum counter value*/ + MftQdDrv_PhaseParamsType phaseAConfig; /*!< Configuration for the input phase a */ + MftQdDrv_PhaseParamsType phaseBConfig; /*!< Configuration for the input phase b */ +} MftQdDrv_ConfigType; + +/*! \brief MFT quadrature state(counter value and flags) + */ +typedef struct +{ + uint16_t counter; /*!< Counter value */ + bool overflowFlag; /*!< True if overflow occurred, False if overflow doesn't occurred */ + bool overflowDirection; /*!< False if overflow occurred at minimum value, True if overflow occurred at maximum value */ + bool counterDirection; /*!< False MFT counter is increasing, True MFT counter is decreasing */ +} MftQdDrv_StateType; + +/*! \brief The definition of MFT capture driver prototype + * \details Derived from MFT driver + */ +typedef struct _MftQdDrvType_ +{ + MftDrvType *base; /*!< base class is MFT driver */ + bool isStarted; /*!< Is quadrature decoder started */ +} MftQdDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the MFT quadrature decode mode + * + * This function initializes MFT quadrature decode driver by setting the MFT driver + * instance to it. + * + * \param[in] obj : pointer to MFT quadrature decode mode driver instance + * \param[in] base : pointer to MFT driver instance + */ +extern void MftQdDrv_Init(MftQdDrvType *obj, MftDrvType *base); + +/*! \brief Get default configures the MFT quadrature decode mode for configuration structure + * + * This function gets default configures the MFT quadrature decode mode for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void MftQdDrv_GetDefaultConfig(MftQdDrv_ConfigType *userConfig); + +/*! \brief Configures the quadrature mode and starts measurement + * + * This function configures the quadrature mode and starts measurement + * + * \param[in] obj : pointer to MFT quadrature decode mode driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void MftQdDrv_ConfigAndStart(MftQdDrvType *obj, const MftQdDrv_ConfigType *userConfig); + +/*! \brief De-activates the quadrature decode mode. + * + * This function de-activates the quadrature decode mode. + * + * \param[in] obj : pointer to MFT quadrature decode mode driver instance + */ +extern void MftQdDrv_QuadDecodeStop(MftQdDrvType *obj); + +/*! \brief Get the current quadrature decoder state + * + * This function get the current quadrature decoder state (counter value, overflow flag and + * overflow direction) + * + * \param[in] obj : pointer to MFT quadrature decode mode driver instance + * \param[out] state : pointer to the current state of quadrature decoder + */ +extern void MftQdDrv_GetState(MftQdDrvType *obj, MftQdDrv_StateType *state); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _MFT_QD_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mpu/mpu_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mpu/mpu_drv.c new file mode 100644 index 0000000..01a42e5 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mpu/mpu_drv.c @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "mpu_drv.h" +#include "mpu_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void MpuDrv_Init(MpuDrvType *obj, struct _MpuRegType_ *reg) +{ + obj->reg = reg; +} + +void MpuDrv_GetDefaultConfig(MpuDrv_ConfigType *userConfig) +{ + uint8_t regDescNum; + uint8_t masterNum; + uint8_t slvPortNum; + + /* mpu PID is used, default: false */ + userConfig->isEnableErrPid = false; + /* mpu main switch, default: enable */ + userConfig->ctrlInfo.mpuValid = true; + /* region description total num, default: 8 */ + userConfig->ctrlInfo.mpuTotalNumRegDesc = MPUDRV_NUMOFRGD_8; + + /* mpu control info */ + for(slvPortNum = 0; slvPortNum < MPUDRV_SLVPORTMAX; slvPortNum++) + { + /* slave port error status, default: false */ + userConfig->ctrlInfo.slvPortErrStatus[slvPortNum] = false; + + /* + * slave port default info + */ + + /* slave port access master number */ + userConfig->slvPortErrInfo->master = (MpuDrv_MasterType)0; + /* salve port error PID number,default: 0 */ + userConfig->slvPortErrInfo->pidNumber = 0; + /* salve port access mode, default: user mode */ + userConfig->slvPortErrInfo->attrbutes = MPUDRV_INSTRUCTION_ACCESS_IN_USER_MODE; + /* slave port access type, default: read mode */ + userConfig->slvPortErrInfo->accType = MPUDRV_ERRTYPE_READ; + /* salve port access error claw(EACD), default: 0 */ + userConfig->slvPortErrInfo->accCtrl = 0; + /* salve port error address, when master access fault,default: 0 */ + userConfig->slvPortErrInfo->addr = 0; + } + + /* region description default configure */ + for(regDescNum = 0; regDescNum < MPUDRV_CHMAX; regDescNum++) + { + /* region description channel 0 default all rights allow */ + if(regDescNum == 0) + { + /* RGD channel 0 tatus, mpu functions, default: enable */ + userConfig->regDescCfgInfo[regDescNum].chnEnable = true; + /* RGD channel 0 start address, default: 0 */ + userConfig->regDescCfgInfo[regDescNum].startAddr = 0; + /* RGD channel 0 end address, default: 0xFFFFFF1F */ + userConfig->regDescCfgInfo[regDescNum].endAddr = 0xFFFFFF1F; + /* RGD channel 0 PID mask number, default: 0 */ + userConfig->regDescCfgInfo[regDescNum].pidMask = 0; + /* RGD channel 0 PID number, default: 0 */ + userConfig->regDescCfgInfo[regDescNum].pidNumber = 0; + + for(masterNum = 0; masterNum < MPUDRV_MASTER_NUMMAX; masterNum++) + { + /* RGD master in privilege mode access right, default: same as user */ + userConfig->regDescCfgInfo[regDescNum].masterAccRight[masterNum].masterPrivilegeAccRight = MPUDRV_SUPERVISOR_SAME_AS_USER; + /* RGD master in user mode access right, default: RWX allow */ + userConfig->regDescCfgInfo[regDescNum].masterAccRight[masterNum].masterUserAccRight = MPUDRV_USER_RWX; + /* RGD master PID enable flag, default: false */ + userConfig->regDescCfgInfo[regDescNum].masterAccRight[masterNum].pidFlagEnable = false; + + /* + * Alternate Access Control channel 0 default all rights allow + */ + + /* AAC channel 0 onfig master in privilege mode access right, default: same as user */ + userConfig->aacCfgInfo[regDescNum].masterPrivilegeAccRight = MPUDRV_SUPERVISOR_SAME_AS_USER; + /* AAC channel 0 config master in user mode access right, default: RWX allow */ + userConfig->aacCfgInfo[regDescNum].masterUserAccRight = MPUDRV_USER_RWX; + /* AAC channel 0 config master PID enable flag, default: false */ + userConfig->aacCfgInfo[regDescNum].pidFlagEnable = false; + } + } + else + { + /* + * region description channel 1~8 default all rights forbidden + */ + + /* RGD channel 1~8 tatus, mpu functions, default: disable */ + userConfig->regDescCfgInfo[regDescNum].chnEnable = false; + /* RGD channel 1~8 start address, default: 0 */ + userConfig->regDescCfgInfo[regDescNum].startAddr = 0; + /* RGD channel 1~8 end address, default: 0x0 */ + userConfig->regDescCfgInfo[regDescNum].endAddr = 0x1F; + /* RGD channel 1~8 PID mask number, default: 0 */ + userConfig->regDescCfgInfo[regDescNum].pidMask = 0; + /* RGD channel 1~8 PID number, default: 0 */ + userConfig->regDescCfgInfo[regDescNum].pidNumber = 0; + + for(masterNum = 0; masterNum < MPUDRV_MASTER_NUMMAX; masterNum++) + { + /* RGD master in privilege mode access right, default: RWX allow */ + userConfig->regDescCfgInfo[regDescNum].masterAccRight[masterNum].masterPrivilegeAccRight = MPUDRV_SUPERVISOR_RWX; + /* RGD master in user mode access right, default: none */ + userConfig->regDescCfgInfo[regDescNum].masterAccRight[masterNum].masterUserAccRight = MPUDRV_USER_NONE; + /* RGD master PID enable flag, default: false */ + userConfig->regDescCfgInfo[regDescNum].masterAccRight[masterNum].pidFlagEnable = false; + + /* + * Alternate Access Control channel 1~8 default all rights forbidden + */ + + /* AAC channel 1~8 onfig master in privilege mode access right, default: RWX allow */ + userConfig->aacCfgInfo[regDescNum].masterPrivilegeAccRight = MPUDRV_SUPERVISOR_RWX; + /* AAC channel 1~8 config master in user mode access right, default: none */ + userConfig->aacCfgInfo[regDescNum].masterUserAccRight = MPUDRV_USER_NONE; + /* AAC channel 1~8 config master PID enable flag, default: false */ + userConfig->aacCfgInfo[regDescNum].pidFlagEnable = false; + } + } + } +} + +void MpuDrv_GetCtrlInfo(MpuDrvType *obj, MpuDrv_CtrlInfoType *ctrlInfo) +{ + uint8_t slvPortNum; + + for(slvPortNum = 0; slvPortNum < MPUDRV_SLVPORTMAX; slvPortNum++) + { + /* get slave port error info */ + ctrlInfo->slvPortErrStatus[slvPortNum] = MpuReg_GetSlvPortErrStatus(obj->reg, slvPortNum); + } + /* get total number of region description */ + ctrlInfo->mpuTotalNumRegDesc = (MpuDrv_RegDescTotalNumType)MpuReg_GetNumOfRegionDesc(obj->reg); + /* get MPU global enable status */ + ctrlInfo->mpuValid = MpuReg_GetMpuGlobalEnableStatus(obj->reg); +} + +__attribute__((always_inline)) static inline MpuDrv_MasterType MpuDrv_SlvPortEMNtoMaster(uint8_t emn) +{ + switch(emn) + { + case 0: + return MPUDRV_MASTER_CPU; + case 1: + return MPUDRV_MASTER_DEBUGGER; + case 2: + return MPUDRV_MASTER_DMA; + default: + return MPUDRV_MASTER_NUMMAX; + } +} + + +void MpuDrv_GetSlvPortErrInfo(MpuDrvType *obj, MpuDrv_SlvPortErrInfoType *slvPortErrInfo, bool isEnablePid) +{ + uint8_t slvPortNum; + + for(slvPortNum = 0; slvPortNum < MPUDRV_SLVPORTMAX; slvPortNum++) + { + /* get slave port error access detail info */ + slvPortErrInfo[slvPortNum].accCtrl = MpuReg_GetSlvPortEACD(obj->reg, slvPortNum); + /* get slave port error type R/W */ + slvPortErrInfo[slvPortNum].accType = (MpuDrv_AccType)MpuReg_GetSlvPortErrDetailERW(obj->reg, slvPortNum); + /* get slave port error type master number */ + slvPortErrInfo[slvPortNum].master = (MpuDrv_MasterType)MpuDrv_SlvPortEMNtoMaster(MpuReg_GetSlvPortErrDetailEMN(obj->reg, slvPortNum)); + /* get slave port error attribute */ + slvPortErrInfo[slvPortNum].attrbutes = (MpuDrv_AttrType)MpuReg_GetSlvPortErrDetailEAttr(obj->reg, slvPortNum); + /* get slave port error address */ + slvPortErrInfo[slvPortNum].addr = MpuReg_GetSlvPortErrAddr(obj->reg, slvPortNum); + + if(isEnablePid) + { + /* get slave port error PID */ + slvPortErrInfo[slvPortNum].pidNumber = MpuReg_GetSlvPortErrPID(obj->reg, slvPortNum); + } + } +} + +void MpuDrv_GetMasterAccRight(MpuDrvType *obj, + MpuDrv_MasterAccConfigType *masterAccRight, + MpuDrv_RegDescChnNumType regDescNum, + MpuDrv_MasterType masterNum) +{ + /* get master privilege mode access right */ + masterAccRight[masterNum].masterPrivilegeAccRight = (MpuDrv_MasterPrivilegeAccType)MpuReg_GetRegionDescPrivilegeAuthority(obj->reg, regDescNum, masterNum); + /* get master user mode access right */ + masterAccRight[masterNum].masterUserAccRight = (MpuDrv_MasterUserAccType)MpuReg_GetRegionDescUserAuthority(obj->reg, regDescNum, masterNum); + /* get master PID enable status (Only master0 & master1) */ + masterAccRight[masterNum].pidFlagEnable = MpuReg_GetRegionDescPIDFlagEnableStatus(obj->reg, regDescNum, masterNum); +} + +void MpuDrv_GetRegDescCfgInfo(MpuDrvType *obj, MpuDrv_RegDescType *regDesc, bool isEnablePid) +{ + uint8_t regDescNum; + uint8_t masterNum; + + for(regDescNum = 0; regDescNum < MPUDRV_CHMAX; regDescNum++) + { + /* get region description current channel start address */ + regDesc[regDescNum].startAddr = MpuReg_GetRegionDescStartAddr(obj->reg, regDescNum); + /* get region description current channel end address */ + regDesc[regDescNum].endAddr = MpuReg_GetRegionDescEndAddr(obj->reg, regDescNum); + + for(masterNum = 0; masterNum < MPUDRV_MASTER_NUMMAX; masterNum++) + { + /* get region description current channel master accsee right */ + MpuDrv_GetMasterAccRight(obj, ®Desc[regDescNum].masterAccRight[masterNum], (MpuDrv_RegDescChnNumType)regDescNum, (MpuDrv_MasterType)masterNum); + } + + if(isEnablePid) + { + /* get region description current channel PID */ + regDesc[regDescNum].pidNumber = MpuReg_GetPID(obj->reg, regDescNum); + /* get region description current channel PIDMask */ + regDesc[regDescNum].pidMask = MpuReg_GetPIDMask(obj->reg, regDescNum); + } + } +} + +void MpuDrv_GetAacCtrlInfo(MpuDrvType *obj, MpuDrv_MasterAccConfigType *aacRegDesc) +{ + uint8_t regDescNum; + uint8_t masterNum; + + for(regDescNum = 0; regDescNum < MPUDRV_CHMAX; regDescNum++) + { + for(masterNum = 0; masterNum < MPUDRV_MASTER_NUMMAX; masterNum++) + { + /* get AAC config master privilege mode access right */ + aacRegDesc[masterNum].masterPrivilegeAccRight = (MpuDrv_MasterPrivilegeAccType)MpuReg_GetRegionDescAACPrivilegeAuthority(obj->reg, regDescNum, masterNum); + /* get AAC config master user mode access right */ + aacRegDesc[masterNum].masterUserAccRight = (MpuDrv_MasterUserAccType)MpuReg_GetRegionDescAACUserAuthority(obj->reg, regDescNum, masterNum); + /* get AAC config master PID enable status (Only master0 & master1) */ + aacRegDesc[masterNum].pidFlagEnable = MpuReg_GetRegionDescAACPIDFlagEnableStatus(obj->reg, regDescNum, masterNum); + } + } +} + +void MpuDrv_GetConfigure(MpuDrvType *obj, MpuDrv_ConfigType *userConfig) +{ + /* get common part control info */ + MpuDrv_GetCtrlInfo(obj, &userConfig->ctrlInfo); + /* get slave port error info */ + MpuDrv_GetSlvPortErrInfo(obj, (MpuDrv_SlvPortErrInfoType *)&userConfig->slvPortErrInfo, userConfig->isEnableErrPid); + /* get region description config info */ + MpuDrv_GetRegDescCfgInfo(obj, (MpuDrv_RegDescType *)&userConfig->regDescCfgInfo, userConfig->isEnableErrPid); + /* get alternate access config info */ + MpuDrv_GetAacCtrlInfo(obj, (MpuDrv_MasterAccConfigType *)&userConfig->aacCfgInfo); +} + +static void MpuDrv_SetMasterAccRight(MpuDrvType *obj, + MpuDrv_MasterAccConfigType *masterAccRight, + MpuDrv_RegDescChnNumType regDescChnNum, + MpuDrv_MasterType masterNum) +{ + /* set master privilege mode access right */ + MpuReg_SetRegionDescPrivilegeAuthority(obj->reg, regDescChnNum, masterNum, masterAccRight[masterNum].masterPrivilegeAccRight); + /* set master user mode access right */ + MpuReg_SetRegionDescUserAuthority(obj->reg, regDescChnNum, masterNum, masterAccRight[masterNum].masterUserAccRight); + /* set master PID enable status (Only master0 & master1) */ + MpuReg_SetRegionDescPIDFlagEnable(obj->reg, regDescChnNum, masterNum, masterAccRight[masterNum].pidFlagEnable); +} + +void MpuDrv_EnableRegDescChn(MpuDrvType *obj, MpuDrv_RegDescChnNumType chnNum, bool enable) +{ + /* set region description channle enable */ + MpuReg_SetRegionDescValid(obj->reg, chnNum, enable); +} + +void MpuDrv_SetRegDescChnCfg(MpuDrvType *obj, + const MpuDrv_RegDescType *regDescCfg, + MpuDrv_RegDescChnNumType regDescChnNum, + bool pidEnable) +{ + uint8_t masterNum; + + /* set region description start address */ + MpuReg_SetRegionDescStartAddr(obj->reg, regDescCfg->startAddr, regDescChnNum); + /* set region description end address */ + MpuReg_SetRegionDescEndAddr(obj->reg, regDescCfg->endAddr, regDescChnNum); + + for(masterNum = 0; masterNum < MPUDRV_MASTER_NUMMAX; masterNum++) + { + /* set region description master access right */ + MpuDrv_SetMasterAccRight(obj, (MpuDrv_MasterAccConfigType *)®DescCfg->masterAccRight, (MpuDrv_RegDescChnNumType)regDescChnNum, (MpuDrv_MasterType)masterNum); + if(masterNum < MPUDRV_MASTER_DMA) + { + /* set region description pid enable */ + MpuReg_SetRegionDescPIDFlagEnable(obj->reg, regDescChnNum, masterNum, pidEnable); + } + } + + MpuDrv_EnableRegDescChn(obj, regDescChnNum, regDescCfg->chnEnable); +} + +void MpuDrv_SetAacCtrlInfo(MpuDrvType *obj, + MpuDrv_MasterAccConfigType *aacRegDesc, + MpuDrv_RegDescChnNumType regDescChnNum, + MpuDrv_MasterType masterNum) +{ + if(regDescChnNum >= MPUDRV_CHMAX || masterNum >= MPUDRV_MASTER_NUMMAX) + { + return; + } + + /* set AAC config master privilege mode access right */ + MpuReg_SetRegionDescAACPrivilegeAuthority(obj->reg, regDescChnNum, masterNum, aacRegDesc->masterPrivilegeAccRight); + /* set AAC config master user mode access right */ + MpuReg_SetRegionDescAACUserAuthority(obj->reg, regDescChnNum, masterNum, aacRegDesc->masterUserAccRight); + /* set AAC config master PID enable status (Only master0 & master1) */ + MpuReg_SetRegionDescAACPIDFlagEnable(obj->reg, regDescChnNum, masterNum, aacRegDesc->pidFlagEnable); +} + +bool MpuDrv_GetGlobalEnableStatus(MpuDrvType *obj) +{ + /* Get MPU Enable status */ + return MpuReg_GetMpuGlobalEnableStatus(obj->reg); +} + +void MpuDrv_SetGlobalEnable(MpuDrvType *obj, bool enable) +{ + /* Set MPU global Enable status */ + MpuReg_GlobalEnable(obj->reg, enable); +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mpu/mpu_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mpu/mpu_drv.h new file mode 100644 index 0000000..10245f5 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/mpu/mpu_drv.h @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MPU_DRV_H_ +#define _MPU_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of MPU + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup mpu_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief MPU access error + */ +typedef enum +{ + MPUDRV_ERRTYPE_READ = 0U, /*!< MPU error type: read */ + MPUDRV_ERRTYPE_WRITE = 1U /*!< MPU error type: write */ +} MpuDrv_AccType; + +/*! \brief MPU access error attributes + */ +typedef enum +{ + MPUDRV_INSTRUCTION_ACCESS_IN_USER_MODE = 0U, /*!< Access instruction error in user mode */ + MPUDRV_DATA_ACCESS_IN_USER_MODE = 1U, /*!< Access data error in user mode */ + MPUDRV_INSTRUCTION_ACCESS_IN_SUPERVISOR_MODE = 2U, /*!< Access instruction error in supervisor mode */ + MPUDRV_DATA_ACCESS_IN_SUPERVISOR_MODE = 3U /*!< Access data error in supervisor mode */ +} MpuDrv_AttrType; + +/*! \brief MPU Region Description Number + */ +typedef enum +{ + MPUDRV_NUMOFRGD_8 = 0U, /*!< MPU Total Number of Region 8 Descriptions */ + MPUDRV_NUMOFRGD_12 = 1U, /*!< MPU Total Number of Region 12 Descriptions */ + MPUDRV_NUMOFRGD_16 = 2U, /*!< MPU Total Number of Region 16 Descriptions */ +} MpuDrv_RegDescTotalNumType; + +/*! \brief MPU access Master Type + * Implements : MpuDrv_MasterType + */ +typedef enum +{ + MPUDRV_MASTER_CPU = 0U, /*!< MPU Access Master Type CPU */ + MPUDRV_MASTER_DEBUGGER = 1U, /*!< MPU Access Master Type DEBUGGER */ + MPUDRV_MASTER_DMA = 2U, /*!< MPU Access Master Type DMA */ + MPUDRV_MASTER_NUMMAX = 3U /*!< Master Number value Max */ +} MpuDrv_MasterType; + +/*! \brief MPU slave port Type + */ +typedef enum +{ + MPUDRV_SLVPORT0 = 0U, /*!< MPU Slave Port Number0 */ + MPUDRV_SLVPORT1 = 1U, /*!< MPU Slave Port Number1 */ + MPUDRV_SLVPORTMAX = 2U /*!< MPU Slave Port NumberMax */ +} MpuDrv_SlvPortNumType; + +/*! \brief MPU Region Description Type + */ +typedef enum +{ + MPUDRV_CH0 = 0U, /*!< MPU RGD channel number 0 */ + MPUDRV_CH1 = 1U, /*!< MPU RGD channel number 1 */ + MPUDRV_CH2 = 2U, /*!< MPU RGD channel number 2 */ + MPUDRV_CH3 = 3U, /*!< MPU RGD channel number 3 */ + MPUDRV_CH4 = 4U, /*!< MPU RGD channel number 4 */ + MPUDRV_CH5 = 5U, /*!< MPU RGD channel number 5 */ + MPUDRV_CH6 = 6U, /*!< MPU RGD channel number 6 */ + MPUDRV_CH7 = 7U, /*!< MPU RGD channel number 7 */ + MPUDRV_CHMAX = 8U /*!< MPU RGD channel total num */ +} MpuDrv_RegDescChnNumType; + +/*! \brief MPU privilege access rights. + */ +typedef enum +{ + MPUDRV_SUPERVISOR_RWX = 0x0U, /*!< 0b00U : rwx, Allow Read, write, execute in supervisor mode */ + MPUDRV_SUPERVISOR_RX = 0x1U, /*!< 0b01U : r-x, Allow Read, execute in supervisor mode */ + MPUDRV_SUPERVISOR_RW = 0x2U, /*!< 0b10U : rw-, Allow Read, write in supervisor mode */ + MPUDRV_SUPERVISOR_SAME_AS_USER = 0x3U, /*!< 0b11U : xxx, Allow right the same as user mode */ +} MpuDrv_MasterPrivilegeAccType; + +/*! \brief MPU user access rights. + */ +typedef enum +{ + MPUDRV_USER_NONE = 0x00U, /*!< 0b000U : ---, No access allowed user modes */ + MPUDRV_USER_X = 0x01U, /*!< 0b001U : --x, Execute operation is allowed user modes */ + MPUDRV_USER_W = 0x02U, /*!< 0b010U : -w-, Write operation is allowed user modes */ + MPUDRV_USER_WX = 0x03U, /*!< 0b011U : -wx, Write and execute operations are allowed in user modes */ + MPUDRV_USER_R = 0x04U, /*!< 0b100U : r--, Read operation is allowed user modes */ + MPUDRV_USER_RX = 0x05U, /*!< 0b101U : r-x, Allow Read, execute in user mode */ + MPUDRV_USER_RW = 0x06U, /*!< 0b110U : rw-, Allow Read, write in user mode */ + MPUDRV_USER_RWX = 0x07U, /*!< 0b111U : rwx, Allow Read, write, execute in user mode */ +} MpuDrv_MasterUserAccType; + +/* Forward declaration of MPU register */ +struct _MpuRegType_; + +/*! \brief The definition of MPU driver class + */ +typedef struct _MpuDrvType_ +{ + struct _MpuRegType_ *reg; +} MpuDrvType; + +/*! \brief MPU control info + */ +typedef struct _MpuDrv_CtrlInfoType_ +{ + bool mpuValid; /*!< MPU main enable */ + MpuDrv_RegDescTotalNumType mpuTotalNumRegDesc; /*!< MPU channel num of region description */ + bool slvPortErrStatus[MPUDRV_SLVPORTMAX]; /*!< MPU slave portx error status */ +} MpuDrv_CtrlInfoType; + +/*! \brief MPU slave port detail error access info + */ +typedef struct _MpuDrv_SlvPortErrInfoType_ +{ + MpuDrv_MasterType master; /*!< Access error master */ + MpuDrv_AttrType attrbutes; /*!< Access error attributes */ + MpuDrv_AccType accType; /*!< Access error type */ + uint16_t accCtrl; /*!< Access error control(EACD) */ + uint32_t addr; /*!< Access error address */ + uint8_t pidNumber; /*!< Access error processor identification */ +} MpuDrv_SlvPortErrInfoType; + +/*! \brief MPU master access rights. + */ +typedef struct _MpuDrv_MasterAccConfigType_ +{ + MpuDrv_MasterPrivilegeAccType masterPrivilegeAccRight; /*!< Master Privilege Access right */ + MpuDrv_MasterUserAccType masterUserAccRight; /*!< Master User Access right */ + bool pidFlagEnable; /*!< Enables or disables process identifier */ +} MpuDrv_MasterAccConfigType; + +/*! \brief MPU Region Description rights + */ +typedef struct _MpuDrv_RegDescType_ +{ + uint32_t startAddr; /*!< Memory region start address */ + uint32_t endAddr; /*!< Memory region end address */ + MpuDrv_MasterAccConfigType masterAccRight[MPUDRV_MASTER_NUMMAX]; /*!< Access right for masters */ + uint8_t pidNumber; /*!< Process identifier */ + uint8_t pidMask; /*!< Process identifier mask. The setting bit will ignore the same bit in process identifier */ + bool chnEnable; /*!< current channel protect function enable */ +} MpuDrv_RegDescType; + +/*! \brief The definition of MPU driver class + */ +typedef struct _MpuDrv_ConfigType_ +{ + MpuDrv_CtrlInfoType ctrlInfo; /*!< MPU main ctrl info */ + MpuDrv_SlvPortErrInfoType slvPortErrInfo[MPUDRV_SLVPORTMAX]; /*!< MPU slave port error info */ + MpuDrv_RegDescType regDescCfgInfo[MPUDRV_CHMAX]; /*!< MPU region description config info */ + MpuDrv_MasterAccConfigType aacCfgInfo[MPUDRV_CHMAX]; /*!< MPU AAC register config info */ + bool isEnableErrPid; /*!< MPU Error PID is enable, user determine */ +} MpuDrv_ConfigType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the MPU driver module + * + * This function initializes MPU driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] reg : pointer to MPU register instance + */ +extern void MpuDrv_Init(MpuDrvType *obj, struct _MpuRegType_ *reg); + +/*! \brief Get MPU Default Config + * + * This function get MPU all default paramters + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] userConfig : pointer to user get all default + * + */ +extern void MpuDrv_GetDefaultConfig(MpuDrv_ConfigType *userConfig); + +/*! \brief Get MPU common Control Config + * + * This function get MPU common control paramters + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] ctrlInfo : pointer to common config paramter + * + */ +extern void MpuDrv_GetCtrlInfo(MpuDrvType *obj, MpuDrv_CtrlInfoType *ctrlInfo); + +/*! \brief Get MPU slave port Error info + * + * This function get MPU slave error info + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] slvPortErrInfo : slave port error info + * \param[in] isEnablePID : PID status + * + */ +extern void MpuDrv_GetSlvPortErrInfo(MpuDrvType *obj, MpuDrv_SlvPortErrInfoType *slvPortErrInfo, bool isEnablePid); + +/*! \brief Get MPU Master Config + * + * This function get MPU master config + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] masterAccRight : master access right + * \param[in] regDescNum : region description number + * \param[in] masterNum : master number + * + */ +extern void MpuDrv_GetMasterAccRight(MpuDrvType *obj, MpuDrv_MasterAccConfigType *masterAccRight, MpuDrv_RegDescChnNumType regDescNum, MpuDrv_MasterType masterNum); + +/*! \brief Get MPU Region Description config + * + * This function get MPU region description config parameters + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] regDesc : pointer to region description config parameter + * \param[in] isEnablePID : region description PID enable status + * + */ +extern void MpuDrv_GetRegDescCfgInfo(MpuDrvType *obj, MpuDrv_RegDescType *regDesc, bool isEnablePid); + +/*! \brief Get MPU Master Access Right + * + * This function get MPU master access right + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] aacRegDesc : pointer to mster access right paramter + * + */ +extern void MpuDrv_GetAacCtrlInfo(MpuDrvType *obj, MpuDrv_MasterAccConfigType *aacRegDesc); + +/*! \brief Get MPU Current all Config + * + * This function get MPU current all config paramters + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] userConfig : pointer to user get current all config + * + */ +extern void MpuDrv_GetConfigure(MpuDrvType *obj, MpuDrv_ConfigType *userConfig); + +/*! \brief Set Region Description channel Enable + * + * This function set mpu region description channle enable + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] chnNum : select config channel + * \param[in] enable : + * - true : enable + * - false : disable + * + */ +extern void MpuDrv_EnableRegDescChn(MpuDrvType *obj, MpuDrv_RegDescChnNumType chnNum, bool enable); + +/*! \brief Set Region Description channel Enable + * + * This function set mpu region description channle enable + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] regDescCfg : pointer to region description + * \param[in] regDescChnNum : region description number + * \param[in] pidEnable : + * - true : enable + * - false : disable + * + */ +extern void MpuDrv_SetRegDescChnCfg(MpuDrvType *obj,const MpuDrv_RegDescType *regDescCfg, MpuDrv_RegDescChnNumType regDescChnNum, bool pidEnable); + +/*! \brief Set Master Access Right + * + * This function set master access ram or flash right + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] aacRegDesc : pointer to master access right + * \param[in] regDescChnNum : region description number + * \param[in] masterNum : master number + * + */ +extern void MpuDrv_SetAacCtrlInfo(MpuDrvType *obj, MpuDrv_MasterAccConfigType *aacRegDesc, MpuDrv_RegDescChnNumType regDescChnNum, MpuDrv_MasterType masterNum); + +/*! \brief Get MPU enable status + * + * This function get MPU enable status enable + * + * \param[in] obj : pointer to MPU driver instance + * + */ +extern bool MpuDrv_GetGlobalEnableStatus(MpuDrvType *obj); + +/*! \brief Get MPU enable status + * + * This function get MPU enable status enable + * + * \param[in] obj : pointer to MPU driver instance + * \param[in] enable : + * - true : enable + * - false : disable + * + */ +extern void MpuDrv_SetGlobalEnable(MpuDrvType *obj, bool enable); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _MPU_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/pdb/pdb_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/pdb/pdb_drv.c new file mode 100644 index 0000000..e6cdd5e --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/pdb/pdb_drv.c @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "pdb_drv.h" +#include "pdb_reg.h" +#include "sim_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define PDB_CF_MASK (1U) +#define PDBDRV_PRE_TRG_ENABLE (1U) +#define PDBDRV_PRE_BB_MODE_ENABLE (1U) +#define PDBDRV_PRE_DLY_MODE_ENABLE (1U) +#define PDBDRV_PO_ENABLE (1U) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void PdbDrv_Init(PdbDrvType *obj, struct _PdbRegType_ *pdbReg) +{ + obj->pdbReg = pdbReg; +} + +void PdbDrv_EnablePdb(PdbDrvType *obj) +{ + PdbReg_SetPdbenReg(obj->pdbReg, true); +} + +void PdbDrv_PdbDisable(PdbDrvType *obj) +{ + PdbReg_SetPdbenReg(obj->pdbReg, false); +} + +void PdbDrv_SwtrigCmd(PdbDrvType *obj) +{ + PdbReg_SwtrigReg(obj->pdbReg); +} + +void PdbDrv_ClrPdbif(PdbDrvType *obj) +{ + PdbReg_ClrPdbifReg(obj->pdbReg); +} + +void PdbDrv_LoadCmd(PdbDrvType *obj) +{ + PdbReg_StartLoadReg(obj->pdbReg); +} + +uint16_t PdbDrv_GetCnt(const PdbDrvType *obj) +{ + return (PdbReg_GetCntReg(obj->pdbReg)); +} + +uint8_t PdbDrv_GetChnCf(const PdbDrvType *obj, PdbDrv_ChType chn) +{ + uint8_t tmp; + tmp = PdbReg_GetChnCfReg(obj->pdbReg, (uint8_t)chn); + return (tmp); +} + +void PdbDrv_ClrChnCf(PdbDrvType *obj, PdbDrv_ChType chn) +{ + PdbReg_ClrChnCfReg(obj->pdbReg, (uint8_t)chn); +} + +uint8_t PdbDrv_GetChnErr(const PdbDrvType *obj, PdbDrv_ChType chn) +{ + uint8_t tmp; + tmp = PdbReg_GetChnErrReg(obj->pdbReg, (uint8_t)chn); + return (tmp); +} + +void PdbDrv_ClrChnErr(PdbDrvType *obj, PdbDrv_ChType chn) +{ + PdbReg_ClrChnErrReg(obj->pdbReg, (uint8_t)chn); +} + +void PdbDrv_SetChnBbMode(PdbDrvType *obj, PdbDrv_ChType chn, uint8_t value) +{ + PdbReg_SetChnBbReg(obj->pdbReg, value, (uint8_t)chn); +} + +uint8_t PdbDrv_GetChnBbMode(PdbDrvType *obj, PdbDrv_ChType chn) +{ + return (PdbReg_GetChnBbReg(obj->pdbReg, (uint8_t)chn)); +} + +void PdbDrv_SetChnTosMode(PdbDrvType *obj, PdbDrv_ChType chn, uint8_t value) +{ + PdbReg_SetChnTosReg(obj->pdbReg, value, (uint8_t)chn); +} + +uint8_t PdbDrv_GetChnTosMode(PdbDrvType *obj, PdbDrv_ChType chn) +{ + return (PdbReg_GetChnTosReg(obj->pdbReg, (uint8_t)chn)); +} + +void PdbDrv_ConfigPreTrg(PdbDrvType *obj, const PdbDrv_PreTrgType *userConfig) +{ + PdbDrv_ChType ch; + PdbDrv_PreChType preCh; + uint8_t tos; + uint8_t en; + uint8_t bb; + /* Pre-Trigger channel configuration */ + for(ch = PDBDRV_CHANNEL0; ch < PDBDRV_CH_NUMBER; ch++) + { + tos = 0; + en = 0; + bb = 0; + for(preCh = PDBDRV_PRE_CHANNEL0; preCh < PDBDRV_PRE_CH_NUMBER; preCh++) + { + switch(userConfig->mode[ch][preCh]) + { + case PDBDRV_PRETRG_DISABLE: + break; + case PDBDRV_PRETRG_BYPASSED_MODE: + en |= PDBDRV_PRE_TRG_ENABLE << preCh; + break; + case PDBDRV_PRETRG_DELAY_MODE: + en |= PDBDRV_PRE_TRG_ENABLE << preCh; + tos |= PDBDRV_PRE_DLY_MODE_ENABLE << preCh; + break; + case PDBDRV_PRETRG_BB_MODE: + en |= PDBDRV_PRE_TRG_ENABLE << preCh; + bb |= PDBDRV_PRE_BB_MODE_ENABLE << preCh; + break; + default: + /* Impossible case */ + break; + } + } + PdbReg_SetChnBbReg(obj->pdbReg, bb, ch); + PdbReg_SetChnTosReg(obj->pdbReg, tos, ch); + PdbReg_SetChnEnReg(obj->pdbReg, en, ch); + } +} + +void PdbDrv_GetPreTrgCfg(const PdbDrvType *obj, PdbDrv_PreTrgType *userConfig) +{ + PdbDrv_ChType ch; + PdbDrv_PreChType preCh; + uint8_t tos; + uint8_t en; + uint8_t bb; + /* Pre-Trigger channel configuration */ + for(ch = PDBDRV_CHANNEL0; ch < PDBDRV_CH_NUMBER; ch++) + { + tos = PdbReg_GetChnTosReg(obj->pdbReg, ch); + en = PdbReg_GetChnEnReg(obj->pdbReg, ch); + bb = PdbReg_GetChnBbReg(obj->pdbReg, ch); + for(preCh = PDBDRV_PRE_CHANNEL0; preCh < PDBDRV_PRE_CH_NUMBER; preCh++) + { + uint8_t preChEn = (en >> preCh) & PDBDRV_PRE_TRG_ENABLE; + uint8_t preChBb = (bb >> preCh) & PDBDRV_PRE_BB_MODE_ENABLE; + uint8_t preChDly = (tos >> preCh) & PDBDRV_PRE_DLY_MODE_ENABLE; + if(preChEn == 0) + { + userConfig->mode[ch][preCh] = PDBDRV_PRETRG_DISABLE; + } + else if(preChBb == 1) + { + userConfig->mode[ch][preCh] = PDBDRV_PRETRG_BB_MODE; + } + else if(preChDly == 1) + { + userConfig->mode[ch][preCh] = PDBDRV_PRETRG_DELAY_MODE; + } + else + { + userConfig->mode[ch][preCh] = PDBDRV_PRETRG_BYPASSED_MODE; + } + } + } +} + +void PdbDrv_GetDefaultConfig(PdbDrv_ConfigType *userConfig) +{ + userConfig->ldmode = PDBDRV_LDMOD_LOAD_VAL_IMMEDIATELY; + userConfig->pdbeie = false; + userConfig->dmaen = false; + userConfig->prescalerFactor = PDBDRV_PRESCALER_1MULT; + userConfig->trgInSel = PDBDRV_TRGSEL_TRGGER_SOFTWARE; + userConfig->pdbie = false; + userConfig->mult = PDBDRV_MULT_FACTOR_1; + userConfig->cMode = PDBDRV_CONT_CONTINUOUS; + + userConfig->dlyCfg.modCnt = 60000; + userConfig->dlyCfg.idlyCnt = 0; + + PdbDrv_ChType ch; + PdbDrv_PreChType preCh; + PdbDrv_PoChType poCh; + for(ch = PDBDRV_CHANNEL0; ch < PDBDRV_CH_NUMBER; ch++) + { + for(preCh = PDBDRV_PRE_CHANNEL0; preCh < PDBDRV_PRE_CH_NUMBER; preCh++) + { + userConfig->preTrgCfg.mode[ch][preCh] = PDBDRV_PRETRG_DISABLE; + userConfig->dlyCfg.dlyCnt[ch][preCh] = 0; + } + } + userConfig->preTrgCfg.mode[0][0] = PDBDRV_PRETRG_BYPASSED_MODE; + + for(poCh = PDBDRV_PO_CHANNEL0; poCh < PDBDRV_PO_CH_NUMBER; poCh++) + { + userConfig->poCfg.poen[poCh] = false; + userConfig->poCfg.dly1[poCh] = 0; + userConfig->poCfg.dly2[poCh] = 0; + } +} + +void PdbDrv_Configure(PdbDrvType *obj, const PdbDrv_ConfigType *userConfig) +{ + PdbDrv_ChType ch; + PdbDrv_PreChType preCh; + PdbDrv_PoChType poCh; + + /* Disable PDB */ + PdbDrv_PdbDisable(obj); + + /* Delay count configuration */ + PdbReg_SetModReg(obj->pdbReg, userConfig->dlyCfg.modCnt); + PdbReg_SetIdlyReg(obj->pdbReg, userConfig->dlyCfg.idlyCnt); + for(ch = PDBDRV_CHANNEL0; ch < PDBDRV_CH_NUMBER; ch++) + { + for(preCh = PDBDRV_PRE_CHANNEL0; preCh < PDBDRV_PRE_CH_NUMBER; preCh++) + { + PdbReg_SetChnDlyReg(obj->pdbReg, userConfig->dlyCfg.dlyCnt[ch][preCh], ch, preCh); + } + } + + /* Pre-trigger channel configuration */ + PdbDrv_ConfigPreTrg(obj, &userConfig->preTrgCfg); + + /* General configuration*/ + PdbReg_SetPdbeieReg(obj->pdbReg, (uint8_t)userConfig->pdbeie); + PdbReg_SetDmaenReg(obj->pdbReg, (uint8_t)userConfig->dmaen); + PdbReg_SetPrescalerReg(obj->pdbReg, userConfig->prescalerFactor); + PdbReg_SetTrgselReg(obj->pdbReg, (uint8_t)userConfig->trgInSel); + PdbReg_SetPdbieReg(obj->pdbReg, (uint8_t)userConfig->pdbie); + PdbReg_SetMultReg(obj->pdbReg, userConfig->mult); + PdbReg_SetContReg(obj->pdbReg, (uint8_t)userConfig->cMode); + + /* Pulse out configuration*/ + uint8_t poen = 0; + + for(poCh = PDBDRV_PO_CHANNEL0; poCh < PDBDRV_PO_CH_NUMBER; poCh++) + { + uint32_t tmp; + tmp = (userConfig->poCfg.dly1[poCh] << PDB_POnDLY_DLY1_SHIFT) | (userConfig->poCfg.dly2[poCh] << PDB_POnDLY_DLY2_SHIFT); + + /*! \note dly1 & dly2 need at the same time to write*/ + PdbReg_SetPonDlyReg(obj->pdbReg, tmp, poCh); + + if(userConfig->poCfg.poen[poCh]) + { + poen |= PDBDRV_PO_ENABLE << poCh; + } + } + PdbReg_SetPoenReg(obj->pdbReg, poen); + + /* Load delay count first*/ + PdbDrv_EnablePdb(obj); + PdbReg_SetLdmodReg(obj->pdbReg, (uint8_t)PDBDRV_LDMOD_LOAD_VAL_IMMEDIATELY); + PdbDrv_LoadCmd(obj); + PdbDrv_PdbDisable(obj); + + /* Load mode configuration */ + PdbReg_SetLdmodReg(obj->pdbReg, (uint8_t)userConfig->ldmode); + + /*! \note When enable PDB depend on user(use PdbDrv_EnablePdb for enable PDB)*/ +} + +void PdbDrv_GetConfig(const PdbDrvType *obj, PdbDrv_ConfigType *userConfig) +{ + PdbDrv_ChType ch; + PdbDrv_PreChType preCh; + PdbDrv_PoChType poCh; + + /* Get general configuration */ + userConfig->ldmode = (PdbDrv_LdmodType)(PdbReg_GetLdmodReg(obj->pdbReg)); + userConfig->pdbeie = PdbReg_GetPdbeieReg(obj->pdbReg); + userConfig->dmaen = PdbReg_GetDmaenReg(obj->pdbReg); + userConfig->prescalerFactor = (PdbDrv_PrescalerType)PdbReg_GetPrescalerReg(obj->pdbReg); + userConfig->trgInSel = (PdbDrv_TrgselType)PdbReg_GetTrgselReg(obj->pdbReg); + userConfig->pdbie = PdbReg_GetPdbieReg(obj->pdbReg); + userConfig->mult = (PdbDrv_MultFactorType)PdbReg_GetMultReg(obj->pdbReg); + userConfig->cMode = (PdbDrv_ContType)PdbReg_GetContReg(obj->pdbReg); + + /* Get pre-trigger channel configuration */ + PdbDrv_PreTrgType preTrgCfg; + PdbDrv_GetPreTrgCfg(obj, &preTrgCfg); + + /* Get delay count configuration */ + userConfig->dlyCfg.modCnt = PdbReg_GetModReg(obj->pdbReg); + userConfig->dlyCfg.idlyCnt = PdbReg_GetIdlyReg(obj->pdbReg); + for(ch = PDBDRV_CHANNEL0; ch < PDBDRV_CH_NUMBER; ch++) + { + for(preCh = PDBDRV_PRE_CHANNEL0; preCh < PDBDRV_PRE_CH_NUMBER; preCh++) + { + userConfig->dlyCfg.dlyCnt[ch][preCh] = PdbReg_GetChnDlyReg(obj->pdbReg, ch, preCh); + userConfig->preTrgCfg.mode[ch][preCh] = preTrgCfg.mode[ch][preCh]; + } + } + + /* Get pulse out configuration */ + uint8_t poen = PdbReg_GetPoenReg(obj->pdbReg); + for(poCh = PDBDRV_PO_CHANNEL0; poCh < PDBDRV_PO_CH_NUMBER; poCh++) + { + userConfig->poCfg.poen[poCh] = (poen >> poCh) & PDBDRV_PO_ENABLE; + userConfig->poCfg.dly1[poCh] = PdbReg_GetPonDly1Reg(obj->pdbReg, poCh); + userConfig->poCfg.dly2[poCh] = PdbReg_GetPonDly2Reg(obj->pdbReg, poCh); + } +} + +void PdbDrv_ConfigDly(PdbDrvType *obj, const PdbDrv_DlyCfgType *userConfig) +{ + PdbDrv_ChType ch; + PdbDrv_PreChType preCh; + + /* Delay count configuration */ + PdbReg_SetModReg(obj->pdbReg, userConfig->modCnt); + PdbReg_SetIdlyReg(obj->pdbReg, userConfig->idlyCnt); + for(ch = PDBDRV_CHANNEL0; ch < PDBDRV_CH_NUMBER; ch++) + { + for(preCh = PDBDRV_PRE_CHANNEL0; preCh < PDBDRV_PRE_CH_NUMBER; preCh++) + { + PdbReg_SetChnDlyReg(obj->pdbReg, userConfig->dlyCnt[ch][preCh], ch, preCh); + } + } + + /*! \note When effective delay count depend on user & load mode(use PdbDrv_LoadCmd for load)*/ +} + +void PdbDrv_GetConfigDly(const PdbDrvType *obj, PdbDrv_DlyCfgType *userConfig) +{ + PdbDrv_ChType ch; + PdbDrv_PreChType preCh; + + /* Get delay count configuration */ + userConfig->modCnt = PdbReg_GetModReg(obj->pdbReg); + userConfig->idlyCnt = PdbReg_GetIdlyReg(obj->pdbReg); + for(ch = PDBDRV_CHANNEL0; ch < PDBDRV_CH_NUMBER; ch++) + { + for(preCh = PDBDRV_PRE_CHANNEL0; preCh < PDBDRV_PRE_CH_NUMBER; preCh++) + { + userConfig->dlyCnt[ch][preCh] = PdbReg_GetChnDlyReg(obj->pdbReg, ch, preCh); + } + } + + /*! \note When effective delay count depend on user(use PdbDrv_LoadCmd for load)*/ +} + +void PdbDrv_ConfigPo(PdbDrvType *obj, const PdbDrv_PoCfgType *userConfig) +{ + PdbDrv_PoChType poCh; + + /* Pulse out configuration */ + + uint8_t poen = 0; + for(poCh = PDBDRV_PO_CHANNEL0; poCh < PDBDRV_PO_CH_NUMBER; poCh++) + { + uint32_t tmp; + tmp = (userConfig->dly1[poCh] << PDB_POnDLY_DLY1_SHIFT) | (userConfig->dly2[poCh] << PDB_POnDLY_DLY2_SHIFT); + PdbReg_SetPonDlyReg(obj->pdbReg, tmp, poCh); + if(userConfig->poen[poCh]) + { + poen |= PDBDRV_PO_ENABLE << poCh; + } + } + PdbReg_SetPoenReg(obj->pdbReg, poen); + + /*! \note When effective delay count depend on user & load mode(use PdbDrv_LoadCmd for load)*/ +} + +void PdbDrv_GetConfigPo(const PdbDrvType *obj, PdbDrv_PoCfgType *userConfig) +{ + PdbDrv_PoChType poCh; + + /* Pulse out configuration */ + uint8_t poen = 0; + poen = PdbReg_GetPoenReg(obj->pdbReg); + for(poCh = PDBDRV_PO_CHANNEL0; poCh < PDBDRV_PO_CH_NUMBER; poCh++) + { + userConfig->dly1[poCh] = PdbReg_GetPonDly1Reg(obj->pdbReg, poCh); + userConfig->dly2[poCh] = PdbReg_GetPonDly2Reg(obj->pdbReg, poCh); + uint8_t poChPoen = (poen >> poCh) & PDBDRV_PO_ENABLE; + if(poChPoen == 1U) + { + userConfig->poen[poCh] = true; + } + } +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/pdb/pdb_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/pdb/pdb_drv.h new file mode 100644 index 0000000..b87a9f4 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/pdb/pdb_drv.h @@ -0,0 +1,481 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PDB_DRV_H_ +#define _PDB_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of PDB module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup pdb_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + *******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief PDB type of LDMOD + */ +typedef enum +{ + /*!< The internal registers are loaded with the values from their buffers, immediately after 1 is written to LDOK. */ + PDBDRV_LDMOD_LOAD_VAL_IMMEDIATELY = 0U, + + /*!< The internal registers are loaded with the values from their buffers when the PDB counter (CNT) = MOD + 1 CNT delay elapsed, after 1 is written to LDOK. */ + PDBDRV_LDMOD_LOAD_VAL_AT_MODULO_COUNTER = 1U, + + /*!< The internal registers are loaded with the values from their buffers when a trigger input event is detected, after 1 is written to LDOK.*/ + PDBDRV_LDMOD_LOAD_VAL_AT_NEXT_TRIGGER = 2U, + + /*!< The internal registers are loaded with the values from their buffers when either the PDB counter (CNT) = MOD + 1 CNT delay elapsed, or a trigger + input event is detected, after 1 is written to LDOK.*/ + PDBDRV_LDMOD_LOAD_VAL_AT_MODULO_COUNTER_OR_NEXT_TRIGGER = 3U, +} PdbDrv_LdmodType; + +/*! \brief PDB type of trigger input source select + * Trigger-In 1 ~ Trigger-In 14 is reserved + */ +typedef enum +{ + PDBDRV_TRGSEL_TRGGER_IN_0 = 0U, /*!< Select Trigger channel 0*/ + PDBDRV_TRGSEL_TRGGER_IN_1 = 1U, /*!< Select Trigger channel 1*/ + PDBDRV_TRGSEL_TRGGER_IN_2 = 2U, /*!< Select Trigger channel 2*/ + PDBDRV_TRGSEL_TRGGER_IN_3 = 3U, /*!< Select Trigger channel 3*/ + PDBDRV_TRGSEL_TRGGER_IN_4 = 4U, /*!< Select Trigger channel 4*/ + PDBDRV_TRGSEL_TRGGER_IN_5 = 5U, /*!< Select Trigger channel 5*/ + PDBDRV_TRGSEL_TRGGER_IN_6 = 6U, /*!< Select Trigger channel 6*/ + PDBDRV_TRGSEL_TRGGER_IN_7 = 7U, /*!< Select Trigger channel 7*/ + PDBDRV_TRGSEL_TRGGER_IN_8 = 8U, /*!< Select Trigger channel 8*/ + PDBDRV_TRGSEL_TRGGER_IN_9 = 9U, /*!< Select Trigger channel 9*/ + PDBDRV_TRGSEL_TRGGER_IN_10 = 10U, /*!< Select Trigger channel 10*/ + PDBDRV_TRGSEL_TRGGER_IN_11 = 11U, /*!< Select Trigger channel 11*/ + PDBDRV_TRGSEL_TRGGER_IN_12 = 12U, /*!< Select Trigger channel 12*/ + PDBDRV_TRGSEL_TRGGER_IN_13 = 13U, /*!< Select Trigger channel 13*/ + PDBDRV_TRGSEL_TRGGER_IN_14 = 14U, /*!< Select Trigger channel 14*/ + PDBDRV_TRGSEL_TRGGER_SOFTWARE = 15U, /*!< Select Trigger form Software*/ +} PdbDrv_TrgselType; + +/*! \brief PDB type of Pre-Trigger channel selection. + */ +typedef enum +{ + PDBDRV_PRE_CHANNEL0 = 0U, /*!< Select Pre-Trigger channel 0*/ + PDBDRV_PRE_CHANNEL1 = 1U, /*!< Select Pre-Trigger channel 1*/ + PDBDRV_PRE_CHANNEL2 = 2U, /*!< Select Pre-Trigger channel 2*/ + PDBDRV_PRE_CHANNEL3 = 3U, /*!< Select Pre-Trigger channel 3*/ + PDBDRV_PRE_CHANNEL4 = 4U, /*!< Select Pre-Trigger channel 4*/ + PDBDRV_PRE_CHANNEL5 = 5U, /*!< Select Pre-Trigger channel 5*/ + PDBDRV_PRE_CHANNEL6 = 6U, /*!< Select Pre-Trigger channel 6*/ + PDBDRV_PRE_CHANNEL7 = 7U, /*!< Select Pre-Trigger channel 7*/ + PDBDRV_PRE_CH_NUMBER = 8U, /*!< Pre-Trigger channel number*/ +} PdbDrv_PreChType; + +/*! \brief PDB type of channel selection. + */ +typedef enum +{ + PDBDRV_CHANNEL0 = 0U, /*!< Select channel 0*/ + PDBDRV_CHANNEL1 = 1U, /*!< Select channel 1*/ + PDBDRV_CH_NUMBER = 2U, /*!< channel number*/ +} PdbDrv_ChType; + +/*! \brief PDB type of Pulse out channel selection. + */ +typedef enum +{ + PDBDRV_PO_CHANNEL0 = 0U, /*!< Select pulse out channel 0*/ + PDBDRV_PO_CH_NUMBER = 1U, /*!< Pulse out channel number*/ +} PdbDrv_PoChType; + +/*! \brief PDB type of CONT + */ +typedef enum +{ + PDBDRV_CONT_ONE_SHOT = 0U, /*!< PDB operation in One-Shot mode*/ + PDBDRV_CONT_CONTINUOUS = 1U, /*!< PDB operation in Continuous mode*/ +} PdbDrv_ContType; + +/*! \brief PDB type of PRESCALER + */ +typedef enum +{ + PDBDRV_PRESCALER_1MULT = 0U, /*!< Counting uses the peripheral clock divided by MULT (the multiplication factor). */ + PDBDRV_PRESCALER_2MULT = 1U, /*!< Counting uses the peripheral clock divided by 2 x MULT (the multiplication factor). */ + PDBDRV_PRESCALER_4MULT = 2U, /*!< Counting uses the peripheral clock divided by 4 x MULT (the multiplication factor). */ + PDBDRV_PRESCALER_8MULT = 3U, /*!< Counting uses the peripheral clock divided by 8 x MULT (the multiplication factor). */ + PDBDRV_PRESCALER_16MULT = 4U, /*!< Counting uses the peripheral clock divided by 16 x MULT (the multiplication factor). */ + PDBDRV_PRESCALER_32MULT = 5U, /*!< Counting uses the peripheral clock divided by 32 x MULT (the multiplication factor). */ + PDBDRV_PRESCALER_64MULT = 6U, /*!< Counting uses the peripheral clock divided by 64 x MULT (the multiplication factor). */ + PDBDRV_PRESCALER_128MULT = 7U, /*!< Counting uses the peripheral clock divided by 128 x MULT (the multiplication factor). */ +} PdbDrv_PrescalerType; + +/*! \brief PDB type of MULT + */ +typedef enum +{ + PDBDRV_MULT_FACTOR_1 = 0U, /*!< Multiplication factor is 1*/ + PDBDRV_MULT_FACTOR_10 = 1U, /*!< Multiplication factor is 10*/ + PDBDRV_MULT_FACTOR_20 = 2U, /*!< Multiplication factor is 20*/ + PDBDRV_MULT_FACTOR_40 = 3U, /*!< Multiplication factor is 40*/ +} PdbDrv_MultFactorType; + +/*! \brief PDB type of pre-trigger mode + */ +typedef enum +{ + PDBDRV_PRETRG_DISABLE = 0U, /*!< PDB Channel Pre-Trigger disable*/ + PDBDRV_PRETRG_BYPASSED_MODE = 1U, /*!< PDB Channel Pre-Trigger bypassed enable*/ + PDBDRV_PRETRG_DELAY_MODE = 2U, /*!< PDB Channel Pre-Trigger delay enable*/ + PDBDRV_PRETRG_BB_MODE = 3U, /*!< PDB Channel Pre-Trigger Back-to-Back operation enable*/ +} PdbDrv_PreTrgModeType; + +/*! \brief Definition of delay count configuration of PDB driver + */ +typedef struct _PdbDrv_DlyCfgType_ +{ + uint16_t modCnt; /*!port = port; + obj->gpio = gpio; +} + +void PinsDrv_SetPullSel(PinsDrvType *obj, uint32_t pin, PinsDrv_InternalPullModeType pullMode) +{ + if(PORT_PCR_COUNT <= pin) + { + return; + } + + /* Pull-down and pull-up cannot be enabled at the same time */ + switch(pullMode) + { + case PINSDRV_INTERNAL_NO_PULL: + PortReg_SetPcrPde(obj->port, pin, 0); /* disable pull-down */ + PortReg_SetPcrPue(obj->port, pin, 0); /* disable pull-up */ + break; + case PINSDRV_INTERNAL_PULL_DOWN: + PortReg_SetPcrPde(obj->port, pin, 1); /* enable pull-down */ + PortReg_SetPcrPue(obj->port, pin, 0); /* disable pull-up */ + break; + case PINSDRV_INTERNAL_PULL_UP: + PortReg_SetPcrPde(obj->port, pin, 0); /* disable pull-down */ + PortReg_SetPcrPue(obj->port, pin, 1); /* enable pull-up */ + break; + default: + break; + } +} + +void PinsDrv_SetPinPasFlt(PinsDrvType *obj, uint32_t pin, bool enable) +{ + if(PORT_PCR_COUNT <= pin) + { + return; + } + + PortReg_SetPcrPasFlt(obj->port, pin, enable); +} + +void PinsDrv_SetPinSr(PinsDrvType *obj, uint32_t pin, bool enable) +{ + if(PORT_PCR_COUNT <= pin) + { + return; + } + + PortReg_SetPcrSr(obj->port, pin, enable); +} + +void PinsDrv_SetPinDrvStr(PinsDrvType *obj, uint32_t pin, bool enable) +{ + if(PORT_PCR_COUNT <= pin) + { + return; + } + + PortReg_SetPcrDrvStr(obj->port, pin, enable); +} + +void PinsDrv_SetPinOde(PinsDrvType *obj, uint32_t pin, bool enable) +{ + if(PORT_PCR_COUNT <= pin) + { + return; + } + + PortReg_SetPcrOde(obj->port, pin, enable); +} +void PinsDrv_SetMuxModeSel(PinsDrvType *obj, uint32_t pin, PinsDrv_MuxType mux) +{ + /* analog feature */ + if(mux == PINSDRV_PIN_DISABLED) + { + PortReg_SetPcrMux(obj->port, pin, mux); + /* Analog pin, need enable analog feature */ + PortReg_SetPcrAen(obj->port, pin, 1); + } + else + { + /* Other functions, must disable analog feature */ + PortReg_SetPcrAen(obj->port, pin, 0); + PortReg_SetPcrMux(obj->port, pin, mux); + } +} + +void PinsDrv_SetPinLock(PinsDrvType *obj, uint32_t pin, bool enable) +{ + if(PORT_PCR_COUNT <= pin) + { + return; + } + + PortReg_SetPcrLock(obj->port, pin, enable); +} + +void PinsDrv_SetPinIntSel(PinsDrvType *obj, uint32_t pin, PinsDrv_InterruptConfigType intConfig) +{ + if(PORT_PCR_COUNT <= pin) + { + return; + } + + PortReg_SetPcrIrqCfg(obj->port, pin, intConfig); +} + +PinsDrv_InterruptConfigType PinsDrv_GetPinIntSel(const PinsDrvType *obj, uint32_t pin) +{ + PinsDrv_InterruptConfigType retval; + if(PORT_PCR_COUNT <= pin) + { + retval = PINSDRV_DMA_INT_RESERVED; + } + else + { + retval = (PinsDrv_InterruptConfigType)PortReg_GetPcrIrqCfg(obj->port, pin); + } + return retval; +} + +void PinsDrv_ClearPinIntFlagCmd(PinsDrvType *obj, uint32_t pin) +{ + if(PORT_PCR_COUNT <= pin) + { + return; + } + + PortReg_SetPcrIsf(obj->port, pin, 1); /* Write 1 to clear */ +} + +void PinsDrv_EnableDigitalFilter(PinsDrvType *obj, uint32_t pin) +{ + if(PORT_PCR_COUNT <= pin) + { + return; + } + + uint32_t tmp = PortReg_GetDferEn(obj->port); + tmp |= (uint32_t)1U << pin; + PortReg_SetDferEn(obj->port, tmp); +} + +void PinsDrv_DisableDigitalFilter(PinsDrvType *obj, uint32_t pin) +{ + if(PORT_PCR_COUNT <= pin) + { + return; + } + + uint32_t tmp = PortReg_GetDferEn(obj->port); + tmp &= ~((uint32_t)1U << pin); + PortReg_SetDferEn(obj->port, tmp); +} + +void PinsDrv_ConfigDigitalFilter(PinsDrvType *obj, const PinsDrv_FilterConfigType *config) +{ + PortReg_SetDfwrLen(obj->port, config->width); +} + +uint32_t PinsDrv_GetPortIntFlag(const PinsDrvType *obj) +{ + return PortReg_GetIsfrIsf(obj->port); +} + +void PinsDrv_ClearPortIntFlagCmd(PinsDrvType *obj) +{ + PortReg_SetIsfrIsf(obj->port, 0xffffffff); +} + +void PinsDrv_SetGlobalPinControl(PinsDrvType *obj, uint16_t pins, uint16_t value, PinsDrv_GlobalControlPinsType whichHalf) +{ + uint32_t mask = 0; + /* keep only available fields */ + mask |= PORT_PCR_PUE_MASK; + mask |= PORT_PCR_PDE_MASK; + mask |= PORT_PCR_PAS_FLT_MASK; + mask |= PORT_PCR_SR_MASK; + mask |= PORT_PCR_DRV_STR_MASK; + mask |= PORT_PCR_ODE_MASK; + mask |= PORT_PCR_MUX_MASK; + mask |= PORT_PCR_LOCK_MASK; + mask &= value; + + /* analog feature */ + if(((mask & PORT_PCR_MUX_MASK) >> PORT_PCR_MUX_SHIFT) == PINSDRV_PIN_DISABLED) + { + /* Analog pin, need enable analog feature */ + mask |= PORT_PCR_AEN_MASK; + } + + mask <<= 16; + mask += pins; + + switch(whichHalf) + { + case PINDRV_GLOBAL_CONTROL_LOWER_HALF_PINS: + PortReg_SetGpclr(obj->port, mask); + break; + case PINDRV_GLOBAL_CONTROL_UPPER_HALF_PINS: + PortReg_SetGpchr(obj->port, mask); + break; + default: + break; + } +} + +void PinsDrv_SetGlobalIntControl(PinsDrvType *obj, uint16_t pins, uint16_t value, PinsDrv_GlobalControlPinsType whichHalf) +{ + uint32_t mask = 0; + + mask = ((uint32_t)value << 16) + pins; + + switch(whichHalf) + { + case PINDRV_GLOBAL_CONTROL_LOWER_HALF_PINS: + PortReg_SetGiclrInt(obj->port, mask); + break; + case PINDRV_GLOBAL_CONTROL_UPPER_HALF_PINS: + PortReg_SetGichrInt(obj->port, mask); + break; + default: + break; + } +} + +uint32_t PinsDrv_GetPinsDirection(const PinsDrvType *obj) +{ + return GpioReg_GetPddrDir(obj->gpio); +} + +void PinsDrv_SetPinDirection(PinsDrvType *obj, uint32_t pin, uint8_t direction) +{ + uint32_t pinDirections = GpioReg_GetPddrDir(obj->gpio); + pinDirections &= (uint32_t)(~((uint32_t)1U << pin)); + pinDirections |= (uint32_t)((uint32_t)direction << pin); + GpioReg_SetPddrDir(obj->gpio, pinDirections); +} + +void PinsDrv_SetPortInputDisable(PinsDrvType *obj, uint32_t mask) +{ + GpioReg_SetPidrInDisable(obj->gpio, mask); +} + +uint32_t PinsDrv_GetPortInputDisable(const PinsDrvType *obj) +{ + return GpioReg_GetPidrInDisable(obj->gpio); +} + +void PinsDrv_WritePin(PinsDrvType *obj, uint32_t pin, uint8_t value) +{ + uint32_t pinDirections = GpioReg_GetPdorDatOut(obj->gpio); + pinDirections &= (uint32_t)(~((uint32_t)1U << pin)); + pinDirections |= (uint32_t)((uint32_t)value << pin); + GpioReg_SetPdorDatOut(obj->gpio, pinDirections); +} + +void PinsDrv_WritePins(PinsDrvType *obj, uint32_t mask) +{ + GpioReg_SetPdorDatOut(obj->gpio, mask); +} + +uint8_t PinsDrv_GetPinOutput(const PinsDrvType *obj, uint32_t pin) +{ + return (uint8_t)((GpioReg_GetPdorDatOut(obj->gpio) >> pin) & 0x01); +} + +uint32_t PinsDrv_GetPinsOutput(const PinsDrvType *obj) +{ + return GpioReg_GetPdorDatOut(obj->gpio); +} + +void PinsDrv_SetPin(PinsDrvType *obj, uint32_t pin) +{ + GpioReg_SetPsorDatSet(obj->gpio, (uint32_t)1U << pin); +} + +void PinsDrv_SetPins(PinsDrvType *obj, uint32_t mask) +{ + GpioReg_SetPsorDatSet(obj->gpio, mask); +} + +void PinsDrv_ClearPin(PinsDrvType *obj, uint32_t pin) +{ + GpioReg_SetPcorDatClr(obj->gpio, (uint32_t)1U << pin); +} + +void PinsDrv_ClearPins(PinsDrvType *obj, uint32_t mask) +{ + GpioReg_SetPcorDatClr(obj->gpio, mask); +} + +void PinsDrv_TogglePin(PinsDrvType *obj, uint32_t pin) +{ + GpioReg_SetPtorDatTog(obj->gpio, (uint32_t)1U << pin); +} + +void PinsDrv_TogglePins(PinsDrvType *obj, uint32_t mask) +{ + GpioReg_SetPtorDatTog(obj->gpio, mask); +} + +uint8_t PinsDrv_ReadPin(PinsDrvType *obj, uint32_t pin) +{ + uint8_t retval = 0; + uint32_t pinsData = GpioReg_GetPdirDatIn(obj->gpio) & ((uint32_t)1U << pin); + if(pinsData == 0) + { + retval = 0; + } + else + { + retval = 1; + } + + return retval; +} + +uint32_t PinsDrv_ReadPins(const PinsDrvType *obj) +{ + return GpioReg_GetPdirDatIn(obj->gpio); +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/pins/pins_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/pins/pins_drv.h new file mode 100644 index 0000000..334a12a --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/pins/pins_drv.h @@ -0,0 +1,539 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PINS_DRV_H_ +#define _PINS_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of pins + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup pins_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Internal resistor pull feature selection + */ +typedef enum +{ + PINSDRV_INTERNAL_NO_PULL = 0x00U, /*!< Internal pull-down or pull-up resistor is not enabled */ + PINSDRV_INTERNAL_PULL_DOWN = 0x01U, /*!< Internal pull-down resistor is enabled */ + PINSDRV_INTERNAL_PULL_UP = 0x02U, /*!< Internal pull-up resistor is enabled */ +} PinsDrv_InternalPullModeType; + +/*! \brief Configures the Pin mux selection + */ +typedef enum +{ + PINSDRV_PIN_DISABLED = 0U, /*!< corresponding pin is disabled, but is used as an analog pin */ + PINSDRV_MUX_AS_GPIO = 1U, /*!< corresponding pin is configured as GPIO */ + PINSDRV_MUX_ALT2 = 2U, /*!< chip-specific */ + PINSDRV_MUX_ALT3 = 3U, /*!< chip-specific */ + PINSDRV_MUX_ALT4 = 4U, /*!< chip-specific */ + PINSDRV_MUX_ALT5 = 5U, /*!< chip-specific */ + PINSDRV_MUX_ALT6 = 6U, /*!< chip-specific */ + PINSDRV_MUX_ALT7 = 7U, /*!< chip-specific */ +} PinsDrv_MuxType; + +/*! \brief Configures the interrupt generation condition. + */ +typedef enum +{ + PINSDRV_DMA_INT_DISABLED = 0x0U, /*!< Interrupt/DMA request is disabled. */ + PINSDRV_DMA_RISING_EDGE = 0x1U, /*!< DMA request on rising edge. */ + PINSDRV_DMA_FALLING_EDGE = 0x2U, /*!< DMA request on falling edge. */ + PINSDRV_DMA_EITHER_EDGE = 0x3U, /*!< DMA request on either edge. */ + PINSDRV_INT_LOGIC_ZERO = 0x8U, /*!< Interrupt when logic 0. */ + PINSDRV_INT_RISING_EDGE = 0x9U, /*!< Interrupt on rising edge. */ + PINSDRV_INT_FALLING_EDGE = 0xAU, /*!< Interrupt on falling edge. */ + PINSDRV_INT_EITHER_EDGE = 0xBU, /*!< Interrupt on either edge. */ + PINSDRV_INT_LOGIC_ONE = 0xCU, /*!< Interrupt when logic 1. */ + PINSDRV_DMA_INT_RESERVED = 0xFU, /*!< reserved. */ +} PinsDrv_InterruptConfigType; + +/*! \brief The digital filter configuration + */ +typedef struct +{ + uint8_t width; /*!< The digital filter width value */ +} PinsDrv_FilterConfigType; + +/*! \brief The port global pin/interuppt control registers + */ +typedef enum +{ + PINDRV_GLOBAL_CONTROL_LOWER_HALF_PINS = 0U, /*!< the lower of pins is configured */ + PINDRV_GLOBAL_CONTROL_UPPER_HALF_PINS = 1U /*!< the upper of pins is configured */ +} PinsDrv_GlobalControlPinsType; + +/* Forward declaration of PORT register */ +struct _PortRegType_; +/* Forward declaration of PORT register */ +struct _GpioRegType_; + +/*! \brief The definition of pins driver class + */ +typedef struct _PinsDrvType_ +{ + struct _PortRegType_ *port; /*!< pointer to the port register */ + struct _GpioRegType_ *gpio; /*!< pointer to the gpio register */ +} PinsDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the pins driver module + * + * This function initializes pins driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] port : pointer to PORT register instance + * \param[in] gpio : pointer to GPIO register instance + * \param[in] func : the function of setting digital filter clock + */ +extern void PinsDrv_Init(PinsDrvType *obj, struct _PortRegType_ *port, struct _GpioRegType_ *gpio); + +/*! \brief Configures the internal resistor. + * + * This function configures the internal resistor. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + * \param[in] pullMode : the pull mode + */ +extern void PinsDrv_SetPullSel(PinsDrvType *obj, uint32_t pin, PinsDrv_InternalPullModeType pullMode); + +/*! \brief Configures the port pin passive filter. + * + * This function Configures the port pin passive filter. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + * \param[in] enable : passive filter enable/disable + * - 0 : corresponding pin is set to disable passive filter + * - 1 : corresponding pin is set to enable passive filter + */ +extern void PinsDrv_SetPinPasFlt(PinsDrvType *obj, uint32_t pin, bool enable); + +/*! \brief Configures the port pin slew rate. + * + * This function Configures the port pin slew rate. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + * \param[in] enable : fast/slow slew rate + * - 0 : corresponding pin is set to slow slew rate + * - 1 : corresponding pin is set to fast slew rate + */ +extern void PinsDrv_SetPinSr(PinsDrvType *obj, uint32_t pin, bool enable); + +/*! \brief Configures the port pin drive strength. + * + * This function Configures the port pin drive strength. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + * \param[in] enable : high/low drive strength + * - 0 : corresponding pin is set to low drive strength + * - 1 : corresponding pin is set to high drive strength + */ +extern void PinsDrv_SetPinDrvStr(PinsDrvType *obj, uint32_t pin, bool enable); + +/*! \brief Configures the port pin output mode. + * + * This function Configures the port pin output mode. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + * \param[in] enable : ode/push-pull output + * - 0 : corresponding pin is set to push-pull output + * - 1 : corresponding pin is set to ode output + */ +extern void PinsDrv_SetPinOde(PinsDrvType *obj, uint32_t pin, bool enable); + +/*! \brief Configures the pin muxing. + * + * This function configures the pin muxing. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + * \param[in] mux : Pin muxing slot selection + */ +extern void PinsDrv_SetMuxModeSel(PinsDrvType *obj, uint32_t pin, PinsDrv_MuxType mux); + +/*! \brief Configures the port pin register lock or unlock. + * + * This function Configures the port pin register lock or unlock. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + * \param[in] enable : lock register + * - 0 : Pin Control Register fields [15:0] are not locked + * - 1 : Pin Control Register fields [15:0] are locked and cannot be updated until the next system reset + */ +extern void PinsDrv_SetPinLock(PinsDrvType *obj, uint32_t pin, bool enable); + +/*! \brief Configures the port pin interrupt/DMA request. + * + * This function configures the port pin interrupt/DMA request. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + * \param[in] intConfig : Interrupt configuration + */ +extern void PinsDrv_SetPinIntSel(PinsDrvType *obj, uint32_t pin, PinsDrv_InterruptConfigType intConfig); + +/*! \brief Gets the current port pin interrupt/DMA request configuration. + * + * This function gets the current port pin interrupt/DMA request configuration. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + * \return Interrupt configuration + */ +extern PinsDrv_InterruptConfigType PinsDrv_GetPinIntSel(const PinsDrvType *obj, uint32_t pin); + +/*! \brief Clears the individual pin-interrupt status flag. + * + * This function clears the individual pin-interrupt status flag. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + */ +extern void PinsDrv_ClearPinIntFlagCmd(PinsDrvType *obj, uint32_t pin); + +/*! \brief Enables digital filter for digital pin muxing + * + * This function enables digital filter feature for digital pin muxing + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + */ +extern void PinsDrv_EnableDigitalFilter(PinsDrvType *obj, uint32_t pin); + +/*! \brief Disables digital filter for digital pin muxing + * + * This function disables digital filter feature for digital pin muxing + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number + */ +extern void PinsDrv_DisableDigitalFilter(PinsDrvType *obj, uint32_t pin); + +/*! \brief Configures digital filter for port with given configuration + * + * This function configures digital filter for port with given configuration. + * + * User should configure the port filter clock first with the clock module. + * + * \note Updating the filter configuration must be done only after all filters are disabled. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] config : the digital filter configuration struct + */ +extern void PinsDrv_ConfigDigitalFilter(PinsDrvType *obj, const PinsDrv_FilterConfigType *config); + +/*! \brief Reads the entire port interrupt status flag + * + * This function reads the entire port interrupt status flag. + * + * \param[in] obj : pointer to pins driver instance + * \return All 32 pin interrupt status flags + */ +extern uint32_t PinsDrv_GetPortIntFlag(const PinsDrvType *obj); + +/*! \brief Clears the entire port interrupt status flag. + * + * This function clears the entire port interrupt status flag. + * + * \param[in] obj : pointer to pins driver instance + */ +extern void PinsDrv_ClearPortIntFlagCmd(PinsDrvType *obj); + +/*! \brief Quickly configures multiple pins with the same pin configuration. + * + * This function quickly configures multiple pins within the one port for the same peripheral + * function with the same pin configuration. Supports up to 16 pins with the lower or upper + * half of pin registers at the same port. + * + * \note The set global interrupt control function (PinsDrv_SetGlobalIntControl) cannot be + * configured if you ever used this function at the same port + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pins : Pin mask where each bit represents one pin. For each bit: + * - 0 : pins corresponding to bits with value of '1' is updated with the value input + * - 1 : pins corresponding to bits with value of '0' is not updated with the value input + * \param[in] value : the config value will be updated for the pins are set to '1' + * \param[in] whichHalf : the lower or upper half of pin registers at the same port + */ +extern void PinsDrv_SetGlobalPinControl(PinsDrvType *obj, uint16_t pins, uint16_t value, PinsDrv_GlobalControlPinsType whichHalf); + +/*! \brief Quickly configures multiple pins with the same interrupt configuration. + * + * This function quickly configures multiple pins within the one port for the same peripheral + * function with the same interrupt configuration. Supports up to 16 pins with the lower or + * upper half of pin registers at the same port. + * + * \note The set global pin control function (PinsDrv_SetGlobalPinControl) cannot be + * configured if you ever used this function at the same port + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pins : Pin mask where each bit represents one pin. For each bit: + * - 0 : pins corresponding to bits with value of '1' is updated with the value input + * - 1 : pins corresponding to bits with value of '0' is not updated with the value input + * \param[in] value : the config value will be updated for the pins are set to '1' + * \param[in] whichHalf : the lower or upper half of pin registers at the same port + */ +extern void PinsDrv_SetGlobalIntControl(PinsDrvType *obj, uint16_t pins, uint16_t value, PinsDrv_GlobalControlPinsType whichHalf); + +/*! \brief Get the pins directions configuration for a port + * + * This function returns the current pins directions for a port. Pins + * corresponding to bits with value of '1' are configured as output and + * pins corresponding to bits with value of '0' are configured as input. + * + * \param[in] obj : pointer to pins driver instance + * \return GPIO directions. Each bit represents one pin (LSB is pin 0, MSB is pin 31). + * For each bit: + * - 0 : corresponding pin is set to input + * - 1 : corresponding pin is set to output + */ +extern uint32_t PinsDrv_GetPinsDirection(const PinsDrvType *obj); + +/*! \brief Configure the direction for a certain pin from a port + * + * This function configures the direction for the given pin, with the + * given value('1' for pin to be configured as output and '0' for pin to + * be configured as input) + * + * \note With some platforms when you want to set a pin as output only and disable + * input completely, it is required to call PinsDrv_SetPortInputDisable if platform + * has this feature. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number for which to configure the direction + * \param[in] direction : pin direction + * - 0 : corresponding pin is set to input + * - 1 : corresponding pin is set to output + */ +extern void PinsDrv_SetPinDirection(PinsDrvType *obj, uint32_t pin, uint8_t direction); + +/*! \brief Set the pins input disable state for a port + * + * This function sets the pins input state for a port. + * Pins corresponding to bits with value of '1' will not be configured as input + * and pins corresponding to bits with value of '0' will be configured + * as input. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] mask : pin mask where each bit represents one pin (LSB is pin 0, MSB is pin 31). + * For each bit: + * - 0 : corresponding pin is set to input + * - 1 : corresponding pin is not set to input + */ +extern void PinsDrv_SetPortInputDisable(PinsDrvType *obj, uint32_t mask); + +/*! \brief Get the pins input disable state for a port + * + * This function returns the current pins input state for a port. Pins + * corresponding to bits with value of '1' are not configured as input and + * pins corresponding to bits with value of '0' are configured as input. + * + * \param[in] obj : pointer to pins driver instance + * \return GPIO input state. Each bit represents one pin (LSB is pin 0, MSB is pin 31). + * For each bit: + * - 0 : corresponding pin is set to input + * - 1 : corresponding pin is not set to input + */ +extern uint32_t PinsDrv_GetPortInputDisable(const PinsDrvType *obj); + +/*! \brief Write a pin of a port with a given value + * + * This function writes the given pin from a port, with the given value + * ('0' represents LOW, '1' represents HIGH). + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number to be written + * \param[in] value : pin value to be written + * - 0 : corresponding pin is set to LOW + * - 1 : corresponding pin is set to HIGH + */ +extern void PinsDrv_WritePin(PinsDrvType *obj, uint32_t pin, uint8_t value); + +/*! \brief Write all pins of a port + * + * This function writes all pins configured as output with the values given in + * the parameter pins. '0' represents LOW, '1' represents HIGH. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] mask : pin mask to be written + * - 0 : corresponding pin is set to LOW + * - 1 : corresponding pin is set to HIGH + */ +extern void PinsDrv_WritePins(PinsDrvType *obj, uint32_t mask); + +/*! \brief Get the current output from a pin + * + * This function returns the current output that is written to a pin. Only pin + * that are configured as output will have meaningful values. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number to be read + * \return GPIO pin output + * - 0 : corresponding pin is set to LOW + * - 1 : corresponding pin is set to HIGH + */ +extern uint8_t PinsDrv_GetPinOutput(const PinsDrvType *obj, uint32_t pin); + +/*! \brief Get the current output from a port + * + * This function returns the current output that is written to a port. Only pins + * that are configured as output will have meaningful values. + * + * \param[in] obj : pointer to pins driver instance + * \return GPIO outputs. Each bit represents one pin (LSB is pin 0, MSB is pin 31). + * For each bit: + * - 0 : corresponding pin is set to LOW + * - 1 : corresponding pin is set to HIGH + */ +extern uint32_t PinsDrv_GetPinsOutput(const PinsDrvType *obj); + +/*! \brief Write pin with 'Set' value + * + * This function configures output pin in parameter to have a value of 'set' (HIGH). + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : Pin that will be set. + */ +extern void PinsDrv_SetPin(PinsDrvType *obj, uint32_t pin); + +/*! \brief Write pins with 'Set' value + * + * This function configures output pins listed in parameter pins (bits that are + * '1') to have a value of 'set' (HIGH). Pins corresponding to '0' will be + * unaffected. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] mask : Pin mask of bits to be set. Each bit represents one pin (LSB is pin 0, MSB is pin 31). + * For each bit: + * - 0: corresponding pin is unaffected + * - 1: corresponding pin is set to HIGH + */ +extern void PinsDrv_SetPins(PinsDrvType *obj, uint32_t mask); + +/*! \brief Write pin to 'Clear' value + * + * This function configures output pin in parameter to have a 'cleared' value (LOW). + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : Pin that will be cleared. + */ +extern void PinsDrv_ClearPin(PinsDrvType *obj, uint32_t pin); + +/*! \brief Write pins to 'Clear' value + * + * This function configures output pins listed in parameter pins (bits that are + * '1') to have a 'cleared' value (LOW). Pins corresponding to '0' will be + * unaffected. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] mask : Pin mask of bits to be cleared. Each bit represents one pin (LSB is pin 0, MSB is pin 31). + * For each bit: + * - 0 : corresponding pin is unaffected + * - 1 : corresponding pin is cleared(set to LOW) + */ +extern void PinsDrv_ClearPins(PinsDrvType *obj, uint32_t mask); + +/*! \brief Toggle pin value + * + * This function toggles output pin in parameter. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : Pin that will be toggled. + */ +extern void PinsDrv_TogglePin(PinsDrvType *obj, uint32_t pin); + +/*! \brief Toggle pins value + * + * This function toggles output pins listed in parameter pins (bits that are + * '1'). Pins corresponding to '0' will be unaffected. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] mask : Pin mask of bits to be toggled. Each bit represents one pin (LSB is pin 0, MSB is pin 31). + * For each bit: + * - 0 : corresponding pin is unaffected + * - 1 : corresponding pin is toggled + */ +extern void PinsDrv_TogglePins(PinsDrvType *obj, uint32_t mask); + +/*! \brief Read a pin of a port + * + * This function returns the current input value of the given pin from a port. + * Only pins configured as input will have meaningful values. + * + * \param[in] obj : pointer to pins driver instance + * \param[in] pin : pin number to read + * \return pin value + * - 0 : corresponding pin is read as LOW + * - 1 : corresponding pin is read as HIGH + */ +extern uint8_t PinsDrv_ReadPin(PinsDrvType *obj, uint32_t pin); + +/*! \brief Read input pins + * + * This function returns the current input values from a port. Only pins + * configured as input will have meaningful values. + * + * \param[in] obj : pointer to pins driver instance + * \return GPIO inputs. Each bit represents one pin (LSB is pin 0, MSB is pin 31). + * For each bit: + * - 0 : corresponding pin is read as LOW + * - 1 : corresponding pin is read as HIGH + */ +extern uint32_t PinsDrv_ReadPins(const PinsDrvType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _PINS_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/power/power_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/power/power_drv.c new file mode 100644 index 0000000..1a711d7 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/power/power_drv.c @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "../cpu/cpu_drv.h" +#include "power_drv.h" +#include "pmc_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void PowerDrv_Init(PowerDrvType *obj, struct _PmcRegType_ *pmcReg, struct _Scg2RegType_ *scg2Reg, struct _Scg1RegType_ *scg1Reg, struct _Scg0RegType_ *scg0Reg) +{ + obj->pmcReg = pmcReg; + obj->scg2Reg = scg2Reg; + obj->scg1Reg = scg1Reg; + obj->scg0Reg = scg0Reg; +} + +void PowerDrv_UnlockRegWriteAccess(PowerDrvType *obj) +{ + PmcReg_SetKey(obj->pmcReg, 0x20220509); +} + +void PowerDrv_LockRegWriteAccess(PowerDrvType *obj) +{ + PmcReg_SetKey(obj->pmcReg, 0); +} + +void PowerDrv_EnableLvwWarning(PowerDrvType *obj) +{ + PmcReg_SetDAIntfCtrlEnLvw(obj->pmcReg, true); +} + +void PowerDrv_DisableLvwWarning(PowerDrvType *obj) +{ + PmcReg_SetDAIntfCtrlEnLvw(obj->pmcReg, false); +} + +void PowerDrv_SetLvwLevel(PowerDrvType *obj, PowerDrvLvwLevelType level) +{ + PmcReg_SetDAIntfCtrlSelLvw(obj->pmcReg, level); +} + +void PowerDrv_EnableLvdDetect(PowerDrvType *obj) +{ + PmcReg_SetDAIntfCtrlEnLvd(obj->pmcReg, true); +} + +void PowerDrv_DisableLvdDetect(PowerDrvType *obj) +{ + PmcReg_SetDAIntfCtrlEnLvd(obj->pmcReg, false); +} + +void PowerDrv_EnableOtpWarning(PowerDrvType *obj) +{ + PmcReg_SetDAIntfCtrlOtpEn(obj->pmcReg, true); +} + +void PowerDrv_DisableOtpWarning(PowerDrvType *obj) +{ + PmcReg_SetDAIntfCtrlOtpEn(obj->pmcReg, false); +} + +void PowerDrv_EnableFldoDetect(PowerDrvType *obj) +{ + PmcReg_SetDAIntfCtrlEnFldoVDet(obj->pmcReg, true); +} + +void PowerDrv_DisableFldoDetect(PowerDrvType *obj) +{ + PmcReg_SetDAIntfCtrlEnFldoVDet(obj->pmcReg, false); +} + +void PowerDrv_ReleasePadKeep(PowerDrvType *obj) +{ + /* this bit is W1C, user should release it as early as possible */ + PowerDrv_UnlockRegWriteAccess(obj); + PmcReg_ClearStatusPadKeep(obj->pmcReg); + PowerDrv_LockRegWriteAccess(obj); +} + +uint8_t PowerDrv_GetStbAbortFlag(PowerDrvType *obj) +{ + uint8_t retval = 0; + retval = PmcReg_GetStatusStdbyAbortSts(obj->pmcReg); + return retval; +} + +void PowerDrv_ClrStbAbortFlag(PowerDrvType *obj) +{ + if(PmcReg_GetStatusStdbyAbortSts(obj->pmcReg)) + { + /* only clear when this bit is set, and this bit is W1C */ + PmcReg_ClearStatusStdbyAbortSts(obj->pmcReg); + } +} + +void PowerDrv_ClrAllWakupFlags(PowerDrvType *obj) +{ + /* clear all the wakeup flags */ + PowerDrv_UnlockRegWriteAccess(obj); + PmcReg_ClearWakupFlgCmpWakupEvtFlag(obj->pmcReg); + PmcReg_ClearWakupFlgLptmrWakupEvtFlg(obj->pmcReg); + PmcReg_ClearWakupFlgLpitWakupEvtFlg(obj->pmcReg); + PmcReg_ClearWakupFlgRtcWakupEvtFlg(obj->pmcReg); + PmcReg_ClearWakupFlgExtrstWakupEvtFlg(obj->pmcReg); + PmcReg_ClearWakupFlgPortEWakupEvtFlg(obj->pmcReg); + PmcReg_ClearWakupFlgPortDWakupEvtFlg(obj->pmcReg); + PmcReg_ClearWakupFlgPortCWakupEvtFlg(obj->pmcReg); + PmcReg_ClearWakupFlgPortBWakupEvtFlg(obj->pmcReg); + PmcReg_ClearWakupFlgPortAWakupEvtFlg(obj->pmcReg); + PowerDrv_LockRegWriteAccess(obj); +} + +void PowerDrv_ClrWakeupFlag(PowerDrvType *obj, PowerDrvWakeupFlagType flag) +{ + PowerDrv_UnlockRegWriteAccess(obj); + switch(flag) + { + case POWERDRV_PORTA_WU: + PmcReg_ClearWakupFlgPortAWakupEvtFlg(obj->pmcReg); + break; + case POWERDRV_PORTB_WU: + PmcReg_ClearWakupFlgPortBWakupEvtFlg(obj->pmcReg); + break; + case POWERDRV_PORTC_WU: + PmcReg_ClearWakupFlgPortCWakupEvtFlg(obj->pmcReg); + break; + case POWERDRV_PORTD_WU: + PmcReg_ClearWakupFlgPortDWakupEvtFlg(obj->pmcReg); + break; + case POWERDRV_PORTE_WU: + PmcReg_ClearWakupFlgPortEWakupEvtFlg(obj->pmcReg); + break; + case POWERDRV_RSTPIN_WU: + PmcReg_ClearWakupFlgExtrstWakupEvtFlg(obj->pmcReg); + break; + case POWERDRV_RTC_WU: + PmcReg_ClearWakupFlgRtcWakupEvtFlg(obj->pmcReg); + break; + case POWERDRV_LPIT_WU: + PmcReg_ClearWakupFlgLpitWakupEvtFlg(obj->pmcReg); + break; + case POWERDRV_LPTMR_WU: + PmcReg_ClearWakupFlgLptmrWakupEvtFlg(obj->pmcReg); + break; + case POWERDRV_CMP_WU: + PmcReg_ClearWakupFlgCmpWakupEvtFlag(obj->pmcReg); + break; + default: + break; + } + PowerDrv_LockRegWriteAccess(obj); +} + +PowerDrvWakeupFlagType PowerDrv_GetWakeupSource(PowerDrvType *obj) +{ + PowerDrvWakeupFlagType rtv = POWERDRV_NO_WU; + /* scan and return the wakeup flag which is set */ + for(uint8_t i = POWERDRV_PORTA_WU; i <= POWERDRV_CMP_WU; i++) + { + uint32_t temp = 1; + temp <<= i; + if(obj->pmcReg->WAKUP_FLG & temp) + { + rtv = (PowerDrvWakeupFlagType)i; + } + } + return rtv; +} + +void PowerDrv_StandbyModePreTask(PowerDrvType *obj) +{ + /* make sure these bits setting are correct before standby mode */ + PowerDrv_DisableOtpWarning(obj); + PowerDrv_DisableLvdDetect(obj); + PowerDrv_DisableLvwWarning(obj); + Scg0Reg_SetOscCtrlEnSosc(obj->scg0Reg, 0); + Scg0Reg_SetOscCtrlEnExtClk(obj->scg0Reg, 0); + Scg0Reg_SetPllCtrl0PllEn(obj->scg0Reg, 0); +} + +void PowerDrv_SetPowerMode(PowerDrvType *obj, PowerDrvPowerModeType mode) +{ + PowerDrv_UnlockRegWriteAccess(obj); + Scg0Reg_SetKey(obj->scg0Reg, 0x19962020); + /* target mode is stop mode */ + if(mode == POWERDRV_POWER_MODE_STOP) + { + /* enable stop mode */ + PmcReg_SetGlbCtrlStdbyEn(obj->pmcReg, 0); + PmcReg_SetGlbCtrlStopEn(obj->pmcReg, 1); + PmcReg_SetGlbCtrlCpuRetionEn(obj->pmcReg, 0); + Scg1Reg_SetCpuModeRet(obj->scg1Reg, 0); + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + } + /* target mode is standby mode */ + else + { + Scg2Reg_SetCsrSrcSys(obj->scg2Reg, 0); + PmcReg_SetGlbCtrlStopEn(obj->pmcReg, 0); + PmcReg_SetGlbCtrlStdbyEn(obj->pmcReg, 1); + PowerDrv_StandbyModePreTask(obj); + if(mode == POWERDRV_POWER_MODE_STANDBY_WITH_CPU_RETENTION) + { + PmcReg_SetGlbCtrlCpuRetionEn(obj->pmcReg, 1); + Scg1Reg_SetCpuModeRet(obj->scg1Reg, 1); + } + else + { + PmcReg_SetGlbCtrlCpuRetionEn(obj->pmcReg, 0); + Scg1Reg_SetCpuModeRet(obj->scg1Reg, 0); + } + PowerDrv_ClrAllWakupFlags(obj); + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + } + PowerDrv_LockRegWriteAccess(obj); + Scg0Reg_SetKey(obj->scg0Reg, 0); + __WFI(); +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/power/power_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/power/power_drv.h new file mode 100644 index 0000000..c2cc86e --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/power/power_drv.h @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _POWER_DRV_H_ +#define _POWER_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of power related modules such as reset + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup power_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +typedef enum +{ + POWERDRV_LVW1 = 0x0U, /*!< LVW LEVEL1 */ + POWERDRV_LVW2 = 0x1U, /*!< LVW LEVEL2 */ + POWERDRV_LVW3 = 0x2U /*!< LVW LEVEL3 */ +} PowerDrvLvwLevelType; + +typedef enum +{ + POWERDRV_POWER_MODE_RUN = 0x0U, /*!< RUN MODE */ + POWERDRV_POWER_MODE_STOP = 0x1U, /*!< STOP MODE */ + POWERDRV_POWER_MODE_STANDBY_WITH_CPU_RETENTION = 0x2U, /*!< STANDBY MODE WITH CPU RETENTION */ + POWERDRV_POWER_MODE_STANDBY_WITHOUT_CPU_RETENTION + = 0x3U /*!< STANDBY MODE WITHOUT CPU RETENTION */ +} PowerDrvPowerModeType; + +typedef enum +{ + POWERDRV_PORTA_WU = 0x00U, /*!< WAKEUP BY PORTA */ + POWERDRV_PORTB_WU = 0x01U, /*!< WAKEUP BY PORTB */ + POWERDRV_PORTC_WU = 0x02U, /*!< WAKEUP BY PORTC */ + POWERDRV_PORTD_WU = 0x03U, /*!< WAKEUP BY PORTD */ + POWERDRV_PORTE_WU = 0x04U, /*!< WAKEUP BY PORTE */ + POWERDRV_RSTPIN_WU = 0x05U, /*!< WAKEUP BY RESET PIN */ + POWERDRV_RTC_WU = 0x06U, /*!< WAKEUP BY RTC */ + POWERDRV_LPIT_WU = 0x08U, /*!< WAKEUP BY LPIT */ + POWERDRV_LPTMR_WU = 0x09U, /*!< WAKEUP BY LPTMR */ + POWERDRV_CMP_WU = 0x0AU, /*!< WAKEUP BY CMP */ + POWERDRV_NO_WU = 0xFFU /*!< No WAKEUP FLAG */ +} PowerDrvWakeupFlagType; + +typedef struct _PowerDrvType_ +{ + struct _PmcRegType_ *pmcReg; + struct _Scg2RegType_ *scg2Reg; + struct _Scg1RegType_ *scg1Reg; + struct _Scg0RegType_ *scg0Reg; +} PowerDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ +/*! \brief Initializes the Power reg + * + * + * \param[in] obj : pointer to POWER driver instance + * \param[in] pmcReg : pointer to POWER register instance + * \param[in] scg2Reg : pointer to SCG2 register instance + * \param[in] scg1Reg : pointer to SCG1 register instance + * \param[in] scg0Reg : pointer to SCG0 register instance + */ +extern void PowerDrv_Init(PowerDrvType *obj, struct _PmcRegType_ *pmcReg, struct _Scg2RegType_ *scg2Reg, struct _Scg1RegType_ *scg1Reg, struct _Scg0RegType_ *scg0Reg); + +/*! \brief Unlock the PMC register write access + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_UnlockRegWriteAccess(PowerDrvType *obj); + +/*! \brief Lock the PMC register write access + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_LockRegWriteAccess(PowerDrvType *obj); + +/*! \brief Enable the LVW warning + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_EnableLvwWarning(PowerDrvType *obj); + +/*! \brief Disable the LVW warning + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_DisableLvwWarning(PowerDrvType *obj); + +/*! \brief set the lvw warning level + * + * + * \param[in] obj : pointer to POWER driver instance + * \param[in] level : the target lvw warning level + */ +extern void PowerDrv_SetLvwLevel(PowerDrvType *obj, PowerDrvLvwLevelType level); + +/*! \brief Enable the LVD detect + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_EnableLvdDetect(PowerDrvType *obj); + +/*! \brief Disable the LVD detect + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_DisableLvdDetect(PowerDrvType *obj); + +/*! \brief Enable the OTP warning + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_EnableOtpWarning(PowerDrvType *obj); + +/*! \brief Disable the OTP warning + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_DisableOtpWarning(PowerDrvType *obj); + +/*! \brief Enable the FLDO detect + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_EnableFldoDetect(PowerDrvType *obj); + +/*! \brief Disable the FLDO detect + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_DisableFldoDetect(PowerDrvType *obj); + +/*! \brief release the pad keep feature + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_ReleasePadKeep(PowerDrvType *obj); + +/*! \brief get the standby abort flag + * + * + * \param[in] obj : pointer to POWER driver instance + * \param[out] flag : flag + * - 0 : no abort happenned + * - 1 : abort happenned + */ +extern uint8_t PowerDrv_GetStbAbortFlag(PowerDrvType *obj); + +/*! \brief clear the standby abort flag + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_ClrStbAbortFlag(PowerDrvType *obj); + +/*! \brief clear all wakeup flags + * + * + * \param[in] obj : pointer to POWER driver instance + */ +extern void PowerDrv_ClrAllWakupFlags(PowerDrvType *obj); + +/*! \brief clear dedicated wakeup flag + * + * + * \param[in] obj : pointer to POWER driver instance + * \param[in] flag : the wakeup flag + */ +extern void PowerDrv_ClrWakeupFlag(PowerDrvType *obj, PowerDrvWakeupFlagType flag); + +/*! \brief get the wakeup flag + * + * + * \param[in] obj : pointer to POWER driver instance + * \param[out] PowerDrvWakeupFlagType : flag + */ +extern PowerDrvWakeupFlagType PowerDrv_GetWakeupSource(PowerDrvType *obj); + +/*! \brief set the power mode + * + * + * \param[in] obj : pointer to POWER driver instance + * \param[in] mode : the target mode + */ +extern void PowerDrv_SetPowerMode(PowerDrvType *obj, PowerDrvPowerModeType mode); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _POWER_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/pwmlite/pwmlite_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/pwmlite/pwmlite_drv.c new file mode 100644 index 0000000..81feb16 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/pwmlite/pwmlite_drv.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "pwmlite_drv.h" +#include "pwmlite_reg.h" +#include "sim_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +typedef void (*setPwmLiteMuxFunc)(SimRegType *obj, uint8_t value); + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +const setPwmLiteMuxFunc c_pwmLiteMuxFuncTable[PWMLITEDRV_MUX_PAD_PWM_NUM] = { + SimReg_SetPwmCtrl0PwmFunc0, + SimReg_SetPwmCtrl0PwmFunc1, + SimReg_SetPwmCtrl0PwmFunc2, + SimReg_SetPwmCtrl0PwmFunc3, + + SimReg_SetPwmCtrl1PwmFunc4, + SimReg_SetPwmCtrl1PwmFunc5, +}; + +const PwmLiteDrv_PwmMuxPadNumType c_pwmLiteMuxPadIndex[] = { + PWMLITEDRV_MUX_PAD_PWM0, + PWMLITEDRV_MUX_PAD_PWM1, + PWMLITEDRV_MUX_PAD_PWM2, + PWMLITEDRV_MUX_PAD_PWM3, + PWMLITEDRV_MUX_PAD_PWM4, + PWMLITEDRV_MUX_PAD_PWM5, +}; +#define PWMLITE_PWMMUXINDEX_MAX (sizeof(c_pwmLiteMuxPadIndex) / sizeof(PwmLiteDrv_PwmMuxPadNumType)) + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +void PwmLiteDrv_Init(PwmLiteDrvType *obj, struct _PwmLiteRegType_ *pwmLiteReg, struct _SimRegType_ *simReg) +{ + uint16_t i; + + obj->pwmLiteReg = pwmLiteReg; + obj->simReg = simReg; + /* disable the mux pwm output */ + for(i = 0; i < PWMLITE_PWMMUXINDEX_MAX; i++) + { + PwmLiteDrv_OutputMux(obj, PWMLITEDRV_MUX_PWM_CH_INVALID, c_pwmLiteMuxPadIndex[i]); + } +} + +void PwmLiteDrv_ModuleConfig(PwmLiteDrvType *obj, const PwmLiteDrv_ModuleConfigType *userConfig) +{ + /* disable the module first */ + PwmLiteDrv_DisableModule(obj); + /* Set the pwm period value */ + PwmLiteReg_SetPrdPeriod(obj->pwmLiteReg, userConfig->period); + /* Set the syne type of the module */ + PwmLiteReg_SetCtrlSyncMode(obj->pwmLiteReg, userConfig->syncType); +} + +void PwmLiteDrv_GetDefaultModuleConfig(PwmLiteDrv_ModuleConfigType *ModuleConfigType) +{ + ModuleConfigType->period = 0; + ModuleConfigType->syncType = PWMLITEDRV_SYNC_AT_RUNNING; +} + +void PwmLiteDrv_ConfigChannel(PwmLiteDrvType *obj, uint8_t channel, const PwmLiteDrv_ChannelConfigType *userConfig) +{ + if(channel >= PWMLITEDRV_PWM_CH_NUM) + { + return; + } + /* disable the module first */ + PwmLiteDrv_DisableModule(obj); + /* Set the pwm channels to target pad channel through SIM */ + PwmLiteDrv_OutputMux(obj, userConfig->pwmMuxType.channelNumber, userConfig->pwmMuxType.padNumber); + /* Set pwm threshold0/1 value */ + PwmLiteDrv_UpdatePwmThresholdAtRunning(obj, channel, userConfig->threshold0, userConfig->threshold1); + /* Set pwm threshold0 behavior */ + PwmLiteReg_SetChCtrl0(obj->pwmLiteReg, channel, userConfig->behavior0); + /* Set pwm threshold1 behavior */ + PwmLiteReg_SetChCtrl1(obj->pwmLiteReg, channel, userConfig->behavior1); +} + +void PwmLiteDrv_GetDefaultChannelConfig(PwmLiteDrv_ChannelConfigType *ChannelConfigType) +{ + ChannelConfigType->behavior0 = PWMLITEDRV_TOGGLE_AT_REACH; + ChannelConfigType->behavior1 = PWMLITEDRV_TOGGLE_AT_REACH; + ChannelConfigType->threshold0 = 0; + ChannelConfigType->threshold1 = 0; +} + +void PwmLiteDrv_EnableModule(PwmLiteDrvType *obj) +{ + PwmLiteReg_SetCtrlEn(obj->pwmLiteReg, 1); +} + +void PwmLiteDrv_DisableModule(PwmLiteDrvType *obj) +{ + PwmLiteReg_SetCtrlEn(obj->pwmLiteReg, 0); +} + +void PwmLiteDrv_Resume(PwmLiteDrvType *obj) +{ + PwmLiteReg_SetStopPause(obj->pwmLiteReg, 0); +} + +void PwmLiteDrv_Pause(PwmLiteDrvType *obj) +{ + PwmLiteReg_SetStopPause(obj->pwmLiteReg, 1); +} + +void PwmLiteDrv_UpdatePwmThresholdAtRunning(PwmLiteDrvType *obj, uint8_t channel, uint32_t threshold0, uint32_t threshold1) +{ + uint32_t prd = PwmLiteReg_GetPrdPeriod(obj->pwmLiteReg); + if(threshold1 == threshold0) /* DUTY: 0% */ + { + /* Set pwm threshold0 value */ + PwmLiteReg_SetChThr0(obj->pwmLiteReg, channel, (prd + 0x1u)); + /* Set pwm threshold1 value */ + PwmLiteReg_SetChThr1(obj->pwmLiteReg, channel, 0x0u); + } + else if(threshold1 - threshold0 == prd) /* DUTY: 100% */ + { + /* Set pwm threshold0 value */ + PwmLiteReg_SetChThr0(obj->pwmLiteReg, channel, 0x0u); + /* Set pwm threshold1 value */ + PwmLiteReg_SetChThr1(obj->pwmLiteReg, channel, (prd + 0x1u)); + } + else /* DUTY: 0~100% */ + { + /* Set pwm threshold0 value */ + PwmLiteReg_SetChThr0(obj->pwmLiteReg, channel, threshold0); + /* Set pwm threshold1 value */ + PwmLiteReg_SetChThr1(obj->pwmLiteReg, channel, threshold1); + } +} + +void PwmLiteDrv_UpdatePwmThresholdAtSync(PwmLiteDrvType *obj, uint8_t channel, uint32_t threshold0, uint32_t threshold1) +{ + uint32_t prd = PwmLiteReg_GetPrdPeriod(obj->pwmLiteReg); + if(threshold1 == threshold0) /* DUTY: 0% */ + { + /* Set pwm threshold0 value */ + PwmLiteReg_SetChThr0(obj->pwmLiteReg, channel, (prd + 0x1u)); + /* Set pwm threshold1 value */ + PwmLiteReg_SetChThr1(obj->pwmLiteReg, channel, 0x0u); + } + else if(threshold1 - threshold0 == prd) /* DUTY: 100% */ + { + /* Set pwm threshold0 value */ + PwmLiteReg_SetChThr0(obj->pwmLiteReg, channel, 0x0u); + /* Set pwm threshold1 value */ + PwmLiteReg_SetChThr1(obj->pwmLiteReg, channel, (prd + 0x1u)); + } + else /* DUTY: 0~100% */ + { + /* Set pwm threshold0 value */ + PwmLiteReg_SetChThr0(obj->pwmLiteReg, channel, threshold0); + /* Set pwm threshold1 value */ + PwmLiteReg_SetChThr1(obj->pwmLiteReg, channel, threshold1); + } + PwmLiteDrv_TrigSync(obj); + while(PwmLiteDrv_GetSyncResult(obj)) + { + ; + } +} + +void PwmLiteDrv_OutputMux(PwmLiteDrvType *obj, PwmLiteDrv_PwmMuxChannelType channel, PwmLiteDrv_PwmMuxPadNumType number) +{ + if(number >= PWMLITEDRV_MUX_PAD_PWM_NUM) + { + return; + } + /* select the correct path through target channel number */ + c_pwmLiteMuxFuncTable[number](obj->simReg, (uint8_t)channel); +} + +uint8_t PwmLiteDrv_GetSyncResult(PwmLiteDrvType *obj) +{ + uint8_t result = 0; + result = PwmLiteReg_GetSyncStatus(obj->pwmLiteReg); + return result; +} + +void PwmLiteDrv_TrigSync(PwmLiteDrvType *obj) +{ + PwmLiteReg_SetSyncStart(obj->pwmLiteReg, 1); +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/pwmlite/pwmlite_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/pwmlite/pwmlite_drv.h new file mode 100644 index 0000000..22a11b5 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/pwmlite/pwmlite_drv.h @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PWMLITE_DRV_H_ +#define _PWMLITE_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of PWMLITE + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup pwmlite_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +typedef enum +{ + PWMLITEDRV_PWM_CH0 = 0x0U, /*!< Pwm0/1 channel0 */ + PWMLITEDRV_PWM_CH1 = 0x1U, /*!< Pwm0/1 channel1 */ + PWMLITEDRV_PWM_CH2 = 0x2U, /*!< Pwm0/1 channel2 */ + PWMLITEDRV_PWM_CH3 = 0x3U, /*!< Pwm0/1 channel3 */ + PWMLITEDRV_PWM_CH4 = 0x4U, /*!< Pwm0/1 channel4 */ + PWMLITEDRV_PWM_CH5 = 0x5U, /*!< Pwm0/1 channel5 */ + + PWMLITEDRV_PWM_CH_NUM, +} PwmLiteDrv_PwmChannelType; + +typedef enum +{ + PWMLITEDRV_MUX_PWM0_CH0 = 0x0U, /*!< Mux Pwm0 channel0 */ + PWMLITEDRV_MUX_PWM0_CH1 = 0x1U, /*!< Mux Pwm0 channel1 */ + PWMLITEDRV_MUX_PWM0_CH2 = 0x2U, /*!< Mux Pwm0 channel2 */ + PWMLITEDRV_MUX_PWM0_CH3 = 0x3U, /*!< Mux Pwm0 channel3 */ + PWMLITEDRV_MUX_PWM0_CH4 = 0x4U, /*!< Mux Pwm0 channel4 */ + PWMLITEDRV_MUX_PWM0_CH5 = 0x5U, /*!< Mux Pwm0 channel5 */ + PWMLITEDRV_MUX_PWM1_CH0 = 0x6U, /*!< Mux Pwm1 channel0 */ + PWMLITEDRV_MUX_PWM1_CH1 = 0x7U, /*!< Mux Pwm1 channel1 */ + PWMLITEDRV_MUX_PWM1_CH2 = 0x8U, /*!< Mux Pwm1 channel2 */ + PWMLITEDRV_MUX_PWM1_CH3 = 0x9U, /*!< Mux Pwm1 channel3 */ + PWMLITEDRV_MUX_PWM1_CH4 = 0xAU, /*!< Mux Pwm1 channel4 */ + PWMLITEDRV_MUX_PWM1_CH5 = 0xBU, /*!< Mux Pwm1 channel5 */ + + PWMLITEDRV_MUX_PWM_CH_INVALID, +} PwmLiteDrv_PwmMuxChannelType; + +typedef enum +{ + PWMLITEDRV_MUX_PAD_PWM0 = 0x0U, /*!< MUX PWM00 PAD */ + PWMLITEDRV_MUX_PAD_PWM1 = 0x1U, /*!< MUX PWM01 PAD */ + PWMLITEDRV_MUX_PAD_PWM2 = 0x2U, /*!< MUX PWM02 PAD */ + PWMLITEDRV_MUX_PAD_PWM3 = 0x3U, /*!< MUX PWM03 PAD */ + PWMLITEDRV_MUX_PAD_PWM4 = 0x4U, /*!< MUX PWM04 PAD */ + PWMLITEDRV_MUX_PAD_PWM5 = 0x5U, /*!< MUX PWM05 PAD */ + + PWMLITEDRV_MUX_PAD_PWM_NUM, +} PwmLiteDrv_PwmMuxPadNumType; + +typedef enum +{ + PWMLITEDRV_SYNC_AT_RUNNING = 0x0U, /*!< Sync at running */ + PWMLITEDRV_SYNC_AT_PERIOD = 0x1U /*!< Sync at period */ +} PwmLiteDrv_SyncType; + +typedef enum +{ + PWMLITEDRV_KEEP_AT_REACH = 0x0U, /*!< Output keep at reach match value */ + PWMLITEDRV_LOW_AT_REACH = 0x1U, /*!< Output set low at reach match value */ + PWMLITEDRV_HIGH_AT_REACH = 0x2U, /*!< Output set high at reach match value */ + PWMLITEDRV_TOGGLE_AT_REACH = 0x3U /*!< Output toggle at reach match value */ +} PwmLiteDrv_OutBehaviorType; + +/*! \brief The definition of PWMLITE driver class + */ +typedef struct _PwmLiteDrvType_ +{ + struct _PwmLiteRegType_ *pwmLiteReg; + struct _SimRegType_ *simReg; +} PwmLiteDrvType; + +typedef struct _PwmLiteDrv_PwmMuxConfigType_ +{ + PwmLiteDrv_PwmMuxChannelType channelNumber; /*!< The pwmlite channel number */ + PwmLiteDrv_PwmMuxPadNumType padNumber; /*!< The target pad number */ +} PwmLiteDrv_PwmMuxConfigType; + +typedef struct _PwmLiteDrv_ModuleConfigType_ +{ + uint32_t period; /*!< Pwm period value */ + PwmLiteDrv_SyncType syncType; /*!< Module sync type */ + +} PwmLiteDrv_ModuleConfigType; + +typedef struct _PwmLiteDrv_ChannelConfigType_ +{ + PwmLiteDrv_PwmMuxConfigType pwmMuxType; /*!< Pwm mux output type */ + + uint32_t threshold0; /*!< Threshold0 of the channel */ + uint32_t threshold1; /*!< Threshold1 of the channel */ + PwmLiteDrv_OutBehaviorType behavior0; /*!< Behavior0 on reach threshold0 */ + PwmLiteDrv_OutBehaviorType behavior1; /*!< Behavior1 on reach threshold1 */ +} PwmLiteDrv_ChannelConfigType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the PWMlite reg + * + * + * \param[in] obj : pointer to PWMLITE driver instance + * \param[in] pwmLiteReg : pointer to PWMLITE register instance + * \param[in] simReg : pointer to SIM register instance + */ +extern void PwmLiteDrv_Init(PwmLiteDrvType *obj, struct _PwmLiteRegType_ *pwmLiteReg, struct _SimRegType_ *simReg); + +/*! \brief Get default configures the PWMLITE module for configuration structure + * + * This function gets default configures the PWMLITE module for user configuration structure + * + * \param[in] obj : pointer to PWMLITE driver instance + * + */ +extern void PwmLiteDrv_GetDefaultModuleConfig(PwmLiteDrv_ModuleConfigType *ModuleConfigType); + +/*! \brief config the pwm module according to user config + * + * + * \param[in] obj : pointer to PWMLITE driver instance + * \param[in] userConfig : pointer to the user config structure + */ +extern void PwmLiteDrv_ModuleConfig(PwmLiteDrvType *obj, const PwmLiteDrv_ModuleConfigType *userConfig); + +/*! \brief Get default configures the PWMLITE module channel for configuration structure + * + * This function gets default configures the PWMLITE module channel for user configuration structure + * + * \param[in] obj : pointer to PWMLITE driver instance + * + */ +extern void PwmLiteDrv_GetDefaultChannelConfig(PwmLiteDrv_ChannelConfigType *userConfig); + +/*! \brief config the pwm channel according to user config + * + * + * \param[in] obj : pointer to PWMLITE driver instance + * \param[in] channel : the pwm channel number + * \param[in] userConfig : pointer to the user config structure + */ +extern void PwmLiteDrv_ConfigChannel(PwmLiteDrvType *obj, uint8_t channel, const PwmLiteDrv_ChannelConfigType *userConfig); + +/*! \brief update the Pwm duty value at running + * + * + * \param[in] obj : pointer to PWMLITE driver instance + * \param[in] channel : the pwm channel number + * \param[in] threshold0 : new threshold0 value + * \param[in] threshold1 : new threshold1 value + */ +extern void PwmLiteDrv_UpdatePwmThresholdAtRunning(PwmLiteDrvType *obj, uint8_t channel, uint32_t threshold0, uint32_t threshold1); + +/*! \brief update the Pwm duty value at sync time + * + * + * \param[in] obj : pointer to PWMLITE driver instance + * \param[in] channel : the pwm channel number + * \param[in] threshold0 : new threshold0 value + * \param[in] threshold1 : new threshold1 value + */ +extern void PwmLiteDrv_UpdatePwmThresholdAtSync(PwmLiteDrvType *obj, uint8_t channel, uint32_t threshold0, uint32_t threshold1); + +/*! \brief mux the pwm channels to target pad channel through SIM + * + * + * \param[in] channel : the pwm channel number + * \param[in] number : the target pad number + */ +extern void PwmLiteDrv_OutputMux(PwmLiteDrvType *obj, PwmLiteDrv_PwmMuxChannelType channel, PwmLiteDrv_PwmMuxPadNumType number); + +/*! \brief resume the pwm module output + * + * + * \param[in] obj : pointer to PWMLITE driver instance + */ +extern void PwmLiteDrv_Resume(PwmLiteDrvType *obj); + +/*! \brief pause the pwm module output + * + * + * \param[in] obj : pointer to PWMLITE driver instance + */ +extern void PwmLiteDrv_Pause(PwmLiteDrvType *obj); + +/*! \brief enable the pwm module + * + * + * \param[in] obj : pointer to PWMLITE driver instance + */ +extern void PwmLiteDrv_EnableModule(PwmLiteDrvType *obj); + +/*! \brief disable the pwm module + * + * + * \param[in] obj : pointer to PWMLITE driver instance + */ +extern void PwmLiteDrv_DisableModule(PwmLiteDrvType *obj); + +/*! \brief get the sync result + * + * + * \param[in] obj : pointer to PWMLITE driver instance + * \param[out] bool : result + * - 0 : update done + * - 1 : during update + */ +extern uint8_t PwmLiteDrv_GetSyncResult(PwmLiteDrvType *obj); + +/*! \brief trig the sync action + * + * + * \param[in] obj : pointer to PWMLITE driver instance + */ +extern void PwmLiteDrv_TrigSync(PwmLiteDrvType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _PWMLITE_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/reset/reset_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/reset/reset_drv.c new file mode 100644 index 0000000..9f158da --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/reset/reset_drv.c @@ -0,0 +1,457 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "reset_drv.h" +#include "rcm_reg.h" +#include "pcc0_reg.h" +#include "pcc1_reg.h" +#include "../cpu/cpu_drv.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define RESET_RCM_UNLOCK (0x52434D4Bu) +#define RESET_PCC_UNLOCK (0x55534552u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void ResetDrv_Init(ResetDrvType *obj, struct _RcmRegType_ *rcmReg, struct _Pcc1RegType_ *pcc1Reg, struct _Pcc0RegType_ *pcc0Reg) +{ + obj->rcmReg = rcmReg; + obj->pcc1Reg = pcc1Reg; + obj->pcc0Reg = pcc0Reg; +} + +void ResetDrv_GetDefaultConfig(ResetDrv_ConfigType *userConfig) +{ + userConfig->enableExtFlt = false; + userConfig->extFltLen = 16; + userConfig->enableResetInterrupt = false; + userConfig->delay = RESETDRV_RESETDELAY_514LPOCYCLES; +} + +void ResetDrv_Configure(ResetDrvType *obj, const ResetDrv_ConfigType *userConfig) +{ + if((userConfig->extFltLen > 32) || (userConfig->extFltLen < 1)) + { + return; + } + if(userConfig->delay > RESETDRV_RESETDELAY_514LPOCYCLES) + { + return; + } + + RcmReg_SetKey(obj->rcmReg, RESET_RCM_UNLOCK); /* Unlock RCM */ + + RcmReg_SetExtRstFltEn(obj->rcmReg, userConfig->enableExtFlt); + RcmReg_SetExtRstFltLen(obj->rcmReg, (uint8_t)(userConfig->extFltLen - 1)); + RcmReg_SetRstCtrlGlobalIE(obj->rcmReg, userConfig->enableResetInterrupt); + RcmReg_SetRstCtrlRstDelay(obj->rcmReg, userConfig->delay); + + RcmReg_SetKey(obj->rcmReg, 0); /* Lock RCM again */ +} + +bool ResetDrv_IsResetCaused(const ResetDrvType *obj, ResetDrv_SourceType source) +{ + bool retval = false; + if(source >= RESETDRV_SOURCE_NUM) + { + return retval; + } + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:low] "still keep default though it's not reachable" */ + switch(source) + { + case RESETDRV_SOURCE_WDG: + retval = RcmReg_GetRstFlagWdg(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_SYS: + retval = RcmReg_GetRstFlagSys(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_LOCKUP: + retval = RcmReg_GetRstFlagLockup(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_PIN: + retval = RcmReg_GetRstFlagPin(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_MDMAP: + retval = RcmReg_GetRstFlagMdmap(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_PLL_LOSS: + retval = RcmReg_GetRstFlagPllLoss(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_CMUP: + retval = RcmReg_GetRstFlagCmuPll(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_CMUS: + retval = RcmReg_GetRstFlagCmuSosc(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_FHU: + retval = RcmReg_GetRstFlagFhu(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_STDBY_EXIT: + retval = RcmReg_GetRstFlagStdbyExit(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_FLS_INITIAL: + retval = RcmReg_GetRstFlagFlsInitial(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_LVR: + retval = RcmReg_GetRstFlagLvr(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_POR: + retval = RcmReg_GetRstFlagPor(obj->rcmReg) == 1; + break; + default: + /* Should not get here */ + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:low] "still keep default though it's not reachable" */ + return retval; +} + +bool ResetDrv_IsResetSticky(const ResetDrvType *obj, ResetDrv_SourceType source) +{ + bool retval = false; + if(source >= RESETDRV_SOURCE_NUM) + { + return retval; + } + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:low] "still keep default though it's not reachable" */ + switch(source) + { + case RESETDRV_SOURCE_WDG: + retval = RcmReg_GetRstSFlagWdg(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_SYS: + retval = RcmReg_GetRstSFlagSys(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_LOCKUP: + retval = RcmReg_GetRstSFlagLockup(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_PIN: + retval = RcmReg_GetRstSFlagPin(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_MDMAP: + retval = RcmReg_GetRstSFlagMdmap(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_PLL_LOSS: + retval = RcmReg_GetRstSFlagPllLoss(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_CMUP: + retval = RcmReg_GetRstSFlagCmuPll(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_CMUS: + retval = RcmReg_GetRstSFlagCmuSosc(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_FHU: + retval = RcmReg_GetRstSFlagFhu(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_STDBY_EXIT: + retval = RcmReg_GetRstSFlagStdbyExit(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_FLS_INITIAL: + retval = RcmReg_GetRstSFlagFlsInitial(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_LVR: + retval = RcmReg_GetRstSFlagLvr(obj->rcmReg) == 1; + break; + case RESETDRV_SOURCE_POR: + retval = RcmReg_GetRstSFlagPor(obj->rcmReg) == 1; + break; + default: + /* Should not get here */ + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:low] "still keep default though it's not reachable" */ + return retval; +} + +void ResetDrv_ClrResetStickyFlag(ResetDrvType *obj, ResetDrv_SourceType source) +{ + if(source >= RESETDRV_SOURCE_NUM) + { + return; + } + RcmReg_SetKey(obj->rcmReg, RESET_RCM_UNLOCK); /* Unlock RCM */ + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:low] "still keep default though it's not reachable" */ + switch(source) + { + case RESETDRV_SOURCE_WDG: + RcmReg_SetRstSFlagWdg(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_SYS: + RcmReg_SetRstSFlagSys(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_LOCKUP: + RcmReg_SetRstSFlagLockup(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_PIN: + RcmReg_SetRstSFlagPin(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_MDMAP: + RcmReg_SetRstSFlagMdmap(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_PLL_LOSS: + RcmReg_SetRstSFlagPllLoss(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_CMUP: + RcmReg_SetRstSFlagCmuPll(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_CMUS: + RcmReg_SetRstSFlagCmuSosc(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_FHU: + RcmReg_SetRstSFlagFhu(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_STDBY_EXIT: + RcmReg_SetRstSFlagStdbyExit(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_FLS_INITIAL: + RcmReg_SetRstSFlagFlsInitial(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_LVR: + RcmReg_SetRstSFlagLvr(obj->rcmReg, 1); + break; + case RESETDRV_SOURCE_POR: + RcmReg_SetRstSFlagPor(obj->rcmReg, 1); + break; + default: + /* Should not get here */ + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:low] "still keep default though it's not reachable" */ + RcmReg_SetKey(obj->rcmReg, 0); /* Lock RCM again */ +} + +void ResetDrv_EnableResetInterrupt(ResetDrvType *obj, ResetDrv_ResetIntModuleType module, bool enable) +{ + RcmReg_SetKey(obj->rcmReg, RESET_RCM_UNLOCK); /* Unlock RCM */ + switch(module) + { + case RESETDRV_RESETINT_WDG: + RcmReg_SetRstCtrlWdgRstIE(obj->rcmReg, enable ? 1 : 0); + break; + case RESETDRV_RESETINT_SYS: + RcmReg_SetRstCtrlSysRstIE(obj->rcmReg, enable ? 1 : 0); + break; + case RESETDRV_RESETINT_PIN: + RcmReg_SetRstCtrlPinRstIE(obj->rcmReg, enable ? 1 : 0); + break; + case RESETDRV_RESETINT_MDMAP: + RcmReg_SetRstCtrlMdmapRstIE(obj->rcmReg, enable ? 1 : 0); + break; + case RESETDRV_RESETINT_PLL_LOSS: + RcmReg_SetRstCtrlPllLossIE(obj->rcmReg, enable ? 1 : 0); + break; + case RESETDRV_RESETINT_CMUP: + RcmReg_SetRstCtrlCmuPllIE(obj->rcmReg, enable ? 1 : 0); + break; + case RESETDRV_RESETINT_CMUS: + RcmReg_SetRstCtrlCmuSoscIE(obj->rcmReg, enable ? 1 : 0); + break; + default: + /* Should not get here */ + break; + } + RcmReg_SetKey(obj->rcmReg, 0); /* Lock RCM again */ +} + +void ResetDrv_EnableReset(ResetDrvType *obj, ResetDrv_ResetEnModuleType module, bool enable) +{ + RcmReg_SetKey(obj->rcmReg, RESET_RCM_UNLOCK); /* Unlock RCM */ + switch(module) + { + case RESETDRV_RESETEN_PLL_LOSS: + RcmReg_SetRstCtrlPllLossEn(obj->rcmReg, enable ? 1 : 0); + break; + case RESETDRV_RESETEN_LOCKUP: + RcmReg_SetRstCtrlLockupEn(obj->rcmReg, enable ? 1 : 0); + break; + default: + /* Should not get here */ + break; + } + RcmReg_SetKey(obj->rcmReg, 0); /* Lock RCM again */ +} + +void ResetDrv_SoftwareResetModule(ResetDrvType *obj, ResetDrv_SwResetModuleType module) +{ + Pcc0Reg_SetKey(obj->pcc0Reg, RESET_PCC_UNLOCK); /* Unlock PCC */ + switch(module) + { + case RESETDRV_SWRESET_CMP: + Pcc0Reg_SetCmpSwR(obj->pcc0Reg, 1); + Pcc0Reg_SetCmpSwR(obj->pcc0Reg, 0); + break; + case RESETDRV_SWRESET_PORTA: + Pcc0Reg_SetPortASwR(obj->pcc0Reg, 1); + Pcc0Reg_SetPortASwR(obj->pcc0Reg, 0); + break; + case RESETDRV_SWRESET_PORTB: + Pcc0Reg_SetPortBSwR(obj->pcc0Reg, 1); + Pcc0Reg_SetPortBSwR(obj->pcc0Reg, 0); + break; + case RESETDRV_SWRESET_PORTC: + Pcc0Reg_SetPortCSwR(obj->pcc0Reg, 1); + Pcc0Reg_SetPortCSwR(obj->pcc0Reg, 0); + break; + case RESETDRV_SWRESET_PORTD: + Pcc0Reg_SetPortDSwR(obj->pcc0Reg, 1); + Pcc0Reg_SetPortDSwR(obj->pcc0Reg, 0); + break; + case RESETDRV_SWRESET_PORTE: + Pcc0Reg_SetPortESwR(obj->pcc0Reg, 1); + Pcc0Reg_SetPortESwR(obj->pcc0Reg, 0); + break; + case RESETDRV_SWRESET_LPTMR: + Pcc0Reg_SetLptmrSwR(obj->pcc0Reg, 1); + Pcc0Reg_SetLptmrSwR(obj->pcc0Reg, 0); + break; + case RESETDRV_SWRESET_LPIT: + Pcc0Reg_SetLpitSwR(obj->pcc0Reg, 1); + Pcc0Reg_SetLpitSwR(obj->pcc0Reg, 0); + break; + case RESETDRV_SWRESET_WDG: + Pcc0Reg_SetWdgSwR(obj->pcc0Reg, 1); + Pcc0Reg_SetWdgSwR(obj->pcc0Reg, 0); + break; + case RESETDRV_SWRESET_DMA: + Pcc1Reg_SetDmaSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetDmaSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_MSCM: + Pcc1Reg_SetMscmSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetMscmSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_CRC: + Pcc1Reg_SetCrcSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetCrcSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_EIM: + Pcc1Reg_SetEimSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetEimSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_ERM: + Pcc1Reg_SetErmSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetErmSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_FHU: + Pcc1Reg_SetFhuSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetFhuSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_ADC: + Pcc1Reg_SetAdcSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetAdcSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_PDB: + Pcc1Reg_SetPdbSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetPdbSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_SPI0: + Pcc1Reg_SetSpi0SwR(obj->pcc1Reg, 1); + Pcc1Reg_SetSpi0SwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_SPI1: + Pcc1Reg_SetSpi1SwR(obj->pcc1Reg, 1); + Pcc1Reg_SetSpi1SwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_UART0: + Pcc1Reg_SetUart0SwR(obj->pcc1Reg, 1); + Pcc1Reg_SetUart0SwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_UART1: + Pcc1Reg_SetUart1SwR(obj->pcc1Reg, 1); + Pcc1Reg_SetUart1SwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_UART2: + Pcc1Reg_SetUart2SwR(obj->pcc1Reg, 1); + Pcc1Reg_SetUart2SwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_CAN: + Pcc1Reg_SetCanSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetCanSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_I2C: + Pcc1Reg_SetI2CSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetI2CSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_I2SM: + Pcc1Reg_SetI2SMSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetI2SMSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_I2SS: + Pcc1Reg_SetI2SSSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetI2SSSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_PWMLITE0: + Pcc1Reg_SetPwm0SwR(obj->pcc1Reg, 1); + Pcc1Reg_SetPwm0SwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_PWMLITE1: + Pcc1Reg_SetPwm1SwR(obj->pcc1Reg, 1); + Pcc1Reg_SetPwm1SwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_MFT0: + Pcc1Reg_SetMft0SwR(obj->pcc1Reg, 1); + Pcc1Reg_SetMft0SwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_MFT1: + Pcc1Reg_SetMft1SwR(obj->pcc1Reg, 1); + Pcc1Reg_SetMft1SwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_GPIO: + Pcc1Reg_SetGpioSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetGpioSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_CMUP: + Pcc1Reg_SetCmupSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetCmupSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_CMUS: + Pcc1Reg_SetCmusSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetCmusSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_FLS: + Pcc1Reg_SetFlsCtlSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetFlsCtlSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_MPU: + Pcc1Reg_SetMpuSwR(obj->pcc1Reg, 1); + Pcc1Reg_SetMpuSwR(obj->pcc1Reg, 0); + break; + case RESETDRV_SWRESET_SYS: + NVIC_SystemReset(); + break; + default: + /* Should not get here */ + break; + } + Pcc0Reg_SetKey(obj->pcc0Reg, 0); /* Lock Pcc0 again */ +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/reset/reset_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/reset/reset_drv.h new file mode 100644 index 0000000..6a67139 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/reset/reset_drv.h @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _RESET_DRV_H_ +#define _RESET_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of Reset + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup reset_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Definition of modules that can be software reset + */ +typedef enum +{ + RESETDRV_SWRESET_CMP = 0, + RESETDRV_SWRESET_PORTA, + RESETDRV_SWRESET_PORTB, + RESETDRV_SWRESET_PORTC, + RESETDRV_SWRESET_PORTD, + RESETDRV_SWRESET_PORTE, + RESETDRV_SWRESET_LPTMR, + RESETDRV_SWRESET_LPIT, + RESETDRV_SWRESET_WDG, + + RESETDRV_SWRESET_DMA, + RESETDRV_SWRESET_MSCM, + RESETDRV_SWRESET_CRC, + RESETDRV_SWRESET_EIM, + RESETDRV_SWRESET_ERM, + RESETDRV_SWRESET_FHU, + RESETDRV_SWRESET_ADC, + RESETDRV_SWRESET_PDB, + RESETDRV_SWRESET_SPI0, + RESETDRV_SWRESET_SPI1, + RESETDRV_SWRESET_UART0, + RESETDRV_SWRESET_UART1, + RESETDRV_SWRESET_UART2, + RESETDRV_SWRESET_CAN, + RESETDRV_SWRESET_I2C, + RESETDRV_SWRESET_I2SM, + RESETDRV_SWRESET_I2SS, + RESETDRV_SWRESET_PWMLITE0, + RESETDRV_SWRESET_PWMLITE1, + RESETDRV_SWRESET_MFT0, + RESETDRV_SWRESET_MFT1, + RESETDRV_SWRESET_GPIO, + RESETDRV_SWRESET_CMUP, + RESETDRV_SWRESET_CMUS, + RESETDRV_SWRESET_FLS, + RESETDRV_SWRESET_MPU, + RESETDRV_SWRESET_SYS +} ResetDrv_SwResetModuleType; + +/*! \brief Definition of delay between interrupt and reset + * \details The unit is LPO128k clock cycle + */ +typedef enum +{ + RESETDRV_RESETDELAY_10LPOCYCLES = 0, + RESETDRV_RESETDELAY_34LPOCYCLES = 1, + RESETDRV_RESETDELAY_130LPOCYCLES = 2, + RESETDRV_RESETDELAY_514LPOCYCLES = 3 +} ResetDrv_ResetDelayType; + +/*! \brief Definition of reset enable modules + */ +typedef enum +{ + RESETDRV_RESETEN_PLL_LOSS, + RESETDRV_RESETEN_LOCKUP, +} ResetDrv_ResetEnModuleType; + +/*! \brief Definition of reset interrupt modules + */ +typedef enum +{ + RESETDRV_RESETINT_WDG, + RESETDRV_RESETINT_SYS, + RESETDRV_RESETINT_PIN, + RESETDRV_RESETINT_MDMAP, + RESETDRV_RESETINT_PLL_LOSS, + RESETDRV_RESETINT_CMUP, + RESETDRV_RESETINT_CMUS, +} ResetDrv_ResetIntModuleType; + +/*! \brief Definition of reset source + */ +typedef enum +{ + RESETDRV_SOURCE_WDG = 0, + RESETDRV_SOURCE_SYS, + RESETDRV_SOURCE_LOCKUP, + RESETDRV_SOURCE_PIN, + RESETDRV_SOURCE_MDMAP, + RESETDRV_SOURCE_PLL_LOSS, + RESETDRV_SOURCE_CMUP, + RESETDRV_SOURCE_CMUS, + RESETDRV_SOURCE_FHU, + RESETDRV_SOURCE_STDBY_EXIT, + RESETDRV_SOURCE_FLS_INITIAL, + RESETDRV_SOURCE_LVR, + RESETDRV_SOURCE_POR, + + RESETDRV_SOURCE_NUM +} ResetDrv_SourceType; + +/*! \brief Definition of configuration of Reset driver + */ +typedef struct _ResetDrv_ConfigType_ +{ + bool enableExtFlt; /*!< whether to enable the external reset input digital filter */ + uint16_t extFltLen; /*!< external reset input digital filter length */ + bool enableResetInterrupt; /*!< whether to enable the global reset interrupt */ + ResetDrv_ResetDelayType delay; /*!< The delay between the interrupt and the reset */ +} ResetDrv_ConfigType; + +/* Forward declaration of related register */ +struct _RcmRegType_; +struct _Pcc1RegType_; +struct _Pcc0RegType_; + +/*! \brief The definition of RESET driver class + */ +typedef struct _ResetDrvType_ +{ + struct _RcmRegType_ *rcmReg; /*!< pointer to RCM register */ + struct _Pcc1RegType_ *pcc1Reg; /*!< pointer to PCC register */ + struct _Pcc0RegType_ *pcc0Reg; /*!< pointer to APC register */ +} ResetDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the Reset driver module + * + * This function initializes Reset driver by setting the register + * instances to it. + * + * \param[in] obj : pointer to Reset driver instance + * \param[in] rcmReg : pointer to RCM register instance + * \param[in] apcReg : pointer to APC register instance + */ +extern void ResetDrv_Init(ResetDrvType *obj, struct _RcmRegType_ *rcmReg, struct _Pcc1RegType_ *pcc1Reg, struct _Pcc0RegType_ *pcc0Reg); + +/*! \brief Get default configures the Reset module for configuration structure + * + * This function gets default configures the Reset module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void ResetDrv_GetDefaultConfig(ResetDrv_ConfigType *userConfig); + +/*! \brief Configures the Reset module from a user configuration structure + * + * This function configures the Reset module from a used configuration. + * + * \param[in] obj : pointer to Reset driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void ResetDrv_Configure(ResetDrvType *obj, const ResetDrv_ConfigType *userConfig); + +/*! \brief Get whether a specified source caused MCU's most recent reset + * + * This function gets whether a specified source caused MCU's most recent reset. + * Multiple source can be true if multiple reset events occur at the same time. + * + * \param[in] obj : pointer to Reset driver instance + * \param[in] source : the reset source + * \return whether the specified source caused MCU's most recent reset + * - true : the reset source occurred + * - false : the reset source not occurred + */ +extern bool ResetDrv_IsResetCaused(const ResetDrvType *obj, ResetDrv_SourceType source); + +/*! \brief Get whether a specified reset occurred since the last POR or LVD that have not been cleared by software + * + * This function gets whether a specified reset occurred since the last POR or LVD that have not been cleared by software + * + * \param[in] obj : pointer to Reset driver instance + * \param[in] source : the reset source + * \return whether the specified reset occurred since the last POR or LVD that have not been cleared by software + * - true : the reset source occurred + * - false : the reset source not occurred + */ +extern bool ResetDrv_IsResetSticky(const ResetDrvType *obj, ResetDrv_SourceType source); + +/*! \brief Clear Sticky reset flag since a reset has been caused + * + * This function clear Sticky reset flag since a reset has been caused + * + * \param[in] obj : pointer to Reset driver instance + * \param[in] source : the reset source + */ +extern void ResetDrv_ClrResetStickyFlag(ResetDrvType *obj, ResetDrv_SourceType source); + +/*! \brief Enable or disable the reset interrupt for a given module + * + * This function enable or disable the reset interrupt for a given module + * + * \param[in] obj : pointer to Reset driver instance + * \param[in] module : the module to configure + * \param[in] enable : whether to enable or disable the reset interrupt + * - true : enable the reset interrupt + * - falsa : disable the reset interrupt + */ +extern void ResetDrv_EnableResetInterrupt(ResetDrvType *obj, ResetDrv_ResetIntModuleType module, bool enable); + +/*! \brief Enable or disable the reset for a given module + * + * This function enable or disable the reset for a given module + * + * \param[in] obj : pointer to Reset driver instance + * \param[in] module : the module to configure + * \param[in] enable : whether to enable or disable the reset + * - true : enable the reset + * - falsa : disable the reset + */ +extern void ResetDrv_EnableReset(ResetDrvType *obj, ResetDrv_ResetEnModuleType module, bool enable); + +/*! \brief Trigger the software reset for a given module + * + * This function triggers the software reset for a given module + * + * \param[in] obj : pointer to Reset driver instance + * \param[in] module : the module to configure + */ +extern void ResetDrv_SoftwareResetModule(ResetDrvType *obj, ResetDrv_SwResetModuleType module); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _RESET_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/rtc/rtc_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/rtc/rtc_drv.c new file mode 100644 index 0000000..966d02b --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/rtc/rtc_drv.c @@ -0,0 +1,653 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "rtc_drv.h" +#include "rtc_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* Constants to transfer between TimeData and seconds*/ +#define SECONDS_IN_A_DAY (86400UL) +#define SECONDS_IN_A_HOUR (3600U) +#define SECONDS_IN_A_MIN (60U) +#define MINS_IN_A_HOUR (60U) +#define HOURS_IN_A_DAY (24U) +#define DAYS_IN_A_YEAR (365U) +#define DAYS_IN_A_LEAP_YEAR (366U) +#define YEAR_RANGE_START (1970U) +#define YEAR_RANGE_END (2099U) +#define MONTH_RANGE_START (1U) +#define MONTH_RANGE_END (12U) +#define DAY_RANGE_START (1U) +#define DAY_RANGE_END (31U) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief RTC register lock + */ +typedef enum +{ + RTCDRV_LOCK_REG_LOCK = 0x00U, /*!< RTC Lock Register lock */ + RTCDRV_STATUS_REG_LOCK = 0x01U, /*!< RTC Status Register lock */ + RTCDRV_CTRL_REG_LOCK = 0x02U, /*!< RTC Control Register lock */ +} RtcDrv_LockRegSelectType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/* Table of month length (in days) for the Un-leap-year*/ +const uint8_t c_unLeapYear[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U}; + +/* Table of month length (in days) for the Leap-year*/ +const uint8_t c_leapYear[] = {0U, 31U, 29U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U}; + +/* Number of days from begin of the non Leap-year*/ +const uint16_t c_monthDays[] = {0U, 0U, 31U, 59U, 90U, 120U, 151U, 181U, 212U, 243U, 273U, 304U, 334U}; + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the register lock status + * + * This function gets the register lock status + * + * \param[in] obj : pointer to RTC driver instance + * \param[in] lockRegSelect : the select of register lock + * \return the status of register lock + * - false : not locked + * - true : locked + */ +static inline bool RtcDrv_IsRegisterLocked(const RtcDrvType *obj, RtcDrv_LockRegSelectType lockRegSelect) +{ + bool result = false; + + switch(lockRegSelect) + { + case RTCDRV_LOCK_REG_LOCK: + result = ((RtcReg_GetLrLrl(obj->reg) == 0) ? true : false); + break; + case RTCDRV_STATUS_REG_LOCK: + result = ((RtcReg_GetLrSrl(obj->reg) == 0) ? true : false); + break; + case RTCDRV_CTRL_REG_LOCK: + result = ((RtcReg_GetLrCrl(obj->reg) == 0) ? true : false); + break; + default: + /* This statement should not be reached */ + break; + } + return result; +} + +/*! \brief Configure the RTC Clock out pin + * + * This function allows you to configure the RTC Clock out pin. + * + * \param[in] obj : pointer to RTC driver instance + * \param[in] config : the clock out configuration + * \return the result of the configure operation + * - false : failed + * - true : success + */ +static inline bool RtcDrv_ConfigureClockOut(RtcDrvType *obj, RtcDrv_ClkOutConfigType config) +{ + bool result = true; + + if(RtcDrv_IsRegisterLocked(obj, RTCDRV_CTRL_REG_LOCK) == true) + { + result = false; + } + else + { + switch(config) + { + case RTCDRV_CLKOUT_DISABLED: + RtcReg_SetCrCpe(obj->reg, 0); + break; + case RTCDRV_CLKOUT_SRC_TSIC: + RtcReg_SetCrCps(obj->reg, 0); + RtcReg_SetCrCpe(obj->reg, 1); + break; + case RTCDRV_CLKOUT_SRC_RTC: + RtcReg_SetCrCps(obj->reg, 1); + RtcReg_SetCrClkO(obj->reg, 0); + RtcReg_SetCrCpe(obj->reg, 1); + break; + default: + /* This statement should not be reached */ + break; + } + } + return result; +} + +/*! \brief Checks if the TCE can be written + * + * This function checks the following conditions to find if the + * Time Counter Enable bit is writable. + * - if Update Mode bitfield if 1 and: + * - Time is invalid or + * - Time Seconds Register has overflowed or + * - Time Counter is disabled, + * then the TCE bit can be set even if Status Register is locked. + * + * \param[in] obj : pointer to RTC driver instance + * \param[in] config : the clock out configuration + * \return the result of the configure operation + * - false : failed + * - true : success + */ +static inline bool RtcDrv_CanWriteTce(const RtcDrvType *obj) +{ + bool result = false; + + /* Check if the status register is locked */ + if(RtcDrv_IsRegisterLocked(obj, RTCDRV_STATUS_REG_LOCK) == false) + { + result = true; + } + /* Get the Update Mode bit */ + else if(RtcReg_GetCrUm(obj->reg) == 1) + { + bool tifFlagSet = RtcReg_GetSrTif(obj->reg) == 1; + bool tofFlagSet = RtcReg_GetSrTof(obj->reg) == 1; + bool tceFlagSet = RtcReg_GetSrTce(obj->reg) == 1; + + /* Check for the specified conditions */ + if((tifFlagSet == true) || (tofFlagSet == true) || (tceFlagSet == false)) + { + result = true; + } + } + else + { + result = false; + } + + /* Return the exit code */ + return result; +} + +void RtcDrv_Init(RtcDrvType *obj, struct _RtcRegType_ *const reg) +{ + obj->reg = reg; + + /* Initialize runtime structure */ + obj->runtimeConfig.isAlarmTimeNew = false; + obj->runtimeConfig.isAlarmConfigSet = false; + obj->runtimeConfig.isIntConfigSet = false; + obj->runtimeConfig.isSecondsIntConfigSet = false; +} + +void RtcDrv_GetDefaultConfig(RtcDrv_ConfigType *userConfig) +{ + userConfig->clockOutConfig = RTCDRV_CLKOUT_DISABLED; + userConfig->updateEnable = true; + userConfig->nonSupervisorAccessEnable = true; +} + +bool RtcDrv_Configure(RtcDrvType *obj, const RtcDrv_ConfigType *userConfig) +{ + bool retval = false; + + if(RtcDrv_IsRegisterLocked(obj, RTCDRV_CTRL_REG_LOCK) == false) + { /* not locked */ + RtcReg_SetCrSwr(obj->reg, 1); /* Write 1 to reset */ + while(RtcReg_GetSrTif(obj->reg) == 0) + { + ; + } + RtcReg_SetCrSwr(obj->reg, 0); + RtcDrv_ConfigureClockOut(obj, userConfig->clockOutConfig); + RtcReg_SetCrUm(obj->reg, userConfig->updateEnable ? 1 : 0); + RtcReg_SetCrSup(obj->reg, userConfig->nonSupervisorAccessEnable ? 1 : 0); + retval = true; + } + + return retval; +} + +bool RtcDrv_StartCounter(RtcDrvType *obj) +{ + /* Check if the TCE is writable and return corresponding result */ + if(RtcDrv_CanWriteTce(obj) == false) + { + return false; + } + /* if the counter is already enabled */ + if(RtcReg_GetSrTce(obj->reg) == 1) + { + return false; + } + RtcReg_SetSrCsd(obj->reg, 1); + /* if the counter is already CSD reg will set */ + while(RtcReg_GetSrCsd(obj->reg) == 0) + { + ; + } + RtcReg_SetSrTce(obj->reg, 1); + return true; +} + +bool RtcDrv_StopCounter(RtcDrvType *obj) +{ + /* Check if the TCE is writable and return corresponding result */ + if(RtcDrv_CanWriteTce(obj) == false) + { + return false; + } + /* if the counter is already enabled */ + if(RtcReg_GetSrTce(obj->reg) == 1) + { + RtcReg_SetSrTce(obj->reg, 0); + } + /* Read TCE bit to check if the counter is really disabled */ + return RtcReg_GetSrTce(obj->reg) == 0; +} + +bool RtcDrv_GetCurrentTimeDate(RtcDrvType *obj, RtcDrv_TimeDateType *currentTime) +{ + bool result = false; + uint32_t seconds; + uint32_t tempSeconds; + + /* Make two consecutive reads to ensure that the read was not + * done when the counter is incrementing. */ + tempSeconds = RtcReg_GetTsr(obj->reg); + seconds = RtcReg_GetTsr(obj->reg); + /* If the read was done when the counter was incrementing, + * try and read again. */ + if(tempSeconds != seconds) + { + tempSeconds = RtcReg_GetTsr(obj->reg); /* get the current time again */ + if(tempSeconds == seconds) + { + /* Convert the current time from seconds to time date structure */ + RtcDrv_ConvertSecondsToTimeDate(seconds, currentTime); + result = true; + } + } + else + { + /* Convert the current time from seconds to time date structure */ + RtcDrv_ConvertSecondsToTimeDate(seconds, currentTime); + result = true; + } + + return result; +} + +bool RtcDrv_SetTimeDate(RtcDrvType *obj, const RtcDrv_TimeDateType *time) +{ + /* Check if the TimeDate format is valid */ + if(RtcDrv_IsTimeDateCorrectFormat(time) == false) + { + return false; + } + /* Check if the TCE is writable and return corresponding result */ + if(RtcDrv_CanWriteTce(obj) == false) + { + return false; + } + /* Check if the counter is already started */ + if(RtcReg_GetSrTce(obj->reg) == 1) + { + return false; + } + + /* Convert the desired time to seconds */ + uint32_t seconds = 0; + RtcDrv_ConvertTimeDateToSeconds(time, &seconds); + RtcReg_SetTsr(obj->reg, seconds); + return true; +} + +bool RtcDrv_ConfigureRegisterLock(RtcDrvType *obj, const RtcDrv_RegLockConfigType *lockConfig) +{ + if(RtcReg_GetLrLrl(obj->reg) == 0) + { + return false; + } + + /* Configure Control register lock */ + if(lockConfig->controlRegisterLock) + { + RtcReg_SetLrCrl(obj->reg, 0); /* Write 0 to lock */ + } + /* Configure Status register lock */ + if(lockConfig->statusRegisterLock) + { + RtcReg_SetLrSrl(obj->reg, 0); /* Write 0 to lock */ + } + /* Configure Lock register lock */ + if(lockConfig->lockRegisterLock) + { + RtcReg_SetLrLrl(obj->reg, 0); /* Write 0 to lock */ + } + return true; +} + +void RtcDrv_GetRegisterLock(RtcDrvType *obj, RtcDrv_RegLockConfigType *lockConfig) +{ + /* For the Lock Register */ + lockConfig->lockRegisterLock = RtcDrv_IsRegisterLocked(obj, RTCDRV_LOCK_REG_LOCK); + /* For the Control Register */ + lockConfig->controlRegisterLock = RtcDrv_IsRegisterLocked(obj, RTCDRV_CTRL_REG_LOCK); + /* For the Status Register */ + lockConfig->statusRegisterLock = RtcDrv_IsRegisterLocked(obj, RTCDRV_STATUS_REG_LOCK); +} + +void RtcDrv_ConfigureOverFlowInt(RtcDrvType *obj, const RtcDrv_InterruptConfigType *intConfig) +{ + obj->runtimeConfig.intConfig = *intConfig; + obj->runtimeConfig.isIntConfigSet = true; + RtcReg_SetIerTioe(obj->reg, intConfig->overflowIntEnable ? 1 : 0); +} + +void RtcDrv_ConfigureSecondsInt(RtcDrvType *obj, const RtcDrv_SecondsIntConfigType *intConfig) +{ + obj->runtimeConfig.secondsIntConfig = *intConfig; + obj->runtimeConfig.isSecondsIntConfigSet = true; + + RtcReg_SetIerTsie(obj->reg, 0); + RtcReg_SetIerTsic(obj->reg, intConfig->secondIntConfig); + RtcReg_SetIerTsie(obj->reg, intConfig->secondIntEnable ? 1 : 0); +} + +bool RtcDrv_ConfigureAlarm(RtcDrvType *obj, const RtcDrv_AlarmConfigType *alarmConfig) +{ + bool result = false; + uint32_t alarmTime; + uint32_t currentTime; + + /* Check if the alarm time is in a correct format */ + if(RtcDrv_IsTimeDateCorrectFormat(&alarmConfig->alarmTime) == true) + { + /* Convert the time date to seconds */ + RtcDrv_ConvertTimeDateToSeconds(&alarmConfig->alarmTime, &alarmTime); + /* Get current time in seconds */ + currentTime = RtcReg_GetTsr(obj->reg); + /* Check if the alarm time is greater than current time */ + if(alarmTime > currentTime) + { + obj->runtimeConfig.alarmConfig = *alarmConfig; + obj->runtimeConfig.isAlarmConfigSet = true; + RtcReg_SetIerTaie(obj->reg, 0); + RtcReg_SetTar(obj->reg, alarmTime); + RtcReg_SetIerTaie(obj->reg, alarmConfig->alarmIntEnable); + } + } + + return result; +} + +void RtcDrv_GetAlarmConfig(const RtcDrvType *obj, RtcDrv_AlarmConfigType *alarmConfig) +{ + if(obj->runtimeConfig.isAlarmConfigSet) + { + *alarmConfig = obj->runtimeConfig.alarmConfig; + } +} + +bool RtcDrv_IsAlarmPending(const RtcDrvType *obj) +{ + return RtcReg_GetSrTaf(obj->reg) == 1; +} + +void RtcDrv_ConvertSecondsToTimeDate(uint32_t seconds, RtcDrv_TimeDateType *timeDate) +{ + uint8_t i; + bool yearLeap = false; + uint32_t numberOfDays = 0U; + uint32_t tempSeconds; + uint16_t daysInYear; + + /* Because the starting year(1970) is not leap, set the daysInYear + * variable with the number of the days in a normal year + */ + daysInYear = DAYS_IN_A_YEAR; + /* Set the year to the beginning of the range */ + timeDate->year = YEAR_RANGE_START; + /* Get the number of days */ + numberOfDays = seconds / SECONDS_IN_A_DAY; + /* Get the number of seconds remaining */ + tempSeconds = seconds % SECONDS_IN_A_DAY; + /* Get the current hour */ + timeDate->hour = (uint16_t)(tempSeconds / SECONDS_IN_A_HOUR); + /* Get the remaining seconds */ + tempSeconds = tempSeconds % SECONDS_IN_A_HOUR; + /* Get the minutes */ + timeDate->minutes = (uint16_t)(tempSeconds / SECONDS_IN_A_MIN); + /* Get seconds */ + timeDate->seconds = (uint8_t)(tempSeconds % SECONDS_IN_A_MIN); + /* Get the current year */ + while(numberOfDays >= daysInYear) + { + /* Increment year if the number of days is greater than the ones in one year */ + timeDate->year++; + /* Subtract the number of the days */ + numberOfDays -= daysInYear; + + /* Check if the year is leap or unleap */ + if(!RtcDrv_IsYearLeap(timeDate->year)) + { + daysInYear = DAYS_IN_A_YEAR; + } + else + { + daysInYear = DAYS_IN_A_LEAP_YEAR; + } + } + /* Add the current day */ + numberOfDays += 1U; + /* Check if the current year is leap */ + yearLeap = RtcDrv_IsYearLeap(timeDate->year); + /* Get the month */ + for(i = 1U; i <= 12U; i++) + { + uint32_t daysInCurrentMonth = ((yearLeap == true) ? (uint32_t)c_leapYear[i] : (uint32_t)c_unLeapYear[i]); + if(numberOfDays <= daysInCurrentMonth) + { + timeDate->month = (uint16_t)i; + break; + } + else + { + numberOfDays -= daysInCurrentMonth; + } + } + /* Set the current day */ + timeDate->day = (uint16_t)numberOfDays; +} + +void RtcDrv_ConvertTimeDateToSeconds(const RtcDrv_TimeDateType *timeDate, uint32_t *seconds) +{ + /* Declare local variables */ + uint16_t year; + + /* Convert years to seconds */ + (*seconds) = (uint32_t)(DAYS_IN_A_YEAR * (uint32_t)(SECONDS_IN_A_DAY)); + (*seconds) *= ((uint32_t)timeDate->year - YEAR_RANGE_START); + + /* Add the seconds from the leap years */ + for(year = YEAR_RANGE_START; year < timeDate->year; year++) + { + if(RtcDrv_IsYearLeap(year)) + { + (*seconds) += SECONDS_IN_A_DAY; + } + } + + /* If the current year is leap and 29th of February has passed, add + * another day to seconds passed. + */ + if(RtcDrv_IsYearLeap(year) && timeDate->month > 2U) + { + (*seconds) += SECONDS_IN_A_DAY; + } + + (*seconds) += c_monthDays[timeDate->month] * SECONDS_IN_A_DAY; + (*seconds) += (uint32_t)(((uint32_t)timeDate->day - 1U) * (uint32_t)SECONDS_IN_A_DAY); + (*seconds) += (uint32_t)((uint32_t)timeDate->hour * SECONDS_IN_A_HOUR) + (uint32_t)((uint32_t)timeDate->minutes * SECONDS_IN_A_MIN) + (uint32_t)((uint32_t)timeDate->seconds); +} + +bool RtcDrv_IsYearLeap(uint16_t year) +{ + bool isYearLeap = false; + + if((year % 4U) > 0U) + { + isYearLeap = false; + } + else if((year % 100U) > 0U) + { + isYearLeap = true; + } + else if((year % 400U) > 0U) + { + isYearLeap = false; + } + else + { + isYearLeap = true; + } + + return isYearLeap; +} + +bool RtcDrv_IsTimeDateCorrectFormat(const RtcDrv_TimeDateType *timeDate) +{ + /* Declare local variables */ + bool retval = true; + const uint8_t *pDays; + + /* Set the days-in-month table for the corresponding year */ + pDays = RtcDrv_IsYearLeap(timeDate->year) ? (c_leapYear) : (c_unLeapYear); + + /* Check if the time and date are in the correct ranges */ + if((timeDate->year < YEAR_RANGE_START) || (timeDate->year > YEAR_RANGE_END) + || (timeDate->month < 1U) || (timeDate->month > 12U) + || (timeDate->day < 1U) || (timeDate->day > 31U) + || (timeDate->hour >= HOURS_IN_A_DAY) + || (timeDate->minutes >= MINS_IN_A_HOUR) || (timeDate->seconds >= SECONDS_IN_A_MIN)) + { + retval = false; + } + /* Check if the day is a valid day from the corresponding month */ + else if(timeDate->day > pDays[timeDate->month]) + { + retval = false; + } + else + { + retval = true; + } + + return retval; +} + +bool RtcDrv_GetNextAlarmTime(RtcDrvType *obj, RtcDrv_TimeDateType *alarmTime) +{ + bool result = false; + uint32_t alarmInSec; + /* Check if is a new alarm and if true update alarm time date format from time seconds */ + if(obj->runtimeConfig.isAlarmTimeNew == true) + { + alarmInSec = RtcReg_GetTar(obj->reg); + RtcDrv_ConvertSecondsToTimeDate(alarmInSec, alarmTime); + result = true; + } + return result; +} + +void RtcDrv_IrqHandler(RtcDrvType *obj) +{ + uint32_t tempSeconds; + + /* Check if an alarm has occurred */ + if(RtcReg_GetSrTaf(obj->reg) == 1) + { + /* If the alarm interrupt configuration has been defined process the + * alarm IRQ + */ + if(obj->runtimeConfig.isAlarmConfigSet) + { + /* If recurrence is enabled modify the alarm register to the next + * alarm. + */ + if((obj->runtimeConfig.alarmConfig.numberOfRepeats > 0UL) || (obj->runtimeConfig.alarmConfig.repeatForever == true)) + { + /* Get current time */ + tempSeconds = RtcReg_GetTsr(obj->reg); + /* Current time is incremented with the repetition value */ + tempSeconds += obj->runtimeConfig.alarmConfig.repetitionInterval - 1; + /* Set new value to trigger the alarm */ + RtcReg_SetTar(obj->reg, tempSeconds); + + obj->runtimeConfig.isAlarmTimeNew = true; + /* If the alarm repeats forever, set number of repeats to 0 + * to avoid an accidental trigger of the core overflow flag + */ + obj->runtimeConfig.alarmConfig.numberOfRepeats = (obj->runtimeConfig.alarmConfig.repeatForever == false) ? (obj->runtimeConfig.alarmConfig.numberOfRepeats - 1UL) : 0UL; + } + else + { + /* If the alarm does not repeat, write 0 to TAR to clear the + * alarm flag. + */ + RtcReg_SetTar(obj->reg, 0); + obj->runtimeConfig.isAlarmTimeNew = false; + } + /* If the user has defined a callback, call it */ + if(obj->runtimeConfig.alarmConfig.alarmCallback != NULL) + { + obj->runtimeConfig.alarmConfig.alarmCallback(obj->runtimeConfig.alarmConfig.callbackParams); + } + } + } + + /* Check if an overflow has occurred */ + if(RtcReg_GetSrTof(obj->reg) == 1) + { + /* If the overflow interrupt configuration has been defined process the IRQ */ + if(obj->runtimeConfig.isIntConfigSet) + { + if(obj->runtimeConfig.intConfig.overflowCallback != NULL) + { + obj->runtimeConfig.intConfig.overflowCallback(obj->runtimeConfig.intConfig.callbackParams); + } + } + } +} + +void RtcDrv_SecondsIrqHandler(RtcDrvType *obj) +{ + if(obj->runtimeConfig.isSecondsIntConfigSet && obj->runtimeConfig.secondsIntConfig.secondsCallback != NULL) + { + obj->runtimeConfig.secondsIntConfig.secondsCallback(obj->runtimeConfig.secondsIntConfig.callbackParams); + } +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/rtc/rtc_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/rtc/rtc_drv.h new file mode 100644 index 0000000..df296f6 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/rtc/rtc_drv.h @@ -0,0 +1,403 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _RTC_DRV_H_ +#define _RTC_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of RTC (Real Time Clock) + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup rtc_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Definition of RTC CLKOUT Pin Configuration. + */ +typedef enum +{ + RTCDRV_CLKOUT_DISABLED = 0x00U, /*!< Clock out disabled */ + RTCDRV_CLKOUT_SRC_TSIC = 0x01U, /*!< The prescaler output clock (as configured by TSIC) is output on RTC_CLKOUT. */ + RTCDRV_CLKOUT_SRC_RTC = 0x02U, /*!< The RTC source clock is output on RTC_CLKOUT, provided it is output to other peripherals. */ +} RtcDrv_ClkOutConfigType; + +/*! \brief Definition of RTC Timer Seconds Interrupt Configuration. + */ +typedef enum +{ + RTCDRV_SECOND_INT_1HZ = 0x00U, /*!< Timer Seconds Interrupt Configuration 1 Hz */ + RTCDRV_SECOND_INT_2HZ = 0x01U, /*!< Timer Seconds Interrupt Configuration 2 Hz */ + RTCDRV_SECOND_INT_4HZ = 0x02U, /*!< Timer Seconds Interrupt Configuration 4 Hz */ + RTCDRV_SECOND_INT_8HZ = 0x03U, /*!< Timer Seconds Interrupt Configuration 8 Hz */ + RTCDRV_SECOND_INT_16HZ = 0x04U, /*!< Timer Seconds Interrupt Configuration 16 Hz */ + RTCDRV_SECOND_INT_32HZ = 0x05U, /*!< Timer Seconds Interrupt Configuration 32 Hz */ + RTCDRV_SECOND_INT_64HZ = 0x06U, /*!< Timer Seconds Interrupt Configuration 64 Hz */ + RTCDRV_SECOND_INT_128HZ = 0x07U /*!< Timer Seconds Interrupt Configuration 128 Hz */ +} RtcDrv_SecondIntConfigType; + +/*! \brief RTC Time TimeDate. + */ +typedef struct _RtcDrv_TimeDateType_ +{ + uint16_t year; /*!< Year. */ + uint16_t month; /*!< Month. */ + uint16_t day; /*!< Day. */ + uint16_t hour; /*!< Hour. */ + uint16_t minutes; /*!< Minutes. */ + uint8_t seconds; /*!< Seconds. */ +} RtcDrv_TimeDateType; + +/*! \brief RTC Register Lock configuration + */ +typedef struct _RtcDrv_RegLockConfigType_ +{ + bool lockRegisterLock; /*!< Lock state of the Lock Register */ + bool statusRegisterLock; /*!< Lock state of the Status Register */ + bool controlRegisterLock; /*!< Lock state of the Control Register */ +} RtcDrv_RegLockConfigType; + +/*! \brief RTC Interrupt configuration + */ +typedef struct _RtcDrv_InterruptConfigType_ +{ + bool overflowIntEnable; /*!< Enable Time Overflow Interrupt. */ + void (*overflowCallback)(void *callbackParams); /*!< OverFlow Interrupt callback. */ + void *callbackParams; /*!< OverFlow Interrupt callback parameters. */ +} RtcDrv_InterruptConfigType; + +/*! \brief RTC Seconds Interrupt configuration + */ +typedef struct _RtcDrv_SecondsIntConfigType_ +{ + RtcDrv_SecondIntConfigType secondIntConfig; /*!< Seconds Interrupt Configures The Frequency. */ + bool secondIntEnable; /*!< Seconds Interrupt Enable. */ + void (*secondsCallback)(void *callbackParams); /*!< Seconds Interrupt Callback. */ + void *callbackParams; /*!< Seconds Interrupt Callback Parameters. */ +} RtcDrv_SecondsIntConfigType; + +/*! \brief RTC Alarm Interrupt Configuration + */ +typedef struct _RtcDrv_AlarmConfigType_ +{ + RtcDrv_TimeDateType alarmTime; /*!< Alarm TimeData. */ + uint32_t repetitionInterval; /*!< Interval of repetition in sec */ + uint32_t numberOfRepeats; /*!< Number of alarm repeats */ + bool repeatForever; /*!< Repeat forever if set, discard number of repeats */ + bool alarmIntEnable; /*!< Enable alarm interrupt */ + void (*alarmCallback)(void *callbackParams); /*!< Pointer to the user callback method. */ + void *callbackParams; /*!< Pointer to the callback parameters. */ +} RtcDrv_AlarmConfigType; + +/*! \brief RTC Configuration + */ +typedef struct _RtcDrv_ConfigType_ +{ + RtcDrv_ClkOutConfigType clockOutConfig; /*!< RTC CLKOUT Pin Configuration. */ + bool updateEnable; /*!< RTC Update Mode configuration. */ + bool nonSupervisorAccessEnable; /*!< RTC Supervisor Access. */ +} RtcDrv_ConfigType; + +/*! \brief RTC runtime structure + */ +typedef struct _RtcDrv_RuntimeConfigType_ +{ + bool isAlarmTimeNew; /*!< Check if there is a new alarm */ + bool isAlarmConfigSet; /*!< If the alarm configure set */ + RtcDrv_AlarmConfigType alarmConfig; /*!< Alarm configuration */ + bool isIntConfigSet; /*!< If the interrupt configure set */ + RtcDrv_InterruptConfigType intConfig; /*!< Interrupt configuration */ + bool isSecondsIntConfigSet; /*!< If the seconds interrupt configure set */ + RtcDrv_SecondsIntConfigType secondsIntConfig; /*!< Time seconds interrupt configuration */ +} RtcDrv_RuntimeConfigType; + +/* Forward declaration of related register */ +struct _RtcRegType_; + +/*! \brief The definition of RTC driver class + */ +typedef struct _RtcDrvType_ +{ + struct _RtcRegType_ *reg; /*!< pointer to the RTC register*/ + RtcDrv_RuntimeConfigType runtimeConfig; /*!< runtime configuration */ +} RtcDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the RTC driver module + * + * This function initializes RTC driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to RTC driver instance + * \param[in] reg : pointer to RTC register instance + */ +extern void RtcDrv_Init(RtcDrvType *obj, struct _RtcRegType_ *reg); + +/*! \brief Get default configures the RTC module for configuration structure + * + * This function gets default configures the Rtc module for user configuration structure + * + * \note This function is a "static" function regardless of instances + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void RtcDrv_GetDefaultConfig(RtcDrv_ConfigType *userConfig); + +/*! \brief Configures the RTC module from a user configuration structure + * + * This function configures the RTC instance with the settings + * provided by the user via the userConfig parameter. The user must ensure + * that clock is enabled for the RTC instance used. + * In order to clear the CR Lock the user must perform a power-on reset. + * + * \param[in] obj : pointer to RTC driver instance + * \param[in] userConfig : pointer to configuration structure + * \return the result of the configure operation + * - false : configure failed + * - true : success + */ +extern bool RtcDrv_Configure(RtcDrvType *obj, const RtcDrv_ConfigType *userConfig); + +/*! \brief Start RTC instance counter. + * + * This function starts the RTC counter. + * Should use RtcDrv_Configure to configure the start time. + * + * \param[in] obj : pointer to RTC driver instance. + */ +extern bool RtcDrv_StartCounter(RtcDrvType *obj); + +/*! \brief Disable RTC instance counter. + * + * This function stops the RTC counter + * + * \param[in] obj : pointer to RTC driver instance. + */ +extern bool RtcDrv_StopCounter(RtcDrvType *obj); + +/*! \brief Get current TimeData from RTC instance. + * + * \param[in] obj : pointer to RTC driver instance. + * \param[out] currentTime : pointer to Rtc TimeDate structure. + * \return the result of the operation + * - false : the operation failed + * - true : success + */ +extern bool RtcDrv_GetCurrentTimeDate(RtcDrvType *obj, RtcDrv_TimeDateType *currentTime); + +/*! \brief Set timedate for RTC instance. + * + * The user must stop the counter + * before using this function. Otherwise it will return an error + * + * \param[in] obj : pointer to RTC driver instance. + * \param[in] time : pointer to Rtc Time TimeDate structure. + * \return the result of the operation + * - false : the operation failed, the time provided was invalid or the counter was not stopped + * - true : success + */ +extern bool RtcDrv_SetTimeDate(RtcDrvType *obj, const RtcDrv_TimeDateType *time); + +/*! \brief This method configures register lock for the corresponding RTC instance. + * + * Remember that all the registers are unlocked only by software reset or power on reset. + * (Except for CR that is unlocked only by POR). + * + * \param[in] obj : pointer to RTC driver instance. + * \param[in] lockConfig : pointer to Rtc Register Lock structure. + */ +extern bool RtcDrv_ConfigureRegisterLock(RtcDrvType *obj, const RtcDrv_RegLockConfigType *lockConfig); + +/*! \brief Get which registers are locked for RTC instance + * + * This function gets which registers are locked + * + * \param[in] obj : pointer to RTC driver instance. + * \param[out] lockConfig : pointer to Rtc Register Lock structure. + */ +extern void RtcDrv_GetRegisterLock(RtcDrvType *obj, RtcDrv_RegLockConfigType *lockConfig); + +/*! \brief Configure OverFlow Interrupt. + * + * This function configures the overflow interrupt + * + * \note Must disable the corresponding interrupt in the IRQ system + * before configure + * + * \param[in] obj : pointer to RTC driver instance. + * \param[in] intConfig : pointer to the structure which holds the configuration + */ +extern void RtcDrv_ConfigureOverFlowInt(RtcDrvType *obj, const RtcDrv_InterruptConfigType *intConfig); + +/*! \brief Configure Seconds Interrupt. + * + * This function configures the Seconds interrupt + * + * \note Must disable the corresponding interrupt in the IRQ system + * before configure + * + * \param[in] obj : pointer to RTC driver instance. + * \param[in] intConfig : pointer to the structure which holds the configuration + */ +extern void RtcDrv_ConfigureSecondsInt(RtcDrvType *obj, const RtcDrv_SecondsIntConfigType *intConfig); + +/*! \brief Configure alarm. + * + * This function configures the alarm with the configuration from the alarmConfig parameter + * + * \note Must disable the corresponding interrupt in the IRQ system + * before configure + * + * \param[in] obj : pointer to RTC driver instance. + * \param[in] alarmConfig : pointer to Rtc Alarm Interrupt Configuration. + * \return the result of the configure + * - false : the alarm time is invalid + * - true : configure success + */ +extern bool RtcDrv_ConfigureAlarm(RtcDrvType *obj, const RtcDrv_AlarmConfigType *alarmConfig); + +/*! \brief Get alarm configuration for RTC instance + * + * This function gets the current alarm configuration + * + * \param[in] obj : pointer to RTC driver instance. + * \param[out] alarmConfig : Pointer to the structure in which to store the alarm configuration + */ +extern void RtcDrv_GetAlarmConfig(const RtcDrvType *obj, RtcDrv_AlarmConfigType *alarmConfig); + +/*! \brief Get Time Alarm Flag. + * + * This function gets the time alarm flag + * + * \param[in] obj : pointer to RTC driver instance. + * \return if there is the alarm pending flag + * - false : no alarm pending + * - true : alarm is pending + */ +extern bool RtcDrv_IsAlarmPending(const RtcDrvType *obj); + +/*! \brief Convert Seconds To TimeDate. + * + * This function converts the seconds to TimeDate format. + * + * \note This function is a "static" function regardless of instances + * + * \param[in] seconds : seconds. + * \param[out] timeDate : pointer to Rtc TimeDate Structure. + */ +extern void RtcDrv_ConvertSecondsToTimeDate(uint32_t seconds, RtcDrv_TimeDateType *timeDate); + +/*! \brief Convert TimeDate To Seconds. + * + * This function converts the TimeDate format to seconds + * + * \note This function is a "static" function regardless of instances + * + * \param[in] timeDate : Rtc TimeDate Structure. + * \param[out] seconds : pointer to seconds. + */ +extern void RtcDrv_ConvertTimeDateToSeconds(const RtcDrv_TimeDateType *timeDate, uint32_t *seconds); + +/*! \brief Check year is leap + * + * This function checks whether it's a leap year + * + * \note This function is a "static" function regardless of instances + * + * \param[in] year : Year to check + * \return if the year is leap + * - false : not leap + * - true : the year is leap + */ +extern bool RtcDrv_IsYearLeap(uint16_t year); + +/*! \brief Check if the date time struct is configured properly + * + * This function checks if the TimeDate format is valid. + * + * \note This function is a "static" function regardless of instances + * + * \param[in] config: timeDate Structure + * \return if the time date is in the corrent format + * - false : not in the corrent format + * - true : the format is corrent + */ +extern bool RtcDrv_IsTimeDateCorrectFormat(const RtcDrv_TimeDateType *timeDate); + +/*! \brief Gets the next alarm time + * + * \param[in] obj : pointer to RTC driver instance. + * \param[in] config : pointer to Rtc Alarm Configuration Structure. + * \param[in] gettime : pointer to Rtc TimeDate Structure. + * \return the result of the operation + * - false : the get operation failed + * - true : success + */ +extern bool RtcDrv_GetNextAlarmTime(RtcDrvType *obj, RtcDrv_TimeDateType *alarmTime); + +/*! \brief IRQ Handler + * + * This method is the API's Interrupt handler for generic and alarm IRQ. + * It will handle the alarm repetition and calls the user callbacks if they + * are not NULL. + * Should be called in the IRQ handler of the IRQ system + * + * \param[in] obj : pointer to RTC driver instance. + */ +extern void RtcDrv_IrqHandler(RtcDrvType *obj); + +/*! \brief Seconds IRQ Handler + * + * This method is the API's Interrupt handler for RTC Second + * interrupt. This ISR will call the user callback if defined. + * Should be called in the IRQ handler of the IRQ system + * + * \param[in] obj : pointer to RTC driver instance. + */ +extern void RtcDrv_SecondsIrqHandler(RtcDrvType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _RTC_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/spi/spi_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/spi/spi_drv.c new file mode 100644 index 0000000..ccea836 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/spi/spi_drv.c @@ -0,0 +1,1966 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/****************************************************************************** + * the includes + *****************************************************************************/ + +#include "spi_drv.h" + +/****************************************************************************** + * the defines + *****************************************************************************/ + +/****************************************************************************** + * the typedefs + *****************************************************************************/ + +/****************************************************************************** + * the globals + *****************************************************************************/ + +/****************************************************************************** + * the static function declarations + *****************************************************************************/ +static void SpiDrv_GoldenSectionAlgorithm(SpiDrv_GoldenSectionInfoType *pGoldenSectionInfo); +static void SpiDrv_InitTxCommand(SpiRegType *obj, const SpiDrv_InitCfgType *pInitCfg); +static void SpiDrv_InitBasicParameters(SpiRegType *obj, const SpiDrv_BasicParametersType *pBasicParameters); +static void SpiDrv_InitExtendParameters(SpiRegType *obj, const SpiDrv_ExtendParametersType *pExtendParameters, const SpiDrv_ExtendFeaturesType *pExtendFeatures); +static SpiDrv_ShiftFirstBitType SpiDrv_GetDataShiftDirection(const SpiDrvType *obj); + +/****************************************************************************** + * the functions + *****************************************************************************/ + +/*! \brief the algorithm of golden section + * + * the algorithm of golden section + * + * \param[in] pGoldenSectionInfo : the golden section structure + * \return: void + */ +static void SpiDrv_GoldenSectionAlgorithm(SpiDrv_GoldenSectionInfoType *pGoldenSectionInfo) +{ + uint8_t tPrescalerIdx = 0; + uint8_t tMinIdx = 0; + uint32_t tDiffMin = 0; + uint32_t tFreq = 0; + uint16_t tDivIdx = 0; + bool tScanOver = false; + + SpiDrv_CalculateTblType tCalculateTbl[8] = {0}; + const uint32_t prescalerList[8] = {1, 2, 4, 8, 16, 32, 64, 128}; + const uint8_t prescalerNums = 8; + const uint32_t maxDivValue = 0xFF + 2; + + for(tPrescalerIdx = 0; tPrescalerIdx < prescalerNums; tPrescalerIdx++) + { + tCalculateTbl[tPrescalerIdx].diff = 0xFFFFFFFF; + tCalculateTbl[tPrescalerIdx].div = 0; + } + + for(tPrescalerIdx = 0; tPrescalerIdx < prescalerNums; tPrescalerIdx++) + { + for(tDivIdx = 2; tDivIdx <= maxDivValue; tDivIdx++) + { + tFreq = (pGoldenSectionInfo->freqInput / prescalerList[tPrescalerIdx]) / tDivIdx; + + if(tFreq == pGoldenSectionInfo->freqTargetOut) + { + tCalculateTbl[tPrescalerIdx].div = tDivIdx; + tCalculateTbl[tPrescalerIdx].prescalerIdx = tPrescalerIdx; + tCalculateTbl[tPrescalerIdx].diff = 0; + + tScanOver = true; + break; + } + else if(tFreq < pGoldenSectionInfo->freqTargetOut) + { + tCalculateTbl[tPrescalerIdx].div = tDivIdx; + tCalculateTbl[tPrescalerIdx].prescalerIdx = tPrescalerIdx; + tCalculateTbl[tPrescalerIdx].diff = pGoldenSectionInfo->freqTargetOut - tFreq; + break; + } + } + + if(tScanOver == true) + { + break; + } + } + + tMinIdx = 0; + tDiffMin = tCalculateTbl[tMinIdx].diff; + for(tPrescalerIdx = 1; tPrescalerIdx < prescalerNums; tPrescalerIdx++) + { + if(tCalculateTbl[tPrescalerIdx].diff < tDiffMin) + { + tDiffMin = tCalculateTbl[tPrescalerIdx].diff; + tMinIdx = tPrescalerIdx; + } + } + + if(tCalculateTbl[tMinIdx].div < 2) + { + tFreq = (pGoldenSectionInfo->freqInput / prescalerList[prescalerNums - 1]) / maxDivValue; + + pGoldenSectionInfo->bestOutPrescaler = prescalerNums - 1; + pGoldenSectionInfo->bestOutDiv = maxDivValue - 2; + pGoldenSectionInfo->bestOutFreq = tFreq; + } + else + { + pGoldenSectionInfo->bestOutPrescaler = tCalculateTbl[tMinIdx].prescalerIdx; + pGoldenSectionInfo->bestOutDiv = tCalculateTbl[tMinIdx].div - 2; + pGoldenSectionInfo->bestOutFreq = (uint32_t)(pGoldenSectionInfo->freqTargetOut - tCalculateTbl[tMinIdx].diff); + } +} + +/*! \brief Sets the Transmit Command Register (TCR) parameters + * + * this function initial the spi parameters about clock polarity and other parameters + * + * \param[in] obj : base reg address for the SPI instance + * \param[in] pInitCfg : Structure that contains the settings + * \return: void + */ +static void SpiDrv_InitTxCommand(SpiRegType *obj, const SpiDrv_InitCfgType *pInitCfg) +{ + uint32_t tTcr = 0; + uint8_t tPrescaler = 0; + uint32_t tDiv = 0; + + tTcr = SpiReg_GetTcr(obj); + + /* Normal transfer, used the default configuration, set it again if extend features used */ + SpiDrv_SetTxDataMask(&tTcr, false); + SpiDrv_SetRxDataMask(&tTcr, false); + + /* First Bit shift */ + SpiDrv_SetLowBitFirstTransfer(&tTcr, pInitCfg->basicParameters.dataShiftFirstBit); + + /* CPHA */ + SpiDrv_SetClockPhase(&tTcr, pInitCfg->basicParameters.clockPhase); + + /* CPOL */ + SpiDrv_SetClockPolarity(&tTcr, pInitCfg->basicParameters.clockPolarity); + + { + SpiDrv_GoldenSectionInfoType tGoldenSectionInfo; + + tGoldenSectionInfo.freqTargetOut = pInitCfg->basicParameters.baudRate; + tGoldenSectionInfo.freqInput = pInitCfg->basicParameters.busClockFreq; + + SpiDrv_GoldenSectionAlgorithm(&tGoldenSectionInfo); + + tPrescaler = (uint8_t)tGoldenSectionInfo.bestOutPrescaler; + tDiv = tGoldenSectionInfo.bestOutDiv; + /* SCK Div */ + SpiReg_SetSckDiv(obj, (uint8_t)tDiv); + } + + /* Prescaler */ + SpiDrv_SetPrescaler(&tTcr, tPrescaler); + + /* Frame Size */ + SpiDrv_SetFrameSize(&tTcr, (uint16_t)(pInitCfg->basicParameters.frameBitSize - 1u)); + + /* Byte-Swap, only in the frame size /32 != 0u case, can used the byte swap */ + if((pInitCfg->basicParameters.frameBitSize & SPIDRV_ONE_FRAME_BITS_MAX_NUM) != 0u) + { + SpiDrv_SetByteSwap(&tTcr, pInitCfg->extendFeatures.byteSwapEn); + } + else + { + SpiDrv_SetByteSwap(&tTcr, 0u); + } + + /* Select PCS */ + SpiDrv_SetPcsSelection(&tTcr, pInitCfg->basicParameters.pcsSelection); + + /* PIN Cfg */ + switch(pInitCfg->extendParameters.pinCfg) + { + case SPIDRV_PIN_CFG_SIN_IN_SOUT_OUT: + /* only support single-full duplex */ + SpiDrv_SetTransferWidth(&tTcr, 0); + + /* TX RX MASK */ + SpiDrv_SetRxDataMask(&tTcr, pInitCfg->extendFeatures.rxMaskEn); + SpiDrv_SetTxDataMask(&tTcr, pInitCfg->extendFeatures.txMaskEn); + break; + + case SPIDRV_PIN_CFG_HALF_DUPLEX_SIN: + /* For half-duplex parallel transfers, either Receive Data Mask (RXMSK) or Transmit Data Mask (TXMSK) must be set */ + SpiDrv_SetRxDataMask(&tTcr, 1); + SpiDrv_SetTxDataMask(&tTcr, 0); + + /* Duplex, single line or double line */ + if(pInitCfg->extendParameters.duplexType == SPIDRV_DUPLEX_HALF_DUPLEX_IN_SINGLE_LINE) + { + SpiDrv_SetTransferWidth(&tTcr, 0); + } + else if(pInitCfg->extendParameters.duplexType == SPIDRV_DUPLEX_HALF_DUPLEX_IN_DOUBLE_LINE) + { + SpiDrv_SetTransferWidth(&tTcr, 1); + } + break; + + case SPIDRV_PIN_CFG_HALF_DUPLEX_SOUT: + /* Duplex, single line or double line */ + if(pInitCfg->extendParameters.duplexType == SPIDRV_DUPLEX_HALF_DUPLEX_IN_SINGLE_LINE) + { + SpiDrv_SetTransferWidth(&tTcr, 0); + } + else if(pInitCfg->extendParameters.duplexType == SPIDRV_DUPLEX_HALF_DUPLEX_IN_DOUBLE_LINE) + { + SpiDrv_SetTransferWidth(&tTcr, 1); + } + + /* For half-duplex parallel transfers, either Receive Data Mask (RXMSK) or Transmit Data Mask (TXMSK) must be set */ + SpiDrv_SetRxDataMask(&tTcr, 1); + SpiDrv_SetTxDataMask(&tTcr, 0); + break; + + case SPIDRV_PIN_CFG_SIN_OUT_SOUT_IN: + /* only support single-full duplex */ + SpiDrv_SetTransferWidth(&tTcr, 0); + + /* TX RX MASK */ + SpiDrv_SetRxDataMask(&tTcr, pInitCfg->extendFeatures.rxMaskEn); + SpiDrv_SetTxDataMask(&tTcr, pInitCfg->extendFeatures.txMaskEn); + break; + + default: + /* only support single-full duplex */ + SpiDrv_SetTransferWidth(&tTcr, 0); + + /* TX RX MASK */ + SpiDrv_SetRxDataMask(&tTcr, pInitCfg->extendFeatures.rxMaskEn); + SpiDrv_SetTxDataMask(&tTcr, pInitCfg->extendFeatures.txMaskEn); + break; + } + + obj->TCR = tTcr; +} + +/*! \brief Init the spi module basic parameters and basic functions + * + * this function initializes the basic features with the parameters + * + * \param[in] obj : pointer to the instance + * \param[in] pBasicParameters : the conbination of basic parameters + * \return: void + */ +static void SpiDrv_InitBasicParameters(SpiRegType *obj, const SpiDrv_BasicParametersType *pBasicParameters) +{ + /* Configures the SPI in master or slave mode */ + SpiReg_SetNodeMode(obj, pBasicParameters->isMasterNode); + + /* Peripheral Chip Select Polarity */ + SpiReg_SetPcsPolarity(obj, (uint8_t)(((uint8_t)pBasicParameters->pcsPolarity) << ((uint8_t)pBasicParameters->pcsSelection))); +} + +/*! \brief Init the spi module extend parameters and extend functions + * + * this function initializes the extend features with the parameters + * + * \param[in] obj : pointer to the instance + * \param[in] pExtendParameters: the conbination of all extend parameters + * \param[in] pExtendFeatures: the conbination of the all extend features + * \return: void + */ +static void SpiDrv_InitExtendParameters(SpiRegType *obj, const SpiDrv_ExtendParametersType *pExtendParameters, const SpiDrv_ExtendFeaturesType *pExtendFeatures) +{ + /* DMA TX */ + SpiReg_SetTxDMA(obj, pExtendFeatures->dmaTxEn); + + /* DMA RX */ + SpiReg_SetRxDMA(obj, pExtendFeatures->dmaRxEn); + + /* NO-STALL */ + SpiReg_SetNoStallMode(obj, pExtendFeatures->noStallEn); + + /* CIRCULAR FIFO */ + SpiReg_SetCircularFIFO(obj, pExtendFeatures->circularFifoEn); + + /* Slave AUTO-PCS */ + if(SpiReg_GetNodeMasterState(obj) == false) + { + SpiReg_SetAutoCS(obj, pExtendFeatures->slaveAutoPcsEn); + } + + /* Stop or Debug to use module */ + SpiReg_EnableDozeMode(obj, pExtendFeatures->stopEn); + SpiReg_EnableDebugMode(obj, pExtendFeatures->dbgEn); + + /* Delay between transfers */ + SpiReg_SetDelayDBT(obj, pExtendParameters->delayBetweenTransfer); + + /* Delay from pcs to sck */ + SpiReg_SetDelayPcsToSck(obj, pExtendParameters->delayFromPcsToSck); + + /* Delay from sck to pcs */ + SpiReg_SetDelaySckToPcs(obj, pExtendParameters->delayFromSckToPcs); + + /* Master sck delay ticks */ + SpiReg_SetMstSckDelay(obj, pExtendParameters->masterSampleSckDelay); + + /* PIN Cfg */ + switch(pExtendParameters->pinCfg) + { + case SPIDRV_PIN_CFG_SIN_IN_SOUT_OUT: + SpiReg_SetOutCfg(obj, pExtendParameters->outCfg); + SpiReg_SetPinCfg(obj, 0); + break; + + case SPIDRV_PIN_CFG_HALF_DUPLEX_SIN: + SpiReg_SetPinCfg(obj, 1); + /* If performing half-duplex transfers, this bit must be set */ + SpiReg_SetOutCfg(obj, 1); + break; + + case SPIDRV_PIN_CFG_HALF_DUPLEX_SOUT: + SpiReg_SetPinCfg(obj, 2); + /* If performing half-duplex transfers, this bit must be set */ + SpiReg_SetOutCfg(obj, 1); + break; + + case SPIDRV_PIN_CFG_SIN_OUT_SOUT_IN: + SpiReg_SetOutCfg(obj, pExtendParameters->outCfg); + SpiReg_SetPinCfg(obj, 3); + break; + + default: + SpiReg_SetOutCfg(obj, pExtendParameters->outCfg); + SpiReg_SetPinCfg(obj, 0); + break; + } +} + +/*! \brief Get default configures the module for configuration structure + * + * This function gets default configures the module for user configuration structure + * + * \param[out] pInitCfg :pointer to configuration structure + * \return: void + */ +void SpiDrv_GetDefaultConfig(SpiDrv_InitCfgType *pInitCfg) +{ + /* If no user configuration, used the default configuration */ + pInitCfg->basicParameters.busClockFreq = 80000000ul; + pInitCfg->basicParameters.baudRate = 1000000ul; + pInitCfg->basicParameters.isMasterNode = true; + pInitCfg->basicParameters.clockPhase = SPIDRV_CLK_PHASE_DATA_SAMPLE_ON_LEADING_EDGE; + pInitCfg->basicParameters.clockPolarity = SPIDRV_CLK_POLARITY_IDLE_IN_LOW; + pInitCfg->basicParameters.pcsSelection = SPIDRV_PCS_SEL_PCS0; + pInitCfg->basicParameters.pcsPolarity = SPIDRV_PCS_POLARITY_ACTIVE_LOW; + pInitCfg->basicParameters.dataShiftFirstBit = SPIDRV_SHIFT_FIRST_BIT_LSB; + pInitCfg->basicParameters.frameBitSize = 8; + + pInitCfg->extendFeatures.dmaTxEn = false; + pInitCfg->extendFeatures.dmaRxEn = false; + pInitCfg->extendFeatures.noStallEn = false; + pInitCfg->extendFeatures.circularFifoEn = false; + pInitCfg->extendFeatures.byteSwapEn = false; + pInitCfg->extendFeatures.slaveAutoPcsEn = false; + pInitCfg->extendFeatures.dbgEn = false; + pInitCfg->extendFeatures.rxMaskEn = false; + pInitCfg->extendFeatures.txMaskEn = false; + pInitCfg->extendFeatures.stopEn = false; + + pInitCfg->extendParameters.duplexType = SPIDRV_DUPLEX_FULL_DUPLEX; + pInitCfg->extendParameters.delayBetweenTransfer = 10; /* N* fModule (Busclock / Prescaler) */ + pInitCfg->extendParameters.delayFromPcsToSck = 10; /* N* fModule (Busclock / Prescaler) */ + pInitCfg->extendParameters.delayFromSckToPcs = 10; /* N* fModule (Busclock / Prescaler) */ + pInitCfg->extendParameters.masterSampleSckDelay = 0; + pInitCfg->extendParameters.pinCfg = SPIDRV_PIN_CFG_SIN_IN_SOUT_OUT; + pInitCfg->extendParameters.outCfg = SPIDRV_OUTCFG_IN_OLD_VALUE; +} + +/*! \brief Set the spi module parameters include basic&extend features + * + * this function initializes the run-time state structure to provide for module configuration + * + * \param[in] obj : pointer to the instance + * \param[in] pInitCfg: the pointer to the user configuration + * \return: void + */ +void SpiDrv_SetConfig(SpiDrvType *obj, const SpiDrv_InitCfgType *pInitCfg) +{ + /* Disable the Module to make sure that some register be configured successfully */ + SpiReg_EnableModule(obj->reg, false); + + /* clear Tx&Rx FIFO */ + SpiReg_ResetTxFIFO(obj->reg); + SpiReg_ResetRxFIFO(obj->reg); + + /* set some duration after reset the module */ + __asm volatile("nop"); + __asm volatile("nop"); + __asm volatile("nop"); + + /* Set the basic parameters */ + SpiDrv_InitBasicParameters(obj->reg, &pInitCfg->basicParameters); + + /* Set the extend features if used */ + SpiDrv_InitExtendParameters(obj->reg, &pInitCfg->extendParameters, &pInitCfg->extendFeatures); + + /* Enable the module */ + SpiReg_EnableModule(obj->reg, true); + + /* Configure the tx parameters */ + SpiDrv_InitTxCommand(obj->reg, pInitCfg); +} + +/*! \brief Resets the SPI internal logic and registers to their default settings + * + * this function instance an object and reset module + * + * \param[in/out] this : pointer to the instance + * \param[in] pReg : the phycial module base address pointer + * \return: void + */ +void SpiDrv_Init(SpiDrvType *obj, SpiRegType *pReg) +{ + obj->reg = pReg; + + /* Reset tx&rx fifo first after reset or reinit or power-on */ + SpiReg_ResetTxFIFO(obj->reg); + SpiReg_ResetRxFIFO(obj->reg); + + /* Reset the module */ + SpiReg_ResetModule(obj->reg, true); + + /* set some duration after reset the module */ + __asm volatile("nop"); + __asm volatile("nop"); + __asm volatile("nop"); + /* Notice: the reset bit should be clear by software, 7/5/2022 Changed by CVAchip */ + obj->reg->CR = 0; +} + +/*! \brief Set the module to special condition + * + * call back in the usage of Low power or sleep requirements + * + * \param[in] obj : pointer to the instance + * \return: void + */ +void SpiDrv_DeInit(SpiDrvType *obj) +{ + /* clear Tx&Rx FIFO */ + SpiReg_ResetTxFIFO(obj->reg); + SpiReg_ResetRxFIFO(obj->reg); + __asm volatile("nop"); + __asm volatile("nop"); + __asm volatile("nop"); + + SpiReg_ResetModule(obj->reg, true); + /* set some duration after reset the module */ + __asm volatile("nop"); + __asm volatile("nop"); + __asm volatile("nop"); + /* Notice: the reset bit should be clear by software, 7/5/2022 Changed by CVAchip */ + SpiReg_ResetModule(obj->reg, false); + + /* Disable the Module */ + SpiReg_EnableModule(obj->reg, false); +} + +/*! \brief Get the data shift direction of transfer + * + * this function get the current configuration about data shift method + * + * \param[in] obj : pointer to the instance + * \return: return the data shift direction + */ +static SpiDrv_ShiftFirstBitType SpiDrv_GetDataShiftDirection(const SpiDrvType *obj) +{ + SpiDrv_ShiftFirstBitType tRtn = SPIDRV_SHIFT_FIRST_BIT_MSB; + + if(SpiReg_GetTransferDataBitLsbState(obj->reg) == true) + { + tRtn = SPIDRV_SHIFT_FIRST_BIT_LSB; + } + + return tRtn; +} + +/*! \brief Get the status of the SpiDrv_StatusType of event + * + * this function read out the special status what want to be read + * + * \param[in] obj : pointer to the instance + * \param[in] status: which status to be read out + * \return: bool + * true: The status is exist + * false: The status is not exist + */ +bool SpiDrv_GetStatus(const SpiDrvType *obj, SpiDrv_StatusType status) +{ + bool tRtn = false; + + uint32_t tRegValue = 0; + + switch(status) + { + case SPIDRV_STATUS_TX_DATA: + tRegValue = SpiReg_GetTxDataFlag(obj->reg); + break; + + case SPIDRV_STATUS_RX_DATA: + tRegValue = SpiReg_GetRxDataFlag(obj->reg); + break; + + case SPIDRV_STATUS_RX_WORD_DONE: + tRegValue = SpiReg_GetRxWordDoneFlag(obj->reg); + break; + + case SPIDRV_STATUS_FRAME_DONE: + tRegValue = SpiReg_GetFrameDoneFlag(obj->reg); + break; + + case SPIDRV_STATUS_XFR_DONE: + tRegValue = SpiReg_GetMasterTransferDoneFlag(obj->reg); + break; + + case SPIDRV_STATUS_TX_UF: + tRegValue = SpiReg_GetTxUnderFlowFlag(obj->reg); + break; + + case SPIDRV_STATUS_RX_OF: + tRegValue = SpiReg_GetRxOverFlowFlag(obj->reg); + break; + + case SPIDRV_STATUS_BUSY: + tRegValue = SpiReg_GetBusyFlag(obj->reg); + break; + + default: + break; + } + + if(tRegValue != 0ul) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief Clear the status + * + * this function clear the special status falg + * + * \param[in] obj : pointer to the instance + * \param[in] status : combination of any SpiDrv_StatusType event + * example: Status = (SPIDRV_STATUS_RX_WORD_DONE | SPIDRV_STATUS_FRAME_DONE) + * \return: void + */ +void SpiDrv_ClearStatus(SpiDrvType *obj, uint32_t status) +{ + /* RX_WORD_DONE */ + if((status & SPIDRV_STATUS_RX_WORD_DONE) != 0ul) + { + SpiReg_ClearRxWordDoneFlag(obj->reg); + } + + /* FRAME_DONE */ + if((status & SPIDRV_STATUS_FRAME_DONE) != 0ul) + { + SpiReg_ClearFrameDoneFlag(obj->reg); + } + + /* MST_TRANSFER_DONE */ + if((status & SPIDRV_STATUS_XFR_DONE) != 0ul) + { + SpiReg_ClearMasterTransferDoneFlag(obj->reg); + } + + /* TX_UF */ + if((status & SPIDRV_STATUS_TX_UF) != 0ul) + { + SpiReg_ClearTxUnderFlowFlag(obj->reg); + } + + /* RX_OF */ + if((status & SPIDRV_STATUS_RX_OF) != 0ul) + { + SpiReg_ClearRxOverFlowFlag(obj->reg); + } +} + +/*! \brief Master Sync tx data, sent and received data from other node + * + * _____ DATA DATA DATA DATA __________ + * PCS |_____________________| + * + * \param[in] obj : pointer to the instance + * \param[in] frameSizeBitType: the data width to describe the pTxBuffer + * \param[in] txFrameNums: the nums data to be sent + * \param[in] pTxBuffer: the transmit data buffer pointer + * \param[in] pRxBuffer: the pointer for the read-out datas + * \return: bool + * false: the current tx fifo is full, no enough space for this transmit + * true: no error + */ +bool SpiDrv_MasterSyncTransfer(SpiDrvType *obj, SpiDrv_FrameSizeBitType frameSizeBitType, uint16_t txFrameNums, const void *pTxBuffer, void *pRxBuffer) +{ + bool tRtn = true; + uint8_t tTxFreeNums = 0; + + tTxFreeNums = SPIDRV_TX_FIFO_SIZE - SpiReg_GetTxFifoCounter(obj->reg); + + if(tTxFreeNums >= txFrameNums) + { + uint32_t tTcr = 0, tTimeout = 0; + uint16_t x = 0; + + tTcr = SpiReg_GetTcr(obj->reg); + SpiDrv_SetContinuousCmd(&tTcr, false); + SpiDrv_SetContinuousTransfer(&tTcr, true); + SpiDrv_SetTxDataMask(&tTcr, false); + SpiDrv_SetRxDataMask(&tTcr, false); + SpiDrv_SetFrameSize(&tTcr, (uint16_t)((uint16_t)frameSizeBitType * 8u - 1u)); + SpiReg_SetTcr(obj->reg, tTcr); + + for(x = 0; x < txFrameNums; x++) + { + while(SpiReg_GetTxDataFlag(obj->reg) == false) + { + /* Wait tx fifo avaliable */ + tTimeout++; + if(tTimeout > 1000ul) + { + tRtn = false; + break; + } + } + + /* Transmit data */ + if(frameSizeBitType == SPIDRV_FRAME_SIZE_BIT_TYPE_BYTE) + { + obj->reg->TDR = ((uint8_t *)pTxBuffer)[x]; + } + else if(frameSizeBitType == SPIDRV_FRAME_SIZE_BIT_TYPE_HALF_WORD) + { + obj->reg->TDR = ((uint16_t *)pTxBuffer)[x]; + } + else + { + obj->reg->TDR = ((uint32_t *)pTxBuffer)[x]; + } + + tTimeout = 0; + + while((SpiReg_GetRxFifoEmptyState(obj->reg) == true)) + { + tTimeout++; + if(tTimeout > 1000ul) + { + tRtn = false; + break; + } + } + + if(frameSizeBitType == SPIDRV_FRAME_SIZE_BIT_TYPE_BYTE) + { + ((uint8_t *)pRxBuffer)[x] = (obj->reg->RDR & 0xFF); + } + else if(frameSizeBitType == SPIDRV_FRAME_SIZE_BIT_TYPE_HALF_WORD) + { + ((uint16_t *)pRxBuffer)[x] = (obj->reg->RDR & 0xFFFF); + } + else + { + ((uint32_t *)pRxBuffer)[x] = obj->reg->RDR; + } + } + + SpiDrv_SetContinuousCmd(&tTcr, false); + SpiDrv_SetContinuousTransfer(&tTcr, false); + SpiReg_SetTcr(obj->reg, tTcr); + } + else + { + /* Transfer by byte, but not enough space to fill tx datas in bytes */ + tRtn = false; + } + + return tRtn; +} + +/*! \brief Send one short frame each frame bits numbers is equal to or less than 32bits, every time hard set pcs signal again + * the DBT feature is valid + * _____ DATA (DBT) _________ DATA(DBT) __________ + * PCS |_____________| |_____________| + * + * \param[in] obj : pointer to the instance + * \param[in] txData:data to be sent + * \param[in] frameSizeBitType:the frame bit width(8bit/16bit/32bit) to describe the pTxBuffer data width type + * \return: bool + * true: no err + * false: no enough space for the current tx requirement + */ +bool SpiDrv_AsyncSingleFrameTransfer(SpiDrvType *obj, uint32_t txData, SpiDrv_FrameSizeBitType frameSizeBitType) +{ + bool tRtn = true; + uint8_t tTxFreeNums = 0; + + tTxFreeNums = SPIDRV_TX_FIFO_SIZE - SpiReg_GetTxFifoCounter(obj->reg) - 1u; + + if(tTxFreeNums > 0) + { + uint32_t tTcr = 0; + + tTcr = SpiReg_GetTcr(obj->reg); + SpiDrv_SetContinuousCmd(&tTcr, false); + SpiDrv_SetContinuousTransfer(&tTcr, false); + SpiDrv_SetFrameSize(&tTcr, (uint16_t)((uint16_t)frameSizeBitType * 8u - 1u)); + SpiReg_SetTcr(obj->reg, tTcr); + + if(frameSizeBitType == SPIDRV_FRAME_SIZE_BIT_TYPE_BYTE) + { + /* Transmit data */ + obj->reg->TDR = (txData & 0xFF); + } + else if(frameSizeBitType == SPIDRV_FRAME_SIZE_BIT_TYPE_HALF_WORD) + { + /* Transmit data */ + obj->reg->TDR = (txData & 0xFFFF); + } + else + { + /* Transmit data */ + obj->reg->TDR = txData; + } + } + else + { + /* Transfer by byte, but not enough space to fill tx datas in bytes */ + tRtn = false; + } + + return tRtn; +} + +/*! \brief Send more than 32bits frame one time, the DBT feature is invalid + * + * _____ DATA DATA DATA DATA __________ + * PCS |_____________________| + * + * \param[in] obj : pointer to the instance + * \param[in] txFrameNums: the nums data to be sent + * \param[in] pTxBuffer: th pointer of which data to be sent + * \param[in] frameSizeBitType:the frame bit width(8bit/16bit/32bit) to describe the pTxBuffer data width type + * \param[in] littleEndDian: transfer byte turn + * \return: bool + * true: no err + * false: no enough space for the current tx requirement + */ +bool SpiDrv_AsyncLongFrameTransfer(SpiDrvType *obj, uint16_t txFrameNums, const void *pTxBuffer, SpiDrv_FrameSizeBitType frameSizeBitType, bool littleEndDian) +{ + bool tRtn = true; + uint8_t tTxFreeNums = 0; + uint16_t tTxBytesNums = txFrameNums * (uint16_t)frameSizeBitType; + + tTxFreeNums = SPIDRV_TX_FIFO_SIZE - SpiReg_GetTxFifoCounter(obj->reg); + + if(tTxFreeNums >= ((tTxBytesNums + 3) / 4u)) + { + uint32_t tTcr = 0; + + tTcr = SpiReg_GetTcr(obj->reg); + SpiDrv_SetContinuousCmd(&tTcr, false); + SpiDrv_SetContinuousTransfer(&tTcr, false); + SpiDrv_SetFrameSize(&tTcr, (uint16_t)(tTxBytesNums * 8u - 1u)); + SpiReg_SetTcr(obj->reg, tTcr); + + tRtn = SpiDrv_AsyncBitDataWriteIntoHwTxBuffer(obj, (uint16_t)(tTxBytesNums * 8u), pTxBuffer, littleEndDian); + } + else + { + /* Transfer by byte, but not enough space to fill tx datas in bytes */ + tRtn = false; + } + + return tRtn; +} + +/*! \brief continue Send constinues frame,each frame bits numbers is equal to or less than 32bits + * the DBT feature is valid + * _____ DATA(xbits) (DBT) DATA(xBits)__________ + * PCS |_______________________________| + * + * \param[in] obj : pointer to the instance + * \param[in] txFrameNums: the nums data to be sent + * \param[in] pTxBuffer: th pointer of which data to be sent + * \param[in] frameSizeBitType:the frame bit width(8bit/16bit/32bit) to describe the pTxBuffer data width type + * \return: bool + * true: no err + * false: no enough space for the current tx requirement + */ +bool SpiDrv_AsyncContinueFrameTransfer(SpiDrvType *obj, uint16_t txFrameNums, const void *pTxBuffer, SpiDrv_FrameSizeBitType frameSizeBitType) +{ + bool tRtn = true; + uint8_t tTxFreeNums = 0; + + tTxFreeNums = SPIDRV_TX_FIFO_SIZE - SpiReg_GetTxFifoCounter(obj->reg); + + if(tTxFreeNums >= txFrameNums) + { + uint32_t tTcr = 0; + uint16_t i = 0; + + tTcr = SpiReg_GetTcr(obj->reg); + SpiDrv_SetContinuousCmd(&tTcr, false); + SpiDrv_SetContinuousTransfer(&tTcr, true); + SpiDrv_SetFrameSize(&tTcr, (uint16_t)((uint16_t)frameSizeBitType * 8u - 1u)); + SpiReg_SetTcr(obj->reg, tTcr); + + if(frameSizeBitType == SPIDRV_FRAME_SIZE_BIT_TYPE_BYTE) + { + for(i = 0; i < txFrameNums; i++) + { + /* Transmit data */ + obj->reg->TDR = ((uint8_t *)pTxBuffer)[i]; + } + } + else if(frameSizeBitType == SPIDRV_FRAME_SIZE_BIT_TYPE_HALF_WORD) + { + for(i = 0; i < txFrameNums; i++) + { + /* Transmit data */ + obj->reg->TDR = ((uint16_t *)pTxBuffer)[i]; + } + } + else + { + for(i = 0; i < txFrameNums; i++) + { + /* Transmit data */ + obj->reg->TDR = ((uint32_t *)pTxBuffer)[i]; + } + } + + SpiDrv_SetContinuousTransfer(&tTcr, false); + SpiReg_SetTcr(obj->reg, tTcr); + } + else + { + /* Transfer by byte, but not enough space to fill tx datas in bytes */ + tRtn = false; + } + + return tRtn; +} + +/*! \brief Set the link route function in the slave node with byte transfer + * + * this function is used for slave node to link transfer from master to other node with bytes + * + * \param[in] obj : pointer to the instance + * \param[in] txBytesCnt: the data bytes to be sent + * \param[in] pTxByteBuffer: pointer to the tx data byte buffer + * the tx data will fill or not by special requirement + * \return: void + */ +void SpiDrv_SlaveAsyncLinkTransferBytes(SpiDrvType *obj, uint16_t txBytesCnt, const uint8_t *pTxByteBuffer) +{ + uint8_t tTxFreeNums = 0; + + tTxFreeNums = SPIDRV_TX_FIFO_SIZE - SpiReg_GetTxFifoCounter(obj->reg); + + if(tTxFreeNums > ((txBytesCnt + 3u) / 4u)) + { + uint32_t tTcr = 0; + uint32_t i = 0; + uint8_t tMultFrameNums = 0, tRestNums = 0; + + if(txBytesCnt > 0) + { + uint8_t tBufferIdx = 0; + + tTcr = SpiReg_GetTcr(obj->reg); + SpiDrv_SetContinuousCmd(&tTcr, false); + SpiDrv_SetContinuousTransfer(&tTcr, true); + SpiDrv_SetTxDataMask(&tTcr, false); + SpiDrv_SetRxDataMask(&tTcr, false); + SpiDrv_SetFrameSize(&tTcr, 7u); + SpiReg_SetTcr(obj->reg, tTcr); + + tMultFrameNums = (uint8_t)(txBytesCnt / 4u); + tRestNums = (txBytesCnt & 0x03); + + if(tMultFrameNums > 0) + { + for(i = 0; i < tMultFrameNums; i++) + { + /* Transmit data */ + obj->reg->TDR = *((uint32_t *)&pTxByteBuffer[tBufferIdx]); + tBufferIdx += 4; + } + } + + if(tRestNums > 0) + { + uint8_t x = 0; + SpiDrv_DataAlignedType tTxDataAligned; + + tTxDataAligned.wordData = 0; + + /* The rest bytes filled action */ + if(SpiDrv_GetDataShiftDirection(obj) == SPIDRV_SHIFT_FIRST_BIT_LSB) + { + for(x = 0; x < tRestNums; x++) + { + tTxDataAligned.byteData[tRestNums - 1 - x] = pTxByteBuffer[tBufferIdx]; + tBufferIdx++; + } + } + else + { + for(x = 0; x < tRestNums; x++) + { + tTxDataAligned.byteData[x] = pTxByteBuffer[tBufferIdx]; + tBufferIdx++; + } + } + + /* Transmit data */ + obj->reg->TDR = tTxDataAligned.wordData; + } + } + } +} + +/*! \brief Set the link route function in the slave node with halfword transfer + * + * this function is used for slave node to link transfer from master to other node with halfwords + * + * \param[in] obj : pointer to the instance + * \param[in] txHalfWordsCnt: the data halfwords to be sent + * \param[in] pTxHalfWordBuffer: pointer to the tx data halfword buffer + * the tx data will fill or not by special requirement + * \return: void + */ +void SpiDrv_SlaveAsyncLinkTransferHalfWords(SpiDrvType *obj, uint16_t txHalfWordsCnt, const uint16_t *pTxHalfWordBuffer) +{ + uint8_t tTxFreeNums = 0; + + tTxFreeNums = SPIDRV_TX_FIFO_SIZE - SpiReg_GetTxFifoCounter(obj->reg); + + if(tTxFreeNums > ((txHalfWordsCnt + 1u) / 2u)) + { + uint32_t tTcr = 0, i = 0; + uint16_t tMultFrameNums = 0, tRestNums = 0; + + if(txHalfWordsCnt > 0) + { + uint8_t tBufferIdx = 0; + + tTcr = SpiReg_GetTcr(obj->reg); + SpiDrv_SetContinuousCmd(&tTcr, false); + SpiDrv_SetContinuousTransfer(&tTcr, true); + SpiDrv_SetTxDataMask(&tTcr, false); + SpiDrv_SetRxDataMask(&tTcr, false); + SpiDrv_SetFrameSize(&tTcr, 15u); + SpiReg_SetTcr(obj->reg, tTcr); + + tMultFrameNums = txHalfWordsCnt; + tRestNums = (txHalfWordsCnt & 0x01); + + for(i = 0; i < tMultFrameNums; i++) + { + /* Transmit data */ + obj->reg->TDR = *((uint32_t *)&pTxHalfWordBuffer[tBufferIdx]); + tBufferIdx += 2; + } + + if(tRestNums > 0) + { + uint8_t x = 0; + SpiDrv_DataAlignedType tTxDataAligned; + + tTxDataAligned.wordData = 0; + + /* The rest bytes filled action */ + if(SpiDrv_GetDataShiftDirection(obj) == SPIDRV_SHIFT_FIRST_BIT_LSB) + { + for(x = 0; x < tRestNums; x++) + { + tTxDataAligned.halfWordData[tRestNums - 1 - x] = pTxHalfWordBuffer[tBufferIdx]; + tBufferIdx++; + } + } + else + { + for(x = 0; x < tRestNums; x++) + { + tTxDataAligned.halfWordData[x] = pTxHalfWordBuffer[tBufferIdx]; + tBufferIdx++; + } + } + + /* Transmit data */ + obj->reg->TDR = tTxDataAligned.wordData; + } + } + } +} + +/*! \brief Set the link route function in the slave node with word transfer + * + * this function is used for slave node to link transfer from master to other node with words + * + * \param[in] obj : base address for the SPI instance + * \param[in] txWodsCnt: the data words to be sent + * \param[in] pTxWordBuffer: pointer to the tx data word buffer + * the tx data will fill or not by special requirement + * \return: void + */ +void SpiDrv_SlaveAsyncLinkTransferWords(SpiDrvType *obj, uint16_t txWodsCnt, const uint32_t *pTxWordBuffer) +{ + uint8_t tTxFreeNums = 0; + + tTxFreeNums = SPIDRV_TX_FIFO_SIZE - SpiReg_GetTxFifoCounter(obj->reg); + + if(tTxFreeNums > txWodsCnt) + { + uint32_t tTcr = 0, i = 0; + + if(txWodsCnt > 0) + { + tTcr = SpiReg_GetTcr(obj->reg); + SpiDrv_SetContinuousCmd(&tTcr, false); + SpiDrv_SetContinuousTransfer(&tTcr, true); + SpiDrv_SetTxDataMask(&tTcr, false); + SpiDrv_SetRxDataMask(&tTcr, false); + SpiDrv_SetFrameSize(&tTcr, 31u); + SpiReg_SetTcr(obj->reg, tTcr); + + for(i = 0; i < txWodsCnt; i++) + { + /* Transmit data */ + obj->reg->TDR = pTxWordBuffer[i]; + } + } + } +} + +/*! \brief Update Transmit Command Register configuration structure + * + * Any writes to the TCR will cause the entire TCR contents to be pushed to the TX FIFO. + * Therefore any updates to the TCR should include updates to all of the register + * bit fields to form a 32-bit write to the TCR. + * + * \param[in] obj : pointer to the instance + * \param[in] pTcrInfo : Transmit Command Register configuration structure + * \return void + */ +void SpiDrv_SetTcrCmdConfig(SpiDrvType *obj, const SpiDrv_TcrInfoType *pTcrInfo) +{ + uint32_t tTcr = 0; + + tTcr = SpiReg_GetTcr(obj->reg); + + /* TX RX MASK */ + SpiDrv_SetTxDataMask(&tTcr, pTcrInfo->txMask); + SpiDrv_SetRxDataMask(&tTcr, pTcrInfo->rxMask); + + /* Byte-Swap, only in the frame size /32 != 0u case, can used the byte swap */ + SpiDrv_SetByteSwap(&tTcr, pTcrInfo->byteSwap); + + /* First Bit shift */ + SpiDrv_SetLowBitFirstTransfer(&tTcr, pTcrInfo->dataShiftFirstBit); + + /* CPHA */ + SpiDrv_SetClockPhase(&tTcr, pTcrInfo->clockPhase); + + /* CPOL */ + SpiDrv_SetClockPolarity(&tTcr, pTcrInfo->clockPolarity); + + /* Select PCS */ + SpiDrv_SetPcsSelection(&tTcr, pTcrInfo->pcsSelection); + + /* Continuous transfer */ + SpiDrv_SetContinuousTransfer(&tTcr, pTcrInfo->continuousTransfer); + + /* Continuous command */ + SpiDrv_SetContinuousCmd(&tTcr, pTcrInfo->continuousCmd); + + /* Frame Size */ + SpiDrv_SetFrameSize(&tTcr, pTcrInfo->frameBitSize); + + /* Transfer width */ + SpiDrv_SetTransferWidth(&tTcr, pTcrInfo->transferWidth); + + /* Update the tcr register */ + SpiReg_SetTcr(obj->reg, tTcr); +} + +/*! \brief Get Transmit Command Register configuration structure + * + * This function get the current tcr register value + * + * \param[in] obj : pointer to the instance + * \return: Transmit Command Register configuration structure + */ +SpiDrv_TcrInfoType SpiDrv_GetTcrCmdConfig(const SpiDrvType *obj) +{ + SpiDrv_TcrInfoType tTcrInfo; + uint32_t tTcr = 0; + + tTcr = SpiReg_GetTcr(obj->reg); + + if((tTcr & SPI_TCR_CPHA_MASK) != 0u) + { + tTcrInfo.clockPhase = SPIDRV_CLK_PHASE_DATA_SAMPLE_ON_TRAILING_EDGE; + } + else + { + tTcrInfo.clockPhase = SPIDRV_CLK_PHASE_DATA_SAMPLE_ON_LEADING_EDGE; + } + + if((tTcr & SPI_TCR_CPOL_MASK) != 0u) + { + tTcrInfo.clockPolarity = SPIDRV_CLK_POLARITY_IDLE_IN_HIGH; + } + else + { + tTcrInfo.clockPolarity = SPIDRV_CLK_POLARITY_IDLE_IN_LOW; + } + + if((((tTcr & SPI_TCR_PCS_SEL_MASK) >> SPI_TCR_PCS_SEL_SHIFT) & 0xFF) == 0u) + { + tTcrInfo.pcsSelection = SPIDRV_PCS_SEL_PCS0; + } + else if((((tTcr & SPI_TCR_PCS_SEL_MASK) >> SPI_TCR_PCS_SEL_SHIFT) & 0xFF) == 1u) + { + tTcrInfo.pcsSelection = SPIDRV_PCS_SEL_PCS1; + } + else if((((tTcr & SPI_TCR_PCS_SEL_MASK) >> SPI_TCR_PCS_SEL_SHIFT) & 0xFF) == 2u) + { + tTcrInfo.pcsSelection = SPIDRV_PCS_SEL_PCS2; + } + else if((((tTcr & SPI_TCR_PCS_SEL_MASK) >> SPI_TCR_PCS_SEL_SHIFT) & 0xFF) == 3u) + { + tTcrInfo.pcsSelection = SPIDRV_PCS_SEL_PCS3; + } + + if((tTcr & SPI_TCR_LSB_FIRST_MASK) != 0u) + { + tTcrInfo.dataShiftFirstBit = SPIDRV_SHIFT_FIRST_BIT_LSB; + } + else + { + tTcrInfo.dataShiftFirstBit = SPIDRV_SHIFT_FIRST_BIT_MSB; + } + + tTcrInfo.frameBitSize = (((tTcr & SPI_TCR_FRAME_SIZE_MASK) >> SPI_TCR_FRAME_SIZE_SHIFT) & 0xFFF); + tTcrInfo.transferWidth = (((tTcr & SPI_TCR_TRANSFER_WIDTH_MASK) >> SPI_TCR_TRANSFER_WIDTH_SHIFT) & 0x03u); + tTcrInfo.prescaler = (((tTcr & SPI_TCR_PRESCALER_MASK) >> SPI_TCR_PRESCALER_SHIFT) & 0xFF); + + if((tTcr & SPI_TCR_RX_MASK_MASK) != 0u) + { + tTcrInfo.rxMask = true; + } + else + { + tTcrInfo.rxMask = false; + } + + if((tTcr & SPI_TCR_TX_MASK_MASK) != 0u) + { + tTcrInfo.txMask = true; + } + else + { + tTcrInfo.txMask = false; + } + + if((tTcr & SPI_TCR_BYTE_SWAP_MASK) != 0u) + { + tTcrInfo.byteSwap = true; + } + else + { + tTcrInfo.byteSwap = false; + } + + tTcrInfo.continuousTransfer = (((tTcr & SPI_TCR_CONTINUE_TRANSFER_MASK) >> SPI_TCR_CONTINUE_TRANSFER_SHIFT) & 0x01); + tTcrInfo.continuousCmd = (((tTcr & SPI_TCR_CONTINUE_CMD_MASK) >> SPI_TCR_CONTINUE_CMD_SHIFT) & 0x01); + + return tTcrInfo; +} + +/*! \brief Set Slave rx fifo water mark + * + * the max water mark is must less than the supported depth + * + * \param[in] obj : pointer to the instance + * \param[in] txFrameNums: the tx frame to be sent + * \param[in] frameSizeBitType: frame bit width(8bit/16bit/32bit) + * \return: bool + * false: the current water is more than the actual max supported depth + * true: no error + */ +bool SpiDrv_SlaveSetRxWaterMark(SpiDrvType *obj, uint16_t txFrameNums, SpiDrv_FrameSizeBitType frameSizeBitType) +{ + bool tRtn = false; + uint8_t tMultFrameNums = 0, tRestNums = 0; + uint16_t tTxBytesNum = 0; + + if(frameSizeBitType == SPIDRV_FRAME_SIZE_BIT_TYPE_BYTE) + { + tTxBytesNum = txFrameNums; + } + else if(frameSizeBitType == SPIDRV_FRAME_SIZE_BIT_TYPE_HALF_WORD) + { + tTxBytesNum = txFrameNums * 2; + } + else + { + tTxBytesNum = txFrameNums * 4; + } + + tMultFrameNums = (uint8_t)(tTxBytesNum / 4u); + tRestNums = (tTxBytesNum & 0x03); + + if(tMultFrameNums < (SpiReg_GetRxFifoDepth(obj->reg) - SpiReg_GetRxFifoCounter(obj->reg))) + { + if(tRestNums > 0) + { + SpiReg_SetRxFifoWaterMark(obj->reg, tMultFrameNums); + } + else + { + if(tMultFrameNums > 0) + { + SpiReg_SetRxFifoWaterMark(obj->reg, (uint8_t)(tMultFrameNums - 1u)); + } + else + { + SpiReg_SetRxFifoWaterMark(obj->reg, 0u); + } + } + + tRtn = true; + } + + return tRtn; +} + +/*! \brief Async bit data write to hardware tx data buffer + * + * this function just only fill datas to tx fifo, but not read out datas from rx fifo + * + * \param[in] obj : pointer to the instance + * \param[in] txBitNums: the tx data bits numbers to be write + * \param[in] pTxBuffer: write data buffer, notice: aligned with 32bits + * \param[in] littleEndDian: write bit flow turn + * \return: bool + * false: error + * true: no error + */ +bool SpiDrv_AsyncBitDataWriteIntoHwTxBuffer(SpiDrvType *obj, uint16_t txBitNums, const void *pTxBuffer, bool littleEndDian) +{ + bool tRtn = true; + uint16_t tRestBitNums = 0, i = 0; + uint8_t tBufferIdx = 0; + uint32_t timeOutCnt = 0; + SpiDrv_DataAlignedType tDataAligned; + + tRestBitNums = txBitNums; + do + { + if(SpiReg_GetTxFifoCounter(obj->reg) <= (SPIDRV_TX_FIFO_SIZE - 1u)) + { + tDataAligned.wordData = 0; + + if(tRestBitNums >= (SPIDRV_FRAME_SIZE_WORD + 1u)) + { + if(littleEndDian == false) + { + for(i = 0u; i < 4; i++) + { + tDataAligned.byteData[i] = ((uint8_t *)pTxBuffer)[tBufferIdx + 3 - i]; + } + } + else + { + for(i = 0; i < 4u; i++) + { + tDataAligned.byteData[i] = ((uint8_t *)pTxBuffer)[tBufferIdx + i]; + } + } + + obj->reg->TDR = tDataAligned.wordData; + tRestBitNums -= 32u; + tBufferIdx += 4u; + } + else if(tRestBitNums >= (SPIDRV_FRAME_SIZE_HALF_WORD + 1u)) + { + if(tRestBitNums > 24u) + { + if(littleEndDian == false) + { + for(i = 0u; i < 4; i++) + { + tDataAligned.byteData[i] = ((uint8_t *)pTxBuffer)[tBufferIdx + 3 - i]; + } + } + else + { + for(i = 0; i < 4u; i++) + { + tDataAligned.byteData[i] = ((uint8_t *)pTxBuffer)[tBufferIdx + i]; + } + } + + tBufferIdx += 4u; + } + else if(tRestBitNums > 16u) + { + if(littleEndDian == false) + { + for(i = 0u; i < 3; i++) + { + tDataAligned.byteData[i] = ((uint8_t *)pTxBuffer)[tBufferIdx + 2 - i]; + } + } + else + { + for(i = 0; i < 3u; i++) + { + tDataAligned.byteData[i] = ((uint8_t *)pTxBuffer)[tBufferIdx + i]; + } + } + + tBufferIdx += 3u; + } + else + { + if(littleEndDian == false) + { + for(i = 0u; i < 2; i++) + { + tDataAligned.byteData[i] = ((uint8_t *)pTxBuffer)[tBufferIdx + 1 - i]; + } + } + else + { + for(i = 0; i < 2u; i++) + { + tDataAligned.byteData[i] = ((uint8_t *)pTxBuffer)[tBufferIdx + i]; + } + } + + tBufferIdx += 2u; + } + + tRestBitNums = 0u; + obj->reg->TDR = tDataAligned.wordData; + } + else if(tRestBitNums >= (SPIDRV_FRAME_SIZE_BYTE + 1u)) + { + if(tRestBitNums > 8u) + { + if(littleEndDian == false) + { + for(i = 0u; i < 2u; i++) + { + tDataAligned.byteData[i] = ((uint8_t *)pTxBuffer)[tBufferIdx + 1 - i]; + } + } + else + { + for(i = 0; i < 2u; i++) + { + tDataAligned.byteData[i] = ((uint8_t *)pTxBuffer)[tBufferIdx + i]; + } + } + + tBufferIdx += 2u; + } + else + { + tDataAligned.byteData[0] = (((uint8_t *)pTxBuffer)[tBufferIdx]); + } + + obj->reg->TDR = tDataAligned.wordData; + tRestBitNums = 0u; + tBufferIdx += 1u; + } + else + { + obj->reg->TDR = (((uint8_t *)pTxBuffer)[tBufferIdx]); + tRestBitNums = 0; + tBufferIdx++; + } + + timeOutCnt = 0; + } + else + { + timeOutCnt++; + } + + } while((tRestBitNums > 0u) && (timeOutCnt < SPIDRV_TX_TIMEOUT_CNT)); + + if(timeOutCnt >= SPIDRV_TX_TIMEOUT_CNT) + { + tRtn = false; + } + + return tRtn; +} + +/*! \brief Async tx data with any length of bits + * + * this function just only fill datas to tx fifo, but not read out datas from rx fifo, the bits num should be multile by 2! + * + * \param[in] obj : pointer to the instance + * \param[in] txBitNums: the nums bits of data to be sent + * \param[in] pBuffer: th pointer of which data to be sent;if in half duplex mode, and the txmask is true, no care about this parameter, + * notice: aligned with 32bits + * \param[in] txMask: tx mask bit + * \param[in] rxMask: rx mask bit + * \param[in] littleEndDian: transfer data flow + * \return: bool + * true: no error + * false: error + */ +bool SpiDrv_AsyncBitsTransfer(SpiDrvType *obj, uint16_t txBitNums, const void *pBuffer, bool txMask, bool rxMask, bool littleEndDian) +{ + bool tRtn = true; + SpiDrv_TcrInfoType tcrInfo; + + tcrInfo = SpiDrv_GetTcrCmdConfig(obj); + tcrInfo.frameBitSize = txBitNums - 1u; + tcrInfo.txMask = txMask; + tcrInfo.rxMask = rxMask; + + SpiDrv_SetTcrCmdConfig(obj, &tcrInfo); + + if(tcrInfo.txMask == false) + { + tRtn = SpiDrv_AsyncBitDataWriteIntoHwTxBuffer(obj, txBitNums, pBuffer, littleEndDian); + } + + return tRtn; +} + +/*! \brief Async bits Received + * + * this function read the datas from rx fifo, and return the bytes nums have been readout. + * Notice: Returns the number of words currently stored in the receive FIFO, may be just one byte in rx fifo, but still return four bytes + * so the total read out bytes number must be more than the actual useful numbers + * + * \param[in] obj : pointer to the instance + * \param[in] pBuffer: th pointer of which data to be stored, Notice: the address must be aligned with word!!!! + * \param[in] littleEndDian: transfer data flow + * \return: the bytes in the rx fifo + */ +uint8_t SpiDrv_AsyncReceive(SpiDrvType *obj, void *pBuffer, bool littleEndDian) +{ + uint8_t retBytesNum = 0; + + if(SpiReg_GetRxFifoEmptyState(obj->reg) == false) + { + uint8_t tRxFifoCnt = 0, tWriteByteIdx = 0; + uint16_t i = 0, y = 0; + SpiDrv_DataAlignedType tDataAligned; + uint32_t frameBitSize = 0; + + /* Read out the number of words currently stored in the receive FIFO. */ + tRxFifoCnt = SpiReg_GetRxFifoCounter(obj->reg); + frameBitSize = SpiReg_GetFrameSize(obj->reg); + + /* the rx fifo counter is aligned with word , so may by just read out less than 4bytes, also return 4bytes! */ + if(frameBitSize > SPIDRV_FRAME_SIZE_HALF_WORD) + { + retBytesNum = tRxFifoCnt << 2; + + for(i = 0; i < tRxFifoCnt; i++) + { + tDataAligned.wordData = obj->reg->RDR; + + if(littleEndDian == true) + { + for(y = 0; y < 4u; y++) + { + ((uint8_t *)pBuffer)[tWriteByteIdx++] = tDataAligned.byteData[y]; + } + } + else + { + for(y = 0; y < 4u; y++) + { + ((uint8_t *)pBuffer)[tWriteByteIdx++] = tDataAligned.byteData[3 - y]; + } + } + } + } + else if(frameBitSize > SPIDRV_FRAME_SIZE_BYTE) + { + retBytesNum = tRxFifoCnt << 1; + + for(i = 0; i < tRxFifoCnt; i++) + { + tDataAligned.wordData = obj->reg->RDR; + + if(littleEndDian == true) + { + for(y = 0; y < 2u; y++) + { + ((uint8_t *)pBuffer)[tWriteByteIdx++] = tDataAligned.byteData[y]; + } + } + else + { + for(y = 0; y < 2u; y++) + { + ((uint8_t *)pBuffer)[tWriteByteIdx++] = tDataAligned.byteData[1 - y]; + } + } + } + } + else + { + retBytesNum = tRxFifoCnt; + + for(i = 0; i < tRxFifoCnt; i++) + { + ((uint8_t *)pBuffer)[tWriteByteIdx++] = obj->reg->RDR; + } + } + } + + return retBytesNum; +} + +/*! \brief Set SPI interrupt config + * + * \param[in] obj : pointer to the instance + * \param[in] isrSrc: interrupt source + * \param[in] enabled: config status + * \return: void + */ +void SpiDrv_SetIsrConfig(SpiDrvType *obj, SpiDrv_IsrSrcType isrSrc, bool enabled) +{ + switch(isrSrc) + { + case SPIDRV_ISR_SRC_TX_DATA: + SpiReg_SetTxDataIsr(obj->reg, enabled); + break; + + case SPIDRV_ISR_SRC_RX_DATA: + SpiReg_SetRxDataIsr(obj->reg, enabled); + break; + + case SPIDRV_ISR_SRC_RX_WORD_DONE: + SpiReg_SetRxWordDoneIsr(obj->reg, enabled); + break; + + case SPIDRV_ISR_SRC_FRAME_DONE: + SpiReg_SetFrameDoneIsr(obj->reg, enabled); + break; + + case SPIDRV_ISR_SRC_MASTER_XFR_DONE: + SpiReg_SetTxTransferDoneIsr(obj->reg, enabled); + break; + + case SPIDRV_ISR_SRC_TX_UF: + SpiReg_SetTxUnderflowIsr(obj->reg, enabled); + break; + + case SPIDRV_ISR_SRC_RX_OF: + SpiReg_SetRxOverflowIsr(obj->reg, enabled); + break; + + default: + break; + } +} + +/*! \brief Get SPI interrupt config + * + * \param[in] obj : pointer to the instance + * \param[in] isrSrc: interrupt source + * \return: config status + */ +bool SpiDrv_GetIsrConfig(SpiDrvType *obj, SpiDrv_IsrSrcType isrSrc) +{ + bool isrCfg = false; + + switch(isrSrc) + { + case SPIDRV_ISR_SRC_TX_DATA: + isrCfg = SpiReg_GetIntReqEnableState(obj->reg, SPI_IER_TX_DATA_IE_MASK); + break; + + case SPIDRV_ISR_SRC_RX_DATA: + isrCfg = SpiReg_GetIntReqEnableState(obj->reg, SPI_IER_RX_DATA_IE_MASK); + break; + + case SPIDRV_ISR_SRC_RX_WORD_DONE: + isrCfg = SpiReg_GetIntReqEnableState(obj->reg, SPI_IER_RX_WORD_DONE_IE_MASK); + break; + + case SPIDRV_ISR_SRC_FRAME_DONE: + isrCfg = SpiReg_GetIntReqEnableState(obj->reg, SPI_IER_FRAME_DONE_IE_MASK); + break; + + case SPIDRV_ISR_SRC_MASTER_XFR_DONE: + isrCfg = SpiReg_GetIntReqEnableState(obj->reg, SPI_IER_MST_TRANSFER_DONE_IE_MASK); + break; + + case SPIDRV_ISR_SRC_TX_UF: + isrCfg = SpiReg_GetIntReqEnableState(obj->reg, SPI_IER_TX_UF_IE_MASK); + break; + + case SPIDRV_ISR_SRC_RX_OF: + isrCfg = SpiReg_GetIntReqEnableState(obj->reg, SPI_IER_RX_OF_IE_MASK); + break; + + default: + break; + } + + return isrCfg; +} + +/*! \brief Set rx fifo water mask + * + * \param[in] obj : pointer to the instance + * \param[in] waterMask: fifo water mask + * \return: void + */ +void SpiDrv_SetRxFifoWaterMask(SpiDrvType *obj, uint8_t waterMask) +{ + SpiReg_SetRxFifoWaterMark(obj->reg, waterMask); +} + +/*! \brief Set tx fifo water mask + * + * \param[in] obj : pointer to the instance + * \param[in] waterMask: fifo water mask + * \return: void + */ +void SpiDrv_SetTxFifoWaterMask(SpiDrvType *obj, uint8_t waterMask) +{ + SpiReg_SetTxFifoWaterMark(obj->reg, waterMask); +} + +/*! \brief Set Clock Polarity + * + * The Clock Polarity field is only updated when PCS negated. + * + * \param[in] pTcr : TCR variable instance + * \param[in] clockPolarity : + * 0b : The inactive state value of SCK is low + * 1b : The inactive state value of SCK is high + * \return: void + */ +void SpiDrv_SetClockPolarity(uint32_t *pTcr, uint8_t clockPolarity) +{ + uint32_t tmp = *pTcr; + + tmp &= ~SPI_TCR_CPOL_MASK; + tmp |= (((uint32_t)(((uint32_t)(clockPolarity)) << SPI_TCR_CPOL_SHIFT)) & SPI_TCR_CPOL_MASK); + *pTcr = tmp; +} + +/*! \brief Set Clock Phase + * + * The Clock Phase field is only updated when PCS negated. + * + * \param[in] pTcr : TCR variable instance + * \param[in] clockPhase : + * 0b : Data is captured on the leading edge of SCK and changed on the following edge of SCK + * 1b : Data is changed on the leading edge of SCK and captured on the following edge of SCK + * \return: void + */ +void SpiDrv_SetClockPhase(uint32_t *pTcr, uint8_t clockPhase) +{ + uint32_t tmp = *pTcr; + + tmp &= ~SPI_TCR_CPHA_MASK; + tmp |= (((uint32_t)(((uint32_t)(clockPhase)) << SPI_TCR_CPHA_SHIFT)) & SPI_TCR_CPHA_MASK); + *pTcr = tmp; +} + +/*! \brief Set Prescaler Value + * + * For all SPI bus transfers, the Prescaler value applied to the clock configuration register. The Prescaler Value field is only updated when PCS negated. + * + * \param[in] pTcr : TCR variable instance + * \param[in] prescaler : + * 000b : Divide by 1 + * 001b : Divide by 2 + * 010b : Divide by 4 + * 011b : Divide by 8 + * 100b : Divide by 16 + * 101b : Divide by 32 + * 110b : Divide by 64 + * 111b : Divide by 128 + * \return: void + */ +void SpiDrv_SetPrescaler(uint32_t *pTcr, uint8_t prescaler) +{ + uint32_t tmp = *pTcr; + + tmp &= ~SPI_TCR_PRESCALER_MASK; + tmp |= (((uint32_t)(((uint32_t)(prescaler)) << SPI_TCR_PRESCALER_SHIFT)) & SPI_TCR_PRESCALER_MASK); + *pTcr = tmp; +} + +/*! \brief Select Peripheral Chip + * + * Configures the peripheral chip select used for the transfer. The Peripheral Chip Select field is only updated when PCS negated. + * + * \param[in] pTcr : TCR variable instance + * \param[in] pcsSelection : + * 00b : Transfer using SPI_PCS[0] + * 01b : Transfer using SPI_PCS[1] + * 10b : Transfer using SPI_PCS[2] + * 11b : Transfer using SPI_PCS[3] + * \return: void + */ +void SpiDrv_SetPcsSelection(uint32_t *pTcr, uint8_t pcsSelection) +{ + uint32_t tmp = *pTcr; + + tmp &= ~SPI_TCR_PCS_SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(pcsSelection)) << SPI_TCR_PCS_SEL_SHIFT)) & SPI_TCR_PCS_SEL_MASK); + *pTcr = tmp; +} + +/*! \brief Set data transfer direction + * + * + * + * \param[in] pTcr : TCR variable instance + * \param[in] lsbFirst : + * 0b:Data is transferred MSB first + * 1b:Data is transferred LSB first + * \return: void + */ +void SpiDrv_SetLowBitFirstTransfer(uint32_t *pTcr, uint8_t lsbFirst) +{ + uint32_t tmp = *pTcr; + + tmp &= ~SPI_TCR_LSB_FIRST_MASK; + tmp |= (((uint32_t)(((uint32_t)(lsbFirst)) << SPI_TCR_LSB_FIRST_SHIFT)) & SPI_TCR_LSB_FIRST_MASK); + *pTcr = tmp; +} + +/*! \brief Set Byte Swap + * + * Byte swap will swap the contents of [31:24] with [7:0] and [23:16] with [15:8] for each transmit data word read from + * the FIFO and for each received data word stored to the FIFO + * + * \param[in] pTcr : TCR variable instance + * \param[in] enable : + * 0b:Byte swap is disabled + * 1b:Byte swap is enabled + * \return: void + */ +void SpiDrv_SetByteSwap(uint32_t *pTcr, bool enable) +{ + uint32_t tRegValue = *pTcr; + + if(enable == true) + { + *pTcr = ((1ul << SPI_TCR_BYTE_SWAP_SHIFT) | ((~SPI_TCR_BYTE_SWAP_MASK) & tRegValue)); + } + else + { + *pTcr = ((0ul << SPI_TCR_BYTE_SWAP_SHIFT) | ((~SPI_TCR_BYTE_SWAP_MASK) & tRegValue)); + } +} + +/*! \brief Set Continuous Transfer + * + * In master mode, continuous transfer will keep the PCS asserted at the end of the frame size, + * until a command word is received that starts a new frame. + * In slave mode, when continuous transfer is enabled, the SPI will only transmit the first FRAMESZ bits; + * after which the SPI will transmit received data (assuming a 32-bit shift register) until the next PCS negation. + * + * \param[in] pTcr : TCR variable instance + * \param[in] enable : + * 0b:Continuous transfer is disabled + * 1b:Continuous transfer is enabled + * \return: void + */ +void SpiDrv_SetContinuousTransfer(uint32_t *pTcr, bool enable) +{ + uint32_t tRegValue = *pTcr; + + if(enable == true) + { + *pTcr = ((1ul << SPI_TCR_CONTINUE_TRANSFER_SHIFT) | ((~SPI_TCR_CONTINUE_TRANSFER_MASK) & tRegValue)); + } + else + { + *pTcr = ((0ul << SPI_TCR_CONTINUE_TRANSFER_SHIFT) | ((~SPI_TCR_CONTINUE_TRANSFER_MASK) & tRegValue)); + } +} + +/*! \brief Set Continuing Command + * + * In master mode, the Continuing Command bit allows the command word to be changed within a transfer. + * 1. in continuous transfer + * - the initial command word must enable continuous transfer (CONT=1), + * - the continuing command must set this bit (CONTC=1), + * - the continuing command word must be loaded on a frame size boundary. + * 2. in non-continuous transfer + * - the continuing command must set this bit (CONTC=1), + * - the continuing command word must be loaded on a frame size boundary. + * + * \param[in] pTcr : TCR variable instance + * \param[in] cmd : + * 0b:Command word for start of new transfer + * 1b:Command word for continuing transfer + * \return: void + */ +void SpiDrv_SetContinuousCmd(uint32_t *pTcr, uint8_t cmd) +{ + uint32_t tmp = *pTcr; + + tmp &= ~SPI_TCR_CONTINUE_CMD_MASK; + tmp |= (((uint32_t)(((uint32_t)(cmd)) << SPI_TCR_CONTINUE_CMD_SHIFT)) & SPI_TCR_CONTINUE_CMD_MASK); + *pTcr = tmp; +} + +/*! \brief Set Receive Data Mask + * + * When set, receive data is masked (receive data is not stored in receive FIFO). + * + * \param[in] pTcr : TCR variable instance + * \param[in] enableMask : + * 0b:Normal transfer + * 1b:Receive data is masked + * \return: void + */ +void SpiDrv_SetRxDataMask(uint32_t *pTcr, bool enableMask) +{ + uint32_t tRegValue = *pTcr; + + if(enableMask == true) + { + *pTcr = ((1ul << SPI_TCR_RX_MASK_SHIFT) | ((~SPI_TCR_RX_MASK_MASK) & tRegValue)); + } + else + { + *pTcr = ((0ul << SPI_TCR_RX_MASK_SHIFT) | ((~SPI_TCR_RX_MASK_MASK) & tRegValue)); + } +} + +/*! \brief Set Transmit Data Mask + * + * When set, transmit data is masked (no data is loaded from transmit FIFO and output pin is tristated). + * In master mode, the Transmit Data Mask bit will initiate a new transfer + * which cannot be aborted by another command word; TXMSK bit will be cleared by hardware at the end of the transfer. + * + * \param[in] pTcr : TCR variable instance + * \param[in] enableMask : + * 0b:Normal transfer + * 1b:Mask transmit data + * \return: void + */ +void SpiDrv_SetTxDataMask(uint32_t *pTcr, bool enableMask) +{ + uint32_t tRegValue = *pTcr; + + if(enableMask == true) + { + *pTcr = ((1ul << SPI_TCR_TX_MASK_SHIFT) | ((~SPI_TCR_TX_MASK_MASK) & tRegValue)); + } + else + { + *pTcr = ((0ul << SPI_TCR_TX_MASK_SHIFT) | ((~SPI_TCR_TX_MASK_MASK) & tRegValue)); + } +} + +/*! \brief Set Transfer data Width + * + * Configures between serial (1-bit) or parallel transfers. For half-duplex parallel transfers, either Receive Data Mask (RXMSK) or Transmit Data Mask (TXMSK) must be set. + * + * \param[in] pTcr : TCR variable instance + * \param[in] transferWidth : + * 00b:1 bit transfer + * 01b:2 bit transfer + * 10b:Reserved + * 11b:Reserved + * \return: void + */ +void SpiDrv_SetTransferWidth(uint32_t *pTcr, uint8_t transferWidth) +{ + uint32_t tmp = *pTcr; + + tmp &= ~SPI_TCR_TRANSFER_WIDTH_MASK; + tmp |= (((uint32_t)(((uint32_t)(transferWidth)) << SPI_TCR_TRANSFER_WIDTH_SHIFT)) & SPI_TCR_TRANSFER_WIDTH_MASK); + *pTcr = tmp; +} + +/*! \brief Set Frame Size + * + * The minimum frame size is 8 bits, The minimum word size is 2 bits; a frame size of 33 bits (or similar) is not supported. + * If the frame size is larger than 32 bits, then the frame is divided into multiple words of 32-bits; + * each word is loaded from the transmit FIFO and stored in the receive FIFO separately. + * If the size of the frame is not divisible by 32, then the last load of the transmit FIFO and store of the receive FIFO will contain the remainder bits. + * For example, a 72-bit transfer will consist of 3 words: the 1st and 2nd words are 32 bits, and the 3rd word is 8 bits. + * + * \param[in] pTcr : TCR variable instance + * \param[in] frameSize :Configures the frame size in number of bits equal to (FRAMESZ + 1) + * \return: void + */ +void SpiDrv_SetFrameSize(uint32_t *pTcr, uint16_t frameSize) +{ + uint32_t tmp = *pTcr; + + tmp &= ~SPI_TCR_FRAME_SIZE_MASK; + tmp |= (((uint32_t)(((uint32_t)(frameSize)) << SPI_TCR_FRAME_SIZE_SHIFT)) & SPI_TCR_FRAME_SIZE_MASK); + *pTcr = tmp; +} + +/*! \brief Transmit Command config + * + * this function config the clock polarity, clock phase prescaler value and transfer mode .... + * + * \param[in] obj: pointer to the instance + * \param[in] tcr: Transmit Command + * \return: void + */ +void SpiDrv_SetTcr(SpiDrvType *obj, uint32_t tcr) +{ + SpiReg_SetTcr(obj->reg, tcr); +} + +/*! \brief Get Transmit Command config + * + * this function config get the clock polarity, clock phase prescaler value and transfer mode .... + * + * \param[in] obj: pointer to the instance + * \return: Transmit Command + */ +uint32_t SpiDrv_GetTcr(const SpiDrvType *obj) +{ + return SpiReg_GetTcr(obj->reg); +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/spi/spi_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/spi/spi_drv.h new file mode 100644 index 0000000..18a9eb4 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/spi/spi_drv.h @@ -0,0 +1,764 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _SPI_DRV_H_ +#define _SPI_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of SPI module + */ + +/****************************************************************************** + * the includes + *****************************************************************************/ + +#include +#include +#include "spi_reg.h" + +/*! \addtogroup spi_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * the defines + *****************************************************************************/ + +#define SPIDRV_ONE_FRAME_BITS_MAX_NUM (32u) +#define SPIDRV_TX_FIFO_SIZE (16u) +#define SPIDRV_RX_FIFO_IN_WORD_SIZE (16u) +#define SPIDRV_TX_TIMEOUT_CNT (1000u) + +/****************************************************************************** + * the typedefs + *****************************************************************************/ + +/*! \brief SPI Peripheral Chip Select (PCS) configuration (which PCS to configure).*/ +typedef enum +{ + SPIDRV_PCS_SEL_PCS0 = 0u, + SPIDRV_PCS_SEL_PCS1, + SPIDRV_PCS_SEL_PCS2, + SPIDRV_PCS_SEL_PCS3, + + SPIDRV_PCS_SEL_NUM +} SpiDrv_PcsSelType; + +/*! \brief SPI Signal (PCS and Host Request) Polarity configuration.*/ +typedef enum +{ + SPIDRV_PCS_POLARITY_ACTIVE_LOW = 0u, + SPIDRV_PCS_POLARITY_ACTIVE_HIGH, + + SPIDRV_PCS_POLARITY_NUM +} SpiDrv_PcsPolarityType; + +/*! \brief SPI clock phase configuration.*/ +typedef enum +{ + SPIDRV_CLK_PHASE_DATA_SAMPLE_ON_LEADING_EDGE = 0u, + SPIDRV_CLK_PHASE_DATA_SAMPLE_ON_TRAILING_EDGE, + + SPIDRV_CLK_PHASE_NUM +} SpiDrv_ClockPhaseType; + +/*! \brief SPI Clock Signal (SCK) Polarity configuration. */ +typedef enum +{ + SPIDRV_CLK_POLARITY_IDLE_IN_LOW = 0u, + SPIDRV_CLK_POLARITY_IDLE_IN_HIGH, + + SPIDRV_CLK_POLARITY_NUM +} SpiDrv_ClockPolarityType; + +/*! \brief SPI Duplex mode selection */ +typedef enum +{ + SPIDRV_DUPLEX_HALF_DUPLEX_IN_SINGLE_LINE = 0u, + SPIDRV_DUPLEX_HALF_DUPLEX_IN_DOUBLE_LINE, + SPIDRV_DUPLEX_FULL_DUPLEX, + SPIDRV_DUPLEX_NUM +} SpiDrv_DuplexType; + +/*! \brief SPI data shift direction */ +typedef enum +{ + SPIDRV_SHIFT_FIRST_BIT_MSB = 0u, + SPIDRV_SHIFT_FIRST_BIT_LSB, + + SPIDRV_SHIFT_FIRST_BIT_NUM +} SpiDrv_ShiftFirstBitType; + +/*! \brief SPI communication duplex pin configuration */ +typedef enum +{ + SPIDRV_PIN_CFG_SIN_IN_SOUT_OUT = 0u, + SPIDRV_PIN_CFG_HALF_DUPLEX_SIN, + SPIDRV_PIN_CFG_HALF_DUPLEX_SOUT, + SPIDRV_PIN_CFG_SIN_OUT_SOUT_IN, + + SPIDRV_PIN_CFG_NUM +} SpiDrv_PinCfgType; + +/*! \brief SPI pin out level after transmit */ +typedef enum +{ + SPIDRV_OUTCFG_IN_OLD_VALUE = 0u, + SPIDRV_OUTCFG_IN_TRISTATE, + + SPIDRV_OUTCFG_NUM +} SpiDrv_OutCfgType; + +/*! \brief SPI Frame size bit width */ +typedef enum +{ + SPIDRV_FRAME_SIZE_BYTE = 7u, + SPIDRV_FRAME_SIZE_HALF_WORD = 15u, + SPIDRV_FRAME_SIZE_WORD = 31u +} SpiDrv_FrameSizeType; + +/*! \brief SPI Frame size type */ +typedef enum +{ + SPIDRV_FRAME_SIZE_BIT_TYPE_BYTE = 1u, + SPIDRV_FRAME_SIZE_BIT_TYPE_HALF_WORD = 2u, + SPIDRV_FRAME_SIZE_BIT_TYPE_WORD = 4u +} SpiDrv_FrameSizeBitType; + +/*! \brief SPI Frame type selection */ +typedef enum +{ + SPIDRV_FRAME_TRANSFER_SHORT_FRAME = 0u, + SPIDRV_FRAME_TRANSFER_LONG_FRAME, + SPIDRV_FRAME_TRANSFER_MULTI_FRAME +} SpiDrv_FrameTransferType; + +/*! \brief Interrupt source */ +typedef enum +{ + SPIDRV_ISR_SRC_TX_DATA = 0x01ul, + SPIDRV_ISR_SRC_RX_DATA = 0x02ul, + SPIDRV_ISR_SRC_RX_WORD_DONE = 0x100ul, + SPIDRV_ISR_SRC_FRAME_DONE = 0x200ul, + SPIDRV_ISR_SRC_MASTER_XFR_DONE = 0x400ul, + SPIDRV_ISR_SRC_TX_UF = 0x800ul, + SPIDRV_ISR_SRC_RX_OF = 0x1000ul, + + SPIDRV_ISR_SRC_ALL = 0xFFFFFFFF +} SpiDrv_IsrSrcType; + +/*! \brief Status flag */ +typedef enum +{ + SPIDRV_STATUS_TX_DATA = 0x01ul, + SPIDRV_STATUS_RX_DATA = 0x02ul, + SPIDRV_STATUS_RX_WORD_DONE = 0x100ul, + SPIDRV_STATUS_FRAME_DONE = 0x200ul, + SPIDRV_STATUS_XFR_DONE = 0x400ul, + SPIDRV_STATUS_TX_UF = 0x800ul, + SPIDRV_STATUS_RX_OF = 0x1000ul, + SPIDRV_STATUS_BUSY = 0x1000000ul, + SPIDRV_STATUS_ALL = 0x1FFFFFFul +} SpiDrv_StatusType; + +/*! \brief golden section information diff table */ +typedef struct _SpiDrv_CalculateTblType_ +{ + uint32_t diff; + uint16_t div; + uint8_t prescalerIdx; +} SpiDrv_CalculateTblType; + +/*! \brief golden section information */ +typedef struct +{ + uint32_t freqInput; + uint32_t freqTargetOut; + uint32_t bestOutPrescaler; + uint32_t bestOutDiv; + uint32_t bestOutFreq; +} SpiDrv_GoldenSectionInfoType; + +/*! \brief data aligned union */ +typedef union _SpiDrv_DataAlignedType_ +{ + uint8_t byteData[4]; + uint16_t halfWordData[2]; + uint32_t wordData; +} SpiDrv_DataAlignedType; + +/*! \brief TCR information */ +typedef struct _SpiDrv_TcrInfoType_ +{ + SpiDrv_ClockPhaseType clockPhase; + SpiDrv_ClockPolarityType clockPolarity; + SpiDrv_PcsSelType pcsSelection; + SpiDrv_ShiftFirstBitType dataShiftFirstBit; + uint16_t frameBitSize; + uint8_t transferWidth; + uint8_t prescaler; + bool txMask; + bool rxMask; + bool byteSwap; + bool continuousTransfer; + bool continuousCmd; +} SpiDrv_TcrInfoType; + +/*! \brief SPI basic parameter information */ +typedef struct _SpiDrv_BasicParametersType_ +{ + uint32_t busClockFreq; + uint32_t baudRate; + bool isMasterNode; + SpiDrv_ClockPhaseType clockPhase; + SpiDrv_ClockPolarityType clockPolarity; + SpiDrv_PcsSelType pcsSelection; + SpiDrv_PcsPolarityType pcsPolarity; + SpiDrv_ShiftFirstBitType dataShiftFirstBit; + uint16_t frameBitSize; +} SpiDrv_BasicParametersType; + +/*! \brief SPI extend parameter inoformation */ +typedef struct _SpiDrv_ExtendParametersType_ +{ + SpiDrv_DuplexType duplexType; + uint8_t delayBetweenTransfer; + uint8_t delayFromPcsToSck; + uint8_t delayFromSckToPcs; + uint8_t masterSampleSckDelay; + SpiDrv_PinCfgType pinCfg; + SpiDrv_OutCfgType outCfg; +} SpiDrv_ExtendParametersType; + +/*! \brief SPI extend feature information */ +typedef struct _SpiDrv_ExtendFeaturesType_ +{ + bool dmaTxEn; + bool dmaRxEn; + bool noStallEn; + bool circularFifoEn; + bool byteSwapEn; + bool slaveAutoPcsEn; + bool dbgEn; + bool stopEn; + bool rxMaskEn; + bool txMaskEn; +} SpiDrv_ExtendFeaturesType; + +/*! \brief SPI Isr access information */ +typedef struct _SpiDrv_IsrAccessType_ +{ + uint8_t txWatermark; + uint8_t rxWatermark; + bool rxdataIsrEnable; + bool txdataIsrEnable; + bool rxWordDoneIsrEnable; + bool frameDoneIsrEnable; + bool masterTransferDoneIsrEnable; + bool rxOfIsrEnable; + bool txUfIsrEnable; +} SpiDrv_IsrAccessType; + +/*! \brief SPI initialize configuration information */ +typedef struct _SpiDrv_InitCfgType_ +{ + SpiDrv_BasicParametersType basicParameters; + SpiDrv_ExtendParametersType extendParameters; + SpiDrv_ExtendFeaturesType extendFeatures; +} SpiDrv_InitCfgType; + +/*! \brief SPI instance pointer */ +typedef struct _SpiDrvType_ +{ + SpiRegType *reg; +} SpiDrvType; + +/****************************************************************************** + * the globals + *****************************************************************************/ + +/****************************************************************************** + * the function prototypes + *****************************************************************************/ + +/*! \brief Set Clock Polarity + * + * The Clock Polarity field is only updated when PCS negated. + * + * \param[in] pTcr : TCR variable instance + * \param[in] clockPolarity : + * 0b : The inactive state value of SCK is low + * 1b : The inactive state value of SCK is high + * \return: void + */ +extern void SpiDrv_SetClockPolarity(uint32_t *pTcr, uint8_t clockPolarity); + +/*! \brief Set Clock Phase + * + * The Clock Phase field is only updated when PCS negated. + * + * \param[in] pTcr : TCR variable instance + * \param[in] clockPhase : + * 0b : Data is captured on the leading edge of SCK and changed on the following edge of SCK + * 1b : Data is changed on the leading edge of SCK and captured on the following edge of SCK + * \return: void + */ +extern void SpiDrv_SetClockPhase(uint32_t *pTcr, uint8_t clockPhase); + +/*! \brief Set Prescaler Value + * + * For all SPI bus transfers, the Prescaler value applied to the clock configuration register. The Prescaler Value field is only updated when PCS negated. + * + * \param[in] pTcr : TCR variable instance + * \param[in] prescaler : + * 000b : Divide by 1 + * 001b : Divide by 2 + * 010b : Divide by 4 + * 011b : Divide by 8 + * 100b : Divide by 16 + * 101b : Divide by 32 + * 110b : Divide by 64 + * 111b : Divide by 128 + * \return: void + */ +extern void SpiDrv_SetPrescaler(uint32_t *pTcr, uint8_t prescaler); + +/*! \brief Select Peripheral Chip + * + * Configures the peripheral chip select used for the transfer. The Peripheral Chip Select field is only updated when PCS negated. + * + * \param[in] pTcr : TCR variable instance + * \param[in] pcsSelection : + * 00b : Transfer using SPI_PCS[0] + * 01b : Transfer using SPI_PCS[1] + * 10b : Transfer using SPI_PCS[2] + * 11b : Transfer using SPI_PCS[3] + * \return: void + */ +extern void SpiDrv_SetPcsSelection(uint32_t *pTcr, uint8_t pcsSelection); + +/*! \brief Set data transfer direction + * + * + * + * \param[in] pTcr : TCR variable instance + * \param[in] lsbFirst : + * 0b:Data is transferred MSB first + * 1b:Data is transferred LSB first + * \return: void + */ +extern void SpiDrv_SetLowBitFirstTransfer(uint32_t *pTcr, uint8_t lsbFirst); + +/*! \brief Set Byte Swap + * + * Byte swap will swap the contents of [31:24] with [7:0] and [23:16] with [15:8] for each transmit data word read from + * the FIFO and for each received data word stored to the FIFO + * + * \param[in] pTcr : TCR variable instance + * \param[in] enable : + * 0b:Byte swap is disabled + * 1b:Byte swap is enabled + * \return: void + */ +extern void SpiDrv_SetByteSwap(uint32_t *pTcr, bool enable); + +/*! \brief Set Continuous Transfer + * + * In master mode, continuous transfer will keep the PCS asserted at the end of the frame size, + * until a command word is received that starts a new frame. + * In slave mode, when continuous transfer is enabled, the SPI will only transmit the first FRAMESZ bits; + * after which the SPI will transmit received data (assuming a 32-bit shift register) until the next PCS negation. + * + * \param[in] pTcr : TCR variable instance + * \param[in] enable : + * 0b:Continuous transfer is disabled + * 1b:Continuous transfer is enabled + * \return: void + */ +extern void SpiDrv_SetContinuousTransfer(uint32_t *pTcr, bool enable); + +/*! \brief Set Continuing Command + * + * In master mode, the Continuing Command bit allows the command word to be changed within a transfer. + * 1. in continuous transfer + * - the initial command word must enable continuous transfer (CONT=1), + * - the continuing command must set this bit (CONTC=1), + * - the continuing command word must be loaded on a frame size boundary. + * 2. in non-continuous transfer + * - the continuing command must set this bit (CONTC=1), + * - the continuing command word must be loaded on a frame size boundary. + * + * \param[in] pTcr : TCR variable instance + * \param[in] cmd : + * 0b:Command word for start of new transfer + * 1b:Command word for continuing transfer + * \return: void + */ +extern void SpiDrv_SetContinuousCmd(uint32_t *pTcr, uint8_t cmd); + +/*! \brief Set Receive Data Mask + * + * When set, receive data is masked (receive data is not stored in receive FIFO). + * + * \param[in] pTcr : TCR variable instance + * \param[in] enableMask : + * 0b:Normal transfer + * 1b:Receive data is masked + * \return: void + */ +extern void SpiDrv_SetRxDataMask(uint32_t *pTcr, bool enableMask); + +/*! \brief Set Transmit Data Mask + * + * When set, transmit data is masked (no data is loaded from transmit FIFO and output pin is tristated). + * In master mode, the Transmit Data Mask bit will initiate a new transfer + * which cannot be aborted by another command word; TXMSK bit will be cleared by hardware at the end of the transfer. + * + * \param[in] pTcr : TCR variable instance + * \param[in] enableMask : + * 0b:Normal transfer + * 1b:Mask transmit data + * \return: void + */ +extern void SpiDrv_SetTxDataMask(uint32_t *pTcr, bool enableMask); + +/*! \brief Set Transfer data Width + * + * Configures between serial (1-bit) or parallel transfers. For half-duplex parallel transfers, either Receive Data Mask (RXMSK) or Transmit Data Mask (TXMSK) must be set. + * + * \param[in] pTcr : TCR variable instance + * \param[in] transferWidth : + * 00b:1 bit transfer + * 01b:2 bit transfer + * 10b:Reserved + * 11b:Reserved + * \return: void + */ +extern void SpiDrv_SetTransferWidth(uint32_t *pTcr, uint8_t transferWidth); + +/*! \brief Set Frame Size + * + * The minimum frame size is 8 bits, The minimum word size is 2 bits; a frame size of 33 bits (or similar) is not supported. + * If the frame size is larger than 32 bits, then the frame is divided into multiple words of 32-bits; + * each word is loaded from the transmit FIFO and stored in the receive FIFO separately. + * If the size of the frame is not divisible by 32, then the last load of the transmit FIFO and store of the receive FIFO will contain the remainder bits. + * For example, a 72-bit transfer will consist of 3 words: the 1st and 2nd words are 32 bits, and the 3rd word is 8 bits. + * + * \param[in] pTcr : TCR variable instance + * \param[in] frameSize :Configures the frame size in number of bits equal to (FRAMESZ + 1) + * \return: void + */ +extern void SpiDrv_SetFrameSize(uint32_t *pTcr, uint16_t frameSize); + +/*! \brief Transmit Command config + * + * this function config the clock polarity, clock phase prescaler value and transfer mode .... + * + * \param[in] obj: pointer to the instance + * \param[in] tcr: Transmit Command + * \return: void + */ +extern void SpiDrv_SetTcr(SpiDrvType *obj, uint32_t tcr); + +/*! \brief Get Transmit Command config + * + * this function config get the clock polarity, clock phase prescaler value and transfer mode .... + * + * \param[in] obj: pointer to the instance + * \return: Transmit Command + */ +extern uint32_t SpiDrv_GetTcr(const SpiDrvType *obj); + +/*! \brief Get default configures the module for configuration structure + * + * This function gets default configures the module for user configuration structure + * + * \param[out] pInitCfg :pointer to configuration structure + * \return: void + */ +extern void SpiDrv_GetDefaultConfig(SpiDrv_InitCfgType *pInitCfg); + +/*! \brief Set the spi module parameters include basic&extend features + * + * this function initializes the run-time state structure to provide for module configuration + * + * \param[in] obj : pointer to the instance + * \param[in] - const SpiDrv_InitCfgType * const pInitCfg: the pointer to the user configuration + * \return: void + */ +extern void SpiDrv_SetConfig(SpiDrvType *obj, const SpiDrv_InitCfgType *pInitCfg); + +/*! \brief Resets the SPI internal logic and registers to their default settings + * + * this function instance an object and reset module + * + * \param[in/out] : pointer to the instance + * \param[in] pReg : the phycial module base address pointer + * \return: void + */ +extern void SpiDrv_Init(SpiDrvType *obj, SpiRegType *pReg); + +/*! \brief Set the module to special condition + * + * call back in the usage of Low power or sleep requirements + * + * \param[in] obj : pointer to the instance + * \return: void + */ +extern void SpiDrv_DeInit(SpiDrvType *obj); + +/*! \brief Get the status of the SpiDrv_StatusType of event + * + * this function read out the special status what want to be read + * + * \param[in] obj : pointer to the instance + * \param[in] status : which status to be read out + * \return: bool + * true: The status is exist + * false: The status is not exist + */ +extern bool SpiDrv_GetStatus(const SpiDrvType *obj, SpiDrv_StatusType status); + +/*! \brief Clear the status + * + * this function clear the special status falg + * + * \param[in] obj : pointer to the instance + * \param[in] status : combination of any SpiDrv_StatusType event + * example: status = (SPIDRV_STATUS_RX_WORD_DONE | SPIDRV_STATUS_FRAME_DONE) + * \return: void + */ +extern void SpiDrv_ClearStatus(SpiDrvType *obj, uint32_t status); + +/*! \brief Set the link route function in the slave node with byte transfer + * + * this function is used for slave node to link transfer from master to other node with bytes + * + * \param[in] obj : pointer to the instance + * \param[in] txBytesCnt: the data bytes to be sent + * \param[in] pTxByteBuffer: pointer to the tx data byte buffer + * the tx data will fill or not by special requirement + * \return: void + */ +extern void SpiDrv_SlaveAsyncLinkTransferBytes(SpiDrvType *obj, uint16_t txBytesCnt, const uint8_t *pTxByteBuffer); + +/*! \brief Set the link route function in the slave node with halfword transfer + * + * this function is used for slave node to link transfer from master to other node with halfwords + * + * \param[in] obj : pointer to the instance + * \param[in] txHalfWordsCnt: the data halfwords to be sent + * \param[in] pTxHalfWordBuffer: pointer to the tx data halfword buffer + * the tx data will fill or not by special requirement + * \return: void + */ +extern void SpiDrv_SlaveAsyncLinkTransferHalfWords(SpiDrvType *obj, uint16_t txHalfWordsCnt, const uint16_t *pTxHalfWordBuffer); + +/*! \brief Set the link route function in the slave node with word transfer + * + * this function is used for slave node to link transfer from master to other node with words + * + * \param[in] obj : pointer to the instance + * \param[in] txWodsCnt: the data words to be sent + * \param[in] pTxWordBuffer: pointer to the tx data word buffer + * the tx data will fill or not by special requirement + * \return: void + */ +extern void SpiDrv_SlaveAsyncLinkTransferWords(SpiDrvType *obj, uint16_t txWodsCnt, const uint32_t *pTxWordBuffer); + +/*! \brief Set Transmit Command Register configuration + * + * Any writes to the TCR will cause the entire TCR contents to be pushed to the TX FIFO. + * Therefore any updates to the TCR should include updates to all of the register + * bit fields to form a 32-bit write to the TCR. + * + * \param[in] obj : pointer to the instance + * \param[in] pTcrInfo : Transmit Command Register configuration structure + * \return void + */ +extern void SpiDrv_SetTcrCmdConfig(SpiDrvType *obj, const SpiDrv_TcrInfoType *pTcrInfo); + +/*! \brief Get Transmit Command Register configuration structure + * + * This function get the current tcr register value + * + * \param[in] obj : pointer to the instance + * \return: Transmit Command Register configuration structure + */ +extern SpiDrv_TcrInfoType SpiDrv_GetTcrCmdConfig(const SpiDrvType *obj); + +/*! \brief Send one short frame each frame bits numbers is equal to or less than 32bits, every time hard set pcs signal again + * the DBT feature is valid + * _____ DATA (DBT) _________ DATA(DBT) __________ + * PCS |_____________| |_____________| + * + * \param[in] obj : pointer to the instance + * \param[in] txData:data to be sent + * \param[in] frameSizeBitType:the frame bit width(8bit/16bit/32bit) to describe the pTxBuffer data width type + * \return: bool + * true: no err + * false: no enough space for the current tx requirement + */ +extern bool SpiDrv_AsyncSingleFrameTransfer(SpiDrvType *obj, uint32_t txData, SpiDrv_FrameSizeBitType frameSizeBitType); + +/*! \brief Send more than 32bits frame one time, the DBT feature is invalid + * + * _____ DATA DATA DATA DATA __________ + * PCS |_____________________| + * + * \param[in] obj : pointer to the instance + * \param[in] txFrameNums: the nums data to be sent + * \param[in] pTxBuffer: th pointer of which data to be sent + * \param[in] frameSizeBitType:the frame bit width(8bit/16bit/32bit) to describe the pTxBuffer data width type + * \param[in] littleEndDian: transfer byte turn + * \return: bool + * true: no err + * false: no enough space for the current tx requirement + */ +extern bool SpiDrv_AsyncLongFrameTransfer(SpiDrvType *obj, uint16_t txFrameNums, const void *pTxBuffer, SpiDrv_FrameSizeBitType frameSizeBitType, bool littleEndDian); + +/*! \brief continue Send constinues frame,each frame bits numbers is equal to or less than 32bits + * the DBT feature is valid + * _____ DATA(xbits) (DBT) DATA(xBits)__________ + * PCS |_______________________________| + * + * \param[in] obj : pointer to the instance + * \param[in] txFrameNums: the nums data to be sent + * \param[in] pTxBuffer: th pointer of which data to be sent + * \param[in] frameSizeBitType:the frame bit width(8bit/16bit/32bit) to describe the pTxBuffer data width type + * \return: bool + * true: no err + * false: no enough space for the current tx requirement + */ +extern bool SpiDrv_AsyncContinueFrameTransfer(SpiDrvType *obj, uint16_t txFrameNums, const void *pTxBuffer, SpiDrv_FrameSizeBitType frameSizeBitType); + +/*! \brief Async bit data write to hardware tx data buffer + * + * this function just only fill datas to tx fifo, but not read out datas from rx fifo + * + * \param[in] obj : pointer to the instance + * \param[in] txBitNums: the tx data bits numbers to be write + * \param[in] pTxBuffer: write data buffer , notice: aligned with 32bits + * \param[in] littleEndDian: write bit flow turn + * \return: bool + * false: error + * true: no error + */ +extern bool SpiDrv_AsyncBitDataWriteIntoHwTxBuffer(SpiDrvType *obj, uint16_t txBitNums, const void *pTxBuffer, bool littleEndDian); + +/*! \brief Master Async tx data with any length of bits + * + * this function just only fill datas to tx fifo, but not read out datas from rx fifo, the bits num should be multile by 2! + * + * \param[in] obj : pointer to the instance + * \param[in] txBitNums: the nums bits of data to be sent + * \param[in] pBuffer: th pointer of which data to be sent;if in half duplex mode, and the txmask is true, no care about this parameter, + * notice: aligned with 32bits + * \param[in] txMask: tx mask bit + * \param[in] rxMask: rx mask bit + * \param[in] littleEndDian: transfer data flow + * \return: bool + * true: no error + * false: error + */ +extern bool SpiDrv_AsyncBitsTransfer(SpiDrvType *obj, uint16_t txBitNums, const void *pBuffer, bool txMask, bool rxMask, bool littleEndDian); + +/*! \brief Async bits Received + * + * this function read the datas from rx fifo, and return the bytes nums have been readout. + * Notice: Returns the number of words currently stored in the receive FIFO, may be just one byte in rx fifo, but still return four bytes + * so the total read out bytes number must be more than the actual useful numbers + * + * \param[in] obj : pointer to the instance + * \param[in] pBuffer: th pointer of which data to be stored, Notice: the address must be aligned with word!!!! + * \param[in] littleEndDian: transfer data flow + * \return: the bytes in the rx fifo + */ +extern uint8_t SpiDrv_AsyncReceive(SpiDrvType *obj, void *pBuffer, bool littleEndDian); + +/*! \brief Master Sync tx data, sent and received data from other node + * + * _____ DATA DATA DATA DATA __________ + * PCS |_____________________| + * + * \param[in] obj : pointer to the instance + * \param[in] frameSizeBitType: the data width to describe the pTxBuffer + * \param[in] txFrameNums: the nums data to be sent + * \param[in] pTxBuffer: the transmit data buffer pointer + * \param[in] pRxBuffer: the pointer for the read-out datas + * \return: bool + * false: the current tx fifo is full, no enough space for this transmit + * true: no error + */ +extern bool SpiDrv_MasterSyncTransfer(SpiDrvType *obj, SpiDrv_FrameSizeBitType frameSizeBitType, uint16_t txFrameNums, const void *pTxBuffer, void *pRxBuffer); + +/*! \brief Set Slave rx fifo water mark + * + * the max water mark is must less than the supported depth + * + * \param[in] obj : pointer to the instance + * \param[in] txFrameNums: the tx frame to be sent + * \param[in] frameSizeBitType: frame bit width(8bit/16bit/32bit) + * \return: bool + * false: the current water is more than the actual max supported depth + * true: no error + */ +extern bool SpiDrv_SlaveSetRxWaterMark(SpiDrvType *obj, uint16_t txFrameNums, SpiDrv_FrameSizeBitType frameSizeBitType); + +/*! \brief Set rx fifo water mask + * + * \param[in] obj : pointer to the instance + * \param[in] waterMask: fifo water mask + * \return: void + */ +extern void SpiDrv_SetRxFifoWaterMask(SpiDrvType *obj, uint8_t waterMask); + +/*! \brief Set tx fifo water mask + * + * \param[in] obj : pointer to the instance + * \param[in] waterMask: fifo water mask + * \return: void + */ +extern void SpiDrv_SetTxFifoWaterMask(SpiDrvType *obj, uint8_t waterMask); + +/*! \brief Set SPI interrupt config + * + * \param[in] obj : pointer to the instance + * \param[in] isrSrc: interrupt source + * \param[in] enabled: config status + * \return: void + */ +extern void SpiDrv_SetIsrConfig(SpiDrvType *obj, SpiDrv_IsrSrcType isrSrc, bool enabled); + +/*! \brief Get SPI interrupt config + * + * \param[in] obj : pointer to the instance + * \param[in] isrSrc: interrupt source + * \return: config status + */ +extern bool SpiDrv_GetIsrConfig(SpiDrvType *obj, SpiDrv_IsrSrcType isrSrc); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _SPI_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/trgmux/trgmux_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/trgmux/trgmux_drv.c new file mode 100644 index 0000000..9e2969c --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/trgmux/trgmux_drv.c @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "trgmux_drv.h" +#include "trgmux_reg.h" +#include "sim_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* Number of target modules for TRGMUX IP */ +#define TRGMUXDRV_MODULE_NUM (sizeof(TrgMuxRegType) / sizeof(uint32_t)) +/* Number of output ports in one target module */ +#define TRGMUXDRV_TARGET_NUM (4) +/* Sim software trigger delay */ +#define TRGMUXDRV_DELAY(x) \ + do \ + { \ + for(volatile int cnt = 0; cnt < x; cnt++) \ + { \ + ; \ + } \ + } while(0) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/* Definition of function prototype of getting module's lock state */ +typedef uint8_t (*TrgMuxReg_GetModuleLockFunc)(const TrgMuxRegType *obj); +/* Definition of function prototype of locking module selection */ +typedef void (*TrgMuxReg_SetModuleLockFunc)(TrgMuxRegType *obj, uint8_t value); +/* Definition of function prototype of getting module selection */ +typedef uint8_t (*TrgMuxReg_GetModuleSelFunc)(const TrgMuxRegType *obj); +/* Definition of function prototype of setting module selection */ +typedef void (*TrgMuxReg_SetModuleSelFunc)(TrgMuxRegType *obj, uint8_t value); + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/* Definition of the table of getting module's lock state functions */ +static const TrgMuxReg_GetModuleLockFunc c_getModuleLockFuncTable[TRGMUXDRV_MODULE_NUM] = { + TrgMuxReg_GetDmaMux0Lk, + TrgMuxReg_GetExtOut0Lk, + NULL, + TrgMuxReg_GetAdcLk, + NULL, + TrgMuxReg_GetCmpLk, + TrgMuxReg_GetMft0Lk, + TrgMuxReg_GetMft1Lk, + NULL, + NULL, + TrgMuxReg_GetPdbLk, + NULL, + TrgMuxReg_GetLpitLk, + TrgMuxReg_GetLptmrLk}; + +/* Definition of the table of setting module's lock state functions */ +static const TrgMuxReg_SetModuleLockFunc c_setModuleLockFuncTable[TRGMUXDRV_MODULE_NUM] = { + TrgMuxReg_SetDmaMux0Lk, + TrgMuxReg_SetExtOut0Lk, + NULL, + TrgMuxReg_SetAdcLk, + NULL, + TrgMuxReg_SetCmpLk, + TrgMuxReg_SetMft0Lk, + TrgMuxReg_SetMft1Lk, + NULL, + NULL, + TrgMuxReg_SetPdbLk, + NULL, + TrgMuxReg_SetLpitLk, + TrgMuxReg_SetLptmrLk}; + +/* Definition of the table of getting module's selection functions */ +static const TrgMuxReg_GetModuleSelFunc c_getModuleSelFuncTable[TRGMUXDRV_MODULE_NUM][TRGMUXDRV_TARGET_NUM] = { + {TrgMuxReg_GetDmaMux0Sel0, TrgMuxReg_GetDmaMux0Sel1, TrgMuxReg_GetDmaMux0Sel2, TrgMuxReg_GetDmaMux0Sel3}, + {TrgMuxReg_GetExtOut0Sel0, TrgMuxReg_GetExtOut0Sel1, TrgMuxReg_GetExtOut0Sel2, TrgMuxReg_GetExtOut0Sel3}, + {NULL, NULL, NULL, NULL }, + {TrgMuxReg_GetAdcSel0, TrgMuxReg_GetAdcSel1, TrgMuxReg_GetAdcSel2, TrgMuxReg_GetAdcSel3 }, + {NULL, NULL, NULL, NULL }, + {TrgMuxReg_GetCmpSel0, NULL, NULL, NULL }, + {TrgMuxReg_GetMft0Sel0, TrgMuxReg_GetMft0Sel1, TrgMuxReg_GetMft0Sel2, TrgMuxReg_GetMft0Sel3 }, + {TrgMuxReg_GetMft1Sel0, TrgMuxReg_GetMft1Sel1, TrgMuxReg_GetMft1Sel2, TrgMuxReg_GetMft1Sel3 }, + {NULL, NULL, NULL, NULL }, + {NULL, NULL, NULL, NULL }, + {TrgMuxReg_GetPdbSel0, NULL, NULL, NULL }, + {NULL, NULL, NULL, NULL }, + {TrgMuxReg_GetLpitSel0, TrgMuxReg_GetLpitSel1, TrgMuxReg_GetLpitSel2, TrgMuxReg_GetLpitSel3 }, + {TrgMuxReg_GetLptmrSel0, NULL, NULL, NULL }, +}; + +/* Definition of the table of setting module's selection functions */ +static const TrgMuxReg_SetModuleSelFunc c_setModuleSelFuncTable[TRGMUXDRV_MODULE_NUM][TRGMUXDRV_TARGET_NUM] = { + {TrgMuxReg_SetDmaMux0Sel0, TrgMuxReg_SetDmaMux0Sel1, TrgMuxReg_SetDmaMux0Sel2, TrgMuxReg_SetDmaMux0Sel3}, + {TrgMuxReg_SetExtOut0Sel0, TrgMuxReg_SetExtOut0Sel1, TrgMuxReg_SetExtOut0Sel2, TrgMuxReg_SetExtOut0Sel3}, + {NULL, NULL, NULL, NULL }, + {TrgMuxReg_SetAdcSel0, TrgMuxReg_SetAdcSel1, TrgMuxReg_SetAdcSel2, TrgMuxReg_SetAdcSel3 }, + {NULL, NULL, NULL, NULL }, + {TrgMuxReg_SetCmpSel0, NULL, NULL, NULL }, + {TrgMuxReg_SetMft0Sel0, TrgMuxReg_SetMft0Sel1, TrgMuxReg_SetMft0Sel2, TrgMuxReg_SetMft0Sel3 }, + {TrgMuxReg_SetMft1Sel0, TrgMuxReg_SetMft1Sel1, TrgMuxReg_SetMft1Sel2, TrgMuxReg_SetMft1Sel3 }, + {NULL, NULL, NULL, NULL }, + {NULL, NULL, NULL, NULL }, + {TrgMuxReg_SetPdbSel0, NULL, NULL, NULL }, + {NULL, NULL, NULL, NULL }, + {TrgMuxReg_SetLpitSel0, TrgMuxReg_SetLpitSel1, TrgMuxReg_SetLpitSel2, TrgMuxReg_SetLpitSel3 }, + {TrgMuxReg_SetLptmrSel0, NULL, NULL, NULL }, +}; + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void TrgMuxDrv_Init(TrgMuxDrvType *obj, struct _TrgMuxRegType_ *trgMuxReg, struct _SimRegType_ *simReg) +{ + obj->trgMuxReg = trgMuxReg; + obj->simReg = simReg; +} + +void TrgMuxDrv_Configure(TrgMuxDrvType *obj, const TrgMuxDrv_ConfigType *userConfig) +{ + uint16_t index; + + if((obj == NULL) + || (userConfig == NULL) + || (userConfig->numOfInOutMappings == 0)) + { + return; + } + + for(index = 0; index < userConfig->numOfInOutMappings; index++) + { + TrgMuxDrv_SetTrigSourceForTargetModule(obj, + userConfig->inOutMapping[index].triggerSource, + userConfig->inOutMapping[index].targetModule); + } + for(index = 0; index < userConfig->numOfInOutMappings; index++) + { + if(userConfig->inOutMapping[index].lockTargetModuleReg) + { + TrgMuxDrv_SetLockForTargetModule(obj, userConfig->inOutMapping[index].targetModule); + } + } +} + +bool TrgMuxDrv_SetTrigSourceForTargetModule(TrgMuxDrvType *obj, TrgMuxDrv_TrigSourceType triggerSource, TrgMuxDrv_TargetModuleType targetModule) +{ + bool retval; + + if(TrgMuxDrv_GetLockForTargetModule(obj, targetModule) == true) + { + retval = false; + } + else + { + /* Configure link between trigger source and target module. */ + uint8_t moduleIndex = (uint8_t)((uint32_t)targetModule / 4); + uint8_t sourceIndex = (uint8_t)((uint32_t)targetModule % 4); + if(c_setModuleSelFuncTable[moduleIndex][sourceIndex] != NULL) + { + c_setModuleSelFuncTable[moduleIndex][sourceIndex](obj->trgMuxReg, triggerSource); + retval = true; + } + else + { + retval = false; + } + } + + return retval; +} + +TrgMuxDrv_TrigSourceType TrgMuxDrv_GetTrigSourceForTargetModule(const TrgMuxDrvType *obj, TrgMuxDrv_TargetModuleType targetModule) +{ + TrgMuxDrv_TrigSourceType retval = TRGMUXDRV_TRIGSOURCE_SIG0; + uint8_t moduleIndex = (uint8_t)((uint32_t)targetModule / 4); + uint8_t sourceIndex = (uint8_t)((uint32_t)targetModule % 4); + if(c_getModuleSelFuncTable[moduleIndex][sourceIndex] != NULL) + { + retval = (TrgMuxDrv_TrigSourceType)c_getModuleSelFuncTable[moduleIndex][sourceIndex](obj->trgMuxReg); + } + + return retval; +} + +void TrgMuxDrv_SetLockForTargetModule(TrgMuxDrvType *obj, TrgMuxDrv_TargetModuleType targetModule) +{ + uint8_t moduleIndex = (uint8_t)((uint32_t)targetModule / 4); + if(c_setModuleLockFuncTable[moduleIndex] != NULL) + { + c_setModuleLockFuncTable[moduleIndex](obj->trgMuxReg, 1); + } +} + +bool TrgMuxDrv_GetLockForTargetModule(const TrgMuxDrvType *obj, TrgMuxDrv_TargetModuleType targetModule) +{ + bool retval = true; + uint8_t moduleIndex = (uint8_t)((uint32_t)targetModule / 4); + if(c_getModuleLockFuncTable[moduleIndex] != NULL) + { + retval = (c_getModuleLockFuncTable[moduleIndex](obj->trgMuxReg) == 1); + } + + return retval; +} + +void TrgMuxDrv_GenSWTrigger(TrgMuxDrvType *obj, uint32_t delay) +{ + /* The trigger is generated only when writing from 0 to 1*/ + SimReg_SetSwTrg(obj->simReg, 0); + TRGMUXDRV_DELAY(delay); + SimReg_SetSwTrg(obj->simReg, 1); +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/trgmux/trgmux_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/trgmux/trgmux_drv.h new file mode 100644 index 0000000..d736e7b --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/trgmux/trgmux_drv.h @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _TRGMUX_DRV_H_ +#define _TRGMUX_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of TRGMUX (Trigger MUX) + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup trgmux_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of TRGMUX trigger source + */ +typedef enum +{ + TRGMUXDRV_TRIGSOURCE_SIG0 = 0U, + TRGMUXDRV_TRIGSOURCE_SIG1 = 1U, + TRGMUXDRV_TRIGSOURCE_TRGMUX_IN0 = 2U, + TRGMUXDRV_TRIGSOURCE_TRGMUX_IN1 = 3U, + TRGMUXDRV_TRIGSOURCE_TRGMUX_IN2 = 4U, + TRGMUXDRV_TRIGSOURCE_TRGMUX_IN3 = 5U, + TRGMUXDRV_TRIGSOURCE_TRGMUX_IN4 = 6U, + TRGMUXDRV_TRIGSOURCE_TRGMUX_IN5 = 7U, + + TRGMUXDRV_TRIGSOURCE_TRGMUX_IN7 = 9U, + TRGMUXDRV_TRIGSOURCE_TRGMUX_IN8 = 10U, + TRGMUXDRV_TRIGSOURCE_TRGMUX_IN9 = 11U, + + TRGMUXDRV_TRIGSOURCE_CMP0_OUT = 14U, + + TRGMUXDRV_TRIGSOURCE_LPIT_CH0 = 16U, + TRGMUXDRV_TRIGSOURCE_LPIT_CH1 = 17U, + TRGMUXDRV_TRIGSOURCE_LPIT_CH2 = 18U, + TRGMUXDRV_TRIGSOURCE_LPIT_CH3 = 19U, + + TRGMUXDRV_TRIGSOURCE_LPTMR0 = 21U, + TRGMUXDRV_TRIGSOURCE_MFT0_INIT_TRIG = 22U, + TRGMUXDRV_TRIGSOURCE_MFT0_EXT_TRIG = 23U, + TRGMUXDRV_TRIGSOURCE_MFT1_INIT_TRIG = 24U, + TRGMUXDRV_TRIGSOURCE_MFT1_EXT_TRIG = 25U, + + TRGMUXDRV_TRIGSOURCE_ADC0_SC1A_COCO = 30U, + TRGMUXDRV_TRIGSOURCE_ADC0_SC1B_COCO = 31U, + + TRGMUXDRV_TRIGSOURCE_PDB0_CH0_TRIG = 34U, + TRGMUXDRV_TRIGSOURCE_PDB0_PULSE_OUT = 35U, + + TRGMUXDRV_TRIGSOURCE_RTC_ALARM = 38U, + TRGMUXDRV_TRIGSOURCE_RTC_SECOND = 39U, + TRGMUXDRV_TRIGSOURCE_SPI0_FRAME = 40U, + TRGMUXDRV_TRIGSOURCE_SPI0_WORD = 41U, + TRGMUXDRV_TRIGSOURCE_SPI1_FRAME = 42U, + TRGMUXDRV_TRIGSOURCE_SPI1_WORD = 43U, + + TRGMUXDRV_TRIGSOURCE_SIM_SW_TRIG = 48U, + +} TrgMuxDrv_TrigSourceType; + +/*! \brief The definition of TRGMUX trigger module + */ +typedef enum +{ + TRGMUXDRV_TARGETMODULE_DMA_CH0 = 0U, + TRGMUXDRV_TARGETMODULE_DMA_CH1 = 1U, + TRGMUXDRV_TARGETMODULE_DMA_CH2 = 2U, + TRGMUXDRV_TARGETMODULE_DMA_CH3 = 3U, + TRGMUXDRV_TARGETMODULE_TRGMUX_OUT0 = 4U, + TRGMUXDRV_TARGETMODULE_TRGMUX_OUT1 = 5U, + TRGMUXDRV_TARGETMODULE_TRGMUX_OUT2 = 6U, + TRGMUXDRV_TARGETMODULE_TRGMUX_OUT3 = 7U, + + TRGMUXDRV_TARGETMODULE_ADC0_ADHWT_TLA0 = 12U, + TRGMUXDRV_TARGETMODULE_ADC0_ADHWT_TLA1 = 13U, + TRGMUXDRV_TARGETMODULE_ADC0_ADHWT_TLA2 = 14U, + TRGMUXDRV_TARGETMODULE_ADC0_ADHWT_TLA3 = 15U, + + TRGMUXDRV_TARGETMODULE_CMP0_SAMPLE = 20U, + TRGMUXDRV_TARGETMODULE_MFT0_HWTRIG0 = 24U, + TRGMUXDRV_TARGETMODULE_MFT0_FAULT0 = 25U, + TRGMUXDRV_TARGETMODULE_MFT0_FAULT1 = 26U, + TRGMUXDRV_TARGETMODULE_MFT0_FAULT2 = 27U, + TRGMUXDRV_TARGETMODULE_MFT1_HWTRIG0 = 28U, + TRGMUXDRV_TARGETMODULE_MFT1_FAULT0 = 29U, + TRGMUXDRV_TARGETMODULE_MFT1_FAULT1 = 30U, + TRGMUXDRV_TARGETMODULE_MFT1_FAULT2 = 31U, + + TRGMUXDRV_TARGETMODULE_PDB0_TRG_IN = 40U, + + TRGMUXDRV_TARGETMODULE_LPIT_TRG_CH0 = 48U, + TRGMUXDRV_TARGETMODULE_LPIT_TRG_CH1 = 49U, + TRGMUXDRV_TARGETMODULE_LPIT_TRG_CH2 = 50U, + TRGMUXDRV_TARGETMODULE_LPIT_TRG_CH3 = 51U, + TRGMUXDRV_TARGETMODULE_LPTMR_ALT0 = 52U, +} TrgMuxDrv_TargetModuleType; + +/*! \brief Definition of In Out Mapping of TRGMUX driver + */ +typedef struct _TrgMuxDrv_InOutMappingType_ +{ + TrgMuxDrv_TrigSourceType triggerSource; /*!< selects one of the TRGMUX trigger sources */ + TrgMuxDrv_TargetModuleType targetModule; /*!< selects one of the TRGMUX target modules */ + bool lockTargetModuleReg; /*!< if true, the LOCK bit of the target module register will be + set by TrgMuxDrv_Configure(), after the current mapping is configured */ + +} TrgMuxDrv_InOutMappingType; + +/*! \brief Definition of configuration of TRGMUX driver + */ +typedef struct _TrgMuxDrv_ConfigType_ +{ + uint16_t numOfInOutMappings; /*!< number of in-out mappings defined in TRGMUX configuration */ + const TrgMuxDrv_InOutMappingType *inOutMapping; /*!< pointer to array of in-out mapping structures */ +} TrgMuxDrv_ConfigType; + +/* Forward declaration of TRGMUX register */ +struct _TrgMuxRegType_; +/* Forward declaration of TRGMUX register */ +struct _SimRegType_; + +/*! \brief The definition of TRGMUX driver class + */ +typedef struct _TrgMuxDrvType_ +{ + struct _TrgMuxRegType_ *trgMuxReg; + struct _SimRegType_ *simReg; +} TrgMuxDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +/*! \brief Initializes the TRGMUX driver module + * + * This function initializes TRGMUX driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to TRGMUX driver instance + * \param[in] reg : pointer to TRGMUX register instance + */ +extern void TrgMuxDrv_Init(TrgMuxDrvType *obj, struct _TrgMuxRegType_ *trgMuxReg, struct _SimRegType_ *simReg); + +/*! \brief Configures the TRGMUX module from the user configuration structure + * + * This function configures the TRGMUX module from the user configuration structure + * + * \param[in] obj : pointer to TRGMUX driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void TrgMuxDrv_Configure(TrgMuxDrvType *obj, const TrgMuxDrv_ConfigType *userConfig); + +/*! \brief Configure a source trigger for a selected target module. + * + * This function configures a TRGMUX link between a source trigger and a target module, + * if the requested target module is not locked. + * + * \param[in] obj : pointer to TRGMUX driver instance + * \param[in] triggerSource : One of the values in the TrgMuxDrv_TrigSourceType enumeration + * \param[in] targetModule : One of the values in the TrgMuxDrv_TargetModuleType enumeration + * \return the result of setting source for target module + * - true : succeed + * - false : failed because targetModule is locked + */ +extern bool TrgMuxDrv_SetTrigSourceForTargetModule(TrgMuxDrvType *obj, TrgMuxDrv_TrigSourceType triggerSource, TrgMuxDrv_TargetModuleType targetModule); + +/*! \brief Get the source trigger configured for a target module. + * + * This function returns the TRGMUX source trigger linked to a selected target module. + * + * \note If the target module is invalid (not in the enum), this function will return source 0 + * which has no meaning. + * + * \param[in] obj : pointer to TRGMUX driver instance + * \param[in] triggerSource : One of the values in the TrgMuxDrv_TrigSourceType enumeration + * \param[in] targetModule : One of the values in the TrgMuxDrv_TargetModuleType enumeration + */ +extern TrgMuxDrv_TrigSourceType TrgMuxDrv_GetTrigSourceForTargetModule(const TrgMuxDrvType *obj, TrgMuxDrv_TargetModuleType targetModule); + +/*! \brief Locks the TRGMUX register of a target module. + * + * This function sets the LK bit of the TRGMUX register corresponding to + * the selected target module. Please note that some TRGMUX registers can contain up to 4 + * SEL bitfields, meaning that these registers can be used to configure up to 4 target + * modules independently. Because the LK bit is only one per register, the configuration + * of all target modules referred from that register will be locked. + * + * \param[in] obj : pointer to TRGMUX driver instance + * \param[in] targetModule : One of the values in the TrgMuxDrv_TargetModuleType enumeration + */ +extern void TrgMuxDrv_SetLockForTargetModule(TrgMuxDrvType *obj, TrgMuxDrv_TargetModuleType targetModule); + +/*! \brief Get the Lock bit status of the TRGMUX register of a target module. + * + * This function gets the value of the LK bit from the TRGMUX register corresponding to + * the selected target module. + * + * \param[in] obj : pointer to TRGMUX driver instance + * \param[in] targetModule : One of the values in the TrgMuxDrv_TargetModuleType enumeration + * \return the result of lock + * - true : if the selected targetModule register is locked + * - false : if the selected targetModule register is not locked + */ +extern bool TrgMuxDrv_GetLockForTargetModule(const TrgMuxDrvType *obj, TrgMuxDrv_TargetModuleType targetModule); + +/*! \brief Generate software triggers + * + * This function uses a SIM register in order to generate a software triggers to the target + * peripherals selected in TRGMUX + * + * \param[in] obj : pointer to TRGMUX driver instance + * \param[in] delay : set delay time for trigger pulse width + */ +extern void TrgMuxDrv_GenSWTrigger(TrgMuxDrvType *obj, uint32_t delay); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _TRGMUX_DRV_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/uart/uart_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/uart/uart_drv.c new file mode 100644 index 0000000..0402154 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/uart/uart_drv.c @@ -0,0 +1,805 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/****************************************************************************** + * the includes + *****************************************************************************/ + +#include "uart_drv.h" + +/****************************************************************************** + * the defines + *****************************************************************************/ + +/****************************************************************************** + * the globals + ******************************************************************************/ + +/****************************************************************************** + * the Static Function Declarations + ******************************************************************************/ +static void UartDrv_InitBasicParameters(UartDrvType *obj, const UartDrv_BasicParametersType *pBasicParameters); +static void UartDrv_InitExtendParameters(UartDrvType *obj, const UartDrv_ExtendParametersType *pExtendParameters, const UartDrv_ExtendFeaturesType *pExtendFeatures); + +/****************************************************************************** + * the functions + *****************************************************************************/ + +/*! \brief Config the basic parameter of the usart basic feature + * + * This function initializes the basic features with the parameters + * + * \param[in] obj: pointer to UART driver instance + * \param[in] pBasicParameters : the combination of basic parameters + * \return: void + */ +static void UartDrv_InitBasicParameters(UartDrvType *obj, const UartDrv_BasicParametersType *pBasicParameters) +{ + /* Parity configuration setting */ + if(pBasicParameters->paritySelection < UARTDRV_PARITY_SELECT_UNUSED) + { + UartReg_SelectParity(obj->reg, pBasicParameters->paritySelection); + UartReg_SetParityControlEnable(obj->reg, true); + } + else + { + UartReg_SetParityControlEnable(obj->reg, false); + } + + /* Data length set */ + UartReg_SetWordLength(obj->reg, pBasicParameters->dataBitsNum); + + /* STOP Bit num */ + UartReg_SetStopBitNums(obj->reg, pBasicParameters->stopBitsNum); + + /* Data shift direction */ + UartReg_SetFirstBitShift(obj->reg, pBasicParameters->dataShiftDirection); + + /* Sampliing setting */ + UartReg_SetOverSamplingMode(obj->reg, pBasicParameters->overSamplingMode); + + /* note: When the one sample bit method is selected the noise detection flag (NF) is disabled */ + UartReg_SetSampleBitMethod(obj->reg, pBasicParameters->oneSampleBitMethod); + + if(pBasicParameters->baudRate != UARTDRV_BRAUD_RATE_INVALID) + { + /* TODO: How to get the system clock frequency? if 6/24/2022 Changed by %USERNAME% */ + uint32_t tDiv = 0; + + if(pBasicParameters->overSamplingMode == UARTDRV_OVERSAMPLING_MODE_BY_8) + { + /* + -BRR[2:0] = UARTDIV[3:0] shifted 1 bit to the right + -BRR[3] must be kept cleared + -BRR[15:4] = UARTDIV[15:4] + */ + tDiv = pBasicParameters->busClockFreq / (pBasicParameters->baudRate >> 1ul); + tDiv = ((tDiv & UARTDRV_BRR_LOW_4BITS_MASK) >> 1u) | (tDiv & (~UARTDRV_BRR_LOW_4BITS_MASK)); + } + else + { + /* overSamplingMode == 16, BRR = UARTDIV */ + tDiv = pBasicParameters->busClockFreq / pBasicParameters->baudRate; + } + + UartReg_SetBaudRate(obj->reg, (uint16_t)(tDiv & 0xFFFF)); + + /* Disable Auto detect baud rate feature */ + UartReg_EnableAutoBaudrateFeature(obj->reg, false); + } + + /* Transceiver enable */ + switch(pBasicParameters->dataTransferDirect) + { + case UARTDRV_DATA_TRANSFER_TX_RX_EN: + UartReg_SetReceiverEnable(obj->reg, true); + UartReg_SetTransmitterEnable(obj->reg, true); + break; + + case UARTDRV_DATA_TRANSFER_TX_ONLY: + UartReg_SetReceiverEnable(obj->reg, false); + UartReg_SetTransmitterEnable(obj->reg, true); + break; + + case UARTDRV_DATA_TRANSFER_RX_ONLY: + UartReg_SetReceiverEnable(obj->reg, true); + UartReg_SetTransmitterEnable(obj->reg, false); + break; + + case UARTDRV_DATA_TRANSFER_TX_RX_DIS: + UartReg_SetReceiverEnable(obj->reg, false); + UartReg_SetTransmitterEnable(obj->reg, false); + break; + + default: + UartReg_SetReceiverEnable(obj->reg, false); + UartReg_SetTransmitterEnable(obj->reg, false); + break; + } +} + +/*! \brief Set the extend parameter of the extend feature + * + * This function initializes the extend features with the parameters + * + * \param[in] obj: pointer to UART driver instance + * \param[in] pExtendParameters: the combination of extend parameters + * \param[in] pExtendFeatures: the combination of extendFeatures + * \return: void + */ +static void UartDrv_InitExtendParameters(UartDrvType *obj, const UartDrv_ExtendParametersType *pExtendParameters, const UartDrv_ExtendFeaturesType *pExtendFeatures) +{ + /* Loops mode */ + UartReg_SetLoopsMode(obj->reg, pExtendFeatures->loopEn); + + switch(pExtendFeatures->cosplayer) + { + case UARTDRV_COSPLAY_LIN: + UartReg_EnableCts(obj->reg, false); + UartReg_EnableRts(obj->reg, false); + UartReg_SetDriverEnableMode(obj->reg, false); + UartReg_SetTxLinSyncBreakWidth(obj->reg, pExtendParameters->breakFieldSyncBreakTxBitsNum); + UartReg_SetLinDelimitorWidth(obj->reg, pExtendParameters->breakFieldDelimiterTxBitsNum); + UartReg_SetLinSyncBreakDetectLen(obj->reg, pExtendParameters->syncBreakRxBitsNum); + UartReg_EnableLineBreakDetectFeature(obj->reg, true); + break; + + case UARTDRV_COSPLAY_RS232: + UartReg_EnableLineBreakDetectFeature(obj->reg, false); + UartReg_SetDriverEnableMode(obj->reg, false); + /* CTS Hardware flow control enable */ + UartReg_EnableCts(obj->reg, true); + UartReg_EnableRts(obj->reg, true); + break; + + case UARTDRV_COSPLAY_RS485: + UartReg_EnableLineBreakDetectFeature(obj->reg, false); + UartReg_SetDEDT(obj->reg, pExtendParameters->driverEnDeassertionTime); + UartReg_SetDEAT(obj->reg, pExtendParameters->driverEnAssertionTime); + UartReg_SetDriverPolarity(obj->reg, pExtendParameters->driverEnablePolarityActiveInLow); + UartReg_SetDriverEnableMode(obj->reg, true); + break; + + case UARTDRV_COSPLAY_UART: + default: + UartReg_EnableCts(obj->reg, false); + UartReg_EnableRts(obj->reg, false); + UartReg_SetDriverEnableMode(obj->reg, false); + UartReg_EnableLineBreakDetectFeature(obj->reg, false); + break; + } + + /* Inversion in Rx&Tx Pin & Data */ + UartReg_EnableRxInverteFeature(obj->reg, pExtendFeatures->rxInvertEn); + UartReg_EnableTxInverteFeature(obj->reg, pExtendFeatures->txInvertEn); + UartReg_EnableDataInverteFeature(obj->reg, pExtendFeatures->dataInvertEn); + + if(pExtendFeatures->autoBaudRateDetectionEn == true) + { + /* Enable Auto detect baud rate feature */ + UartReg_EnableAutoBaudrateFeature(obj->reg, true); + UartReg_SetAutoBaudrateMode(obj->reg, pExtendParameters->autoBaudRateMode); + } + else + { + UartReg_EnableAutoBaudrateFeature(obj->reg, false); + } + + if(pExtendParameters->rxTimeoutBitsCnt > 0u) + { + /* This bit-field gives the Receiver timeout value in terms of number of bit duration */ + UartReg_SetRxTimeout(obj->reg, pExtendParameters->rxTimeoutBitsCnt); + UartReg_EnableRxTimeoutFeature(obj->reg, true); + } + else + { + UartReg_EnableRxTimeoutFeature(obj->reg, false); + } + + if(pExtendFeatures->wakeUpEn == true) + { + if(pExtendParameters->wakeSrc == UARTDRV_WAKE_SOURCE_ADDRESS_MARK) + { + UartReg_SetNodeAddress(obj->reg, pExtendParameters->addrMarkDetectValue); + UartReg_SetAutoBaudrateMode(obj->reg, pExtendParameters->addrDetectMode); + } + else + { + UartReg_SetIdleConfig(obj->reg, pExtendParameters->idleCharNums); + } + + UartReg_SetMuteMode(obj->reg, true); + UartReg_SetWakeupMethod(obj->reg, pExtendParameters->wakeSrc); + } + else + { + UartReg_SetMuteMode(obj->reg, false); + UartReg_SetIdleConfig(obj->reg, pExtendParameters->idleCharNums); + } + + if(pExtendFeatures->dmaEn == true) + { + switch(pExtendParameters->dmaSelection) + { + case UARTDRV_DMA_SELECTION_TX_RX_DIS: + UartReg_EnableRxDMA(obj->reg, false); + UartReg_EnableTxDMA(obj->reg, false); + break; + + case UARTDRV_DMA_SELECTION_TX_EN_RX_DIS: + UartReg_EnableRxDMA(obj->reg, false); + UartReg_EnableTxDMA(obj->reg, true); + break; + + case UARTDRV_DMA_SELECTION_TX_DIS_RX_EN: + UartReg_EnableRxDMA(obj->reg, true); + UartReg_EnableTxDMA(obj->reg, false); + break; + + case UARTDRV_DMA_SELECTION_TX_EN_RX_EN: + UartReg_EnableRxDMA(obj->reg, true); + UartReg_EnableTxDMA(obj->reg, true); + break; + + default: + UartReg_EnableRxDMA(obj->reg, false); + UartReg_EnableTxDMA(obj->reg, false); + break; + } + } + else + { + UartReg_EnableRxDMA(obj->reg, false); + UartReg_EnableTxDMA(obj->reg, false); + } +} + +/*! \brief Transmit one data + * + * This function write one data to tx fifo + * + * \param[in] obj :pointer to UART driver instance + * \param[in] txDatabuf : the copy of data to be sent + * \return: void + */ +void UartDrv_TxData(UartDrvType *obj, uint16_t txData) +{ + UartReg_TxData(obj->reg, txData); +} + +/*! \brief Read out from the rx buffer to the specific address and indicated how + * + * This function read out received datas from rx fifo + * + * \param[in] obj : pointer to UART driver instance + * \return: read-out value , if PE or FE or NF, return UARTDRV_READ_DATA_INVALID + */ +uint16_t UartDrv_RxData(const UartDrvType *obj) +{ + uint16_t tRtn = UARTDRV_READ_DATA_INVALID; + + uint32_t tRegValue = obj->reg->RDR; + + if((tRegValue & UART_RDR_ERR_MASK) == 0u) + { + tRtn = (((tRegValue & UART_RDR_RDR_MASK) >> UART_RDR_RDR_SHIFT) & 0x1FF); + } + + return tRtn; +} + +/*! \brief Read out the current status flag + * + * This function Get the expected status + * + * \param[in] obj : pointer to UART driver instance + * \param[in] status: which status want to get + * \return : bool + * FALSE: + * TRUE: some event happend + */ +bool UartDrv_GetStatus(const UartDrvType *obj, UartDrv_StatusType status) +{ + bool tRtn = false; + + uint32_t tRegValue = 0; + + if(status <= UARTDRV_STATUS_RWU) + { + /* FIFO */ + if((status == UARTDRV_STATUS_RXUF) || (status == UARTDRV_STATUS_TXOF)) + { + if(status == UARTDRV_STATUS_RXUF) + { + tRtn = UartReg_GetRxUnderflowFlag(obj->reg); + } + else + { + tRtn = UartReg_GetTxOverflowFlag(obj->reg); + } + } + else + { + /* ISR */ + tRegValue = obj->reg->ISR; + + if((tRegValue & status) != 0u) + { + tRtn = true; + } + } + } + else if(status <= UARTDRV_STATUS_RX_EMPTY) + { + tRegValue = obj->reg->FIFO; + + if(status == UARTDRV_STATUS_RX_EMPTY) + { + if((tRegValue & UART_FIFO_RXEMPT_MASK) != 0u) + { + tRtn = true; + } + } + else + { + if((tRegValue & UART_FIFO_TXEMPT_MASK) != 0u) + { + tRtn = true; + } + } + } + else + { + /* Nothing to do */ + } + + return tRtn; +} + +/*! \brief Clear the expected status + * + * This function clear the special status , can be combination with more than one status + * + * \param[in] obj : pointer to UART driver instance + * \param[in] status: can used the combination of the UartDrv_IsrStatusIdxType to clear more than one bit interrupt flag; + * for example: if want to clear PE&FE: (UARTDRV_STATUS_RXUF | UART_STATUS_PE) + * \return: void + */ +void UartDrv_ClearStatus(UartDrvType *obj, uint32_t status) +{ + /* FIFO */ + if(((status & UARTDRV_STATUS_RXUF) != 0ul) || ((status & UARTDRV_STATUS_TXOF) != 0ul)) + { + if((status & UARTDRV_STATUS_TXOF) != 0ul) + { + UartReg_ClearTxOverflowFlag(obj->reg); + } + else + { + UartReg_ClearRxUnderflowFlag(obj->reg); + } + } + else if((status & UARTDRV_STATUS_ABRE) != 0ul) + { + UartReg_ReqAutoBaudRate(obj->reg); + } + else if((status & UARTDRV_STATUS_LBDT_FAIL) != 0ul) + { + UartReg_ClearLinBreakDetectedResultFlag(obj->reg); + } + else + { + /* ISR */ + obj->reg->ICR = (uint32_t)status; + } +} + +/*! \brief Enable or Disable one or more than one interrupt source + * + * This function set the interrupt request action if condition matched + * + * \param[in] obj :pointer to UART driver instance + * \param[in] isrSrc :can used the more than one interrupt source once + * \param[in] isrEn :True(Enable) or false(Disable) + * \return: void + */ +void UartDrv_SetInterruptReq(UartDrvType *obj, uint32_t isrSrc, bool isrEn) +{ + /* Tx interrupt configuration */ + /* Transmit overflow */ + if((isrSrc & UARTDRV_ISR_SRC_TX_OVERFLOW) != 0u) + { + UartReg_SetTxOverflowIsr(obj->reg, isrEn); + } + + /* Transmit data register empty */ + if((isrSrc & UARTDRV_ISR_SRC_TX_EMPTY) != 0u) + { + UartReg_SetTxBufferEmptyIsr(obj->reg, isrEn); + } + /* Transmission Complete */ + if((isrSrc & UARTDRV_ISR_SRC_TX_COMPLETE) != 0u) + { + UartReg_SetTxCompletedIsr(obj->reg, isrEn); + } + /* Send break done flag */ + if((isrSrc & UARTDRV_ISR_SRC_TX_SYNC_BREAK) != 0u) + { + UartReg_SetBreakTxCompletedIsr(obj->reg, isrEn); + } + + /* Rx interrupt configuration */ + /* Receive under flow */ + if((isrSrc & UARTDRV_ISR_SRC_RX_UNDERFLOW) != 0u) + { + UartReg_SetRxUnderflowIsr(obj->reg, isrEn); + } + + /* Receive Data Register Full */ + if((isrSrc & UARTDRV_ISR_SRC_RX_FULL) != 0u) + { + UartReg_SetRxBufferFullIsr(obj->reg, isrEn); + } + + /* Receiver timeout */ + if((isrSrc & UARTDRV_ISR_SRC_RX_TIMEOUT) != 0u) + { + UartReg_SetRxTimeoutIsr(obj->reg, isrEn); + } + + /* LIN Break Detect Done */ + if((isrSrc & UARTDRV_ISR_SRC_RX_SYNC_BREAK) != 0u) + { + UartReg_SetLinBreakDetectedIsr(obj->reg, isrEn); + } + + /* Idle line detected */ + if((isrSrc & UARTDRV_ISR_SRC_RX_IDLE) != 0u) + { + UartReg_SetIdleIsr(obj->reg, isrEn); + } + + /* CTS */ + if((isrSrc & UARTDRV_ISR_SRC_RX_CTS) != 0u) + { + UartReg_SetCtsIsr(obj->reg, isrEn); + } + + /* Err interrupt configuration */ + /* Parity error */ + if((isrSrc & UARTDRV_ISR_SRC_ERR_PARITY) != 0u) + { + UartReg_SetParityErrIsr(obj->reg, isrEn); + } + + /* One of the frame err or noise err or over run err */ + if(((isrSrc & UARTDRV_ISR_SRC_ERR_FRAME) != 0u) || ((isrSrc & UARTDRV_ISR_SRC_ERR_NOISE) != 0u) || ((isrSrc & UARTDRV_ISR_SRC_ERR_OVER_RUN) != 0u)) + { + UartReg_SetErrIsr(obj->reg, isrEn); + } +} + +/*! \brief Get one interrupt source is enable or disable + * + * This function gets one interrupt source is enable or disable + * + * \param[in] obj :pointer to UART driver instance + * \param[in] isrType :one interrupt source type + * \return: True(Enable) or false(Disable) + */ +bool UartDrv_IsInterruptEnabled(UartDrvType *obj, UartDrv_IsrSrcType isrType) +{ + bool bRet = false; + + switch(isrType) + { + case UARTDRV_ISR_SRC_TX_OVERFLOW: + bRet = UartReg_GetTxOverflowIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_TX_EMPTY: + bRet = UartReg_GetTxBufferEmptyIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_TX_COMPLETE: + bRet = UartReg_GetTxCompletedIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_TX_SYNC_BREAK: + bRet = UartReg_GetBreakTxCompletedIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_RX_UNDERFLOW: + bRet = UartReg_GetRxUnderflowIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_RX_FULL: + bRet = UartReg_GetRxBufferFullIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_RX_TIMEOUT: + bRet = UartReg_GetRxTimeoutIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_RX_SYNC_BREAK: + bRet = UartReg_GetLinBreakDetectedIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_RX_IDLE: + bRet = UartReg_GetIdleIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_RX_CTS: + bRet = UartReg_GetCtsIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_ERR_PARITY: + bRet = UartReg_GetParityErrIsrIsEnabled(obj->reg); + break; + case UARTDRV_ISR_SRC_ERR_FRAME: + case UARTDRV_ISR_SRC_ERR_NOISE: + case UARTDRV_ISR_SRC_ERR_OVER_RUN: + bRet = UartReg_GetErrIsrIsEnabled(obj->reg); + break; + default: + break; + } + + return bRet; +} + +/*! \brief Get default configures the UART module for configuration structure + * + * This function gets default configures the UART module for user configuration structure + * + * \param[out] userConfig : pointer to configuration structure + * \return: void + */ +void UartDrv_GetDefaultConfig(UartDrv_InitCfgType *pInitCfg) +{ + pInitCfg->basicParameters.baudRate = 19200; + pInitCfg->basicParameters.dataBitsNum = UARTDRV_DATA_BITS_NUM_8; + pInitCfg->basicParameters.stopBitsNum = UARTDRV_STOP_BITS_NUM_1; + pInitCfg->basicParameters.dataShiftDirection = UARTDRV_DATA_SHIFT_DIRECTION_LSB; + pInitCfg->basicParameters.paritySelection = UARTDRV_PARITY_SELECT_UNUSED; + pInitCfg->basicParameters.oneSampleBitMethod = UARTDRV_ONE_SAMPLE_BIT_METHOD_IN_3BITS; + pInitCfg->basicParameters.overSamplingMode = UARTDRV_OVERSAMPLING_MODE_BY_16; + pInitCfg->basicParameters.dataTransferDirect = UARTDRV_DATA_TRANSFER_TX_RX_EN; + + pInitCfg->extendParameters.addrDetectMode = UARTDRV_ADDR_DETECTION_MODE_ALL_BITS; + pInitCfg->extendParameters.addrMarkDetectValue = 0x55; + pInitCfg->extendParameters.idleCharNums = UARTDRV_IDLE_CHAR_NUM_4; + pInitCfg->extendParameters.wakeSrc = UARTDRV_WAKE_SOURCE_IDLE_LINE; + pInitCfg->extendParameters.rxTimeoutBitsCnt = 0x00FF; + + pInitCfg->extendParameters.breakFieldSyncBreakTxBitsNum = UARTDRV_BREAK_FIELD_SYNC_BREAK_TX_BITS_NUM_13; + pInitCfg->extendParameters.breakFieldDelimiterTxBitsNum = UARTDRV_BREAK_FIELD_DELIMITER_TX_BITS_NUM_1; + pInitCfg->extendParameters.syncBreakRxBitsNum = UARTDRV_LIN_SYNC_BREAK_RX_BITS_NUM_11; + + pInitCfg->extendParameters.autoBaudRateMode = UARTDRV_AUTO_BAUDRATE_MODE_0; + + pInitCfg->extendParameters.dmaSelection = UARTDRV_DMA_SELECTION_TX_RX_DIS; + + pInitCfg->extendParameters.driverEnAssertionTime = 4; + pInitCfg->extendParameters.driverEnDeassertionTime = 2; + pInitCfg->extendParameters.driverEnablePolarityActiveInLow = true; + + pInitCfg->extendFeatures.wakeUpEn = false; + pInitCfg->extendFeatures.dmaEn = false; + pInitCfg->extendFeatures.autoBaudRateDetectionEn = false; + pInitCfg->extendFeatures.rxInvertEn = false; + pInitCfg->extendFeatures.txInvertEn = false; + pInitCfg->extendFeatures.dataInvertEn = false; + pInitCfg->extendFeatures.loopEn = false; + pInitCfg->extendFeatures.cosplayer = UARTDRV_COSPLAY_UART; +} + +/*! \brief Set the config for the uart module + * + * This function initializes the run-time state structure to provide for module configuration + * + * \param[in] obj :pointer to UART driver instance + * \param[in] pInitCfg :the pointer to the user configuration + * \return: void + */ +void UartDrv_SetConfig(UartDrvType *obj, const UartDrv_InitCfgType *pInitCfg) +{ + /* Disable Uart Module to make sure that some register be configured successfully */ + UartReg_EnableModule(obj->reg, false); + + /* Clear tx&rx fifo */ + UartReg_FlushTxFifo(obj->reg); + + UartReg_FlushRxFifo(obj->reg); + + UartDrv_InitBasicParameters(obj, &pInitCfg->basicParameters); + + UartDrv_InitExtendParameters(obj, &pInitCfg->extendParameters, &pInitCfg->extendFeatures); + + /* Enable Uart module */ + UartReg_EnableModule(obj->reg, true); + + /* Clear all Interrupt status or flag, avoid to enter interrupt routines only in Module is enabled */ + UartDrv_ClearStatus(obj, UARTDRV_STATUS_ISR_ALL); +} + +/*! \brief Enable or disable the uart module + * + * This function enables or disables the uart module + * + * \param[in] obj :pointer to UART driver instance + * \param[in] isEnable: + * 0: UART disabled + * 1: UART enabled + * \return: void + */ +void UartDrv_EnableModule(UartDrvType *obj, bool isEnable) +{ + /* Enable or disable Uart module */ + UartReg_EnableModule(obj->reg, isEnable); +} + +/*! \brief Get received data number in Rx FIFO + * + * This function gets received data number in Rx FIFO + * + * \param[in] obj : pointer to UART driver instance + * \return : data counter in Rx FIFO + */ +uint8_t UartDrv_GetRxCounter(const UartDrvType *obj) +{ + return UartReg_GetRxCounter(obj->reg); +} + +/*! \brief Get wait to transmit data number in Tx FIFO + * + * This function gets wait to transmit data number in Tx FIFO + * + * \param[in] obj : pointer to UART driver instance + * \return : data counter in Tx FIFO + */ +uint8_t UartDrv_GetTxCounter(const UartDrvType *obj) +{ + return UartReg_GetTxCounter(obj->reg); +} + +/*! \brief clear all data of Tx FIFO + * + * This function clears all data of Tx FIFO + * + * \param[in] obj : pointer to UART driver instance + */ +void UartDrv_ClearTxFifo(const UartDrvType *obj) +{ + /* Clear tx fifo */ + UartReg_FlushTxFifo(obj->reg); +} + +/*! \brief clear all data of Rx FIFO + * + * This function clears all data of Rx FIFO + * + * \param[in] obj : pointer to UART driver instance + */ +void UartDrv_ClearRxFifo(const UartDrvType *obj) +{ + /* Clear rx fifo */ + UartReg_FlushRxFifo(obj->reg); +} + +/*! \brief Set the threshold value of Rx FIFO + * + * This function sets the threshold value of Rx FIFO + * + * \param[in] obj : pointer to the instance + * \param[in] txWater : threshold value (range 0 to 3) + * \return : void + */ +void UartDrv_SetRxWater(const UartDrvType *obj, uint8_t rxWater) +{ + if(true == UartReg_GetEnable(obj->reg)) + { + UartReg_EnableModule(obj->reg, false); + UartReg_SetRxWater(obj->reg, rxWater); + UartReg_EnableModule(obj->reg, true); + } + else + { + UartReg_SetRxWater(obj->reg, rxWater); + } +} + +/*! \brief Set the threshold value of Tx FIFO + * + * This function sets the threshold value of Tx FIFO + * + * \param[in] obj : pointer to the instance + * \param[in] txWater : threshold value (range 0 to 3) + * \return : void + */ +void UartDrv_SetTxWater(const UartDrvType *obj, uint8_t txWater) +{ + if(true == UartReg_GetEnable(obj->reg)) + { + UartReg_EnableModule(obj->reg, false); + UartReg_SetTxWater(obj->reg, txWater); + UartReg_EnableModule(obj->reg, true); + } + else + { + UartReg_SetTxWater(obj->reg, txWater); + } +} + +/*! \brief Send lin sync break field + * + * This function sends lin sync break field + * + * \param[in] obj : pointer to UART driver instance + * \return : void + */ +void UartDrv_SendLinBreakField(const UartDrvType *obj) +{ + UartReg_ReqTxBreak(obj->reg); +} + +/*! \brief Enable or disable the Line break detect + * + * This function enables or disables the Line break detect + * + * \param[in] obj :pointer to UART driver instance + * \param[in] isEnable: + * 0: Line break detect disable + * 1: Line break detect enable + * \return: void + */ +void UartDrv_EnableLineBreakDetect(const UartDrvType *obj, bool isEnable) +{ + UartReg_EnableLineBreakDetectFeature(obj->reg, isEnable); +} + +/*! \brief Initializes the UART driver module + * + * This function initializes UART driver by setting the register instance to it. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] reg : pointer to UART register instance + * \return: void + */ +void UartDrv_Init(UartDrvType *obj, UartRegType *pReg) +{ + obj->reg = pReg; + + /* Clear tx&rx fifo */ + UartReg_FlushTxFifo(obj->reg); + + UartReg_FlushRxFifo(obj->reg); + + obj->reg->CR1 = 0; +} + +/*! \brief DeInit the uart module to default + * + * This function call back in the usage of low power or sleep requirements + * + * \param[in] obj : pointer to UART driver instance + * \return: void + */ +void UartDrv_DeInit(UartDrvType *obj) +{ + /* Clear all Interrupt status or flag, avoid to enter interrupt routines only in Module is enabled */ + UartDrv_ClearStatus(obj, UARTDRV_STATUS_ISR_ALL); + + /* Disable all Interrupt enable bit */ + UartDrv_SetInterruptReq(obj, UARTDRV_ISR_SRC_ALL, false); + + /* Clear tx&rx fifo */ + UartReg_FlushTxFifo(obj->reg); + UartReg_FlushRxFifo(obj->reg); + + /* Disable module */ + UartReg_EnableModule(obj->reg, false); +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/uart/uart_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/uart/uart_drv.h new file mode 100644 index 0000000..54d9b2f --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/uart/uart_drv.h @@ -0,0 +1,496 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UARTDRV_DRV_H_ +#define _UARTDRV_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of UART module + */ + +/****************************************************************************** + * the includes + *****************************************************************************/ + +#include +#include +#include "uart_reg.h" + +/*! \addtogroup uart_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * the defines + *****************************************************************************/ + +#define UARTDRV_BRR_LOW_4BITS_MASK (0x0000000Fu) +#define UARTDRV_READ_DATA_INVALID (0xFFFFul) +#define UARTDRV_BRAUD_RATE_INVALID (0xFFFFFFFF) + +/****************************************************************************** + * the typedefs + *****************************************************************************/ + +/*! \brief Word length */ +typedef enum +{ + UARTDRV_DATA_BITS_NUM_8 = 0x00u, /*!< 1 Start bit, 8 data bits, n stop bits */ + UARTDRV_DATA_BITS_NUM_9 /*!< 1 Start bit, 9 data bits, n stop bits */ +} UartDrv_DataBitsNumType; + +/*! \brief stop bits setting */ +typedef enum +{ + UARTDRV_STOP_BITS_NUM_1 = 0x00u, /*!< 1 stop bit */ + UARTDRV_STOP_BITS_NUM_2 /*!< 2 stop bits */ +} UartDrv_StopBitsNumType; + +/*! \brief transfer data bit sequeue */ +typedef enum +{ + UARTDRV_DATA_SHIFT_DIRECTION_LSB = 0x00u, /*!< data is transmitted/received with data bit 0 first, following the start bit. */ + UARTDRV_DATA_SHIFT_DIRECTION_MSB /*!< data is transmitted/received with the MSB (bit 7/8/9) first, following the start bit. */ +} UartDrv_DataShiftDirectionType; + +/*! \brief parity selection */ +typedef enum +{ + UARTDRV_PARITY_SELECT_EVEN = 0x00u, /*!< Even parity */ + UARTDRV_PARITY_SELECT_ODD, /*!< Odd parity */ + UARTDRV_PARITY_SELECT_UNUSED /*!< Parity check feature is not used */ +} UartDrv_ParitySelectionType; + +/*! \brief Transfer mode usage */ +typedef enum +{ + UARTDRV_DATA_TRANSFER_TX_RX_DIS = 0x00u, /*!< Transfer is not in tx&rx */ + UARTDRV_DATA_TRANSFER_TX_ONLY, /*!< Transfer is in tx */ + UARTDRV_DATA_TRANSFER_RX_ONLY, /*!< Transfer is in rx*/ + UARTDRV_DATA_TRANSFER_TX_RX_EN /*!< Transfer is in rx&tx */ +} UartDrv_DataTransferDirectType; + +/*! \brief Idle character nums */ +typedef enum +{ + UARTDRV_IDLE_CHAR_NUM_1 = 0x00u, /*!< 1 idle character */ + UARTDRV_IDLE_CHAR_NUM_2, /*!< 2 idle character */ + UARTDRV_IDLE_CHAR_NUM_4, /*!< 4 idle character */ + UARTDRV_IDLE_CHAR_NUM_8, /*!< 8 idle character */ + UARTDRV_IDLE_CHAR_NUM_16, /*!< 16 idle character */ + UARTDRV_IDLE_CHAR_NUM_32, /*!< 32 idle character */ + UARTDRV_IDLE_CHAR_NUM_64, /*!< 64 idle character */ + UARTDRV_IDLE_CHAR_NUM_128 /*!< 128 idle character */ +} UartDrv_IdleCharNumsType; + +/*! \brief wakeup source selection */ +typedef enum +{ + UARTDRV_WAKE_SOURCE_IDLE_LINE = 0x00u, /*!< Idle line */ + UARTDRV_WAKE_SOURCE_ADDRESS_MARK /*!< Address mark */ +} UartDrv_WakeSourceType; + +/*! \brief Oversampling mode */ +typedef enum +{ + UARTDRV_ONE_SAMPLE_BIT_METHOD_IN_3BITS = 0u, /*!< Three sample bit method */ + UARTDRV_ONE_SAMPLE_BIT_METHOD_IN_1BITS /*!< One sample bit method */ +} UartDrv_OneSampleBitMethod; + +/*! \brief oversampling mode */ +typedef enum +{ + UARTDRV_OVERSAMPLING_MODE_BY_16 = 0x00u, /*!< Oversampling by 16 */ + UARTDRV_OVERSAMPLING_MODE_BY_8 /*!< Oversampling by 8 */ +} UartDrv_OverSamplingModeType; + +/*! \brief Dma selection */ +typedef enum +{ + UARTDRV_DMA_SELECTION_TX_RX_DIS = 0x00u, /*!< DMA mode is disabled for tx&rx */ + UARTDRV_DMA_SELECTION_TX_EN_RX_DIS, /*!< DMA mode is enabled for tx */ + UARTDRV_DMA_SELECTION_TX_DIS_RX_EN, /*!< DMA mode is enabled for rx */ + UARTDRV_DMA_SELECTION_TX_EN_RX_EN /*!< DMA mode is enabled for tx&rx */ +} UartDrv_DmaSelectionType; + +/*! \brief Auto baudrate detect mode */ +typedef enum +{ + UARTDRV_AUTO_BAUDRATE_MODE_0 = 0x00u, /*!< Measurement of the start bit is used to detect the baud rate */ + UARTDRV_AUTO_BAUDRATE_MODE_1, /*!< Falling edge to falling edge measurement */ + UARTDRV_AUTO_BAUDRATE_MODE_2, /*!< 0x7F frame detection */ + UARTDRV_AUTO_BAUDRATE_MODE_3, /*!< 0x55 frame detection */ +} UartDrv_AutoBaudRateModeType; + +/*! \brief 7-bit Address Detection/4-bit Address Detection */ +typedef enum +{ + UARTDRV_ADDR_DETECTION_MODE_LOW_4BITS = 0x00u, /*!< 4-bit address detection */ + UARTDRV_ADDR_DETECTION_MODE_ALL_BITS /*!< 7-bit address detection (in 8-bit data mode) */ +} UartDrv_AddrDetectionModeType; + +/*! \brief Send the bits of the sync break signal(Low level) */ +typedef enum +{ + UARTDRV_BREAK_FIELD_SYNC_BREAK_TX_BITS_NUM_13 = 0x00u, /*!< - 13 bits */ + UARTDRV_BREAK_FIELD_SYNC_BREAK_TX_BITS_NUM_14, /*!< - 14 bits */ + UARTDRV_BREAK_FIELD_SYNC_BREAK_TX_BITS_NUM_15 /*!< - 15 bits */ +} UartDrv_BreakFieldSyncBreakTxBitsNumType; + +/*! \brief Send the bits of the delimiter (High level) */ +typedef enum +{ + UARTDRV_BREAK_FIELD_DELIMITER_TX_BITS_NUM_1 = 0x00u, /*!<- 1 bits */ + UARTDRV_BREAK_FIELD_DELIMITER_TX_BITS_NUM_2 /*!< - 2 bits */ +} UartDrv_BreakFieldDelimiterTxBitsNumType; + +/*! \brief LIN synch break detect length: */ +typedef enum +{ + UARTDRV_LIN_SYNC_BREAK_RX_BITS_NUM_11 = 0x00u, /*!< - 11 bits */ + UARTDRV_LIN_SYNC_BREAK_RX_BITS_NUM_12, /*!< - 12 bits */ + UARTDRV_LIN_SYNC_BREAK_RX_BITS_NUM_13 /*!< - 13 bits */ +} UartDrv_LinSyncBreakRxBitsNumType; + +typedef enum +{ + UARTDRV_COSPLAY_UART = 0x00u, + UARTDRV_COSPLAY_LIN, + UARTDRV_COSPLAY_RS232, + UARTDRV_COSPLAY_RS485 +} UartDrv_Cosplay; + +/*! \brief Interrupt source */ +typedef enum +{ + UARTDRV_ISR_SRC_TX_OVERFLOW = 0x01ul, + UARTDRV_ISR_SRC_TX_EMPTY = 0x02ul, + UARTDRV_ISR_SRC_TX_COMPLETE = 0x04ul, + UARTDRV_ISR_SRC_TX_SYNC_BREAK = 0x08ul, + + UARTDRV_ISR_SRC_RX_UNDERFLOW = 0x10ul, + UARTDRV_ISR_SRC_RX_FULL = 0x20ul, + UARTDRV_ISR_SRC_RX_TIMEOUT = 0x40ul, + UARTDRV_ISR_SRC_RX_SYNC_BREAK = 0x80ul, + UARTDRV_ISR_SRC_RX_IDLE = 0x100ul, + UARTDRV_ISR_SRC_RX_CTS = 0x200ul, + + UARTDRV_ISR_SRC_ERR_PARITY = 0x400ul, + UARTDRV_ISR_SRC_ERR_FRAME = 0x800ul, + UARTDRV_ISR_SRC_ERR_NOISE = 0x1000ul, + UARTDRV_ISR_SRC_ERR_OVER_RUN = 0x2000ul, + UARTDRV_ISR_SRC_ERR_ALL = 0x4000ul, + + UARTDRV_ISR_SRC_ALL = 0xFFFFFFFF +} UartDrv_IsrSrcType; + +/*! \brief Status flag */ +typedef enum +{ + UARTDRV_STATUS_PE = 0x01ul, + UARTDRV_STATUS_FE = 0x02ul, + UARTDRV_STATUS_NF = 0x04ul, + UARTDRV_STATUS_ORE = 0x08ul, + UARTDRV_STATUS_IDLE = 0x10ul, + UARTDRV_STATUS_RDRF = 0x20ul, + UARTDRV_STATUS_TC = 0x40ul, + UARTDRV_STATUS_TDRE = 0x80ul, + UARTDRV_STATUS_LBDT_DONE = 0x100ul, + UARTDRV_STATUS_CTSIF = 0x200ul, + UARTDRV_STATUS_CTS = 0x400ul, + UARTDRV_STATUS_RTOF = 0x800ul, + UARTDRV_STATUS_RXUF = 0x1000ul, + UARTDRV_STATUS_TXOF = 0x2000ul, + UARTDRV_STATUS_ABRE = 0x4000ul, + UARTDRV_STATUS_ABRF = 0x8000ul, + UARTDRV_STATUS_BUSY = 0x10000ul, + UARTDRV_STATUS_LBDT_FAIL = 0x20000ul, + UARTDRV_STATUS_SBRKD = 0x40000ul, + UARTDRV_STATUS_ISR_ALL = 0xFFFFCFFF, + UARTDRV_STATUS_RWU = 0x80000ul, + UARTDRV_STATUS_TX_EMPTY = 0x100000ul, + UARTDRV_STATUS_RX_EMPTY = 0x200000ul +} UartDrv_StatusType; + +/*! \brief Basic parameters for the basic features */ +typedef struct _UartDrv_BasicParametersType_ +{ + uint32_t busClockFreq; + uint32_t baudRate; + UartDrv_DataBitsNumType dataBitsNum; + UartDrv_StopBitsNumType stopBitsNum; + UartDrv_DataShiftDirectionType dataShiftDirection; + UartDrv_ParitySelectionType paritySelection; + UartDrv_OneSampleBitMethod oneSampleBitMethod; + UartDrv_OverSamplingModeType overSamplingMode; + UartDrv_DataTransferDirectType dataTransferDirect; +} UartDrv_BasicParametersType; + +/*! \brief advanced parameters for the advance features if used */ +typedef struct _UartDrv_ExtendParametersType_ +{ + UartDrv_AutoBaudRateModeType autoBaudRateMode; + UartDrv_DmaSelectionType dmaSelection; + UartDrv_AddrDetectionModeType addrDetectMode; + UartDrv_WakeSourceType wakeSrc; + UartDrv_BreakFieldSyncBreakTxBitsNumType breakFieldSyncBreakTxBitsNum; + UartDrv_BreakFieldDelimiterTxBitsNumType breakFieldDelimiterTxBitsNum; + UartDrv_LinSyncBreakRxBitsNumType syncBreakRxBitsNum; + UartDrv_IdleCharNumsType idleCharNums; + uint32_t rxTimeoutBitsCnt; + uint8_t addrMarkDetectValue; + uint8_t driverEnDeassertionTime; + uint8_t driverEnAssertionTime; + bool driverEnablePolarityActiveInLow; +} UartDrv_ExtendParametersType; + +/*! \brief advance features if wanted to be used */ +typedef struct _UartDrv_ExtendFeaturesType_ +{ + bool dmaEn; + bool autoBaudRateDetectionEn; + bool rxInvertEn; + bool txInvertEn; + bool dataInvertEn; + bool loopEn; + bool wakeUpEn; + UartDrv_Cosplay cosplayer; +} UartDrv_ExtendFeaturesType; + +/*! \brief the initial configuration if used to be set */ +typedef struct _UartDrv_InitCfgType_ +{ + UartDrv_BasicParametersType basicParameters; + UartDrv_ExtendParametersType extendParameters; + UartDrv_ExtendFeaturesType extendFeatures; +} UartDrv_InitCfgType; + +/*! \brief uart instance pointer */ +typedef struct _UartDrvType_ +{ + UartRegType *reg; +} UartDrvType; + +/****************************************************************************** + * the globals + ******************************************************************************/ + +/****************************************************************************** + * the function prototypes + ******************************************************************************/ + +/*! \brief Get default configures the UART module for configuration structure + * + * This function gets default configures the UART module for user configuration structure + * + * \param[out] userConfig : pointer to configuration structure + * \return: void + */ +extern void UartDrv_GetDefaultConfig(UartDrv_InitCfgType *pInitCfg); + +/*! \brief Set the config for the uart module + * + * this function initializes the run-time state structure to provide for module configuration + * + * \param[in] obj : pointer to UART driver instance + * \param[in] pInitCfg :the pointer to the user configuration + * \return: void + */ +extern void UartDrv_SetConfig(UartDrvType *obj, const UartDrv_InitCfgType *pInitCfg); + +/*! \brief Enable or disable the uart module + * + * This function enables or disables the uart module + * + * \param[in] obj :pointer to UART driver instance + * \param[in] isEnable: + * 0: UART disabled + * 1: UART enabled + * \return: void + */ +extern void UartDrv_EnableModule(UartDrvType *obj, bool isEnable); + +/*! \brief Get received data number in Rx FIFO + * + * This function gets received data number in Rx FIFO + * + * \param[in] obj : pointer to UART driver instance + * \return : data counter in Rx FIFO + */ +extern uint8_t UartDrv_GetRxCounter(const UartDrvType *obj); + +/*! \brief Get wait to transmit data number in Tx FIFO + * + * This function gets wait to transmit data number in Tx FIFO + * + * \param[in] obj : pointer to UART driver instance + * \return : data counter in Tx FIFO + */ +extern uint8_t UartDrv_GetTxCounter(const UartDrvType *obj); + +/*! \brief clear all data of Tx FIFO + * + * This function clears all data of Tx FIFO + * + * \param[in] obj : pointer to UART driver instance + */ +extern void UartDrv_ClearTxFifo(const UartDrvType *obj); + +/*! \brief clear all data of Rx FIFO + * + * This function clears all data of Rx FIFO + * + * \param[in] obj : pointer to UART driver instance + */ +extern void UartDrv_ClearRxFifo(const UartDrvType *obj); + +/*! \brief Set the threshold value of Rx FIFO + * + * This function sets the threshold value of Rx FIFO + * + * \param[in] obj : pointer to the instance + * \param[in] txWater : threshold value (range 0 to 3) + * \return : void + */ +extern void UartDrv_SetRxWater(const UartDrvType *obj, uint8_t rxWater); + +/*! \brief Set the threshold value of Tx FIFO + * + * This function sets the threshold value of Tx FIFO + * + * \param[in] obj : pointer to the instance + * \param[in] txWater : threshold value (range 0 to 3) + * \return : void + */ +extern void UartDrv_SetTxWater(const UartDrvType *obj, uint8_t txWater); + +/*! \brief Send lin sync break field + * + * This function sends lin sync break field + * + * \param[in] obj : pointer to UART driver instance + * \return : void + */ +extern void UartDrv_SendLinBreakField(const UartDrvType *obj); + +/*! \brief Enable or disable the Line break detect + * + * This function enables or disables the Line break detect + * + * \param[in] obj :pointer to UART driver instance + * \param[in] isEnable: + * 0: Line break detect disable + * 1: Line break detect enable + * \return: void + */ +extern void UartDrv_EnableLineBreakDetect(const UartDrvType *obj, bool isEnable); + +/*! \brief Initializes the UART driver module + * + * This function initializes UART driver by setting the register instance to it. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] reg : pointer to UART register instance + * \return: void + */ +extern void UartDrv_Init(UartDrvType *obj, UartRegType *pReg); + +/*! \brief DeInit the uart module to default + * + * Call back in the usage of low power or sleep requirements + * + * \param[in] obj :pointer to UART driver instance + * \return: void + */ +extern void UartDrv_DeInit(UartDrvType *obj); + +/*! \brief Read out from the rx buffer to the specific address and indicated how + * + * this function read out received datas from rx fifo + * + * \param[in] obj : pointer to UART driver instance + * \return: uint16_t : + * read-out value , if PE or FE or NF, return UARTDRV_READ_DATA_INVALID + */ +extern uint16_t UartDrv_RxData(const UartDrvType *obj); + +/*! \brief Transmit one data + * + * This function write one data to tx fifo + * + * \param[in] obj :pointer to UART driver instance + * \param[in] txDatabuf : the copy of data to be sent + * \return: void + */ +extern void UartDrv_TxData(UartDrvType *obj, uint16_t txDatabuf); + +/*! \brief Read out the current status flag + * + * This function get the expected status + * + * \param[in] obj : pointer to UART driver instance + * \param[in] status : which status want to get + * \return None + * - FALSE: + * - TRUE: some event happend + */ +extern bool UartDrv_GetStatus(const UartDrvType *obj, UartDrv_StatusType status); + +/*! \brief Clear the expected status + * + * This function clear the special status , can be conbination with more than one status + * + * \param[in] obj : pointer to UART driver instance + * \param[in] status : can used the combination of the UartDrv_IsrStatusIdxType + * to clear more than one bit interrupt flag; + * for example: if want to clear PE&FE: (UARTDRV_STATUS_RXUF | UARTDRV_STATUS_STATUS_PE) + * \return: void + */ +extern void UartDrv_ClearStatus(UartDrvType *obj, uint32_t status); + +/*! \brief Enable or Disable one or more than one interrupt source + * + * This function set the interrupt request action if condition matched + * + * \param[in] obj :pointer to UART driver instance + * \param[in] isrSrc : can used the more than one interrupt source once + * \param[in] isrEn : True(Enable) or false(Disable) + * \return: void + */ +extern void UartDrv_SetInterruptReq(UartDrvType *obj, uint32_t isrSrc, bool isrEn); + +/*! \brief Get one interrupt source is enable or disable + * + * This function gets one interrupt source is enable or disable + * + * \param[in] obj :pointer to UART driver instance + * \param[in] isrType :one interrupt source type + * \return: True(Enable) or false(Disable) + */ +extern bool UartDrv_IsInterruptEnabled(UartDrvType *obj, UartDrv_IsrSrcType isrType); + + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/wdg/wdg_drv.c b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/wdg/wdg_drv.c new file mode 100644 index 0000000..af686ee --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/wdg/wdg_drv.c @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "wdg_drv.h" +#include "wdg_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define WDGDRV_REFRESH_VALUE (0xB480A602U) /* refresh wdg counter value */ +#define WDGDRV_UNLOCK_VALUE (0xD928C520U) /* unlock wdg reg */ +#define WDGDRV_TO_RESET_VALUE (0xFFFFU) /* the wdg TOVAL configuration default value */ +#define WDGDRV_WIN_RESET_VALUE (0x0U) /* the wdg WIN configuration default value */ +#define WDGDRV_CLEAR_INT_FLAG_VALUE (0x1U) /* W1C, the wdg clear interrupt flag value */ + +/* Unlock WDG register */ +#define WDGDRV_UNLOCK(x) ((x)->CNT = WDGDRV_UNLOCK_VALUE) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void WdgDrv_Init(WdgDrvType *obj, struct _WdgRegType_ *reg) +{ + obj->reg = reg; +} + +void WdgDrv_Configure(WdgDrvType *obj, const WdgDrv_ConfigureType *userConfig) +{ + uint8_t enable = WdgReg_IsEnabled(obj->reg); + uint8_t update = WdgReg_IsEnabledUpdate(obj->reg); + uint8_t csd = WdgReg_IsDoneConfigSync(obj->reg); + + if((enable == 0x0u) && (update == 0x01u) && (csd == 0x01u)) + { + /* Clear the bits used for configuration */ + WdgRegType preReg = {0}; + preReg.CS &= ~(WDG_CS_CLK_MASK + | WDG_CS_WIN_MASK + | WDG_CS_PRES_MASK + | WDG_CS_INTR_MASK + | WDG_CS_UPDATE_MASK + | WDG_CS_TST_MASK + | WDG_CS_DEBUG_MASK + | WDG_CS_STOP_MASK); + /* pre-configuration: Construct CS register new value */ + WdgReg_SetClockSource(&preReg, (uint8_t)userConfig->clkSource); + WdgReg_EnableWinMode(&preReg, userConfig->winEnable); + WdgReg_EnablePrescaler(&preReg, userConfig->prescalerEnable); + WdgReg_EnableInterrupt(&preReg, userConfig->intEnable); + WdgReg_EnableUpdate(&preReg, userConfig->updateEnable); + WdgReg_EnableDebugMode(&preReg, userConfig->debugModeEnable); + WdgReg_EnableStopMode(&preReg, userConfig->stopModeEnable); + WdgReg_ClearInterruptFlag(&preReg, userConfig->flag); + WdgReg_Enable(&preReg, userConfig->enable); + WdgReg_SetTestMode(&preReg, (uint8_t)userConfig->testMode); + /* configuration: Construct register new value */ + WDGDRV_UNLOCK(obj->reg); + obj->reg->CS = preReg.CS; + obj->reg->TOVAL = userConfig->timeoutValue; + while(!WdgReg_IsSuccessConfig(obj->reg)) + { + /* Wait until the reconfiguration successful */ + } + while(!WdgReg_IsDoneConfigSync(obj->reg)) + { + /* Wait until the synchronization of new configuration done */ + } + if(userConfig->winEnable) + { + WdgReg_SetCntVal(obj->reg, WDGDRV_REFRESH_VALUE); + WDGDRV_UNLOCK(obj->reg); + obj->reg->WIN = userConfig->windowValue; + while(!WdgReg_IsDoneConfigSync(obj->reg)) + { + /* Wait until the synchronization of new configuration done */ + } + } + } +} + +void WdgDrv_GetDefaultConfig(WdgDrv_ConfigureType *userConfig) +{ + userConfig->clkSource = WDGDRV_CLK_SRC_LPO128K; + userConfig->winEnable = 0x0u; + userConfig->flag = WDGDRV_CLEAR_INT_FLAG_VALUE; + userConfig->prescalerEnable = 0x0u; + userConfig->enable = 0x0u; + userConfig->intEnable = 0x0u; + userConfig->updateEnable = 0x1u; + userConfig->debugModeEnable = 0x0u; + userConfig->stopModeEnable = 0x0u; + userConfig->timeoutValue = WDGDRV_TO_RESET_VALUE; + userConfig->windowValue = WDGDRV_WIN_RESET_VALUE; + userConfig->testMode = WDGDRV_TEST_MODE_DISABLED; +} + +void WdgDrv_GetCurrentConfig(const WdgDrvType *obj, WdgDrv_ConfigureType *userConfig) +{ + userConfig->clkSource = (WdgDrv_ClkSrcType)WdgReg_GetClockSource(obj->reg); + userConfig->winEnable = WdgReg_IsEnabledWinMode(obj->reg); + userConfig->flag = WdgReg_GetInterruptFlag(obj->reg); + userConfig->prescalerEnable = WdgReg_IsEnabledPrescaler(obj->reg); + userConfig->enable = WdgReg_IsEnabled(obj->reg); + userConfig->intEnable = WdgReg_IsEnabledInterrupt(obj->reg); + userConfig->updateEnable = WdgReg_IsEnabledUpdate(obj->reg); + userConfig->debugModeEnable = WdgReg_IsEnabledDebugMode(obj->reg); + userConfig->stopModeEnable = WdgReg_IsEnabledStopMode(obj->reg); + userConfig->timeoutValue = WdgReg_GetToval(obj->reg); + userConfig->windowValue = WdgReg_GetWinVal(obj->reg); + userConfig->testMode = (WdgDrv_TestModeType)WdgReg_GetTestModeStatus(obj->reg); +} + +void WdgDrv_Enable(WdgDrvType *obj) +{ + uint8_t update = WdgReg_IsEnabledUpdate(obj->reg); + /* If allowed reconfigures WDG */ + if(update == 0x01u) + { + uint32_t csTmp = obj->reg->CS; + csTmp &= ~(WDG_CS_EN_MASK); + csTmp |= (((uint32_t)(((uint32_t)(true)) << WDG_CS_EN_SHIFT)) & WDG_CS_EN_MASK); + WDGDRV_UNLOCK(obj->reg); + obj->reg->CS = csTmp; + while(WdgReg_IsUnlocked(obj->reg)) + { + /* Wait until the unlock window closes */ + } + } +} + +void WdgDrv_Disable(WdgDrvType *obj) +{ + uint8_t update = WdgReg_IsEnabledUpdate(obj->reg); + /* If allowed reconfigures WDG */ + if(update == 0x01u) + { + WDGDRV_UNLOCK(obj->reg); + obj->reg->CS &= ~((uint32_t)WDG_CS_EN_MASK); + /* reset timeout value for the WDG */ + obj->reg->TOVAL = WDGDRV_TO_RESET_VALUE; + while(WdgReg_IsUnlocked(obj->reg)) + { + /* Wait until the unlock window closes */ + } + while(!WdgReg_IsDoneConfigSync(obj->reg)) + { + /* Wait until the synchronization of new configuration done */ + } + } +} + +void WdgDrv_SetInt(WdgDrvType *obj, bool enable) +{ + uint8_t update = WdgReg_IsEnabledUpdate(obj->reg); + /* If allowed reconfigures WDG */ + if(update == 0x01u) + { + uint32_t csTmp = obj->reg->CS; + csTmp &= ~(WDG_CS_INTR_MASK); + csTmp |= (((uint32_t)(((uint32_t)(enable)) << WDG_CS_INTR_SHIFT)) & WDG_CS_INTR_MASK); + WDGDRV_UNLOCK(obj->reg); + obj->reg->CS = csTmp; + while(WdgReg_IsUnlocked(obj->reg)) + { + /* Wait until the unlock window closes */ + } + } +} + +void WdgDrv_ClearIntFlag(WdgDrvType *obj) +{ + /* Clear interrupt flag of the WDG, W1C*/ + WDGDRV_UNLOCK(obj->reg); + WdgReg_ClearInterruptFlag(obj->reg, WDGDRV_CLEAR_INT_FLAG_VALUE); +} + +void WdgDrv_Refresh(WdgDrvType *obj) +{ + WdgReg_SetCntVal(obj->reg, WDGDRV_REFRESH_VALUE); +} + +uint32_t WdgDrv_GetCnt(const WdgDrvType *obj) +{ + return WdgReg_GetCntVal(obj->reg); +} + +void WdgDrv_SetWindow(WdgDrvType *obj, uint32_t winVal, bool enable) +{ + uint8_t update = WdgReg_IsEnabledUpdate(obj->reg); + /* If allowed reconfigures WDG */ + if(update == 0x01u) + { + uint32_t csTmp = obj->reg->CS; + csTmp &= ~(WDG_CS_WIN_MASK); + csTmp |= (((uint32_t)(((uint32_t)(enable)) << WDG_CS_WIN_SHIFT)) & WDG_CS_WIN_MASK); + WDGDRV_UNLOCK(obj->reg); + obj->reg->CS = csTmp; + /* Set window value for the WDG */ + obj->reg->WIN = winVal; + while(WdgReg_IsUnlocked(obj->reg)) + { + /* Wait until the unlock window closes */ + } + } +} + +void WdgDrv_SetStopMode(WdgDrvType *obj, bool enable) +{ + uint8_t update = WdgReg_IsEnabledUpdate(obj->reg); + /* If allowed reconfigures WDG */ + if(update == 0x01u) + { + uint32_t csTmp = obj->reg->CS; + csTmp &= ~(WDG_CS_STOP_MASK); + csTmp |= (((uint32_t)(((uint32_t)(enable)) << WDG_CS_STOP_SHIFT)) & WDG_CS_STOP_MASK); + WDGDRV_UNLOCK(obj->reg); + /* Set stop mode */ + obj->reg->CS = csTmp; + while(WdgReg_IsUnlocked(obj->reg)) + { + /* Wait until the unlock window closes */ + } + } +} + +void WdgDrv_SetTimeout(WdgDrvType *obj, uint32_t toval) +{ + uint8_t update = WdgReg_IsEnabledUpdate(obj->reg); + /* If allowed reconfigures WDG */ + if(update == 0x01u) + { + WDGDRV_UNLOCK(obj->reg); + /* Set timeout value for the WDG */ + WdgReg_SetToval(obj->reg, toval); + while(WdgReg_IsUnlocked(obj->reg)) + { + /* Wait until the unlock window closes */ + } + } +} + +void WdgDrv_SetTestMode(WdgDrvType *obj, WdgDrv_TestModeType type) +{ + uint8_t update = WdgReg_IsEnabledUpdate(obj->reg); + /* If allowed reconfigures WDG */ + if(update == 0x01u) + { + uint32_t csTmp = obj->reg->CS; + csTmp &= ~(WDG_CS_TST_MASK | WDG_CS_EN_MASK); + csTmp |= (((uint32_t)(((uint32_t)(type)) << WDG_CS_TST_SHIFT)) & WDG_CS_TST_MASK); + csTmp |= (((uint32_t)(((uint32_t)(1)) << WDG_CS_EN_SHIFT)) & WDG_CS_EN_MASK); + WDGDRV_UNLOCK(obj->reg); + /* Set test mode */ + obj->reg->CS = csTmp; + while(WdgReg_IsUnlocked(obj->reg)) + { + /* Wait until the unlock window closes */ + } + } +} + +WdgDrv_TestModeType WdgDrv_GetTestMode(const WdgDrvType *obj) +{ + /* Get test mode configuration type */ + uint8_t testModeType = WdgReg_GetTestModeStatus(obj->reg); + /* Gets test mode */ + return ((WdgDrv_TestModeType)testModeType); +} diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/wdg/wdg_drv.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/wdg/wdg_drv.h new file mode 100644 index 0000000..c11409f --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/drivers/wdg/wdg_drv.h @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _WDG_DRV_H_ +#define _WDG_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of WDG module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ +#include +#include + +/*! \addtogroup wdg_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Definition of mode options available for the clock source type + */ +typedef enum +{ + WDGDRV_CLK_SRC_BUS = 0x00U, /*!< Bus clock */ + WDGDRV_CLK_SRC_LPO128K = 0x01U, /*!< LPO128 clock */ + WDGDRV_CLK_SRC_SOSC = 0x02U, /*!< SOSC clock */ + WDGDRV_CLK_SRC_SIRC = 0x03U, /*!< SIRC clock */ + WDGDRV_CLK_SRC_LPO32K = 0x04U, /*!< LPO32 clock */ + WDGDRV_CLK_SRC_LPO1K = 0x05U, /*!< LPO1 clock */ +} WdgDrv_ClkSrcType; + +/*! \brief Definition of mode options available for the TEST mode + */ +typedef enum +{ + WDGDRV_TEST_MODE_DISABLED = 0x00U, /*!< Test mode disabled */ + WDGDRV_TEST_MODE_USER = 0x01U, /*!< User mode enabled. (Test mode disabled.) */ + WDGDRV_TEST_MODE_LOW = 0x02U, /*!< Test mode enabled, only the low byte is used. */ + WDGDRV_TEST_MODE_HIGH = 0x03U /*!< Test mode enabled, only the high byte is used. */ +} WdgDrv_TestModeType; + +/*! \brief Definition of configuration of WDG driver + */ +typedef struct _WdgDrv_ConfigureType_ +{ + WdgDrv_ClkSrcType clkSource; /*!< RW, The clock source of the WDOG */ + uint8_t winEnable; /*!< RW, If true, window mode is enabled */ + uint8_t flag; /*!< W1C, If true, clear wdg interrupt flag */ + uint8_t prescalerEnable; /*!< RW, If true, a fixed 256 prescaling of the counter reference clock is enabled */ + uint8_t enable; /*!< RW, If true, the WDOG are enabled */ + uint8_t intEnable; /*!< RW, If true, an interrupt request is generated before reset */ + uint8_t updateEnable; /*!< RW, If true, further updates of the WDOG are enabled */ + WdgDrv_TestModeType testMode; /*!< RW, Test mode */ + uint8_t debugModeEnable; /*!< RW, Debug mode */ + uint8_t stopModeEnable; /*!< RW, Stop mode */ + uint32_t windowValue; /*!< RW, The window value */ + uint32_t timeoutValue; /*!< RW, The timeout value */ + +} WdgDrv_ConfigureType; + +/*! \brief Forward declaration of WDG register + */ +struct _WdgRegType_; + +/*! \brief The definition of WDG driver class + */ +typedef struct _WdgDrvType_ +{ + struct _WdgRegType_ *reg; /*!< pointer to WDG register */ +} WdgDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the WDG driver module + * + * This function initializes WDG driver by setting the register + * instance to it. + * + * \param[in] obj : pointer to WDG driver instance + * \param[in] reg : pointer to WDG register instance + */ +extern void WdgDrv_Init(WdgDrvType *obj, struct _WdgRegType_ *reg); + +/*! \brief Get default configures the WDG module for configuration structure + * + * This function gets default configures the WDG module for user configuration structure + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void WdgDrv_GetDefaultConfig(WdgDrv_ConfigureType *userConfig); + +/*! \brief Configures the WDG module from a user configuration structure + * + * This function configures the WDG module from a user configuration structure + * + * \param[in] obj : pointer to WDG driver instance + * \param[in] userConfig : pointer to configuration structure + */ +extern void WdgDrv_Configure(WdgDrvType *obj, const WdgDrv_ConfigureType *userConfig); + +/*! \brief Get current configures the WDG module for configuration structure + * + * This function gets current configures the WDG module for user configuration structure + * + * \param[out] userConfig : pointer to configuration structure + */ +extern void WdgDrv_GetCurrentConfig(const WdgDrvType *obj, WdgDrv_ConfigureType *userConfig); + +/*! \brief Enable the WDG module currently + * + * This function enable the WDG module currently + * + * \param[in] obj : pointer to WDG driver instance + */ +extern void WdgDrv_Enable(WdgDrvType *obj); + +/*! \brief Disable the WDG module currently + * + * This function Disable the WDG module currently + * + * \param[in] obj : pointer to WDG driver instance + */ +extern void WdgDrv_Disable(WdgDrvType *obj); + +/*! + * \brief Enables/Disables the WDG Interrupt. + * + * This function enables/disables the WDG Interrupt. + * + * \param[in] obj : pointer to WDG driver instance + * \param[in] enable : enable/disable WDG Interrupt. + */ +extern void WdgDrv_SetInt(WdgDrvType *obj, bool enable); + +/*! + * \brief Clear the WDG Interrupt flag. + * + * This function Clear the WDG Interrupt flag. + * + * \param[in] obj : pointer to WDG driver instance + */ +extern void WdgDrv_ClearIntFlag(WdgDrvType *obj); + +/*! + * \brief refresh the WDG counter value. + * + * This function refresh the WDG counter. + * + * \param[in] obj : pointer to WDG driver instance + */ +extern void WdgDrv_Refresh(WdgDrvType *obj); + +/*! + * \brief Enables/Disables the WDG window mode. + * + * This function enables/Disables the WDG window mode. + * + * \param[in] obj : pointer to WDG driver instance + * \param[in] winVal : pointer to window value. + * \param[in] enable : enable/disable WDG Interrupt. + */ +extern void WdgDrv_SetWindow(WdgDrvType *obj, uint32_t winVal, bool enable); + +/*! + * \brief Enables/Disables the WDG stop mode. + * + * This function enables/disables the WDG stop mode. + * + * \param[in] obj : pointer to WDG driver instance + * \param[in] enable : enable/disable WDG stop mode. + */ +extern void WdgDrv_SetStopMode(WdgDrvType *obj, bool enable); + +/*! + * \brief set timeout value. + * + * This function set timeout value. + * + * \param[in] obj : pointer to WDG driver instance + * \param[in] toval : set timeout value. + */ +extern void WdgDrv_SetTimeout(WdgDrvType *obj, uint32_t toval); + +/*! + * \brief Sets the WDG test mode. + * + * This function sets the WDG test mode. + * + * \param[in] obj : pointer to WDG driver instance + * \param[in] type set WDG test mode. + * - 000b: watchdog test mode disable + * - 001b: watchdog user mode enable. (watchdog test mode disabled) + * - 010b: watchdog test mode enabled, only the low byte is used. + * - 011b: watchdog test mode enabled, only the high byte is used. + */ +extern void WdgDrv_SetTestMode(WdgDrvType *obj, WdgDrv_TestModeType type); + +/*! + * \brief Get type of the WDG test mode. + * + * This function get type of the WDG test mode. + * + * \param[in] obj : pointer to WDG driver instance + * \param[out] func : test mode type. + */ +extern WdgDrv_TestModeType WdgDrv_GetTestMode(const WdgDrvType *obj); + +/*! + * \brief Get value of the WDG counter. + * + * This function get value of the WDG counter. + * + * \param[in] obj : pointer to WDG driver instance + * \param[out] func : CNT value. + */ +extern uint32_t WdgDrv_GetCnt(const WdgDrvType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/linker/CVM0118_flash.icf b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/linker/CVM0118_flash.icf new file mode 100644 index 0000000..72d6c70 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/linker/CVM0118_flash.icf @@ -0,0 +1,117 @@ +/* +** ################################################################### +** Processor: CVM0118 +** Compiler: IAR ANSI C/C++ Compiler for ARM +** +** Abstract: +** Linker file for the IAR ANSI C/C++ Compiler for ARM +** +** Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD +** All rights reserved. +** +** Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use +** exclusively with CVA's microcontroller products. This file can be freely +** distributed within development tools that are supporting such microcontroller +** products. +** +** THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED +** OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. +** CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, +** OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +** +** http: www.cvachip.com +** +** ################################################################### +*/ + +/* If symbol __flash_vector_table__=1 is defined at link time + * the interrupt vector will not be copied to RAM. + * Warning: Using the interrupt vector from FLASH will not allow + * INT_SYS_InstallHandler because the section is Read Only. + */ +define symbol __ram_vector_table_size__ = isdefinedsymbol(__flash_vector_table__) ? 0 : 0x000000C0; +define symbol __ram_vector_table_offset__ = isdefinedsymbol(__flash_vector_table__) ? 0 : 0x00000000; + +/* Flash */ +define symbol m_interrupts_start = 0x00000000; +define symbol m_interrupts_end = 0x000000C0; + +define symbol m_flash_config_start = 0x00000400; +define symbol m_flash_config_end = 0x0000041F; + +define symbol m_text_start = 0x00000420; +define symbol m_text_end = 0x00037FFF; + +/* SRAM */ +define symbol m_interrupts_ram_start = 0x20000000; +define symbol m_interrupts_ram_end = 0x200003FF; + +define symbol m_data_start = 0x20000400; +define symbol m_data_end = 0x200033FF; + +define symbol m_data_2_start = 0x20003400; +define symbol m_data_2_end = 0x200063FF; + +/* Sizes */ +if (isdefinedsymbol(__stack_size__)) { + define symbol __size_cstack__ = __stack_size__; +} else { + define symbol __size_cstack__ = 0x00000200; +} + +if (isdefinedsymbol(__heap_size__)) { + define symbol __size_heap__ = __heap_size__; +} else { + define symbol __size_heap__ = 0x00000200; +} + +define exported symbol __VECTOR_TABLE = m_interrupts_start; +define exported symbol __VECTOR_RAM = isdefinedsymbol(__flash_vector_table__) ? m_interrupts_start : m_interrupts_ram_start; +define exported symbol __RAM_VECTOR_TABLE_SIZE = __ram_vector_table_size__; + +define exported symbol __RAM_START = m_interrupts_ram_start; +define exported symbol __RAM_END = m_data_2_end; + +define memory mem with size = 4G; +define region m_flash_config_region = mem:[from m_flash_config_start to m_flash_config_end]; +define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end] + | mem:[from m_text_start to m_text_end]; +define region DATA_region = mem:[from m_data_start to m_data_end]; +define region DATA_region_2 = mem:[from m_data_2_start to m_data_2_end-__size_cstack__]; +define region CSTACK_region = mem:[from m_data_2_end-__size_cstack__+1 to m_data_2_end]; +define region m_interrupts_ram_region = mem:[from m_interrupts_ram_start to m_interrupts_ram_end]; + + +define block CSTACK with alignment = 8, size = __size_cstack__ { }; +define block HEAP with alignment = 8, size = __size_heap__ { }; +define block RW { readwrite }; +define block ZI { zi }; + +/* Custom Section Block that can be used to place data at absolute address. */ +/* Use __attribute__((section (".customSection"))) to place data here. */ +define block customSectionBlock { section .customSection }; + +define block __CODE_ROM { section .textrw_init }; +define block __CODE_RAM { section .textrw }; + +initialize manually { section .textrw }; +initialize manually { section .bss }; +initialize manually { section .customSection }; +initialize manually { section .data }; +initialize manually { section __DLIB_PERTHREAD }; +do not initialize { section .noinit, section .bss, section .data, section __DLIB_PERTHREAD, section .customSection }; + +place at address mem: m_interrupts_start { readonly section .intvec }; +place in m_flash_config_region { section FlashConfig }; +place in TEXT_region { readonly }; +place in TEXT_region { block __CODE_ROM }; +place in DATA_region { block RW }; +place in DATA_region { block __CODE_RAM }; +place in DATA_region_2 { first block customSectionBlock }; +place in DATA_region_2 { block ZI }; +place in DATA_region_2 { last block HEAP }; +place in CSTACK_region { block CSTACK }; +place in m_interrupts_ram_region { section m_interrupts_ram }; + + diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/linker/CVM0118_ram.icf b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/linker/CVM0118_ram.icf new file mode 100644 index 0000000..7f5a3af --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/linker/CVM0118_ram.icf @@ -0,0 +1,93 @@ +/* +** ################################################################### +** Processor: CVM0118 +** Compiler: IAR ANSI C/C++ Compiler for ARM +** +** Abstract: +** Linker file for the IAR ANSI C/C++ Compiler for ARM +** +** Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD +** All rights reserved. +** +** Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use +** exclusively with CVA's microcontroller products. This file can be freely +** distributed within development tools that are supporting such microcontroller +** products. +** +** THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED +** OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. +** CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, +** OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +** +** http: www.cvachip.com +** +** ################################################################### +*/ + +/* SRAM_U */ +define symbol m_interrupts_start = 0x20000000; +define symbol m_interrupts_end = 0x200000BF; + +define symbol m_text_start = 0x200000C0; +define symbol m_text_end = 0x200030BF; + +define symbol m_custom_start = 0x200030C0; +define symbol m_custom_end = 0x200034BF; + +define symbol m_data_start = 0x200034C0; +define symbol m_data_end = 0x200063FF; + +/* Sizes */ +if (isdefinedsymbol(__stack_size__)) { + define symbol __size_cstack__ = __stack_size__; +} else { + define symbol __size_cstack__ = 0x00000200; +} + +if (isdefinedsymbol(__heap_size__)) { + define symbol __size_heap__ = __heap_size__; +} else { + define symbol __size_heap__ = 0x00000200; +} + +define exported symbol __VECTOR_TABLE = m_interrupts_start; +define exported symbol __VECTOR_RAM = m_interrupts_start; +define exported symbol __RAM_VECTOR_TABLE_SIZE = 0x0; + +define exported symbol __RAM_START = m_interrupts_start; +define exported symbol __RAM_END = m_data_end; + +define memory mem with size = 4G; +define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end] + | mem:[from m_text_start to m_text_end]; +define region DATA_region = mem:[from m_data_start to m_data_end-__size_cstack__]; +define region CSTACK_region = mem:[from m_data_end-__size_cstack__+1 to m_data_end]; + + +define block CSTACK with alignment = 8, size = __size_cstack__ { }; +define block HEAP with alignment = 8, size = __size_heap__ { }; +define block RW { readwrite }; +define block ZI { zi }; + +/* Custom Section Block that can be used to place data at absolute address. */ +/* Use __attribute__((section (".customSection"))) to place data here. */ +define block customSectionBlock { section .customSection }; +define block __CODE_RAM { section .textrw }; +define block __CODE_ROM { section .textrw_init }; + +initialize manually { section .bss }; +initialize manually { section .customSection }; +initialize manually { section .textrw }; +initialize manually { section __DLIB_PERTHREAD }; +do not initialize { section .noinit, section .bss, section __DLIB_PERTHREAD, section .customSection }; + +place at address mem: m_interrupts_start { readonly section .intvec }; +place in TEXT_region { readonly }; +place in TEXT_region { block __CODE_ROM }; +place in DATA_region { first block customSectionBlock }; +place in DATA_region { block RW }; +place in DATA_region { block __CODE_RAM }; +place in DATA_region { block ZI }; +place in DATA_region { last block HEAP }; +place in CSTACK_region { block CSTACK }; \ No newline at end of file diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/adc_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/adc_reg.h new file mode 100644 index 0000000..0477888 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/adc_reg.h @@ -0,0 +1,1284 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _ADC_REG_H_ +#define _ADC_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the ADC Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define ADC_REG_LOCK_KEY (0x0U) +#define ADC_REG_UNLOCK_KEY (0xA5D2C3C3U) + +/* Number of channels register for every ADC instance */ +#define ADC_REG_CH_COUNT (16U) + +/* CFG1 Bit Fields */ +#define ADC_CFG1_WITHOUT_W1C_MASK (0xFFFFFEFFu) +#define ADC_CFG1_CLRLTRG_MASK (0x100u) +#define ADC_CFG1_CLRLTRG_SHIFT (8u) +#define ADC_CFG1_CLRLTRG_WIDTH (1u) +#define ADC_CFG1_MODE_MASK (0x03u) +#define ADC_CFG1_MODE_SHIFT (0u) +#define ADC_CFG1_MODE_WIDTH (2u) + +/* CFG2 Bit Fields */ +#define ADC_CFG2_LEN_PWR_ON_MASK (0x3F0000u) +#define ADC_CFG2_LEN_PWR_ON_SHIFT (16u) +#define ADC_CFG2_LEN_PWR_ON_WIDTH (6u) +#define ADC_CFG2_LEN_SMPL_1ST_MASK (0xFF00u) +#define ADC_CFG2_LEN_SMPL_1ST_SHIFT (8u) +#define ADC_CFG2_LEN_SMPL_1ST_WIDTH (8u) +#define ADC_CFG2_LEN_SMPL_MASK (0xFFu) +#define ADC_CFG2_LEN_SMPL_SHIFT (0u) +#define ADC_CFG2_LEN_SMPL_WIDTH (8u) + +/* CV1 Bit Fields */ +#define ADC_CV1_CV_MASK (0xFFFFu) +#define ADC_CV1_CV_SHIFT (0u) +#define ADC_CV1_CV_WIDTH (16u) +#define ADC_CV2_CV_MASK (0xFFFFu) +#define ADC_CV2_CV_SHIFT (0u) +#define ADC_CV2_CV_WIDTH (16u) + +/* SC2 Bit Fields */ +#define ADC_SC2_WITHOUT_W1C_MASK (0xFFFFFFu) +#define ADC_SC2_TRGSTERR_MASK (0xF000000u) +#define ADC_SC2_TRGSTERR_SHIFT (24u) +#define ADC_SC2_TRGSTERR_WIDTH (4u) +#define ADC_SC2_TRGSTLAT_MASK (0xF0000u) +#define ADC_SC2_TRGSTLAT_SHIFT (16u) +#define ADC_SC2_TRGSTLAT_WIDTH (4u) +#define ADC_SC2_TRGPRNUM_MASK (0x6000u) +#define ADC_SC2_TRGPRNUM_SHIFT (13u) +#define ADC_SC2_TRGPRNUM_WIDTH (2u) +#define ADC_SC2_ADACT_MASK (0x80u) +#define ADC_SC2_ADACT_SHIFT (7u) +#define ADC_SC2_ADACT_WIDTH (1u) +#define ADC_SC2_ADTRG_MASK (0x40u) +#define ADC_SC2_ADTRG_SHIFT (6u) +#define ADC_SC2_ADTRG_WIDTH (1u) +#define ADC_SC2_ACFE_MASK (0x20u) +#define ADC_SC2_ACFE_SHIFT (5u) +#define ADC_SC2_ACFE_WIDTH (1u) +#define ADC_SC2_ACFGT_MASK (0x10u) +#define ADC_SC2_ACFGT_SHIFT (4u) +#define ADC_SC2_ACFGT_WIDTH (1u) +#define ADC_SC2_ACREN_MASK (0x08u) +#define ADC_SC2_ACREN_SHIFT (3u) +#define ADC_SC2_ACREN_WIDTH (1u) +#define ADC_SC2_DMAEN_MASK (0x04u) +#define ADC_SC2_DMAEN_SHIFT (2u) +#define ADC_SC2_DMAEN_WIDTH (1u) + +/* SC3 Bit Fields */ +#define ADC_SC3_ADC_PD_MASK (0x10000u) +#define ADC_SC3_ADC_PD_SHIFT (16u) +#define ADC_SC3_ADC_PD_WIDTH (1u) +#define ADC_SC3_STSEL_MASK (0x3000u) +#define ADC_SC3_STSEL_SHIFT (12u) +#define ADC_SC3_STSEL_WIDTH (2u) +#define ADC_SC3_STVCM_EN_MASK (0x800u) +#define ADC_SC3_STVCM_EN_SHIFT (11u) +#define ADC_SC3_STVCM_EN_WIDTH (1u) +#define ADC_SC3_CAL_GE_MASK (0x20u) +#define ADC_SC3_CAL_GE_SHIFT (5u) +#define ADC_SC3_CAL_GE_WIDTH (1u) +#define ADC_SC3_CAL_OFS_MASK (0x10u) +#define ADC_SC3_CAL_OFS_SHIFT (4u) +#define ADC_SC3_CAL_OFS_WIDTH (1u) +#define ADC_SC3_ADCO_MASK (0x08u) +#define ADC_SC3_ADCO_SHIFT (3u) +#define ADC_SC3_ADCO_WIDTH (1u) +#define ADC_SC3_AVGE_MASK (0x04u) +#define ADC_SC3_AVGE_SHIFT (2u) +#define ADC_SC3_AVGE_WIDTH (1u) +#define ADC_SC3_AVGS_MASK (0x03u) +#define ADC_SC3_AVGS_SHIFT (0u) +#define ADC_SC3_AVGS_WIDTH (2u) + +/* OFS Bit Fields */ +#define ADC_OFS_SUB_OFS_MASK (0x10000u) +#define ADC_OFS_SUB_OFS_SHIFT (16u) +#define ADC_OFS_SUB_OFS_WIDTH (1u) +#define ADC_OFS_VAL_OFS_MASK (0x7FFu) +#define ADC_OFS_VAL_OFS_SHIFT (0u) +#define ADC_OFS_VAL_OFS_WIDTH (11u) + +/* GE Bit Fields */ +#define ADC_GE_VAL_GE_MASK (0xFFFu) +#define ADC_GE_VAL_GE_SHIFT (0u) +#define ADC_GE_VAL_GE_WIDTH (12u) + +/* USRK Bit Fields */ +#define ADC_USRK_USER_KEY_MASK (0xFFFFFFFFu) +#define ADC_USRK_USER_KEY_SHIFT (0u) +#define ADC_USRK_USER_KEY_WIDTH (32u) + +/* SC Bit Fields */ +#define ADC_SC_COCO_MASK (0x80u) +#define ADC_SC_COCO_SHIFT (7u) +#define ADC_SC_COCO_WIDTH (1u) +#define ADC_SC_AIEN_MASK (0x40u) +#define ADC_SC_AIEN_SHIFT (6u) +#define ADC_SC_AIEN_WIDTH (1u) +#define ADC_SC_ADCH_MASK (0xFu) +#define ADC_SC_ADCH_SHIFT (0u) +#define ADC_SC_ADCH_WIDTH (4u) + +/* R Bit Fields */ +#define ADC_R_DATA_MASK (0x3FFFu) +#define ADC_R_DATA_SHIFT (0u) +#define ADC_R_DATA_WIDTH (14u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of ADC registers + */ +typedef struct _AdcRegType_ +{ + volatile uint32_t CFG1; /*!< Configs Register 1, Offset: 0000H */ + volatile uint32_t CFG2; /*!< Configs Register 2, Offset: 0004H */ + volatile uint32_t CV1; /*!< Compare Value 1, Offset: 0008H */ + volatile uint32_t CV2; /*!< Compare Value 2, Offset: 000CH */ + volatile uint32_t SC2; /*!< Status and Control Register 2, Offset: 0010H */ + volatile uint32_t SC3; /*!< Status and Control Register 3, Offset: 0014H */ + volatile uint32_t OFS; /*!< Offset Register, Offset: 0018H */ + volatile uint32_t GE; /*!< Error Gain Register, Offset: 001CH */ + volatile uint32_t USRK; /*!< User Key Register, Offset: 0020H */ + uint32_t RESERVED0[55]; /*!< reserverd block, Offset: 0024H */ + volatile uint32_t SC[ADC_REG_CH_COUNT]; /*!< Status and Control Register, Offset: 0100H */ + uint32_t RESERVED1[16]; /*!< reserverd block, Offset: 0160H */ + const volatile uint32_t R[ADC_REG_CH_COUNT]; /*!< Conversion Result Register, Offset: 0180H */ +} AdcRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Sets the Clear Latch Trigger in Trigger Handler Block + * + * This function sets the Clear Latch Trigger in Trigger Handler Block. + * Writing a 1 to this field clears all the latched triggers inside the trigger + * handler except the one under processing. Writing 0 has no effect. This is a + * write-only-one bit that self-clears immediately + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Clear Latch Trigger in Trigger Handler Block + */ +__attribute__((always_inline)) static inline void AdcReg_ClrTrg(AdcRegType *obj) +{ + uint32_t tmp = obj->CFG1; + + tmp &= ~ADC_CFG1_CLRLTRG_MASK; + tmp |= (((uint32_t)(((uint32_t)(1u)) << ADC_CFG1_CLRLTRG_SHIFT)) & ADC_CFG1_CLRLTRG_MASK); + obj->CFG1 = tmp; +} + +/*! \brief Gets the Conversion Mode Selection + * + * This function gets the current Conversion Mode Selection. + * Selects the ADC resolution. + * + * \param[in] obj : pointer to ADC register instance + * \return Conversion Mode Selection + * - 00b : 8-bit conversion. + * - x1b : 12-bit conversion. + * - 10b : 10-bit conversion. + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetCfg1Mode(const AdcRegType *obj) +{ + return ((obj->CFG1 & ADC_CFG1_MODE_MASK) >> ADC_CFG1_MODE_SHIFT); +} + +/*! \brief Sets the Conversion Mode Selection + * + * This function sets the Conversion Mode Selection. + * Selects the ADC resolution. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Conversion Mode Selection + * - 00b : 8-bit conversion. + * - x1b : 12-bit conversion. + * - 10b : 10-bit conversion. + */ +__attribute__((always_inline)) static inline void AdcReg_SetCfg1Mode(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CFG1; + tmp &= ADC_CFG1_WITHOUT_W1C_MASK; + tmp &= ~ADC_CFG1_MODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_CFG1_MODE_SHIFT)) & ADC_CFG1_MODE_MASK); + obj->CFG1 = tmp; +} + +/*! \brief Gets the POWER On Sample Delay Config + * + * This function gets the current POWER On Sample Delay Config. + * After ADC power on, this register configs delay time before sampling is + * started. The delay time is (LEN_PWR_ON+1)*clk_adc + * + * \param[in] obj : pointer to ADC register instance + * \return POWER On Sample Delay Config + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetCfg2LenPwrOn(const AdcRegType *obj) +{ + return ((obj->CFG2 & ADC_CFG2_LEN_PWR_ON_MASK) >> ADC_CFG2_LEN_PWR_ON_SHIFT); +} + +/*! \brief Sets the POWER On Sample Delay Config + * + * This function sets the POWER On Sample Delay Config. + * After ADC power on, this register configs delay time before sampling is + * started. The delay time is (LEN_PWR_ON+1)*clk_adc + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of POWER On Sample Delay Config + */ +__attribute__((always_inline)) static inline void AdcReg_SetCfg2LenPwrOn(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CFG2; + + tmp &= ~ADC_CFG2_LEN_PWR_ON_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_CFG2_LEN_PWR_ON_SHIFT)) & ADC_CFG2_LEN_PWR_ON_MASK); + obj->CFG2 = tmp; +} + +/*! \brief Gets the First Sample Delay Config + * + * This function gets the current First Sample Delay Config. + * After ADC power on or channel changes, the first sampling time needs to be + * LEN_SMPL added by LEN_SMPL_1ST, so the actual sample time is + * (LEN_SMPL_1ST+LEN_SMPL+1)*clk_adc + * + * \param[in] obj : pointer to ADC register instance + * \return First Sample Delay Config + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetCfg2LenSmpl1st(const AdcRegType *obj) +{ + return ((obj->CFG2 & ADC_CFG2_LEN_SMPL_1ST_MASK) >> ADC_CFG2_LEN_SMPL_1ST_SHIFT); +} + +/*! \brief Sets the First Sample Delay Config + * + * This function sets the First Sample Delay Config. + * After ADC power on or channel changes, the first sampling time needs to be + * LEN_SMPL added by LEN_SMPL_1ST, so the actual sample time is + * (LEN_SMPL_1ST+LEN_SMPL+1)*clk_adc + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of First Sample Delay Config + */ +__attribute__((always_inline)) static inline void AdcReg_SetCfg2LenSmpl1st(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CFG2; + + tmp &= ~ADC_CFG2_LEN_SMPL_1ST_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_CFG2_LEN_SMPL_1ST_SHIFT)) & ADC_CFG2_LEN_SMPL_1ST_MASK); + obj->CFG2 = tmp; +} + +/*! \brief Gets the ADC Sampling Time + * + * This function gets the current ADC Sampling Time. + * Configs ADC Sampling time, the actual time is (LEN_SMPL+1)*clk_adc + * + * \param[in] obj : pointer to ADC register instance + * \return ADC Sampling Time + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetCfg2LenSmpl(const AdcRegType *obj) +{ + return ((obj->CFG2 & ADC_CFG2_LEN_SMPL_MASK) >> ADC_CFG2_LEN_SMPL_SHIFT); +} + +/*! \brief Sets the ADC Sampling Time + * + * This function sets the ADC Sampling Time. + * Configs ADC Sampling time, the actual time is (LEN_SMPL+1)*clk_adc + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of ADC Sampling Time + */ +__attribute__((always_inline)) static inline void AdcReg_SetCfg2LenSmpl(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CFG2; + + tmp &= ~ADC_CFG2_LEN_SMPL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_CFG2_LEN_SMPL_SHIFT)) & ADC_CFG2_LEN_SMPL_MASK); + obj->CFG2 = tmp; +} + +/*! \brief Gets the compare value 1 + * + * This function gets the current compare value 1. + * + * \param[in] obj : pointer to ADC register instance + * \return compare value 1 + */ +__attribute__((always_inline)) static inline uint16_t AdcReg_GetCv1Cv(const AdcRegType *obj) +{ + return ((obj->CV1 & ADC_CV1_CV_MASK) >> ADC_CV1_CV_SHIFT); +} + +/*! \brief Sets the compare value 1 + * + * This function sets the compare value 1. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of compare value 1 + */ +__attribute__((always_inline)) static inline void AdcReg_SetCv1Cv(AdcRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->CV1; + + tmp &= ~ADC_CV1_CV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_CV1_CV_SHIFT)) & ADC_CV1_CV_MASK); + obj->CV1 = tmp; +} + +/*! \brief Gets the compare value 2 + * + * This function gets the current compare value 2. + * + * \param[in] obj : pointer to ADC register instance + * \return compare value 2 + */ +__attribute__((always_inline)) static inline uint16_t AdcReg_GetCv2Cv(const AdcRegType *obj) +{ + return ((obj->CV2 & ADC_CV2_CV_MASK) >> ADC_CV2_CV_SHIFT); +} + +/*! \brief Sets the compare value 2 + * + * This function sets the compare value 2. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of compare value 2 + */ +__attribute__((always_inline)) static inline void AdcReg_SetCv2Cv(AdcRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->CV2; + + tmp &= ~ADC_CV2_CV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_CV2_CV_SHIFT)) & ADC_CV2_CV_MASK); + obj->CV2 = tmp; +} + +/*! \brief Gets the Error in Multiplexed Trigger Request + * + * This function gets the current Error in Multiplexed Trigger Request. + * Each of these error signals indicate that a multiplexed hardware trigger + * request from a source has been missed, in which case the request has already + * been latched or is being serviced. Each bit in this field can be cleared by + * writing a 1 to it, and each bit corresponds to an individual trigger request: + * - Bit 24 corresponds to trigger request 0 + * - Bit 25 corresponds to trigger request 1 + * - Bit 26 corresponds to trigger request 2 + * - Bit 27 corresponds to trigger request 3 + * The read value of each bit in this field is interpreted individually + * + * \param[in] obj : pointer to ADC register instance + * \return Error in Multiplexed Trigger Request + * - 0b : No error has occurred + * - 1b : An error has occurred + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2TrgStErr(const AdcRegType *obj) +{ + return ((obj->SC2 & ADC_SC2_TRGSTERR_MASK) >> ADC_SC2_TRGSTERR_SHIFT); +} + +/*! \brief Sets the Error in Multiplexed Trigger Request + * + * This function sets the Error in Multiplexed Trigger Request. + * Each of these error signals indicate that a multiplexed hardware trigger + * request from a source has been missed, in which case the request has already + * been latched or is being serviced. Each bit in this field can be cleared by + * writing a 1 to it, and each bit corresponds to an individual trigger request: + * - Bit 24 corresponds to trigger request 0 + * - Bit 25 corresponds to trigger request 1 + * - Bit 26 corresponds to trigger request 2 + * - Bit 27 corresponds to trigger request 3 + * The read value of each bit in this field is interpreted individually + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Error in Multiplexed Trigger Request + * - 0b : No error has occurred + * - 1b : An error has occurred + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc2TrgStErr(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC2; + + tmp &= ~ADC_SC2_TRGSTERR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC2_TRGSTERR_SHIFT)) & ADC_SC2_TRGSTERR_MASK); + obj->SC2 = tmp; +} + +/*! \brief Gets the Trigger Status + * + * This function gets the current Trigger Status. + * Each of these status bits indicate that a multiplexed hardware trigger + * request from a source has been latched. Each bit in this field corresponds to + * an individual trigger request: + * - Bit 16 corresponds to trigger request 0 + * - Bit 17 corresponds to trigger request 1 + * - Bit 18 corresponds to trigger request 2 + * - Bit 19 corresponds to trigger request 3 + * The read value of each bit in this field is interpreted individually + * + * \param[in] obj : pointer to ADC register instance + * \return Trigger Status + * - 0b : No trigger request has been latched + * - 1b : A trigger request has been latched + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2TrgStLat(const AdcRegType *obj) +{ + return ((obj->SC2 & ADC_SC2_TRGSTLAT_MASK) >> ADC_SC2_TRGSTLAT_SHIFT); +} + +/*! \brief Gets the Trigger Process Number + * + * This function gets the current Trigger Process Number. + * Indicates the trigger number that is being serviced. + * This has to be qualified with the 1-bit value for the corresponding trigger + * latch status. + * - TRGPRNUM=00 is valid only if TRGSTLAT[16]=1 + * - TRGPRNUM=01 is valid only if TRGSTLAT[17]=1 + * - TRGPRNUM=10 is valid only if TRGSTLAT[18]=1 + * - TRGPRNUM=11 is valid only if TRGSTLAT[19]=1 + * + * \note Occasionally there may be a mismatch between the TRGPRNUM and the ideal + * trigger to be selected as per TRGSTLAT by Round Robin algorithm. This happens + * because of different operating clocks of the TRGSTLAT and the hardware logic. + * The TRGSTLAT is updated first with arrival of triggers, and then it is + * synchronized into the hardware clock. So, the hardware uses a delayed version + * of TRGSTLAT. Any trigger that arrives during the synchronization time is not + * presented to hardware immediately, but shows in TRGSTLAT + * + * \param[in] obj : pointer to ADC register instance + * \return Trigger Process Number + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2TrgPrNum(const AdcRegType *obj) +{ + return ((obj->SC2 & ADC_SC2_TRGPRNUM_MASK) >> ADC_SC2_TRGPRNUM_SHIFT); +} + +/*! \brief Gets the Conversion Active + * + * This function gets the current Conversion Active. + * Indicates that a conversion or hardware averaging is in progress. + * ADACT is set when a conversion is initiated and cleared when a conversion is + * completed or aborted. + * + * \param[in] obj : pointer to ADC register instance + * \return Conversion Active + * - 0b : Conversion not in progress. + * - 1b : Conversion in progress. + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2AdAct(const AdcRegType *obj) +{ + return ((obj->SC2 & ADC_SC2_ADACT_MASK) >> ADC_SC2_ADACT_SHIFT); +} + +/*! \brief Gets the Conversion Trigger state + * + * This function gets the current Conversion Trigger state. + * + * \param[in] obj : pointer to ADC register instance + * \return Conversion Trigger Select + * - 0b : trigger disable. + * - 1b : trigger enable. + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2AdTrg(const AdcRegType *obj) +{ + return ((obj->SC2 & ADC_SC2_ADTRG_MASK) >> ADC_SC2_ADTRG_SHIFT); +} + +/*! \brief Sets the Conversion Trigger state + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Conversion Trigger state select + * - 0b : trigger disable. + * - 1b : trigger enable. + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc2AdTrg(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC2; + + tmp &= ADC_SC2_WITHOUT_W1C_MASK; + tmp &= ~ADC_SC2_ADTRG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC2_ADTRG_SHIFT)) & ADC_SC2_ADTRG_MASK); + obj->SC2 = tmp; +} + +/*! \brief Gets the Compare Function Enable + * + * This function gets the current Compare Function Enable. + * Enables the compare function. + * + * \param[in] obj : pointer to ADC register instance + * \return Compare Function Enable + * - 0b : Compare function disabled. + * - 1b : Compare function enabled. + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2Acfe(const AdcRegType *obj) +{ + return ((obj->SC2 & ADC_SC2_ACFE_MASK) >> ADC_SC2_ACFE_SHIFT); +} + +/*! \brief Sets the Compare Function Enable + * + * This function sets the Compare Function Enable. + * Enables the compare function. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Compare Function Enable + * - 0b : Compare function disabled. + * - 1b : Compare function enabled. + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc2Acfe(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC2; + + tmp &= ADC_SC2_WITHOUT_W1C_MASK; + tmp &= ~ADC_SC2_ACFE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC2_ACFE_SHIFT)) & ADC_SC2_ACFE_MASK); + obj->SC2 = tmp; +} + +/*! \brief Gets the Compare Function Greater Than Enable + * + * This function gets the current Compare Function Greater Than Enable. + * Configures the compare function to check the conversion result relative to + * CV1 and CV2 based upon the value of ACREN. ACFE must be set for ACFGT to have + * any effect. + * + * \param[in] obj : pointer to ADC register instance + * \return Compare Function Greater Than Enable + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2AcFgt(const AdcRegType *obj) +{ + return ((obj->SC2 & ADC_SC2_ACFGT_MASK) >> ADC_SC2_ACFGT_SHIFT); +} + +/*! \brief Sets the Compare Function Greater Than Enable + * + * This function sets the Compare Function Greater Than Enable. + * Configures the compare function to check the conversion result relative to + * CV1 and CV2 based upon the value of ACREN. ACFE must be set for ACFGT to have + * any effect. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Compare Function Greater Than Enable + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc2AcFgt(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC2; + + tmp &= ADC_SC2_WITHOUT_W1C_MASK; + tmp &= ~ADC_SC2_ACFGT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC2_ACFGT_SHIFT)) & ADC_SC2_ACFGT_MASK); + obj->SC2 = tmp; +} + +/*! \brief Gets the Compare Function Range Enable + * + * This function gets the current Compare Function Range Enable. + * Configures the compare function to check if the conversion result of the + * input being monitored is either between or outside the range formed by CV1 + * and CV2 determined by the value of ACFGT. ACFE must be set for ACFGT to have + * any effect. + * + * \param[in] obj : pointer to ADC register instance + * \return Compare Function Range Enable + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2AcREn(const AdcRegType *obj) +{ + return ((obj->SC2 & ADC_SC2_ACREN_MASK) >> ADC_SC2_ACREN_SHIFT); +} + +/*! \brief Sets the Compare Function Range Enable + * + * This function sets the Compare Function Range Enable. + * Configures the compare function to check if the conversion result of the + * input being monitored is either between or outside the range formed by CV1 + * and CV2 determined by the value of ACFGT. ACFE must be set for ACFGT to have + * any effect. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Compare Function Range Enable + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc2AcREn(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC2; + + tmp &= ADC_SC2_WITHOUT_W1C_MASK; + tmp &= ~ADC_SC2_ACREN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC2_ACREN_SHIFT)) & ADC_SC2_ACREN_MASK); + obj->SC2 = tmp; +} + +/*! \brief Gets the DMA Enable + * + * This function gets the current DMA Enable. + * + * \param[in] obj : pointer to ADC register instance + * \return DMA Enable + * - 0b : DMA is disabled. + * - 1b : DMA is enabled and will assert the ADC DMA request during an + * ADC conversion complete event, which is indicated when any SCn[COCO] flag is + * asserted. + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2DmaEn(const AdcRegType *obj) +{ + return ((obj->SC2 & ADC_SC2_DMAEN_MASK) >> ADC_SC2_DMAEN_SHIFT); +} + +/*! \brief Sets the DMA Enable + * + * This function sets the DMA Enable. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of DMA Enable + * - 0b : DMA is disabled. + * - 1b : DMA is enabled and will assert the ADC DMA request + * during an ADC conversion complete event, which is indicated when any + * SCn[COCO] flag is asserted. + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc2DmaEn(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC2; + + tmp &= ADC_SC2_WITHOUT_W1C_MASK; + tmp &= ~ADC_SC2_DMAEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC2_DMAEN_SHIFT)) & ADC_SC2_DMAEN_MASK); + obj->SC2 = tmp; +} + +/*! \brief Gets the ADC Power Down + * + * This function gets the current ADC Power Down. + * + * \note It is recommended that powers on ADC first, and then configs other + * registers. + * + * \param[in] obj : pointer to ADC register instance + * \return ADC Power Down + * - 0b : power on + * - 1b : power down + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3AdcPD(const AdcRegType *obj) +{ + return ((obj->SC3 & ADC_SC3_ADC_PD_MASK) >> ADC_SC3_ADC_PD_SHIFT); +} + +/*! \brief Sets the ADC Power Down + * + * This function sets the ADC Power Down. + * + * \note It is recommended that powers on ADC first, and then configs other + * registers. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of ADC Power Down + * - 0b : power on + * - 1b : power down + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc3AdcPD(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC3; + + tmp &= ~ADC_SC3_ADC_PD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_ADC_PD_SHIFT)) & ADC_SC3_ADC_PD_MASK); + obj->SC3 = tmp; +} + +/*! \brief Gets the ADC Self-test Channel Select + * + * This function gets the current ADC Self-test Channel Select. + * + * \param[in] obj : pointer to ADC register instance + * \return ADC Self-test Channel Select + * - 00b : AVSS + * - 01b : 1/8*VREF + * - 10b : 1/2*VREF + * - 11b : 7/8*VREF + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3StSel(const AdcRegType *obj) +{ + return ((obj->SC3 & ADC_SC3_STSEL_MASK) >> ADC_SC3_STSEL_SHIFT); +} + +/*! \brief Sets the ADC Self-test Channel Select + * + * This function sets the ADC Self-test Channel Select. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of ADC Self-test Channel Select + * - 00b : AVSS + * - 01b : 1/8*VREF + * - 10b : 1/2*VREF + * - 11b : 7/8*VREF + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc3StSel(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC3; + + tmp &= ~ADC_SC3_STSEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_STSEL_SHIFT)) & ADC_SC3_STSEL_MASK); + obj->USRK = ADC_REG_UNLOCK_KEY; + obj->SC3 = tmp; + obj->USRK = ADC_REG_LOCK_KEY; +} + +/*! \brief Gets the ADC Self-test Common Mode Level Enable + * + * This function gets the current ADC Self-test Common Mode Level Enable. + * This configs the common mode level enable, which is used in calibration and + * self-test + * + * \param[in] obj : pointer to ADC register instance + * \return ADC Self-test Common Mode Level Enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3StVcmEn(const AdcRegType *obj) +{ + return ((obj->SC3 & ADC_SC3_STVCM_EN_MASK) >> ADC_SC3_STVCM_EN_SHIFT); +} + +/*! \brief Sets the ADC Self-test Common Mode Level Enable + * + * This function sets the ADC Self-test Common Mode Level Enable. + * This configs the common mode level enable, which is used in calibration and + * self-test + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of ADC Self-test Common Mode Level Enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc3StVcmEn(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC3; + + tmp &= ~ADC_SC3_STVCM_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_STVCM_EN_SHIFT)) & ADC_SC3_STVCM_EN_MASK); + obj->USRK = ADC_REG_UNLOCK_KEY; + obj->SC3 = tmp; + obj->USRK = ADC_REG_LOCK_KEY; +} + +/*! \brief Gets the Gain Error Calibration Start + * + * This function gets the current Gain Error Calibration Start. + * Write 1 to this bit to start gain error calibration. This bit is cleared by + * hardware when calibration finishes. + * + * \param[in] obj : pointer to ADC register instance + * \return Gain Error Calibration Start + * - 0b : gain error calibration is no ongoing + * - 1b : gain error calibration is in progress + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3CalGE(const AdcRegType *obj) +{ + return ((obj->SC3 & ADC_SC3_CAL_GE_MASK) >> ADC_SC3_CAL_GE_SHIFT); +} + +/*! \brief Sets the Gain Error Calibration Start + * + * This function sets the Gain Error Calibration Start. + * Write 1 to this bit to start gain error calibration. This bit is cleared by + * hardware when calibration finishes. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Gain Error Calibration Start + * - 0b : gain error calibration is no ongoing + * - 1b : gain error calibration is in progress + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc3CalGE(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC3; + + tmp &= ~ADC_SC3_CAL_GE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_CAL_GE_SHIFT)) & ADC_SC3_CAL_GE_MASK); + obj->SC3 = tmp; +} + +/*! \brief Gets the Offset Calibration Start + * + * This function gets the current Offset Calibration Start. + * Write 1 to this bit to start offset calibration. This bit is cleared by + * hardware when calibration finishes. + * + * \param[in] obj : pointer to ADC register instance + * \return Offset Calibration Start + * - 0b : offset calibration is no ongoing + * - 1b : offset calibration is in progress + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3CalOfs(const AdcRegType *obj) +{ + return ((obj->SC3 & ADC_SC3_CAL_OFS_MASK) >> ADC_SC3_CAL_OFS_SHIFT); +} + +/*! \brief Sets the Offset Calibration Start + * + * This function sets the Offset Calibration Start. + * Write 1 to this bit to start offset calibration. This bit is cleared by + * hardware when calibration finishes. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Offset Calibration Start + * - 0b : offset calibration is no ongoing + * - 1b : offset calibration is in progress + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc3CalOfs(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC3; + + tmp &= ~ADC_SC3_CAL_OFS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_CAL_OFS_SHIFT)) & ADC_SC3_CAL_OFS_MASK); + obj->SC3 = tmp; +} + +/*! \brief Gets the Continuous Conversion Enable + * + * This function gets the current Continuous Conversion Enable. + * Enables continuous conversions. + * + * \param[in] obj : pointer to ADC register instance + * \return Continuous Conversion Enable + * - 0b : One conversion will be performed (or one set of conversions, + * if AVGE is set) after a conversion is initiated. + * - 1b : Continuous conversions will be performed (or continuous sets + * of conversions, if AVGE is set) after a conversion is initiated. + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3Adco(const AdcRegType *obj) +{ + return ((obj->SC3 & ADC_SC3_ADCO_MASK) >> ADC_SC3_ADCO_SHIFT); +} + +/*! \brief Sets the Continuous Conversion Enable + * + * This function sets the Continuous Conversion Enable. + * Enables continuous conversions. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Continuous Conversion Enable + * - 0b : One conversion will be performed (or one set of + * conversions, if AVGE is set) after a conversion is initiated. + * - 1b : Continuous conversions will be performed (or + * continuous sets of conversions, if AVGE is set) after a conversion is + * initiated. + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc3Adco(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC3; + + tmp &= ~ADC_SC3_ADCO_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_ADCO_SHIFT)) & ADC_SC3_ADCO_MASK); + obj->SC3 = tmp; +} + +/*! \brief Gets the Hardware Average Enable + * + * This function gets the current Hardware Average Enable. + * Enables the hardware average function of the ADC. + * + * \param[in] obj : pointer to ADC register instance + * \return Hardware Average Enable + * - 0b : Hardware average function disabled. + * - 1b : Hardware average function enabled. + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3AvgE(const AdcRegType *obj) +{ + return ((obj->SC3 & ADC_SC3_AVGE_MASK) >> ADC_SC3_AVGE_SHIFT); +} + +/*! \brief Sets the Hardware Average Enable + * + * This function sets the Hardware Average Enable. + * Enables the hardware average function of the ADC. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Hardware Average Enable + * - 0b : Hardware average function disabled. + * - 1b : Hardware average function enabled. + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc3AvgE(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC3; + + tmp &= ~ADC_SC3_AVGE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_AVGE_SHIFT)) & ADC_SC3_AVGE_MASK); + obj->SC3 = tmp; +} + +/*! \brief Gets the Hardware Average Select + * + * This function gets the current Hardware Average Select. + * Determines how many ADC conversions will be averaged to create the ADC + * average result. + * + * \param[in] obj : pointer to ADC register instance + * \return Hardware Average Select + * - 00b : 4 samples averaged. + * - 01b : 8 samples averaged. + * - 10b : 16 samples averaged. + * - 11b : 32 samples averaged. + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3AvgS(const AdcRegType *obj) +{ + return ((obj->SC3 & ADC_SC3_AVGS_MASK) >> ADC_SC3_AVGS_SHIFT); +} + +/*! \brief Sets the Hardware Average Select + * + * This function sets the Hardware Average Select. + * Determines how many ADC conversions will be averaged to create the ADC + * average result. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of Hardware Average Select + * - 00b : 4 samples averaged. + * - 01b : 8 samples averaged. + * - 10b : 16 samples averaged. + * - 11b : 32 samples averaged. + */ +__attribute__((always_inline)) static inline void AdcReg_SetSc3AvgS(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC3; + + tmp &= ~ADC_SC3_AVGS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_AVGS_SHIFT)) & ADC_SC3_AVGS_MASK); + obj->SC3 = tmp; +} + +/*! \brief Gets the ADC Offset Addition Subtraction Flag + * + * This function gets the current ADC Offset Addition Subtraction Flag. + * This bit configs how offset is used in calibration. It can be set by hardware + * or software. + * + * \param[in] obj : pointer to ADC register instance + * \return ADC Offset Addition Subtraction Flag + * - 0b : ADC output will be added by VAL_OFS(ceiling to 4095) + * - 1b : ADC output will be subtracted by VAL_OFS(flooring to 4095) + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetOfsSubOfs(const AdcRegType *obj) +{ + return ((obj->OFS & ADC_OFS_SUB_OFS_MASK) >> ADC_OFS_SUB_OFS_SHIFT); +} + +/*! \brief Sets the ADC Offset Addition Subtraction Flag + * + * This function sets the ADC Offset Addition Subtraction Flag. + * This bit configs how offset is used in calibration. It can be set by hardware + * or software. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of ADC Offset Addition Subtraction Flag + * - 0b : ADC output will be added by VAL_OFS(ceiling to + * 4095) + * - 1b : ADC output will be subtracted by VAL_OFS(flooring + * to 4095) + */ +__attribute__((always_inline)) static inline void AdcReg_SetOfsSubOfs(AdcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OFS; + + tmp &= ~ADC_OFS_SUB_OFS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_OFS_SUB_OFS_SHIFT)) & ADC_OFS_SUB_OFS_MASK); + obj->OFS = tmp; +} + +/*! \brief Gets the ADC Offset Value + * + * This function gets the current ADC Offset Value. + * Used in calibration to caculate the final result. It can be set by hardware + * or software + * + * \param[in] obj : pointer to ADC register instance + * \return ADC Offset Value + */ +__attribute__((always_inline)) static inline uint16_t AdcReg_GetOfsValOfs(const AdcRegType *obj) +{ + return ((obj->OFS & ADC_OFS_VAL_OFS_MASK) >> ADC_OFS_VAL_OFS_SHIFT); +} + +/*! \brief Sets the ADC Offset Value + * + * This function sets the ADC Offset Value. + * Used in calibration to caculate the final result. It can be set by hardware + * or software + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of ADC Offset Value + */ +__attribute__((always_inline)) static inline void AdcReg_SetOfsValOfs(AdcRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->OFS; + + tmp &= ~ADC_OFS_VAL_OFS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_OFS_VAL_OFS_SHIFT)) & ADC_OFS_VAL_OFS_MASK); + obj->OFS = tmp; +} + +/*! \brief Gets the ADC Gain Error Value + * + * This function gets the current ADC Gain Error Value. + * Used in gain error adjusting. It can be set by hardware or software. + * ADC output * 3072/VAL_GE is the gain erro + * + * \param[in] obj : pointer to ADC register instance + * \return ADC Gain Error Value + */ +__attribute__((always_inline)) static inline uint16_t AdcReg_GetGeValGE(const AdcRegType *obj) +{ + return ((obj->GE & ADC_GE_VAL_GE_MASK) >> ADC_GE_VAL_GE_SHIFT); +} + +/*! \brief Sets the ADC Gain Error Value + * + * This function sets the ADC Gain Error Value. + * Used in gain error adjusting. It can be set by hardware or software. + * ADC output * 3072/VAL_GE is the gain erro + * + * \param[in] obj : pointer to ADC register instance + * \param[in] value : the value of ADC Gain Error Value + */ +__attribute__((always_inline)) static inline void AdcReg_SetGeValGE(AdcRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->GE; + + tmp &= ~ADC_GE_VAL_GE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_GE_VAL_GE_SHIFT)) & ADC_GE_VAL_GE_MASK); + obj->GE = tmp; +} + +/*! \brief Gets the Conversion Complete Flag + * + * This function gets the current Conversion Complete Flag. + * This is a read-only field that is set each time a conversion is completed + when one or more of the following is true: + * - The compare function is disabled SC2[ACFE]=0 and the hardware average + function is disabled SC3[AVGE]=0 + * If the compare result is true, then COCO is set upon completion of a + conversion if one or more of the following is true: + * - The compare function is enabled SC2[ACFE]=1 + * COCO is set upon completion of the selected number of conversions (determined + by AVGS) if one or more of the following is true: + * - The hardware average function is enabled SC3[AVGE]=1 + * COCO is cleared when one of the following is true: + - The respective SCn register is written + - The respective Rn register is read + * + * \param[in] obj : pointer to ADC register instance + * \param[in] channel : the channel number + * \return Conversion Complete Flag + * - 0b : Conversion is not completed. + * - 1b : Conversion is completed. + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetScCoCo(const AdcRegType *obj, uint8_t channel) +{ + return ((obj->SC[channel] & ADC_SC_COCO_MASK) >> ADC_SC_COCO_SHIFT); +} + +/*! \brief Gets the Interrupt Enable + * + * This function gets the current Interrupt Enable. + * Enables conversion complete interrupts. When COCO becomes set while the + * respective AIEN is high, an interrupt is asserted. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] channel : the channel number + * \return Interrupt Enable + * - 0b : Conversion complete interrupt is disabled. + * - 1b : Conversion complete interrupt is enabled. + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetScAIEn(const AdcRegType *obj, uint8_t channel) +{ + return ((obj->SC[channel] & ADC_SC_AIEN_MASK) >> ADC_SC_AIEN_SHIFT); +} + +/*! \brief Sets the Interrupt Enable + * + * This function sets the Interrupt Enable. + * Enables conversion complete interrupts. When COCO becomes set while the + * respective AIEN is high, an interrupt is asserted. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] channel : the channel number + * \param[in] value : the value of Interrupt Enable + * - 0b : Conversion complete interrupt is disabled. + * - 1b : Conversion complete interrupt is enabled. + */ +__attribute__((always_inline)) static inline void AdcReg_SetScAIEn(AdcRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->SC[channel]; + + tmp &= ~ADC_SC_AIEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC_AIEN_SHIFT)) & ADC_SC_AIEN_MASK); + obj->SC[channel] = tmp; +} + +/*! \brief Gets the Input channel select + * + * This function gets the current Input channel select. + * Selects one of the input channels. + * The successive approximation converter subsystem is turned off when the + * channel bits are all set (i.e.ADCH set to all 1s). This feature allows + * explicit disabling of the ADC and isolation of the input channel from all + * sources. Terminating continuous conversions this way prevents an additional + * single conversion from being performed. It is not necessary to set ADCH to + * all 1s to place the ADC in a low:power state when continuous conversions are + * not enabled because the module automatically enters a low:power state when a + * conversion completes. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] channel : the channel number + * \return Input channel select + * - 0x0 : External channel 0 is selected as ADC input + * - 0x1 : External channel 1 is selected as ADC input + * - 0x2 : External channel 2 is selected as ADC input + * - 0x3 : External channel 3 is selected as ADC input + * - 0x4 : External channel 4 is selected as ADC input + * - 0x5 : External channel 5 is selected as ADC input + * - 0x6 : External channel 6 is selected as ADC input + * - 0x7 : External channel 7 is selected as ADC input + * - 0x8 : External channel 8 is selected as ADC input + * - 0x9 : External channel 9 is selected as ADC input + * - 0xA : External channel 10 is selected as ADC input + * - 0xB : External channel 11 is selected as ADC input + * - 0xC : External channel 12 is selected as ADC input + * - 0xD : External channel 13 is selected as ADC input + * - 0xE : External channel 14 is selected as ADC input + * - 0xF : External channel 15 is selected as ADC input + * - 0x10 : VBUF_TSEN_LPVBG + * - 0x11 : VBUF_TSEN_LPVBG + * - 0x12 : VBG + * - 0x13 : monitor ldo output + * - 0x14 : monitor supply voltage(0.5*supply_voltage) + * - 0x15 : AVSS + * - 0x16 : AVSS + * - 0x17 : Self Test Voltage + * - 0x18 ~ 0x1E : Reserved + * - 0x1F : Module is disabled + */ +__attribute__((always_inline)) static inline uint8_t AdcReg_GetScAdCh(const AdcRegType *obj, uint8_t channel) +{ + return ((obj->SC[channel] & ADC_SC_ADCH_MASK) >> ADC_SC_ADCH_SHIFT); +} + +/*! \brief Sets the Input channel select + * + * This function sets the Input channel select. + * Selects one of the input channels. + * The successive approximation converter subsystem is turned off when the + * channel bits are all set (i.e.ADCH set to all 1s). This feature allows + * explicit disabling of the ADC and isolation of the input channel from all + * sources. Terminating continuous conversions this way prevents an additional + * single conversion from being performed. It is not necessary to set ADCH to + * all 1s to place the ADC in a low:power state when continuous conversions are + * not enabled because the module automatically enters a low:power state when a + * conversion completes. + * + * \param[in] obj : pointer to ADC register instance + * \param[in] channel : the channel number + * \param[in] value : the value of Input channel select + * - 0x0 : External channel 0 is selected as ADC input + * - 0x1 : External channel 1 is selected as ADC input + * - 0x2 : External channel 2 is selected as ADC input + * - 0x3 : External channel 3 is selected as ADC input + * - 0x4 : External channel 4 is selected as ADC input + * - 0x5 : External channel 5 is selected as ADC input + * - 0x6 : External channel 6 is selected as ADC input + * - 0x7 : External channel 7 is selected as ADC input + * - 0x8 : External channel 8 is selected as ADC input + * - 0x9 : External channel 9 is selected as ADC input + * - 0xA : External channel 10 is selected as ADC input + * - 0xB : External channel 11 is selected as ADC input + * - 0xC : External channel 12 is selected as ADC input + * - 0xD : External channel 13 is selected as ADC input + * - 0xE : External channel 14 is selected as ADC input + * - 0xF : External channel 15 is selected as ADC input + * - 0x10 : VBUF_TSEN_LPVBG + * - 0x11 : VBUF_TSEN_LPVBG + * - 0x12 : VBG + * - 0x13 : monitor ldo output + * - 0x14 : monitor supply voltage(0.5*supply_voltage) + * - 0x15 : AVSS + * - 0x16 : AVSS + * - 0x17 : Self Test Voltage + * - 0x18 ~ 0x1E : Reserved + * - 0x1F : Module is disabled + */ +__attribute__((always_inline)) static inline void AdcReg_SetScAdCh(AdcRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->SC[channel]; + + tmp &= ~ADC_SC_ADCH_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC_ADCH_SHIFT)) & ADC_SC_ADCH_MASK); + obj->SC[channel] = tmp; +} + +/*! \brief Gets the ADC data result + * + * This function gets the current ADC data result. + * \param[in] obj : pointer to ADC register instance + * \param[in] channel : the channel number + * \return ADC data result + */ +__attribute__((always_inline)) static inline uint16_t AdcReg_GetRData(const AdcRegType *obj, uint8_t channel) +{ + return ((obj->R[channel] & ADC_R_DATA_MASK) >> ADC_R_DATA_SHIFT); +} + +/*! \brief Abort ADC chn + * This function for software trigger ADC. + * \param[in] obj : pointer to ADC register instance + * \param[in] chn : expect abort channel number + */ +__attribute__((always_inline)) static inline void AdcReg_AbortChn(AdcRegType *obj, uint8_t chn) +{ + uint32_t tmp = obj->SC[chn]; + obj->SC[chn] = tmp; +} +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _ADC_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/axbs_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/axbs_reg.h new file mode 100644 index 0000000..5632b6b --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/axbs_reg.h @@ -0,0 +1,528 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _AXBS_REG_H_ +#define _AXBS_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the AXBS Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define AXBS_MASTER_NUM (8) + +/* CSR Bit Fields */ +#define AXBS_CSR_MERR7_MASK (0x80000000u) +#define AXBS_CSR_MERR7_SHIFT (31u) +#define AXBS_CSR_MERR7_WIDTH (1u) +#define AXBS_CSR_MERR6_MASK (0x40000000u) +#define AXBS_CSR_MERR6_SHIFT (30u) +#define AXBS_CSR_MERR6_WIDTH (1u) +#define AXBS_CSR_MERR5_MASK (0x20000000u) +#define AXBS_CSR_MERR5_SHIFT (29u) +#define AXBS_CSR_MERR5_WIDTH (1u) +#define AXBS_CSR_MERR4_MASK (0x10000000u) +#define AXBS_CSR_MERR4_SHIFT (28u) +#define AXBS_CSR_MERR4_WIDTH (1u) +#define AXBS_CSR_MERR3_MASK (0x8000000u) +#define AXBS_CSR_MERR3_SHIFT (27u) +#define AXBS_CSR_MERR3_WIDTH (1u) +#define AXBS_CSR_MERR2_MASK (0x4000000u) +#define AXBS_CSR_MERR2_SHIFT (26u) +#define AXBS_CSR_MERR2_WIDTH (1u) +#define AXBS_CSR_MERR1_MASK (0x2000000u) +#define AXBS_CSR_MERR1_SHIFT (25u) +#define AXBS_CSR_MERR1_WIDTH (1u) +#define AXBS_CSR_MERR0_MASK (0x1000000u) +#define AXBS_CSR_MERR0_SHIFT (24u) +#define AXBS_CSR_MERR0_WIDTH (1u) +#define AXBS_CSR_AHB_REG_VLD_MASK (0x01u) +#define AXBS_CSR_AHB_REG_VLD_SHIFT (0u) +#define AXBS_CSR_AHB_REG_VLD_WIDTH (1u) + +/* EAR Bit Fields */ +#define AXBS_EAR_EADDR_MASK (0xFFFFFFFFu) +#define AXBS_EAR_EADDR_SHIFT (0u) +#define AXBS_EAR_EADDR_WIDTH (32u) + +/* EDR Bit Fields */ +#define AXBS_EDR_EMN_MASK (0xF000u) +#define AXBS_EDR_EMN_SHIFT (12u) +#define AXBS_EDR_EMN_WIDTH (4u) +#define AXBS_EDR_EATTR_MASK (0xF0u) +#define AXBS_EDR_EATTR_SHIFT (4u) +#define AXBS_EDR_EATTR_WIDTH (4u) +#define AXBS_EDR_ERW_MASK (0x01u) +#define AXBS_EDR_ERW_SHIFT (0u) +#define AXBS_EDR_ERW_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of AHB registers + */ +typedef struct _AxbsRegType_ +{ + volatile uint32_t CSR; /*!< AXBS control/error status register, offset: 0x0 */ + uint32_t RESERVED0[3]; /*!< Reserverd block, 0004H */ + struct + { + const volatile uint32_t EAR; /*!< Master n Error Address Register */ + const volatile uint32_t EDR; /*!< Master n Error Detail Register */ + } ERR[AXBS_MASTER_NUM]; +} AxbsRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the AXBS master 0 Error + * + * This function gets the current AXBS master 0 Error. + * Indicates a captured error in AXBS master0 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \return AXBS master 0 Error + * - 0b : No error has occurred for AXBS master 0 interface. + * - 1b : An error has occurred for AXBS master 0 interface. + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetCsrMErr0(const AxbsRegType *obj) +{ + return ((obj->CSR & AXBS_CSR_MERR0_MASK) >> AXBS_CSR_MERR0_SHIFT); +} + +/*! \brief Sets the AXBS master 0 Error + * + * This function sets the AXBS master 0 Error. + * Indicates a captured error in AXBS master0 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] value : whether to clear the flag + * - 0b : No effect + * - 1b : Clear the error flag + */ +__attribute__((always_inline)) static inline void AxbsReg_SetCsrMErr0(AxbsRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = obj->CSR & AXBS_CSR_AHB_REG_VLD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << AXBS_CSR_MERR0_SHIFT)) & AXBS_CSR_MERR0_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the AXBS master 1 Error + * + * This function gets the current AXBS master 1 Error. + * Indicates a captured error in AXBS master1 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \return AXBS master 1 Error + * - 0b : No error has occurred for AXBS master 1 interface. + * - 1b : An error has occurred for AXBS master 1 interface. + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetCsrMErr1(const AxbsRegType *obj) +{ + return ((obj->CSR & AXBS_CSR_MERR1_MASK) >> AXBS_CSR_MERR1_SHIFT); +} + +/*! \brief Sets the AXBS master 1 Error + * + * This function sets the AXBS master 1 Error. + * Indicates a captured error in AXBS master1 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] value : whether to clear the flag + * - 0b : No effect + * - 1b : Clear the error flag + */ +__attribute__((always_inline)) static inline void AxbsReg_SetCsrMErr1(AxbsRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = obj->CSR & AXBS_CSR_AHB_REG_VLD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << AXBS_CSR_MERR1_SHIFT)) & AXBS_CSR_MERR1_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the AXBS master 2 Error + * + * This function gets the current AXBS master 2 Error. + * Indicates a captured error in AXBS master2 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \return AXBS master 2 Error + * - 0b : No error has occurred for AXBS master 2 interface. + * - 1b : An error has occurred for AXBS master 2 interface. + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetCsrMErr2(const AxbsRegType *obj) +{ + return ((obj->CSR & AXBS_CSR_MERR2_MASK) >> AXBS_CSR_MERR2_SHIFT); +} + +/*! \brief Sets the AXBS master 2 Error + * + * This function sets the AXBS master 2 Error. + * Indicates a captured error in AXBS master2 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] value : whether to clear the flag + * - 0b : No effect + * - 1b : Clear the error flag + */ +__attribute__((always_inline)) static inline void AxbsReg_SetCsrMErr2(AxbsRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = obj->CSR & AXBS_CSR_AHB_REG_VLD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << AXBS_CSR_MERR2_SHIFT)) & AXBS_CSR_MERR2_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the AXBS master 3 Error + * + * This function gets the current AXBS master 3 Error. + * Indicates a captured error in AXBS master3 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \return AXBS master 3 Error + * - 0b : No error has occurred for AXBS master 3 interface. + * - 1b : An error has occurred for AXBS master 3 interface. + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetCsrMErr3(const AxbsRegType *obj) +{ + return ((obj->CSR & AXBS_CSR_MERR3_MASK) >> AXBS_CSR_MERR3_SHIFT); +} + +/*! \brief Sets the AXBS master 3 Error + * + * This function sets the AXBS master 3 Error. + * Indicates a captured error in AXBS master3 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] value : whether to clear the flag + * - 0b : No effect + * - 1b : Clear the error flag + */ +__attribute__((always_inline)) static inline void AxbsReg_SetCsrMErr3(AxbsRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = obj->CSR & AXBS_CSR_AHB_REG_VLD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << AXBS_CSR_MERR3_SHIFT)) & AXBS_CSR_MERR3_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the AXBS master 4 Error + * + * This function gets the current AXBS master 4 Error. + * Indicates a captured error in AXBS master4 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \return AXBS master 4 Error + * - 0b : No error has occurred for AXBS master 4 interface. + * - 1b : An error has occurred for AXBS master 4 interface. + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetCsrMErr4(const AxbsRegType *obj) +{ + return ((obj->CSR & AXBS_CSR_MERR4_MASK) >> AXBS_CSR_MERR4_SHIFT); +} + +/*! \brief Sets the AXBS master 4 Error + * + * This function sets the AXBS master 4 Error. + * Indicates a captured error in AXBS master4 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] value : whether to clear the flag + * - 0b : No effect + * - 1b : Clear the error flag + */ +__attribute__((always_inline)) static inline void AxbsReg_SetCsrMErr4(AxbsRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = obj->CSR & AXBS_CSR_AHB_REG_VLD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << AXBS_CSR_MERR4_SHIFT)) & AXBS_CSR_MERR4_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the AXBS master 5 Error + * + * This function gets the current AXBS master 5 Error. + * Indicates a captured error in AXBS master5 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \return AXBS master 5 Error + * - 0b : No error has occurred for AXBS master 5 interface. + * - 1b : An error has occurred for AXBS master 5 interface. + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetCsrMErr5(const AxbsRegType *obj) +{ + return ((obj->CSR & AXBS_CSR_MERR5_MASK) >> AXBS_CSR_MERR5_SHIFT); +} + +/*! \brief Sets the AXBS master 5 Error + * + * This function sets the AXBS master 5 Error. + * Indicates a captured error in AXBS master5 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] value : whether to clear the flag + * - 0b : No effect + * - 1b : Clear the error flag + */ +__attribute__((always_inline)) static inline void AxbsReg_SetCsrMErr5(AxbsRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = obj->CSR & AXBS_CSR_AHB_REG_VLD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << AXBS_CSR_MERR5_SHIFT)) & AXBS_CSR_MERR5_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the AXBS master 6 Error + * + * This function gets the current AXBS master 6 Error. + * Indicates a captured error in AXBS master6 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \return AXBS master 6 Error + * - 0b : No error has occurred for AXBS master 6 interface. + * - 1b : An error has occurred for AXBS master 6 interface. + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetCsrMErr6(const AxbsRegType *obj) +{ + return ((obj->CSR & AXBS_CSR_MERR6_MASK) >> AXBS_CSR_MERR6_SHIFT); +} + +/*! \brief Sets the AXBS master 6 Error + * + * This function sets the AXBS master 6 Error. + * Indicates a captured error in AXBS master6 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] value : whether to clear the flag + * - 0b : No effect + * - 1b : Clear the error flag + */ +__attribute__((always_inline)) static inline void AxbsReg_SetCsrMErr6(AxbsRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = obj->CSR & AXBS_CSR_AHB_REG_VLD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << AXBS_CSR_MERR6_SHIFT)) & AXBS_CSR_MERR6_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the AXBS master 7 Error + * + * This function gets the current AXBS master 7 Error. + * Indicates a captured error in AXBS master7 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \return AXBS master 7 Error + * - 0b : No error has occurred for AXBS master 7 interface. + * - 1b : An error has occurred for AXBS master 7 interface. + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetCsrMErr7(const AxbsRegType *obj) +{ + return ((obj->CSR & AXBS_CSR_MERR7_MASK) >> AXBS_CSR_MERR7_SHIFT); +} + +/*! \brief Sets the AXBS master 7 Error + * + * This function sets the AXBS master 7 Error. + * Indicates a captured error in AXBS master7 interface. + * This bit is set when the hardware detects an error and records the faulting address and attributes. + * It is cleared by writing one to it. + * If another error is captured at the exact same cycle as the write, the flag remains set, + * and the latest error information is captured. + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] value : whether to clear the flag + * - 0b : No effect + * - 1b : Clear the error flag + */ +__attribute__((always_inline)) static inline void AxbsReg_SetCsrMErr7(AxbsRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = obj->CSR & AXBS_CSR_AHB_REG_VLD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << AXBS_CSR_MERR7_SHIFT)) & AXBS_CSR_MERR7_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the AXBS status regsiter module enable flag + * + * This function gets the current AXBS status regsiter module enable flag + * + * \param[in] obj : pointer to AXBS register instance + * \return the current AXBS status regsiter module enable flag + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetCsrRegVld(const AxbsRegType *obj) +{ + return ((obj->CSR & AXBS_CSR_AHB_REG_VLD_MASK) >> AXBS_CSR_AHB_REG_VLD_SHIFT); +} + +/*! \brief Sets the AXBS status regsiter module enable flag + * + * This function sets the AXBS status regsiter module enable flag. + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] value : the value of AXBS status regsiter module enable flag + */ +__attribute__((always_inline)) static inline void AxbsReg_SetCsrRegVld(AxbsRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CSR; + + tmp &= ~AXBS_CSR_AHB_REG_VLD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << AXBS_CSR_AHB_REG_VLD_SHIFT)) & AXBS_CSR_AHB_REG_VLD_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the Error Address + * + * This function gets the current Error Address. + * Indicates the reference address from master 0 that generated the access erro + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] master : the master index + * \return Error Address + */ +__attribute__((always_inline)) static inline uint32_t AxbsReg_GetEarEAddr(const AxbsRegType *obj, uint8_t master) +{ + return ((obj->ERR[master].EAR & AXBS_EAR_EADDR_MASK) >> AXBS_EAR_EADDR_SHIFT); +} + +/*! \brief Gets the Error Master Number + * + * This function gets the current Error Master Number. + * Indicates the bus master that generated the access error + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] master : the master index + * \return Error Master Number + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetEdrEmn(const AxbsRegType *obj, uint8_t master) +{ + return ((obj->ERR[master].EDR & AXBS_EDR_EMN_MASK) >> AXBS_EDR_EMN_SHIFT); +} + +/*! \brief Gets the Error Attributes + * + * This function gets the current Error Attributes. + * Indicates hprot[3:0] of error access + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] master : the master index + * \return Error Attributes + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetEdrEAttr(const AxbsRegType *obj, uint8_t master) +{ + return ((obj->ERR[master].EDR & AXBS_EDR_EATTR_MASK) >> AXBS_EDR_EATTR_SHIFT); +} + +/*! \brief Gets the Error Read/Write + * + * This function gets the current Error Read/Write. + * Indicates the access type of the faulting reference. + * + * \param[in] obj : pointer to AXBS register instance + * \param[in] master : the master index + * \return Error Read/Write + * - 0b : Read + * - 1b : Write + */ +__attribute__((always_inline)) static inline uint8_t AxbsReg_GetEdrErw(const AxbsRegType *obj, uint8_t master) +{ + return ((obj->ERR[master].EDR & AXBS_EDR_ERW_MASK) >> AXBS_EDR_ERW_SHIFT); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _AXBS_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/cmp_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/cmp_reg.h new file mode 100644 index 0000000..e9109da --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/cmp_reg.h @@ -0,0 +1,2304 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CMP_REG_H_ +#define _CMP_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the CMP Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* CMP Register Lock Key for unlock or lock */ +#define UNLOCK_KEY (0x5f5f0101u) +#define LOCK_KEY (0x00000000u) + +/* C0 Bit Fields */ +#define CMP_C0_WITHOUT_W1C_MASK (0xF9FFFFFFu) +#define CMP_C0_HYSTCTR_MASK (0x3u) +#define CMP_C0_HYSTCTR_SHIFT (0u) +#define CMP_C0_HYSTCTR_WIDTH (2u) +#define CMP_C0_OFFSET_MASK (0x4u) +#define CMP_C0_OFFSET_SHIFT (2u) +#define CMP_C0_OFFSET_WIDTH (1u) +#define CMP_C0_FILTER_CNT_MASK (0x70u) +#define CMP_C0_FILTER_CNT_SHIFT (4u) +#define CMP_C0_FILTER_CNT_WIDTH (3u) +#define CMP_C0_EN_MASK (0x100u) +#define CMP_C0_EN_SHIFT (8u) +#define CMP_C0_EN_WIDTH (1u) +#define CMP_C0_OPE_MASK (0x200u) +#define CMP_C0_OPE_SHIFT (9u) +#define CMP_C0_OPE_WIDTH (1u) +#define CMP_C0_COS_MASK (0x400u) +#define CMP_C0_COS_SHIFT (10u) +#define CMP_C0_COS_WIDTH (1u) +#define CMP_C0_INVT_MASK (0x800u) +#define CMP_C0_INVT_SHIFT (11u) +#define CMP_C0_INVT_WIDTH (1u) +#define CMP_C0_PMODE_MASK (0x1000u) +#define CMP_C0_PMODE_SHIFT (12u) +#define CMP_C0_PMODE_WIDTH (1u) +#define CMP_C0_WE_MASK (0x4000u) +#define CMP_C0_WE_SHIFT (14u) +#define CMP_C0_WE_WIDTH (1u) +#define CMP_C0_SE_MASK (0x8000u) +#define CMP_C0_SE_SHIFT (15u) +#define CMP_C0_SE_WIDTH (1u) +#define CMP_C0_FPR_MASK (0xFF0000u) +#define CMP_C0_FPR_SHIFT (16u) +#define CMP_C0_FPR_WIDTH (8u) +#define CMP_C0_COUT_MASK (0x1000000u) +#define CMP_C0_COUT_SHIFT (24u) +#define CMP_C0_COUT_WIDTH (1u) +#define CMP_C0_CFF_MASK (0x2000000u) +#define CMP_C0_CFF_SHIFT (25u) +#define CMP_C0_CFF_WIDTH (1u) +#define CMP_C0_CFR_MASK (0x4000000u) +#define CMP_C0_CFR_SHIFT (26u) +#define CMP_C0_CFR_WIDTH (1u) +#define CMP_C0_IEF_MASK (0x8000000u) +#define CMP_C0_IEF_SHIFT (27u) +#define CMP_C0_IEF_WIDTH (1u) +#define CMP_C0_IER_MASK (0x10000000u) +#define CMP_C0_IER_SHIFT (28u) +#define CMP_C0_IER_WIDTH (1u) +#define CMP_C0_LPFSEL_MASK (0x60000000u) +#define CMP_C0_LPFSEL_SHIFT (29u) +#define CMP_C0_LPFSEL_WIDTH (2u) +#define CMP_C0_DMAEN_MASK (0x80000000u) +#define CMP_C0_DMAEN_SHIFT (31u) +#define CMP_C0_DMAEN_WIDTH (1u) + +/* C1 Bit Fields */ +#define CMP_C1_VOSEL_MASK (0xFFu) +#define CMP_C1_VOSEL_SHIFT (0u) +#define CMP_C1_VOSEL_WIDTH (8u) +#define CMP_C1_MSEL_MASK (0x700u) +#define CMP_C1_MSEL_SHIFT (8u) +#define CMP_C1_MSEL_WIDTH (3u) +#define CMP_C1_PSEL_MASK (0x3800u) +#define CMP_C1_PSEL_SHIFT (11u) +#define CMP_C1_PSEL_WIDTH (3u) +#define CMP_C1_VRSEL_MASK (0x4000u) +#define CMP_C1_VRSEL_SHIFT (14u) +#define CMP_C1_VRSEL_WIDTH (1u) +#define CMP_C1_DACEN_MASK (0x8000u) +#define CMP_C1_DACEN_SHIFT (15u) +#define CMP_C1_DACEN_WIDTH (1u) +#define CMP_C1_CHN0_MASK (0x10000u) +#define CMP_C1_CHN0_SHIFT (16u) +#define CMP_C1_CHN0_WIDTH (1u) +#define CMP_C1_CHN1_MASK (0x20000u) +#define CMP_C1_CHN1_SHIFT (17u) +#define CMP_C1_CHN1_WIDTH (1u) +#define CMP_C1_CHN2_MASK (0x40000u) +#define CMP_C1_CHN2_SHIFT (18u) +#define CMP_C1_CHN2_WIDTH (1u) +#define CMP_C1_CHN3_MASK (0x80000u) +#define CMP_C1_CHN3_SHIFT (19u) +#define CMP_C1_CHN3_WIDTH (1u) +#define CMP_C1_CHN4_MASK (0x100000u) +#define CMP_C1_CHN4_SHIFT (20u) +#define CMP_C1_CHN4_WIDTH (1u) +#define CMP_C1_CHN5_MASK (0x200000u) +#define CMP_C1_CHN5_SHIFT (21u) +#define CMP_C1_CHN5_WIDTH (1u) +#define CMP_C1_CHN6_MASK (0x400000u) +#define CMP_C1_CHN6_SHIFT (22u) +#define CMP_C1_CHN6_WIDTH (1u) +#define CMP_C1_CHN7_MASK (0x800000u) +#define CMP_C1_CHN7_SHIFT (23u) +#define CMP_C1_CHN7_WIDTH (1u) +#define CMP_C1_INNSEL_MASK (0x3000000u) +#define CMP_C1_INNSEL_SHIFT (24u) +#define CMP_C1_INNSEL_WIDTH (2u) +#define CMP_C1_INPSEL_MASK (0x18000000u) +#define CMP_C1_INPSEL_SHIFT (27u) +#define CMP_C1_INPSEL_WIDTH (2u) + +/* C2 Bit Fields */ +#define CMP_C2_WITHOUT_W1C_MASK (0xFF00FFFFu) +#define CMP_C2_ACO0_MASK (0x1u) +#define CMP_C2_ACO0_SHIFT (0u) +#define CMP_C2_ACO0_WIDTH (1u) +#define CMP_C2_ACO1_MASK (0x2u) +#define CMP_C2_ACO1_SHIFT (1u) +#define CMP_C2_ACO1_WIDTH (1u) +#define CMP_C2_ACO2_MASK (0x4u) +#define CMP_C2_ACO2_SHIFT (2u) +#define CMP_C2_ACO2_WIDTH (1u) +#define CMP_C2_ACO3_MASK (0x8u) +#define CMP_C2_ACO3_SHIFT (3u) +#define CMP_C2_ACO3_WIDTH (1u) +#define CMP_C2_ACO4_MASK (0x10u) +#define CMP_C2_ACO4_SHIFT (4u) +#define CMP_C2_ACO4_WIDTH (1u) +#define CMP_C2_ACO5_MASK (0x20u) +#define CMP_C2_ACO5_SHIFT (5u) +#define CMP_C2_ACO5_WIDTH (1u) +#define CMP_C2_ACO6_MASK (0x40u) +#define CMP_C2_ACO6_SHIFT (6u) +#define CMP_C2_ACO6_WIDTH (1u) +#define CMP_C2_ACO7_MASK (0x80u) +#define CMP_C2_ACO7_SHIFT (7u) +#define CMP_C2_ACO7_WIDTH (1u) +#define CMP_C2_INITMOD_MASK (0x3F00u) +#define CMP_C2_INITMOD_SHIFT (8u) +#define CMP_C2_INITMOD_WIDTH (6u) +#define CMP_C2_NSAM_MASK (0xC000u) +#define CMP_C2_NSAM_SHIFT (14u) +#define CMP_C2_NSAM_WIDTH (2u) +#define CMP_C2_CHnF_MASK (0xFF0000u) +#define CMP_C2_CH0F_MASK (0x10000u) +#define CMP_C2_CH0F_SHIFT (16u) +#define CMP_C2_CH0F_WIDTH (1u) +#define CMP_C2_CH1F_MASK (0x20000u) +#define CMP_C2_CH1F_SHIFT (17u) +#define CMP_C2_CH1F_WIDTH (1u) +#define CMP_C2_CH2F_MASK (0x40000u) +#define CMP_C2_CH2F_SHIFT (18u) +#define CMP_C2_CH2F_WIDTH (1u) +#define CMP_C2_CH3F_MASK (0x80000u) +#define CMP_C2_CH3F_SHIFT (19u) +#define CMP_C2_CH3F_WIDTH (1u) +#define CMP_C2_CH4F_MASK (0x100000u) +#define CMP_C2_CH4F_SHIFT (20u) +#define CMP_C2_CH4F_WIDTH (1u) +#define CMP_C2_CH5F_MASK (0x200000u) +#define CMP_C2_CH5F_SHIFT (21u) +#define CMP_C2_CH5F_WIDTH (1u) +#define CMP_C2_CH6F_MASK (0x400000u) +#define CMP_C2_CH6F_SHIFT (22u) +#define CMP_C2_CH6F_WIDTH (1u) +#define CMP_C2_CH7F_MASK (0x800000u) +#define CMP_C2_CH7F_SHIFT (23u) +#define CMP_C2_CH7F_WIDTH (1u) +#define CMP_C2_FXMXCH_MASK (0xE000000u) +#define CMP_C2_FXMXCH_SHIFT (25u) +#define CMP_C2_FXMXCH_WIDTH (3u) +#define CMP_C2_FXMP_MASK (0x20000000u) +#define CMP_C2_FXMP_SHIFT (29u) +#define CMP_C2_FXMP_WIDTH (1u) +#define CMP_C2_RRIE_MASK (0x40000000u) +#define CMP_C2_RRIE_SHIFT (30u) +#define CMP_C2_RRIE_WIDTH (1u) +#define CMP_C2_RRE_MASK (0x80000000u) +#define CMP_C2_RRE_SHIFT (31u) +#define CMP_C2_RRE_WIDTH (1u) + +/* C4 Bit Fields */ +#define CMP_C4_LOCK_KEY_MASK (0xFFFFFFFFu) +#define CMP_C4_LOCK_KEY_SHIFT (0u) +#define CMP_C4_LOCK_KEY_WIDTH (32u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of CMP registers + */ +typedef struct _CmpRegType_ +{ + volatile uint32_t C0; /*!< CMP control register 0, offset: 0x0 */ + volatile uint32_t C1; /*!< CMP control register 1, offset: 0x4 */ + volatile uint32_t C2; /*!< CMP control register 2, offset: 0x8 */ + const volatile uint32_t C3; /*!< CMP control register 3, offset: 0xC */ + volatile uint32_t C4; /*!< CMP control register 4, offset: 0x10 */ +} CmpRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Get the current CMP LOCK_KEY register configuration + * + * This function gets the current CMP LOCK_KEY register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP LOCK_KEY register configuration. + */ +__attribute__((always_inline)) static inline uint32_t CmpReg_GetLockKeyReg(const CmpRegType *obj) +{ + return ((obj->C4 & CMP_C4_LOCK_KEY_MASK) >> CMP_C4_LOCK_KEY_SHIFT); +} + +/*! \brief Set CMP LOCK_KEY configuration for lock + * + * This function writes new configuration to CMP LOCK_KEY register for lock + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_LockReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C4; + tmp &= ~(CMP_C4_LOCK_KEY_MASK); + tmp |= (((uint32_t)(((uint32_t)(LOCK_KEY)) << CMP_C4_LOCK_KEY_SHIFT)) & CMP_C4_LOCK_KEY_MASK); + obj->C4 = tmp; +} + +/*! \brief Set CMP LOCK_KEY configuration for unlock + * + * This function writes new configuration to CMP LOCK_KEY register for unlock + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_UnlockReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C4; + tmp &= ~(CMP_C4_LOCK_KEY_MASK); + tmp |= (((uint32_t)(((uint32_t)(UNLOCK_KEY)) << CMP_C4_LOCK_KEY_SHIFT)) & CMP_C4_LOCK_KEY_MASK); + obj->C4 = tmp; +} + +/*! \brief Get the current CMP HYSTCTR register configuration + * + * This function gets the current CMP HYSTCTR register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP HYSTCTR register configuration. + * - 00b: The hard block output has level 0 hysteresis internally. + * - 01b: The hard block output has level 1 hysteresis internally. + * - 10b: The hard block output has level 2 hysteresis internally. + * - 11b: The hard block output has level 3 hysteresis internally. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetHystctrReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_HYSTCTR_MASK) >> CMP_C0_HYSTCTR_SHIFT); +} + +/*! \brief Set CMP HYSTCTR configuration + * + * This function writes new configuration to CMP HYSTCTR register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write protect by CMP_C4_LOCK_KEY + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP HYSTCTR register configuration + * - 00b: The hard block output has level 0 hysteresis internally. + * - 01b: The hard block output has level 1 hysteresis internally. + * - 10b: The hard block output has level 2 hysteresis internally. + * - 11b: The hard block output has level 3 hysteresis internally. + */ +__attribute__((always_inline)) static inline void CmpReg_SetHystctrReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_HYSTCTR_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_HYSTCTR_SHIFT)) & CMP_C0_HYSTCTR_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP OFFSET register configuration + * + * This function gets the current CMP OFFSET register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP OFFSET register configuration. + * - 0b: The comparator hard block output has level 0 offset internally. + * - 1b: The comparator hard block output has level 1 offset internally. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetOffsetReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_OFFSET_MASK) >> CMP_C0_OFFSET_SHIFT); +} + +/*! \brief Set CMP OFFSET configuration + * + * This function writes new configuration to CMP OFFSET register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write protect by CMP_C4_LOCK_KEY + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP OFFSET register configuration + * - 0b: The comparator hard block output has level 0 offset internally. + * - 1b: The comparator hard block output has level 1 offset internally. + */ +__attribute__((always_inline)) static inline void CmpReg_SetOffsetReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_OFFSET_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_OFFSET_SHIFT)) & CMP_C0_OFFSET_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP FILTER_CNT register configuration + * + * This function gets the current CMP FILTER_CNT register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP FILTER_CNT register configuration. + * - 000b: Filter is disabled. If SE = 1, then COUT is a logic zero (this is not a legal state, and is not recommended). If SE = 0, COUT = COUTA. + * - 001b: 1 consecutive sample must agree (comparator output is simply sampled). + * - 010b: 2 consecutive samples must agree. + * - 011b: 3 consecutive samples must agree. + * - 100b: 4 consecutive samples must agree. + * - 101b: 5 consecutive samples must agree. + * - 110b: 6 consecutive samples must agree. + * - 111b: 7 consecutive samples must agree. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetFilterCntReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_FILTER_CNT_MASK) >> CMP_C0_FILTER_CNT_SHIFT); +} + +/*! \brief Set CMP FILTER_CNT configuration + * + * This function writes new configuration to CMP FILTER_CNT register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP FILTER_CNT register configuration + * - 000b: Filter is disabled. If SE = 1, then COUT is a logic zero (this is not a legal state, and is not recommended). If SE = 0, COUT = COUTA. + * - 001b: 1 consecutive sample must agree (comparator output is simply sampled). + * - 010b: 2 consecutive samples must agree. + * - 011b: 3 consecutive samples must agree. + * - 100b: 4 consecutive samples must agree. + * - 101b: 5 consecutive samples must agree. + * - 110b: 6 consecutive samples must agree. + * - 111b: 7 consecutive samples must agree. + */ +__attribute__((always_inline)) static inline void CmpReg_SetFilterCntReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_FILTER_CNT_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_FILTER_CNT_SHIFT)) & CMP_C0_FILTER_CNT_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP EN register configuration + * + * This function gets the current CMP EN register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP EN register configuration. + * - 0b: Analog Comparator is disabled. + * - 1b: Analog Comparator is enabled. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetEnReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_EN_MASK) >> CMP_C0_EN_SHIFT); +} + +/*! \brief Set CMP EN configuration + * + * This function writes new configuration to CMP EN register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write protect by CMP_C4_LOCK_KEY + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP EN register configuration + * - 0b: Analog Comparator is disabled. + * - 1b: Analog Comparator is enabled. + */ +__attribute__((always_inline)) static inline void CmpReg_SetEnReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_EN_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_EN_SHIFT)) & CMP_C0_EN_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP OPE register configuration + * + * This function gets the current CMP OPE register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP OPE register configuration. + * - 0b: The comparator output (after window/filter settings dependent on software configuration) is not available to a packaged pin. + * - 1b: If the software has configured the comparator to own a packaged pin, the comparator is available in a packaged pin. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetOpeReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_OPE_MASK) >> CMP_C0_OPE_SHIFT); +} + +/*! \brief Set CMP OPE configuration + * + * This function writes new configuration to CMP OPE register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP OPE register configuration + * - 0b: The comparator output (after window/filter settings dependent on software configuration) is not available to a packaged pin. + * - 1b: If the software has configured the comparator to own a packaged pin, the comparator is available in a packaged pin. + */ +__attribute__((always_inline)) static inline void CmpReg_SetOpeReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_OPE_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_OPE_SHIFT)) & CMP_C0_OPE_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP COS register configuration + * + * This function gets the current CMP COS register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP COS register configuration. + * - 0b: Set CMPO to equal COUT (filtered comparator output). + * - 1b: Set CMPO to equal COUTA (unfiltered comparator output). + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCosReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_COS_MASK) >> CMP_C0_COS_SHIFT); +} + +/*! \brief Set CMP COS configuration + * + * This function writes new configuration to CMP COS register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP COS register configuration + * - 0b: Set CMPO to equal COUT (filtered comparator output). + * - 1b: Set CMPO to equal COUTA (unfiltered comparator output). + */ +__attribute__((always_inline)) static inline void CmpReg_SetCosReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_COS_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_COS_SHIFT)) & CMP_C0_COS_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP INVT register configuration + * + * This function gets the current CMP INVT register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP INVT register configuration. + * - 0b: Does not invert the comparator output. + * - 1b: Inverts the comparator output. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetInvtReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_INVT_MASK) >> CMP_C0_INVT_SHIFT); +} + +/*! \brief Set CMP INVT configuration + * + * This function writes new configuration to CMP INVT register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP INVT register configuration + * - 0b: Does not invert the comparator output. + * - 1b: Inverts the comparator output. + */ +__attribute__((always_inline)) static inline void CmpReg_SetInvtReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_INVT_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_INVT_SHIFT)) & CMP_C0_INVT_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP PMODE register configuration + * + * This function gets the current CMP PMODE register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP PMODE register configuration. + * - 0b: Low Speed (LS) comparison mode is selected. + * - 1b: High Speed (HS) comparison mode is selected, in VLPx mode, or Stop mode switched to Low Speed (LS) mode. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetPmodeReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_PMODE_MASK) >> CMP_C0_PMODE_SHIFT); +} + +/*! \brief Set CMP PMODE configuration + * + * This function writes new configuration to CMP PMODE register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write protect by CMP_C4_LOCK_KEY + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP PMODE register configuration + * - 0b: Low Speed (LS) comparison mode is selected. + * - 1b: High Speed (HS) comparison mode is selected, in VLPx mode, or Stop mode switched to Low Speed (LS) mode. + */ +__attribute__((always_inline)) static inline void CmpReg_SetPmodeReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_PMODE_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_PMODE_SHIFT)) & CMP_C0_PMODE_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP WE register configuration + * + * This function gets the current CMP WE register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP WE register configuration. + * - 0b: Windowing mode is not selected. + * - 1b: Windowing mode is selected. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetWeReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_WE_MASK) >> CMP_C0_WE_SHIFT); +} + +/*! \brief Set CMP WE configuration + * + * This function writes new configuration to CMP WE register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP WE register configuration + * - 0b: Windowing mode is not selected. + * - 1b: Windowing mode is selected. + */ +__attribute__((always_inline)) static inline void CmpReg_SetWeReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_WE_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_WE_SHIFT)) & CMP_C0_WE_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP SE register configuration + * + * This function gets the current CMP SE register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP SE register configuration. + * - 0b: Sampling mode is not selected. + * - 1b: Sampling mode is selected. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetSeReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_SE_MASK) >> CMP_C0_SE_SHIFT); +} + +/*! \brief Set CMP SE configuration + * + * This function writes new configuration to CMP SE register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP SE register configuration + * - 0b: Sampling mode is not selected. + * - 1b: Sampling mode is selected. + */ +__attribute__((always_inline)) static inline void CmpReg_SetSeReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_SE_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_SE_SHIFT)) & CMP_C0_SE_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP FPR register configuration + * + * This function gets the current CMP FPR register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP FPR register configuration. + * Specifies the sampling period, in bus clock cycles, of the comparator output filter, when C0[SE] = 0. + * -0b: disables the filter. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetFprReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_FPR_MASK) >> CMP_C0_FPR_SHIFT); +} + +/*! \brief Set CMP FPR configuration + * + * This function writes new configuration to CMP FPR register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP FPR register configuration + * Specifies the sampling period, in bus clock cycles, of the comparator output filter, when C0[SE] = 0. + * -0b: disables the filter. + */ +__attribute__((always_inline)) static inline void CmpReg_SetFprReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_FPR_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_FPR_SHIFT)) & CMP_C0_FPR_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP COUT register + * + * This function gets the current CMP COUT register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register read only + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP COUT register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCoutReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_COUT_MASK) >> CMP_C0_COUT_SHIFT); +} + +/*! \brief Get the current CMP CFF register + * + * This function gets the current CMP CFF register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CFF register configuration. + * - 0b: A falling edge has not been detected on COUT. + * - 1b: A falling edge on COUT has occurred. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCffReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_CFF_MASK) >> CMP_C0_CFF_SHIFT); +} + +/*! \brief Clear CMP CFF register + * + * This function clear CMP CFF register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write 1 to Clear + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_ClearCffReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_CFF_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(1u)) << CMP_C0_CFF_SHIFT)) & CMP_C0_CFF_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP CFR register + * + * This function gets the current CMP CFR register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CFR register configuration. + * - 0b: A rising edge has not been detected on COUT. + * - 1b: A rising edge on COUT has occurred. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCfrReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_CFR_MASK) >> CMP_C0_CFR_SHIFT); +} + +/*! \brief Clear CMP CFR register + * + * This function clear CMP CFR register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write 1 to Clear + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_ClearCfrReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_CFR_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(1u)) << CMP_C0_CFR_SHIFT)) & CMP_C0_CFR_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP IEF register configuration + * + * This function gets the current CMP IEF register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP IEF register configuration. + * - 0b: Interrupt is disabled. + * - 1b: Interrupt is enabled. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetIefReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_IEF_MASK) >> CMP_C0_IEF_SHIFT); +} + +/*! \brief Set CMP IEF configuration + * + * This function writes new configuration to CMP IEF register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP IEF register configuration + * - 0b: Interrupt is disabled. + * - 1b: Interrupt is enabled. + */ +__attribute__((always_inline)) static inline void CmpReg_SetIefReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_IEF_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_IEF_SHIFT)) & CMP_C0_IEF_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP IER register configuration + * + * This function gets the current CMP IER register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP IER register configuration. + * - 0b: Interrupt is disabled. + * - 1b: Interrupt is enabled. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetIerReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_IER_MASK) >> CMP_C0_IER_SHIFT); +} + +/*! \brief Set CMP IER configuration + * + * This function writes new configuration to CMP IER register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP IER register configuration + * - 0b: Interrupt is disabled. + * - 1b: Interrupt is enabled. + */ +__attribute__((always_inline)) static inline void CmpReg_SetIerReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_IER_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_IER_SHIFT)) & CMP_C0_IER_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP LPFSEL register configuration + * + * This function gets the current CMP LPFSEL register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP LPFSEL register configuration. + * - 00b: 23MHz + * - 01b: 16MHz + * - 10b: 13MHz + * - 11b: 10MHz + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetLpfselReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_LPFSEL_MASK) >> CMP_C0_LPFSEL_SHIFT); +} + +/*! \brief Set CMP LPFSEL configuration + * + * This function writes new configuration to CMP LPFSEL register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write protect by CMP_C4_LOCK_KEY + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP LPFSEL register configuration + * - 00b: 23MHz + * - 01b: 16MHz + * - 10b: 13MHz + * - 11b: 10MHz + */ +__attribute__((always_inline)) static inline void CmpReg_SetLpfselReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_LPFSEL_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_LPFSEL_SHIFT)) & CMP_C0_LPFSEL_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP DMAEN register configuration + * + * This function gets the current CMP DMAEN register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP DMAEN register configuration. + * - 0b: DMA is disabled. + * - 1b: DMA is enabled. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetDmaenReg(const CmpRegType *obj) +{ + return ((obj->C0 & CMP_C0_DMAEN_MASK) >> CMP_C0_DMAEN_SHIFT); +} + +/*! \brief Set CMP DMAEN configuration + * + * This function writes new configuration to CMP DMAEN register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP DMAEN register configuration + * - 0b: DMA is disabled. + * - 1b: DMA is enabled. + */ +__attribute__((always_inline)) static inline void CmpReg_SetDmaenReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C0; + tmp &= ~(CMP_C0_DMAEN_MASK); + tmp &= CMP_C0_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C0_DMAEN_SHIFT)) & CMP_C0_DMAEN_MASK); + obj->C0 = tmp; +} + +/*! \brief Get the current CMP VOSEL register configuration + * + * This function gets the current CMP VOSEL register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP VOSEL register configuration. + * DAC Output Voltage = (Vin/256) × (VOSEL[7:0] + 1). + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetVoselReg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_VOSEL_MASK) >> CMP_C1_VOSEL_SHIFT); +} + +/*! \brief Set CMP VOSEL configuration + * + * This function writes new configuration to CMP LPFSEL register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write protect by CMP_C4_LOCK_KEY + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP VOSEL register configuration + * DAC Output Voltage = (Vin/256) × (VOSEL[7:0] + 1). + */ +__attribute__((always_inline)) static inline void CmpReg_SetVoselReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_VOSEL_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_VOSEL_SHIFT)) & CMP_C1_VOSEL_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP MSEL register configuration + * + * This function gets the current CMP MSEL register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP MSEL register configuration. + * - 000b: IN0 + * - 001b: IN1 + * - 010b: IN2 + * - 011b: IN3 + * - 100b: IN4 + * - 101b: IN5 + * - 110b: IN6 + * - 111b: IN7 + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetMselReg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_MSEL_MASK) >> CMP_C1_MSEL_SHIFT); +} + +/*! \brief Set CMP MSEL configuration + * + * This function writes new configuration to CMP MSEL register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP MSEL register configuration + * - 000b: IN0 + * - 001b: IN1 + * - 010b: IN2 + * - 011b: IN3 + * - 100b: IN4 + * - 101b: IN5 + * - 110b: IN6 + * - 111b: IN7 + */ +__attribute__((always_inline)) static inline void CmpReg_SetMselReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_MSEL_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_MSEL_SHIFT)) & CMP_C1_MSEL_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP PSEL register configuration + * + * This function gets the current CMP PSEL register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP PSEL register configuration. + * - 000b: IN0 + * - 001b: IN1 + * - 010b: IN2 + * - 011b: IN3 + * - 100b: IN4 + * - 101b: IN5 + * - 110b: IN6 + * - 111b: IN7 + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetPselReg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_PSEL_MASK) >> CMP_C1_PSEL_SHIFT); +} + +/*! \brief Set CMP PSEL configuration + * + * This function writes new configuration to CMP PSEL register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP PSEL register configuration + * - 000b: IN0 + * - 001b: IN1 + * - 010b: IN2 + * - 011b: IN3 + * - 100b: IN4 + * - 101b: IN5 + * - 110b: IN6 + * - 111b: IN7 + */ +__attribute__((always_inline)) static inline void CmpReg_SetPselReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_PSEL_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_PSEL_SHIFT)) & CMP_C1_PSEL_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP VRSEL register configuration + * + * This function gets the current CMP VRSEL register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP VRSEL register configuration. + * - 0b: Vin1 is selected as resistor ladder network supply reference Vin. + * - 1b: Vin2 is selected as resistor ladder network supply reference Vin. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetVrselReg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_VRSEL_MASK) >> CMP_C1_VRSEL_SHIFT); +} + +/*! \brief Set CMP VRSEL configuration + * + * This function writes new configuration to CMP VRSEL register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write protect by CMP_C4_LOCK_KEY + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP VRSEL register configuration + * - 0b: Vin1 is selected as resistor ladder network supply reference Vin. + * - 1b: Vin2 is selected as resistor ladder network supply reference Vin. + */ +__attribute__((always_inline)) static inline void CmpReg_SetVrselReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_VRSEL_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_VRSEL_SHIFT)) & CMP_C1_VRSEL_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP DACEN register configuration + * + * This function gets the current CMP DACEN register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP DACEN register configuration. + * - 0b: DAC is disabled. + * - 1b: DAC is enabled. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetDacenReg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_DACEN_MASK) >> CMP_C1_DACEN_SHIFT); +} + +/*! \brief Set CMP DACEN configuration + * + * This function writes new configuration to CMP DACEN register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write protect by CMP_C4_LOCK_KEY + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP DACEN register configuration + * - 0b: DAC is disabled. + * - 1b: DAC is enabled. + */ +__attribute__((always_inline)) static inline void CmpReg_SetDacenReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_DACEN_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_DACEN_SHIFT)) & CMP_C1_DACEN_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP CHN0 register configuration + * + * This function gets the current CMP CHN0 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Channel 0 of the input enable for the round-robin checker. + * If CHN0 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CHN0 register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetChn0Reg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_CHN0_MASK) >> CMP_C1_CHN0_SHIFT); +} + +/*! \brief Set CMP CHN0 configuration + * + * This function writes new configuration to CMP CHN0 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 0 of the input enable for the round-robin checker. + * If CHN0 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP CHN0 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetChn0Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_CHN0_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_CHN0_SHIFT)) & CMP_C1_CHN0_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP CHN1 register configuration + * + * This function gets the current CMP CHN1 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 1 of the input enable for the round-robin checker. + * If CHN1 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CHN1 register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetChn1Reg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_CHN1_MASK) >> CMP_C1_CHN1_SHIFT); +} + +/*! \brief Set CMP CHN1 configuration + * + * This function writes new configuration to CMP CHN1 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 1 of the input enable for the round-robin checker. + * If CHN1 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP CHN1 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetChn1Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_CHN1_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_CHN1_SHIFT)) & CMP_C1_CHN1_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP CHN2 register configuration + * + * This function gets the current CMP CHN2 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 2 of the input enable for the round-robin checker. + * If CHN2 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CHN2 register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetChn2Reg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_CHN2_MASK) >> CMP_C1_CHN2_SHIFT); +} + +/*! \brief Set CMP CHN2 configuration + * + * This function writes new configuration to CMP CHN2 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 2 of the input enable for the round-robin checker. + * If CHN2 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP CHN2 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetChn2Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_CHN2_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_CHN2_SHIFT)) & CMP_C1_CHN2_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP CHN3 register configuration + * + * This function gets the current CMP CHN3 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 3 of the input enable for the round-robin checker. + * If CHN3 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CHN3 register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetChn3Reg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_CHN3_MASK) >> CMP_C1_CHN3_SHIFT); +} + +/*! \brief Set CMP CHN3 configuration + * + * This function writes new configuration to CMP CHN3 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 3 of the input enable for the round-robin checker. + * If CHN3 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP CHN3 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetChn3Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_CHN3_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_CHN3_SHIFT)) & CMP_C1_CHN3_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP CHN4 register configuration + * + * This function gets the current CMP CHN4 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 4 of the input enable for the round-robin checker. + * If CHN4 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CHN4 register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetChn4Reg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_CHN4_MASK) >> CMP_C1_CHN4_SHIFT); +} + +/*! \brief Set CMP CHN4 configuration + * + * This function writes new configuration to CMP CHN4 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 4 of the input enable for the round-robin checker. + * If CHN4 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP CHN4 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetChn4Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_CHN4_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_CHN4_SHIFT)) & CMP_C1_CHN4_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP CHN5 register configuration + * + * This function gets the current CMP CHN5 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 5 of the input enable for the round-robin checker. + * If CHN5 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CHN5 register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetChn5Reg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_CHN5_MASK) >> CMP_C1_CHN5_SHIFT); +} + +/*! \brief Set CMP CHN5 configuration + * + * This function writes new configuration to CMP CHN5 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 5 of the input enable for the round-robin checker. + * If CHN5 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP CHN5 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetChn5Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_CHN5_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_CHN5_SHIFT)) & CMP_C1_CHN5_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP CHN6 register configuration + * + * This function gets the current CMP CHN6 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 6 of the input enable for the round-robin checker. + * If CHN6 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CHN6 register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetChn6Reg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_CHN6_MASK) >> CMP_C1_CHN6_SHIFT); +} + +/*! \brief Set CMP CHN6 configuration + * + * This function writes new configuration to CMP CHN6 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 6 of the input enable for the round-robin checker. + * If CHN6 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP CHN6 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetChn6Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_CHN6_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_CHN6_SHIFT)) & CMP_C1_CHN6_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP CHN7 register configuration + * + * This function gets the current CMP CHN7 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 7 of the input enable for the round-robin checker. + * If CHN7 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CHN7 register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetChn7Reg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_CHN7_MASK) >> CMP_C1_CHN7_SHIFT); +} + +/*! \brief Set CMP CHN7 configuration + * + * This function writes new configuration to CMP CHN7 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * Set 1 for Channel 7 of the input enable for the round-robin checker. + * If CHN7 is set, then the corresponding channel to the non-fixed mux port is + * enabled to check its voltage value in the round-robin mode. If the same channel + * is selected as the reference voltage, this bit has no effect. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP CHN7 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetChn7Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_CHN7_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_CHN7_SHIFT)) & CMP_C1_CHN7_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP INNSEL register configuration + * + * This function gets the current CMP INNSEL register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP INNSEL register configuration. + * - 00b: IN0, from the 8-bit DAC output + * - 01b: IN1, from the analog 8-1 mux + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetInnselReg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_INNSEL_MASK) >> CMP_C1_INNSEL_SHIFT); +} + +/*! \brief Set CMP INNSEL configuration + * + * This function writes new configuration to CMP INNSEL register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write protect by CMP_C4_LOCK_KEY + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP INNSEL register configuration + * - 00b: IN0, from the 8-bit DAC output + * - 01b: IN1, from the analog 8-1 mux + */ +__attribute__((always_inline)) static inline void CmpReg_SetInnselReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_INNSEL_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_INNSEL_SHIFT)) & CMP_C1_INNSEL_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP INPSEL register configuration + * + * This function gets the current CMP INPSEL register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP INPSEL register configuration. + * - 00b: IN0, from the 8-bit DAC output + * - 01b: IN1, from the analog 8-1 mux + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetInpselReg(const CmpRegType *obj) +{ + return ((obj->C1 & CMP_C1_INPSEL_MASK) >> CMP_C1_INPSEL_SHIFT); +} + +/*! \brief Set CMP INPSEL configuration + * + * This function writes new configuration to CMP INPSEL register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write protect by CMP_C4_LOCK_KEY + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP INPSEL register configuration + * - 00b: IN0, from the 8-bit DAC output + * - 01b: IN1, from the analog 8-1 mux + */ +__attribute__((always_inline)) static inline void CmpReg_SetInpselReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C1; + tmp &= ~(CMP_C1_INPSEL_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C1_INPSEL_SHIFT)) & CMP_C1_INPSEL_MASK); + obj->C1 = tmp; +} + +/*! \brief Get the current CMP ACO0 register configuration + * + * This function gets the current CMP ACO0 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP ACO0 register configuration. + * This field stores the latest comparison result of the input channel 0 with the fixed mux port. + * Reading this bit returns the latest comparison result. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetAco0Reg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_ACO0_MASK) >> CMP_C2_ACO0_SHIFT); +} + +/*! \brief Set CMP ACO0 configuration + * + * This function writes new configuration to CMP ACO0 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * Writing this field defines the pre-set state of channel 0. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP ACO0 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetAco0Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_ACO0_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_ACO0_SHIFT)) & CMP_C2_ACO0_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP ACO1 register configuration + * + * This function gets the current CMP ACO1 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP ACO1 register configuration. + * This field stores the latest comparison result of the input channel 1 with the fixed mux port. + * Reading this bit returns the latest comparison result. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetAco1Reg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_ACO1_MASK) >> CMP_C2_ACO1_SHIFT); +} + +/*! \brief Set CMP ACO1 configuration + * + * This function writes new configuration to CMP ACO1 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * Writing this field defines the pre-set state of channel 1. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP ACO1 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetAco1Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_ACO1_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_ACO1_SHIFT)) & CMP_C2_ACO1_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP ACO2 register configuration + * + * This function gets the current CMP ACO2 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP ACO2 register configuration. + * This field stores the latest comparison result of the input channel 2 with the fixed mux port. + * Reading this bit returns the latest comparison result. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetAco2Reg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_ACO2_MASK) >> CMP_C2_ACO2_SHIFT); +} + +/*! \brief Set CMP ACO2 configuration + * + * This function writes new configuration to CMP ACO2 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * Writing this field defines the pre-set state of channel 2. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP ACO2 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetAco2Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_ACO2_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_ACO2_SHIFT)) & CMP_C2_ACO2_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP ACO3 register configuration + * + * This function gets the current CMP ACO3 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP ACO3 register configuration. + * This field stores the latest comparison result of the input channel 3 with the fixed mux port. + * Reading this bit returns the latest comparison result. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetAco3Reg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_ACO3_MASK) >> CMP_C2_ACO3_SHIFT); +} + +/*! \brief Set CMP ACO3 configuration + * + * This function writes new configuration to CMP ACO3 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * Writing this field defines the pre-set state of channel 3. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP ACO3 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetAco3Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_ACO3_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_ACO3_SHIFT)) & CMP_C2_ACO3_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP ACO4 register configuration + * + * This function gets the current CMP ACO4 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP ACO4 register configuration. + * This field stores the latest comparison result of the input channel 4 with the fixed mux port. + * Reading this bit returns the latest comparison result. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetAco4Reg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_ACO4_MASK) >> CMP_C2_ACO4_SHIFT); +} + +/*! \brief Set CMP ACO4 configuration + * + * This function writes new configuration to CMP ACO4 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * Writing this field defines the pre-set state of channel 4. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP ACO4 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetAco4Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_ACO4_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_ACO4_SHIFT)) & CMP_C2_ACO4_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP ACO5 register configuration + * + * This function gets the current CMP ACO5 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP ACO5 register configuration. + * This field stores the latest comparison result of the input channel 5 with the fixed mux port. + * Reading this bit returns the latest comparison result. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetAco5Reg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_ACO5_MASK) >> CMP_C2_ACO5_SHIFT); +} + +/*! \brief Set CMP ACO5 configuration + * + * This function writes new configuration to CMP ACO5 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * Writing this field defines the pre-set state of channel 5. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP ACO5 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetAco5Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_ACO5_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_ACO5_SHIFT)) & CMP_C2_ACO5_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP ACO6 register configuration + * + * This function gets the current CMP ACO6 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP ACO6 register configuration. + * This field stores the latest comparison result of the input channel 6 with the fixed mux port. + * Reading this bit returns the latest comparison result. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetAco6Reg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_ACO6_MASK) >> CMP_C2_ACO6_SHIFT); +} + +/*! \brief Set CMP ACO6 configuration + * + * This function writes new configuration to CMP ACO6 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * Writing this field defines the pre-set state of channel 6. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP ACO6 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetAco6Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_ACO6_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_ACO6_SHIFT)) & CMP_C2_ACO6_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP ACO7 register configuration + * + * This function gets the current CMP ACO7 register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP ACO7 register configuration. + * This field stores the latest comparison result of the input channel 7 with the fixed mux port. + * Reading this bit returns the latest comparison result. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetAco7Reg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_ACO7_MASK) >> CMP_C2_ACO7_SHIFT); +} + +/*! \brief Set CMP ACO7 configuration + * + * This function writes new configuration to CMP ACO7 register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * Writing this field defines the pre-set state of channel 7. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP ACO7 register configuration + */ +__attribute__((always_inline)) static inline void CmpReg_SetAco7Reg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_ACO7_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_ACO7_SHIFT)) & CMP_C2_ACO7_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP INITMOD register configuration + * + * This function gets the current CMP INITMOD register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP INITMOD register configuration. + * These values specify the round robin clock cycles used to determine the comparator and DAC initialization delays. + * - 000000b: The modulus is set to 64 (same with 111111). + * other values Initialization delay is set to INITMOD × round robin clock period + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetInitmodReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_INITMOD_MASK) >> CMP_C2_INITMOD_SHIFT); +} + +/*! \brief Set CMP INITMOD configuration + * + * This function writes new configuration to CMP INITMOD register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP INITMOD register configuration + * These values specify the round robin clock cycles used to determine the comparator and DAC initialization delays. + * - 000000b: The modulus is set to 64 (same with 111111). + * other values Initialization delay is set to INITMOD × round robin clock period + */ +__attribute__((always_inline)) static inline void CmpReg_SetInitmodReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_INITMOD_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_INITMOD_SHIFT)) & CMP_C2_INITMOD_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP NSAM register configuration + * + * This function gets the current CMP NSAM register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP NSAM register configuration. + * - 00b: The comparison result is sampled as soon as the active channel is scanned in one round-robin clock. + * - 01b: The sampling takes place 1 round-robin clock cycle after the next cycle of the round-robin clock. + * - 10b: The sampling takes place 2 round-robin clock cycles after the next cycle of the round-robin clock. + * - 11b: The sampling takes place 3 round-robin clock cycles after the next cycle of the round-robin clock. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetNsamReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_NSAM_MASK) >> CMP_C2_NSAM_SHIFT); +} + +/*! \brief Set CMP NSAM configuration + * + * This function writes new configuration to CMP NSAM register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP NSAM register configuration + * - 00b: The comparison result is sampled as soon as the active channel is scanned in one round-robin clock. + * - 01b: The sampling takes place 1 round-robin clock cycle after the next cycle of the round-robin clock. + * - 10b: The sampling takes place 2 round-robin clock cycles after the next cycle of the round-robin clock. + * - 11b: The sampling takes place 3 round-robin clock cycles after the next cycle of the round-robin clock. + */ +__attribute__((always_inline)) static inline void CmpReg_SetNsamReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_NSAM_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_NSAM_SHIFT)) & CMP_C2_NSAM_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP CH0F register + * + * This function gets the current CMP CH0F register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CH0F register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCh0fReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_CH0F_MASK) >> CMP_C2_CH0F_SHIFT); +} + +/*! \brief Clear CMP CH0F register + * + * This function clear CMP CH0F register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write 1 to Clear + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_ClearCh0fReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_CHnF_MASK); + tmp |= (((uint32_t)(((uint32_t)(1u)) << CMP_C2_CH0F_SHIFT)) & CMP_C2_CH0F_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP CH1F register + * + * This function gets the current CMP CH1F register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CH1F register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCh1fReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_CH1F_MASK) >> CMP_C2_CH1F_SHIFT); +} + +/*! \brief Clear CMP CH1F register + * + * This function clear CMP CH1F register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write 1 to Clear + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_ClearCh1fReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_CHnF_MASK); + tmp |= (((uint32_t)(((uint32_t)(1u)) << CMP_C2_CH1F_SHIFT)) & CMP_C2_CH1F_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP CH2F register + * + * This function gets the current CMP CH2F register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CH2F register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCh2fReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_CH2F_MASK) >> CMP_C2_CH2F_SHIFT); +} + +/*! \brief Clear CMP CH2F register + * + * This function clear CMP CH2F register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write 1 to Clear + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_ClearCh2fReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_CHnF_MASK); + tmp |= (((uint32_t)(((uint32_t)(1u)) << CMP_C2_CH2F_SHIFT)) & CMP_C2_CH2F_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP CH3F register + * + * This function gets the current CMP CH3F register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CH3F register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCh3fReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_CH3F_MASK) >> CMP_C2_CH3F_SHIFT); +} + +/*! \brief Clear CMP CH3F register + * + * This function clear CMP CH3F register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write 1 to Clear + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_ClearCh3fReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_CHnF_MASK); + tmp |= (((uint32_t)(((uint32_t)(1u)) << CMP_C2_CH3F_SHIFT)) & CMP_C2_CH3F_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP CH4F register + * + * This function gets the current CMP CH4F register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CH4F register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCh4fReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_CH4F_MASK) >> CMP_C2_CH4F_SHIFT); +} + +/*! \brief Clear CMP CH4F register + * + * This function clear CMP CH4F register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write 1 to Clear + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_ClearCh4fReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_CHnF_MASK); + tmp |= (((uint32_t)(((uint32_t)(1u)) << CMP_C2_CH4F_SHIFT)) & CMP_C2_CH4F_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP CH5F register + * + * This function gets the current CMP CH5F register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CH5F register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCh5fReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_CH5F_MASK) >> CMP_C2_CH5F_SHIFT); +} + +/*! \brief Clear CMP CH5F register + * + * This function clear CMP CH5F register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write 1 to Clear + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_ClearCh5fReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_CHnF_MASK); + tmp |= (((uint32_t)(((uint32_t)(1u)) << CMP_C2_CH5F_SHIFT)) & CMP_C2_CH5F_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP CH6F register + * + * This function gets the current CMP CH6F register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CH6F register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCh6fReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_CH6F_MASK) >> CMP_C2_CH6F_SHIFT); +} + +/*! \brief Clear CMP CH6F register + * + * This function clear CMP CH6F register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write 1 to Clear + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_ClearCh6fReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_CHnF_MASK); + tmp |= (((uint32_t)(((uint32_t)(1u)) << CMP_C2_CH6F_SHIFT)) & CMP_C2_CH6F_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP CH7F register + * + * This function gets the current CMP CH6F register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP CH7F register configuration. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetCh7fReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_CH7F_MASK) >> CMP_C2_CH7F_SHIFT); +} + +/*! \brief Clear CMP CH7F register + * + * This function clear CMP CH7F register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * This register write 1 to Clear + * + * \param[in] obj : pointer to CMP register instance + */ +__attribute__((always_inline)) static inline void CmpReg_ClearCh7fReg(CmpRegType *obj) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_CHnF_MASK); + tmp |= (((uint32_t)(((uint32_t)(1u)) << CMP_C2_CH7F_SHIFT)) & CMP_C2_CH7F_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP FXMXCH register + * + * This function gets the current CMP FXMXCH register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP FXMXCH register configuration. + * - 000b: Channel 0 is selected as the fixed reference input for the fixed mux port. + * - 001b: Channel 1 is selected as the fixed reference input for the fixed mux port. + * - 010b: Channel 2 is selected as the fixed reference input for the fixed mux port. + * - 011b: Channel 3 is selected as the fixed reference input for the fixed mux port. + * - 100b: Channel 4 is selected as the fixed reference input for the fixed mux port. + * - 101b: Channel 5 is selected as the fixed reference input for the fixed mux port. + * - 110b: Channel 6 is selected as the fixed reference input for the fixed mux port. + * - 111b: Channel 7 is selected as the fixed reference input for the fixed mux port. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetFxmxchReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_FXMXCH_MASK) >> CMP_C2_FXMXCH_SHIFT); +} + +/*! \brief Set CMP FXMXCH configuration + * + * This function writes new configuration to CMP FXMXCH register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP FXMXCH register configuration + * - 000b: Channel 0 is selected as the fixed reference input for the fixed mux port. + * - 001b: Channel 1 is selected as the fixed reference input for the fixed mux port. + * - 010b: Channel 2 is selected as the fixed reference input for the fixed mux port. + * - 011b: Channel 3 is selected as the fixed reference input for the fixed mux port. + * - 100b: Channel 4 is selected as the fixed reference input for the fixed mux port. + * - 101b: Channel 5 is selected as the fixed reference input for the fixed mux port. + * - 110b: Channel 6 is selected as the fixed reference input for the fixed mux port. + * - 111b: Channel 7 is selected as the fixed reference input for the fixed mux port. + */ +__attribute__((always_inline)) static inline void CmpReg_SetFxmxchReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_FXMXCH_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_FXMXCH_SHIFT)) & CMP_C2_FXMXCH_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP FXMP register + * + * This function gets the current CMP FXMP register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP FXMP register configuration. + * 0b: The Plus port is fixed. Only the inputs to the Minus port are swept in each round. + * 1b: The Minus port is fixed. Only the inputs to the Plus port are swept in each round. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetFxmpReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_FXMP_MASK) >> CMP_C2_FXMP_SHIFT); +} + +/*! \brief Set CMP FXMP configuration + * + * This function writes new configuration to CMP FXMP register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP FXMP register configuration + * 0b: The Plus port is fixed. Only the inputs to the Minus port are swept in each round. + * 1b: The Minus port is fixed. Only the inputs to the Plus port are swept in each round. + */ +__attribute__((always_inline)) static inline void CmpReg_SetFxmpReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_FXMP_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_FXMP_SHIFT)) & CMP_C2_FXMP_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP RRIE register + * + * This function gets the current CMP RRIE register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP RRIE register configuration. + * - 0b: The round-robin interrupt is disabled. + * - 1b: The round-robin interrupt is enabled when a comparison result changes from the last sample. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetRrieReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_RRIE_MASK) >> CMP_C2_RRIE_SHIFT); +} + +/*! \brief Set CMP RRIE configuration + * + * This function writes new configuration to CMP RRIE register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP RRIE register configuration + * - 0b: The round-robin interrupt is disabled. + * - 1b: The round-robin interrupt is enabled when a comparison result changes from the last sample. + */ +__attribute__((always_inline)) static inline void CmpReg_SetRrieReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_RRIE_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_RRIE_SHIFT)) & CMP_C2_RRIE_MASK); + obj->C2 = tmp; +} + +/*! \brief Get the current CMP RRE register + * + * This function gets the current CMP RRE register . + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \return the current CMP RRE register configuration. + * - 0b: Round-robin operation is disabled. + * - 1b: Round-robin operation is enabled. + */ +__attribute__((always_inline)) static inline uint8_t CmpReg_GetRreReg(const CmpRegType *obj) +{ + return ((obj->C2 & CMP_C2_RRE_MASK) >> CMP_C2_RRE_SHIFT); +} + +/*! \brief Set CMP RRE configuration + * + * This function writes new configuration to CMP RRE register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CMP register instance + * \param[in] value : expected CMP RRE register configuration + * - 0b: Round-robin operation is disabled. + * - 1b: Round-robin operation is enabled. + */ +__attribute__((always_inline)) static inline void CmpReg_SetRreReg(CmpRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->C2; + tmp &= ~(CMP_C2_RRE_MASK); + tmp &= CMP_C2_WITHOUT_W1C_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMP_C2_RRE_SHIFT)) & CMP_C2_RRE_MASK); + obj->C2 = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _CMP_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/cmu_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/cmu_reg.h new file mode 100644 index 0000000..6567b31 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/cmu_reg.h @@ -0,0 +1,413 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CMU_REG_H_ +#define _CMU_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the CMU Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* GCR Bit Fields */ +#define CMU_GCR_EN_MASK (0x01u) +#define CMU_GCR_EN_SHIFT (0u) +#define CMU_GCR_EN_WIDTH (1u) + +/* RCCR Bit Fields */ +#define CMU_RCCR_REF_CNT_MASK (0xFFFFu) +#define CMU_RCCR_REF_CNT_SHIFT (0u) +#define CMU_RCCR_REF_CNT_WIDTH (16u) + +/* HTCR Bit Fields */ +#define CMU_HTCR_HFREF_MASK (0xFFFFFFu) +#define CMU_HTCR_HFREF_SHIFT (0u) +#define CMU_HTCR_HFREF_WIDTH (24u) + +/* LTCR Bit Fields */ +#define CMU_LTCR_LFREF_MASK (0xFFFFFFu) +#define CMU_LTCR_LFREF_SHIFT (0u) +#define CMU_LTCR_LFREF_WIDTH (24u) + +/* SR Bit Fields */ +#define CMU_SR_RS_MASK (0x10u) +#define CMU_SR_RS_SHIFT (4u) +#define CMU_SR_RS_WIDTH (1u) +#define CMU_SR_FHH_MASK (0x02u) +#define CMU_SR_FHH_SHIFT (1u) +#define CMU_SR_FHH_WIDTH (1u) +#define CMU_SR_FLL_MASK (0x01u) +#define CMU_SR_FLL_SHIFT (0u) +#define CMU_SR_FLL_WIDTH (1u) + +/* IER Bit Fields */ +#define CMU_IER_FHHIE_MASK (0x0Cu) +#define CMU_IER_FHHIE_SHIFT (2u) +#define CMU_IER_FHHIE_WIDTH (2u) +#define CMU_IER_FLLIE_MASK (0x03u) +#define CMU_IER_FLLIE_SHIFT (0u) +#define CMU_IER_FLLIE_WIDTH (2u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of CMU registers + */ +typedef struct _CmuRegType_ +{ + volatile uint32_t GCR; /*!< CMU global config register, offset: 0x0 */ + volatile uint32_t RCCR; /*!< CMU reference counter value config register, offset: 0x4 */ + volatile uint32_t HTCR; /*!< CMU high threshold value config register, offset: 0x8 */ + volatile uint32_t LTCR; /*!< CMU low threshold value config register, offset: 0xC */ + volatile uint32_t SR; /*!< CMU status register, offset: 0x10 */ + volatile uint32_t IER; /*!< CMU interrupt enable register, offset: 0x14 */ +} CmuRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the CMU enable + * + * This function gets the CMU enable + * + * \param[in] obj : pointer to CMU register instance + * \return CMU enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t CmuReg_GetEnable(const CmuRegType *obj) +{ + return ((obj->GCR & CMU_GCR_EN_MASK) >> CMU_GCR_EN_SHIFT); +} + +/*! \brief Sets the CMU enable + * + * This function sets the CMU enable + * + * \param[in] obj : pointer to CMU register instance + * \param[in] value : the value of CMU enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void CmuReg_SetEnable(CmuRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->GCR; + + tmp &= ~CMU_GCR_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMU_GCR_EN_SHIFT)) & CMU_GCR_EN_MASK); + obj->GCR = tmp; +} + +/*! \brief Gets the reference counter value + * + * This function gets the reference counter value + * + * \param[in] obj : pointer to CMU register instance + * \return reference counter value + * - 0000h : 0 + * - 0001h : 1 + * - 0002h : 2 + * . + * . + * . + * - FFFFh : 65535 + */ +__attribute__((always_inline)) static inline uint32_t CmuReg_GetRefCnt(const CmuRegType *obj) +{ + return ((obj->RCCR & CMU_RCCR_REF_CNT_MASK) >> CMU_RCCR_REF_CNT_SHIFT); +} + +/*! \brief Sets the reference counter value + * + * This function sets the reference counter value + * + * \param[in] obj : pointer to CMU register instance + * \param[in] value : reference counter value + * - 0000h : 0 + * - 0001h : 1 + * - 0002h : 2 + * . + * . + * . + * - FFFFh : 65535 + */ +__attribute__((always_inline)) static inline void CmuReg_SetRefCnt(CmuRegType *obj, uint32_t value) +{ + uint32_t tmp = obj->RCCR; + + tmp &= ~CMU_RCCR_REF_CNT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMU_RCCR_REF_CNT_SHIFT)) & CMU_RCCR_REF_CNT_MASK); + obj->RCCR = tmp; +} + +/*! \brief Gets the high threshold value + * + * This function gets the high threshold value + * + * \param[in] obj : pointer to CMU register instance + * \return high threshold value + * - 000000h : 0 + * - 000001h : 1 + * - 000002h : 2 + * . + * . + * . + * - FFFFFFh : 16,777,215 + */ +__attribute__((always_inline)) static inline uint32_t CmuReg_GetFreqHighRefValue(const CmuRegType *obj) +{ + return ((obj->HTCR & CMU_HTCR_HFREF_MASK) >> CMU_HTCR_HFREF_SHIFT); +} + +/*! \brief Sets the high threshold value + * + * This function sets the high threshold value + * + * \param[in] obj : pointer to CMU register instance + * \param[in] value : high threshold value + * - 000000h : 0 + * - 000001h : 1 + * - 000002h : 2 + * . + * . + * . + * - FFFFFFh : 16,777,215 + */ +__attribute__((always_inline)) static inline void CmuReg_SetFreqHighRefValue(CmuRegType *obj, uint32_t value) +{ + uint32_t tmp = obj->HTCR; + + tmp &= ~CMU_HTCR_HFREF_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMU_HTCR_HFREF_SHIFT)) & CMU_HTCR_HFREF_MASK); + obj->HTCR = tmp; +} + +/*! \brief Gets the low threshold value + * + * This function gets the low threshold value + * + * \param[in] obj : pointer to CMU register instance + * \return low threshold value + * - 000000h : 0 + * - 000001h : 1 + * - 000002h : 2 + * . + * . + * . + * - FFFFFFh : 16,777,215 + */ +__attribute__((always_inline)) static inline uint32_t CmuReg_GetFreqLowRefValue(const CmuRegType *obj) +{ + return ((obj->LTCR & CMU_LTCR_LFREF_MASK) >> CMU_LTCR_LFREF_SHIFT); +} + +/*! \brief Sets the low threshold value + * + * This function sets the low threshold value + * + * \param[in] obj : pointer to CMU register instance + * \param[in] value : low threshold value + * - 000000h : 0 + * - 000001h : 1 + * - 000002h : 2 + * . + * . + * . + * - FFFFFFh : 16,777,215 + */ +__attribute__((always_inline)) static inline void CmuReg_SetFreqLowRefValue(CmuRegType *obj, uint32_t value) +{ + uint32_t tmp = obj->LTCR; + + tmp &= ~CMU_LTCR_LFREF_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMU_LTCR_LFREF_SHIFT)) & CMU_LTCR_LFREF_MASK); + obj->LTCR = tmp; +} + +/*! \brief Gets the CMU run status + * + * Indicates the CMU run status + * + * \param[in] obj : pointer to CMU register instance + * \return CMU run status + * - 0b : false + * - 1b : true + */ +__attribute__((always_inline)) static inline uint8_t CmuReg_GetRunStatus(const CmuRegType *obj) +{ + return ((obj->SR & CMU_SR_RS_MASK) >> CMU_SR_RS_SHIFT); +} + +/*! \brief Gets the frequency higher event flag + * + * FHH is set when the CMU is enabled and the frequency detected is higher than high threshold value + * + * \param[in] obj : pointer to CMU register instance + * \return frequency higher event flag + * - 0b : false + * - 1b : true + */ +__attribute__((always_inline)) static inline uint8_t CmuReg_GetFreqHighEventFlag(const CmuRegType *obj) +{ + return ((obj->SR & CMU_SR_FHH_MASK) >> CMU_SR_FHH_SHIFT); +} + +/*! \brief Clear the frequency higher event flag + * + * FHH is cleared when a logic 1 is written to it. + * + * \param[in] obj : pointer to CMU register instance + * \return none + * + */ +__attribute__((always_inline)) static inline void CmuReg_ClearFreqHighEventFlag(CmuRegType *obj) +{ + uint32_t tmp = obj->SR; + tmp &= ~(CMU_SR_FHH_MASK | CMU_SR_FLL_MASK); + tmp |= (CMU_SR_FHH_MASK); + obj->SR = tmp; + /* Read back to avoid problem */ + (void)obj->SR; +} + +/*! \brief Gets the frequency lower event flag + * + * FLL is set when the CMU is enabled and the frequency detected is lower than low threshold value + * + * \param[in] obj : pointer to CMU register instance + * \return frequency Lower event flag + * - 0b : false + * - 1b : true + */ +__attribute__((always_inline)) static inline uint8_t CmuReg_GetFreqLowEventFlag(const CmuRegType *obj) +{ + return ((obj->SR & CMU_SR_FLL_MASK) >> CMU_SR_FLL_SHIFT); +} + +/*! \brief Clear the frequency lower event flag + * + * FHH is cleared when a logic 1 is written to it. + * + * \param[in] obj : pointer to CMU register instance + * \return none + * + */ +__attribute__((always_inline)) static inline void CmuReg_ClearFreqLowEventFlag(CmuRegType *obj) +{ + uint32_t tmp = obj->SR; + tmp &= ~(CMU_SR_FHH_MASK | CMU_SR_FLL_MASK); + tmp |= (CMU_SR_FLL_MASK); + obj->SR = tmp; + /* Read back to avoid problem */ + (void)obj->SR; +} + +/*! \brief Gets the frequency high event state + * + * This function gets the frequency high event state + * + * \param[in] obj : pointer to CMU register instance + * \return frequency higher interrupt enable + * - 00b : interrupt and reset disable + * - 01b : interrupt enable, reset disable + * - 10b : interrupt disable, reset enable + * - 11b : interrupt disable, reset enable + */ +__attribute__((always_inline)) static inline uint8_t CmuReg_GetFreqHighEventState(const CmuRegType *obj) +{ + return ((obj->IER & CMU_IER_FHHIE_MASK) >> CMU_IER_FHHIE_SHIFT); +} + +/*! \brief Sets the frequency high event state + * + * This function sets the frequency high event state + * + * \param[in] obj : pointer to CMU register instance + * \param[in] value : the value of the frequency high event state + * - 00b : interrupt and reset disable + * - 01b : interrupt enable, reset disable + * - 10b : interrupt disable, reset enable + * - 11b : interrupt disable, reset enable + */ +__attribute__((always_inline)) static inline void CmuReg_SetFreqHighEventState(CmuRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IER; + + tmp &= ~CMU_IER_FHHIE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMU_IER_FHHIE_SHIFT)) & CMU_IER_FHHIE_MASK); + obj->IER = tmp; +} + +/*! \brief Gets the frequency low event state + * + * This function gets the frequency low event state + * + * \param[in] obj : pointer to CMU register instance + * \return frequency lower interrupt enable + * - 00b : interrupt and reset disable + * - 01b : interrupt enable, reset disable + * - 10b : interrupt disable, reset enable + * - 11b : interrupt disable, reset enable + */ +__attribute__((always_inline)) static inline uint8_t CmuReg_GetFreqLowEventState(const CmuRegType *obj) +{ + return ((obj->IER & CMU_IER_FLLIE_MASK) >> CMU_IER_FLLIE_SHIFT); +} + +/*! \brief Sets the frequency low event state + * + * This function sets the frequency low event state + * + * \param[in] obj : pointer to CMU register instance + * \param[in] value : the value of the frequency low event state + * - 00b : interrupt and reset disable + * - 01b : interrupt enable, reset disable + * - 10b : interrupt disable, reset enable + * - 11b : interrupt disable, reset enable + */ +__attribute__((always_inline)) static inline void CmuReg_SetFreqLowEventState(CmuRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IER; + + tmp &= ~CMU_IER_FLLIE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << CMU_IER_FLLIE_SHIFT)) & CMU_IER_FLLIE_MASK); + obj->IER = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _CMU_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/crc_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/crc_reg.h new file mode 100644 index 0000000..dcb304a --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/crc_reg.h @@ -0,0 +1,416 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CRC_REG_H_ +#define _CRC_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the CRC Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* DR Bit Fields */ +#define CRC_DR_DR_MASK (0xFFFFFFFFu) +#define CRC_DR_DR_SHIFT (0u) +#define CRC_DR_DR_WIDTH (32u) + +/* IDR Bit Fields */ +#define CRC_IDR_COUNTER_MASK (0xFu) +#define CRC_IDR_COUNTER_SHIFT (0u) +#define CRC_IDR_COUNTER_WIDTH (4u) + +/* CR Bit Fields */ +#define CRC_CR_RESET_MASK (0x1u) +#define CRC_CR_RESET_SHIFT (0u) +#define CRC_CR_RESET_WIDTH (1u) +#define CRC_CR_REVIN_MASK (0x60u) +#define CRC_CR_REVIN_SHIFT (5u) +#define CRC_CR_REVIN_WIDTH (2u) +#define CRC_CR_REVOUT_MASK (0x300u) +#define CRC_CR_REVOUT_SHIFT (8u) +#define CRC_CR_REVOUT_WIDTH (2u) +#define CRC_CR_FXOR_MASK (0x800u) +#define CRC_CR_FXOR_SHIFT (11u) +#define CRC_CR_FXOR_WIDTH (1u) +#define CRC_CR_TCRC_MASK (0x1000u) +#define CRC_CR_TCRC_SHIFT (12u) +#define CRC_CR_TCRC_WIDTH (1u) + +/* INIT Bit Fields */ +#define CRC_INIT_INIT_MASK (0xFFFFFFFFu) +#define CRC_INIT_INIT_SHIFT (0u) +#define CRC_INIT_INIT_WIDTH (32u) + +/* POL Bit Fields */ +#define CRC_POL_POL_MASK (0xFFFFFFFFu) +#define CRC_POL_POL_SHIFT (0u) +#define CRC_POL_POL_WIDTH (32u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of CRC registers + */ +typedef struct _CrcRegType_ +{ + union + { + volatile uint32_t DATA_32; /*!< CRC data storage register, offset: 0x0 */ + struct + { + volatile uint16_t L; /*!< CRC_DR_L, offset: 0x0 */ + volatile uint16_t H; /*!< CRC_DR_L, offset: 0x2 */ + } DATA_16; + struct + { + volatile uint8_t LL; /*!< CRC_DR_LL, offset: 0x0 */ + volatile uint8_t LU; /*!< CRC_DR_LU, offset: 0x1 */ + volatile uint8_t HL; /*!< CRC_DR_HL, offset: 0x2 */ + volatile uint8_t HU; /*!< CRC_DR_HU, offset: 0x3 */ + } DATA_8; + } DR; + volatile uint32_t IDR; /*!< CRC data length register, offset: 0x4 */ + volatile uint32_t CR; /*!< CRC control register, offset: 0x8 */ + uint32_t RESERVED; /*!< Reserved register, offset: 0xC */ + volatile uint32_t INIT; /*!< Initial seed value register, offset: 0x10 */ + volatile uint32_t POL; /*!< Initial value of polynormal register, offset: 0x14 */ +} CrcRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Get the current CRC data register + * + * This function gets the current CRC calculation result. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * If CR.RESET happen, it holds the crc_init value + * + * \param[in] obj : pointer to CRC register instance + * \return the current CRC calculation result + */ +__attribute__((always_inline)) static inline uint32_t CrcReg_GetDataReg(const CrcRegType *obj) +{ + return obj->DR.DATA_32; +} + +/*! \brief Set the 32 bits of CRC data register + * + * This function writes new 32 bits data to CRC calculator + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CRC register instance + * \param[in] value : current CRC calculation data + */ +__attribute__((always_inline)) static inline void CrcReg_SetDataReg(CrcRegType *obj, uint32_t value) +{ + obj->DR.DATA_32 = value; +} + +/*! \brief Set the 16 bits of CRC data register + * + * This function writes new 16 bits data to CRC calculator + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CRC register instance + * \param[in] value : current CRC calculation data + */ +__attribute__((always_inline)) static inline void CrcReg_SetData16Reg(CrcRegType *obj, uint16_t value) +{ + obj->DR.DATA_16.L = value; +} + +/*! \brief Set the 8 bits of CRC data register + * + * This function writes new 8 bits data to CRC calculator + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to CRC register instance + * \param[in] value : current CRC calculation data + */ +__attribute__((always_inline)) static inline void CrcReg_SetData8Reg(CrcRegType *obj, uint8_t value) +{ + obj->DR.DATA_8.LL = value; +} + +/*! \brief Get the remain number of data in FIFO + * + * Total depth is 8, the register shows the remain number of data in fifo + * Counter reset to 0 if CR.RESET happened + * This register is read-only + * + * \param[in] obj : pointer to CRC register instance + * \return the remain number of data in fifo + */ +__attribute__((always_inline)) static inline uint32_t CrcReg_GetDataNumInFifo(const CrcRegType *obj) +{ + return ((obj->IDR & CRC_IDR_COUNTER_MASK) >> CRC_IDR_COUNTER_SHIFT); +} + +/*! \brief Get the reset bit in CR register + * + * This bit is automatically cleared by hardware. + * Read as 1 , assert to 1 after reading + * + * \param[in] obj : pointer to CRC register instance + * \return the reset bit value + */ +__attribute__((always_inline)) static inline uint8_t CrcReg_GetCrReset(const CrcRegType *obj) +{ + return ((obj->CR & CRC_CR_RESET_MASK) >> CRC_CR_RESET_SHIFT); +} + +/*! \brief Set the reset bit in CR register + * + * This bit is set to reset CRC calculation unit and set data register to the value stored in CRC_INIT + * + * \param[in] obj : pointer to CRC register instance + */ +__attribute__((always_inline)) static inline void CrcReg_SetCrReset(CrcRegType *obj) +{ + uint32_t crTmp = obj->CR; + + crTmp &= ~(CRC_CR_RESET_MASK); + crTmp |= (((uint32_t)(((uint32_t)(1u)) << CRC_CR_RESET_SHIFT)) & CRC_CR_RESET_MASK); + obj->CR = crTmp; +} + +/*! \brief Get the reversal of bit order of the input data + * + * These bits control the reversal of the bit order of the input data + * This register is not affected by CRC resets generated by the reset bit in the CRC_CR register + * + * \param[in] obj : pointer to CRC register instance + * \return the value of reversal of bit order + * - 0 : No transposition. + * - 1 : Bits in bytes are transposed; bytes are not transposed. + * - 2 : Both bits in bytes and bytes are transposed + * - 3 : Only bytes are transposed; no bits in a byte are transposed + */ +__attribute__((always_inline)) static inline uint8_t CrcReg_GetCrReverseIn(const CrcRegType *obj) +{ + return ((obj->CR & CRC_CR_REVIN_MASK) >> CRC_CR_REVIN_SHIFT); +} + +/*! \brief Set the reversal of bit order of the input data + * + * These bits control the reversal of the bit order of the input data + * This register is not affected by CRC resets generated by the reset bit in the CRC_CR register + * + * \param[in] obj : pointer to CRC register instance + * \param[in] value : the value of reversal of bit order + * - 0 : No transposition. + * - 1 : Bits in bytes are transposed; bytes are not transposed. + * - 2 : Both bits in bytes and bytes are transposed + * - 3 : Only bytes are transposed; no bits in a byte are transposed + */ +__attribute__((always_inline)) static inline void CrcReg_SetCrReverseIn(CrcRegType *obj, uint8_t value) +{ + uint32_t crTmp = obj->CR; + + crTmp &= ~(CRC_CR_REVIN_MASK); + crTmp |= (((uint32_t)(((uint32_t)(value)) << CRC_CR_REVIN_SHIFT)) & CRC_CR_REVIN_MASK); + obj->CR = crTmp; +} + +/*! \brief Get the reversal of bit order of the output data + * + * These bits control the reversal of the bit order of the output data + * This register is not affected by CRC resets generated by the reset bit in the CRC_CR register + * + * \param[in] obj : pointer to CRC register instance + * \return the value of reversal of bit order + * - 0 : No transposition. + * - 1 : Bits in bytes are transposed; bytes are not transposed. + * - 2 : Both bits in bytes and bytes are transposed + * - 3 : Only bytes are transposed; no bits in a byte are transposed + */ +__attribute__((always_inline)) static inline uint8_t CrcReg_GetCrReverseOut(const CrcRegType *obj) +{ + return ((obj->CR & CRC_CR_REVOUT_MASK) >> CRC_CR_REVOUT_SHIFT); +} + +/*! \brief Set the reversal of bit order of the output data + * + * These bits control the reversal of the bit order of the output data + * This register is not affected by CRC resets generated by the reset bit in the CRC_CR register + * + * \param[in] obj : pointer to CRC register instance + * \param[in] value : the value of reversal of bit order + * - 0 : No transposition. + * - 1 : Bits in bytes are transposed; bytes are not transposed. + * - 2 : Both bits in bytes and bytes are transposed + * - 3 : Only bytes are transposed; no bits in a byte are transposed + */ +__attribute__((always_inline)) static inline void CrcReg_SetCrReverseOut(CrcRegType *obj, uint8_t value) +{ + uint32_t crTmp = obj->CR; + + crTmp &= ~(CRC_CR_REVOUT_MASK); + crTmp |= (((uint32_t)(((uint32_t)(value)) << CRC_CR_REVOUT_SHIFT)) & CRC_CR_REVOUT_MASK); + obj->CR = crTmp; +} + +/*! \brief Get complement read of CRC data register + * + * Some CRC protocols require the final checksum to be XORed with 0xFFFFFFFF or 0xFFFF. + * Asserting this bit enables on the fly complementing of read data. + * This register is not affected by CRC resets generated by the reset bit in the CRC_CR register. + * + * \param[in] obj : pointer to CRC register instance + * \return the value of complement read + * - 0 : No XOR on reading. + * - 1 : Invert or complement the read value of the CRC Data register. + */ +__attribute__((always_inline)) static inline uint8_t CrcReg_GetCrFXor(const CrcRegType *obj) +{ + return ((obj->CR & CRC_CR_FXOR_MASK) >> CRC_CR_FXOR_SHIFT); +} + +/*! \brief Set complement read of CRC data register + * + * Some CRC protocols require the final checksum to be XORed with 0xFFFFFFFF or 0xFFFF. + * Asserting this bit enables on the fly complementing of read data. + * This register is not affected by CRC resets generated by the reset bit in the CRC_CR register. + * + * \param[in] obj : pointer to CRC register instance + * \param[in] value : the value of complement read + * - 0 : No XOR on reading. + * - 1 : Invert or complement the read value of the CRC Data register. + */ +__attribute__((always_inline)) static inline void CrcReg_SetCrFXor(CrcRegType *obj, uint8_t value) +{ + uint32_t crTmp = obj->CR; + + crTmp &= ~(CRC_CR_FXOR_MASK); + crTmp |= (((uint32_t)(((uint32_t)(value)) << CRC_CR_FXOR_SHIFT)) & CRC_CR_FXOR_MASK); + obj->CR = crTmp; +} + +/*! \brief Get the width of CRC protocol (poly) + * + * This function gets the width of CRC protocol (poly). + * This register is not affected by CRC resets generated by the reset bit in the CRC_CR register. + * + * \param[in] obj : pointer to CRC register instance + * \return the value of reversal of bit order + * - 0 : 16-bit CRC protocol. + * - 1 : 32-bit CRC protocol. + */ +__attribute__((always_inline)) static inline uint8_t CrcReg_GetCrProtocolWidth(const CrcRegType *obj) +{ + return ((obj->CR & CRC_CR_TCRC_MASK) >> CRC_CR_TCRC_SHIFT); +} + +/*! \brief Set the width of CRC protocol (poly) + * + * This function sets the width of CRC protocol (poly). + * This register is not affected by CRC resets generated by the reset bit in the CRC_CR register. + * + * \param[in] obj : pointer to CRC register instance + * \param[in] value : the value of reversal of bit order + * - 0 : 16-bit CRC protocol. + * - 1 : 32-bit CRC protocol. + */ +__attribute__((always_inline)) static inline void CrcReg_SetCrProtocolWidth(CrcRegType *obj, uint8_t value) +{ + uint32_t crTmp = obj->CR; + + crTmp &= ~(CRC_CR_TCRC_MASK); + crTmp |= (((uint32_t)(((uint32_t)(value)) << CRC_CR_TCRC_SHIFT)) & CRC_CR_TCRC_MASK); + obj->CR = crTmp; +} + +/*! \brief Get the initial seed register value + * + * This function gets the initial seed register value. + * + * \param[in] obj : pointer to CRC register instance + * \return the initial seed register value + */ +__attribute__((always_inline)) static inline uint32_t CrcReg_GetInitReg(const CrcRegType *obj) +{ + return obj->INIT; +} + +/*! \brief Set the initial seed register + * + * This function sets the initial seed register. + * Write this reg also can reset CRC calculation unit. + * + * \param[in] obj : pointer to CRC register instance + * \param[in] value : initial seed + */ +__attribute__((always_inline)) static inline void CrcReg_SetInitReg(CrcRegType *obj, uint32_t value) +{ + obj->INIT = value; +} + +/*! \brief Get the initial value of polynomial + * + * This function gets the initial value of polynomial. + * This register is not affected by CRC resets generated + * by the reset bit in the CRC_CR register. + * + * \param[in] obj : pointer to CRC register instance + * \return the initial value of polynomial + */ +__attribute__((always_inline)) static inline uint32_t CrcReg_GetPolyReg(const CrcRegType *obj) +{ + return obj->POL; +} + +/*! \brief Set initial value of polynomial + * + * This function sets initial value of polynomial. + * This register is not affected by CRC resets generated + * by the reset bit in the CRC_CR register. + * + * \param[in] obj : pointer to CRC register instance + * \param[in] value : the initial value of polynomial + */ +__attribute__((always_inline)) static inline void CrcReg_SetPolyReg(CrcRegType *obj, uint32_t value) +{ + obj->POL = value; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _CRC_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/dmamux_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/dmamux_reg.h new file mode 100644 index 0000000..cc9bdfc --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/dmamux_reg.h @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _DMAMUX_REG_H_ +#define _DMAMUX_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the DMAMUX (Direct Memory Access Multiplexer) Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* DMAMUX peripheral is available in silicon. */ +#define DMAMUX_AVAILABLE +/* Number of DMA channels. */ +#define DMAMUX_CHANNELS (4U) +/* Has the periodic trigger capability */ +#define DMAMUX_HAS_TRIG (1) +/** DMAMUX - Size of Registers Arrays */ +#define DMAMUX_CHCFG_COUNT (4u) + +/* CR Bit Fields */ +#define DMAMUX_CHCFG_SOURCE_MASK (0x3Fu) +#define DMAMUX_CHCFG_SOURCE_SHIFT (0u) +#define DMAMUX_CHCFG_SOURCE_WIDTH (6u) +#define DMAMUX_CHCFG_TRIG_MASK (0x40u) +#define DMAMUX_CHCFG_TRIG_SHIFT (6u) +#define DMAMUX_CHCFG_TRIG_WIDTH (1u) +#define DMAMUX_CHCFG_ENBL_MASK (0x80u) +#define DMAMUX_CHCFG_ENBL_SHIFT (7u) +#define DMAMUX_CHCFG_ENBL_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of DMAMUX registers + */ +typedef struct _DmamuxRegType_ +{ + volatile uint8_t CHCFG[DMAMUX_CHCFG_COUNT]; /*!< Channel Configuration register, array offset: 0x0, array step: 0x1 */ +} DmamuxRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ +/*! \brief Configures the DMA request for the DMAMUX channel. + * + * Selects which DMA source is routed to a DMA channel. + * + * \param[in] obj : pointer to DMAMUX register instance. + * \param[in] channel : DMAMUX channel number. + * \param[in] source : DMA request source. + */ +__attribute__((always_inline)) static inline void DmamuxReg_SetChannelSource(DmamuxRegType *obj, uint8_t channel, uint8_t source) +{ + uint8_t regValTemp; + regValTemp = obj->CHCFG[channel]; + regValTemp &= (uint8_t) ~(DMAMUX_CHCFG_SOURCE_MASK); + regValTemp |= (uint8_t)(((uint8_t)(((uint8_t)(source)) << DMAMUX_CHCFG_SOURCE_SHIFT)) & DMAMUX_CHCFG_SOURCE_MASK); + obj->CHCFG[channel] = regValTemp; +} + +/*! \brief Configure DMA Channel Trigger bit in DMAMUX. + * + * Enables/Disables DMA Channel Trigger bit in DMAMUX. + * + * \param[in] obj : pointer to DMAMUX register instance. + * \param[in] channel : DMAMUX channel number. + * \param[in] enable: Enables (true) or Disables (false) command. + */ +__attribute__((always_inline)) static inline void DmamuxReg_SetChannelTrigger(DmamuxRegType *obj, uint8_t channel, bool enable) +{ + if(enable) + { + obj->CHCFG[channel] |= DMAMUX_CHCFG_TRIG_MASK; + } + else + { + obj->CHCFG[channel] &= ~DMAMUX_CHCFG_TRIG_MASK; + } +} + +/*! \brief Enables/Disables the DMAMUX channel. + * + * Enables the hardware request. If enabled, the hardware request is sent to + * the corresponding DMA channel. + * + * \param[in] obj : pointer to DMAMUX register instance. + * \param[in] channel DMAMUX channel number. + * \param[in] enable: Enables (true) or Disables (false) DMAMUX channel. + */ +__attribute__((always_inline)) static inline void DmamuxReg_SetChannelCmd(DmamuxRegType *obj, uint8_t channel, bool enable) +{ + if(enable) + { + obj->CHCFG[channel] |= DMAMUX_CHCFG_ENBL_MASK; + } + else + { + obj->CHCFG[channel] &= ~DMAMUX_CHCFG_ENBL_MASK; + } +} + +/*! \brief Initializes the DMAMUX module to the reset state. + * + * Initializes the DMAMUX module to the reset state. + * + * \param[in] obj : pointer to DMAMUX register instance. + */ +__attribute__((always_inline)) static inline void DmamuxReg_Init(DmamuxRegType *obj) +{ + uint8_t i; + + for(i = 0; i < DMAMUX_CHANNELS; i++) + { + obj->CHCFG[i] = 0; + } +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _DMAMUX_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/edma_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/edma_reg.h new file mode 100644 index 0000000..79a651d --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/edma_reg.h @@ -0,0 +1,2109 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _EDMA_REG_H_ +#define _EDMA_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the EDMA (Enhance Direct Memory Access) Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* Number of EDMA channels. */ +#define EDMA_CHANNELS (4U) +/* brief Number of EDMA interrupt lines. */ +#define EDMA_CHANNELS_INTERRUPT_LINES (4U) +/* brief EDMA supports the following particular transfer size: */ +#define EDMA_TRANSFER_SIZE_16B +#define EDMA_TRANSFER_SIZE_32B + +/*! \brief Structure for the EDMA hardware request + * + * Defines the structure for the EDMA hardware request collections. The user can configure the + * hardware request into EDMAMUX to trigger the EDMA transfer accordingly. The index + * of the hardware request varies according to the to SoC. + */ + +typedef enum +{ + EDMA_REQ_TRIGGER_0 = 0U, + EDMA_REQ_TRIGGER_1 = 1U, + + EDMA_REQ_DISABLED = 2U, + + EDMA_REQ_UART0_RX = 3U, + EDMA_REQ_UART0_TX = 4U, + EDMA_REQ_UART1_RX = 5U, + EDMA_REQ_UART1_TX = 6U, + EDMA_REQ_UART2_RX = 7U, + EDMA_REQ_UART2_TX = 8U, + + EDMA_REQ_I2S_SLV = 11U, + EDMA_REQ_I2S_MST = 12U, + + EDMA_REQ_SPI0_RX = 13U, + EDMA_REQ_SPI0_TX = 14U, + EDMA_REQ_SPI1_RX = 15U, + EDMA_REQ_SPI1_TX = 16U, + + EDMA_REQ_MFT0_CHANNEL_0 = 21U, + EDMA_REQ_MFT0_CHANNEL_1 = 22U, + EDMA_REQ_MFT0_CHANNEL_2 = 23U, + EDMA_REQ_MFT0_CHANNEL_3 = 24U, + EDMA_REQ_MFT0_CHANNEL_4 = 25U, + EDMA_REQ_MFT0_CHANNEL_5 = 26U, + EDMA_REQ_MFT0_CHANNEL_6 = 27U, + EDMA_REQ_MFT0_CHANNEL_7 = 28U, + + EDMA_REQ_MFT1_CHANNEL_0 = 29U, + EDMA_REQ_MFT1_CHANNEL_1 = 30U, + EDMA_REQ_MFT1_CHANNEL_2 = 31U, + EDMA_REQ_MFT1_CHANNEL_3 = 32U, + EDMA_REQ_MFT1_CHANNEL_4 = 33U, + EDMA_REQ_MFT1_CHANNEL_5 = 34U, + EDMA_REQ_MFT1_CHANNEL_6 = 35U, + EDMA_REQ_MFT1_CHANNEL_7 = 36U, + + EDMA_REQ_I2C0_RX = 45U, + EDMA_REQ_I2C0_TX = 46U, + + EDMA_REQ_PDB = 47U, + + EDMA_REQ_CMP = 49U, + + EDMA_REQ_PORTA = 50U, + EDMA_REQ_PORTB = 51U, + EDMA_REQ_PORTC = 52U, + EDMA_REQ_PORTD = 53U, + EDMA_REQ_PORTE = 54U, + + EDMA_REQ_CAN = 55U, + + EDMA_REQ_LPTMR0 = 59U, + + EDMA_REQ_ADC0 = 60U, +} EDma_RequestSourceType; + +/* CR Bit Fields */ +#define EDMA_CR_EDBG_MASK (0x2u) +#define EDMA_CR_EDBG_SHIFT (1u) +#define EDMA_CR_EDBG_WIDTH (1u) +#define EDMA_CR_ERCA_MASK (0x4u) +#define EDMA_CR_ERCA_SHIFT (2u) +#define EDMA_CR_ERCA_WIDTH (1u) +#define EDMA_CR_HOE_MASK (0x10u) +#define EDMA_CR_HOE_SHIFT (4u) +#define EDMA_CR_HOE_WIDTH (1u) +#define EDMA_CR_HALT_MASK (0x20u) +#define EDMA_CR_HALT_SHIFT (5u) +#define EDMA_CR_HALT_WIDTH (1u) +#define EDMA_CR_CLM_MASK (0x40u) +#define EDMA_CR_CLM_SHIFT (6u) +#define EDMA_CR_CLM_WIDTH (1u) +#define EDMA_CR_EMLM_MASK (0x80u) +#define EDMA_CR_EMLM_SHIFT (7u) +#define EDMA_CR_EMLM_WIDTH (1u) +#define EDMA_CR_ECX_MASK (0x10000u) +#define EDMA_CR_ECX_SHIFT (16u) +#define EDMA_CR_ECX_WIDTH (1u) +#define EDMA_CR_CX_MASK (0x20000u) +#define EDMA_CR_CX_SHIFT (17u) +#define EDMA_CR_CX_WIDTH (1u) +#define EDMA_CR_ACTIVE_MASK (0x80000000u) +#define EDMA_CR_ACTIVE_SHIFT (31u) +#define EDMA_CR_ACTIVE_WIDTH (1u) + +/* ES Bit Fields */ +#define EDMA_ES_DBE_MASK (0x1u) +#define EDMA_ES_DBE_SHIFT (0u) +#define EDMA_ES_DBE_WIDTH (1u) +#define EDMA_ES_SBE_MASK (0x2u) +#define EDMA_ES_SBE_SHIFT (1u) +#define EDMA_ES_SBE_WIDTH (1u) +#define EDMA_ES_SGE_MASK (0x4u) +#define EDMA_ES_SGE_SHIFT (2u) +#define EDMA_ES_SGE_WIDTH (1u) +#define EDMA_ES_NCE_MASK (0x8u) +#define EDMA_ES_NCE_SHIFT (3u) +#define EDMA_ES_NCE_WIDTH (1u) +#define EDMA_ES_DOE_MASK (0x10u) +#define EDMA_ES_DOE_SHIFT (4u) +#define EDMA_ES_DOE_WIDTH (1u) +#define EDMA_ES_DAE_MASK (0x20u) +#define EDMA_ES_DAE_SHIFT (5u) +#define EDMA_ES_DAE_WIDTH (1u) +#define EDMA_ES_SOE_MASK (0x40u) +#define EDMA_ES_SOE_SHIFT (6u) +#define EDMA_ES_SOE_WIDTH (1u) +#define EDMA_ES_SAE_MASK (0x80u) +#define EDMA_ES_SAE_SHIFT (7u) +#define EDMA_ES_SAE_WIDTH (1u) +#define EDMA_ES_ERRCHN_MASK (0xF00u) +#define EDMA_ES_ERRCHN_SHIFT (8u) +#define EDMA_ES_ERRCHN_WIDTH (4u) +#define EDMA_ES_CPE_MASK (0x4000u) +#define EDMA_ES_CPE_SHIFT (14u) +#define EDMA_ES_CPE_WIDTH (1u) +#define EDMA_ES_ECX_MASK (0x10000u) +#define EDMA_ES_ECX_SHIFT (16u) +#define EDMA_ES_ECX_WIDTH (1u) +#define EDMA_ES_VLD_MASK (0x80000000u) +#define EDMA_ES_VLD_SHIFT (31u) +#define EDMA_ES_VLD_WIDTH (1u) + +/* ERQ Bit Fields */ +#define EDMA_ERQ_ERQ0_MASK (0x1u) +#define EDMA_ERQ_ERQ0_SHIFT (0u) +#define EDMA_ERQ_ERQ0_WIDTH (1u) +#define EDMA_ERQ_ERQ1_MASK (0x2u) +#define EDMA_ERQ_ERQ1_SHIFT (1u) +#define EDMA_ERQ_ERQ1_WIDTH (1u) +#define EDMA_ERQ_ERQ2_MASK (0x4u) +#define EDMA_ERQ_ERQ2_SHIFT (2u) +#define EDMA_ERQ_ERQ2_WIDTH (1u) +#define EDMA_ERQ_ERQ3_MASK (0x8u) +#define EDMA_ERQ_ERQ3_SHIFT (3u) +#define EDMA_ERQ_ERQ3_WIDTH (1u) + +/* EEI Bit Fields */ +#define EDMA_EEI_EEI0_MASK (0x1u) +#define EDMA_EEI_EEI0_SHIFT (0u) +#define EDMA_EEI_EEI0_WIDTH (1u) +#define EDMA_EEI_EEI1_MASK (0x2u) +#define EDMA_EEI_EEI1_SHIFT (1u) +#define EDMA_EEI_EEI1_WIDTH (1u) +#define EDMA_EEI_EEI2_MASK (0x4u) +#define EDMA_EEI_EEI2_SHIFT (2u) +#define EDMA_EEI_EEI2_WIDTH (1u) +#define EDMA_EEI_EEI3_MASK (0x8u) +#define EDMA_EEI_EEI3_SHIFT (3u) +#define EDMA_EEI_EEI3_WIDTH (1u) + +/* CEEI Bit Fields */ +#define EDMA_CEEI_CEEI_MASK (0xFu) +#define EDMA_CEEI_CEEI_SHIFT (0u) +#define EDMA_CEEI_CEEI_WIDTH (4u) +#define EDMA_CEEI_CAEE_MASK (0x40u) +#define EDMA_CEEI_CAEE_SHIFT (6u) +#define EDMA_CEEI_CAEE_WIDTH (1u) +#define EDMA_CEEI_NOP_MASK (0x80u) +#define EDMA_CEEI_NOP_SHIFT (7u) +#define EDMA_CEEI_NOP_WIDTH (1u) + +/* SEEI Bit Fields */ +#define EDMA_SEEI_SEEI_MASK (0xFu) +#define EDMA_SEEI_SEEI_SHIFT (0u) +#define EDMA_SEEI_SEEI_WIDTH (4u) +#define EDMA_SEEI_SAEE_MASK (0x40u) +#define EDMA_SEEI_SAEE_SHIFT (6u) +#define EDMA_SEEI_SAEE_WIDTH (1u) +#define EDMA_SEEI_NOP_MASK (0x80u) +#define EDMA_SEEI_NOP_SHIFT (7u) +#define EDMA_SEEI_NOP_WIDTH (1u) + +/* CERQ Bit Fields */ +#define EDMA_CERQ_CERQ_MASK (0xFu) +#define EDMA_CERQ_CERQ_SHIFT (0u) +#define EDMA_CERQ_CERQ_WIDTH (4u) +#define EDMA_CERQ_CAER_MASK (0x40u) +#define EDMA_CERQ_CAER_SHIFT (6u) +#define EDMA_CERQ_CAER_WIDTH (1u) +#define EDMA_CERQ_NOP_MASK (0x80u) +#define EDMA_CERQ_NOP_SHIFT (7u) +#define EDMA_CERQ_NOP_WIDTH (1u) + +/* SERQ Bit Fields */ +#define EDMA_SERQ_SERQ_MASK (0xFu) +#define EDMA_SERQ_SERQ_SHIFT (0u) +#define EDMA_SERQ_SERQ_WIDTH (4u) +#define EDMA_SERQ_SAER_MASK (0x40u) +#define EDMA_SERQ_SAER_SHIFT (6u) +#define EDMA_SERQ_SAER_WIDTH (1u) +#define EDMA_SERQ_NOP_MASK (0x80u) +#define EDMA_SERQ_NOP_SHIFT (7u) +#define EDMA_SERQ_NOP_WIDTH (1u) + +/* CDNE Bit Fields */ +#define EDMA_CDNE_CDNE_MASK (0xFu) +#define EDMA_CDNE_CDNE_SHIFT (0u) +#define EDMA_CDNE_CDNE_WIDTH (4u) +#define EDMA_CDNE_CADN_MASK (0x40u) +#define EDMA_CDNE_CADN_SHIFT (6u) +#define EDMA_CDNE_CADN_WIDTH (1u) +#define EDMA_CDNE_NOP_MASK (0x80u) +#define EDMA_CDNE_NOP_SHIFT (7u) +#define EDMA_CDNE_NOP_WIDTH (1u) + +/* SSRT Bit Fields */ +#define EDMA_SSRT_SSRT_MASK (0xFu) +#define EDMA_SSRT_SSRT_SHIFT (0u) +#define EDMA_SSRT_SSRT_WIDTH (4u) +#define EDMA_SSRT_SAST_MASK (0x40u) +#define EDMA_SSRT_SAST_SHIFT (6u) +#define EDMA_SSRT_SAST_WIDTH (1u) +#define EDMA_SSRT_NOP_MASK (0x80u) +#define EDMA_SSRT_NOP_SHIFT (7u) +#define EDMA_SSRT_NOP_WIDTH (1u) + +/* CERR Bit Fields */ +#define EDMA_CERR_CERR_MASK (0xFu) +#define EDMA_CERR_CERR_SHIFT (0u) +#define EDMA_CERR_CERR_WIDTH (4u) +#define EDMA_CERR_CAEI_MASK (0x40u) +#define EDMA_CERR_CAEI_SHIFT (6u) +#define EDMA_CERR_CAEI_WIDTH (1u) +#define EDMA_CERR_NOP_MASK (0x80u) +#define EDMA_CERR_NOP_SHIFT (7u) +#define EDMA_CERR_NOP_WIDTH (1u) + +/* CINT Bit Fields */ +#define EDMA_CINT_CINT_MASK (0xFu) +#define EDMA_CINT_CINT_SHIFT (0u) +#define EDMA_CINT_CINT_WIDTH (4u) +#define EDMA_CINT_CAIR_MASK (0x40u) +#define EDMA_CINT_CAIR_SHIFT (6u) +#define EDMA_CINT_CAIR_WIDTH (1u) +#define EDMA_CINT_NOP_MASK (0x80u) +#define EDMA_CINT_NOP_SHIFT (7u) +#define EDMA_CINT_NOP_WIDTH (1u) + +/* INT Bit Fields */ +#define EDMA_INT_INT0_MASK (0x1u) +#define EDMA_INT_INT0_SHIFT (0u) +#define EDMA_INT_INT0_WIDTH (1u) +#define EDMA_INT_INT1_MASK (0x2u) +#define EDMA_INT_INT1_SHIFT (1u) +#define EDMA_INT_INT1_WIDTH (1u) +#define EDMA_INT_INT2_MASK (0x4u) +#define EDMA_INT_INT2_SHIFT (2u) +#define EDMA_INT_INT2_WIDTH (1u) +#define EDMA_INT_INT3_MASK (0x8u) +#define EDMA_INT_INT3_SHIFT (3u) +#define EDMA_INT_INT3_WIDTH (1u) + +/* ERR Bit Fields */ +#define EDMA_ERR_ERRN_MASK (0x1u) +#define EDMA_ERR_ERR0_MASK (0x1u) +#define EDMA_ERR_ERR0_SHIFT (0u) +#define EDMA_ERR_ERR0_WIDTH (1u) +#define EDMA_ERR_ERR1_MASK (0x2u) +#define EDMA_ERR_ERR1_SHIFT (1u) +#define EDMA_ERR_ERR1_WIDTH (1u) +#define EDMA_ERR_ERR2_MASK (0x4u) +#define EDMA_ERR_ERR2_SHIFT (2u) +#define EDMA_ERR_ERR2_WIDTH (1u) +#define EDMA_ERR_ERR3_MASK (0x8u) +#define EDMA_ERR_ERR3_SHIFT (3u) +#define EDMA_ERR_ERR3_WIDTH (1u) + +/* HRS Bit Fields */ +#define EDMA_HRS_HRS0_MASK (0x1u) +#define EDMA_HRS_HRS0_SHIFT (0u) +#define EDMA_HRS_HRS0_WIDTH (1u) +#define EDMA_HRS_HRS1_MASK (0x2u) +#define EDMA_HRS_HRS1_SHIFT (1u) +#define EDMA_HRS_HRS1_WIDTH (1u) +#define EDMA_HRS_HRS2_MASK (0x4u) +#define EDMA_HRS_HRS2_SHIFT (2u) +#define EDMA_HRS_HRS2_WIDTH (1u) +#define EDMA_HRS_HRS3_MASK (0x8u) +#define EDMA_HRS_HRS3_SHIFT (3u) +#define EDMA_HRS_HRS3_WIDTH (1u) + +/* DCHPRI Bit Fields */ +#define EDMA_DCHPRI_CHPRI_MASK (0xFu) +#define EDMA_DCHPRI_CHPRI_SHIFT (0u) +#define EDMA_DCHPRI_CHPRI_WIDTH (4u) +#define EDMA_DCHPRI_DPA_MASK (0x40u) +#define EDMA_DCHPRI_DPA_SHIFT (6u) +#define EDMA_DCHPRI_DPA_WIDTH (1u) +#define EDMA_DCHPRI_ECP_MASK (0x80u) +#define EDMA_DCHPRI_ECP_SHIFT (7u) +#define EDMA_DCHPRI_ECP_WIDTH (1u) + +/* TCD_SADDR Bit Fields */ +#define EDMA_TCD_SADDR_SADDR_MASK (0xFFFFFFFFu) +#define EDMA_TCD_SADDR_SADDR_SHIFT (0u) +#define EDMA_TCD_SADDR_SADDR_WIDTH (32u) + +/* TCD_SOFF Bit Fields */ +#define EDMA_TCD_SOFF_SOFF_MASK (0xFFFFu) +#define EDMA_TCD_SOFF_SOFF_SHIFT (0u) +#define EDMA_TCD_SOFF_SOFF_WIDTH (16u) + +/* TCD_ATTR Bit Fields */ +#define EDMA_TCD_ATTR_SDSIZE_MASK (0x7u) +#define EDMA_TCD_ATTR_SDSIZE_SHIFT (0u) +#define EDMA_TCD_ATTR_SDSIZE_WIDTH (3u) +#define EDMA_TCD_ATTR_SDSIZE(x) (((uint16_t)(((uint16_t)(x)) << EDMA_TCD_ATTR_SDSIZE_SHIFT)) & EDMA_TCD_ATTR_SDSIZE_MASK) +#define EDMA_TCD_ATTR_DMOD_MASK (0xF8u) +#define EDMA_TCD_ATTR_DMOD_SHIFT (3u) +#define EDMA_TCD_ATTR_DMOD_WIDTH (5u) +#define EDMA_TCD_ATTR_DMOD(x) (((uint16_t)(((uint16_t)(x)) << EDMA_TCD_ATTR_DMOD_SHIFT)) & EDMA_TCD_ATTR_DMOD_MASK) +#define EDMA_TCD_ATTR_SMOD_MASK (0xF800u) +#define EDMA_TCD_ATTR_SMOD_SHIFT (11u) +#define EDMA_TCD_ATTR_SMOD_WIDTH (5u) +#define EDMA_TCD_ATTR_SMOD(x) (((uint16_t)(((uint16_t)(x)) << EDMA_TCD_ATTR_SMOD_SHIFT)) & EDMA_TCD_ATTR_SMOD_MASK) + +/* TCD_NBYTES_MLOFFNO Bit Fields */ +#define EDMA_TCD_NBYTES_MLOFFNO_NBYTES_MASK (0x3FFFFFFFu) +#define EDMA_TCD_NBYTES_MLOFFNO_NBYTES_SHIFT (0u) +#define EDMA_TCD_NBYTES_MLOFFNO_NBYTES_WIDTH (30u) +#define EDMA_TCD_NBYTES_MLOFFNO_DMLOE_MASK (0x40000000u) +#define EDMA_TCD_NBYTES_MLOFFNO_DMLOE_SHIFT (30u) +#define EDMA_TCD_NBYTES_MLOFFNO_DMLOE_WIDTH (1u) +#define EDMA_TCD_NBYTES_MLOFFNO_SMLOE_MASK (0x80000000u) +#define EDMA_TCD_NBYTES_MLOFFNO_SMLOE_SHIFT (31u) +#define EDMA_TCD_NBYTES_MLOFFNO_SMLOE_WIDTH (1u) + +/* TCD_NBYTES_MLOFFYES Bit Fields */ +#define EDMA_TCD_NBYTES_MLOFFYES_NBYTES_MASK (0x3FFu) +#define EDMA_TCD_NBYTES_MLOFFYES_NBYTES_SHIFT (0u) +#define EDMA_TCD_NBYTES_MLOFFYES_NBYTES_WIDTH (10u) +#define EDMA_TCD_NBYTES_MLOFFYES_MLOFF_MASK (0x3FFFFC00u) +#define EDMA_TCD_NBYTES_MLOFFYES_MLOFF_SHIFT (10u) +#define EDMA_TCD_NBYTES_MLOFFYES_MLOFF_WIDTH (20u) +#define EDMA_TCD_NBYTES_MLOFFYES_DMLOE_MASK (0x40000000u) +#define EDMA_TCD_NBYTES_MLOFFYES_DMLOE_SHIFT (30u) +#define EDMA_TCD_NBYTES_MLOFFYES_DMLOE_WIDTH (1u) +#define EDMA_TCD_NBYTES_MLOFFYES_SMLOE_MASK (0x80000000u) +#define EDMA_TCD_NBYTES_MLOFFYES_SMLOE_SHIFT (31u) +#define EDMA_TCD_NBYTES_MLOFFYES_SMLOE_WIDTH (1u) + +/* TCD_SLAST Bit Fields */ +#define EDMA_TCD_SLAST_SLAST_MASK (0xFFFFFFFFu) +#define EDMA_TCD_SLAST_SLAST_SHIFT (0u) +#define EDMA_TCD_SLAST_SLAST_WIDTH (32u) + +/* TCD_DADDR Bit Fields */ +#define EDMA_TCD_DADDR_DADDR_MASK (0xFFFFFFFFu) +#define EDMA_TCD_DADDR_DADDR_SHIFT (0u) +#define EDMA_TCD_DADDR_DADDR_WIDTH (32u) + +/* TCD_DOFF Bit Fields */ +#define EDMA_TCD_DOFF_DOFF_MASK (0xFFFFu) +#define EDMA_TCD_DOFF_DOFF_SHIFT (0u) +#define EDMA_TCD_DOFF_DOFF_WIDTH (16u) + +/* TCD_CITER_ELINKNO Bit Fields */ +#define EDMA_TCD_CITER_ELINKNO_CITER_MASK (0x7FFFu) +#define EDMA_TCD_CITER_ELINKNO_CITER_SHIFT (0u) +#define EDMA_TCD_CITER_ELINKNO_CITER_WIDTH (15u) +#define EDMA_TCD_CITER_ELINKNO_ELINK_MASK (0x8000u) +#define EDMA_TCD_CITER_ELINKNO_ELINK_SHIFT (15u) +#define EDMA_TCD_CITER_ELINKNO_ELINK_WIDTH (1u) + +/* TCD_CITER_ELINKYES Bit Fields */ +#define EDMA_TCD_CITER_ELINKYES_CITER_MASK (0x1FFu) +#define EDMA_TCD_CITER_ELINKYES_CITER_SHIFT (0u) +#define EDMA_TCD_CITER_ELINKYES_CITER_WIDTH (9u) +#define EDMA_TCD_CITER_ELINKYES_LINKCH_MASK (0x1E00u) +#define EDMA_TCD_CITER_ELINKYES_LINKCH_SHIFT (9u) +#define EDMA_TCD_CITER_ELINKYES_LINKCH_WIDTH (4u) +#define EDMA_TCD_CITER_ELINKYES_ELINK_MASK (0x8000u) +#define EDMA_TCD_CITER_ELINKYES_ELINK_SHIFT (15u) +#define EDMA_TCD_CITER_ELINKYES_ELINK_WIDTH (1u) + +/* TCD_DLASTSGA Bit Fields */ +#define EDMA_TCD_DLASTSGA_DLASTSGA_MASK (0xFFFFFFFFu) +#define EDMA_TCD_DLASTSGA_DLASTSGA_SHIFT (0u) +#define EDMA_TCD_DLASTSGA_DLASTSGA_WIDTH (32u) + +/* TCD_CSR Bit Fields */ +#define EDMA_TCD_CSR_START_MASK (0x1u) +#define EDMA_TCD_CSR_START_SHIFT (0u) +#define EDMA_TCD_CSR_START_WIDTH (1u) +#define EDMA_TCD_CSR_INTMAJOR_MASK (0x2u) +#define EDMA_TCD_CSR_INTMAJOR_SHIFT (1u) +#define EDMA_TCD_CSR_INTMAJOR_WIDTH (1u) +#define EDMA_TCD_CSR_INTHALF_MASK (0x4u) +#define EDMA_TCD_CSR_INTHALF_SHIFT (2u) +#define EDMA_TCD_CSR_INTHALF_WIDTH (1u) +#define EDMA_TCD_CSR_DREQ_MASK (0x8u) +#define EDMA_TCD_CSR_DREQ_SHIFT (3u) +#define EDMA_TCD_CSR_DREQ_WIDTH (1u) +#define EDMA_TCD_CSR_ESG_MASK (0x10u) +#define EDMA_TCD_CSR_ESG_SHIFT (4u) +#define EDMA_TCD_CSR_ESG_WIDTH (1u) +#define EDMA_TCD_CSR_MAJORELINK_MASK (0x20u) +#define EDMA_TCD_CSR_MAJORELINK_SHIFT (5u) +#define EDMA_TCD_CSR_MAJORELINK_WIDTH (1u) +#define EDMA_TCD_CSR_ACTIVE_MASK (0x40u) +#define EDMA_TCD_CSR_ACTIVE_SHIFT (6u) +#define EDMA_TCD_CSR_ACTIVE_WIDTH (1u) +#define EDMA_TCD_CSR_DONE_MASK (0x80u) +#define EDMA_TCD_CSR_DONE_SHIFT (7u) +#define EDMA_TCD_CSR_DONE_WIDTH (1u) +#define EDMA_TCD_CSR_MAJORLINKCH_MASK (0xF00u) +#define EDMA_TCD_CSR_MAJORLINKCH_SHIFT (8u) +#define EDMA_TCD_CSR_MAJORLINKCH_WIDTH (4u) +#define EDMA_TCD_CSR_HARD_CLR_DONE_MASK (0x1000u) +#define EDMA_TCD_CSR_HARD_CLR_DONE_SHIFT (12u) +#define EDMA_TCD_CSR_HARD_CLR_DONE_WIDTH (1u) + +/* TCD_BITER_ELINKNO Bit Fields */ +#define EDMA_TCD_BITER_ELINKNO_BITER_MASK (0x7FFFu) +#define EDMA_TCD_BITER_ELINKNO_BITER_SHIFT (0u) +#define EDMA_TCD_BITER_ELINKNO_BITER_WIDTH (15u) +#define EDMA_TCD_BITER_ELINKNO_ELINK_MASK (0x8000u) +#define EDMA_TCD_BITER_ELINKNO_ELINK_SHIFT (15u) +#define EDMA_TCD_BITER_ELINKNO_ELINK_WIDTH (1u) + +/* TCD_BITER_ELINKYES Bit Fields */ +#define EDMA_TCD_BITER_ELINKYES_BITER_MASK (0x1FFu) +#define EDMA_TCD_BITER_ELINKYES_BITER_SHIFT (0u) +#define EDMA_TCD_BITER_ELINKYES_BITER_WIDTH (9u) +#define EDMA_TCD_BITER_ELINKYES_LINKCH_MASK (0x1E00u) +#define EDMA_TCD_BITER_ELINKYES_LINKCH_SHIFT (9u) +#define EDMA_TCD_BITER_ELINKYES_LINKCH_WIDTH (4u) +#define EDMA_TCD_BITER_ELINKYES_ELINK_MASK (0x8000u) +#define EDMA_TCD_BITER_ELINKYES_ELINK_SHIFT (15u) +#define EDMA_TCD_BITER_ELINKYES_ELINK_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +/*! \brief EDMA - Size of Registers Arrays + */ +#define EDMA_DCHPRI_COUNT (4u) +#define EDMA_TCD_COUNT (4u) + +/*! \brief The definition of EDMA registers + */ +typedef struct _EDmaRegType_ +{ + volatile uint32_t CR; /*!< EDMA control register, offset: 0x0 */ + volatile uint32_t ES; /*!< EDMA status register, offset: 0x4 */ + uint32_t RESERVED0; /*!< Reserved register, offset: 0x8 */ + volatile uint32_t ERQ; /*!< EDMA enable request register, offset: 0xC */ + uint32_t RESERVED1; /*!< Reserved register, offset: 0x10 */ + volatile uint32_t EEI; /*!< EDMA enable error interrupt register, offset: 0x14 */ + volatile uint8_t CEEI; /*!< EDMA clear enable error interrupt register, offset: 0x18 */ + volatile uint8_t SEEI; /*!< EDMA clear enable error interrupt register, offset: 0x19 */ + volatile uint8_t CERQ; /*!< EDMA clear enable error interrupt register, offset: 0x1A */ + volatile uint8_t SERQ; /*!< EDMA clear enable error interrupt register, offset: 0x1B */ + volatile uint8_t CDNE; /*!< EDMA clear enable error interrupt register, offset: 0x1C */ + volatile uint8_t SSRT; /*!< EDMA clear enable error interrupt register, offset: 0x1D */ + volatile uint8_t CERR; /*!< EDMA clear enable error interrupt register, offset: 0x1E */ + volatile uint8_t CINT; /*!< EDMA clear enable error interrupt register, offset: 0x1F */ + uint32_t RESERVED2; /*!< Reserved register, offset: 0x20 */ + volatile uint32_t INT; /*!< EDMA interrupt request register, offset: 0x24 */ + uint32_t RESERVED3; /*!< Reserved register, offset: 0x28 */ + volatile uint32_t ERR; /*!< EDMA error register, offset: 0x2C */ + uint32_t RESERVED4; /*!< Reserved register, offset: 0x30 */ + volatile uint32_t HRS; /*!< EDMA hardware request status register, offset: 0x34 */ + uint32_t RESERVED5[50]; /*!< Reserved register, offset: 0x38 */ + volatile uint8_t DCHPRI_N[EDMA_DCHPRI_COUNT]; /*!< EDMA channel N arbitration priority register, offset: 0x100 */ + uint32_t RESERVED6[959]; /*!< Reserved register, offset: 0x110 */ + struct + { + volatile uint32_t SADDR; /*!< EDMA tcd source address register, offset: 0x1000 */ + volatile uint16_t SOFF; /*!< EDMA tcd signed source address offset register, offset: 0x1004 */ + volatile uint16_t ATTR; /*!< EDMA tcd transfer attributes register, offset: 0x1006 */ + volatile uint32_t NBYTES; /*!< EDMA tcd minor byte count register, offset: 0x1008 */ + volatile uint32_t SLAST; /*!< EDMA tcd last source address adjustment register, offset: 0x100C */ + volatile uint32_t DADDR; /*!< EDMA tcd destination address register, offset: 0x1010 */ + volatile uint16_t DOFF; /*!< EDMA tcd destination address signed offset register, offset: 0x1014 */ + volatile uint16_t CITER; /*!< EDMA tcd current minor loop link major loop link register, offset: 0x1016 */ + volatile uint32_t DLASTSGA; /*!< EDMA last destination address adjustment/scatter gather address register, offset: 0x1018 */ + volatile uint16_t CSR; /*!< EDMA tcd control and status register, offset 0x101C */ + volatile uint16_t BITER; /*!< EDMA tcd current begining minor loop link, major loop count register, offset: 0x101E */ + } TCD[EDMA_TCD_COUNT]; +} EDmaRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ +/*! \brief Get Debug mode + * + * \param[in] obj : pointer to eDMA register instance + * \return debug mode + * -0b: when in debug mode, the DMA continues to operate + * -1b: when in debug mode, the DMA stalls the start of a new channel. + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetDebugMode(const EDmaRegType *obj) +{ + return ((obj->CR & EDMA_CR_EDBG_MASK) >> EDMA_CR_EDBG_SHIFT); +} + +/*! \brief Set When in debug mode, the DMA stalls the start of a new channel. + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableDebugStall(EDmaRegType *obj) +{ + obj->CR |= EDMA_CR_EDBG_MASK; +} + +/*! \brief Set When in debug mode, the DMA continues to operate + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableDebugStall(EDmaRegType *obj) +{ + obj->CR &= ~EDMA_CR_EDBG_MASK; +} + +/*! \brief Get the channel arbitration mode + * + * \param[in] obj base pointer to eDMA register instance + * \return arbitration mode + * - 0b: Fixed priority arbitration is used for channel selection + * - 1b: Round-Robin arbitration is used for channel selection + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetChannelArbitrationMode(const EDmaRegType *obj) +{ + return ((obj->CR & EDMA_CR_ERCA_MASK) >> EDMA_CR_ERCA_SHIFT); +} + +/*! \brief Sets the channel arbitration algorithm. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] mode : Round-Robin(1) way or fixed(0) priority way. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetChannelArbitrationMode(EDmaRegType *obj, uint8_t mode) +{ + uint32_t tempVal; + tempVal = obj->CR; + tempVal &= ~EDMA_CR_ERCA_MASK; + tempVal |= (mode << EDMA_CR_ERCA_SHIFT) & EDMA_CR_ERCA_MASK; + obj->CR = tempVal; +} + +/*! \brief Get Halt on error + * + * \param[in] obj : pointer to eDMA register instance + * \return halt on error mode + * - 0: Normal operation + * - 1: Any error causes the HALT bit to set.Subsequently,all service requests are ignored until the HALT bit is cleared. + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetHaltOnError(const EDmaRegType *obj) +{ + return ((obj->CR & EDMA_CR_HOE_MASK) >> EDMA_CR_HOE_SHIFT); +} + +/*! \brief Halts or does not halt the eDMA module when an error occurs. + * + * An error causes the HALT bit to be set. Subsequently, all service requests are ignored until the + * HALT bit is cleared. + * + * \param[in] base pointer to eDMA register instance + * \param[in] enable Halts (true) or not halt (false) eDMA module when an error occurs. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetHaltOnErrorCmd(EDmaRegType *obj, uint8_t enable) +{ + if(enable) + { + obj->CR |= EDMA_CR_HOE_MASK; + } + else + { + obj->CR &= ~EDMA_CR_HOE_MASK; + } +} + +/*! \brief Get Halt eDMA operations + * + * \param[in] obj : pointer to eDMA register instance + * \return Halt eDMA operations + * - 0b: normal operation + * - 1b: stall the start of any new channels.Executing channels are allowed to complete. + * Channel execution resumes when this bit is cleared + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetHalt(EDmaRegType *obj) +{ + return ((obj->CR & EDMA_CR_HALT_MASK) >> EDMA_CR_HALT_SHIFT); +} + +/*! \brief Halts or does not halt the eDMA module . + * + * Execution channels are not allowed to complete, dma stop transfer at the end fo read-write sequence + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] enable : Halts (true) or not halt (false) eDMA module. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetHaltCmd(EDmaRegType *obj, uint8_t enable) +{ + if(enable) + { + obj->CR |= EDMA_CR_HALT_MASK; + } + else + { + obj->CR &= ~EDMA_CR_HALT_MASK; + } +} + +/*! \brief Get continuous link mode + * + * \param[in] obj : pointer to eDMA register instance + * \return continuous link mode + * - 0b: a minor loop channel link made to itself goes through channel arbitration before being activated again + * - 1b: a minor loop channel link made to itself does not go through channel arbitration before being activated again. + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetClm(const EDmaRegType *obj) +{ + return ((obj->CR & EDMA_CR_CLM_MASK) >> EDMA_CR_CLM_SHIFT); +} + +/*! \brief Enable continuous link mode + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableClm(EDmaRegType *obj) +{ + obj->CR |= EDMA_CR_CLM_MASK; +} + +/*! \brief Disable continuous link mode + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableClm(EDmaRegType *obj) +{ + obj->CR &= ~EDMA_CR_CLM_MASK; +} + +/*! \brief Get Minor Loop Mapping + * + * \param[in] obj pointer to eDMA register instance + * \return minor loop mapping mode + * - 0b: disable. + * - 1b: enabled + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetMinorLoopMapping(const EDmaRegType *obj) +{ + return ((obj->CR & EDMA_CR_EMLM_MASK) >> EDMA_CR_EMLM_SHIFT); +} + +/*! \brief Enables/Disables the minor loop mapping. + * + * This function enables/disables the minor loop mapping feature. + * If enabled, the NBYTES is redefined to include the individual enable fields and the NBYTES field. The + * individual enable fields allow the minor loop offset to be applied to the source address, the + * destination address, or both. The NBYTES field is reduced when either offset is enabled. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] enable : Enables (true) or Disable (false) minor loop mapping. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetMinorLoopMappingCmd(EDmaRegType *obj, uint8_t enable) +{ + if(enable) + { + obj->CR |= EDMA_CR_EMLM_MASK; + } + else + { + obj->CR &= ~EDMA_CR_EMLM_MASK; + } +} + +/*! \brief Get Error cancel transfer mode + * + * \param[in] obj : pointer to eDMA register instance + * \return error cancel transfer mode + * - 0b: normal operation + * - 1b: cancel the remaining data transfer same as CX bit. Moreover, ECX treats the cancel as an error condition, + * thus updating the Error Status register (DMAx_ES) and generating an optional error interrupt. + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetEcx(const EDmaRegType *obj) +{ + return ((obj->CR & EDMA_CR_ECX_MASK) >> EDMA_CR_ECX_SHIFT); +} + +/*! \brief Cancels the remaining data transfer and treats it as an error condition. + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableEcx(EDmaRegType *obj) +{ + obj->CR |= EDMA_CR_ECX_MASK; +} + +/*! \brief Disable error cancel transfer + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableEcx(EDmaRegType *obj) +{ + obj->CR &= ~EDMA_CR_ECX_MASK; +} + +/*! \brief Get Cancel transfer mode + * + * \param[in] obj : pointer to eDMA register instance + * \return cancel transfer mode + * - 0b: normal operation + * - 1b: cancel the remaining data transfer. Stop the executing channel and force the minor loop to finish. + * The cancel takes effect after the last write of the current read/write sequence. The CX bit clears itself + * after the cancel has been honored. This cancel retires the channel normally as if the minor loop was completed. no error + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetCx(const EDmaRegType *obj) +{ + return ((obj->CR & EDMA_CR_CX_MASK) >> EDMA_CR_CX_SHIFT); +} + +/*! \brief Cancels the remaining data transfer. + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableCx(EDmaRegType *obj) +{ + obj->CR |= EDMA_CR_CX_MASK; +} + +/*! \brief Disable cancel transfer + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableCx(EDmaRegType *obj) +{ + obj->CR &= ~EDMA_CR_CX_MASK; +} + +/*! \brief EDMA active status + * + * \param[in] obj : pointer to eDMA register instance + * \return dma active status + * - 0b: eDMA is idle + * - 1b: eDMA is excuting a channel + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetActiveStatus(const EDmaRegType *obj) +{ + return ((obj->CR & EDMA_CR_ACTIVE_MASK) >> EDMA_CR_ACTIVE_SHIFT); +} + +/*! \brief Get destination bus error status + * + * \param[in] obj : pointer to eDMA register instance + * \return destination bus error status + * - 0b: No destination bus error + * - 1b: The last recorded error was a bus error on a destination write + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetDbeStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_DBE_MASK) >> EDMA_ES_DBE_SHIFT); +} + +/*! \brief Get source bus error status + * + * \param[in] obj : pointer to eDMA register instance + * \return source bus error status + * - 0b: No source bus error + * - 1b: The last recorded error was a bus error on a source read + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetSbeStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_SBE_MASK) >> EDMA_ES_SBE_SHIFT); +} + +/*! \brief Get Scatter/Gather configuration error + * + * \param[in] obj : pointer to eDMA register instance + * \return Scatter/Gather configuration error status + * - 0b: No scatter/gather configuration error + * - 1b: The last recorded error was a configuration error detected in the TCDn_DLASTSGA field. + * TCDn_DLASTSGA is not on a 32 bits boundary. + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetSgeStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_SGE_MASK) >> EDMA_ES_SGE_SHIFT); +} + +/*! \brief Get NBYTES/CITER configuration Error + * + * \param[in] obj : pointer to eDMA register instance + * \return NBYTES/CITER configuration error status + * - 0b: No NBYTES/CITER configuration error + * - 1b: The last recorded error was a configuration error detected in the TCDn_NBYTES or TCDn_CITER fields. + * TCDn_NBYTES is not a multiple of TCDn_ATTR[SSIZE] and TCDn_ATTR[DSIZE], orTCDn_CITER[CITER] is equal to zero, + * orTCDn_CITER[ELINK] is not equal to TCDn_BITER[ELINK] + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetNceStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_NCE_MASK) >> EDMA_ES_NCE_SHIFT); +} + +/*! \brief Get destination offset error + * + * \param[in] obj : pointer to eDMA register instance + * \return destination offset error status + * - 0b: No destination offset configuration error + * - 1b: The last recorded error was a configuration error detected in the TCDn_DOFF field. + * TCDn_DOFF is inconsistent with TCDn_ATTR[SIZE]. + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetDoeStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_DOE_MASK) >> EDMA_ES_DOE_SHIFT); +} + +/*! \brief Get destination address error + * + * \param[in] obj : pointer to eDMA register instance + * \return destination address error status + * - 0b: No destination address configuration error + * - 1b: The last recorded error was a configuration error detected in the TCDn_DADDR field. + * TCDn_DADDR is inconsistent with TCDn_ATTR[SIZE] + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetDaeStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_DAE_MASK) >> EDMA_ES_DAE_SHIFT); +} + +/*! \brief Get source offset error + * + * \param[in] obj : pointer to eDMA register instance + * \return source offset error status + * - 0b: No source offset configuration error + * - 1b: The last recorded error was a configuration error detected in the TCDn_SOFF field. + * TCDn_SOFF is inconsistent with TCDn_ATTR[SIZE]. + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetSoeStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_SOE_MASK) >> EDMA_ES_SOE_SHIFT); +} + +/*! \brief Get source address Error + * + * \param[in] obj : pointer to eDMA register instance + * \return source address error status + * - 0b: No source address configuration error. + * - 1b: The last recorded error was a configuration error detected in the TCDn_SADDR field. + * TCDn_SADDR is inconsistent with TCDn_ATTR[SIZE]. + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetSaeStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_SAE_MASK) >> EDMA_ES_SAE_SHIFT); +} + +/*! \brief Get error channel number or canceled channel number + * + * \param[in] obj : pointer to eDMA register instance + * \return The channel number of the last recorded error, excluding CPE errors, or last recorded error canceled transfer + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetErrChn(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_ERRCHN_MASK) >> EDMA_ES_ERRCHN_SHIFT); +} + +/*! \brief Get channel priority error + * + * \param[in] obj : pointer to eDMA register instance + * \return channel priority error status + * - 0b: No channel priority error + * - 1b: The last recorded error was a configuration error in the channel priorities . Channel priorities are not unique. + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetCpeStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_CPE_MASK) >> EDMA_ES_CPE_SHIFT); +} + +/*! \brief Get transfer Canceled status + * + * \param[in] obj : pointer to eDMA register instance + * \return transfer canceled status + * - 0b: No canceled transfers + * - 1b: The last recorded entry was a canceled transfer by the error cancel transfer input + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetEcxStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_ECX_MASK) >> EDMA_ES_ECX_SHIFT); +} + +/*! \brief Get logical OR of all error status bits + * + * \param[in] obj : pointer to eDMA register instance + * \return logical OR of all error status bits + * - 0b: No ERR bits are set. + * - 1b: At least one ERR bit is set indicating a valid error exists that has not been cleared + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetVldStatus(const EDmaRegType *obj) +{ + return ((obj->ES & EDMA_ES_VLD_MASK) >> EDMA_ES_VLD_SHIFT); +} + +/*! \brief Clear enable error interrupt register + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_ClearEnableErrorInterrupt(EDmaRegType *obj, uint8_t value) +{ + uint32_t ceeiTmp = 0; + ceeiTmp |= (((uint32_t)(((uint32_t)(value)) << EDMA_CEEI_CEEI_SHIFT)) & EDMA_CEEI_CEEI_MASK); + obj->CEEI = ceeiTmp; +} + +/*! \brief Clear all bits in EEI + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableCaee(EDmaRegType *obj) +{ + uint32_t ceeiTmp = 0; + ceeiTmp |= EDMA_CEEI_CAEE_MASK; + obj->CEEI = ceeiTmp; +} + +/*! \brief : Clear only the EEI bit specified in the CEEI field + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableCaee(EDmaRegType *obj) +{ + uint32_t ceeiTmp = 0; + ceeiTmp &= ~EDMA_CEEI_CAEE_MASK; + obj->CEEI = ceeiTmp; +} + +/*! \brief Set enable error interrupt register + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetEnableErrorInterrupt(EDmaRegType *obj, uint8_t channel) +{ + uint8_t seeiTmp = 0; + seeiTmp |= (((uint8_t)(((uint8_t)(channel)) << EDMA_SEEI_SEEI_SHIFT)) & EDMA_SEEI_SEEI_MASK); + obj->SEEI = seeiTmp; +} + +/*! \brief Sets all bits in EEI + * + * \param[in] obj :pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableSaee(EDmaRegType *obj) +{ + uint8_t seeiTmp = 0; + seeiTmp |= EDMA_SEEI_SAEE_MASK; + obj->SEEI = seeiTmp; +} + +/*! \brief Set only the EEI bit specified in the SEEI field. + * + * \param[in] obj :pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableSaee(EDmaRegType *obj) +{ + uint8_t seeiTmp = 0; + seeiTmp &= ~EDMA_SEEI_SAEE_MASK; + obj->SEEI = seeiTmp; +} + +/*! \brief Clear enable request register + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_ClearEnableRequest(EDmaRegType *obj, uint8_t channel) +{ + uint8_t cerqTmp = 0; + cerqTmp |= (((uint8_t)(((uint8_t)(channel)) << EDMA_CERQ_CERQ_SHIFT)) & EDMA_CERQ_CERQ_MASK); + obj->CERQ = cerqTmp; +} + +/*! \brief Clear only the ERQ bit specified in the CERQ field + * + * \param[in] obj :pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableCaer(EDmaRegType *obj) +{ + uint8_t cerqTmp = 0; + cerqTmp |= EDMA_CERQ_CAER_MASK; + obj->CERQ = cerqTmp; +} + +/*! \brief Clear all bits in ERQ + * + * \param[in] obj :pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableCaer(EDmaRegType *obj) +{ + uint8_t cerqTmp = 0; + cerqTmp &= ~EDMA_CERQ_CAER_MASK; + obj->CERQ = cerqTmp; +} + +/*! \brief Set enable request register + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetEnableRequest(EDmaRegType *obj, uint8_t channel) +{ + uint32_t serqTmp = 0; + serqTmp |= (((uint8_t)(((uint8_t)(channel)) << EDMA_SERQ_SERQ_SHIFT)) & EDMA_SERQ_SERQ_MASK); + obj->SERQ = serqTmp; +} + +/*! \brief Set all bits in ERQ + * + * \param[in] obj :pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableSaer(EDmaRegType *obj) +{ + uint8_t serqTmp = 0; + serqTmp |= EDMA_SERQ_SAER_MASK; + obj->SERQ = serqTmp; +} + +/*! \brief Set only the ERQ bit specified in the SERQ field + * + * \param[in] obj :pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableSaer(EDmaRegType *obj) +{ + uint8_t serqTmp = 0; + serqTmp &= ~EDMA_SERQ_SAER_MASK; + obj->SERQ = serqTmp; +} + +/*! \brief Clears the done status for a channel or all channels. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_ClearDoneStatusFlag(EDmaRegType *obj, uint8_t channel) +{ + uint8_t cdenTmp = 0; + cdenTmp |= (((uint8_t)(((uint8_t)(channel)) << EDMA_CDNE_CDNE_SHIFT)) & EDMA_CDNE_CDNE_MASK); + obj->CDNE = cdenTmp; +} + +/*! \brief Clears all bits in TCDn_CSR[DONE] + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableCadn(EDmaRegType *obj) +{ + uint8_t cdenTmp = 0; + cdenTmp |= EDMA_CDNE_CDNE_MASK; + obj->CDNE = cdenTmp; +} + +/*! \brief Clears only the TCDn_CSR[DONE] bit specified in the CDNE field + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableCadn(EDmaRegType *obj) +{ + uint8_t cdenTmp = 0; + cdenTmp &= ~EDMA_CDNE_CDNE_MASK; + obj->CDNE = cdenTmp; +} + +/*! \brief Set set START bit register + * + * \param[in] obj pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetChannelStartFlag(EDmaRegType *obj, uint8_t channel) +{ + uint8_t ssrtTmp = 0; + ssrtTmp |= (((uint8_t)(((uint8_t)(channel)) << EDMA_SSRT_SSRT_SHIFT)) & EDMA_SSRT_SSRT_MASK); + obj->SSRT = ssrtTmp; +} + +/*! \brief Set all bits in TCDn_CSR[START] + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableSast(EDmaRegType *obj) +{ + uint8_t ssrtTmp = 0; + ssrtTmp |= EDMA_SSRT_SAST_MASK; + obj->SSRT = ssrtTmp; +} +/*! \brief Set only the TCDn_CSR[START] bit specified in the SSRT field + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableSast(EDmaRegType *obj) +{ + uint8_t ssrtTmp = 0; + ssrtTmp &= ~EDMA_SSRT_SAST_MASK; + obj->SSRT = ssrtTmp; +} + +/*! \brief Clears the error status for the eDMA channel or channels. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_ClearErrorIntStatusFlag(EDmaRegType *obj, uint8_t channel) +{ + uint8_t cerrTmp = 0; + cerrTmp |= (((uint8_t)(((uint8_t)(channel)) << EDMA_CERR_CERR_SHIFT)) & EDMA_CERR_CERR_MASK); + obj->CERR = cerrTmp; + /* Read back to avoid problem */ + (void)obj->CERR; +} + +/*! \brief Clear all bits in ERR + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableCaei(EDmaRegType *obj) +{ + uint8_t cerrTmp = 0; + cerrTmp |= EDMA_CERR_CAEI_MASK; + obj->CERR = cerrTmp; +} + +/*! \brief Clear only the ERR bit specified in the CERR field + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableCaei(EDmaRegType *obj) +{ + uint8_t cerrTmp = 0; + cerrTmp &= ~EDMA_CERR_CAEI_MASK; + obj->CERR = cerrTmp; +} + +/*! \brief Gets interrupt status + * + * \param[in] obj : pointer to eDMA register instance + * \return 32 bit variable indicating interrupt channels. + */ +__attribute__((always_inline)) static inline uint32_t EDmaReg_GetChnInterruptFlag(const EDmaRegType *obj) +{ + return obj->INT; +} + +/*! \brief Clear interrupt register + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_ClearIntStatusFlag(EDmaRegType *obj, uint8_t channel) +{ + uint8_t cintTmp = 0; + cintTmp |= (((uint8_t)(((uint8_t)(channel)) << EDMA_CINT_CINT_SHIFT)) & EDMA_CINT_CINT_MASK); + obj->CINT = cintTmp; + /* Read back to avoid problem */ + (void)obj->CINT; +} + +/*! \brief Clear all bits in interrupt + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableCair(EDmaRegType *obj) +{ + uint8_t cintTmp = 0; + cintTmp |= EDMA_CINT_CAIR_MASK; + obj->CINT = cintTmp; +} + +/*! \brief Clear only the interrupt bit specified in the CINT field + * + * \param[in] obj : pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableCair(EDmaRegType *obj) +{ + uint8_t cintTmp = 0; + cintTmp &= ~EDMA_CINT_CAIR_MASK; + obj->CINT = cintTmp; +} + +/*! \brief Gets error status + * + * \param[in] obj : pointer to eDMA register instance + * \return 32 bit variable indicating error channels. If error happens on eDMA channel n, the bit n + * of this variable is '1'. If not, the bit n of this variable is '0'. + */ +__attribute__((always_inline)) static inline uint32_t EDmaReg_GetErrorStatusFlag(const EDmaRegType *obj) +{ + return obj->ERR; +} + +/*! \brief Gets channel error status + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \return bool variable indicating error channels. + */ +__attribute__((always_inline)) static inline bool EDmaReg_GetChannelErrorStatusFlag(EDmaRegType *obj, const uint8_t channel) +{ + uint32_t errTmp = 0; + errTmp = obj->ERR; + return 1UL == ((errTmp >> channel) & EDMA_ERR_ERRN_MASK); +} + +/*! \brief Sets the eDMA channel priority. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : Priority of the DMA channel. Different channels should have different priority + * setting inside a group. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetChannelPriority(EDmaRegType *obj, const uint8_t channel, uint8_t value) +{ + uint32_t dchpriTmp = obj->DCHPRI_N[channel]; + + dchpriTmp &= ~(EDMA_DCHPRI_CHPRI_MASK); + dchpriTmp |= (((uint32_t)(((uint32_t)(value)) << EDMA_DCHPRI_CHPRI_SHIFT)) & EDMA_DCHPRI_CHPRI_MASK); + obj->DCHPRI_N[channel] = dchpriTmp; +} + +/*! \brief Channel n can suspend a lower priority channel. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_EnablePreemptAbility(EDmaRegType *obj, const uint8_t channel) +{ + obj->DCHPRI_N[channel] &= ~EDMA_DCHPRI_DPA_MASK; +} + +/*! \brief Channel n cannot suspend any channel, regardless of channel + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_DisablePreemptAbility(EDmaRegType *obj, const uint8_t channel) +{ + obj->DCHPRI_N[channel] |= EDMA_DCHPRI_DPA_MASK; +} + +/*! \brief Channel n can be temporarilly suspended by the service request of a higher priority channel. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_EnableChannelPreemption(EDmaRegType *obj, const uint8_t channel) +{ + obj->DCHPRI_N[channel] |= EDMA_DCHPRI_ECP_MASK; +} + +/*! \brief Channel n cannot be suspended by a higher priority channel's service request. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_DisableChannelPreemption(EDmaRegType *obj, const uint8_t channel) +{ + obj->DCHPRI_N[channel] &= ~EDMA_DCHPRI_ECP_MASK; +} + +/*! \brief Configures the source address for the hardware TCD. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : The pointer to the source memory address. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdSrcAddr(EDmaRegType *obj, const uint8_t channel, uint32_t value) +{ + obj->TCD[channel].SADDR = value; +} + +/*! \brief Configures the source address signed offset for the hardware TCD. + * + * Sign-extended offset applied to the current source address to form the next-state value as each + * source read is complete. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : signed-offset for source address. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdSrcOffset(EDmaRegType *obj, uint8_t channel, int16_t value) +{ + obj->TCD[channel].SOFF = (int16_t)value; +} + +/*! \brief Sets the source/destination transfer size. + * + * Configures the source/destination data read transfer size (1/2/4/16/32 bytes). + * + * \param[in] obj : base pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] size : Source transfer size. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdSrcDesTransferSize(EDmaRegType *obj, uint8_t channel, uint8_t value) +{ + uint16_t attrTemp; + attrTemp = obj->TCD[channel].ATTR; + attrTemp &= (uint16_t)(~(EDMA_TCD_ATTR_SDSIZE_MASK)); + attrTemp |= (((uint16_t)(((uint16_t)(value)) << EDMA_TCD_ATTR_SDSIZE_SHIFT)) & EDMA_TCD_ATTR_SDSIZE_MASK); + obj->TCD[channel].ATTR = attrTemp; +} + +/*! \brief Set the destination address modulo. + * + * 00000b: destination address modulo feature is disabled + * 00001~11111b: This value defnies a specific address range specified to be the value after SADDR + SOFF + * calculation is performed on the original register value. Setting this field provides the ability to implement + * a circular data queue easily. For data queues requiring power-of-2 size bytes, the queue should start + * at a 0-modulo-size address and the SMOD field should be set to the appropriate value for the queue, freezing + * the desired number of upper address bits. The value programmed into this field specifieds the number of lower + * bits alllowed to change. For a cicular queue application, the SOFF is typically set to the transfer size to + * implement post-increment addressing with the SMOD funciton constraining the addresses to a 0-modulo-size range. + * + * \param[in] obj : base pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : address modulo. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdDmod(EDmaRegType *obj, uint8_t channel, uint8_t value) +{ + uint16_t attrTemp; + attrTemp = obj->TCD[channel].ATTR; + attrTemp &= (uint16_t)(~(EDMA_TCD_ATTR_DMOD_MASK)); + attrTemp |= (((uint16_t)(((uint16_t)(value)) << EDMA_TCD_ATTR_DMOD_SHIFT)) & EDMA_TCD_ATTR_DMOD_MASK); + obj->TCD[channel].ATTR = attrTemp; +} + +/*! \brief Set the source address modulo. + * + * 00000b: Source address modulo feature is disabled + * 00001~11111b: This value defnies a specific address range specified to be the value after SADDR + SOFF + * calculation is performed on the original register value. Setting thsi field provides the ability to implement + * a circular data queue easily. For data queues requiring power-of-2 size bytes, the queue should start + * at a 0-modulo-size address and the SMOD field should be set to the appropriate value for the queue, freezing + * the desired number of upper address bits. The value programmed into this field specifieds the number of lower + * bits alllowed to change. For a cicular queue application, the SOFF is typically set to the transfer size to + * implement post-increment addressing with the SMOD funciton constraining the addresses to a 0-modulo-size range. + * + * \param[in] obj : base pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : Source transfer size. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdSmod(EDmaRegType *obj, uint8_t channel, uint8_t value) +{ + uint16_t attrTemp; + attrTemp = obj->TCD[channel].ATTR; + attrTemp &= (uint16_t)(~(EDMA_TCD_ATTR_SMOD_MASK)); + attrTemp |= (((uint16_t)(((uint16_t)(value)) << EDMA_TCD_ATTR_SMOD_SHIFT)) & EDMA_TCD_ATTR_SMOD_MASK); + obj->TCD[channel].ATTR = attrTemp; +} + +/*! \brief Configures the nbytes for the eDMA channel. + * + * + * Note here that user need firstly configure the minor loop mapping feature and then call this + * function. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : Number of bytes to be transferred in each service request of the channel + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdNbytes(EDmaRegType *obj, uint8_t channel, uint32_t value) +{ + if(((obj->CR & EDMA_CR_EMLM_MASK) >> EDMA_CR_EMLM_SHIFT) != 0UL) + { + bool mlOffNo = false; + if(((obj->TCD[channel].NBYTES & EDMA_TCD_NBYTES_MLOFFNO_SMLOE_MASK) >> EDMA_TCD_NBYTES_MLOFFNO_SMLOE_SHIFT) == 0UL) + { + if(((obj->TCD[channel].NBYTES & EDMA_TCD_NBYTES_MLOFFNO_DMLOE_MASK) >> EDMA_TCD_NBYTES_MLOFFNO_DMLOE_SHIFT) == 0UL) + { + obj->TCD[channel].NBYTES = (value & EDMA_TCD_NBYTES_MLOFFNO_NBYTES_MASK); + mlOffNo = true; + } + } + if(!mlOffNo) + { + uint32_t regValTemp; + regValTemp = obj->TCD[channel].NBYTES; + regValTemp &= ~(EDMA_TCD_NBYTES_MLOFFYES_NBYTES_MASK); + regValTemp + |= (((uint16_t)(((uint16_t)(value)) << EDMA_TCD_NBYTES_MLOFFYES_NBYTES_SHIFT)) & EDMA_TCD_NBYTES_MLOFFYES_NBYTES_MASK); + obj->TCD[channel].NBYTES = regValTemp; + } + } + else + { + obj->TCD[channel].NBYTES = value; + } +} + +/*! \brief Enables/disables the source minor loop offset feature for the TCD. + * + * Configures whether the minor loop offset is applied to the source address + * upon minor loop completion. + * NOTE: EMLM bit needs to be enabled prior to calling this function, otherwise + * it has no effect. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] enable : Enables (true) or disables (false) source minor loop offset. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdSrcMinorLoopOffsetCmd(EDmaRegType *obj, uint8_t channel, bool enable) +{ + if(((obj->CR >> EDMA_CR_EMLM_SHIFT) & 1U) != 0U) + { + if(enable) + { + obj->TCD[channel].NBYTES |= EDMA_TCD_NBYTES_MLOFFYES_SMLOE_MASK; + } + else + { + obj->TCD[channel].NBYTES &= ~EDMA_TCD_NBYTES_MLOFFYES_SMLOE_MASK; + } + } +} + +/*! \brief Enables/disables the destination minor loop offset feature for the TCD. + * + * Configures whether the minor loop offset is applied to the destination address + * upon minor loop completion. + * NOTE: EMLM bit needs to be enabled prior to calling this function, otherwise + * it has no effect. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] enable : Enables (true) or disables (false) destination minor loop offset. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdDestMinorLoopOffsetCmd(EDmaRegType *obj, uint8_t channel, bool enable) +{ + if(((obj->CR >> EDMA_CR_EMLM_SHIFT) & 1U) != 0U) + { + if(enable) + { + obj->TCD[channel].NBYTES |= EDMA_TCD_NBYTES_MLOFFYES_DMLOE_MASK; + } + else + { + obj->TCD[channel].NBYTES &= ~EDMA_TCD_NBYTES_MLOFFYES_DMLOE_MASK; + } + } +} + +/*! \brief Configures the minor loop offset for the TCD. + * + * Configures the offset value. If neither source nor destination offset is enabled, + * offset is not configured. + * NOTE: EMLM bit needs to be enabled prior to calling this function, otherwise + * it has no effect. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] offset : Minor loop offset + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdMinorLoopOffset(EDmaRegType *obj, uint8_t channel, int32_t offset) +{ + if(((obj->CR & EDMA_CR_EMLM_MASK) >> EDMA_CR_EMLM_SHIFT) != 0UL) + { + bool mlOffNo = false; + if(((obj->TCD[channel].NBYTES & EDMA_TCD_NBYTES_MLOFFNO_SMLOE_MASK) >> EDMA_TCD_NBYTES_MLOFFNO_SMLOE_SHIFT) != 0UL) + { + mlOffNo = true; + } + if(((obj->TCD[channel].NBYTES & EDMA_TCD_NBYTES_MLOFFNO_DMLOE_MASK) >> EDMA_TCD_NBYTES_MLOFFNO_DMLOE_SHIFT) != 0UL) + { + mlOffNo = true; + } + if(mlOffNo) + { + uint32_t regValTemp; + regValTemp = obj->TCD[channel].NBYTES; + regValTemp &= ~(EDMA_TCD_NBYTES_MLOFFYES_MLOFF_MASK); + regValTemp + |= (((uint32_t)(((uint32_t)(offset)) << EDMA_TCD_NBYTES_MLOFFYES_MLOFF_SHIFT)) & EDMA_TCD_NBYTES_MLOFFYES_MLOFF_MASK); + obj->TCD[channel].NBYTES = regValTemp; + } + } +} + +/*! \brief Configures the last source address adjustment for the TCD. + * + * Adjustment value added to the source address at the completion of the major iteration count. This + * value can be applied to restore the source address to the initial value, or adjust the address to + * reference the next data structure. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : adjustment value + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdSrcLastAdjust(EDmaRegType *obj, uint8_t channel, int32_t value) +{ + obj->TCD[channel].SLAST = (uint32_t)value; +} + +/*! \brief Configures the destination address for the TCD. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : The pointer to the destination address. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdDestAddr(EDmaRegType *obj, uint8_t channel, uint32_t value) +{ + obj->TCD[channel].DADDR = value; +} + +/*! \brief Configures the destination address signed offset for the TCD. + * + * Sign-extended offset applied to the current source address to form the next-state value as each + * destination write is complete. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : signed-offset + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdDestOffset(EDmaRegType *obj, uint8_t channel, int16_t value) +{ + obj->TCD[channel].DOFF = (uint16_t)value; +} + +/*! \brief Enable/Disables channel-to-channel linking on minor-loop complete. + * + * As the channel completes the minor loop,this flag enables linking to another channel, defined by the + * LINKC field. THe link target channel initiates a channel service request via an internal mechanism + * that sets the TCDn_CSR[START]bit of the specified channel. + * If channel linking is disabled, the CITER value is extended to 15 bits in place of a link channel number. + * If the major loop is exhausted, this link mechanism is suppressed in favor of the MAJORELINK channel linking. + * + NOTE: this bit must be equal to the BITER[ELINK] bit;oterwise, a configuration error is reported. + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] enable : Enables (true) or disables (false) signed-offset + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdCiterMinorLinkCmd(EDmaRegType *obj, uint8_t channel, uint8_t enable) +{ + if(enable) + { + obj->TCD[channel].CITER |= EDMA_TCD_CITER_ELINKYES_ELINK_MASK; + } + else + { + obj->TCD[channel].CITER &= ~EDMA_TCD_CITER_ELINKYES_ELINK_MASK; + } +} + +/*! \brief Configures the minor loop link channel number. + * + * If channel-to-channel linking is enabled(ELINK = 1),then after the minor loop is exhausted. + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : channel number for minor link + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdCiterMinorLinkChannel(EDmaRegType *obj, uint8_t channel, uint8_t value) +{ + uint16_t citerElinkTemp; + citerElinkTemp = obj->TCD[channel].CITER; + citerElinkTemp &= (uint16_t) ~(EDMA_TCD_CITER_ELINKYES_LINKCH_MASK); + citerElinkTemp |= (((uint16_t)(((uint16_t)(value)) << EDMA_TCD_CITER_ELINKYES_LINKCH_SHIFT)) & EDMA_TCD_CITER_ELINKYES_LINKCH_MASK); + obj->TCD[channel].CITER = citerElinkTemp; +} + +/*! \brief Configures the major loop count for the channel. + * + * It is decremented each time the minor loop is completed and updated in the transfer control descriptor + * memory. After the major iteration count is exhausted, the channel performs a number of operations, for + * example,final source and destination address calculations, optionally generating an interrupt to signal + * channel completion before reloading the CITER field from the Beginning iteration Count(BITER)field. + * + * NOTE: When the CITER field is initially loaded by software, it must be set to the same value as that + * contained in the BITER field. if the channel is configured to execute a single service request. the + * initial values of BITER and CITER should be 0x0001. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : channel number for minor link + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdMajorCount(EDmaRegType *obj, uint8_t channel, uint16_t count) +{ + uint16_t regValTemp = 0; + if((obj->TCD[channel].BITER & EDMA_TCD_BITER_ELINKNO_ELINK_MASK) == EDMA_TCD_BITER_ELINKNO_ELINK_MASK) + { + regValTemp = obj->TCD[channel].BITER; + regValTemp &= (uint16_t) ~(EDMA_TCD_BITER_ELINKYES_BITER_MASK); + regValTemp |= (((uint16_t)(((uint16_t)(count)) << EDMA_TCD_BITER_ELINKYES_BITER_SHIFT)) & EDMA_TCD_BITER_ELINKYES_BITER_MASK); + obj->TCD[channel].BITER = regValTemp; + + regValTemp = obj->TCD[channel].CITER; + regValTemp &= (uint16_t) ~(EDMA_TCD_CITER_ELINKYES_CITER_MASK); + regValTemp |= (((uint16_t)(((uint16_t)(count)) << EDMA_TCD_CITER_ELINKYES_CITER_SHIFT)) & EDMA_TCD_CITER_ELINKYES_CITER_MASK); + obj->TCD[channel].CITER = regValTemp; + } + else + { + regValTemp = obj->TCD[channel].BITER; + regValTemp &= (uint16_t) ~(EDMA_TCD_BITER_ELINKNO_BITER_MASK); + regValTemp |= (((uint16_t)(((uint16_t)(count)) << EDMA_TCD_BITER_ELINKNO_BITER_SHIFT)) & EDMA_TCD_BITER_ELINKNO_BITER_MASK); + obj->TCD[channel].BITER = regValTemp; + + regValTemp = obj->TCD[channel].CITER; + regValTemp &= (uint16_t) ~(EDMA_TCD_CITER_ELINKNO_CITER_MASK); + regValTemp |= (((uint16_t)(((uint16_t)(count)) << EDMA_TCD_CITER_ELINKNO_CITER_SHIFT)) & EDMA_TCD_CITER_ELINKNO_CITER_MASK); + obj->TCD[channel].CITER = regValTemp; + } +} + +/*! \brief Returns the current major iteration count. + * + * Gets the current major iteration count according to minor loop channel link settings. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \return current : iteration count + */ +__attribute__((always_inline)) static inline uint32_t EDmaReg_GetTcdCurrentMajorCount(const EDmaRegType *obj, uint8_t channel) +{ + uint16_t result = 0U; + if((obj->TCD[channel].BITER & EDMA_TCD_BITER_ELINKNO_ELINK_MASK) == EDMA_TCD_BITER_ELINKNO_ELINK_MASK) + { + result = (uint16_t)((obj->TCD[channel].CITER & EDMA_TCD_CITER_ELINKYES_CITER_MASK) >> EDMA_TCD_CITER_ELINKYES_CITER_SHIFT); + } + else + { + result = (uint16_t)((obj->TCD[channel].CITER & EDMA_TCD_CITER_ELINKNO_CITER_MASK) >> EDMA_TCD_CITER_ELINKNO_CITER_SHIFT); + } + return (uint32_t)result; +} + +/*! \brief Configures the last source address adjustment. + * + * This function adds an adjustment value added to the source address at the completion of the major + * iteration count. This value can be applied to restore the source address to the initial value, or + * adjust the address to reference the next data structure. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : adjustment value + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdDestLastAdjust(EDmaRegType *obj, uint8_t channel, uint32_t value) +{ + obj->TCD[channel].DLASTSGA = (uint32_t)value; +} + +/*! \brief Configures the memory address of the next TCD, in Scatter/Gather mode. + * + * This address points to the beginning of a 0-modulo-32-byte region containing the next transfer control + * descriptor to be loaded into this channel. This channel reload is performed as the major iteration + * count completes. The scatter/gather address must be 0-modulo-32-byte, oterwise a configuration error + * is reported. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] value : next tcd address + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdScatterGatherLink(EDmaRegType *obj, uint8_t channel, uint32_t value) +{ + obj->TCD[channel].DLASTSGA = value; +} + +/*! \brief Channel Start + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] enable : Enable (true) /Disable (false) interrupt after TCD done. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdStartCmd(EDmaRegType *obj, uint8_t channel, uint8_t enable) +{ + if(enable) + { + obj->TCD[channel].CSR |= EDMA_TCD_CSR_START_MASK; + } + else + { + obj->TCD[channel].CSR &= ~EDMA_TCD_CSR_START_MASK; + } +} + +/*! \brief Enables/Disables the interrupt after the major loop completes for the TCD. + * + * If enabled, the channel generates an interrupt request by setting the appropriate bit in the + * interrupt register when the current major iteration count reaches zero. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] enable : Enable (true) /Disable (false) interrupt after TCD done. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdMajorCompleteIntCmd(EDmaRegType *obj, uint8_t channel, uint8_t enable) +{ + if(enable) + { + obj->TCD[channel].CSR |= EDMA_TCD_CSR_INTMAJOR_MASK; + } + else + { + obj->TCD[channel].CSR &= ~EDMA_TCD_CSR_INTMAJOR_MASK; + } +} + +/*! \brief Enables/Disables the half complete interrupt for the TCD. + * + * If set, the channel generates an interrupt request by setting the appropriate bit in the + * interrupt register when the current major iteration count reaches the halfway point. Specifically, + * the comparison performed by the eDMA engine is (CITER == (BITER >> 1)). This half-way point + * interrupt request is provided to support the double-buffered schemes or other types of data movement + * where the processor needs an early indication of the transfer's process. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] enable : Enable (true) /Disable (false) half complete interrupt. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdMajorHalfCompleteIntCmd(EDmaRegType *obj, uint8_t channel, uint8_t enable) +{ + if(enable) + { + obj->TCD[channel].CSR |= EDMA_TCD_CSR_INTHALF_MASK; + } + else + { + obj->TCD[channel].CSR &= ~EDMA_TCD_CSR_INTHALF_MASK; + } +} + +/*! \brief Disables/Enables the DMA request after the major loop completes for the TCD. + * + * If disabled, the eDMA hardware automatically clears the corresponding DMA request when the + * current major iteration count reaches zero. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] enable : Disable (true)/Enable (false) DMA request after TCD complete. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdDisableDmaRequestAfterTcdDoneCmd(EDmaRegType *obj, uint8_t channel, uint8_t disable) +{ + if(disable) + { + obj->TCD[channel].CSR |= EDMA_TCD_CSR_DREQ_MASK; + } + else + { + obj->TCD[channel].CSR &= ~EDMA_TCD_CSR_DREQ_MASK; + } +} + +/*! \brief Enables/Disables the scatter/gather feature for the TCD. + * + * \param[in] obj : base pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] enable : Enables (true) /Disables (false) scatter/gather feature. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdScatterGatherCmd(EDmaRegType *obj, uint8_t channel, uint8_t enable) +{ + if(enable) + { + obj->TCD[channel].CSR |= EDMA_TCD_CSR_ESG_MASK; + } + else + { + obj->TCD[channel].CSR &= ~EDMA_TCD_CSR_ESG_MASK; + } +} + +/*! \brief Configures the major channel link the TCD. + * + * If the major link is enabled, after the major loop counter is exhausted, the eDMA engine initiates a + * channel service request at the channel defined by these six bits by setting that channel start + * bits. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] enable : Enables (true) or Disables (false) channel major link. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdChannelMajorLinkCmd(EDmaRegType *obj, uint8_t channel, uint8_t enable) +{ + if(enable) + { + obj->TCD[channel].CSR |= EDMA_TCD_CSR_MAJORELINK_MASK; + } + else + { + obj->TCD[channel].CSR &= ~EDMA_TCD_CSR_MAJORELINK_MASK; + } +} + +/*! \brief This flag signals the channel is currently in execution + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetTcdChannelActiveStatus(EDmaRegType *obj, uint8_t channel) +{ + return ((obj->TCD[channel].CSR & EDMA_TCD_CSR_ACTIVE_MASK) >> EDMA_TCD_CSR_ACTIVE_SHIFT); +} + +/*! \brief This flag signals the eDMA has completed the major loop. + * + * The eDMA engine sets it as the CITER count reaches zero.The software clears it, orthe hardware when the + * channel is activated. This bit must be cleared to write the MAJORELINK or ESG bits. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_GetTcdChannelDoneStatus(EDmaRegType *obj, uint8_t channel) +{ + return ((obj->TCD[channel].CSR & EDMA_TCD_CSR_DONE_MASK) >> EDMA_TCD_CSR_DONE_SHIFT); +} + +/*! \brief Configures the major channel link the TCD. + * + * If the major link is enabled, after the major loop counter is exhausted, the eDMA engine initiates a + * channel service request at the channel defined by these field by setting that channel's TCDn_CSR[MAJORELINK] + * bit. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] majorLinkChannel : channel number for major link + * \param[in] enable : Enables (true) or Disables (false) channel major link. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdMajorLinkChannel(EDmaRegType *obj, uint8_t channel, uint8_t value) +{ + uint16_t csrTemp; + csrTemp = obj->TCD[channel].CSR; + csrTemp &= (uint16_t) ~(EDMA_TCD_CSR_MAJORLINKCH_MASK); + csrTemp |= (((uint16_t)(((uint16_t)(value)) << EDMA_TCD_CSR_MAJORLINKCH_SHIFT)) & EDMA_TCD_CSR_MAJORLINKCH_MASK); + ; + obj->TCD[channel].CSR = csrTemp; +} + +/*! \brief Get Hardware clear Done automatically + * + * \param[in] obj: pointer to eDMA register instance + * \param[in] channel: eDMA channel number. + * \param[in] enable: Enables (true) or Disables (false) would clear Done automatically. + * 0:hardware would not clear Done automatically + * 1:hardware would clear Done automatically + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdHardClrDoneCmd(EDmaRegType *obj, uint8_t channel, uint8_t enable) +{ + if(enable) + { + obj->TCD[channel].CSR |= EDMA_TCD_CSR_HARD_CLR_DONE_MASK; + } + else + { + obj->TCD[channel].CSR &= ~EDMA_TCD_CSR_HARD_CLR_DONE_MASK; + } +} + +/*! \brief Get Hardware clear Done automatically + * + * \param[in] obj: pointer to eDMA register instance + * \param[in] channel: eDMA channel number. + * \return 0:hardware would not clear Done automatically + * 1:hardware would clear Done automatically + */ +__attribute__((always_inline)) static inline uint8_t EDmaReg_getTcdHardClrDone(EDmaRegType *obj, uint8_t channel) +{ + return ((obj->TCD[channel].CSR & EDMA_TCD_CSR_HARD_CLR_DONE_MASK) >> EDMA_TCD_CSR_HARD_CLR_DONE_SHIFT); +} + +/*! \brief Sets the channel minor link for the TCD. + * + * \param[in] obj: pointer to eDMA register instance + * \param[in] channel: eDMA channel number. + * \param[in] enable: Channel to be linked on minor loop complete. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdBiterMinorLinkChannel(EDmaRegType *obj, uint8_t channel, uint8_t value) +{ + uint16_t biterElinkTemp; + biterElinkTemp = obj->TCD[channel].BITER; + biterElinkTemp &= (uint16_t) ~(EDMA_TCD_BITER_ELINKYES_LINKCH_MASK); + biterElinkTemp |= (((uint16_t)(((uint16_t)(value)) << EDMA_TCD_BITER_ELINKYES_LINKCH_SHIFT)) & EDMA_TCD_BITER_ELINKYES_LINKCH_MASK); + obj->TCD[channel].BITER = biterElinkTemp; +} + +/*! \brief Configures the minor channel link the TCD. + * + * If the major link is enabled, after the major loop counter is exhausted, the eDMA engine initiates a + * channel service request at the channel defined by these six bits by setting that channel start + * bits. + * + * \param[in] obj: pointer to eDMA register instance + * \param[in] channel: eDMA channel number. + * \param[in] enable: Enables (true) or Disables (false) channel major link. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdBiterMinorLinkCmd(EDmaRegType *obj, uint8_t channel, uint8_t enable) +{ + if(enable) + { + obj->TCD[channel].BITER |= EDMA_TCD_BITER_ELINKYES_ELINK_MASK; + } + else + { + obj->TCD[channel].BITER &= ~EDMA_TCD_BITER_ELINKYES_ELINK_MASK; + } +} + +/*! \brief Cancels the remaining data transfer. + * + * This function stops the executing channel and forces the minor loop + * to finish. The cancellation takes effect after the last write of the + * current read/write sequence. The CX clears itself after the cancel has + * been honored. This cancel retires the channel normally as if the minor + * loop had completed. + * + * \param[in] obj: pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_CancelTransfer(EDmaRegType *obj) +{ + EDmaReg_EnableCx(obj); + while(EDmaReg_GetCx(obj) != 0UL) + { + } +} + +/*! \brief Cancels the remaining data transfer and treats it as an error condition. + * + * This function stops the executing channel and forces the minor loop + * to finish. The cancellation takes effect after the last write of the + * current read/write sequence. The CX clears itself after the cancel has + * been honoured. This cancel retires the channel normally as if the minor + * loop had completed. Additional thing is to treat this operation as an error + * condition. + * + * \param[in] obj: pointer to eDMA register instance + */ +__attribute__((always_inline)) static inline void EDmaReg_CancelTransferWithError(EDmaRegType *obj) +{ + EDmaReg_EnableEcx(obj); + while(EDmaReg_GetEcx(obj) != 0UL) + { + } +} + +/*! \brief Enables/Disables the error interrupt for channels. + * + * \param[in] obj: base pointer to eDMA register instance + * \param[in] channel: Channel indicator. + * \param[in] enable : Enable(true) or Disable (false) error interrupt. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetErrorIntCmd(EDmaRegType *obj, uint8_t channel, bool enable) +{ + if(enable) + { + EDmaReg_SetEnableErrorInterrupt(obj, channel); + } + else + { + EDmaReg_ClearEnableErrorInterrupt(obj, channel); + } +} + +/*! \brief Enables/Disables the DMA request for the channel or all channels. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] enable : Enable(true) or Disable (false) eDMA request. + * \param[in] channel : Channel indicator. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetDmaRequestCmd(EDmaRegType *obj, uint8_t channel, bool enable) +{ + if(enable) + { + EDmaReg_SetEnableRequest(obj, channel); + } + else + { + EDmaReg_ClearEnableRequest(obj, channel); + } +} + +/*! \brief Clears all registers to 0 for the hardware TCD. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + */ +__attribute__((always_inline)) static inline void EDmaReg_ClearTcdReg(EDmaRegType *obj, uint8_t channel) +{ + obj->TCD[channel].NBYTES = 0U; + obj->TCD[channel].SADDR = 0U; + obj->TCD[channel].SOFF = 0; + obj->TCD[channel].ATTR = 0U; + obj->TCD[channel].SLAST = 0; + obj->TCD[channel].DADDR = 0U; + obj->TCD[channel].DOFF = 0; + obj->TCD[channel].CITER = 1U; + obj->TCD[channel].DLASTSGA = 0; + obj->TCD[channel].CSR = 0U; + obj->TCD[channel].BITER = 1U; +} + +/*! \brief Configures the transfer attribute for the eDMA channel. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] srcModulo : enumeration type for an allowed source modulo. The value defines a specific address range + * specified as the value after the SADDR + SOFF calculation is performed on the original register + * value. Setting this field provides the ability to implement a circular data. For data queues + * requiring power-of-2 size bytes, the queue should start at a 0-modulo-size address and the SMOD + * field should be set to the appropriate value for the queue, freezing the desired number of upper + * address bits. The value programmed into this field specifies the number of the lower address bits + * allowed to change. For a circular queue application, the SOFF is typically set to the transfer + * size to implement post-increment addressing with SMOD function restricting the addresses to a + * 0-modulo-size range. + * \param[in] destModulo : Enum type for an allowed destination modulo. + * \param[in] transferSize : Enum type for source/destination transfer size. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdAttribute(EDmaRegType *obj, uint8_t channel, uint8_t srcModulo, uint8_t destModulo, uint8_t transferSize) +{ + EDmaReg_SetTcdDmod(obj, channel, destModulo); + EDmaReg_SetTcdSmod(obj, channel, srcModulo); + EDmaReg_SetTcdSrcDesTransferSize(obj, channel, transferSize); +} + +/*! \brief Configures the major channel link the TCD. + * + * If the major link is enabled, after the major loop counter is exhausted, the eDMA engine initiates a + * channel service request at the channel defined by these six bits by setting that channel start + * bits. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] majorLinkChannel : channel number for major link + * \param[in] enable : Enables (true) or Disables (false) channel major link. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdChannelMajorLink(EDmaRegType *obj, uint8_t channel, uint32_t majorLinkChannel, bool enable) +{ + EDmaReg_SetTcdChannelMajorLinkCmd(obj, channel, enable); + EDmaReg_SetTcdMajorLinkChannel(obj, channel, majorLinkChannel); +} + +/*! \brief Sets the channel minor link for the TCD. + * + * \param[in] obj : pointer to eDMA register instance + * \param[in] channel : eDMA channel number. + * \param[in] linkChannel : Channel to be linked on minor loop complete. + * \param[in] enable : Enable (true)/Disable (false) channel minor link. + */ +__attribute__((always_inline)) static inline void EDmaReg_SetTcdChannelMinorLink(EDmaRegType *obj, uint8_t channel, uint32_t linkChannel, bool enable) +{ + EDmaReg_SetTcdBiterMinorLinkCmd(obj, channel, enable); + EDmaReg_SetTcdCiterMinorLinkCmd(obj, channel, enable); + if(enable) + { + EDmaReg_SetTcdBiterMinorLinkChannel(obj, channel, linkChannel); + EDmaReg_SetTcdCiterMinorLinkChannel(obj, channel, linkChannel); + } +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _DMA_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/eim_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/eim_reg.h new file mode 100644 index 0000000..a7c9bbb --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/eim_reg.h @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _EIM_REG_H_ +#define _EIM_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the EIM Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* CR Bit Fields */ +#define EIM_CR_GEIEN_MASK (0x01u) +#define EIM_CR_GEIEN_SHIFT (0u) +#define EIM_CR_GEIEN_WIDTH (1u) + +/* CHEN Bit Fields */ +#define EIM_CH_EN_CH0_MASK (0x01u) +#define EIM_CH_EN_CH0_SHIFT (0u) +#define EIM_CH_EN_CH0_WIDTH (1u) + +/* CH0_DATAH Bit Fields */ +#define EIM_CH0_DATAH_DATAH_MASK (0xFF000000u) +#define EIM_CH0_DATAH_DATAH_SHIFT (24u) +#define EIM_CH0_DATAH_DATAH_WIDTH (8u) + +/* CH0_DATAL Bit Fields */ +#define EIM_CH0_DATAL_DATAL_MASK (0xFFFFFFFFu) +#define EIM_CH0_DATAL_DATAL_SHIFT (0u) +#define EIM_CH0_DATAL_DATAL_WIDTH (32u) + +/* CH0_DATAM Bit Fields */ +#define EIM_CH0_DATAM_DATAM_MASK (0xFFFFFFFFu) +#define EIM_CH0_DATAM_DATAM_SHIFT (0u) +#define EIM_CH0_DATAM_DATAM_WIDTH (32u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of EIM registers + */ +typedef struct _EimRegType_ +{ + volatile uint32_t CR; /*!< Control, Error in Control Register, offset: 0x0 */ + volatile uint32_t CH_EN; /*!< Control, Error in channel enable Register, offset: 0x4 */ + uint32_t RESERVED0[62]; /*!< Reserverd block, offset: 0x8 */ + volatile uint32_t CH0_DATAH; /*!< CH0 data bits[71:64] error injection enable, offset: 0x100 */ + volatile uint32_t CH0_DATAL; /*!< CH0 data bits[31:0] error injection enable, offset: 0x0x104 */ + volatile uint32_t CH0_DATAM; /*!< CH0 data bits[63:32] error injection enable, offset: 0x0x108 */ +} EimRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the Global Error Injection Enable + * + * This function gets the current Global Error Injection Enable. + * This bit globally enables or disables the error injection function of the EIM. + * This field is initialized by hardware reset. + * + * \param[in] obj : pointer to EIM register instance + * \return Global Error Injection Enable + * - 0b : Disabled + * - 1b : Enabled + */ +__attribute__((always_inline)) static inline uint8_t EimReg_GetCrGeiEn(const EimRegType *obj) +{ + return ((obj->CR & EIM_CR_GEIEN_MASK) >> EIM_CR_GEIEN_SHIFT); +} + +/*! \brief Sets the Global Error Injection Enable + * + * This function sets the Global Error Injection Enable. + * This bit globally enables or disables the error injection function of the EIM. + * This field is initialized by hardware reset. + * + * \param[in] obj : pointer to EIM register instance + * \param[in] value : the value of Global Error Injection Enable + * - 0b : Disabled + * - 1b : Enabled + */ +__attribute__((always_inline)) static inline void EimReg_SetCrGeiEn(EimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR; + + tmp &= ~EIM_CR_GEIEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << EIM_CR_GEIEN_SHIFT)) & EIM_CR_GEIEN_MASK); + obj->CR = tmp; +} + +/*! \brief Gets the Error Injection Channel 0 Enable + * + * This function gets the current Error Injection Channel 0 Enable. + * This field enables the corresponding error injection channel. + * The Global Error Injection Enable (EIMCR[GEIEN]) field must also be asserted to enable error injection. + * After error injection is enabled, all subsequent read accesses incur one or more bit inversions as defined + * in the corresponding EIM_CHn_* registers. + * Error injection remains in effect until the error injection channel is manually disabled via software. + * + * \param[in] obj : pointer to EIM register instance + * \return Error Injection Channel 0 Enable + * - 0b : Error injection is disabled on Error Injection Channel 0 + * - 1b : Error injection is enabled on Error Injection Channel 0 + */ +__attribute__((always_inline)) static inline uint8_t EimReg_GetChEnCh0(const EimRegType *obj) +{ + return ((obj->CH_EN & EIM_CH_EN_CH0_MASK) >> EIM_CH_EN_CH0_SHIFT); +} + +/*! \brief Sets the Error Injection Channel 0 Enable + * + * This function sets the Error Injection Channel 0 Enable. + * This field enables the corresponding error injection channel. + * The Global Error Injection Enable (EIMCR[GEIEN]) field must also be asserted to enable error injection. + * After error injection is enabled, all subsequent read accesses incur one or more bit inversions + * as defined in the corresponding EIM_CHn_* registers. + * Error injection remains in effect until the error injection channel is manually disabled via software. + * + * \param[in] obj : pointer to EIM register instance + * \param[in] value : the value of Error Injection Channel 0 Enable + * - 0b : Error injection is disabled on Error Injection Channel 0 + * - 1b : Error injection is enabled on Error Injection Channel 0 + */ +__attribute__((always_inline)) static inline void EimReg_SetChEnCh0(EimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CH_EN; + + tmp &= ~EIM_CH_EN_CH0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << EIM_CH_EN_CH0_SHIFT)) & EIM_CH_EN_CH0_MASK); + obj->CH_EN = tmp; +} + +/*! \brief Gets the Data Inversion Enable [71:64] + * + * This function gets the current Data Inversion Enable [71:64]. + * This field defines a bit-mapped mask that specifies whether the corresponding bit of the read data bus + * from the target RAM should be inverted or remain unmodified. + * Writes to unimplemented bits are ignored. + * + * \param[in] obj : pointer to EIM register instance + * \return Data Inversion Enable [71:64] + * - 0b : The corresponding bit of the checkbit bus remains unmodified. + * - 1b : The corresponding bit of the checkbit bus is inverted. + */ +__attribute__((always_inline)) static inline uint8_t EimReg_GetCh0DataH(const EimRegType *obj) +{ + return ((obj->CH0_DATAH & EIM_CH0_DATAH_DATAH_MASK) >> EIM_CH0_DATAH_DATAH_SHIFT); +} + +/*! \brief Sets the Data Inversion Enable [71:64] + * + * This function sets the Data Inversion Enable [71:64]. + * This field defines a bit-mapped mask that specifies whether the corresponding bit of the read data bus + * from the target RAM should be inverted or remain unmodified. + * Writes to unimplemented bits are ignored. + * + * \param[in] obj : pointer to EIM register instance + * \param[in] value : the value of Data Inversion Enable [71:64] + * - 0b : The corresponding bit of the checkbit bus remains unmodified. + * - 1b : The corresponding bit of the checkbit bus is inverted. + */ +__attribute__((always_inline)) static inline void EimReg_SetCh0DataH(EimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CH0_DATAH; + + tmp &= ~EIM_CH0_DATAH_DATAH_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << EIM_CH0_DATAH_DATAH_SHIFT)) & EIM_CH0_DATAH_DATAH_MASK); + obj->CH0_DATAH = tmp; +} + +/*! \brief Gets the Data Inversion Enable [31:0] + * + * This function gets the current Data Inversion Enable [31:0]. + * This field defines a bit-mapped mask that specifies whether the corresponding bit of the read data bus + * from the target RAM should be inverted or remain unmodified. + * Writes to unimplemented bits are ignored. + * + * \param[in] obj : pointer to EIM register instance + * \return Data Inversion Enable [31:0] + * - 0b : The corresponding bit of the checkbit bus remains unmodified. + * - 1b : The corresponding bit of the checkbit bus is inverted. + */ +__attribute__((always_inline)) static inline uint32_t EimReg_GetCh0DataL(const EimRegType *obj) +{ + return ((obj->CH0_DATAL & EIM_CH0_DATAL_DATAL_MASK) >> EIM_CH0_DATAL_DATAL_SHIFT); +} + +/*! \brief Sets the Data Inversion Enable [31:0] + * + * This function sets the Data Inversion Enable [31:0]. + * This field defines a bit-mapped mask that specifies whether the corresponding bit of the read data bus + * from the target RAM should be inverted or remain unmodified. + * Writes to unimplemented bits are ignored. + * + * \param[in] obj : pointer to EIM register instance + * \param[in] value : the value of Data Inversion Enable [31:0] + * - 0b : The corresponding bit of the checkbit bus remains unmodified. + * - 1b : The corresponding bit of the checkbit bus is inverted. + */ +__attribute__((always_inline)) static inline void EimReg_SetCh0DataL(EimRegType *obj, uint32_t value) +{ + uint32_t tmp = obj->CH0_DATAL; + + tmp &= ~EIM_CH0_DATAL_DATAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << EIM_CH0_DATAL_DATAL_SHIFT)) & EIM_CH0_DATAL_DATAL_MASK); + obj->CH0_DATAL = tmp; +} + +/*! \brief Gets the Data Inversion Enable [63:32] + * + * This function gets the current Data Inversion Enable [63:32]. + * This field defines a bit-mapped mask that specifies whether the corresponding bit of the read data bus + * from the target RAM should be inverted or remain unmodified. + * Writes to unimplemented bits are ignored. + * + * \param[in] obj : pointer to EIM register instance + * \return Data Inversion Enable [63:32] + * - 0b : The corresponding bit of the checkbit bus remains unmodified. + * - 1b : The corresponding bit of the checkbit bus is inverted. + */ +__attribute__((always_inline)) static inline uint32_t EimReg_GetCh0DataM(const EimRegType *obj) +{ + return ((obj->CH0_DATAM & EIM_CH0_DATAM_DATAM_MASK) >> EIM_CH0_DATAM_DATAM_SHIFT); +} + +/*! \brief Sets the Data Inversion Enable [63:32] + * + * This function sets the Data Inversion Enable [63:32]. + * This field defines a bit-mapped mask that specifies whether the corresponding bit of the read data bus + * from the target RAM should be inverted or remain unmodified. + * Writes to unimplemented bits are ignored. + * + * \param[in] obj : pointer to EIM register instance + * \param[in] value : the value of Data Inversion Enable [63:32] + * - 0b : The corresponding bit of the checkbit bus remains unmodified. + * - 1b : The corresponding bit of the checkbit bus is inverted. + */ +__attribute__((always_inline)) static inline void EimReg_SetCh0DataM(EimRegType *obj, uint32_t value) +{ + uint32_t tmp = obj->CH0_DATAM; + + tmp &= ~EIM_CH0_DATAM_DATAM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << EIM_CH0_DATAM_DATAM_SHIFT)) & EIM_CH0_DATAM_DATAM_MASK); + obj->CH0_DATAM = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _EIM_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/erm_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/erm_reg.h new file mode 100644 index 0000000..dea99b8 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/erm_reg.h @@ -0,0 +1,520 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _ERM_REG_H_ +#define _ERM_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the ERM Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* CR0 Bit Fields */ +#define ERM_CR0_ENCIE1_MASK (0x08u) +#define ERM_CR0_ENCIE1_SHIFT (3u) +#define ERM_CR0_ENCIE1_WIDTH (1u) +#define ERM_CR0_ESCIE1_MASK (0x04u) +#define ERM_CR0_ESCIE1_SHIFT (2u) +#define ERM_CR0_ESCIE1_WIDTH (1u) +#define ERM_CR0_ENCIE0_MASK (0x02u) +#define ERM_CR0_ENCIE0_SHIFT (1u) +#define ERM_CR0_ENCIE0_WIDTH (1u) +#define ERM_CR0_ESCIE0_MASK (0x01u) +#define ERM_CR0_ESCIE0_SHIFT (0u) +#define ERM_CR0_ESCIE0_WIDTH (1u) + +/* SR Bit Fields */ +#define ERM_SR_NCE1_MASK (0x08u) +#define ERM_SR_NCE1_SHIFT (3u) +#define ERM_SR_NCE1_WIDTH (1u) +#define ERM_SR_SBC1_MASK (0x04u) +#define ERM_SR_SBC1_SHIFT (2u) +#define ERM_SR_SBC1_WIDTH (1u) +#define ERM_SR_NCE0_MASK (0x02u) +#define ERM_SR_NCE0_SHIFT (1u) +#define ERM_SR_NCE0_WIDTH (1u) +#define ERM_SR_SBC0_MASK (0x01u) +#define ERM_SR_SBC0_SHIFT (0u) +#define ERM_SR_SBC0_WIDTH (1u) + +/* CH0_ST0 Bit Fields */ +#define ERM_CH0_ST0_ADR0_MASK (0xFFFFFFFFu) +#define ERM_CH0_ST0_ADR0_SHIFT (0u) +#define ERM_CH0_ST0_ADR0_WIDTH (32u) + +/* CH0_ST1 Bit Fields */ +#define ERM_CH0_ST1_SYN0_MASK (0xFF000000u) +#define ERM_CH0_ST1_SYN0_SHIFT (24u) +#define ERM_CH0_ST1_SYN0_WIDTH (8u) + +/* CH0_ST2 Bit Fields */ +#define ERM_CH0_ST2_CORR_CNT0_MASK (0xFFu) +#define ERM_CH0_ST2_CORR_CNT0_SHIFT (0u) +#define ERM_CH0_ST2_CORR_CNT0_WIDTH (8u) + +/* CH1_ST0 Bit Fields */ +#define ERM_CH1_ST0_ADR1_MASK (0xFFFFFFFFu) +#define ERM_CH1_ST0_ADR1_SHIFT (0u) +#define ERM_CH1_ST0_ADR1_WIDTH (32u) + +/* CH1_ST1 Bit Fields */ +#define ERM_CH1_ST1_SYN1_MASK (0xFF000000u) +#define ERM_CH1_ST1_SYN1_SHIFT (24u) +#define ERM_CH1_ST1_SYN1_WIDTH (8u) + +/* CH1_ST2 Bit Fields */ +#define ERM_CH1_ST2_CORR_CNT1_MASK (0xFFu) +#define ERM_CH1_ST2_CORR_CNT1_SHIFT (0u) +#define ERM_CH1_ST2_CORR_CNT1_WIDTH (8u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of ERM registers + */ +typedef struct _ErmRegType_ +{ + volatile uint32_t CR0; /*!< Error report channel enable control register, offset: 0x0 */ + uint32_t RESERVED0[3]; /*!< Reserverd block, offset: 0x4 */ + volatile uint32_t SR; /*!< Error report channel status register, offset: 0x10 */ + uint32_t RESERVED1[59]; /*!< Reserverd block, offset: 0x14 */ + volatile uint32_t CH0_ST0; /*!< channel0's error address, offset: 0x100 */ + volatile uint32_t CH0_ST1; /*!< channel0's syndrome, offset: 0x104 */ + volatile uint32_t CH0_ST2; /*!< channel0's Correctable Error Count, offset: 0x108 */ + uint32_t RESERVED2[1]; /*!< Reserverd block, offset: 0x10C */ + volatile uint32_t CH1_ST0; /*!< channel1's error address, offset: 0x110 */ + volatile uint32_t CH1_ST1; /*!< channel1's syndrome, offset: 0x114 */ + volatile uint32_t CH1_ST2; /*!< channel1's Correctable Error Count, offset: 0x118 */ +} ErmRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the Enable Memory 1 Non-Correctable Notification + * + * This function gets the current Enable Memory 1 Non-Correctable Notification. + * + * \param[in] obj : pointer to ERM register instance + * \return Enable Memory 1 Non-Correctable Notification + * - 0b : Notification of Memory 1 non-correctable error events is disabled. + * - 1b : Notification of Memory 1 non-correctable error events is enabled. + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetCr0Encie1(const ErmRegType *obj) +{ + return ((obj->CR0 & ERM_CR0_ENCIE1_MASK) >> ERM_CR0_ENCIE1_SHIFT); +} + +/*! \brief Sets the Enable Memory 1 Non-Correctable Notification + * + * This function sets the Enable Memory 1 Non-Correctable Notification. + * + * \param[in] obj : pointer to ERM register instance + * \param[in] value : the value of Enable Memory 1 Non-Correctable Notification + * - 0b : Notification of Memory 1 non-correctable error events is disabled. + * - 1b : Notification of Memory 1 non-correctable error events is enabled. + */ +__attribute__((always_inline)) static inline void ErmReg_SetCr0Encie1(ErmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR0; + + tmp &= ~ERM_CR0_ENCIE1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ERM_CR0_ENCIE1_SHIFT)) & ERM_CR0_ENCIE1_MASK); + obj->CR0 = tmp; +} + +/*! \brief Gets the Enable Memory 1 Single Correction Notification + * + * This function gets the current Enable Memory 1 Single Correction Notification. + * + * \param[in] obj : pointer to ERM register instance + * \return Enable Memory 1 Single Correction Notification + * - 0b : notification of Memory 1 single-bit correction events is disabled. + * - 1b : notification of Memory 1 single-bit correction events is enabled. + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetCr0Escie1(const ErmRegType *obj) +{ + return ((obj->CR0 & ERM_CR0_ESCIE1_MASK) >> ERM_CR0_ESCIE1_SHIFT); +} + +/*! \brief Sets the Enable Memory 1 Single Correction Notification + * + * This function sets the Enable Memory 1 Single Correction Notification. + * + * \param[in] obj : pointer to ERM register instance + * \param[in] value : the value of Enable Memory 1 Single Correction Notification + * - 0b : notification of Memory 1 single-bit correction events is disabled. + * - 1b : notification of Memory 1 single-bit correction events is enabled. + */ +__attribute__((always_inline)) static inline void ErmReg_SetCr0Escie1(ErmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR0; + + tmp &= ~ERM_CR0_ESCIE1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ERM_CR0_ESCIE1_SHIFT)) & ERM_CR0_ESCIE1_MASK); + obj->CR0 = tmp; +} + +/*! \brief Gets the Enable Memory 0 Non-Correctable Notification to FHU + * + * This function gets the current Enable Memory 0 Non-Correctable Notification to FHU. + * This field is initialized by hardware reset. + * + * \param[in] obj : pointer to ERM register instance + * \return Enable Memory 0 Non-Correctable Notification to FHU + * - 0b : Notification of Memory 0 non-correctable error events is disabled. + * - 1b : Notification of Memory 0 non-correctable error events is enabled. + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetCr0Encie0(const ErmRegType *obj) +{ + return ((obj->CR0 & ERM_CR0_ENCIE0_MASK) >> ERM_CR0_ENCIE0_SHIFT); +} + +/*! \brief Sets the Enable Memory 0 Non-Correctable Notification to FHU + * + * This function sets the Enable Memory 0 Non-Correctable Notification to FHU. + * This field is initialized by hardware reset. + * + * \param[in] obj : pointer to ERM register instance + * \param[in] value : the value of Enable Memory 0 Non-Correctable Notification to FHU + * - 0b : Notification of Memory 0 non-correctable error events is disabled. + * - 1b : Notification of Memory 0 non-correctable error events is enabled. + */ +__attribute__((always_inline)) static inline void ErmReg_SetCr0Encie0(ErmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR0; + + tmp &= ~ERM_CR0_ENCIE0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ERM_CR0_ENCIE0_SHIFT)) & ERM_CR0_ENCIE0_MASK); + obj->CR0 = tmp; +} + +/*! \brief Gets the Enable Memory 0 Single Correction Notification to FHU + * + * This function gets the current Enable Memory 0 Single Correction Notification to FHU. + * This field is initialized by hardware reset. + * + * \param[in] obj : pointer to ERM register instance + * \return Enable Memory 0 Single Correction Notification to FHU + * - 0b : notification of Memory 0 single-bit correction events is disabled. + * - 1b : notification of Memory 0 single-bit correction events is enabled. + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetCr0Escie0(const ErmRegType *obj) +{ + return ((obj->CR0 & ERM_CR0_ESCIE0_MASK) >> ERM_CR0_ESCIE0_SHIFT); +} + +/*! \brief Sets the Enable Memory 0 Single Correction Notification to FHU + * + * This function sets the Enable Memory 0 Single Correction Notification to FHU. + * This field is initialized by hardware reset. + * + * \param[in] obj : pointer to ERM register instance + * \param[in] value : the value of Enable Memory 0 Single Correction Notification to FHU + * - 0b : notification of Memory 0 single-bit correction events is disabled. + * - 1b : notification of Memory 0 single-bit correction events is enabled. + */ +__attribute__((always_inline)) static inline void ErmReg_SetCr0Escie0(ErmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR0; + + tmp &= ~ERM_CR0_ESCIE0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ERM_CR0_ESCIE0_SHIFT)) & ERM_CR0_ESCIE0_MASK); + obj->CR0 = tmp; +} + +/*! \brief Gets the Memory 1 Non-Correctable Error Event + * + * This function gets the current Memory 1 Non-Correctable Error Event. + * + * \param[in] obj : pointer to ERM register instance + * \return Memory 1 Non-Correctable Error Event + * - 0b : No non-correctable error event on Memory 1 detected. + * - 1b : Non-correctable error event on Memory 1 detected. + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetSrNce1(const ErmRegType *obj) +{ + return ((obj->SR & ERM_SR_NCE1_MASK) >> ERM_SR_NCE1_SHIFT); +} + +/*! \brief Sets the Memory 1 Non-Correctable Error Event + * + * This function sets the Memory 1 Non-Correctable Error Event. + * + * \param[in] obj : pointer to ERM register instance + * \param[in] value : the value of Memory 1 Non-Correctable Error Event + * - 0b : No non-correctable error event on Memory 1 detected. + * - 1b : Non-correctable error event on Memory 1 detected. + */ +__attribute__((always_inline)) static inline void ErmReg_SetSrNce1(ErmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << ERM_SR_NCE1_SHIFT)) & ERM_SR_NCE1_MASK); + obj->SR = tmp; +} + +/*! \brief Gets the Memory 1 Single-Bit Correction Event + * + * This function gets the current Memory 1 Single-Bit Correction Event. + * + * \param[in] obj : pointer to ERM register instance + * \return Memory 1 Single-Bit Correction Event + * - 0b : No single-bit correction event on Memory 1 detected. + * - 1b : Single-bit correction event on Memory 1 detected. + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetSrSbc1(const ErmRegType *obj) +{ + return ((obj->SR & ERM_SR_SBC1_MASK) >> ERM_SR_SBC1_SHIFT); +} + +/*! \brief Sets the Memory 1 Single-Bit Correction Event + * + * This function sets the Memory 1 Single-Bit Correction Event. + * + * \param[in] obj : pointer to ERM register instance + * \param[in] value : the value of Memory 1 Single-Bit Correction Event + * - 0b : No single-bit correction event on Memory 1 detected. + * - 1b : Single-bit correction event on Memory 1 detected. + */ +__attribute__((always_inline)) static inline void ErmReg_SetSrSbc1(ErmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << ERM_SR_SBC1_SHIFT)) & ERM_SR_SBC1_MASK); + obj->SR = tmp; +} + +/*! \brief Gets the Memory 0 Non-Correctable Error Event + * + * This function gets the current Memory 0 Non-Correctable Error Event. + * Write 1 to clear this field. This write also clears the corresponding interrupt notification, + * if CR0[ENCIE0] is enabled. + * + * \param[in] obj : pointer to ERM register instance + * \return Memory 0 Non-Correctable Error Event + * - 0b : No non-correctable error event on Memory 0 detected. + * - 1b : Non-correctable error event on Memory 0 detected. + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetSrNce0(const ErmRegType *obj) +{ + return ((obj->SR & ERM_SR_NCE0_MASK) >> ERM_SR_NCE0_SHIFT); +} + +/*! \brief Sets the Memory 0 Non-Correctable Error Event + * + * This function sets the Memory 0 Non-Correctable Error Event. + * Write 1 to clear this field. This write also clears the corresponding interrupt notification, + * if CR0[ENCIE0] is enabled. + * + * \param[in] obj : pointer to ERM register instance + * \param[in] value : the value of Memory 0 Non-Correctable Error Event + * - 0b : No non-correctable error event on Memory 0 detected. + * - 1b : Non-correctable error event on Memory 0 detected. + */ +__attribute__((always_inline)) static inline void ErmReg_SetSrNce0(ErmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << ERM_SR_NCE0_SHIFT)) & ERM_SR_NCE0_MASK); + obj->SR = tmp; +} + +/*! \brief Gets the Memory 0 Single-Bit Correction Event + * + * This function gets the current Memory 0 Single-Bit Correction Event. + * Write 1 to clear this field. This write also clears the corresponding interrupt notification, + * if CR0[ESCIE0] is enabled. + * + * \param[in] obj : pointer to ERM register instance + * \return Memory 0 Single-Bit Correction Event + * - 0b : No single-bit correction event on Memory 0 detected. + * - 1b : Single-bit correction event on Memory 0 detected. + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetSrSbc0(const ErmRegType *obj) +{ + return ((obj->SR & ERM_SR_SBC0_MASK) >> ERM_SR_SBC0_SHIFT); +} + +/*! \brief Sets the Memory 0 Single-Bit Correction Event + * + * This function sets the Memory 0 Single-Bit Correction Event. + * Write 1 to clear this field. This write also clears the corresponding interrupt notification, + * if CR0[ESCIE0] is enabled. + * + * \param[in] obj : pointer to ERM register instance + * \param[in] value : the value of Memory 0 Single-Bit Correction Event + * - 0b : No single-bit correction event on Memory 0 detected. + * - 1b : Single-bit correction event on Memory 0 detected. + */ +__attribute__((always_inline)) static inline void ErmReg_SetSrSbc0(ErmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << ERM_SR_SBC0_SHIFT)) & ERM_SR_SBC0_MASK); + obj->SR = tmp; +} + +/*! \brief Gets the Memory 0 Error Address + * + * This function gets the current Memory 0 Error Address. + * This field contains the faulting system address of the last recorded ECC event on Memory 0 + * + * \param[in] obj : pointer to ERM register instance + * \return Memory 0 Error Address + */ +__attribute__((always_inline)) static inline uint32_t ErmReg_GetCh0St0Adr0(const ErmRegType *obj) +{ + return ((obj->CH0_ST0 & ERM_CH0_ST0_ADR0_MASK) >> ERM_CH0_ST0_ADR0_SHIFT); +} + +/*! \brief Gets the Memory n Syndrome + * + * This function gets the current Memory n Syndrome. + * This field contains the ECC syndrome associated with the last recorded ECC event on Memory n + * + * \param[in] obj : pointer to ERM register instance + * \return Memory n Syndrome + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetCh0St1Syn0(const ErmRegType *obj) +{ + return ((obj->CH0_ST1 & ERM_CH0_ST1_SYN0_MASK) >> ERM_CH0_ST1_SYN0_SHIFT); +} + +/*! \brief Gets the Memory n Correctable Error Count + * + * This function gets the current Memory n Correctable Error Count. + * For each correctable error event, the ERM increments this field's error count value + * until the counter reaches its maximum value FFh. + * COUNT field description can be updated as required. + * COUNT value will stop once it reaches maximum value FFh and will not wrap even if error occurs. + * Read this field to determine the correctable error count value so far. + * Write all zeros to this field to reset the counter. Writing non-zero (or partial zero) values has no effect + * + * \param[in] obj : pointer to ERM register instance + * \return Memory n Correctable Error Count + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetCh0St2CorrCnt0(const ErmRegType *obj) +{ + return ((obj->CH0_ST2 & ERM_CH0_ST2_CORR_CNT0_MASK) >> ERM_CH0_ST2_CORR_CNT0_SHIFT); +} + +/*! \brief Sets the Memory n Correctable Error Count + * + * This function sets the Memory n Correctable Error Count. + * For each correctable error event, the ERM increments this field's error count value + * until the counter reaches its maximum value FFh. + * COUNT field description can be updated as required. + * COUNT value will stop once it reaches maximum value FFh and will not wrap even if error occurs. + * Read this field to determine the correctable error count value so far. + * Write all zeros to this field to reset the counter. Writing non-zero (or partial zero) values has no effect + * + * \param[in] obj : pointer to ERM register instance + * \param[in] value : the value of Memory n Correctable Error Count + */ +__attribute__((always_inline)) static inline void ErmReg_SetCh0St2CorrCnt0(ErmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CH0_ST2; + + tmp &= ~ERM_CH0_ST2_CORR_CNT0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << ERM_CH0_ST2_CORR_CNT0_SHIFT)) & ERM_CH0_ST2_CORR_CNT0_MASK); + obj->CH0_ST2 = tmp; +} + +/*! \brief Gets the Memory 1 Error Address + * + * This function gets the current Memory 1 Error Address. + * This field contains the faulting system address of the last recorded ECC event on Memory 1 + * + * \param[in] obj : pointer to ERM register instance + * \return Memory 1 Error Address + */ +__attribute__((always_inline)) static inline uint32_t ErmReg_GetCh1St0Adr1(const ErmRegType *obj) +{ + return ((obj->CH1_ST0 & ERM_CH1_ST0_ADR1_MASK) >> ERM_CH1_ST0_ADR1_SHIFT); +} + +/*! \brief Gets the Memory n Syndrome + * + * This function gets the current Memory n Syndrome. + * This field contains the ECC syndrome associated with the last recorded ECC event on Memory 1 + * + * \param[in] obj : pointer to ERM register instance + * \return Memory n Syndrome + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetCh1St1Syn1(const ErmRegType *obj) +{ + return ((obj->CH1_ST1 & ERM_CH1_ST1_SYN1_MASK) >> ERM_CH1_ST1_SYN1_SHIFT); +} + +/*! \brief Gets the Memory n Correctable Error Count + * + * This function gets the current Memory n Correctable Error Count. + * For each correctable error event, the ERM increments this field's error count value + * until the counter reaches its maximum value FFh. + * COUNT value will stop once it reaches maximum value FFh and will not wrap even if error occurs. + * Read this field to determine the correctable error count value so far. + * Write all zeros to this field to reset the counter. + * Writing non-zero (or partial zero) values has no effect + * + * \param[in] obj : pointer to ERM register instance + * \return Memory n Correctable Error Count + */ +__attribute__((always_inline)) static inline uint8_t ErmReg_GetCh1St2CorrCnt1(const ErmRegType *obj) +{ + return ((obj->CH1_ST2 & ERM_CH1_ST2_CORR_CNT1_MASK) >> ERM_CH1_ST2_CORR_CNT1_SHIFT); +} + +/*! \brief Sets the Memory n Correctable Error Count + * + * This function sets the Memory n Correctable Error Count. + * For each correctable error event, the ERM increments this field's error count value + * until the counter reaches its maximum value FFh. + * COUNT value will stop once it reaches maximum value FFh and will not wrap even if error occurs. + * Read this field to determine the correctable error count value so far. + * Write all zeros to this field to reset the counter. + * Writing non-zero (or partial zero) values has no effect + * + * \param[in] obj : pointer to ERM register instance + */ +__attribute__((always_inline)) static inline void ErmReg_SetCh1St2CorrCnt1(ErmRegType *obj) +{ + obj->CH1_ST2 = 0; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _ERM_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/fhu_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/fhu_reg.h new file mode 100644 index 0000000..047fd46 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/fhu_reg.h @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FHU_REG_H_ +#define _FHU_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the FHU Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* USER_KEY Bit Fields */ +#define FHU_USER_KEY_USER_KEY_MASK (0xFFFFFFFFu) +#define FHU_USER_KEY_USER_KEY_SHIFT (0u) +#define FHU_USER_KEY_USER_KEY_WIDTH (32u) + +/* USER_LOCK Bit Fields */ +#define FHU_USER_LOCK_USER_LOCK_MASK (0x01u) +#define FHU_USER_LOCK_USER_LOCK_SHIFT (0u) +#define FHU_USER_LOCK_USER_LOCK_WIDTH (1u) + +/* CHCTL Bit Fields */ +#define FHU_CHCTL_CHEN_CTL_MASK (0x1FFu) +#define FHU_CHCTL_CHEN_CTL_SHIFT (0u) +#define FHU_CHCTL_CHEN_CTL_WIDTH (9u) + +/* RSTCTL Bit Fields */ +#define FHU_RSTCTL_RST_CTL_MASK (0x1FFu) +#define FHU_RSTCTL_RST_CTL_SHIFT (0u) +#define FHU_RSTCTL_RST_CTL_WIDTH (9u) + +/* INTCTL Bit Fields */ +#define FHU_INTCTL_INT_CTL_MASK (0x1FFu) +#define FHU_INTCTL_INT_CTL_SHIFT (0u) +#define FHU_INTCTL_INT_CTL_WIDTH (9u) + +/* NMICTL Bit Fields */ +#define FHU_NMICTL_NMI_CTL_MASK (0x1FFu) +#define FHU_NMICTL_NMI_CTL_SHIFT (0u) +#define FHU_NMICTL_NMI_CTL_WIDTH (9u) + +/* CHNRCD Bit Fields */ +#define FHU_CHNRCD_CHN_RCD_MASK (0x3FFu) +#define FHU_CHNRCD_CHN_RCD_SHIFT (0u) +#define FHU_CHNRCD_CHN_RCD_WIDTH (10u) + +/* ADRCD Bit Fields */ +#define FHU_ADRCD_CHN_ADRCD_MASK (0x1Fu) +#define FHU_ADRCD_CHN_ADRCD_SHIFT (0u) +#define FHU_ADRCD_CHN_ADRCD_WIDTH (5u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of FHU registers + */ +typedef struct _FhuRegType_ +{ + volatile uint32_t USER_KEY; /*!< secure key register, offset: 0x00 */ + const volatile uint32_t USER_LOCK; /*!< register lock, offset: 0x04 */ + volatile uint32_t CHCTL; /*!< channel enable control register, offset: 0x08 */ + volatile uint32_t RSTCTL; /*!< channel reset control register, offset: 0x0C */ + volatile uint32_t INTCTL; /*!< channel interrupt control register, offset: 0x10 */ + volatile uint32_t NMICTL; /*!< channel NMI control register, offset: 0x14 */ + volatile uint32_t CHNRCD; /*!< fault channel record register, offset: 0x18 */ + const volatile uint32_t ADRCD; /*!< AD fault channel record register, offset: 0x1C */ +} FhuRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Sets the configure secure key + * + * This function sets the configure secure key. + * + * \param[in] obj : pointer to FHU register instance + * \param[in] value : the value of configure secure key + * - 0x97D356BA : key match + * - others : key mismatch + */ +__attribute__((always_inline)) static inline void FhuReg_SetUserKey(FhuRegType *obj, uint32_t value) +{ + uint32_t tmp = obj->USER_KEY; + + tmp &= ~FHU_USER_KEY_USER_KEY_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FHU_USER_KEY_USER_KEY_SHIFT)) & FHU_USER_KEY_USER_KEY_MASK); + obj->USER_KEY = tmp; +} + +/*! \brief Gets the configure register lock flag + * + * This function gets the current configure register lock flag. + * register lock flag; + * + * \param[in] obj : pointer to FHU register instance + * \return configure register lock flag + * - 0b : unlock + * - 1b : lock + */ +__attribute__((always_inline)) static inline uint8_t FhuReg_GetUserLock(const FhuRegType *obj) +{ + return ((obj->USER_LOCK & FHU_USER_LOCK_USER_LOCK_MASK) >> FHU_USER_LOCK_USER_LOCK_SHIFT); +} + +/*! \brief Gets the configure fault channel enable + * + * This function gets the current configure fault channel enable. + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * [5]:SRAM_SEC; + * [6]:SRAM_DED; + * [7]:FLS_DEC; + * [8]:FLS_DED; + * For each bit: + * - 0b: disable + * - 1b: enabl + * + * \param[in] obj : pointer to FHU register instance + * \return configure fault channel enable + */ +__attribute__((always_inline)) static inline uint16_t FhuReg_GetChCtl(const FhuRegType *obj) +{ + return ((obj->CHCTL & FHU_CHCTL_CHEN_CTL_MASK) >> FHU_CHCTL_CHEN_CTL_SHIFT); +} + +/*! \brief Sets the configure fault channel enable + * + * This function sets the configure fault channel enable. + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * [5]:SRAM_SEC; + * [6]:SRAM_DED; + * [7]:FLS_DEC; + * [8]:FLS_DED; + * For each bit: + * - 0b: disable + * - 1b: enabl + * + * \param[in] obj : pointer to FHU register instance + * \param[in] value : the value of configure fault channel enable + */ +__attribute__((always_inline)) static inline void FhuReg_SetChCtl(FhuRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->CHCTL; + + tmp &= ~FHU_CHCTL_CHEN_CTL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FHU_CHCTL_CHEN_CTL_SHIFT)) & FHU_CHCTL_CHEN_CTL_MASK); + obj->CHCTL = tmp; +} + +/*! \brief Gets the configure fault channel reset enable + * + * This function gets the current configure fault channel reset enable. + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * [5]:SRAM_SEC; + * [6]:SRAM_DED; + * [7]:FLS_DEC; + * [8]:FLS_DED; + * For each bit: + * - 0b: disable system reset generation + * - 1b: enable system reset generatio + * + * \param[in] obj : pointer to FHU register instance + * \return configure fault channel reset enable + */ +__attribute__((always_inline)) static inline uint16_t FhuReg_GetRstCtl(const FhuRegType *obj) +{ + return ((obj->RSTCTL & FHU_RSTCTL_RST_CTL_MASK) >> FHU_RSTCTL_RST_CTL_SHIFT); +} + +/*! \brief Sets the configure fault channel reset enable + * + * This function sets the configure fault channel reset enable. + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * [5]:SRAM_SEC; + * [6]:SRAM_DED; + * [7]:FLS_DEC; + * [8]:FLS_DED; + * For each bit: + * - 0b: disable system reset generation + * - 1b: enable system reset generatio + * + * \param[in] obj : pointer to FHU register instance + * \param[in] value : the value of configure fault channel reset enable + */ +__attribute__((always_inline)) static inline void FhuReg_SetRstCtl(FhuRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->RSTCTL; + + tmp &= ~FHU_RSTCTL_RST_CTL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FHU_RSTCTL_RST_CTL_SHIFT)) & FHU_RSTCTL_RST_CTL_MASK); + obj->RSTCTL = tmp; +} + +/*! \brief Gets the configure fault channel interrupt enable + * + * This function gets the current configure fault channel interrupt enable. + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * [5]:SRAM_SEC; + * [6]:SRAM_DED; + * [7]:FLS_DEC; + * [8]:FLS_DED; + * For each bit: + * -0b: disable interrupt generation + * -1b: enable interrupt generatio + * + * \param[in] obj : pointer to FHU register instance + * \return configure fault channel interrupt enable + */ +__attribute__((always_inline)) static inline uint16_t FhuReg_GetIntCtl(const FhuRegType *obj) +{ + return ((obj->INTCTL & FHU_INTCTL_INT_CTL_MASK) >> FHU_INTCTL_INT_CTL_SHIFT); +} + +/*! \brief Sets the configure fault channel interrupt enable + * + * This function sets the configure fault channel interrupt enable. + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * [5]:SRAM_SEC; + * [6]:SRAM_DED; + * [7]:FLS_DEC; + * [8]:FLS_DED; + * For each bit: + * -0b: disable interrupt generation + * -1b: enable interrupt generatio + * + * \param[in] obj : pointer to FHU register instance + * \param[in] value : the value of configure fault channel interrupt enable + */ +__attribute__((always_inline)) static inline void FhuReg_SetIntCtl(FhuRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->INTCTL; + + tmp &= ~FHU_INTCTL_INT_CTL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FHU_INTCTL_INT_CTL_SHIFT)) & FHU_INTCTL_INT_CTL_MASK); + obj->INTCTL = tmp; +} + +/*! \brief Gets the configure fault channel NMI enable + * + * This function gets the current configure fault channel NMI enable. + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * [5]:SRAM_SEC; + * [6]:SRAM_DED; + * [7]:FLS_DEC; + * [8]:FLS_DED; + * For each bit: + * - 0b: disable NMI generation + * - 1b: enable NMI generatio + * + * \param[in] obj : pointer to FHU register instance + * \return configure fault channel NMI enable + */ +__attribute__((always_inline)) static inline uint16_t FhuReg_GetNmiCtl(const FhuRegType *obj) +{ + return ((obj->NMICTL & FHU_NMICTL_NMI_CTL_MASK) >> FHU_NMICTL_NMI_CTL_SHIFT); +} + +/*! \brief Sets the configure fault channel NMI enable + * + * This function sets the configure fault channel NMI enable. + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * [5]:SRAM_SEC; + * [6]:SRAM_DED; + * [7]:FLS_DEC; + * [8]:FLS_DED; + * For each bit: + * - 0b: disable NMI generation + * - 1b: enable NMI generatio + * + * \param[in] obj : pointer to FHU register instance + * \param[in] value : the value of configure fault channel NMI enable + */ +__attribute__((always_inline)) static inline void FhuReg_SetNmiCtl(FhuRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->NMICTL; + + tmp &= ~FHU_NMICTL_NMI_CTL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FHU_NMICTL_NMI_CTL_SHIFT)) & FHU_NMICTL_NMI_CTL_MASK); + obj->NMICTL = tmp; +} + +/*! \brief Gets the fault channel record + * + * This function gets the current fault channel record. + * record the fault channel number + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * [5]:SRAM_SEC; + * [6]:SRAM_DED; + * [7]:FLS_DEC; + * [8]:FLS_DED; + * [9]:CPU_RET_DED; + * For each bit: + * - 0b: not fault occurs + * - 1b: fault has occurre + * + * \param[in] obj : pointer to FHU register instance + * \return fault channel record + */ +__attribute__((always_inline)) static inline uint16_t FhuReg_GetChnRcd(const FhuRegType *obj) +{ + return ((obj->CHNRCD & FHU_CHNRCD_CHN_RCD_MASK) >> FHU_CHNRCD_CHN_RCD_SHIFT); +} + +/*! \brief Sets the fault channel record + * + * This function sets the fault channel record. + * record the fault channel number + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * [5]:SRAM_SEC; + * [6]:SRAM_DED; + * [7]:FLS_DEC; + * [8]:FLS_DED; + * [9]:CPU_RET_DED; + * For each bit: + * - 0b: not fault occurs + * - 1b: fault has occurre + * + * \note Write 1 to clear for each bit. + * + * \param[in] obj : pointer to FHU register instance + * \param[in] value : the value of fault channel record + */ +__attribute__((always_inline)) static inline void FhuReg_SetChnRcd(FhuRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->CHNRCD; + + tmp &= ~FHU_CHNRCD_CHN_RCD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FHU_CHNRCD_CHN_RCD_SHIFT)) & FHU_CHNRCD_CHN_RCD_MASK); + obj->CHNRCD = tmp; +} + +/*! \brief Gets the AD fault channel record + * + * This function gets the current AD fault channel record. + * record the fault channel number + * Corresponing bit: + * [0]:AD_LVD; + * [1]:AD_LVW; + * [2]:AD_FLDO_RDY; + * [3]:AD_FLDO_LVD; + * [4]:AD_OTP; + * For each bit: + * - 0b: not fault occurs + * - 1b: fault has occurre + * + * \param[in] obj : pointer to FHU register instance + * \return AD fault channel record + */ +__attribute__((always_inline)) static inline uint8_t FhuReg_GetAdRcd(const FhuRegType *obj) +{ + return ((obj->ADRCD & FHU_ADRCD_CHN_ADRCD_MASK) >> FHU_ADRCD_CHN_ADRCD_SHIFT); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _FHU_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/flexcan_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/flexcan_reg.h new file mode 100644 index 0000000..e83db67 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/flexcan_reg.h @@ -0,0 +1,3426 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FLEXCAN_REG_H_ +#define _FLEXCAN_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the FLEXCAN Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +#define MESSAGE_BUFFER_ADDR_OFF (0x80UL) + +#define MESSAGE_BUFFER_CS_WORD_NUM (0) +#define MESSAGE_BUFFER_ID_WORD_NUM (1) + +/* message buffer CS field */ +#define MESSAGE_BUFFER_CS_EDL_SHIFT (31U) +#define MESSAGE_BUFFER_CS_EDL_MASK (0x1UL << MESSAGE_BUFFER_CS_EDL_SHIFT) +#define MESSAGE_BUFFER_CS_BRS_SHIFT (30U) +#define MESSAGE_BUFFER_CS_BRS_MASK (0x1UL << MESSAGE_BUFFER_CS_BRS_SHIFT) +#define MESSAGE_BUFFER_CS_CODE_SHIFT (24U) +#define MESSAGE_BUFFER_CS_CODE_MASK (0xFUL << MESSAGE_BUFFER_CS_CODE_SHIFT) +#define MESSAGE_BUFFER_CS_SRR_SHIFT (22U) +#define MESSAGE_BUFFER_CS_SRR_MASK (0x1UL << MESSAGE_BUFFER_CS_SRR_SHIFT) +#define MESSAGE_BUFFER_CS_IDE_SHIFT (21U) +#define MESSAGE_BUFFER_CS_IDE_MASK (0x1UL << MESSAGE_BUFFER_CS_IDE_SHIFT) +#define MESSAGE_BUFFER_CS_DLC_SHIFT (16U) +#define MESSAGE_BUFFER_CS_DLC_MASK (0xFUL << MESSAGE_BUFFER_CS_DLC_SHIFT) + +/* message buffer ID field */ +#define MESSAGE_BUFFER_ID_EXT_ID_SHIFT (0U) +#define MESSAGE_BUFFER_ID_EXT_ID_MASK (0x1FFFFFFFUL << MESSAGE_BUFFER_ID_EXT_ID_SHIFT) +#define MESSAGE_BUFFER_ID_STD_ID_SHIFT (18U) +#define MESSAGE_BUFFER_ID_STD_ID_MASK (0x7FFUL << MESSAGE_BUFFER_ID_STD_ID_SHIFT) + +/* MCR register */ +#define FLEXCAN_MCR_MDIS_SHIFT (31U) +#define FLEXCAN_MCR_MDIS_MASK (0x1UL << FLEXCAN_MCR_MDIS_SHIFT) +#define FLEXCAN_MCR_MDIS_WIDTH (1u) +#define FLEXCAN_MCR_FRZ_SHIFT (30U) +#define FLEXCAN_MCR_FRZ_MASK (0x1UL << FLEXCAN_MCR_FRZ_SHIFT) +#define FLEXCAN_MCR_FRZ_WIDTH (1u) +#define FLEXCAN_MCR_RFEN_SHIFT (29U) +#define FLEXCAN_MCR_RFEN_MASK (0x1UL << FLEXCAN_MCR_RFEN_SHIFT) +#define FLEXCAN_MCR_RFEN_WIDTH (1u) +#define FLEXCAN_MCR_HALT_SHIFT (28U) +#define FLEXCAN_MCR_HALT_MASK (0x1UL << FLEXCAN_MCR_HALT_SHIFT) +#define FLEXCAN_MCR_HALT_WIDTH (1u) +#define FLEXCAN_MCR_NOTRDY_SHIFT (27U) +#define FLEXCAN_MCR_NOTRDY_MASK (0x1UL << FLEXCAN_MCR_NOTRDY_SHIFT) +#define FLEXCAN_MCR_WAKMSK_SHIFT (26U) +#define FLEXCAN_MCR_WAKMSK_MASK (0x1UL << FLEXCAN_MCR_WAKMSK_SHIFT) +#define FLEXCAN_MCR_SOFTRST_SHIFT (25U) +#define FLEXCAN_MCR_SOFTRST_MASK (0x1UL << FLEXCAN_MCR_SOFTRST_SHIFT) +#define FLEXCAN_MCR_SOFTRST_WIDTH (1u) +#define FLEXCAN_MCR_FRZACK_SHIFT (24U) +#define FLEXCAN_MCR_FRZACK_MASK (0x1UL << FLEXCAN_MCR_FRZACK_SHIFT) +#define FLEXCAN_MCR_FRZACK_WIDTH (1u) +#define FLEXCAN_MCR_SUPV_SHIFT (23U) +#define FLEXCAN_MCR_SUPV_MASK (0x1UL << FLEXCAN_MCR_SUPV_SHIFT) +#define FLEXCAN_MCR_SUPV_WIDTH (1u) +#define FLEXCAN_MCR_SLFWAK_SHIFT (22U) +#define FLEXCAN_MCR_SLFWAK_MASK (0x1UL << FLEXCAN_MCR_SLFWAK_SHIFT) +#define FLEXCAN_MCR_SLFWAK_WIDTH (1u) +#define FLEXCAN_MCR_WRNEN_SHIFT (21U) +#define FLEXCAN_MCR_WRNEN_MASK (0x1UL << FLEXCAN_MCR_WRNEN_SHIFT) +#define FLEXCAN_MCR_WRNEN_WIDTH (1u) +#define FLEXCAN_MCR_LPMACK_SHIFT (20U) +#define FLEXCAN_MCR_LPMACK_MASK (0x1UL << FLEXCAN_MCR_LPMACK_SHIFT) +#define FLEXCAN_MCR_LPMACK_WIDTH (1u) +#define FLEXCAN_MCR_WAKSRC_SHIFT (19U) +#define FLEXCAN_MCR_WAKSRC_MASK (0x1UL << FLEXCAN_MCR_WAKSRC_SHIFT) +#define FLEXCAN_MCR_WAKSRC_WIDTH (1u) +#define FLEXCAN_MCR_DOZE_SHIFT (18U) +#define FLEXCAN_MCR_DOZE_MASK (0x1UL << FLEXCAN_MCR_DOZE_SHIFT) +#define FLEXCAN_MCR_DOZE_WIDTH (1u) +#define FLEXCAN_MCR_SRXDIS_SHIFT (17U) +#define FLEXCAN_MCR_SRXDIS_MASK (0x1UL << FLEXCAN_MCR_SRXDIS_SHIFT) +#define FLEXCAN_MCR_SRXDIS_WIDTH (1u) +#define FLEXCAN_MCR_IRQM_SHIFT (16U) +#define FLEXCAN_MCR_IRQM_MASK (0x1UL << FLEXCAN_MCR_IRQM_SHIFT) +#define FLEXCAN_MCR_IRMQ_WIDTH (1u) +#define FLEXCAN_MCR_DMA_SHIFT (15U) +#define FLEXCAN_MCR_DMA_MASK (0x1UL << FLEXCAN_MCR_DMA_SHIFT) +#define FLEXCAN_MCR_DMA_WIDTH (1u) +#define FLEXCAN_MCR_LPRIOEN_MASK (0x2000u) +#define FLEXCAN_MCR_LPRIOEN_SHIFT (13u) +#define FLEXCAN_MCR_LPRIOEN_WIDTH (1u) +#define FLEXCAN_MCR_AEN_SHIFT (12U) +#define FLEXCAN_MCR_AEN_MASK (0x1UL << FLEXCAN_MCR_AEN_SHIFT) +#define FELXCAN_MCR_AEN_WIDTH (1U) +#define FLEXCAN_MCR_FDEN_SHIFT (11U) +#define FLEXCAN_MCR_FDEN_MASK (0x1UL << FLEXCAN_MCR_FDEN_SHIFT) +#define FLEXCAN_MCR_FDEN_WIDTH (1u) +#define FLEXCAN_MCR_IDAM_SHIFT (8UL) +#define FLEXCAN_MCR_IDAM_MASK (0x3UL << FLEXCAN_MCR_IDAM_SHIFT) +#define FLEXCAN_MCR_IDAM_WIDTH (2U) +#define FLEXCAN_MCR_MAXMB_SHIFT (0U) +#define FLEXCAN_MCR_MAXMB_MASK (0x7FUL << FLEXCAN_MCR_MAXMB_SHIFT) +#define FLEXCAN_MCR_MAXMB_WIDTH (7u) + +/* CTRL1 register */ +#define FLEXCAN_CTRL1_PRESDIV_MASK (0xFF000000u) +#define FLEXCAN_CTRL1_PRESDIV_SHIFT (24u) +#define FLEXCAN_CTRL1_PRESDIV_WIDTH (8u) +#define FLEXCAN_CTRL1_RJW_MASK (0xC00000u) +#define FLEXCAN_CTRL1_RJW_SHIFT (22u) +#define FLEXCAN_CTRL1_RJW_WIDTH (2u) +#define FLEXCAN_CTRL1_PSEG1_MASK (0x380000u) +#define FLEXCAN_CTRL1_PSEG1_SHIFT (19u) +#define FLEXCAN_CTRL1_PSEG1_WIDTH (3u) +#define FLEXCAN_CTRL1_PSEG2_MASK (0x70000u) +#define FLEXCAN_CTRL1_PSEG2_SHIFT (16u) +#define FLEXCAN_CTRL1_PSEG2_WIDTH (3u) +#define FLEXCAN_CTRL1_BOFFMSK_SHIFT (15U) +#define FLEXCAN_CTRL1_BOFFMSK_MASK (0x1UL << FLEXCAN_CTRL1_BOFFMSK_SHIFT) +#define FLEXCAN_CTRL1_BOFFMSK_WIDTH (1U) +#define FLEXCAN_CTRL1_ERRMSK_SHIFT (14U) +#define FLEXCAN_CTRL1_ERRMSK_MASK (0x1UL << FLEXCAN_CTRL1_ERRMSK_SHIFT) +#define FLEXCAN_CTRL1_ERRMSK_WIDTH (1UL) +#define FLEXCAN_CTRL1_CLKSRC_SHIFT (13U) +#define FLEXCAN_CTRL1_CLKSRC_MASK (0x1UL << FLEXCAN_CTRL1_CLKSRC_SHIFT) +#define FLEXCAN_CTRL1_CLKSRC_WIDTH (1u) +#define FLEXCAN_CTRL1_LPB_SHIFT (12U) +#define FLEXCAN_CTRL1_LPB_MASK (0x1UL << FLEXCAN_CTRL1_LPB_SHIFT) +#define FLEXCAN_CTRL1_LPB_WIDTH (1u) +#define FLEXCAN_CTRL1_TWRNMSK_SHIFT (11U) +#define FLEXCAN_CTRL1_TWRNMSK_MASK (0x1UL << FLEXCAN_CTRL1_TWRNMSK_SHIFT) +#define FLEXCAN_CTRL1_TWRNMSK_WIDTH (1U) +#define FLEXCAN_CTRL1_RWRNMSK_SHIFT (10U) +#define FLEXCAN_CTRL1_RWRNMSK_MASK (1UL << FLEXCAN_CTRL1_RWRNMSK_SHIFT) +#define FLEXCAN_CTRL1_RWRNMSK_WIDTH (1U) +#define FLEXCAN_CTRL1_SMP_SHIFT (7U) +#define FLEXCAN_CTRL1_SMP_MASK (1UL << FLEXCAN_CTRL1_SMP_SHIFT) +#define FLEXCAN_CTRL1_SMP_WIDTH (1U) +#define FLEXCAN_CTRL1_BOFFREC_SHIFT (6U) +#define FLEXCAN_CTRL1_BOFFREC_MASK (1UL << FLEXCAN_CTRL1_BOFFREC_SHIFT) +#define FLEXCAN_CTRL1_BOFFREC_WIDTH (1U) +#define FLEXCAN_CTRL1_TSYN_SHIFT (5U) +#define FLEXCAN_CTRL1_TSYN_MASK (0x1UL << FLEXCAN_CTRL1_TSYN_SHIFT) +#define FLEXCAN_CTRL1_TSYN_WIDTH (1U) +#define FLEXCAN_CTRL1_LBUF_SHIFT (4U) +#define FLEXCAN_CTRL1_LBUF_MASK (0x1UL << FLEXCAN_CTRL1_LBUF_SHIFT) +#define FLEXCAN_CTRL1_LBUF_WIDTH (1U) +#define FLEXCAN_CTRL1_LOM_SHIFT (3U) +#define FLEXCAN_CTRL1_LOM_MASK (0x1UL << FLEXCAN_CTRL1_LOM_SHIFT) +#define FLEXCAN_CTRL1_LOM_WIDTH (1U) +#define FLEXCAN_CTRL1_PROPSEG_MASK (0x07u) +#define FLEXCAN_CTRL1_PROPSEG_SHIFT (0u) +#define FLEXCAN_CTRL1_PROPSEG_WIDTH (3u) + +/* TIMER register */ +#define FLEXCAN_TIMER_TIMER_MASK (0xFFFFu) +#define FLEXCAN_TIMER_TIMER_SHIFT (0u) +#define FLEXCAN_TIMER_TIMER_WIDTH (16u) + +/* RXMGMASK register */ +#define FLEXCAN_RXMGMASK_MG_MASK (0xFFFFFFFFu) +#define FLEXCAN_RXMGMASK_MG_SHIFT (0u) +#define FLEXCAN_RXMGMASK_MG_WIDTH (32u) + +/* RX14MASK register */ +#define FLEXCAN_RX14MASK_RX14M_MASK (0xFFFFFFFFu) +#define FLEXCAN_RX14MASK_RX14M_SHIFT (0u) +#define FLEXCAN_RX14MASK_RX14M_WIDTH (32u) + +/* RX15MASK register */ +#define FLEXCAN_RX15MASK_RX15M_MASK (0xFFFFFFFFu) +#define FLEXCAN_RX15MASK_RX15M_SHIFT (0u) +#define FLEXCAN_RX15MASK_RX15M_WIDTH (32u) + +/* ECR register */ +#define FLEXCAN_ECR_RXERRCNTFAST_MASK (0xFF000000u) +#define FLEXCAN_ECR_RXERRCNTFAST_SHIFT (24u) +#define FLEXCAN_ECR_RXERRCNTFAST_WIDTH (8u) +#define FLEXCAN_ECR_TXERRCNTFAST_MASK (0xFF0000u) +#define FLEXCAN_ECR_TXERRCNTFAST_SHIFT (16u) +#define FLEXCAN_ECR_TXERRCNTFAST_WIDTH (8u) +#define FLEXCAN_ECR_RXERRCNT_MASK (0xFF00u) +#define FLEXCAN_ECR_RXERRCNT_SHIFT (8u) +#define FLEXCAN_ECR_RXERRCNT_WIDTH (8u) +#define FLEXCAN_ECR_TXERRCNT_MASK (0xFFu) +#define FLEXCAN_ECR_TXERRCNT_SHIFT (0u) +#define FLEXCAN_ECR_TXERRCNT_WIDTH (8u) + +/* ESR1 register */ +#define FLEXCAN_ESR1_BIT1ERR_FAST_SHIFT (31U) +#define FLEXCAN_ESR1_BIT1ERR_FAST_MASK (1UL << FLEXCAN_ESR1_BIT1ERR_FAST_SHIFT) +#define FLEXCAN_ESR1_BIT1ERR_FAST_WIDTH (1U) +#define FLEXCAN_ESR1_BIT0ERR_FAST_SHIFT (30U) +#define FLEXCAN_ESR1_BIT0ERR_FAST_MASK (1UL << FLEXCAN_ESR1_BIT0ERR_FAST_SHIFT) +#define FLEXCAN_ESR1_BIT0ERR_FAST_WIDTH (1U) +#define FLEXCAN_ESR1_CRCERR_FAST_SHIFT (28U) +#define FLEXCAN_ESR1_CRCERR_FAST_MASK (1UL << FLEXCAN_ESR1_CRCERR_FAST_SHIFT) +#define FLEXCAN_ESR1_CRCERR_FAST_WIDTH (1U) +#define FLEXCAN_ESR1_FRMERR_FAST_SHIFT (27U) +#define FLEXCAN_ESR1_FRMERR_FAST_MASK (1UL << FLEXCAN_ESR1_FRMERR_FAST_SHIFT) +#define FLEXCAN_ESR1_FRMERR_FAST_WIDTH (1U) +#define FLEXCAN_ESR1_STFERR_FAST_SHIFT (26U) +#define FLEXCAN_ESR1_STFERR_FAST_MASK (1UL << FLEXCAN_ESR1_STFERR_FAST_SHIFT) +#define FLEXCAN_ESR1_STFERR_FAST_WIDTH (1U) +#define FLEXCAN_ESR1_ERROVR_SHIFT (21U) +#define FLEXCAN_ESR1_ERROVR_MASK (1UL << FLEXCAN_ESR1_ERROVR_SHIFT) +#define FLEXCAN_ESR1_ERROVR_WIDTH (1U) +#define FLEXCAN_ESR1_ERRINT_FAST_SHIFT (20U) +#define FLEXCAN_ESR1_ERRINT_FAST_MASK (1UL << FLEXCAN_ESR1_ERRINT_FAST_SHIFT) +#define FLEXCAN_ESR1_ERRINT_FAST_WIDTH (1U) +#define FLEXCAN_ESR1_BOFFDONEINT_SHIFT (19U) +#define FLEXCAN_ESR1_BOFFDONEINT_MASK (1UL << FLEXCAN_ESR1_BOFFDONEINT_SHIFT) +#define FLEXCAN_ESR1_BOFFDONEINT_WIDTH (1U) +#define FLEXCAN_ESR1_SYNCH_SHIFT (18U) +#define FLEXCAN_ESR1_SYNCH_MASK (1UL << FLEXCAN_ESR1_SYNCH_SHIFT) +#define FLEXCAN_ESR1_SYNCH_WIDTH (1U) +#define FLEXCAN_ESR1_TWRNINT_SHIFT (17U) +#define FLEXCAN_ESR1_TWRNINT_MASK (1UL << FLEXCAN_ESR1_TWRNINT_SHIFT) +#define FLEXCAN_ESR1_TWRNINT_WIDTH (1U) +#define FLEXCAN_ESR1_RWRNINT_SHIFT (16U) +#define FLEXCAN_ESR1_RWRNINT_MASK (1UL << FLEXCAN_ESR1_RWRNINT_SHIFT) +#define FLEXCAN_ESR1_RWRNINT_WIDTH (1U) +#define FLEXCAN_ESR1_BIT1ERR_SHIFT (15U) +#define FLEXCAN_ESR1_BIT1ERR_MASK (1UL << FLEXCAN_ESR1_BIT1ERR_SHIFT) +#define FLEXCAN_ESR1_BIT1ERR_WIDTH (1U) +#define FLEXCAN_ESR1_BIT0ERR_SHIFT (14U) +#define FLEXCAN_ESR1_BIT0ERR_MASK (1UL << FLEXCAN_ESR1_BIT0ERR_SHIFT) +#define FLEXCAN_ESR1_BIT0ERR_WIDTH (1U) +#define FLEXCAN_ESR1_ACKERR_SHIFT (13U) +#define FLEXCAN_ESR1_ACKERR_MASK (1UL << FLEXCAN_ESR1_ACKERR_SHIFT) +#define FLEXCAN_ESR1_ACKERR_WIDTH (1U) +#define FLEXCAN_ESR1_CRCERR_SHIFT (12U) +#define FLEXCAN_ESR1_CRCERR_MASK (1UL << FLEXCAN_ESR1_CRCERR_SHIFT) +#define FLEXCAN_ESR1_CRCERR_WIDTH (1U) +#define FLEXCAN_ESR1_FRMERR_SHIFT (11U) +#define FLEXCAN_ESR1_FRMERR_MASK (1UL << FLEXCAN_ESR1_FRMERR_SHIFT) +#define FLEXCAN_ESR1_FRMERR_WIDTH (1U) +#define FLEXCAN_ESR1_STFERR_SHIFT (10U) +#define FLEXCAN_ESR1_STFERR_MASK (1UL << FLEXCAN_ESR1_STFERR_SHIFT) +#define FLEXCAN_ESR1_STFERR_WIDTH (1U) +#define FLEXCAN_ESR1_TXWRN_SHIFT (9U) +#define FLEXCAN_ESR1_TXWRN_MASK (0x1UL << FLEXCAN_ESR1_TXWRN_SHIFT) +#define FLEXCAN_ESR1_TXWRN_WIDTH (1U) +#define FLEXCAN_ESR1_RXWRN_SHIFT (8U) +#define FLEXCAN_ESR1_RXWRN_MASK (0x1UL << FLEXCAN_ESR1_RXWRN_SHIFT) +#define FLEXCAN_ESR1_RXWRN_WIDTH (1U) +#define FLEXCAN_ESR1_IDLE_SHIFT (7U) +#define FLEXCAN_ESR1_IDLE_MASK (1UL << FLEXCAN_ESR1_IDLE_SHIFT) +#define FLEXCAN_ESR1_IDLE_WIDTH (1U) +#define FLEXCAN_ESR1_TX_SHIFT (6U) +#define FLEXCAN_ESR1_TX_MASK (1UL << FLEXCAN_ESR1_TX_SHIFT) +#define FLEXCAN_ESR1_TX_WIDTH (1U) +#define FLEXCAN_ESR1_FLTCONF_SHIFT (4U) +#define FLEXCAN_ESR1_FLTCONF_MASK (3UL << FLEXCAN_ESR1_FLTCONF_SHIFT) +#define FLEXCAN_ESR1_FLTCONF_WIDTH (2U) +#define FLEXCAN_ESR1_RX_SHIFT (3U) +#define FLEXCAN_ESR1_RX_MASK (1UL << FLEXCAN_ESR1_RX_SHIFT) +#define FLEXCAN_ESR1_RX_WIDTH (1U) +#define FLEXCAN_ESR1_BOFFINT_SHIFT (2U) +#define FLEXCAN_ESR1_BOFFINT_MASK (0x1UL << FLEXCAN_ESR1_BOFFINT_SHIFT) +#define FLEXCAN_ESR1_BOFFINT_WIDTH (1U) +#define FLEXCAN_ESR1_ERRINT_SHIFT (1U) +#define FLEXCAN_ESR1_ERRINT_MASK (0x1UL << FLEXCAN_ESR1_ERRINT_SHIFT) +#define FLEXCAN_ESR1_ERRINT_WIDTH (1U) +#define FLEXCAN_ESR1_WAKINT_SHIFT (0U) +#define FLEXCAN_ESR1_WAKINT_MASK (0x1UL << FLEXCAN_ESR1_WAKINT_SHIFT) +#define FLEXCAN_ESR1_WAKINT_WIDTH (1U) + +/* CTRL2 register */ +#define FLEXCAN_CTRL2_ERRMSKFAST_MASK (0x80000000u) +#define FLEXCAN_CTRL2_ERRMSKFAST_SHIFT (31u) +#define FLEXCAN_CTRL2_ERRMSKFAST_WIDTH (1u) +#define FLEXCAN_CTRL2_BOFFDONEMSK_MASK (0x40000000u) +#define FLEXCAN_CTRL2_BOFFDONEMSK_SHIFT (30u) +#define FLEXCAN_CTRL2_BOFFDONEMSK_WIDTH (1u) +#define FLEXCAN_CTRL2_ECRWRE_SHIFT (29U) +#define FLEXCAN_CTRL2_ECRWRE_MASK (0x1UL << FLEXCAN_CTRL2_ECRWRE_SHIFT) +#define FLEXCAN_CTRL2_ECRWRE_WIDTH (1u) +#define FLEXCAN_CTRL2_WRMFRZ_SHIFT (28U) +#define FLEXCAN_CTRL2_WRMFRZ_MASK (0x1UL << FLEXCAN_CTRL2_WRMFRZ_SHIFT) +#define FLEXCAN_CTRL2_WRMFRZ_WIDTH (1u) +#define FLEXCAN_CTRL2_RFFN_SHIFT (24U) +#define FLEXCAN_CTRL2_RFFN_MASK (0xFUL << FLEXCAN_CTRL2_RFFN_SHIFT) +#define FLEXCAN_CTRL2_RFFN_WIDTH (4U) +#define FLEXCAN_CTRL2_TASD_MASK (0xF80000u) +#define FLEXCAN_CTRL2_TASD_SHIFT (19u) +#define FLEXCAN_CTRL2_TASD_WIDTH (5u) +#define FLEXCAN_CTRL2_MRP_MASK (0x40000u) +#define FLEXCAN_CTRL2_MRP_SHIFT (18u) +#define FLEXCAN_CTRL2_MRP_WIDTH (1u) +#define FLEXCAN_CTRL2_RRS_MASK (0x20000u) +#define FLEXCAN_CTRL2_RRS_SHIFT (17u) +#define FLEXCAN_CTRL2_RRS_WIDTH (1u) +#define FLEXCAN_CTRL2_EACEN_MASK (0x10000u) +#define FLEXCAN_CTRL2_EACEN_SHIFT (16u) +#define FLEXCAN_CTRL2_EACEN_WIDTH (1u) +#define FLEXCAN_CTRL2_TIMERSRC_MASK (0x8000u) +#define FLEXCAN_CTRL2_TIMERSRC_SHIFT (15u) +#define FLEXCAN_CTRL2_TIMERSRC_WIDTH (1u) +#define FLEXCAN_CTRL2_PREXCEN_MASK (0x4000u) +#define FLEXCAN_CTRL2_PREXCEN_SHIFT (14u) +#define FLEXCAN_CTRL2_PREXCEN_WIDTH (1u) +#define FLEXCAN_CTRL2_ISOCANFDEN_SHIFT (12U) +#define FLEXCAN_CTRL2_ISOCANFDEN_MASK (0x1UL << FLEXCAN_CTRL2_ISOCANFDEN_SHIFT) +#define FLEXCAN_CTRL2_ISOCANFDEN_WIDTH (1u) +#define FLEXCAN_CTRL2_EDFLTDIS_MASK (0x800u) +#define FLEXCAN_CTRL2_EDFLTDIS_SHIFT (11u) +#define FLEXCAN_CTRL2_EDFLTDIS_WIDTH (1u) + +/* ESR2 register */ +#define FLEXCAN_ESR2_LPTM_MASK (0x7F0000u) +#define FLEXCAN_ESR2_LPTM_SHIFT (16u) +#define FLEXCAN_ESR2_LPTM_WIDTH (7u) +#define FLEXCAN_ESR2_VPS_MASK (0x4000u) +#define FLEXCAN_ESR2_VPS_SHIFT (14u) +#define FLEXCAN_ESR2_VPS_WIDTH (1u) +#define FLEXCAN_ESR2_IMB_MASK (0x2000u) +#define FLEXCAN_ESR2_IMB_SHIFT (13u) +#define FLEXCAN_ESR2_IMB_WIDTH (1u) + +/* CRCR register */ +#define FLEXCAN_CRCR_MBCRC_MASK (0x7F0000u) +#define FLEXCAN_CRCR_MBCRC_SHIFT (16u) +#define FLEXCAN_CRCR_MBCRC_WIDTH (7u) +#define FLEXCAN_CRCR_TXCRC_MASK (0x7FFFu) +#define FLEXCAN_CRCR_TXCRC_SHIFT (0u) +#define FLEXCAN_CRCR_TXCRC_WIDTH (15u) + +/* RXFGMASK register */ +#define FLEXCAN_RXFGMASK_FGM_MASK (0xFFFFFFFFu) +#define FLEXCAN_RXFGMASK_FGM_SHIFT (0u) +#define FLEXCAN_RXFGMASK_FGM_WIDTH (32u) + +/* RXFIR register */ +#define FLEXCAN_RXFIR_IDHIT_MASK (0x1FFu) +#define FLEXCAN_RXFIR_IDHIT_SHIFT (0u) +#define FLEXCAN_RXFIR_IDHIT_WIDTH (9u) + +/* CBT register */ +#define FLEXCAN_CBT_BTF_SHIFT (31U) +#define FLEXCAN_CBT_BTF_MASK (0x1UL << FLEXCAN_CBT_BTF_SHIFT) +#define FLEXCAN_CBT_BTF_WIDTH (1u) +#define FLEXCAN_CBT_EPRESDIV_SHIFT (21U) +#define FLEXCAN_CBT_EPRESDIV_MASK (0x3FFUL << FLEXCAN_CBT_EPRESDIV_SHIFT) +#define FLEXCAN_CBT_EPRESDIV_WIDTH (10u) +#define FLEXCAN_CBT_ERJW_SHIFT (16U) +#define FLEXCAN_CBT_ERJW_MASK (0x1FUL << FLEXCAN_CBT_ERJW_SHIFT) +#define FLEXCAN_CBT_ERJW_WIDTH (5u) +#define FLEXCAN_CBT_EPROPSEG_SHIFT (10U) +#define FLEXCAN_CBT_EPROPSEG_MASK (0x3FUL << FLEXCAN_CBT_EPROPSEG_SHIFT) +#define FLEXCAN_CBT_EPROPSEG_WIDTH (6u) +#define FLEXCAN_CBT_EPSEG1_SHIFT (5U) +#define FLEXCAN_CBT_EPSEG1_MASK (0x1FUL << FLEXCAN_CBT_EPSEG1_SHIFT) +#define FLEXCAN_CBT_EPSEG1_WIDTH (5u) +#define FLEXCAN_CBT_EPSEG2_SHIFT (0U) +#define FLEXCAN_CBT_EPSEG2_MASK (0x1FUL << FLEXCAN_CBT_EPSEG2_SHIFT) +#define FLEXCAN_CBT_EPSEG2_WIDTH (5u) + +/* IMASK4 register */ +#define FLEXCAN_IMASK4_BUF127TO96M_MASK (0xFFFFFFFFu) +#define FLEXCAN_IMASK4_BUF127TO96M_SHIFT (0u) +#define FLEXCAN_IMASK4_BUF127TO96M_WIDTH (32u) + +/* IMASK3 register */ +#define FLEXCAN_IMASK3_BUF95TO64M_MASK (0xFFFFFFFFu) +#define FLEXCAN_IMASK3_BUF95TO64M_SHIFT (0u) +#define FLEXCAN_IMASK3_BUF95TO64M_WIDTH (32u) + +/* IFLAG4 register */ +#define FLEXCAN_IFLAG4_BUF127TO96_MASK (0xFFFFFFFFu) +#define FLEXCAN_IFLAG4_BUF127TO96_SHIFT (0u) +#define FLEXCAN_IFLAG4_BUF127TO96_WIDTH (32u) + +/* IFLAG3 register */ +#define FLEXCAN_IFLAG3_BUF95TO64_MASK (0xFFFFFFFFu) +#define FLEXCAN_IFLAG3_BUF95TO64_SHIFT (0u) +#define FLEXCAN_IFLAG3_BUF95TO64_WIDTH (32u) + +/* RXIMRN register */ +#define FLEXCAN_RXIMRN_MI_MASK (0xFFFFFFFFu) +#define FLEXCAN_RXIMRN_MI_SHIFT (0u) +#define FLEXCAN_RXIMRN_MI_WIDTH (32u) + +/* MECR register */ +#define FLEXCAN_MECR_ECRWRDIS_SHIFT (31U) +#define FLEXCAN_MECR_ECRWRDIS_MASK (0x1UL << FLEXCAN_MECR_ECRWRDIS_SHIFT) +#define FLEXCAN_MECR_ECRWRDIS_WIDTH (1u) +#define FLEXCAN_MECR_HANCEIMSK_MASK (0x80000u) +#define FLEXCAN_MECR_HANCEIMSK_SHIFT (19u) +#define FLEXCAN_MECR_HANCEIMSK_WIDTH (1u) +#define FLEXCAN_MECR_FANCEIMSK_MASK (0x40000u) +#define FLEXCAN_MECR_FANCEIMSK_SHIFT (18u) +#define FLEXCAN_MECR_FANCEIMSK_WIDTH (1u) +#define FLEXCAN_MECR_CEIMSK_MASK (0x10000u) +#define FLEXCAN_MECR_CEIMSK_SHIFT (16u) +#define FLEXCAN_MECR_CEIMSK_WIDTH (1u) +#define FLEXCAN_MECR_HAERRIE_MASK (0x8000u) +#define FLEXCAN_MECR_HAERRIE_SHIFT (15u) +#define FLEXCAN_MECR_HAERRIE_WIDTH (1u) +#define FLEXCAN_MECR_FAERRIE_MASK (0x4000u) +#define FLEXCAN_MECR_FAERRIE_SHIFT (14u) +#define FLEXCAN_MECR_FAERRIE_WIDTH (1u) +#define FLEXCAN_MECR_EXTERRIE_MASK (0x2000u) +#define FLEXCAN_MECR_EXTERRIE_SHIFT (13u) +#define FLEXCAN_MECR_EXTERRIE_WIDTH (1u) +#define FLEXCAN_MECR_RERRDIS_MASK (0x200u) +#define FLEXCAN_MECR_RERRDIS_SHIFT (9u) +#define FLEXCAN_MECR_RERRDIS_WIDTH (1u) +#define FLEXCAN_MECR_ECCDIS_SHIFT (8U) +#define FLEXCAN_MECR_ECCDIS_MASK (0x1UL << FLEXCAN_MECR_ECCDIS_SHIFT) +#define FLEXCAN_MECR_ECCDIS_WIDTH (1u) +#define FLEXCAN_MECR_NCEFAFRZ_SHIFT (7U) +#define FLEXCAN_MECR_NCEFAFRZ_MASK (0x1UL << FLEXCAN_MECR_NCEFAFRZ_SHIFT) +#define FLEXCAN_MECR_NCEFAFRZ_WIDTH (1u) + +/* FDCTRL register */ +#define FLEXCAN_FDCTRL_FDRATE_SHIFT (31U) +#define FLEXCAN_FDCTRL_FDRATE_MASK (0x1UL << FLEXCAN_FDCTRL_FDRATE_SHIFT) +#define FLEXCAN_FDCTRL_FDRATE_WIDTH (1u) +#define FLEXCAN_FDCTRL_MBDSR3_SHIFT (25U) +#define FLEXCAN_FDCTRL_MBDSR3_MASK (0x3UL << FLEXCAN_FDCTRL_MBDSR3_SHIFT) +#define FLEXCAN_FDCTRL_MBDSR3_WIDTH (2u) +#define FLEXCAN_FDCTRL_MBDSR2_SHIFT (22U) +#define FLEXCAN_FDCTRL_MBDSR2_MASK (0x3UL << FLEXCAN_FDCTRL_MBDSR2_SHIFT) +#define FLEXCAN_FDCTRL_MBDSR2_WIDTH (2u) +#define FLEXCAN_FDCTRL_MBDSR1_SHIFT (19U) +#define FLEXCAN_FDCTRL_MBDSR1_MASK (0x3UL << FLEXCAN_FDCTRL_MBDSR1_SHIFT) +#define FLEXCAN_FDCTRL_MBDSR1_WIDTH (2u) +#define FLEXCAN_FDCTRL_MBDSR0_SHIFT (16U) +#define FLEXCAN_FDCTRL_MBDSR0_MASK (0x3UL << FLEXCAN_FDCTRL_MBDSR0_SHIFT) +#define FLEXCAN_FDCTRL_MBDSR0_WIDTH (2u) +#define FLEXCAN_FDCTRL_TDCEN_SHIFT (15U) +#define FLEXCAN_FDCTRL_TDCEN_MASK (0x1UL << FLEXCAN_FDCTRL_TDCEN_SHIFT) +#define FLEXCAN_FDCTRL_TDCEN_WIDTH (1u) +#define FLEXCAN_FDCTRL_TDCFAIL_MASK (0x4000u) +#define FLEXCAN_FDCTRL_TDCFAIL_SHIFT (14u) +#define FLEXCAN_FDCTRL_TDCFAIL_WIDTH (1u) +#define FLEXCAN_FDCTRL_TDCOFF_SHIFT (8U) +#define FLEXCAN_FDCTRL_TDCOFF_MASK (0x1FUL << FLEXCAN_FDCTRL_TDCOFF_SHIFT) +#define FLEXCAN_FDCTRL_TDCOFF_WIDTH (5u) +#define FLEXCAN_FDCTRL_TDCVAL_MASK (0x3Fu) +#define FLEXCAN_FDCTRL_TDCVAL_SHIFT (0u) +#define FLEXCAN_FDCTRL_TDCVAL_WIDTH (6u) + +/* FDCBT register */ +#define FLEXCAN_FDCBT_FPRESDIV_SHIFT (20U) +#define FLEXCAN_FDCBT_FPRESDIV_MASK (0x3FFUL << FLEXCAN_FDCBT_FPRESDIV_SHIFT) +#define FLEXCAN_FDCBT_FPRESDIV_WIDTH (10u) +#define FLEXCAN_FDCBT_FRJW_SHIFT (16U) +#define FLEXCAN_FDCBT_FRJW_MASK (0x7UL << FLEXCAN_FDCBT_FRJW_SHIFT) +#define FLEXCAN_FDCBT_FPJW_WIDTH (3u) +#define FLEXCAN_FDCBT_FPROPSEG_SHIFT (10U) +#define FLEXCAN_FDCBT_FPROPSEG_MASK (0x1FUL << FLEXCAN_FDCBT_FPROPSEG_SHIFT) +#define FLEXCAN_FDCBT_FPROPSEG_WIDTH (5u) +#define FLEXCAN_FDCBT_FPSEG1_SHIFT (5U) +#define FLEXCAN_FDCBT_FPSEG1_MASK (0x7UL << FLEXCAN_FDCBT_FPSEG1_SHIFT) +#define FLEXCAN_FDCBT_FPSEG1_WIDTH (3u) +#define FLEXCAN_FDCBT_FPSEG2_SHIFT (0U) +#define FLEXCAN_FDCBT_FPSEG2_MASK (0x7UL << FLEXCAN_FDCBT_FPSEG2_SHIFT) +#define FLEXCAN_FDCBT_FPSEG2_WIDTH (3u) + +/* FDCRC register */ +#define CAN_FDCRC_FDMBCRC_MASK (0x7F000000u) +#define CAN_FDCRC_FDMBCRC_SHIFT (24u) +#define CAN_FDCRC_FDMBCRC_WIDTH (7u) +#define CAN_FDCRC_FDTXCRC_MASK (0x1FFFFFu) +#define CAN_FDCRC_FDTXCRC_SHIFT (0u) +#define CAN_FDCRC_FDTXCRC_WIDTH (21u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of FLEXCAN registers + */ +typedef struct _FlexCanRegType_ +{ + volatile uint32_t MCR; /*!< module configuration register, offset: 0000H */ + volatile uint32_t CTRL1; /*!< control1 register, offset: 0004H */ + volatile uint32_t TIMER; /*!< free running timer register, offset: 0008H */ + volatile uint32_t REVERSED0; /*!< resverd register, offset: 000CH */ + volatile uint32_t RXMGMASK; /*!< rx mailbox global mask register, offset: 0010H */ + volatile uint32_t RX14MASK; /*!< rx 14 mask register, offset: 0014H */ + volatile uint32_t RX15MASK; /*!< rx 15 mask register, offset: 0018H */ + volatile uint32_t ECR; /*!< error countner register, offset: 001CH */ + volatile uint32_t ESR1; /*!< error and status 1 register, offset: 0020H */ + volatile uint32_t IMASK2; /*!< interrupt mask 2 register, offset: 0024H */ + volatile uint32_t IMASK1; /*!< interrupt mask 1 register, offset: 0028H */ + volatile uint32_t IFLAG2; /*!< interrupt flags 2 register, offset: 002CH */ + volatile uint32_t IFLAG1; /*!< interrupt flags 1 register, offset: 0030H */ + volatile uint32_t CTRL2; /*!< control 2 register, offset: 0034H */ + volatile uint32_t ESR2; /*!< error and status 2 register, offset: 0038H */ + volatile uint32_t REVERSED1[2]; /*!< reversed register, offset: 003CH */ + volatile uint32_t CRCR; /*!< crc register, offset: 0044H */ + volatile uint32_t RXFGMASK; /*!< rx fifo global mask register, offset: 0048H */ + volatile uint32_t RXFIR; /*!< rx fifo information register, offset: 004CH */ + volatile uint32_t CBT; /*!< CAN bit timing register, offset: 0050H */ + volatile uint32_t REVERSED2[5]; /*!< reversed register, offset: 0054H */ + volatile uint32_t IMASK4; /*!< interrupt mask 4 register, offset: 0068H */ + volatile uint32_t IMASK3; /*!< interrupt mask 3 register, offset: 006CH */ + volatile uint32_t IFLAG4; /*!< interrupt flags 4 register, offset: 0070H */ + volatile uint32_t IFLAG3; /*!< interrupt flags 3 register, offset: 0074H */ + volatile uint32_t REVERSED3[2]; /*!< reversed registers, offset: 0078H */ + volatile uint32_t MSGBUF[256]; /*!< message buffers, offset: 0080H */ + volatile uint32_t REVERSED4[256]; /*!< Reserved register, offset: 0x480 */ + volatile uint32_t RXIMR[64]; /*!< rx individual mask registers, offset: 0880H */ + volatile uint32_t REVERSED5[88]; /*!< reversed register, offset: 0980H */ + volatile uint32_t MECR; /*!< memory error control register, offset: 0AE0H */ + volatile uint32_t ERRIAR; /*!< error injection address register, offset: 0AE4H */ + volatile uint32_t ERRIDPR; /*!< error injection data pattern register, offset: 0AE8H */ + volatile uint32_t ERRIPPR; /*!< error injection parity pattern register, offset: 0AECH */ + volatile uint32_t RERRAR; /*!< error report address register, offset: 0AF0H */ + volatile uint32_t RERRDR; /*!< error report data register, offset: 0AF4H */ + volatile uint32_t RERRSYNR; /*!< error report syndrome register, offset: 0AF8H */ + volatile uint32_t ERRSR; /*!< error status register, offset: 0AFCH */ + volatile uint32_t CTRL1_PN; /*!< pretended networking control 1 register, offset: 0B00H */ + volatile uint32_t CTRL2_PN; /*!< pretended networking control 2 register, offset: 0B04H */ + volatile uint32_t WU_MTC; /*!< pretended networking wake up match register, offset: 0B08H */ + volatile uint32_t FLT_ID1; /*!< pretended networking ID filter 1 register, offset: 0B0CH */ + volatile uint32_t FLT_DLC; /*!< pretended networking DLC filter register, offset: 0B10H */ + volatile uint32_t PL1_LO; /*!< pretended networking payload low filter 1 register, offset: 0B14H */ + volatile uint32_t PL1_HI; /*!< pretended networking payload high filter 1 register, offset: 0B18H */ + volatile uint32_t FLT_ID2_IDMASK; /*!< pretended networking ID filter 2 register / ID mask register, offset: 0B1CH */ + volatile uint32_t PL2_PLMASK_LO; /*!< pretended networking payload low filter 2 register / payload low mask register, offset: 0B20H */ + volatile uint32_t PL2_PLMASK_HI; /*!< pretended networking payload high filter 2 high order bits / payload high mask register, offset: 0B24H */ + volatile uint32_t REVERSED6[6]; /*!< reversed registers, offset: 0B28H */ + volatile uint32_t WMB0_CS; /*!< wakeup message buffer 0 register for C/S, offset: 0B40H */ + volatile uint32_t WMB0_ID; /*!< wakeup message buffer 0 register for ID, offset: 0B44H */ + volatile uint32_t WMB0_D03; /*!< wakeup message buffer 0 register for data 0 - 3, offset: 0B48H */ + volatile uint32_t WMB0_D47; /*!< wakeup message buffer 0 register for data 4 - 7, offset: 0B4CH */ + volatile uint32_t WMB1_CS; /*!< wakeup message buffer 1 register for C/S, offset: 0B50H */ + volatile uint32_t WMB1_ID; /*!< wakeup message buffer 1 register for ID, offset: 0B54H */ + volatile uint32_t WMB1_D03; /*!< wakeup message buffer 1 register for data 0 - 3, offset: 0B58H */ + volatile uint32_t WMB1_D47; /*!< wakeup message buffer 1 register for data 4 - 7, offest: 0B5CH */ + volatile uint32_t WMB2_CS; /*!< wakeup message buffer 2 register for C/S, offset: 0B60H */ + volatile uint32_t WMB2_ID; /*!< wakeup message buffer 2 register for ID, offset: 0B64H */ + volatile uint32_t WMB2_D03; /*!< wakeup message buffer 2 register for data 0 - 3, offset: 0B68H */ + volatile uint32_t WMB2_D47; /*!< wakeup message buffer 2 register for data 4 - 7, offest: 0B6CH */ + volatile uint32_t WMB3_CS; /*!< wakeup message buffer 3 register for C/S, offset: 0B70H */ + volatile uint32_t WMB3_ID; /*!< wakeup message buffer 3 register for ID, offset: 0B74H */ + volatile uint32_t WMB3_D03; /*!< wakeup message buffer 3 register for data 0 - 3, offset: 0B78H */ + volatile uint32_t WMB3_D47; /*!< wakeup message buffer 3 register for data 4 - 7, offest: 0B7CH */ + volatile uint32_t REVERSED7[32]; /*!< reversed registers, offset: 0B80H */ + volatile uint32_t FDCTRL; /*!< CAN FD control register, offset: 0C00H */ + volatile uint32_t FDCBT; /*!< CAN FD bit timing register, offset: 0C04H */ + volatile uint32_t FDCRC; /*!< CAN FD CRC register, offset: 0C08H */ +} FlexCanRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ +/*! \brief Get FlexCAN module message buffer start address + * + * \param[in] obj : pointer to FlexCAN register instance + * \return module message buffer start address + */ +__attribute__((always_inline)) static inline uint32_t FlexCanReg_GetMsgBufferStartAddr(FlexCanRegType *obj) +{ + return (uint32_t)(&obj->MSGBUF[0]); +} + +/*! \brief Get FlexCAN module disable status + * + * \param[in] obj : pointer to FlexCAN register instance + * \return module disable status + * -0b: enable the FlexCAN module + * -1b: disable the FlexCAN module + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetModuleDisable(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_MDIS_MASK) >> FLEXCAN_MCR_MDIS_SHIFT); +} + +/*! \brief Set FlexCAN module enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : module enable + * -0b: enable the FlexCAN module + * -1b: disable the FlexCAN module + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetModuleDisable(FlexCanRegType *obj, uint8_t isDisable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_MDIS_MASK); + tempReg |= (((uint32_t)isDisable) << FLEXCAN_MCR_MDIS_SHIFT) & FLEXCAN_MCR_MDIS_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get freeze mode + * + * \param[in] obj : pointer to FlexCAN register instance + * \return freeze mode + * -0b: not enabled to enter freeze mode + * -1b: enabled to enter freeze mode + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFreezeMode(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_FRZ_MASK) >> FLEXCAN_MCR_FRZ_SHIFT); +} + +/*! \brief Set freeze mode + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] frzModeReq : freeze mode request + * -0b: not enabled to enter freeze mode + * -1b: enabled to enter freeze mode + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetFreezeMode(FlexCanRegType *obj, uint8_t frzModeReq) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_FRZ_MASK); + tempReg |= (((uint32_t)frzModeReq) << FLEXCAN_MCR_FRZ_SHIFT) & FLEXCAN_MCR_FRZ_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get Rx FIFO enable status + * + * \param[in] obj : pointer to flexCAN register instance + * \return freeze mode + * -0b: Rx FIFO not enable + * -1b: Rx FIFO enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetRxFIFOEnable(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_RFEN_MASK) >> FLEXCAN_MCR_RFEN_SHIFT); +} + +/*! \brief Set Rx FIFO enable status + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] fifoEnable : rx FIFO enable status + * -0b: Rx FIFO not enable + * -1b: Rx FIFO enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRxFIFOEnalbe(FlexCanRegType *obj, uint8_t fifoEnable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_RFEN_MASK); + tempReg |= (((uint32_t)fifoEnable) << FLEXCAN_MCR_RFEN_SHIFT) & FLEXCAN_MCR_RFEN_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get halt mode + * + * \param[in] obj : pointer to flexCAN register instance + * \return halt mode + * -0b: request halt mode + * -1b: no halt mode reuqest + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetHaltMode(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_HALT_MASK) >> FLEXCAN_MCR_HALT_SHIFT); +} + +/*! \brief Set halt mode + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] haltModeReq : halt mode request + * -0b: request halt mode + * -1b: no halt mode reuqest + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetHaltMode(FlexCanRegType *obj, uint8_t haltModeReq) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_HALT_MASK); + tempReg |= (((uint32_t)haltModeReq) << FLEXCAN_MCR_HALT_SHIFT) & FLEXCAN_MCR_HALT_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get not ready flag + * + * \param[in] obj : pointer to flexCAN register instance + * \return not ready flag + * -0b: FlexCAN is either in normal, listen-only, or loop-back mode + * -1b: FlexCAN is either in module disable, doze, stop, or freeze mode + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetNotReadyFlag(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_NOTRDY_MASK) >> FLEXCAN_MCR_NOTRDY_SHIFT); +} + +/*! \brief Get wakeup interrupt mask + * + * \param[in] obj : pointer to flexCAN register instance + * \return wakeup interrupt mask + * -0b: disable wakeup interrupt + * -1b: enable wakeup interrupt + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetWakupIntMask(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_WAKMSK_MASK) >> FLEXCAN_MCR_WAKMSK_SHIFT); +} + +/*! \brief Set wakeup interrupt mask + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] enable : wakeup interrupt mask enable + * -0b: disable wakeup interrupt + * -1b: enable wakeup interrupt + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetWakeupIntMask(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_WAKMSK_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_MCR_WAKMSK_SHIFT) & FLEXCAN_MCR_WAKMSK_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get soft reset request + * + * \param[in] obj : pointer to flexCAN register instance + * \return soft reset request + * -0b: reset the registers affected by soft reset + * -1b: no reset request + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetSoftResetRequest(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_SOFTRST_MASK) >> FLEXCAN_MCR_SOFTRST_SHIFT); +} + +/*! \brief Set soft reset request + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] enable : soft reset request + * -0b : reset the registers affected by soft reset + * -1b : no reset request + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetSoftResetRequest(FlexCanRegType *obj, uint8_t softRstReq) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_SOFTRST_MASK); + tempReg |= (((uint32_t)softRstReq) << FLEXCAN_MCR_SOFTRST_SHIFT) & FLEXCAN_MCR_SOFTRST_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get freeze mode acknowledge + * + * \param[in] obj : pointer to flexCAN register instance + * \return freeze mode acknowledge + * -0b : FlexCAN not in freeze mode, prescaler running + * -1b : FlexCAN in freeze mode, prescaler stopped + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFreezeAck(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_FRZACK_MASK) >> FLEXCAN_MCR_FRZACK_SHIFT); +} + +/*! \brief Get FlexCAN access mode + * + * \param[in] obj : pointer to flexCAN register instance + * \return access mode + * -0b : FlexCAN is in user mode, affected registers allow both + * supervisor and unrestricted access + * -1b : FlexCAN is in supervisor mode. Affected registers allow + * only supervisor access. Unrestricted access behaves as + * though the access was done to an unnimplemented register + * location. + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetAccessMode(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_SUPV_MASK) >> FLEXCAN_MCR_SUPV_SHIFT); +} + +/*! \brief Set FlexCAN access mode + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] accMode : access mode + * -0b : FlexCAN is in user mode, affected registers allow both + * supervisor and unrestricted access + * -1b : FlexCAN is in supervisor mode. Affected registers allow + * only supervisor access. Unrestricted access behaves as + * though the access was done to an unimplemented register + * location. + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetAccessMode(FlexCanRegType *obj, uint8_t accMode) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_SUPV_MASK); + tempReg |= (((uint32_t)accMode) << FLEXCAN_MCR_SUPV_SHIFT) & FLEXCAN_MCR_SUPV_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get self wakeup enable + * + * \param[in] obj : pointer to flexCAN register instance + * \return self wakeup enable + * -0b : Disable FlexCAN self wakeup feature + * -1b : Enable FlexCAN self wakeup feature + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetSelfWakeupEnable(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_SLFWAK_MASK) >> FLEXCAN_MCR_SLFWAK_SHIFT); +} + +/*! \brief Get self wakeup enable + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] enable : self wakeup enable + * -0b : Disable FlexCAN self wakeup feature + * -1b : Enable FlexCAN self wakeup feature + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetSelfWakeupEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_SLFWAK_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_MCR_SLFWAK_SHIFT) & FLEXCAN_MCR_SLFWAK_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get self warning interrupt enable + * + * \param[in] obj : pointer to flexCAN register instance + * \return warning interrupt enable + * -0b : warning interrupt not enable + * -1b : warning interrupt enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetWarningIntEnable(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_WRNEN_MASK) >> FLEXCAN_MCR_WRNEN_SHIFT); +} + +/*! \brief Set self warning interrupt enable + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] enable : warning interrupt enable + * -0b : warning interrupt not enable + * -1b : warning interrupt enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetWarningIntEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_WRNEN_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_MCR_WRNEN_SHIFT) & FLEXCAN_MCR_WRNEN_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get low power mode acknowledge + * + * \param[in] obj : pointer to FlexCAN register instance + * \return low power mode acknowledge + * -0b : FlexCAN is not in a low power mode + * -1b : FlexCAN is in a low power mode + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetLowPowerAck(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_LPMACK_MASK) >> FLEXCAN_MCR_LPMACK_SHIFT); +} + +/*! \brief Get wake up source + * + * \param[in] obj : pointer to FlexCAN register instance + * \return wake up source + * -0b : FlexCAN uses the unfiltered Rx input to detect recessive-to-dominant edges on the CAN bus + * -1b : FlexCAN uses the filtered Rx input to detect recessive-to-dominant edges on the CAN bus + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetWakeupSource(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_WAKSRC_MASK) >> FLEXCAN_MCR_WAKSRC_SHIFT); +} + +/*! \brief Set wake up source + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] enable : wake up source + * -0b : FlexCAN uses the unfiltered Rx input to detect recessive-to-dominant edges on the CAN bus + * -1b : FlexCAN uses the filtered Rx input to detect recessive-to-dominant edges on the CAN bus + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetWakeupSource(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_WAKSRC_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_MCR_WAKSRC_SHIFT) & FLEXCAN_MCR_WAKSRC_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get doze mode enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return doze mode enable + * -0b : FlexCAN is not enabled to enter low-power mode when Doze mode is request + * -1b : FlexCAN is enabled to enter low-power mode when Doze mode is request + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetDozeMode(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_DOZE_MASK) >> FLEXCAN_MCR_DOZE_SHIFT); +} + +/*! \brief Set doze mode enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : doze mode enable + * -0b : FlexCAN is not enabled to enter low-power mode when Doze mode is request + * -1b : FlexCAN is enabled to enter low-power mode when Doze mode is request + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetDozeMode(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_DOZE_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_MCR_DOZE_SHIFT) & FLEXCAN_MCR_DOZE_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get self reception + * + * \param[in] obj : pointer to FlexCAN register instance + * \return self reception enable + * -0b : self reception enable + * -1b : self reception disable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetSelfReceptionDisable(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_SRXDIS_MASK) >> FLEXCAN_MCR_SRXDIS_SHIFT); +} + +/*! \brief Set self reception + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] isDisable : self reception enable + * -0b : self reception enable + * -1b : self reception disable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetSelfReceptionDisable(FlexCanRegType *obj, uint8_t isDisable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_SRXDIS_MASK); + tempReg |= (((uint32_t)isDisable) << FLEXCAN_MCR_SRXDIS_SHIFT) & FLEXCAN_MCR_SRXDIS_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Set rx individual mask + * + * \param[in] obj : pointer to FlexCAN register instance + * \return individual mask enable + * -0b : individual mask disable + * -1b : individual mask enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetIndividualMaskEnable(const FlexCanRegType *obj) +{ + return ((obj->MCR & FLEXCAN_MCR_IRQM_MASK) >> FLEXCAN_MCR_IRQM_SHIFT); +} + +/*! \brief Set rx individual mask + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : individual mask enable + * -0b : individual mask disable + * -1b : individual mask enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetIndividualMaskEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_IRQM_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_MCR_IRQM_SHIFT) & FLEXCAN_MCR_IRQM_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get rx fifo dma enable or disable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return rx fifo dma enable + * -0b : rx fifo dma disable + * -1b : rx fifo dma enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetRxFIFODmaEnable(const FlexCanRegType *obj) +{ + return ((obj->MCR & FLEXCAN_MCR_DMA_MASK) >> FLEXCAN_MCR_DMA_SHIFT); +} + +/*! \brief Set rx fifo dma enable or disable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : rx fifo dma enable + * -0b : rx fifo dma disable + * -1b : rx fifo dma enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRxFIFODmaEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_DMA_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_MCR_DMA_SHIFT) & FLEXCAN_MCR_DMA_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get local priority enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return local priority enable + * -0b : local priority disable + * -1b : local priority enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetMcrLprioen(const FlexCanRegType *obj) +{ + return ((obj->MCR & FLEXCAN_MCR_LPRIOEN_MASK) >> FLEXCAN_MCR_LPRIOEN_SHIFT); +} + +/*! \brief Set local priority enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : local priority enable + * -0b : local priority disable + * -1b : local priority enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetMcrLprioen(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MCR; + + tmp &= ~FLEXCAN_MCR_LPRIOEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_MCR_LPRIOEN_SHIFT)) & FLEXCAN_MCR_LPRIOEN_MASK); + obj->MCR = tmp; +} + +/*! \brief Get Tx message pending abort mechanism enable + * + * \param[in] obj : pointer to flexCAN register instance + * \return Tx message pending abort mechanism enable + * -0b: disable abort + * -1b: enable abort + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetTxAbortEnable(FlexCanRegType *obj) +{ + return (uint8_t)((obj->MCR & FLEXCAN_MCR_AEN_MASK) >> FLEXCAN_MCR_AEN_SHIFT); +} + +/*! \brief Set Tx message pending abort mechanism enable + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] enable : Tx message pending abort mechanism enable + * -0b: disable abort + * -1b: enable abort + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetTxAbortEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_AEN_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_MCR_AEN_SHIFT) & FLEXCAN_MCR_AEN_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get CAN FD operation enable + * + * \param[in] obj : pointer to flexCAN register instance + * \return CAN FD operation enable + * -0b: CAN FD operation enable + * -1b: CAN FD operation disable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFdEnable(const FlexCanRegType *obj) +{ + return ((obj->MCR & FLEXCAN_MCR_FDEN_MASK) >> FLEXCAN_MCR_FDEN_SHIFT); +} + +/*! \brief Set CAN FD operation enable + * + * \param[in] obj : pointer to flexCAN register instance + * \param[in] enable : CAN FD operation enable + * -0b: CAN FD operation enable + * -1b: CAN FD operation disable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetFdEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_FDEN_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_MCR_FDEN_SHIFT) & FLEXCAN_MCR_FDEN_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Set Rx FIFO ID filter acceptance mode + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : Rx FIFO ID filter acceptance mode + * -0h : Format A One full ID (standard and extended) per + * ID filter table element + * -1h : Format B Two full standard IDs or two partial 14-bit + * (standard and extended) IDs per ID filter table element + * -2h : Format C Four partial 8-bit standard IDs per ID filter + * table element + * -3h : Format D All frames rejected + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRxFifoFiltMode(FlexCanRegType *obj, uint8_t val) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_IDAM_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_MCR_IDAM_SHIFT) & FLEXCAN_MCR_IDAM_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get Rx FIFO ID filter acceptance mode + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: Rx FIFO ID filter acceptance mode + * -0h : Format A One full ID (standard and extended) per + * ID filter table element + * -1h : Format B Two full standard IDs or two partial 14-bit + * (standard and extended) IDs per ID filter table element + * -2h : Format C Four partial 8-bit standard IDs per ID filter + * table element + * -3h : Format D All frames rejected + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetRxFifoFiltMode(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->MCR) & FLEXCAN_MCR_IDAM_MASK) >> FLEXCAN_MCR_IDAM_SHIFT); +} + +/*! \brief Get number of the last message buffer + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: number of the last message buffer + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetMcrMaxmb(const FlexCanRegType *obj) +{ + return ((obj->MCR & FLEXCAN_MCR_MAXMB_MASK) >> FLEXCAN_MCR_MAXMB_SHIFT); +} + +/*! \brief Set number of the last message buffer + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] maxNum : number of the last message buffer + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetMaxMsgBufferNum(FlexCanRegType *obj, uint8_t maxNum) +{ + uint32_t tempReg; + tempReg = obj->MCR; + tempReg &= (~FLEXCAN_MCR_MAXMB_MASK); + tempReg |= (((uint32_t)maxNum) << FLEXCAN_MCR_MAXMB_SHIFT) & FLEXCAN_MCR_MAXMB_MASK; + + obj->MCR = tempReg; +} + +/*! \brief Get prescaler division factor + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: prescaler division factor + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl1Presdiv(const FlexCanRegType *obj) +{ + return ((obj->CTRL1 & FLEXCAN_CTRL1_PRESDIV_MASK) >> FLEXCAN_CTRL1_PRESDIV_SHIFT); +} + +/*! \brief Set prescaler division factor + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : prescaler division factor + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl1Presdiv(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL1; + + tmp &= ~FLEXCAN_CTRL1_PRESDIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL1_PRESDIV_SHIFT)) & FLEXCAN_CTRL1_PRESDIV_MASK); + obj->CTRL1 = tmp; +} + +/*! \brief Get resync jump width + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: resync jump width + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl1Rjw(const FlexCanRegType *obj) +{ + return ((obj->CTRL1 & FLEXCAN_CTRL1_RJW_MASK) >> FLEXCAN_CTRL1_RJW_SHIFT); +} + +/*! \brief Set resync jump width + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : resync jump width + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl1Rjw(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL1; + + tmp &= ~FLEXCAN_CTRL1_RJW_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL1_RJW_SHIFT)) & FLEXCAN_CTRL1_RJW_MASK); + obj->CTRL1 = tmp; +} + +/*! \brief Get phase segment 1 + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: phase segment 1 + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl1Pseg1(const FlexCanRegType *obj) +{ + return ((obj->CTRL1 & FLEXCAN_CTRL1_PSEG1_MASK) >> FLEXCAN_CTRL1_PSEG1_SHIFT); +} + +/*! \brief Set phase segment 1 + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : phase segment 1 + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl1Pseg1(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL1; + + tmp &= ~FLEXCAN_CTRL1_PSEG1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL1_PSEG1_SHIFT)) & FLEXCAN_CTRL1_PSEG1_MASK); + obj->CTRL1 = tmp; +} + +/*! \brief Get phase segment 2 + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: phase segment 2 + */ +__attribute__((always_inline)) static inline uint8_t CanReg_GetCtrl1Pseg2(const FlexCanRegType *obj) +{ + return ((obj->CTRL1 & FLEXCAN_CTRL1_PSEG2_MASK) >> FLEXCAN_CTRL1_PSEG2_SHIFT); +} + +/*! \brief Set phase segment 2 + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : phase segment 2 + */ +__attribute__((always_inline)) static inline void CanReg_SetCtrl1Pseg2(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL1; + + tmp &= ~FLEXCAN_CTRL1_PSEG2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL1_PSEG2_SHIFT)) & FLEXCAN_CTRL1_PSEG2_MASK); + obj->CTRL1 = tmp; +} + +/*! \brief Set bus off interrupt enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : bus off interrupt enable + * -0b : bus off interrupt disabled + * -1b : bus off interrupt enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetBusOffIntEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_BOFFMSK_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL1_BOFFMSK_SHIFT) & FLEXCAN_CTRL1_BOFFMSK_MASK; + + obj->CTRL1 = tempReg; +} + +/*! \brief Get bus off interrupt enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: bus off interrupt enable + * -0b : bus off interrupt disabled + * -1b : bus off interrupt enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetBusOffIntEnable(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->CTRL1) & FLEXCAN_CTRL1_BOFFMSK_MASK) >> FLEXCAN_CTRL1_BOFFMSK_SHIFT); +} + +/*! \brief Set error interrupt enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : error interrupt enable + * -0b : error interrupt disabled + * -1b : error interrupt enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetErrorIntEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_ERRMSK_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL1_ERRMSK_SHIFT) & FLEXCAN_CTRL1_ERRMSK_MASK; + + obj->CTRL1 = tempReg; +} + +/*! \brief Get error interrupt enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: error interrupt enable + * -0b : error interrupt disabled + * -1b : error interrupt enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetErrorIntEnable(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->CTRL1) & FLEXCAN_CTRL1_ERRMSK_MASK) >> FLEXCAN_CTRL1_ERRMSK_SHIFT); +} + +/*! \brief Get module clock source + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: module clock source + * -0b : The PE clock source is the oscillator clock. + * -1b : The PE clock source is the peripheral clock. + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetClockSource(const FlexCanRegType *obj) +{ + return ((obj->CTRL1 & FLEXCAN_CTRL1_CLKSRC_MASK) >> FLEXCAN_CTRL1_CLKSRC_SHIFT); +} + +/*! \brief Selects the clock source to the PE submodule to be either the peripheral clock or the oscillator clock + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] clkSrc : + * 0b - The PE clock source is the oscillator clock. + * 1b - The PE clock source is the peripheral clock. + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetClockSource(FlexCanRegType *obj, uint8_t clkSrc) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_CLKSRC_MASK); + tempReg |= (((uint32_t)clkSrc) << FLEXCAN_CTRL1_CLKSRC_SHIFT) & FLEXCAN_CTRL1_CLKSRC_MASK; + + obj->CTRL1 = tempReg; +} + +/*! \brief Get can loop back mode + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: can loop back mode + * 0b - disable + * 1b - enable + */ +__attribute__((always_inline)) static inline uint8_t CanReg_GetLoopbackMode(const FlexCanRegType *obj) +{ + return ((obj->CTRL1 & FLEXCAN_CTRL1_LPB_MASK) >> FLEXCAN_CTRL1_LPB_SHIFT); +} + +/*! \brief Set can loop back mode + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : loop back mode feature select + * 0b - disable + * 1b - enable + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetLoopbackMode(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_LPB_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL1_LPB_SHIFT) & FLEXCAN_CTRL1_LPB_MASK; + + obj->CTRL1 = tempReg; +} + +/*! \brief Set tx warning interrupt enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : tx warning interrupt enable + * -0b : tx warning interrupt disabled + * -1b : tx warning interrupt enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetTxWarnIntEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_TWRNMSK_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL1_TWRNMSK_SHIFT) & FLEXCAN_CTRL1_TWRNMSK_MASK; + + obj->CTRL1 = tempReg; +} + +/*! \brief Get tx warning interrupt enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: tx warning interrupt enable + * -0b : tx warning interrupt disabled + * -1b : tx warning interrupt enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetTxWarnIntEnable(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->CTRL1) & FLEXCAN_CTRL1_TWRNMSK_MASK) >> FLEXCAN_CTRL1_TWRNMSK_SHIFT); +} + +/*! \brief Set rx warning interrupt enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : rx warning interrupt enable + * -0b : rx warning interrupt disabled + * -1b : rx warning interrupt enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRxWarnIntEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_RWRNMSK_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL1_RWRNMSK_SHIFT) & FLEXCAN_CTRL1_RWRNMSK_MASK; + + obj->CTRL1 = tempReg; +} + +/*! \brief Get rx warning interrupt enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: rx warning interrupt enable + * -0b : rx warning interrupt disabled + * -1b : rx warning interrupt enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetRxWarnIntEnable(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->CTRL1) & FLEXCAN_CTRL1_RWRNMSK_MASK) >> FLEXCAN_CTRL1_RWRNMSK_SHIFT); +} + +/*! \brief Get CAN bit sampling mode + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: CAN bit sampling mode + * -0b : one sample is used to determine the bit value + * -1b : three samples are used to determine the value of the received bit + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetBitSamplingType(const FlexCanRegType *obj) +{ + return ((obj->CTRL1 & FLEXCAN_CTRL1_SMP_MASK) >> FLEXCAN_CTRL1_SMP_SHIFT); +} + +/*! \brief Set CAN bit sampling mode + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] threeSamplingEn : can bit sampling + * -0b : one sample is used to determine the bit value + * -1b : three samples are used to determine the value of the received bit + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetBitSamplingType(FlexCanRegType *obj, uint8_t threeSamplingEn) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_SMP_MASK); + tempReg |= (((uint32_t)threeSamplingEn) << FLEXCAN_CTRL1_SMP_SHIFT) & FLEXCAN_CTRL1_SMP_MASK; + + obj->CTRL1 = tempReg; +} + +/*! \brief Set bus off automatic recovering enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : bus off automatic recovering enable + * -1b : bus off automatic recovering disabled + * -0b : bus off automatic recovering enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetBusOffRecEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_BOFFREC_MASK); + if(enable == true) + { + tempReg |= (((uint32_t)0) << FLEXCAN_CTRL1_BOFFREC_SHIFT) & FLEXCAN_CTRL1_BOFFREC_MASK; + } + else + { + tempReg |= (((uint32_t)1) << FLEXCAN_CTRL1_BOFFREC_SHIFT) & FLEXCAN_CTRL1_BOFFREC_MASK; + } + + obj->CTRL1 = tempReg; +} + +/*! \brief Get bus off automatic recovering enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: bus off automatic recovering enable + * -0b : bus off automatic recovering disabled + * -1b : bus off automatic recovering enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetBusOffRecEnable(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->CTRL1) & FLEXCAN_CTRL1_BOFFREC_MASK) >> FLEXCAN_CTRL1_BOFFREC_SHIFT); +} + +/*! \brief Set timer synchronze feature enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : timer synchronze feature enable + * -0b : timer sync feature disabled + * -1b : timer sync feature enabled + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetTimerSyncEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_TSYN_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL1_TSYN_SHIFT) & FLEXCAN_CTRL1_TSYN_MASK; + + obj->CTRL1 = tempReg; +} + +/*! \brief Get timer synchronze feature enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: timer synchronze feature enable + * -0b : timer sync feature disabled + * -1b : timer sync feature enabled + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetTimerSyncEnable(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->CTRL1) & FLEXCAN_CTRL1_TSYN_MASK) >> FLEXCAN_CTRL1_TSYN_SHIFT); +} + +/*! \brief Set lowest buffer transmit first enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : timer synchronze feature enable + * -0b : lowest buffer transmit first disable + * -1b : lowest buffer transmit first enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetLowestBufTxFirstEna(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_LBUF_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL1_LBUF_SHIFT) & FLEXCAN_CTRL1_LBUF_MASK; + + obj->CTRL1 = tempReg; +} + +/*! \brief Get lowest buffer transmit first enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: lowest buffer transmit first enable + * -0b : lowest buffer transmit first disable + * -1b : lowest buffer transmit first enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetLowestBufTxFirstEna(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->CTRL1) & FLEXCAN_CTRL1_LBUF_MASK) >> FLEXCAN_CTRL1_LBUF_SHIFT); +} + +/*! \brief Set listen only mode enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : listen only mode enable + * -0b : listen only mode disable + * -1b : listen only mode enable + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetListenOnlyModeEna(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL1; + tempReg &= (~FLEXCAN_CTRL1_LOM_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL1_LOM_SHIFT) & FLEXCAN_CTRL1_LOM_MASK; + + obj->CTRL1 = tempReg; +} + +/*! \brief Get listen only mode enable + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: listen only mode enable + * -0b : listen only mode disable + * -1b : listen only mode enable + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetListenOnlyModeEna(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->CTRL1) & FLEXCAN_CTRL1_LOM_MASK) >> FLEXCAN_CTRL1_LOM_SHIFT); +} + +/*! \brief Get propagation segment + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: propagation segment length + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl1Propseg(const FlexCanRegType *obj) +{ + return ((obj->CTRL1 & FLEXCAN_CTRL1_PROPSEG_MASK) >> FLEXCAN_CTRL1_PROPSEG_SHIFT); +} + +/*! \brief Set propagation segment + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : propagation segment length + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl1Propseg(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL1; + + tmp &= ~FLEXCAN_CTRL1_PROPSEG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL1_PROPSEG_SHIFT)) & FLEXCAN_CTRL1_PROPSEG_MASK); + obj->CTRL1 = tmp; +} + +/*! \brief Get free running timer + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: free running timer counter + * + */ +__attribute__((always_inline)) static inline uint32_t FlexCanReg_GetFreeRunningTimer(FlexCanRegType *obj) +{ + return obj->TIMER; +} + +/*! \brief Get Rx mailboxes global mask + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: Rx mailboxes global mask + * + */ +__attribute__((always_inline)) static inline uint32_t FlexCanReg_GetRxMailboxGlobalMask(FlexCanRegType *obj) +{ + return obj->RXMGMASK; +} + +/*! \brief Set Rx mailboxes global mask + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] mask : Rx mailboxes global mask + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRxMailboxGlobalMask(FlexCanRegType *obj, uint32_t mask) +{ + obj->RXMGMASK = mask; +} + + +/*! \brief Set Rx mailbox 14 mask + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] mask : mask for Rx mailbox 14 + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRxMailbox14Mask(FlexCanRegType *obj, uint32_t mask) +{ + obj->RX14MASK = mask; +} + +/*! \brief Get Rx mailbox 14 mask + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: mask for Rx mailbox 14 + * + */ +__attribute__((always_inline)) static inline uint32_t FlexCanReg_GetRxMailbox14Mask(FlexCanRegType *obj) +{ + return (obj->RX14MASK); +} + +/*! \brief Set Rx mailbox 15 mask + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] mask : mask for Rx mailbox 15 + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRxMailbox15Mask(FlexCanRegType *obj, uint32_t mask) +{ + obj->RX15MASK = mask; +} + +/*! \brief Get Rx mailbox 15 mask + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: mask for Rx mailbox 15 + * + */ +__attribute__((always_inline)) static inline uint32_t FlexCanReg_GetRxMailbox15Mask(FlexCanRegType *obj) +{ + return (obj->RX15MASK); +} + +/*! \brief Get receive error counter for fast bits + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: receive error counter for fast bits + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEcrRxerrcntfast(const FlexCanRegType *obj) +{ + return ((obj->ECR & FLEXCAN_ECR_RXERRCNTFAST_MASK) >> FLEXCAN_ECR_RXERRCNTFAST_SHIFT); +} + +/*! \brief Set receive error counter for fast bits + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : receive error counter for fast bits + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetEcrRxerrcntfast(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ECR; + + tmp &= ~FLEXCAN_ECR_RXERRCNTFAST_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_ECR_RXERRCNTFAST_SHIFT)) & FLEXCAN_ECR_RXERRCNTFAST_MASK); + obj->ECR = tmp; +} + +/*! \brief Get transmit error counter for fast bits + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: transmit error counter for fast bits + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEcrTxerrcntfast(const FlexCanRegType *obj) +{ + return ((obj->ECR & FLEXCAN_ECR_TXERRCNTFAST_MASK) >> FLEXCAN_ECR_TXERRCNTFAST_SHIFT); +} + +/*! \brief Set transmit error counter for fast bits + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : transmit error counter for fast bits + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetEcrTxerrcntfast(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ECR; + + tmp &= ~FLEXCAN_ECR_TXERRCNTFAST_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_ECR_TXERRCNTFAST_SHIFT)) & FLEXCAN_ECR_TXERRCNTFAST_MASK); + obj->ECR = tmp; +} + +/*! \brief Get receive error counter + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: receive error counter + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEcrRxerrcnt(const FlexCanRegType *obj) +{ + return ((obj->ECR & FLEXCAN_ECR_RXERRCNT_MASK) >> FLEXCAN_ECR_RXERRCNT_SHIFT); +} + +/*! \brief Set receive error counter + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : receive error counter + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetEcrRxerrcnt(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ECR; + + tmp &= ~FLEXCAN_ECR_RXERRCNT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_ECR_RXERRCNT_SHIFT)) & FLEXCAN_ECR_RXERRCNT_MASK); + obj->ECR = tmp; +} + +/*! \brief Get transmit error counter + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: transmit error counter + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEcrTxerrcnt(const FlexCanRegType *obj) +{ + return ((obj->ECR & FLEXCAN_ECR_TXERRCNT_MASK) >> FLEXCAN_ECR_TXERRCNT_SHIFT); +} + +/*! \brief Set transmit error counter + * + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : transmit error counter + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetEcrTxerrcnt(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ECR; + + tmp &= ~FLEXCAN_ECR_TXERRCNT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_ECR_TXERRCNT_SHIFT)) & FLEXCAN_ECR_TXERRCNT_MASK); + obj->ECR = tmp; +} + + +/*! \brief Get bit 1 error in FD frame data phase + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: bit 1 error in FD frame data phase + * - 0 : no such error occurrence + * - 1 : at least one bit sent as recessive is received as dominant + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetBit1FastError(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_BIT1ERR_FAST_MASK) >> FLEXCAN_ESR1_BIT1ERR_FAST_SHIFT); +} + +/*! \brief Get bit 0 error in FD frame data phase + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: bit 0 error in FD frame data phase + * - 0 : no such error occurrence + * - 1 : at least one bit sent as dominant is received as recessive + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetBit0FastError(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_BIT0ERR_FAST_MASK) >> FLEXCAN_ESR1_BIT0ERR_FAST_SHIFT); +} + +/*! \brief Get CRC error in FD frame data phase + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: CRC error in FD frame data phase + * - 0 : no such error occurrence + * - 1 : a CRC error occurred since last read of this register + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCrcFastError(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_CRCERR_FAST_MASK) >> FLEXCAN_ESR1_CRCERR_FAST_SHIFT); +} + +/*! \brief Get form error in FD frame data phase + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: form error in FD frame data phase + * - 0 : no such error occurrence + * - 1 : a form error occurred since last read of this register + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFormFastError(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_FRMERR_FAST_MASK) >> FLEXCAN_ESR1_FRMERR_FAST_SHIFT); +} + +/*! \brief Get stuff error in FD frame data phase + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: stuff error in FD frame data phase + * - 0 : no such error occurrence + * - 1 : a stuff error occurred since last read of this register + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetStuffFastError(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_STFERR_FAST_MASK) >> FLEXCAN_ESR1_STFERR_FAST_SHIFT); +} + +/*! \brief Get error overrun + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: error overrun + * - 0 : overrun has occurred + * - 1 : overrun has not occurred + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEsr1Errovr(const FlexCanRegType *obj) +{ + return ((obj->ESR1 & FLEXCAN_ESR1_ERROVR_MASK) >> FLEXCAN_ESR1_ERROVR_SHIFT); +} + +/*! \brief Clear error overrun + * + * \param[in] obj : pointer to FlexCAN register instance + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_ClearEsr1Errovr(FlexCanRegType *obj) +{ + obj->ESR1 = FLEXCAN_ESR1_ERROVR_MASK; +} + +/*! \brief Get error interrupt for errors detected in the data phase of CAN FD frames with the + * BRS Bit set + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: error interrupt for errors detected in the data phase + * - 0 : no error + * - 1 : error has detected in CAN FD frame data phase + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEsr1Errintfast(const FlexCanRegType *obj) +{ + return ((obj->ESR1 & FLEXCAN_ESR1_ERRINT_FAST_MASK) >> FLEXCAN_ESR1_ERRINT_FAST_SHIFT); +} + +/*! \brief Clear error interrupt for errors detected in the data phase of CAN FD frames with the + * BRS Bit set + * + * \param[in] obj : pointer to FlexCAN register instance + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_ClearEsr1Errintfast(FlexCanRegType *obj) +{ + obj->ESR1 = FLEXCAN_ESR1_ERRINT_FAST_MASK; +} + +/*! \brief Get bus off done interrupt + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: bus off done interrupt + * - 0 : no such occurrence + * - 1 : module has completed bus off process + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEsr1Boffdoneint(const FlexCanRegType *obj) +{ + return ((obj->ESR1 & FLEXCAN_ESR1_BOFFDONEINT_MASK) >> FLEXCAN_ESR1_BOFFDONEINT_SHIFT); +} + +/*! \brief Clear bus off done interrupt + * + * \param[in] obj : pointer to FlexCAN register instance + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_ClearEsr1Boffdoneint(FlexCanRegType *obj) +{ + obj->ESR1 = FLEXCAN_ESR1_BOFFDONEINT_MASK; +} + +/*! \brief Get CAN synchronization status + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: CAN synchronization status + * - 0 : not synchronized to the can bus + * - 1 : synchronized to the can bus + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEsr1Synch(const FlexCanRegType *obj) +{ + return ((obj->ESR1 & FLEXCAN_ESR1_SYNCH_MASK) >> FLEXCAN_ESR1_SYNCH_SHIFT); +} + +/*! \brief Get Tx warning interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: Tx warning interrupt flag + * - 0 : no such occurrence + * - 1 : tx error counter transitioned from less than 96 to greater than or equal to 96 + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEsr1Twrnint(const FlexCanRegType *obj) +{ + return ((obj->ESR1 & FLEXCAN_ESR1_TWRNINT_MASK) >> FLEXCAN_ESR1_TWRNINT_SHIFT); +} + +/*! \brief Clear Tx warning interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_ClearEsr1Twrnint(FlexCanRegType *obj) +{ + obj->ESR1 = FLEXCAN_ESR1_TWRNINT_MASK; +} + +/*! \brief Get Rx warning interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: Rx warning interrupt flag + * - 0 : no such occurrence + * - 1 : Rx error counter transitioned from less than 96 to greater than or equal to 96 + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEsr1Rwrnint(const FlexCanRegType *obj) +{ + return ((obj->ESR1 & FLEXCAN_ESR1_RWRNINT_MASK) >> FLEXCAN_ESR1_RWRNINT_SHIFT); +} + +/*! \brief Clear Rx warning interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_ClearEsr1Rwrnint(FlexCanRegType *obj) +{ + obj->ESR1 = FLEXCAN_ESR1_RWRNINT_MASK; +} + +/*! \brief Get bit 1 error + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: bit 1 error + * - 0 : no such error occurrence + * - 1 : at least one bit sent as recessive is received as dominant + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetBit1Error(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_BIT1ERR_MASK) >> FLEXCAN_ESR1_BIT1ERR_SHIFT); +} + +/*! \brief Get bit 0 error + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: bit 0 error + * - 0 : no such error occurrence + * - 1 : at least one bit sent as dominant is received as recessive + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetBit0Error(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_BIT0ERR_MASK) >> FLEXCAN_ESR1_BIT0ERR_SHIFT); +} + +/*! \brief Get ACK error + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: ACK error + * - 0 : no such error occurrence + * - 1 : an ACK error occurred since last read of this register + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetAckError(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_ACKERR_MASK) >> FLEXCAN_ESR1_ACKERR_SHIFT); +} + +/*! \brief Get CRC error + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: CRC error + * - 0 : no such error occurrence + * - 1 : an CRC error occurred since last read of this register + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCrcError(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_CRCERR_MASK) >> FLEXCAN_ESR1_CRCERR_SHIFT); +} + +/*! \brief Get form error + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: form error + * - 0 : no such error occurrence + * - 1 : an form error occurred since last read of this register + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFormError(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_FRMERR_MASK) >> FLEXCAN_ESR1_FRMERR_SHIFT); +} + +/*! \brief Get stuff error + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: stuff error + * - 0 : no such error occurrence + * - 1 : an stuff error occurred since last read of this register + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetStuffError(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_STFERR_MASK) >> FLEXCAN_ESR1_STFERR_SHIFT); +} + +/*! \brief Get Tx error warning + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: Tx error warning + * - 0 : no such error occurrence + * - 1 : TXERRCNT is greater than or equal to 96 + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetTxErrWarning(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_TXWRN_MASK) >> FLEXCAN_ESR1_TXWRN_SHIFT); +} + +/*! \brief Get Rx error warning + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: Rx error warning + * - 0 : no such error occurrence + * - 1 : RXERRCNT is greater than or equal to 96 + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetRxErrWarning(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_RXWRN_MASK) >> FLEXCAN_ESR1_RXWRN_SHIFT); +} + +/*! \brief Get idle state + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: idle state + * - 0 : no such occurrence + * - 1 : CAN bus is now idle + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetIdleState(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_IDLE_MASK) >> FLEXCAN_ESR1_IDLE_SHIFT); +} + +/*! \brief Get Tx state + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: Tx state + * - 0 : FlexCan is not transmitting a message + * - 1 : FlexCan is transmitting a message + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetTxState(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_TX_MASK) >> FLEXCAN_ESR1_TX_SHIFT); +} + +/*! \brief Get fault confinement state + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: fault confinement state + * - 0b00 : error passive + * - 0b01 : error active + * - 0b1x : bus off + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFltConfinementState(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_FLTCONF_MASK) >> FLEXCAN_ESR1_FLTCONF_SHIFT); +} + +/*! \brief Get FlexCan Rx state + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: FlexCan Rx state + * - 0 : FlexCan is not receiving a message + * - 1 : FlexCan is receiving a message + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetRxState(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_RX_MASK) >> FLEXCAN_ESR1_RX_SHIFT); +} + +/*! \brief Get bus off interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: bus off interrupt flag + * - 0 : bus off interrupt assert + * - 1 : bus off interrupt deassert + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetBusoffIntFlag(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_BOFFINT_MASK) >> FLEXCAN_ESR1_BOFFINT_SHIFT); +} + +/*! \brief Clear bus off interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_ClearBusoffIntFlag(FlexCanRegType *obj) +{ + obj->ESR1 = FLEXCAN_ESR1_BOFFINT_MASK; +} + +/*! \brief Get error interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: error interrupt flag + * - 0 : error interrupt assert + * - 1 : error interrupt deassert + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetErrIntFlag(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_ERRINT_MASK) >> FLEXCAN_ESR1_ERRINT_SHIFT); +} + +/*! \brief Clear error interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_ClearErrIntFlag(FlexCanRegType *obj) +{ + obj->ESR1 = FLEXCAN_ESR1_ERRINT_MASK; +} + +/*! \brief Get edge wakeup interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: edge wakeup interrupt flag + * - 0 : wakeup interrupt assert + * - 1 : wakeup interrupt deassert + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEdgeWakeIntFlag(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->ESR1) & FLEXCAN_ESR1_WAKINT_MASK) >> FLEXCAN_ESR1_WAKINT_SHIFT); +} + +/*! \brief Clear edge wakeup interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_ClearEdgeWakeIntFlag(FlexCanRegType *obj) +{ + obj->ESR1 = FLEXCAN_ESR1_WAKINT_MASK; +} + +/*! \brief Set FlexCan message buffer interrupt enable mask + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] regId : register index + * \param[in] val : message buffer interrupt enable mask + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetMsgBufInterruptEnable(FlexCanRegType *obj, uint32_t regId, uint32_t val) +{ + switch(regId) + { + case 0: + obj->IMASK1 |= val; + break; + case 1: + obj->IMASK2 |= val; + break; + case 2: + obj->IMASK3 |= val; + break; + case 3: + obj->IMASK4 |= val; + break; + default: + break; + } +} + +/*! \brief Set FlexCan message buffer interrupt disable mask + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] regId : register index + * \param[in] val : message buffer interrupt disable mask + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetMsgBufInterruptDisable(FlexCanRegType *obj, uint32_t regId, uint32_t val) +{ + switch(regId) + { + case 0: + obj->IMASK1 &= val; + break; + case 1: + obj->IMASK2 &= val; + break; + case 2: + obj->IMASK3 &= val; + break; + case 3: + obj->IMASK4 &= val; + break; + default: + break; + } +} + +/*! \brief Get FlexCan message buffer interrupt flag register mask + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] regId : register index + * \return: FlexCan message buffer interrupt flag register[n] mask + * + */ +__attribute__((always_inline)) static inline uint32_t FlexCanReg_GetMsgBufInterruptFlagReg(FlexCanRegType *obj, uint32_t regId) +{ + uint32_t retVal = 0; + + switch(regId) + { + case 0: + retVal = obj->IFLAG1; + break; + case 1: + retVal = obj->IFLAG2; + break; + case 2: + retVal = obj->IFLAG3; + break; + case 3: + retVal = obj->IFLAG4; + break; + default: + break; + } + + return retVal; +} + +/*! \brief Set FlexCan message buffer interrupt flag + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] regId : register index + * \param[in] val : message buffer interrupt flag + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetMsgBufInterruptFlagReg(FlexCanRegType *obj, uint32_t regId, uint32_t val) +{ + switch(regId) + { + case 0: + obj->IFLAG1 = val; + break; + case 1: + obj->IFLAG2 = val; + break; + case 2: + obj->IFLAG3 = val; + break; + case 3: + obj->IFLAG4 = val; + break; + default: + break; + } +} + +/*! \brief Get error interrupt mask in the data phase of CAN FD frame + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: error interrupt mask in the data phase of CAN FD frame + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl2Errmskfast(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_ERRMSKFAST_MASK) >> FLEXCAN_CTRL2_ERRMSKFAST_SHIFT); +} + +/*! \brief Set error interrupt mask in the data phase of CAN FD frame + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : error interrupt mask in the data phase of CAN FD frame + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl2Errmskfast(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL2; + + tmp &= ~FLEXCAN_CTRL2_ERRMSKFAST_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL2_ERRMSKFAST_SHIFT)) & FLEXCAN_CTRL2_ERRMSKFAST_MASK); + obj->CTRL2 = tmp; +} + +/*! \brief Get bus off done interrupt mask + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: bus off done interrupt mask + * 0: bus off done interrupt disable + * 1: bus off done interrupt enable + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl2Boffdonemsk(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_BOFFDONEMSK_MASK) >> FLEXCAN_CTRL2_BOFFDONEMSK_SHIFT); +} + +/*! \brief Set bus off done interrupt mask + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : bus off done interrupt mask + * 0: bus off done interrupt disable + * 1: bus off done interrupt enable + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl2Boffdonemsk(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL2; + + tmp &= ~FLEXCAN_CTRL2_BOFFDONEMSK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL2_BOFFDONEMSK_SHIFT)) & FLEXCAN_CTRL2_BOFFDONEMSK_MASK); + obj->CTRL2 = tmp; +} + +/*! \brief Get error correction configuration register write enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: error correction configuration register write enable + * 0: error correction configuration register write disable + * 1: error correction configuration register write enable + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetMemErrCtrlRegWriteEnable(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_ECRWRE_MASK) >> FLEXCAN_CTRL2_ECRWRE_SHIFT); +} + +/*! \brief Set error correction configuration register write enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : error correction configuration register write enable + * 0: error correction configuration register write disable + * 1: error correction configuration register write enable + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetMemErrCtrlRegWriteEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL2; + tempReg &= (~FLEXCAN_CTRL2_ECRWRE_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL2_ECRWRE_SHIFT) & FLEXCAN_CTRL2_ECRWRE_MASK; + + obj->CTRL2 = tempReg; +} + +/*! \brief Get write access to memory in freeze mode enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: write access to memory in freeze mode enable + * 0: write access to memory in freeze mode disable + * 1: write access to memory in freeze mode enable + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFreezeModeWriteAcc(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_WRMFRZ_MASK) >> FLEXCAN_CTRL2_WRMFRZ_SHIFT); +} + +/*! \brief Set write access to memory in freeze mode enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : write access to memory in freeze mode enable + * 0: write access to memory in freeze mode disable + * 1: write access to memory in freeze mode enable + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetFreezeModeWriteAcc(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL2; + tempReg &= (~FLEXCAN_CTRL2_WRMFRZ_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL2_WRMFRZ_SHIFT) & FLEXCAN_CTRL2_WRMFRZ_MASK; + + obj->CTRL2 = tempReg; +} + +/*! \brief Set number of legacy Rx FIFO filters + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : number of legacy Rx FIFO filters + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRxFifoFilterNum(FlexCanRegType *obj, uint8_t val) +{ + uint32_t tempReg; + tempReg = obj->CTRL2; + tempReg &= (~FLEXCAN_CTRL2_RFFN_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_CTRL2_RFFN_SHIFT) & FLEXCAN_CTRL2_RFFN_MASK; + + obj->CTRL2 = tempReg; +} + +/*! \brief Get number of legacy Rx FIFO filters + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: number of Rx FIFO filters + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetRxFifoFilterNum(FlexCanRegType *obj) +{ + return (uint8_t)(((obj->CTRL2) & FLEXCAN_CTRL2_RFFN_MASK) >> FLEXCAN_CTRL2_RFFN_SHIFT); +} + +/*! \brief Get Tx arbitration start delay + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: Tx arbitration start delay + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl2Tasd(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_TASD_MASK) >> FLEXCAN_CTRL2_TASD_SHIFT); +} + +/*! \brief Set Tx arbitration start delay + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : Tx arbitration start delay + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl2Tasd(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL2; + + tmp &= ~FLEXCAN_CTRL2_TASD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL2_TASD_SHIFT)) & FLEXCAN_CTRL2_TASD_MASK); + obj->CTRL2 = tmp; +} + +/*! \brief Get mailboxes reception priority + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: mailboxes reception priority + * 0: matching starts from Rx FIFO and continues on mailboxes + * 1: matching starts from mailboxes and continues on Rx FIFO + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl2Mrp(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_MRP_MASK) >> FLEXCAN_CTRL2_MRP_SHIFT); +} + +/*! \brief Set mailboxes reception priority + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : mailboxes reception priority + * 0: matching starts from Rx FIFO and continues on mailboxes + * 1: matching starts from mailboxes and continues on Rx FIFO + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl2Mrp(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL2; + + tmp &= ~FLEXCAN_CTRL2_MRP_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL2_MRP_SHIFT)) & FLEXCAN_CTRL2_MRP_MASK); + obj->CTRL2 = tmp; +} + +/*! \brief Get remote request storing + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: remote request storing + * 0: remote response frame is generated + * 1: remote request frame is stored + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl2Rrs(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_RRS_MASK) >> FLEXCAN_CTRL2_RRS_SHIFT); +} + +/*! \brief Set remote request storing + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : remote request storing + * 0: remote response frame is generated + * 1: remote request frame is stored + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl2Rrs(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL2; + + tmp &= ~FLEXCAN_CTRL2_RRS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL2_RRS_SHIFT)) & FLEXCAN_CTRL2_RRS_MASK); + obj->CTRL2 = tmp; +} + +/*! \brief Get entire frame arbitration field comparison enable for rx mailboxes + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: entire frame arbitration field comparison enable for rx mailboxes + * 0: rx mailbox filter's IDE bit is always compared and RTR is never + * compared, regardless of mask bits + * 1: enable the comparison of both the IDE and RTR bits of an + * Rx mailbox filter with the corresponding bits of the incoming + * frame. Mask bits do apply + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl2Eacen(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_EACEN_MASK) >> FLEXCAN_CTRL2_EACEN_SHIFT); +} + +/*! \brief Set entire frame arbitration field comparison enable for rx mailboxes + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : entire frame arbitration field comparison enable for rx mailboxes + * 0: rx mailbox filter's IDE bit is always compared and RTR is never + * compared, regardless of mask bits + * 1: enable the comparison of both the IDE and RTR bits of an + * Rx mailbox filter with the corresponding bits of the incoming + * frame. Mask bits do apply + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl2Eacen(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL2; + + tmp &= ~FLEXCAN_CTRL2_EACEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL2_EACEN_SHIFT)) & FLEXCAN_CTRL2_EACEN_MASK); + obj->CTRL2 = tmp; +} + +/*! \brief Get free running timer source + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: free running timer source + * 0: clocked by CAN bit clock + * 1: clocked by an external time tick, the period can be either adjusted + * to be equal to the baud rate on the CAN bus or a different value as + * required + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl2Timersrc(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_TIMERSRC_MASK) >> FLEXCAN_CTRL2_TIMERSRC_SHIFT); +} + +/*! \brief Set free running timer source + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : free running timer source + * 0: clocked by CAN bit clock + * 1: clocked by an external time tick, the period can be either adjusted + * to be equal to the baud rate on the CAN bus or a different value as + * required + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl2Timersrc(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL2; + + tmp &= ~FLEXCAN_CTRL2_TIMERSRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL2_TIMERSRC_SHIFT)) & FLEXCAN_CTRL2_TIMERSRC_MASK); + obj->CTRL2 = tmp; +} + +/*! \brief Get protocol exception enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: protocol exception enable + * 0: protocol exception disable + * 1: protocol exception enable + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl2Prexcen(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_PREXCEN_MASK) >> FLEXCAN_CTRL2_PREXCEN_SHIFT); +} + +/*! \brief Set protocol exception enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : protocol exception enable + * 0: protocol exception disable + * 1: protocol exception enable + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl2Prexcen(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL2; + + tmp &= ~FLEXCAN_CTRL2_PREXCEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL2_PREXCEN_SHIFT)) & FLEXCAN_CTRL2_PREXCEN_MASK); + obj->CTRL2 = tmp; +} + +/*! \brief Get ISO CAN FD enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: ISO CAN FD enable + * 0: ISO CAN FD disable + * 1: ISO CAN FD enable + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetIsoFdEnalbe(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_ISOCANFDEN_MASK) >> FLEXCAN_CTRL2_ISOCANFDEN_SHIFT); +} + +/*! \brief Set ISO CAN FD enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : ISO CAN FD enable + * 0: ISO CAN FD disable + * 1: ISO CAN FD enable + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetIsoFdEnalbe(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CTRL2; + tempReg &= (~FLEXCAN_CTRL2_ISOCANFDEN_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CTRL2_ISOCANFDEN_SHIFT) & FLEXCAN_CTRL2_ISOCANFDEN_MASK; + + obj->CTRL2 = tempReg; +} + +/*! \brief Get edge filter enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: edge filter enable + * 0: edge filter enable + * 1: edge filter disable + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCtrl2Edfltdis(const FlexCanRegType *obj) +{ + return ((obj->CTRL2 & FLEXCAN_CTRL2_EDFLTDIS_MASK) >> FLEXCAN_CTRL2_EDFLTDIS_SHIFT); +} + +/*! \brief Set edge filter enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] value : edge filter enable + * 0: edge filter enable + * 1: edge filter disable + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetCtrl2Edfltdis(FlexCanRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL2; + + tmp &= ~FLEXCAN_CTRL2_EDFLTDIS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FLEXCAN_CTRL2_EDFLTDIS_SHIFT)) & FLEXCAN_CTRL2_EDFLTDIS_MASK); + obj->CTRL2 = tmp; +} + +/*! \brief Get lowest priority Tx mailbox + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: lowest priority Tx mailbox + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEsr2Lptm(const FlexCanRegType *obj) +{ + return ((obj->ESR2 & FLEXCAN_ESR2_LPTM_MASK) >> FLEXCAN_ESR2_LPTM_SHIFT); +} + +/*! \brief Get valid priority status + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: valid priority status + * 0: contents of IMB and LPTM are invalid + * 1: contents of IMB and LPTM are valid + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEsr2Vps(const FlexCanRegType *obj) +{ + return ((obj->ESR2 & FLEXCAN_ESR2_VPS_MASK) >> FLEXCAN_ESR2_VPS_SHIFT); +} + +/*! \brief Get Inactive mailbox + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: Inactive mailbox + * 0: if CAN_ESR2.VPS is asserted, CAN_ESR2.LPTM is not an inactive mailbox + * 1: if CAN_ESR2.VPS is asserted, there is at least one inactive maibox. + * CAN_ESR2.LPTM content is the number of the first one + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetEsr2Imb(const FlexCanRegType *obj) +{ + return ((obj->ESR2 & FLEXCAN_ESR2_IMB_MASK) >> FLEXCAN_ESR2_IMB_SHIFT); +} + +/*! \brief Get CRC mailbox + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: CRC mailbox, indicats the number of the mailbox corresponding to the value + * in the CAN_CRCR.TXCRC field + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetCrcrMbcrc(const FlexCanRegType *obj) +{ + return ((obj->CRCR & FLEXCAN_CRCR_MBCRC_MASK) >> FLEXCAN_CRCR_MBCRC_SHIFT); +} + +/*! \brief Get transmitted CRC mailbox + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: transmitted CRC mailbox, indicats the CRC value of the last transmitted + * message for non-FD frames + * + */ +__attribute__((always_inline)) static inline uint16_t FlexCanReg_GetCrcrTxcrc(const FlexCanRegType *obj) +{ + return ((obj->CRCR & FLEXCAN_CRCR_TXCRC_MASK) >> FLEXCAN_CRCR_TXCRC_SHIFT); +} + +/*! \brief Get Rx FIFO global mask + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: Rx FIFO global mask + * + */ +__attribute__((always_inline)) static inline uint32_t FlexCanReg_GetRxFifoGlobalMask(FlexCanRegType *obj) +{ + return (obj->RXFGMASK); +} + +/*! \brief Set Rx FIFO global mask + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : Rx FIFO global mask + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRxFifoGlobalMask(FlexCanRegType *obj, uint32_t val) +{ + obj->RXFGMASK = val; +} + +/*! \brief Get identifier acceptance filter hit indicator + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: identifier acceptance filter hit indicator + * + */ +__attribute__((always_inline)) static inline uint16_t FlexCanReg_GetRxfirIdhit(const FlexCanRegType *obj) +{ + return ((obj->RXFIR & FLEXCAN_RXFIR_IDHIT_MASK) >> FLEXCAN_RXFIR_IDHIT_SHIFT); +} + +/*! \brief Get extended bit timing format enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: extended bit timing format enable + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetExtendedBitTimingEnable(const FlexCanRegType *obj) +{ + return ((obj->CBT & FLEXCAN_CBT_BTF_MASK) >> FLEXCAN_CBT_BTF_SHIFT); +} + +/*! \brief Set extended bit timing format enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : extended bit timing format enable + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetExtendedBitTimingEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->CBT; + tempReg &= (~FLEXCAN_CBT_BTF_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_CBT_BTF_SHIFT) & FLEXCAN_CBT_BTF_MASK; + + obj->CBT = tempReg; +} + +/*! \brief Get extended prescaler division factor + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: extended prescaler division factor + * + */ +__attribute__((always_inline)) static inline uint16_t FlexCanReg_GetExtPresalerDivision(const FlexCanRegType *obj) +{ + return ((obj->CBT & FLEXCAN_CBT_EPRESDIV_MASK) >> FLEXCAN_CBT_EPRESDIV_SHIFT); +} + +/*! \brief Set extended prescaler division factor + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : extended prescaler division factor + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetExtPresalerDivision(FlexCanRegType *obj, uint16_t val) +{ + uint32_t tempReg; + tempReg = obj->CBT; + tempReg &= (~FLEXCAN_CBT_EPRESDIV_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_CBT_EPRESDIV_SHIFT) & FLEXCAN_CBT_EPRESDIV_MASK; + + obj->CBT = tempReg; +} + +/*! \brief Get extended resync jump width + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: extended resync jump width + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetExtResyncJumpWidth(const FlexCanRegType *obj) +{ + return ((obj->CBT & FLEXCAN_CBT_ERJW_MASK) >> FLEXCAN_CBT_ERJW_SHIFT); +} + +/*! \brief Set extended resync jump width + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : extended resync jump width + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetExtResyncJumpWidth(FlexCanRegType *obj, uint16_t val) +{ + uint32_t tempReg; + tempReg = obj->CBT; + tempReg &= (~FLEXCAN_CBT_ERJW_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_CBT_ERJW_SHIFT) & FLEXCAN_CBT_ERJW_MASK; + + obj->CBT = tempReg; +} + +/*! \brief Get extended propagation segment + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: extended propagation segment + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetExtPorpSeg(const FlexCanRegType *obj) +{ + return ((obj->CBT & FLEXCAN_CBT_EPROPSEG_MASK) >> FLEXCAN_CBT_EPROPSEG_SHIFT); +} + +/*! \brief Set extended propagation segment + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : extended propagation segment + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetExtPorpSeg(FlexCanRegType *obj, uint16_t val) +{ + uint32_t tempReg; + tempReg = obj->CBT; + tempReg &= (~FLEXCAN_CBT_EPROPSEG_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_CBT_EPROPSEG_SHIFT) & FLEXCAN_CBT_EPROPSEG_MASK; + + obj->CBT = tempReg; +} + +/*! \brief Get extended phase segment 1 + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: extended phase segment 1 + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetExtPhaseSeg1(const FlexCanRegType *obj) +{ + return ((obj->CBT & FLEXCAN_CBT_EPSEG1_MASK) >> FLEXCAN_CBT_EPSEG1_SHIFT); +} + +/*! \brief Set extended phase segment 1 + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : extended phase segment 1 + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetExtPhaseSeg1(FlexCanRegType *obj, uint16_t val) +{ + uint32_t tempReg; + tempReg = obj->CBT; + tempReg &= (~FLEXCAN_CBT_EPSEG1_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_CBT_EPSEG1_SHIFT) & FLEXCAN_CBT_EPSEG1_MASK; + + obj->CBT = tempReg; +} + +/*! \brief Get extended phase segment 2 + * + * \param[in] obj : pointer to FlexCAN register instance + * \return: extended phase segment 2 + * + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetExtPhaseSeg2(const FlexCanRegType *obj) +{ + return ((obj->CBT & FLEXCAN_CBT_EPSEG2_MASK) >> FLEXCAN_CBT_EPSEG2_SHIFT); +} + +/*! \brief Set extended phase segment 2 + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : extended phase segment 2 + * + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetExtPhaseSeg2(FlexCanRegType *obj, uint16_t val) +{ + uint32_t tempReg; + tempReg = obj->CBT; + tempReg &= (~FLEXCAN_CBT_EPSEG2_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_CBT_EPSEG2_SHIFT) & FLEXCAN_CBT_EPSEG2_MASK; + + obj->CBT = tempReg; +} + +/*! \brief Set Rx individual mask n + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] num : number of Rx individual mask + * \param[in] mask: mask + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRxIndividualMask(FlexCanRegType *obj, uint8_t num, uint32_t mask) +{ + obj->RXIMR[num] = mask; +} + +/*! \brief Get Rx individual mask n + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] num : number of Rx individual mask + * \return : mask value + */ +__attribute__((always_inline)) static inline uint32_t FlexCanReg_GetRxIndividualMask(FlexCanRegType *obj, uint8_t num) +{ + return (obj->RXIMR[num]); +} + +/*! \brief Get bit rate switch enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : bit rate switch enable + * 0: transmit a frame in nominal rate, the BRS bit in the Tx MB has no effect + * 1: transmit a frame with bit rate switching if the BRS bit in the Tx MB is + * recessive + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFdRateSwitch(const FlexCanRegType *obj) +{ + return ((obj->FDCTRL & FLEXCAN_FDCTRL_FDRATE_MASK) >> FLEXCAN_FDCTRL_FDRATE_SHIFT); +} + +/*! \brief Set bit rate switch enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : bit rate switch enable + * 0: transmit a frame in nominal rate, the BRS bit in the Tx MB has no effect + * 1: transmit a frame with bit rate switching if the BRS bit in the Tx MB is + * recessive + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetFdRateSwitch(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->FDCTRL; + tempReg &= (~FLEXCAN_FDCTRL_FDRATE_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_FDCTRL_FDRATE_SHIFT) & FLEXCAN_FDCTRL_FDRATE_MASK; + + obj->FDCTRL = tempReg; +} + +/*! \brief Set message buffer data size for region n + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] region : region number + * \param[in] sizeSel : message buffer data size for region n + * 00: selects 8 bytes per message buffer + * 01: selects 16 bytes per message buffer + * 10: selects 32 bytes per message buffer + * 11: selects 64 bytes per message buffer + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetRegionDataSizeSel(FlexCanRegType *obj, uint8_t region, uint8_t sizeSel) +{ + uint32_t tempReg; + tempReg = obj->FDCTRL; + + switch(region) + { + case 0: + tempReg &= (~FLEXCAN_FDCTRL_MBDSR0_MASK); + tempReg |= (((uint32_t)sizeSel) << FLEXCAN_FDCTRL_MBDSR0_SHIFT) & FLEXCAN_FDCTRL_MBDSR0_MASK; + break; + case 1: + tempReg &= (~FLEXCAN_FDCTRL_MBDSR1_MASK); + tempReg |= (((uint32_t)sizeSel) << FLEXCAN_FDCTRL_MBDSR1_SHIFT) & FLEXCAN_FDCTRL_MBDSR1_MASK; + break; + case 2: + tempReg &= (~FLEXCAN_FDCTRL_MBDSR2_MASK); + tempReg |= (((uint32_t)sizeSel) << FLEXCAN_FDCTRL_MBDSR2_SHIFT) & FLEXCAN_FDCTRL_MBDSR2_MASK; + break; + case 3: + tempReg &= (~FLEXCAN_FDCTRL_MBDSR3_MASK); + tempReg |= (((uint32_t)sizeSel) << FLEXCAN_FDCTRL_MBDSR3_SHIFT) & FLEXCAN_FDCTRL_MBDSR3_MASK; + break; + default: + /* size select wrong, do something */ + break; + } + + obj->FDCTRL = tempReg; +} + +/*! \brief Get message buffer data size for region n + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] region : region number + * \return : message buffer data size for region n + * 00: selects 8 bytes per message buffer + * 01: selects 16 bytes per message buffer + * 10: selects 32 bytes per message buffer + * 11: selects 64 bytes per message buffer + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetRegionDataSizeSel(FlexCanRegType *obj, uint8_t region) +{ + uint8_t retVal = 0; + + switch(region) + { + case 0: + retVal = (uint8_t)((obj->FDCTRL & FLEXCAN_FDCTRL_MBDSR0_MASK) >> FLEXCAN_FDCTRL_MBDSR0_SHIFT); + break; + case 1: + retVal = (uint8_t)((obj->FDCTRL & FLEXCAN_FDCTRL_MBDSR1_MASK) >> FLEXCAN_FDCTRL_MBDSR1_SHIFT); + break; + case 2: + retVal = (uint8_t)((obj->FDCTRL & FLEXCAN_FDCTRL_MBDSR2_MASK) >> FLEXCAN_FDCTRL_MBDSR2_SHIFT); + break; + case 3: + retVal = (uint8_t)((obj->FDCTRL & FLEXCAN_FDCTRL_MBDSR3_MASK) >> FLEXCAN_FDCTRL_MBDSR3_SHIFT); + break; + default: + /* size select wrong, do something */ + break; + } + + return retVal; +} + +/*! \brief Get bit rate switch enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : bit rate switch enable + * 0: transmit a frame in nominal rate, the BRS bit in the Tx MB has no effect + * 1: transmit a frame with bit rate switching if the BRS bit in the Tx MB is + * recessive + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetTdcEnable(const FlexCanRegType *obj) +{ + return ((obj->FDCTRL & FLEXCAN_FDCTRL_TDCEN_MASK) >> FLEXCAN_FDCTRL_TDCEN_SHIFT); +} + +/*! \brief Set bit rate switch enable + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] enable : bit rate switch enable + * 0: transmit a frame in nominal rate, the BRS bit in the Tx MB has no effect + * 1: transmit a frame with bit rate switching if the BRS bit in the Tx MB is + * recessive + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetTdcEnable(FlexCanRegType *obj, uint8_t enable) +{ + uint32_t tempReg; + tempReg = obj->FDCTRL; + tempReg &= (~FLEXCAN_FDCTRL_TDCEN_MASK); + tempReg |= (((uint32_t)enable) << FLEXCAN_FDCTRL_TDCEN_SHIFT) & FLEXCAN_FDCTRL_TDCEN_MASK; + + obj->FDCTRL = tempReg; +} + +/*! \brief Get transceiver delay compensation fail + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : transceiver delay compensation fail + * 0: measured loop delay is in range + * 1: transmit a frame with bit rate switching if the BRS bit in the Tx MB is + * recessive + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFdctrlTdcfail(const FlexCanRegType *obj) +{ + return ((obj->FDCTRL & FLEXCAN_FDCTRL_TDCFAIL_MASK) >> FLEXCAN_FDCTRL_TDCFAIL_SHIFT); +} + +/*! \brief Clear transceiver delay compensation fail + * + * \param[in] obj : pointer to FlexCAN register instance + */ +__attribute__((always_inline)) static inline void FlexCanReg_ClearFdctrlTdcfail(FlexCanRegType *obj) +{ + uint32_t tmp = obj->FDCTRL; + + tmp |= (((uint32_t)(((uint32_t)(1)) << FLEXCAN_FDCTRL_TDCFAIL_SHIFT)) & FLEXCAN_FDCTRL_TDCFAIL_MASK); + obj->FDCTRL = tmp; +} + +/*! \brief Get transceiver delay compensation offset + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : transceiver delay compensation offset + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFdctrlTdcoff(const FlexCanRegType *obj) +{ + return ((obj->FDCTRL & FLEXCAN_FDCTRL_TDCOFF_MASK) >> FLEXCAN_FDCTRL_TDCOFF_SHIFT); +} + +/*! \brief Set transceiver delay compensation offset + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] offset : transceiver delay compensation offset + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetTdcOffset(FlexCanRegType *obj, uint8_t offset) +{ + uint32_t tempReg; + tempReg = obj->FDCTRL; + tempReg &= (~FLEXCAN_FDCTRL_TDCOFF_MASK); + tempReg |= (((uint32_t)offset) << FLEXCAN_FDCTRL_TDCOFF_SHIFT) & FLEXCAN_FDCTRL_TDCOFF_MASK; + + obj->FDCTRL = tempReg; +} + +/*! \brief Get transceiver delay compensation value + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : transceiver delay compensation value + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFdctrlTdcval(const FlexCanRegType *obj) +{ + return ((obj->FDCTRL & FLEXCAN_FDCTRL_TDCVAL_MASK) >> FLEXCAN_FDCTRL_TDCVAL_SHIFT); +} + +/*! \brief Get fast prescaler division factor + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : fast prescaler division factor + */ +__attribute__((always_inline)) static inline uint16_t FlexCanReg_GetFdPrescalerDivision(const FlexCanRegType *obj) +{ + return ((obj->FDCBT & FLEXCAN_FDCBT_FPRESDIV_MASK) >> FLEXCAN_FDCBT_FPRESDIV_SHIFT); +} + +/*! \brief Set fast prescaler division factor + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : fast prescaler division factor + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetFdPrescalerDivision(FlexCanRegType *obj, uint16_t val) +{ + uint32_t tempReg; + tempReg = obj->FDCBT; + tempReg &= (~FLEXCAN_FDCBT_FPRESDIV_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_FDCBT_FPRESDIV_SHIFT) & FLEXCAN_FDCBT_FPRESDIV_MASK; + + obj->FDCBT = tempReg; +} + +/*! \brief Get fast resync jump width + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : fast resync jump width + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFdResyncJumpWidth(const FlexCanRegType *obj) +{ + return ((obj->FDCBT & FLEXCAN_FDCBT_FRJW_MASK) >> FLEXCAN_FDCBT_FRJW_SHIFT); +} + +/*! \brief Set fast resync jump width + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : fast resync jump width + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetFdResyncJumpWidth(FlexCanRegType *obj, uint16_t val) +{ + uint32_t tempReg; + tempReg = obj->FDCBT; + tempReg &= (~FLEXCAN_FDCBT_FRJW_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_FDCBT_FRJW_SHIFT) & FLEXCAN_FDCBT_FRJW_MASK; + + obj->FDCBT = tempReg; +} + +/*! \brief Get fast propagation segment + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : fast propagation segment + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFdPorpSeg(const FlexCanRegType *obj) +{ + return ((obj->FDCBT & FLEXCAN_FDCBT_FPROPSEG_MASK) >> FLEXCAN_FDCBT_FPROPSEG_SHIFT); +} + +/*! \brief Set fast propagation segment + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : fast propagation segment + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetFdPorpSeg(FlexCanRegType *obj, uint16_t val) +{ + uint32_t tempReg; + tempReg = obj->FDCBT; + tempReg &= (~FLEXCAN_FDCBT_FPROPSEG_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_FDCBT_FPROPSEG_SHIFT) & FLEXCAN_FDCBT_FPROPSEG_MASK; + + obj->FDCBT = tempReg; +} + +/*! \brief Get fast phase segment 1 + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : fast phase segment 1 + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFdPhaseSeg1(const FlexCanRegType *obj) +{ + return ((obj->FDCBT & FLEXCAN_FDCBT_FPSEG1_MASK) >> FLEXCAN_FDCBT_FPSEG1_SHIFT); +} + +/*! \brief Set fast phase segment 1 + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : fast phase segment 1 + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetFdPhaseSeg1(FlexCanRegType *obj, uint16_t val) +{ + uint32_t tempReg; + tempReg = obj->FDCBT; + tempReg &= (~FLEXCAN_FDCBT_FPSEG1_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_FDCBT_FPSEG1_SHIFT) & FLEXCAN_FDCBT_FPSEG1_MASK; + + obj->FDCBT = tempReg; +} + +/*! \brief Get fast phase segment 2 + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : fast phase segment 2 + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFdPhaseSeg2(const FlexCanRegType *obj) +{ + return ((obj->FDCBT & FLEXCAN_FDCBT_FPSEG2_MASK) >> FLEXCAN_FDCBT_FPSEG2_SHIFT); +} + +/*! \brief Set fast phase segment 2 + * + * \param[in] obj : pointer to FlexCAN register instance + * \param[in] val : fast phase segment 2 + */ +__attribute__((always_inline)) static inline void FlexCanReg_SetFdPhaseSeg2(FlexCanRegType *obj, uint16_t val) +{ + uint32_t tempReg; + tempReg = obj->FDCBT; + tempReg &= (~FLEXCAN_FDCBT_FPSEG2_MASK); + tempReg |= (((uint32_t)val) << FLEXCAN_FDCBT_FPSEG2_SHIFT) & FLEXCAN_FDCBT_FPSEG2_MASK; + + obj->FDCBT = tempReg; +} + +/*! \brief Get crc mailbox number for FD_TXCRC + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : crc mailbox number for FD_TXCRC + */ +__attribute__((always_inline)) static inline uint8_t FlexCanReg_GetFdcrcFdmbcrc(const FlexCanRegType *obj) +{ + return ((obj->FDCRC & CAN_FDCRC_FDMBCRC_MASK) >> CAN_FDCRC_FDMBCRC_SHIFT); +} + +/*! \brief Get extended transmitted CRC value + * + * \param[in] obj : pointer to FlexCAN register instance + * \return : extended transmitted CRC value + */ +__attribute__((always_inline)) static inline uint32_t FlexCanReg_GetFdcrcFdtxcrc(const FlexCanRegType *obj) +{ + return ((obj->FDCRC & CAN_FDCRC_FDTXCRC_MASK) >> CAN_FDCRC_FDTXCRC_SHIFT); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _FLEXCAN_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/ftfc_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/ftfc_reg.h new file mode 100644 index 0000000..3fc7231 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/ftfc_reg.h @@ -0,0 +1,994 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FTFC_REG_H_ +#define _FTFC_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the FTFC Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* FSTAT Bit Fields */ +#define FTFC_FSTAT_CCI_CLR_MASK (0x10000u) /*!FSTAT = tmp; +} + +/*! \brief Gets the flash eee state page error flag + * + * This function gets the current flash eee state page error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash eee state page error flag + * - 0b : eee state pasges ok + * - 1b : eee state pasges error + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatEeeStpgErrF(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_EEE_SPERR_MASK) >> FTFC_FSTAT_EEE_SPERR_SHIFT); +} + +/*! \brief Sets the emulated eeprom full level overflow flag + * + * This function sets the emulated eeprom full level overflow flag. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of emulated eeprom full level overflow flag + * - 0b : no effect + * - 1b : clear the flag + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFstatEeeFlov(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = 0; + tmp = (((uint32_t)(((uint32_t)(value)) << FTFC_FSTAT_EEE_FLOV_SHIFT)) & FTFC_FSTAT_EEE_FLOV_MASK); + obj->FSTAT = tmp; +} + +/*! \brief Gets the emulated eeprom full level overflow flag + * + * This function gets the current emulated eeprom full level overflow flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return the emulated eeprom full level overflow flag + * - 0b : eee write pointer under full level + * - 1b : eee write pointer reach/over full level + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatEeeFlov(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_EEE_FLOV_MASK) >> FTFC_FSTAT_EEE_FLOV_SHIFT); +} + +/*! \brief Gets the emulated eeprom threshold level overflow flag + * + * This function gets the current emulated eeprom threshold level overflow flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return the emulated eeprom threshold level overflow flag + * - 0b : eee write pointer under threshold level + * - 1b : eee write pointer reach/over threshold level + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatEeeTlov(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_EEE_TLOV_MASK) >> FTFC_FSTAT_EEE_TLOV_SHIFT); +} + +/*! \brief Sets the emulated eeprom threshold level overflow flag + * + * This function sets the emulated eeprom threshold level overflow flag. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of emulated eeprom threshold level overflow flag + * - 0b : no effect + * - 1b : clear the flag + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFstatEeeTlov(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = 0; + tmp = (((uint32_t)(((uint32_t)(value)) << FTFC_FSTAT_EEE_TLOV_SHIFT)) & FTFC_FSTAT_EEE_TLOV_MASK); + obj->FSTAT = tmp; +} + +/*! \brief Sets the flash eee state page error flag + * + * This function sets the flash eee state page error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash eee state page error flag + * - 0b : no effect + * - 1b : clear the flag + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFstatStpgErrF(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = 0; + tmp = (((uint32_t)(((uint32_t)(value)) << FTFC_FSTAT_EEE_SPERR_SHIFT)) & FTFC_FSTAT_EEE_SPERR_MASK); + obj->FSTAT = tmp; +} + +/*! \brief Gets the ram ready flag + * + * This function gets the current ram ready flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return ram ready flag + * - 0b : flexram is not ready for system ram + * - 1b : flexram is ready for system ram + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatRamRdy(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_RAMRDY_MASK) >> FTFC_FSTAT_RAMRDY_SHIFT); +} + +/*! \brief Gets the eee_ram ready flag + * + * This function gets the current eee_ram ready flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return eee_ram ready flag + * - 0b : flexram is not ready for eee_ram + * - 1b : flexram is ready for eee_ram + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatEeeRamRdy(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_EEERDY_MASK) >> FTFC_FSTAT_EEERDY_SHIFT); +} + +/*! \brief Gets the flash loader error flag + * + * This function gets the current flash loader error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash loader error flag + * - 0b : flash loader no error + * - 1b : flash loader error + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatFlErrF(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_FL_ERRF_MASK) >> FTFC_FSTAT_FL_ERRF_SHIFT); +} + +/*! \brief Gets the flash loader done flag + * + * This function gets the current flash loader done flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash loader done flag + * - 0b : flash loader is not done + * - 1b : flash loader is done + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatFlDone(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_FL_DONE_MASK) >> FTFC_FSTAT_FL_DONE_SHIFT); +} + +/*! \brief Gets the flash erase sector flag + * + * This function gets the current flash erase sector flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash erase sector flag + * - 0b : not erasing sector + * - 1b : erasing sector + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatErsSctF(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_ERSA_REQ_MASK) >> FTFC_FSTAT_ERSA_REQ_SHIFT); +} + +/*! \brief Gets the flash command complete flag + * + * This function gets the current flash command complete flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return ftfc command complete flag + * - 0b : not completed + * - 1b : completed + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatCcif(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_CCIF_MASK) >> FTFC_FSTAT_CCIF_SHIFT); +} + +/*! \brief Sets the flash command complete flag + * + * This function sets the flash command complete flag. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash command complete flag + * - 0b : no effect + * - 1b : clear the flag + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFstatCcif(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = 0; + tmp = (((uint32_t)(((uint32_t)(value)) << FTFC_FSTAT_CCIF_SHIFT)) & FTFC_FSTAT_CCIF_MASK); + obj->FSTAT = tmp; +} + +/*! \brief Gets the flash read collide error flag + * + * This function gets the current flash read collide error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash read collide error flag + * - 0b : not collide + * - 1b : collided + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatRdColF(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_RDCOLERR_MASK) >> FTFC_FSTAT_RDCOLERR_SHIFT); +} + +/*! \brief Sets the flash read collide error flag + * + * This function sets the flash read collide error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash read collide error flag + * - 0b : no effect + * - 1b : clear the flag + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFstatRdColF(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = 0; + tmp = (((uint32_t)(((uint32_t)(value)) << FTFC_FSTAT_RDCOLERR_SHIFT)) & FTFC_FSTAT_RDCOLERR_MASK); + obj->FSTAT = tmp; +} + +/*! \brief Gets the flash command configuration error flag + * + * This function gets the current flash command configuration error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash command configuration error flag + * - 0b : no command configuration error + * - 1b : command configuration error has occurred + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatAccErrF(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_ACCERR_MASK) >> FTFC_FSTAT_ACCERR_SHIFT); +} + +/*! \brief Sets the flash command configuration error flag + * + * This function sets the flash command configuration error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash command configuration error flag + * - 0b : no effect + * - 1b : clear the flag + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFstatAccErrF(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = 0; + tmp = (((uint32_t)(((uint32_t)(value)) << FTFC_FSTAT_ACCERR_SHIFT)) & FTFC_FSTAT_ACCERR_MASK); + obj->FSTAT = tmp; +} + +/*! \brief Gets the flash protection violation error flag + * + * This function gets the current flash protection violation error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash protection violation error flag + * - 0b : not violation + * - 1b : violation + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatProtViolF(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_PVIOL_MASK) >> FTFC_FSTAT_PVIOL_SHIFT); +} + +/*! \brief Sets the flash protection violation error flag + * + * This function sets the flash protection violation error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash protection violation error flag + * - 0b : no effect + * - 1b : clear the flag + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFstatProtViolF(FtfcRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid + * side-effects */ + uint32_t tmp = 0; + tmp = (((uint32_t)(((uint32_t)(value)) << FTFC_FSTAT_PVIOL_SHIFT)) & FTFC_FSTAT_PVIOL_MASK); + obj->FSTAT = tmp; +} + +/*! \brief Gets the flash ecc sec error flag + * + * This function gets the current flash ecc sec error flag. + * presents whether flash happens ecc sec error + * + * \param[in] obj : pointer to FTFC register instance + * \return flash ecc sec error flag + * - 0b : not ecc sec error + * - 1b : ecc sec error + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatSecF(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_SECF_MASK) >> FTFC_FSTAT_SECF_SHIFT); +} + +/*! \brief Sets the flash ecc sec error flag + * + * This function sets the flash ecc sec error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash ecc sec error flag + * - 0b : no effect + * - 1b : clear the flag + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFstatSecF(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = 0; + tmp = (((uint32_t)(((uint32_t)(value)) << FTFC_FSTAT_SECF_SHIFT)) & FTFC_FSTAT_SECF_MASK); + obj->FSTAT = tmp; +} + +/*! \brief Gets the ftfc ecc ded error flag + * + * This function gets the current ftfc ecc ded error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return ftfc ecc ded error flag + * - 0b : not ecc ded error + * - 1b : ecc ded error + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatDedF(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_DEDF_MASK) >> FTFC_FSTAT_DEDF_SHIFT); +} + +/*! \brief Sets the flash ecc ded error flag + * + * This function sets the flash ecc ded error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash ecc ded error flag + * - 0b : no effect + * - 1b : clear the flag + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFstatDedF(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = 0; + tmp = (((uint32_t)(((uint32_t)(value)) << FTFC_FSTAT_DEDF_SHIFT)) & FTFC_FSTAT_DEDF_MASK); + obj->FSTAT = tmp; +} + +/*! \brief Gets the flash ahb bus response error flag + * + * This function gets the current flash ahb bus response error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash ahb bus response error flag + * - 0b : no response error + * - 1b : response error occurred + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatRspErrF(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_RSPERR_MASK) >> FTFC_FSTAT_RSPERR_SHIFT); +} + +/*! \brief Sets the flash ahb bus response error flag + * + * This function sets the current flash ahb bus response error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash ecc sec error flag + * - 0b : no effect + * - 1b : clear the flag + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFstatRspErrF(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = 0; + tmp = (((uint32_t)(((uint32_t)(value)) << FTFC_FSTAT_RSPERR_SHIFT)) & FTFC_FSTAT_RSPERR_MASK); + obj->FSTAT = tmp; +} + +/*! \brief Gets the flash command run error flag + * + * This function gets the current flash command run error flag. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash command run error flag + * - 0b : no run error + * - 1b : run error has happened + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFstatMgStat(const FtfcRegType *obj) +{ + return ((obj->FSTAT & FTFC_FSTAT_MGSTAT0_MASK) >> FTFC_FSTAT_MGSTAT0_SHIFT); +} + +/*! \brief Gets the flash ahb bus read access time + * + * This function gets the current flash ahb bus read access time. + * + * \param[in] obj : pointer to FTFC register instance + * \return the flash ahb bus read access time(T presents one cycle of ahb bus clock, requires "n*T >= 20.83ns" ) + * - 0h : 1T + * - 1h : 2T + * - 2h : 3T + * - 3h : 4T + * - 4h : 5T + * - 5h : 6T + * - 6h : 7T + * - 7h : 8T + * - 8h : 9T + * - 9h : 10T + * - Ah : 11T + * - Bh : 12T + * - Ch : 13T + * - Dh : 14T + * - Eh : 15T + * - Fh : 16T + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFcnfgBusReadTm(const FtfcRegType *obj) +{ + return ((obj->FCNFG & FTFC_FCNFG_BUSRD_T_MASK) >> FTFC_FCNFG_BUSRD_T_SHIFT); +} + +/*! \brief Sets the flash ahb bus read access time + * + * This function gets the current flash ahb bus read access time. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash ahb bus read access time + * (T presents one cycle of ahb bus clock, requires "n*T >= 20.83ns" ) + * - 0h : 1T + * - 1h : 2T + * - 2h : 3T + * - 3h : 4T + * - 4h : 5T + * - 5h : 6T + * - 6h : 7T + * - 7h : 8T + * - 8h : 9T + * - 9h : 10T + * - Ah : 11T + * - Bh : 12T + * - Ch : 13T + * - Dh : 14T + * - Eh : 15T + * - Fh : 16T + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFcnfgBusReadTm(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FCNFG; + + tmp &= ~FTFC_FCNFG_BUSRD_T_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FTFC_FCNFG_BUSRD_T_SHIFT)) & FTFC_FCNFG_BUSRD_T_MASK); + obj->FCNFG = tmp; +} + +/*! \brief Gets the erase sector suspend + * + * This function gets the current erase sector suspend. + * + * \param[in] obj : pointer to FTFC register instance + * \return erase sector suspend + * - 0b : not suspend + * - 1b : suspend + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFcnfgErsSus(const FtfcRegType *obj) +{ + return ((obj->FCNFG & FTFC_FCNFG_ERS_SUS_MASK) >> FTFC_FCNFG_ERS_SUS_SHIFT); +} + +/*! \brief Sets the erase sector suspend + * + * This function sets the erase sector suspend. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of erase sector suspend + * - 0b : not suspend + * - 1b : suspend + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFcnfgErsSus(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FCNFG; + + tmp &= ~FTFC_FCNFG_ERS_SUS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FTFC_FCNFG_ERS_SUS_SHIFT)) & FTFC_FCNFG_ERS_SUS_MASK); + obj->FCNFG = tmp; +} + +/*! \brief Gets the bus error response interrupt enable + * + * This function gets the current bus error response interrupt enable. + * + * \param[in] obj : pointer to FTFC register instance + * \return bus error response interrupt enable + * - 0b : disable interupt + * - 1b : enable interrupt + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFcnfgRspErrIE(const FtfcRegType *obj) +{ + return ((obj->FCNFG & FTFC_FCNFG_RSP_ERR_IE_MASK) >> FTFC_FCNFG_RSP_ERR_IE_SHIFT); +} + +/*! \brief Sets the bus error response interrupt enable + * + * This function sets the bus error response interrupt enable. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of bus error response interrupt enable + * - 0b : disable interupt + * - 1b : enable interrupt + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFcnfgRspErrIE(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FCNFG; + + tmp &= ~FTFC_FCNFG_RSP_ERR_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FTFC_FCNFG_RSP_ERR_IE_SHIFT)) & FTFC_FCNFG_RSP_ERR_IE_MASK); + obj->FCNFG = tmp; +} + +/*! \brief Gets the flash command complete interrupt enable + * + * This function gets the current flash command complete interrupt enable. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash command complete interrupt enable + * - 0b : disable interupt + * - 1b : enable interrupt + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFcnfgCcifIE(const FtfcRegType *obj) +{ + return ((obj->FCNFG & FTFC_FCNFG_CCIF_IE_MASK) >> FTFC_FCNFG_CCIF_IE_SHIFT); +} + +/*! \brief Sets the flash command complete interrupt enable + * + * This function sets the flash command complete interrupt enable. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash command complete interrupt enable + * - 0b : disable interupt + * - 1b : enable interrupt + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFcnfgCcifIE(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FCNFG; + + tmp &= ~FTFC_FCNFG_CCIF_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FTFC_FCNFG_CCIF_IE_SHIFT)) & FTFC_FCNFG_CCIF_IE_MASK); + obj->FCNFG = tmp; +} + +/*! \brief Gets the flash read collide interrupt enable + * + * This function gets the current flash read collide interrupt enable. + * + * \param[in] obj : pointer to FTFC register instance + * \return flash read collide interrupt enable + * - 0b : disable interupt + * - 1b : enable interrupt + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFcnfgRdColIE(const FtfcRegType *obj) +{ + return ((obj->FCNFG & FTFC_FCNFG_RDCOL_IE_MASK) >> FTFC_FCNFG_RDCOL_IE_SHIFT); +} + +/*! \brief Sets the flash read collide interrupt enable + * + * This function sets the flash read collide interrupt enable. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of flash read collide interrupt enable + * - 0b : disable interupt + * - 1b : enable interrupt + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFcnfgRdColIE(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FCNFG; + + tmp &= ~FTFC_FCNFG_RDCOL_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FTFC_FCNFG_RDCOL_IE_SHIFT)) & FTFC_FCNFG_RDCOL_IE_MASK); + obj->FCNFG = tmp; +} + +/*! \brief Gets the verify backdoor key enable + * + * This function gets the current verify backdoor key enable. + * + * \param[in] obj : pointer to FTFC register instance + * \return verify backdoor key enable + * - 00b : disable + * - 01b : disable + * - 10b : enable + * - 11b : disable + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFsecKeyEn(const FtfcRegType *obj) +{ + return ((obj->FSEC & FTFC_FSEC_KEYEN_MASK) >> FTFC_FSEC_KEYEN_SHIFT); +} + +/*! \brief Gets the mass erase enable + * + * This function gets the current mass erase enable. + * + * \param[in] obj : pointer to FTFC register instance + * \return mass erase enable + * - 00b : enable + * - 01b : enable + * - 10b : disable + * - 11b : enable + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFsecMeen(const FtfcRegType *obj) +{ + return ((obj->FSEC & FTFC_FSEC_MEEN_MASK) >> FTFC_FSEC_MEEN_SHIFT); +} + +/*! \brief Gets the secure setting + * + * This function gets the current secure setting. + * + * \param[in] obj : pointer to FTFC register instance + * \return secure setting + * - 0b : unsecure + * - 1b : secure + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFsecSecure(const FtfcRegType *obj) +{ + return ((obj->FSEC & FTFC_FSEC_SECURE_MASK) >> FTFC_FSEC_SECURE_SHIFT); +} + +/*! \brief Gets the pflash protection setting + * + * This function gets the current pflash protection setting. + * + * \param[in] obj : pointer to FTFC register instance + * \return pflash protection setting + * - 0b : unprotect + * - 1b : protect + */ +__attribute__((always_inline)) static inline uint32_t FtfcReg_GetPfProtecion(const FtfcRegType *obj) +{ + return ((obj->PFPROT & FTFC_PFPROT_PFPROT_MASK) >> FTFC_PFPROT_PFPROT_SHIFT); +} + +/*! \brief Sets the pflash protection setting + * + * This function sets the pflash protection setting. + * pflash protection bits can only change from 0(unprotection) to 1(protection) + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of pflash protection setting + * - 0b : unprotect + * - 1b : protect + */ +__attribute__((always_inline)) static inline void FtfcReg_SetPfProtecion(FtfcRegType *obj, + uint32_t value) +{ + uint32_t tmp = obj->PFPROT; + + tmp &= ~FTFC_PFPROT_PFPROT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FTFC_PFPROT_PFPROT_SHIFT)) & FTFC_PFPROT_PFPROT_MASK); + obj->PFPROT = tmp; +} + +/*! \brief Gets the dflash protection setting + * + * This function gets the current dflash protection setting. + * + * \param[in] obj : pointer to FTFC register instance + * \return dflash protection setting + * - 0b : unprotect + * - 1b : protect + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetDfProtecion(const FtfcRegType *obj) +{ + return ((obj->DFPROT & FTFC_DFPROT_DFPROT_MASK) >> FTFC_DFPROT_DFPROT_SHIFT); +} + +/*! \brief Sets the dflash protection setting + * + * This function sets the dflash protection setting. + * dflash protection bits can only change from 0 to 1, unprotection to + * protection; + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of dflash protection setting + * - 0b : unprotect + * - 1b : protect + */ +__attribute__((always_inline)) static inline void FtfcReg_SetDfProtection(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DFPROT; + + tmp &= ~FTFC_DFPROT_DFPROT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FTFC_DFPROT_DFPROT_SHIFT)) & FTFC_DFPROT_DFPROT_MASK); + obj->DFPROT = tmp; +} + +/*! \brief Gets the eee_ram protection setting + * + * This function gets the current eee_ram protection setting. + * + * \param[in] obj : pointer to FTFC register instance + * \return eee_ram protection setting + * - 0b : unprotect + * - 1b : protect + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetEfProtecion(const FtfcRegType *obj) +{ + return ((obj->EFPROT & FTFC_EFPROT_EFPROT_MASK) >> FTFC_EFPROT_EFPROT_SHIFT); +} + +/*! \brief Sets the eee_ram protection setting + * + * This function sets the eee_ram protection setting. + * eee_ram protection bits can only change from 0 to 1, unprotection to + * protection; + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] value : the value of eee_ram protection setting + * - 0b : unprotect + * - 1b : protect + */ +__attribute__((always_inline)) static inline void FtfcReg_SetEfProtection(FtfcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EFPROT; + + tmp &= ~FTFC_EFPROT_EFPROT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << FTFC_EFPROT_EFPROT_SHIFT)) & FTFC_EFPROT_EFPROT_MASK); + obj->EFPROT = tmp; +} + +/*! \brief Gets the flash common command object + * + * This function gets the current flash common command object. + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] index : the index of command object + * - 0 : FCCOB0 + * - 1 : FCCOB1 + * - 2 : FCCOB2 + * - 3 : FCCOB3 + * - 4 : FCCOB4 + * - 5 : FCCOB5 + * - 6 : FCCOB6 + * - 7 : FCCOB7 + * - 8 : FCCOB8 + * - 9 : FCCOB9 + * - 10 : FCCOBa + * - 11 : FCCOBb + * - 12 : FCCOBc + * - 13 : FCCOBd + * - 14 : FCCOBe + * - 15 : FCCOBf + * \return flash common command object + */ +__attribute__((always_inline)) static inline uint8_t FtfcReg_GetFccob(const FtfcRegType *obj, uint8_t index) +{ + uint8_t retval = 0; + + retval = obj->FCCOB[index]; + + return retval; +} + +/*! \brief Sets the flash common command object + * + * This function sets the flash common command object. + * when CCIF=0, can not modify this register; + * + * \param[in] obj : pointer to FTFC register instance + * \param[in] index : the index of command object + * - 0 : FCCOB0 + * - 1 : FCCOB1 + * - 2 : FCCOB2 + * - 3 : FCCOB3 + * - 4 : FCCOB4 + * - 5 : FCCOB5 + * - 6 : FCCOB6 + * - 7 : FCCOB7 + * - 8 : FCCOB8 + * - 9 : FCCOB9 + * - 10 : FCCOBa + * - 11 : FCCOBb + * - 12 : FCCOBc + * - 13 : FCCOBd + * - 14 : FCCOBe + * - 15 : FCCOBf + * \param[in] value : the value of flash common command object + */ +__attribute__((always_inline)) static inline void FtfcReg_SetFccob(FtfcRegType *obj, uint8_t index, uint8_t value) +{ + uint32_t tmp = 0; + uint32_t mask = 0xff; + tmp = obj->FCCOB[index]; + tmp &= ~mask; + tmp |= ((uint8_t)(value)&mask); + obj->FCCOB[index] = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _FTFC_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/gpio_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/gpio_reg.h new file mode 100644 index 0000000..44fecdb --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/gpio_reg.h @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _GPIO_REG_H_ +#define _GPIO_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the GPIO Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of GPIO registers + */ +typedef struct _GpioRegType_ +{ + volatile uint32_t PDOR; /*!< Port data output, offset: 0x00 */ + volatile uint32_t PSOR; /*!< Port Set Output, offset: 0x04 */ + volatile uint32_t PCOR; /*!< Port clear output, offset: 0x08 */ + volatile uint32_t PTOR; /*!< Port toggle output, offset: 0x0C */ + const volatile uint32_t PDIR; /*!< Port data input, offset: 0x10 */ + volatile uint32_t PDDR; /*!< Port data direction, offset: 0x14 */ + volatile uint32_t PIDR; /*!< Port input disable, offset: 0x18 */ +} GpioRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the Port Data Output + * + * This function gets the current Port Data Output. + * Register bits for unbonded pins return an undefined value when read. + * + * \param[in] obj : pointer to GPIO register instance + * \return Port Data Output + * - 0b : Logic level 0 is driven on pin, provided pin is configured for general-purpose output. + * - 1b : Logic level 1 is driven on pin, provided pin is configured for general-purpose output. + */ +__attribute__((always_inline)) static inline uint32_t GpioReg_GetPdorDatOut(const GpioRegType *obj) +{ + return obj->PDOR; +} + +/*! \brief Sets the Port Data Output + * + * This function sets the Port Data Output. + * Register bits for unbonded pins return an undefined value when read. + * + * \param[in] obj : pointer to GPIO register instance + * \param[in] value : the value of Port Data Output + * - 0b : Logic level 0 is driven on pin, provided pin is configured for general-purpose output. + * - 1b : Logic level 1 is driven on pin, provided pin is configured for general-purpose output. + */ +__attribute__((always_inline)) static inline void GpioReg_SetPdorDatOut(GpioRegType *obj, uint32_t value) +{ + obj->PDOR = value; +} + +/*! \brief Sets the Port Set Output + * + * This function sets the Port Set Output. + * Writing to this register updates the contents of the corresponding bit in the PDOR + * + * \param[in] obj : pointer to GPIO register instance + * \param[in] value : the value of Port Set Output + * - 0b : Corresponding bit in PDORn does not change. + * - 1b : Corresponding bit in PDORn is set to logic 1. + */ +__attribute__((always_inline)) static inline void GpioReg_SetPsorDatSet(GpioRegType *obj, uint32_t value) +{ + obj->PSOR = value; +} + +/*! \brief Sets the Port Clear Output + * + * This function sets the Port Clear Output. + * Writing to this register updates the contents of the corresponding bit in the Port Data Output Register (PDOR) + * + * \param[in] obj : pointer to GPIO register instance + * \param[in] value : the value of Port Clear Output + * - 0b : Corresponding bit in PDORn does not change. + * - 1b : Corresponding bit in PDORn is cleared to logic 0. + */ +__attribute__((always_inline)) static inline void GpioReg_SetPcorDatClr(GpioRegType *obj, uint32_t value) +{ + obj->PCOR = value; +} + +/*! \brief Sets the Port Toggle Output + * + * This function sets the Port Toggle Output. + * Writing to this register updates the contents of the corresponding bit in the PDOR + * + * \param[in] obj : pointer to GPIO register instance + * \param[in] value : the value of Port Toggle Output + * - 0b : Corresponding bit in PDORn does not change. + * - 1b : Corresponding bit in PDORn is set to the inverse of its existing logic state. + */ +__attribute__((always_inline)) static inline void GpioReg_SetPtorDatTog(GpioRegType *obj, uint32_t value) +{ + obj->PTOR = value; +} + +/*! \brief Gets the Port Data Input + * + * This function gets the current Port Data Input. + * Reads 0 at the unimplemented pins for a particular device. + * Pins that are not configured for a digital function read 0. + * If the Port Control and Interrupt module is disabled, then the corresponding bit in PDIR does not update. + * + * \param[in] obj : pointer to GPIO register instance + * \return Port Data Input + * - 0b : Pin logic level is logic 0, or is not configured for use by digital function. + * - 1b : Pin logic level is logic 1. + */ +__attribute__((always_inline)) static inline uint32_t GpioReg_GetPdirDatIn(const GpioRegType *obj) +{ + return obj->PDIR; +} + +/*! \brief Gets the Port Data Direction + * + * This function gets the current Port Data Direction. + * Configures individual port pins for input or output. + * + * \param[in] obj : pointer to GPIO register instance + * \return Port Data Direction + * - 0b : Pin is configured as general-purpose input, for the GPIO function. + * The pin will be high-Z if the port input is disabled in GPIOx_PIDR register. + * - 1b : Pin is configured as general-purpose output, for the GPIO function. + */ +__attribute__((always_inline)) static inline uint32_t GpioReg_GetPddrDir(const GpioRegType *obj) +{ + return obj->PDDR; +} + +/*! \brief Sets the Port Data Direction + * + * This function sets the Port Data Direction. + * Configures individual port pins for input or output. + * + * \param[in] obj : pointer to GPIO register instance + * \param[in] value : the value of Port Data Direction + * - 0b : Pin is configured as general-purpose input, for the GPIO function. + * The pin will be high-Z if the port input is disabled in GPIOx_PIDR register. + * - 1b : Pin is configured as general-purpose output, for the GPIO function. + */ +__attribute__((always_inline)) static inline void GpioReg_SetPddrDir(GpioRegType *obj, uint32_t value) +{ + obj->PDDR = value; +} + +/*! \brief Gets the Port Input Disable + * + * This function gets the current Port Input Disable. + * + * \param[in] obj : pointer to GPIO register instance + * \return Port Input Disable + * - 0b : Pin is configured for General Purpose Input, provided the pin is configured for any digital function. + * - 1b : Pin is not configured as General Purpose Input. Corresponding Port Data Input Register bit will read zero. + */ +__attribute__((always_inline)) static inline uint32_t GpioReg_GetPidrInDisable(const GpioRegType *obj) +{ + return obj->PIDR; +} + +/*! \brief Sets the Port Input Disable + * + * This function sets the Port Input Disable. + * + * \param[in] obj : pointer to GPIO register instance + * \param[in] value : the value of Port Input Disable + * - 0b : Pin is configured for General Purpose Input, provided the pin is configured for any digital function. + * - 1b : Pin is not configured as General Purpose Input. Corresponding Port Data Input Register bit will read zero. + */ +__attribute__((always_inline)) static inline void GpioReg_SetPidrInDisable(GpioRegType *obj, uint32_t value) +{ + obj->PIDR = value; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _GPIO_REG_H_ */ \ No newline at end of file diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/i2c_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/i2c_reg.h new file mode 100644 index 0000000..33c2268 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/i2c_reg.h @@ -0,0 +1,1558 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _I2C_REG_H_ +#define _I2C_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of I2C module + */ + +/****************************************************************************** + * the includes + *****************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * the defines + *****************************************************************************/ + +/* CTRL Bit fields */ +#define I2C_CTRL_MST_MODE_MASK (0x00000001ul) +#define I2C_CTRL_MST_MODE_SHIFT (0u) + +#define I2C_CTRL_SPEED_MASK (0x00000006ul) +#define I2C_CTRL_SPEED_SHIFT (1u) + +#define I2C_CTRL_SLV_ADDR_MODE_MASK (0x00000008ul) +#define I2C_CTRL_SLV_ADDR_MODE_SHIFT (3u) + +#define I2C_CTRL_MST_ADDR_MODE_MASK (0x00000010ul) +#define I2C_CTRL_MST_ADDR_MODE_SHIFT (4u) + +#define I2C_CTRL_RESTART_EN_MASK (0x00000020ul) +#define I2C_CTRL_RESTART_EN_SHIFT (5u) + +#define I2C_CTRL_SLAVE_DISABLE_MASK (0x00000040ul) +#define I2C_CTRL_SLAVE_DISABLE_SHIFT (6u) + +#define I2C_CTRL_STOP_DET_IFADDRESSED_MASK (0x00000080ul) +#define I2C_CTRL_STOP_DET_IFADDRESSED_SHIFT (7u) + +#define I2C_CTRL_TX_EMPTY_CTRL_MASK (0x00000100ul) +#define I2C_CTRL_TX_EMPTY_CTRL_SHIFT (8u) + +/* TAR Bit fields */ +#define I2C_TAR_TAR_MASK (0x000003FFul) +#define I2C_TAR_TAR_SHIFT (0u) + +#define I2C_TAR_GC_OR_START_MASK (0x00000400ul) +#define I2C_TAR_GC_OR_START_SHIFT (10u) + +#define I2C_TAR_SPECIAL_MASK (0x00000800ul) +#define I2C_TAR_SPECIAL_SHIFT (11u) + +/* SAR Bit fields */ +#define I2C_SAR_SAR_MASK (0x000003FFul) +#define I2C_SAR_SAR_SHIFT (0u) + +/* DATA_CMD Bit fields */ +#define I2C_DATA_CMD_DATA_MASK (0x000000FFul) +#define I2C_DATA_CMD_DATA_SHIFT (0u) + +#define I2C_DATA_CMD_CMD_MASK (0x00000100ul) +#define I2C_DATA_CMD_CMD_SHIFT (8u) + +/* XX_SCL_XXX_CNT Bit fields */ +#define I2C_XX_SCL_XXX_CNT_COUNTER_MASK (0x0000FFFFul) +#define I2C_XX_SCL_XXX_CNT_COUNTER_SHIFT (0u) + +/* INTR_STAT Bit fields */ +#define I2C_INTR_STAT_RX_UNDER_MASK (0x00000001ul) +#define I2C_INTR_STAT_RX_UNDER_SHIFT (0u) + +#define I2C_INTR_STAT_RX_OVER_MASK (0x00000002ul) +#define I2C_INTR_STAT_RX_OVER_SHIFT (1u) + +#define I2C_INTR_STAT_RX_FULL_MASK (0x00000004ul) +#define I2C_INTR_STAT_RX_FULL_SHIFT (2u) + +#define I2C_INTR_STAT_TX_OVER_MASK (0x00000008ul) +#define I2C_INTR_STAT_TX_OVER_SHIFT (3u) + +#define I2C_INTR_STAT_TX_EMPTY_MASK (0x00000010ul) +#define I2C_INTR_STAT_TX_EMPTY_SHIFT (4u) + +#define I2C_INTR_STAT_RD_REQ_MASK (0x00000020ul) +#define I2C_INTR_STAT_RD_REQ_SHIFT (5u) + +#define I2C_INTR_STAT_TX_ABRT_MASK (0x00000040ul) +#define I2C_INTR_STAT_TX_ABRT_SHIFT (6u) + +#define I2C_INTR_STAT_RX_DONE_MASK (0x00000080ul) +#define I2C_INTR_STAT_RX_DONE_SHIFT (7u) + +#define I2C_INTR_STAT_ACTIVITY_MASK (0x00000100ul) +#define I2C_INTR_STAT_ACTIVITY_SHIFT (8u) + +#define I2C_INTR_STAT_STOP_DET_MASK (0x00000200ul) +#define I2C_INTR_STAT_STOP_DET_SHIFT (9u) + +#define I2C_INTR_STAT_START_DET_MASK (0x00000400ul) +#define I2C_INTR_STAT_START_DET_SHIFT (10u) + +#define I2C_INTR_STAT_GEN_CALL_MASK (0x00000800ul) +#define I2C_INTR_STAT_GEN_CALL_SHIFT (11u) + +#define I2C_INTR_STAT_RESTART_DET_MASK (0x00001000ul) +#define I2C_INTR_STAT_RESTART_DET_SHIFT (12u) + +#define I2C_INTR_STAT_MASTER_ON_HOLD_MASK (0x00002000ul) +#define I2C_INTR_STAT_MASTER_ON_HOLD_SHIFT (13u) + +#define I2C_INTR_STAT_SCL_STUCK_AT_LOW_MASK (0x00004000ul) +#define I2C_INTR_STAT_SCL_STUCK_AT_LOW_SHIFT (14u) + +/* INTR_MASK Bit fields */ +#define I2C_INTR_MASK_RX_UNDER_MASK (0x00000001ul) +#define I2C_INTR_MASK_RX_UNDER_SHIFT (0u) + +#define I2C_INTR_MASK_RX_OVER_MASK (0x00000002ul) +#define I2C_INTR_MASK_RX_OVER_SHIFT (1u) + +#define I2C_INTR_MASK_RX_FULL_MASK (0x00000004ul) +#define I2C_INTR_MASK_RX_FULL_SHIFT (2u) + +#define I2C_INTR_MASK_TX_OVER_MASK (0x00000008ul) +#define I2C_INTR_MASK_TX_OVER_SHIFT (3u) + +#define I2C_INTR_MASK_TX_EMPTY_MASK (0x00000010ul) +#define I2C_INTR_MASK_TX_EMPTY_SHIFT (4u) + +#define I2C_INTR_MASK_RD_REQ_MASK (0x00000020ul) +#define I2C_INTR_MASK_RD_REQ_SHIFT (5u) + +#define I2C_INTR_MASK_TX_ABRT_MASK (0x00000040ul) +#define I2C_INTR_MASK_TX_ABRT_SHIFT (6u) + +#define I2C_INTR_MASK_RX_DONE_MASK (0x00000080ul) +#define I2C_INTR_MASK_RX_DONE_SHIFT (7u) + +#define I2C_INTR_MASK_ACTIVITY_MASK (0x00000100ul) +#define I2C_INTR_MASK_ACTIVITY_SHIFT (8u) + +#define I2C_INTR_MASK_STOP_DET_MASK (0x00000200ul) +#define I2C_INTR_MASK_STOP_DET_SHIFT (9u) + +#define I2C_INTR_MASK_START_DET_MASK (0x00000400ul) +#define I2C_INTR_MASK_START_DET_SHIFT (10u) + +#define I2C_INTR_MASK_GEN_CALL_MASK (0x00000800ul) +#define I2C_INTR_MASK_GEN_CALL_SHIFT (11u) + +#define I2C_INTR_MASK_RESTART_DET_MASK (0x00001000ul) +#define I2C_INTR_MASK_RESTART_DET_SHIFT (12u) + +#define I2C_INTR_MASK_MASTER_ON_HOLD_MASK (0x00002000ul) +#define I2C_INTR_MASK_MASTER_ON_HOLD_SHIFT (13u) + +#define I2C_INTR_MASK_SCL_STUCK_AT_LOW_MASK (0x00004000ul) +#define I2C_INTR_MASK_SCL_STUCK_AT_LOW_SHIFT (14u) + +/* CLR_XXX Bit fields */ +#define I2C_CLR_XXX_CLR_REQ_MASK (0x00000001ul) +#define I2C_CLR_XXX_CLR_REQ_SHIFT (0u) + +/* ENABLE Bit fields */ +#define I2C_ENABLE_ENABLE_MASK (0x00000001ul) +#define I2C_ENABLE_ENABLE_SHIFT (0u) + +#define I2C_ENABLE_ABORT_MASK (0x00000002ul) +#define I2C_ENABLE_ABORT_SHIFT (1u) + +/* STATUS Bit fields */ +#define I2C_STAUTS_ACTIVITY_MASK (0x00000001ul) +#define I2C_STAUTS_ACTIVITY_SHIFT (0u) + +#define I2C_STAUTS_TFNF_MASK (0x00000002ul) +#define I2C_STAUTS_TFNF_SHIFT (1u) + +#define I2C_STAUTS_TFE_MASK (0x00000004ul) +#define I2C_STAUTS_TFE_SHIFT (2u) + +#define I2C_STAUTS_RFNE_MASK (0x00000008ul) +#define I2C_STAUTS_RFNE_SHIFT (3u) + +#define I2C_STAUTS_RFF_MASK (0x00000010ul) +#define I2C_STAUTS_RFF_SHIFT (4u) + +#define I2C_STAUTS_MST_ACTIVITY_MASK (0x00000020ul) +#define I2C_STAUTS_MST_ACTIVITY_SHIFT (5u) + +#define I2C_STAUTS_SLV_ACTIVITY_MASK (0x00000040ul) +#define I2C_STAUTS_SLV_ACTIVITY_SHIFT (6u) + +/* TXFLR Bit fields */ +#define I2C_TXFLR_TXFLR_MASK (0x0000001Ful) +#define I2C_TXFLR_TXFLR_SHIFT (0u) + +/* RXFLR Bit fields */ +#define I2C_RXFLR_RXFLR_MASK (0x0000001Ful) +#define I2C_RXFLR_RXFLR_SHIFT (0u) + +/* SDA_HOLD Bit fields */ +#define I2C_SDA_HOLD_RX_HOLD_MASK (0x000000FFul) +#define I2C_SDA_HOLD_RX_HOLD_SHIFT (16u) + +#define I2C_SDA_HOLD_TX_HOLD_MASK (0x0000FFFFul) +#define I2C_SDA_HOLD_TX_HOLD_SHIFT (0u) + +/* SDA_HOLD Bit fields */ +#define I2C_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK_MASK (0x00000001ul) +#define I2C_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK_SHIFT (0u) + +#define I2C_TX_ABRT_SOURCE_ABRT_10ADDR1_NOACK_MASK (0x00000002ul) +#define I2C_TX_ABRT_SOURCE_ABRT_10ADDR1_NOACK_SHIFT (1u) + +#define I2C_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK_MASK (0x00000004ul) +#define I2C_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK_SHIFT (2u) + +#define I2C_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK_MASK (0x00000008ul) +#define I2C_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK_SHIFT (3u) + +#define I2C_TX_ABRT_SOURCE_ABRT_GCALL_NOACK_MASK (0x00000010ul) +#define I2C_TX_ABRT_SOURCE_ABRT_GCALL_NOACK_SHIFT (4u) + +#define I2C_TX_ABRT_SOURCE_ABRT_GCALL_READ_MASK (0x00000020ul) +#define I2C_TX_ABRT_SOURCE_ABRT_GCALL_READ_SHIFT (5u) + +#define I2C_TX_ABRT_SOURCE_ABRT_HS_ACKDET_MASK (0x00000040ul) +#define I2C_TX_ABRT_SOURCE_ABRT_HS_ACKDET_SHIFT (6u) + +#define I2C_TX_ABRT_SOURCE_ABRT_SBYTE_ACKDET_MASK (0x00000080ul) +#define I2C_TX_ABRT_SOURCE_ABRT_SBYTE_ACKDET_SHIFT (7u) + +#define I2C_TX_ABRT_SOURCE_ABRT_HS_NORSTRT_MASK (0x00000100ul) +#define I2C_TX_ABRT_SOURCE_ABRT_HS_NORSTRT_SHIFT (8u) + +#define I2C_TX_ABRT_SOURCE_ARB_SBYTE_NORSTRT_MASK (0x00000200ul) +#define I2C_TX_ABRT_SOURCE_ARB_SBYTE_NORSTRT_SHIFT (9u) + +#define I2C_TX_ABRT_SOURCE_ARB_10B_RD_NORSTRT_MASK (0x00000400ul) +#define I2C_TX_ABRT_SOURCE_ARB_10B_RD_NORSTRT_SHIFT (10u) + +#define I2C_TX_ABRT_SOURCE_ARB_MASTER_DIS_MASK (0x00000800ul) +#define I2C_TX_ABRT_SOURCE_ARB_MASTER_DIS_SHIFT (11u) + +#define I2C_TX_ABRT_SOURCE_ARB_LOST_MASK (0x00001000ul) +#define I2C_TX_ABRT_SOURCE_ARB_LOST_SHIFT (12u) + +#define I2C_TX_ABRT_SOURCE_ABRT_SLVFLUSH_TXFIFO_MASK (0x00002000ul) +#define I2C_TX_ABRT_SOURCE_ABRT_SLVFLUSH_TXFIFO_SHIFT (13u) + +#define I2C_TX_ABRT_SOURCE_ABRT_SLV_ARBLOST_MASK (0x00004000ul) +#define I2C_TX_ABRT_SOURCE_ABRT_SLV_ARBLOST_SHIFT (14u) + +#define I2C_TX_ABRT_SOURCE_ABRT_SLVRD_INTX_MASK (0x00008000ul) +#define I2C_TX_ABRT_SOURCE_ABRT_SLVRD_INTX_SHIFT (15u) + +#define I2C_TX_ABRT_SOURCE_ABRT_USER_ABRT_MASK (0x00010000ul) +#define I2C_TX_ABRT_SOURCE_ABRT_USER_ABRT_SHIFT (16u) + +#define I2C_TX_ABRT_SOURCE_TX_FLUSH_CNT_MASK (0x0F800000ul) +#define I2C_TX_ABRT_SOURCE_TX_FLUSH_CNT_SHIFT (23u) + +/* I2C_DMA_CR Bit fields */ +#define I2C_DMA_CR_RDMAE_MASK (0x00000001ul) +#define I2C_DMA_CR_RDMAE_SHIFT (0u) + +#define I2C_DMA_CR_TDMAE_MASK (0x00000002ul) +#define I2C_DMA_CR_TDMAE_SHIFT (1u) + +/* I2C_DMA_TDLR Bit fields */ +#define I2C_DMA_TDLR_DMATDL_MASK (0x0000000Ful) +#define I2C_DMA_TDLR_DMATDL_SHIFT (0u) + +/* I2C_DMA_RDLR Bit fields */ +#define I2C_DMA_RDLR_DMARDL_MASK (0x0000000Ful) +#define I2C_DMA_RDLR_DMARDL_SHIFT (0u) + +/* I2C_SDA_SETUP Bit fields */ +#define I2C_SDA_SETUP_SDA_SETUP_MASK (0x000000FFul) +#define I2C_SDA_SETUP_SDA_SETUP_SHIFT (0u) + +/* I2C_ACK_GCALL Bit fields */ +#define I2C_ACK_GCALL_ACK_GEN_CALL_MASK (0x00000001ul) +#define I2C_ACK_GCALL_ACK_GEN_CALL_SHIFT (0u) + +/* I2C_ENABLE_STATUS Bit fields */ +#define I2C_ENABLE_STATUS_EN_MASK (0x00000001ul) +#define I2C_ENABLE_STATUS_EN_SHIFT (0u) + +#define I2C_ENABLE_STATUS_SLV_DISABLED_WHILE_BUSY_MASK (0x00000002ul) +#define I2C_ENABLE_STATUS_SLV_DISABLED_WHILE_BUSY_SHIFT (1u) + +#define I2C_ENABLE_STATUS_SLV_RX_DATA_LOST_MASK (0x00000004ul) +#define I2C_ENABLE_STATUS_SLV_RX_DATA_LOST_SHIFT (2u) + +/* I2C_SPKLEN Bit fields */ +#define I2C_SPKLEN_LEN_MASK (0x000000FFul) +#define I2C_SPKLEN_LEN_SHIFT (0u) + +/****************************************************************************** + * the typedefs + *****************************************************************************/ + +/*! \brief the definition of i2c register */ +typedef struct _I2cRegType_ +{ + volatile uint32_t CTRL; /*!< I2C Control Register, offset: 0x0 */ + volatile uint32_t TAR; /*!< I2C Target address Register, offset: 0x4 */ + volatile uint32_t SAR; /*!< I2C Slave address Register, offset: 0x8 */ + uint32_t Res0; + volatile uint32_t DATA_CMD; /*!< I2C Data & Command Register, offset: 0x10 */ + volatile uint32_t SS_SCL_HCNT; /*!< I2C Standard Speed I2C clock high count Register, offset: 0x14 */ + volatile uint32_t SS_SCL_LCNT; /*!< I2C Standard Speed I2C clock high count Register, offset: 0x18 */ + volatile uint32_t FS_SCL_HCNT; /*!< I2C Fast speed I2C clock high count Register, offset: 0x1c */ + volatile uint32_t FS_SCL_LCNT; /*!< I2C Fast speed I2C clock low count Register, offset: 0x20 */ + uint32_t Res1[2]; + volatile uint32_t INTR_STAT; /*!< I2C Interrupt status Register, offset: 0x2C */ + volatile uint32_t INTR_MASK; /*!< I2C Interrupt mask Register, offset: 0x30 */ + volatile uint32_t RAW_INTR_STAT; /*!< I2C RAW INTERRUPT Register, offset: 0x34 */ + volatile uint32_t RX_TL; /*!< I2C RX FIFO threshold Register, offset: 0x38 */ + volatile uint32_t TX_TL; /*!< I2C TX FIFO threshold Register, offset: 0x3C */ + volatile uint32_t CLR_INTR; /*!< I2C Clear interrupt Register, offset: 0x40 */ + volatile uint32_t CLR_RX_UNDER; /*!< I2C Clear RX_UNDER interrupt Register, offset: 0x44 */ + volatile uint32_t CLR_RX_OVER; /*!< I2C Clear RX OVER interrupt Register, offset: 0x48 */ + volatile uint32_t CLR_TX_OVER; /*!< I2C Clear TX OVER interrupt Register, offset: 0x4C */ + volatile uint32_t CLR_RD_REQ; /*!< I2C Clear RD_REQ interrupt Register, offset: 0x50 */ + volatile uint32_t CLR_TX_ABRT; /*!< I2C Clear TX_ABRT interrupt Register, offset: 0x54 */ + volatile uint32_t CLR_RX_DONE; /*!< I2C Clear RX DONE interrupt Register, offset: 0x58 */ + volatile uint32_t CLR_ACTIVITY; /*!< I2C Clear ACTIVITY interrupt Register, offset: 0x5C */ + volatile uint32_t CLR_STOP_DET; /*!< I2C Clear STOP_DET interrupt Register, offset: 0x60 */ + volatile uint32_t CLR_START_DET; /*!< I2C Clear START_DET interrupt Register, offset: 0x64 */ + volatile uint32_t CLR_GEN_CALL; /*!< I2C Clear GEN_CALL interrupt Register, offset: 0x68 */ + volatile uint32_t ENABLE; /*!< I2C ENABLE Register, offset: 0x6C */ + volatile uint32_t STATUS; /*!< I2C STATUS Register, offset: 0x70 */ + volatile uint32_t TXFLR; /*!< I2C TX FIFO LEVEL Register, offset: 0x74 */ + volatile uint32_t RXFLR; /*!< I2C RX FIFO LEVEL Register, offset: 0x78 */ + volatile uint32_t SDA_HOLD; /*!< I2C SDA HOLD TIME length Register, offset: 0x7C */ + volatile uint32_t TX_ABRT_SOURCE; /*!< I2C Transmit ABORT source Register, offset: 0x80 */ + uint32_t Res2; + volatile uint32_t DMA_CR; /*!< I2C DMA control Register, offset: 0x88 */ + volatile uint32_t DMA_TDLR; /*!< I2C DMA Transmit Data Level Register, offset: 0x8C */ + volatile uint32_t DMA_RDLR; /*!< I2C DMA Receive Data Level Register, offset: 0x90 */ + volatile uint32_t SDA_SETUP; /*!< I2C SDA SETUP Register, offset: 0x94 */ + volatile uint32_t ACK_GCALL; /*!< I2C Ack for General Call Register, offset: 0x98 */ + volatile uint32_t ENABLE_STATUS; /*!< I2C ENABLE status Register, offset: 0x9C */ + volatile uint32_t SPKLEN; /*!< I2C SS,FS,FM+ spike suppression limit Register, offset: 0xA0 */ + uint32_t Res3[23]; +} I2cRegType; + +/****************************************************************************** + * the globals + *****************************************************************************/ + +/****************************************************************************** + * the function prototypes + *****************************************************************************/ + +/*! \brief Set the method of controls the generation of TX_EMPTY interrupt. + * + * the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] ctrlMode: + * 0h: default behaviour + * 1h: controled generation + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetTxEmptyCtrl(I2cRegType *obj, uint8_t ctrlMode) +{ + uint32_t tRegValue = obj->CTRL; + + obj->CTRL = (((uint32_t)ctrlMode << I2C_CTRL_TX_EMPTY_CTRL_SHIFT) | ((~I2C_CTRL_TX_EMPTY_CTRL_MASK) & tRegValue)); +} + +/*! \brief Set the mode of detect stop bit condition + * + * the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] stopDetMode + * 0h: issue the STOP_DET irrespective of whether it is addressed or not + * 1h: issue the STOP_DET irrespective only when it is addressed + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetSlaveDetectStopBitMode(I2cRegType *obj, uint8_t stopDetMode) +{ + uint32_t tRegValue = obj->CTRL; + + obj->CTRL = (((uint32_t)stopDetMode << I2C_CTRL_STOP_DET_IFADDRESSED_SHIFT) | ((~I2C_CTRL_STOP_DET_IFADDRESSED_MASK) & tRegValue)); +} + +/*! \brief slave mode disable + * + * this function set the node as slave node or not + * + * \param[in] obj: base address for the i2cinstance + * \param[in] DdisableSlaveMode: + * false: enable slave mode + * true: disable slave mode + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetSlaveModeDisable(I2cRegType *obj, bool disableSlaveMode) +{ + uint32_t tRegValue = obj->CTRL; + + if(disableSlaveMode == true) + { + obj->CTRL = ((1ul << I2C_CTRL_SLAVE_DISABLE_SHIFT) | ((~I2C_CTRL_SLAVE_DISABLE_MASK) & tRegValue)); + } + else + { + obj->CTRL = ((0ul << I2C_CTRL_SLAVE_DISABLE_SHIFT) | ((~I2C_CTRL_SLAVE_DISABLE_MASK) & tRegValue)); + } +} + +/*! \brief master RESTART enable + * + * the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] restartEnable: + * false: Disabled + * true: Enabled + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetMasterRestartEnable(I2cRegType *obj, bool restartEnable) +{ + uint32_t tRegValue = obj->CTRL; + + if(restartEnable == true) + { + obj->CTRL = ((1ul << I2C_CTRL_RESTART_EN_SHIFT) | ((~I2C_CTRL_RESTART_EN_MASK) & tRegValue)); + } + else + { + obj->CTRL = ((0ul << I2C_CTRL_RESTART_EN_SHIFT) | ((~I2C_CTRL_RESTART_EN_MASK) & tRegValue)); + } +} + +/*! \brief Set master address mode + * + * the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] addressMode: + * 0h:7bit address + * 1h:10bit address + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetMasterAddressMode(I2cRegType *obj, uint8_t addressMode) +{ + uint32_t tRegValue = obj->CTRL; + + obj->CTRL = (((uint32_t)addressMode << I2C_CTRL_MST_ADDR_MODE_SHIFT) | ((~I2C_CTRL_MST_ADDR_MODE_MASK) & tRegValue)); +} + +/*! \brief Set slave address mode + * + * the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] addressMode: + * 0h:7bit address + * 1h:10bit address + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetSlaveAddressMode(I2cRegType *obj, uint8_t addressMode) +{ + uint32_t tRegValue = obj->CTRL; + + obj->CTRL = (((uint32_t)addressMode << I2C_CTRL_SLV_ADDR_MODE_SHIFT) | ((~I2C_CTRL_SLV_ADDR_MODE_MASK) & tRegValue)); +} + +/*! \brief Set the master speed + * + * the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] speedMode: + * 1h:standard mode,100kbit/s + * 2h:fast mode <=400kbit/s or fast mode plus<=1000kbit/s; + * 3h: high speed 3.4Mbit/s--not supported + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetSpeedMode(I2cRegType *obj, uint8_t speedMode) +{ + uint32_t tRegValue = obj->CTRL; + + obj->CTRL = (((uint32_t)speedMode << I2C_CTRL_SPEED_SHIFT) | ((~I2C_CTRL_SPEED_MASK) & tRegValue)); +} + +/*! \brief Get the master speed + * + * this function get the master speed + * + * \param[in] obj: base address for the i2cinstance + * \return: uint8_t + * 1h:standard mode,100kbit/s + * 2h:fast mode <=400kbit/s or fast mode plus<=1000kbit/s; + * 3h: high speed 3.4Mbit/s--not supported + */ +__attribute__((always_inline)) static inline uint8_t I2cReg_GetSpeedMode(const I2cRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->CTRL & I2C_CTRL_SPEED_MASK) >> I2C_CTRL_SPEED_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief I2C master mode control + * + * the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] masterMode: + * 0h: slave mode + * 1h: master mode + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetMasterMode(I2cRegType *obj, bool masterMode) +{ + uint32_t tRegValue = obj->CTRL; + + if(masterMode == true) + { + obj->CTRL = ((1ul << I2C_CTRL_MST_MODE_SHIFT) | ((~I2C_CTRL_MST_MODE_MASK) & tRegValue)); + } + else + { + obj->CTRL = ((0ul << I2C_CTRL_MST_MODE_SHIFT) | ((~I2C_CTRL_MST_MODE_MASK) & tRegValue)); + } +} + +/*! \brief Get the type of the node + * + * this function get the moudle whether it be used as master node + * + * \param[in] obj: base address for the i2cinstance + * \return: bool + * true: as a master node + * false:as a slave node + */ +__attribute__((always_inline)) static inline bool I2cReg_GetModuleAsMaster(const I2cRegType *obj) +{ + bool tRtn = false; + + if((obj->CTRL & I2C_CTRL_MST_MODE_MASK) != 0ul) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief indicates whether software performs a General Call or Start Byte command + * + * the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] supportedSpecialCmd: + * 0b: not support + * 1b: support + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetSpecialCommand(I2cRegType *obj, uint8_t supportedSpecialCmd) +{ + uint32_t tRegValue = obj->TAR; + + obj->TAR = (((uint32_t)supportedSpecialCmd << I2C_TAR_SPECIAL_SHIFT) | ((~I2C_TAR_SPECIAL_MASK) & tRegValue)); +} + +/*! \brief Set special type + * + * the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] SsecialCmdType: + * 0h:General Call + * 1h:Start byte + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetSpecialCmdType(I2cRegType *obj, uint8_t specialCmdType) +{ + uint32_t tRegValue = obj->TAR; + + obj->TAR = (((uint32_t)specialCmdType << I2C_TAR_GC_OR_START_SHIFT) | ((~I2C_TAR_GC_OR_START_MASK) & tRegValue)); +} + +/*! \brief Set target address for master + * + * It is the target address for master transaction. When transmitting a Genral Call, it is ignored, + * the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] targetAddr: the target address of node + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetTargetAddress(I2cRegType *obj, uint16_t targetAddr) +{ + uint32_t tRegValue = obj->TAR; + + obj->TAR = (((uint32_t)targetAddr << I2C_TAR_TAR_SHIFT) | ((~I2C_TAR_TAR_MASK) & tRegValue)); +} + +/*! \brief Get the current target address for master + * + * this function get the target address for master + * + * \param[in] obj: base address for the i2cinstance + * \return: the target node of address + */ +__attribute__((always_inline)) static inline uint32_t I2cReg_GetTargetAddress(const I2cRegType *obj) +{ + uint32_t tRtn = 0; + + tRtn = ((obj->TAR & I2C_TAR_TAR_MASK) >> I2C_TAR_TAR_SHIFT); + + return tRtn; +} + +/*! \brief Set slave address + * + * only be written when I2C interface is disabled.the bit be operated only in the module is in disable + * + * \param[in] obj: base address for the i2cinstance + * \param[in] slaveAddress: the slave node of address + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetSlaveAddress(I2cRegType *obj, uint16_t slaveAddress) +{ + uint32_t tRegValue = obj->SAR; + + obj->SAR = (((uint32_t)slaveAddress << I2C_SAR_SAR_SHIFT) | ((~I2C_SAR_SAR_MASK) & tRegValue)); +} + +/*! \brief Write transmit data and command + * + * Read or write data from this register + * + * \param[in] obj: base address for the i2cinstance + * \param[in] data: the transmit data + * \param[in] readCmd: + * 0b: write command + * 1b: read command + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetDataAndCmd(I2cRegType *obj, uint8_t data, bool readCmd) +{ + uint32_t tDataCmd = 0; + + tDataCmd = data; + + if(readCmd == true) + { + tDataCmd |= I2C_DATA_CMD_CMD_MASK; + } + + obj->DATA_CMD = tDataCmd; +} + +/*! \brief Get received data + * + * this function read out datas from rx fifo + * + * \param[in] obj: base address for the i2cinstance + * \return: received data + */ +__attribute__((always_inline)) static inline uint8_t I2cReg_GetData(const I2cRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->DATA_CMD & I2C_DATA_CMD_DATA_MASK) >> I2C_DATA_CMD_DATA_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Set Standard Speed I2C clock high count + * + * This register can be written only when the I2C interface is disabled + * + * \param[in] obj: base address for the i2cinstance + * \param[in] highCount: the i2c clock high count value + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetStandardModeHighLevelCount(I2cRegType *obj, uint16_t highCount) +{ + uint32_t tRegValue = obj->SS_SCL_HCNT; + + obj->SS_SCL_HCNT = (((uint32_t)highCount << I2C_XX_SCL_XXX_CNT_COUNTER_SHIFT) | ((~I2C_XX_SCL_XXX_CNT_COUNTER_MASK) & tRegValue)); +} + +/*! \brief Get Standard Speed I2C clock high count + * + * this function get the high counter in standard speed mode + * + * \param[in] obj: base address for the i2cinstance + * \return: the i2c clock high count value + */ +__attribute__((always_inline)) static inline uint16_t I2cReg_GetStandardModeHighLevelCount(const I2cRegType *obj) +{ + uint16_t tRtn = 0; + + tRtn = ((obj->SS_SCL_HCNT & I2C_XX_SCL_XXX_CNT_COUNTER_MASK) & 0xFFFF); + + return tRtn; +} + +/*! \brief Set Standard Speed I2C clock low count + * + * This register can be written only when the I2C interface is disabled + * + * \param[in] obj: base address for the i2cinstance + * \param[in] lowCount: Standard Speed I2C clock low count + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetStandardModeLowLevelCount(I2cRegType *obj, uint16_t lowCount) +{ + uint32_t tRegValue = obj->SS_SCL_LCNT; + + obj->SS_SCL_LCNT = (((uint32_t)lowCount << I2C_XX_SCL_XXX_CNT_COUNTER_SHIFT) | ((~I2C_XX_SCL_XXX_CNT_COUNTER_MASK) & tRegValue)); +} + +/*! \brief Get Standard Speed I2C clock low count + * + * this function get the low counter in standard speed mode + * + * \param[in] obj: base address for the i2cinstance + * \return: Standard Speed I2C clock low count + */ +__attribute__((always_inline)) static inline uint16_t I2cReg_GetStandardModeLowLevelCount(const I2cRegType *obj) +{ + uint16_t tRtn = 0; + + tRtn = ((obj->SS_SCL_LCNT & I2C_XX_SCL_XXX_CNT_COUNTER_MASK) & 0xFFFF); + + return tRtn; +} + +/*! \brief Set FAST Speed I2C clock high count + * + * This register can be written only when the I2C interface is disabled + * + * \param[in] obj: base address for the i2cinstance + * \param[in] highCount: FAST Speed I2C clock high count + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetFastModeHighLevelCount(I2cRegType *obj, uint16_t highCount) +{ + uint32_t tRegValue = obj->FS_SCL_HCNT; + + obj->FS_SCL_HCNT = (((uint32_t)highCount << I2C_XX_SCL_XXX_CNT_COUNTER_SHIFT) | ((~I2C_XX_SCL_XXX_CNT_COUNTER_MASK) & tRegValue)); +} + +/*! \brief Get Fast Speed I2C clock High count + * + * this function get the high counter in fast speed mode + * + * \param[in] obj: base address for the i2cinstance + * \return: Fast Speed I2C clock High count + */ +__attribute__((always_inline)) static inline uint16_t I2cReg_GetFastModeHighLevelCount(const I2cRegType *obj) +{ + uint16_t tRtn = 0; + + tRtn = ((obj->FS_SCL_HCNT & I2C_XX_SCL_XXX_CNT_COUNTER_MASK) & 0xFFFF); + + return tRtn; +} + +/*! \brief Set FAST Speed I2C clock low count + * + * This register can be written only when the I2C interface is disabled + * + * \param[in] obj: base address for the i2cinstance + * \param[in] lowCount: FAST Speed I2C clock low count + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetFastModeLowLevelCount(I2cRegType *obj, uint16_t lowCount) +{ + uint32_t tRegValue = obj->FS_SCL_LCNT; + + obj->FS_SCL_LCNT = (((uint32_t)lowCount << I2C_XX_SCL_XXX_CNT_COUNTER_SHIFT) | ((~I2C_XX_SCL_XXX_CNT_COUNTER_MASK) & tRegValue)); +} + +/*! \brief Get Fast Speed I2C clock low count + * + * Note:this function get the low counter in fast speed mode + * + * \param[in] obj: base address for the i2cinstance + * \return: Fast Speed I2C clock low count + */ +__attribute__((always_inline)) static inline uint16_t I2cReg_GetFastModeLowLevelCount(const I2cRegType *obj) +{ + uint16_t tRtn = 0; + + tRtn = ((obj->FS_SCL_LCNT & I2C_XX_SCL_XXX_CNT_COUNTER_MASK) & 0xFFFF); + + return tRtn; +} + +/*! \brief Get I2C interrupt status + * + * this function get the special interrupt status + * + * \param[in] obj: base address for the i2cinstance + * \param[in] interruptStatusMask: conbination of more than one status + * \return: bool + * 0h: inactive + * 1h: active + */ +__attribute__((always_inline)) static inline bool I2cReg_GetInterruptStatus(const I2cRegType *obj, uint32_t interruptStatusMask) +{ + uint32_t tIsrStatus = 0; + bool tRtn = false; + + tIsrStatus = obj->INTR_STAT; + + if((tIsrStatus & interruptStatusMask) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief Get I2C raw interrupt status + * + * this function get the interrupt raw status + * + * \param[in] obj: base address for the i2cinstance + * \param[in] interruptStatusMask: conbination of more than one status + * \return: bool + * 0h: inactive + * 1h: active + */ +__attribute__((always_inline)) static inline bool I2cReg_GetInterruptRawStatus(const I2cRegType *obj, uint32_t interruptStatusMask) +{ + uint32_t tStatus = 0; + bool tRtn = false; + + tStatus = obj->RAW_INTR_STAT; + + if((tStatus & interruptStatusMask) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief Get Ic Status + * + * this function get the ic module status + * + * \param[in] obj: base address for the i2cinstance + * \param[in] statusMask: conbination of more than one status + * \return: bool + * false: no happend + * true: happend + */ +__attribute__((always_inline)) static inline bool I2cReg_GetICStatus(const I2cRegType *obj, uint32_t statusMask) +{ + uint32_t tStatus = 0; + bool tRtn = false; + + tStatus = obj->STATUS; + + if((tStatus & statusMask) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief Enable or disable interrupt req + * + * this function set the special interrupt request action when condition is matched + * + * \param[in] obj: base address for the i2cinstance + * \param[in] interruptStatusMask: the special interrupt status + * \param[in] enInterruptReq: enable or disable + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetInterruptMask(I2cRegType *obj, uint32_t interruptStatusMask, bool enInterruptReq) +{ + if(enInterruptReq == true) + { + obj->INTR_MASK |= interruptStatusMask; + } + else + { + obj->INTR_MASK &= (~interruptStatusMask); + } +} + +/*! \brief Get the current interrupt status + * + * This function get the current inyrttupy is enabled or disabled + * + * \param[in] obj: base address for the i2cinstance + * \param[in] interruptStatusMask: the special interrupt status + * \return: bool + * true: is enabled + * false: is disabled + */ +__attribute__((always_inline)) static inline bool I2cReg_GetInterruptIsEnabled(const I2cRegType *obj, uint32_t interruptStatusMask) +{ + bool isEnabled = false; + + if((obj->INTR_MASK & interruptStatusMask) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief Set RX FIFO threshold + * + * I2C RX FIFO threshold FIFO depth is 16 + * + * \param[in] obj: base address for the i2cinstance + * \param[in] rxFifoThreshold: RX FIFO threshold value + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetRxFifoThreshold(I2cRegType *obj, uint8_t rxFifoThreshold) +{ + uint32_t tRegValue = obj->RX_TL; + + obj->RX_TL = (((uint32_t)rxFifoThreshold << I2C_RXFLR_RXFLR_SHIFT) | ((~I2C_RXFLR_RXFLR_MASK) & tRegValue)); +} + +/*! \brief Set TX FIFO threshold + * + * I2C TX FIFO threshold FIFO depth is 16 + * + * \param[in] obj: base address for the i2cinstance + * \param[in] txFifoThreshold: TX FIFO threshold + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetTxFifoThreshold(I2cRegType *obj, uint8_t txFifoThreshold) +{ + uint32_t tRegValue = obj->TX_TL; + + obj->TX_TL = (((uint32_t)txFifoThreshold << I2C_TXFLR_TXFLR_SHIFT) | ((~I2C_TXFLR_TXFLR_MASK) & tRegValue)); +} + +/*! \brief Clear all interrupt status + * + * Read this register to clear all interrupts and I2C_TX_ABRT_SOURCE, It does not clear hardware clearable interrupts but software clearable interrupts. + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearAllInterruptStatus(I2cRegType *obj) +{ + (void)((obj->CLR_INTR & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_INTR; +} + +/*! \brief clear interrupt status in the RAW_INTR_STAT + * + * this function clear the rx under status after interrupt request handler + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearRxUnderStatus(I2cRegType *obj) +{ + (void)((obj->CLR_RX_UNDER & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_RX_UNDER; +} + +/*! \brief clear interrupt status in the RAW_INTR_STAT + * + * Note:this function clear the rx overflow status after interrupt request handler + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearRxOverStatus(I2cRegType *obj) +{ + (void)((obj->CLR_RX_OVER & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_RX_OVER; +} + +/*! \brief clear interrupt status in the RAW_INTR_STAT + * + * Note:this function clear the tx overflow status after interrupt request handler + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearTxOverStatus(I2cRegType *obj) +{ + (void)((obj->CLR_TX_OVER & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_TX_OVER; +} + +/*! \brief clear interrupt status in the RAW_INTR_STAT + * + * Note:this function clear the rx read request status after interrupt request handler + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearReadReqStatus(I2cRegType *obj) +{ + (void)((obj->CLR_RD_REQ & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_RD_REQ; +} + +/*! \brief clear interrupt status in the RAW_INTR_STAT + * + * Note:this function clear the tx abort status after interrupt request handler + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearTxAbortStatus(I2cRegType *obj) +{ + (void)((obj->CLR_TX_ABRT & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_TX_ABRT; +} + +/*! \brief clear interrupt status in the RAW_INTR_STAT + * + * Note:this function clear the rx done status after interrupt request handler + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearRxDoneStatus(I2cRegType *obj) +{ + (void)((obj->CLR_RX_DONE & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_RX_DONE; +} + +/*! \brief clear interrupt status in the RAW_INTR_STAT + * + * Note:this function clear the activity status after interrupt request handler + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearActivityStatus(I2cRegType *obj) +{ + (void)((obj->CLR_ACTIVITY & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_ACTIVITY; +} + +/*! \brief clear interrupt status in the RAW_INTR_STAT + * + * Note:this function clear the stop bit detected status after interrupt request handler + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearStopBitDetectStatus(I2cRegType *obj) +{ + (void)((obj->CLR_STOP_DET & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_STOP_DET; +} + +/*! \brief clear interrupt status in the RAW_INTR_STAT + * + * Note:this function clear the start bit detected status after interrupt request handler + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearStartBitDetectStatus(I2cRegType *obj) +{ + (void)((obj->CLR_START_DET & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_START_DET; +} + +/*! \brief clear interrupt status in the RAW_INTR_STAT + * + * Note:this function clear the general call status after interrupt request handler + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_ClearGeneralCallStatus(I2cRegType *obj) +{ + (void)((obj->CLR_GEN_CALL & I2C_CLR_XXX_CLR_REQ_MASK) >> I2C_CLR_XXX_CLR_REQ_SHIFT); + + /* Read back to avoid problem */ + (void)obj->CLR_GEN_CALL; +} + +/*! \brief Set module enable + * + * this function enable or disable the i2c module + * + * \param[in] obj: base address for the i2cinstance + * \param[in] ModuleEn: enable or disable + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetModuleEnable(I2cRegType *obj, bool moduleEn) +{ + uint32_t tRegValue = obj->ENABLE; + + if(moduleEn == true) + { + obj->ENABLE = ((1ul << I2C_ENABLE_ENABLE_SHIFT) | ((~I2C_ENABLE_ENABLE_MASK) & tRegValue)); + } + else + { + obj->ENABLE = ((0ul << I2C_ENABLE_ENABLE_SHIFT) | ((~I2C_ENABLE_ENABLE_MASK) & tRegValue)); + } +} + +/*! \brief Abort transfer + * + * only set one in the enable bit is 1, clear by hardware + * after set 1, the hardware will generate a stop condition and clear tx fifo, then hardware clear this bit again + * + * \param[in] obj: base address for the i2cinstance + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetAbortReq(I2cRegType *obj) +{ + uint32_t tRegValue = obj->ENABLE; + + obj->ENABLE = ((1ul << I2C_ENABLE_ABORT_SHIFT) | ((~I2C_ENABLE_ABORT_MASK) & tRegValue)); +} + +/*! \brief Get i2c status + * + * this function get the current status of module + * + * \param[in] obj: base address for the i2cinstance + * \param[in] StatusMask: one special status mask, only one status + * \return: bool + * false: not exist + * true: exist + */ +__attribute__((always_inline)) static inline bool I2cReg_GetModuleStatus(const I2cRegType *obj, uint32_t statusMask) +{ + uint32_t tStatus = 0; + bool tRtn = false; + + tStatus = obj->STATUS; + if((tStatus & statusMask) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief Contains the number of valid data entries in the transmit FIFO. + * + * this function get the number of valid data entries in the transmit FIFO + * + * \param[in] obj: base address for the i2cinstance + * \return: the number of valid data entries + */ +__attribute__((always_inline)) static inline uint8_t I2cReg_GetTxFifoLevel(const I2cRegType *obj) +{ + uint8_t tTxFifoLevel = 0; + + tTxFifoLevel = (((obj->TXFLR & I2C_TXFLR_TXFLR_MASK) >> I2C_TXFLR_TXFLR_SHIFT) & 0xFF); + + return tTxFifoLevel; +} + +/*! \brief Contains the number of valid data entries in the receive FIFO. + * + * this function get the number of valid data entries in the receive FIFO. + * + * \param[in] obj: base address for the i2cinstance + * \return: the number of valid data entries in the receive FIFO. + */ +__attribute__((always_inline)) static inline uint8_t I2cReg_GetRxFifoLevel(const I2cRegType *obj) +{ + uint8_t tRxFifoLevel = 0; + + tRxFifoLevel = (((obj->RXFLR & I2C_RXFLR_RXFLR_MASK) >> I2C_RXFLR_RXFLR_SHIFT) & 0xFF); + + return tRxFifoLevel; +} + +/*! \brief Set RX SDA hold time + * + * this function set IC SDA HOLD TIME length + * + * \param[in] obj: base address for the i2cinstance + * \param[in] HoldTime: IC SDA HOLD TIME length + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetRxDataHoldTime(I2cRegType *obj, uint16_t holdTime) +{ + uint32_t tRegValue = obj->SDA_HOLD; + + obj->SDA_HOLD = (((uint32_t)holdTime << I2C_SDA_HOLD_RX_HOLD_SHIFT) | ((~I2C_SDA_HOLD_RX_HOLD_MASK) & tRegValue)); +} + +/*! \brief Set TX SDA hold time + * + * This bit field can only be written when the I2C_ENABLE[ENABLE] is disabled . + * + * \param[in] obj: base address for the i2cinstance + * \param[in] HoldTime: TX SDA hold time + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetTxDataHoldTime(I2cRegType *obj, uint16_t holdTime) +{ + uint32_t tRegValue = obj->SDA_HOLD; + + obj->SDA_HOLD = (((uint32_t)holdTime << I2C_SDA_HOLD_TX_HOLD_SHIFT) | ((~I2C_SDA_HOLD_TX_HOLD_MASK) & tRegValue)); +} + +/*! \brief Get the Tx abort source information except the tx flush cnt + * + * this function get the tx abort information + * + * \param[in] obj: base address for the i2cinstance + * \param[in] AbortSourceMask: which abort source + * \return: bool + * true: abort detected + * false: abort not detected + */ +__attribute__((always_inline)) static inline bool I2cReg_GetTxAbortInfo(const I2cRegType *obj, uint32_t abortSourceMask) +{ + uint32_t tAbortSource = 0; + bool tRtn = false; + + tAbortSource = obj->TX_ABRT_SOURCE; + + if((tAbortSource & abortSourceMask) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief flush count in TX FIFO + * + * This field indicates the number of Tx FIFO Data Commands which are flushed due to TX_ABRT interrupt. It is cleared whenever I2C is disabled. + * + * \param[in] obj: base address for the i2cinstance + * \return: the number of Tx FIFO Data Commands which are flushed + */ +__attribute__((always_inline)) static inline uint8_t I2cReg_GetTxFlushCounter(const I2cRegType *obj) +{ + uint8_t tTxFlushCounter = 0; + + tTxFlushCounter = (((obj->TX_ABRT_SOURCE & I2C_TX_ABRT_SOURCE_TX_FLUSH_CNT_MASK) >> I2C_TX_ABRT_SOURCE_TX_FLUSH_CNT_SHIFT) & 0xFF); + + return tTxFlushCounter; +} + +/*! \brief This bit enables/disables the transmit FIFO DMA channel. + * + * this function enable or disable the tx with dma features + * + * \param[in] obj: base address for the i2cinstance + * \param[in] en: + * false: Dma tx disabled + * true: Dma tx enabled + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetTxDmaEnable(I2cRegType *obj, bool en) +{ + uint32_t tRegValue = obj->DMA_CR; + + if(en == true) + { + obj->DMA_CR = ((1ul << I2C_DMA_CR_TDMAE_SHIFT) | ((~I2C_DMA_CR_TDMAE_MASK) & tRegValue)); + } + else + { + obj->DMA_CR = ((0ul << I2C_DMA_CR_TDMAE_SHIFT) | ((~I2C_DMA_CR_TDMAE_MASK) & tRegValue)); + } +} + +/*! \brief Get enables/disables the transmit FIFO DMA channel. + * + * this function get the current tx mode is used with dma + * + * \param[in] obj: base address for the i2cinstance + * \return: bool + */ +__attribute__((always_inline)) static inline bool I2cReg_GetDmaTxIsEnabled(const I2cRegType *obj) +{ + bool tRtn = false; + + if((obj->DMA_CR & I2C_DMA_CR_TDMAE_MASK) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief This bit enables/disables the receiver FIFO DMA channel. + * + * this function enable or disable the rx with dma features + * + * \param[in] obj: base address for the i2cinstance + * \param[in] en: + * false: Dma rx disabled + * true: Dma rx enabled + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetRxDmaEnable(I2cRegType *obj, bool en) +{ + uint32_t tRegValue = obj->DMA_CR; + + if(en == true) + { + obj->DMA_CR = ((1ul << I2C_DMA_CR_RDMAE_SHIFT) | ((~I2C_DMA_CR_RDMAE_MASK) & tRegValue)); + } + else + { + obj->DMA_CR = ((0ul << I2C_DMA_CR_RDMAE_SHIFT) | ((~I2C_DMA_CR_RDMAE_MASK) & tRegValue)); + } +} + +/*! \brief Get enables/disables the transmit FIFO DMA channel. + * + * this function get the current rx mode is used with dma + * + * \param[in] obj: base address for the i2cinstance + * \return: bool + * false: Dma rx disabled + * true: Dma rx enabled + */ +__attribute__((always_inline)) static inline bool I2cReg_GetDmaRxIsEnabled(const I2cRegType *obj) +{ + bool tRtn = false; + + if((obj->DMA_CR & I2C_DMA_CR_RDMAE_MASK) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief controls the level at which a DMA request is made by the transmit logic + * + * It is equal to the watermark level; that is, the dma_tx_req signal is generated when the number of valid data entries in the transmit FIFO is equal to + * or below this field value, and TDMAE = 1 + * + * \param[in] obj: base address for the i2cinstance + * \param[in] txLevel: the watermark level + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetDmaTxLevel(I2cRegType *obj, uint8_t txLevel) +{ + uint32_t tRegValue = obj->DMA_TDLR; + + obj->DMA_TDLR = (((uint32_t)txLevel << I2C_DMA_TDLR_DMATDL_SHIFT) | ((~I2C_DMA_TDLR_DMATDL_MASK) & tRegValue)); +} + +/*! \brief controls the level at which a DMA request is made by the receive logic + * + * The watermark level = DMARDL+1; that is, dma_rx_req is generated when the number of valid data entries in the receive FIFO is equal + * to or more than this field value + 1, and RDMAE =1. + * + * \param[in] obj: base address for the i2cinstance + * \param[in] rxLevel: The rx watermark level + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetDmaRxLevel(I2cRegType *obj, uint8_t rxLevel) +{ + uint32_t tRegValue = obj->DMA_RDLR; + + obj->DMA_RDLR = (((uint32_t)rxLevel << I2C_DMA_RDLR_DMARDL_SHIFT) | ((~I2C_DMA_RDLR_DMARDL_MASK) & tRegValue)); +} + +/*! \brief SDA setup + * + * It is recommended that if the required delay is + * 1000ns, then for an I2C_clk frequency of 10 MHz,I2C_SDA_SETUP should be programmed to a value of 11. I2C_SDA_SETUP >=2 + * + * \param[in] obj: base address for the i2cinstance + * \param[in] SetUpTime: SDA setup + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetDataSetUpTime(I2cRegType *obj, uint8_t setUpTime) +{ + uint32_t tRegValue = obj->SDA_SETUP; + + obj->SDA_SETUP = (((uint32_t)setUpTime << I2C_SDA_SETUP_SDA_SETUP_SHIFT) | ((~I2C_SDA_SETUP_SDA_SETUP_MASK) & tRegValue)); +} + +/*! \brief Set ack for General Call + * + * this function configure the ack for the general call cmd + * + * \param[in] obj: base address for the i2cinstance + * \param[in] ackEn: + * false: Disable ack for general call + * true: Enable ack for general call + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetAckForGeneralCall(I2cRegType *obj, bool ackEn) +{ + uint32_t tRegValue = obj->ACK_GCALL; + + if(ackEn == true) + { + obj->ACK_GCALL = ((1ul << I2C_ACK_GCALL_ACK_GEN_CALL_SHIFT) | ((~I2C_ACK_GCALL_ACK_GEN_CALL_MASK) & tRegValue)); + } + else + { + obj->ACK_GCALL = ((0ul << I2C_ACK_GCALL_ACK_GEN_CALL_SHIFT) | ((~I2C_ACK_GCALL_ACK_GEN_CALL_MASK) & tRegValue)); + } +} + +/*! \brief Get slave rx data lost + * + * this function get the status if rx data is lost before + * + * \param[in] obj: base address for the i2cinstance + * \return: bool + * false: Slave RX data is not lost + * true: Slave RX data is lost + */ +__attribute__((always_inline)) static inline bool I2cReg_GetSlaveRxDataLostStatus(const I2cRegType *obj) +{ + bool tRtn = false; + + if((obj->ENABLE_STATUS & I2C_ENABLE_STATUS_SLV_RX_DATA_LOST_MASK) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief Get whether slave is disabled when active + * + * this function get the status if slave is disable but in busy status + * + * \param[in] obj: base address for the i2cinstance + * \return: bool + * false: slave is disabled when it is idle + * true: slave is disabled when it is active + */ +__attribute__((always_inline)) static inline bool I2cReg_GetSlaveDisabledWhileBusyStatus(const I2cRegType *obj) +{ + bool tRtn = false; + + if((obj->ENABLE_STATUS & I2C_ENABLE_STATUS_SLV_DISABLED_WHILE_BUSY_MASK) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief Get module enable status + * + * this function get the current status about module + * + * \param[in] obj: base address for the i2cinstance + * \return: bool + * false: disabled + * true: enabled + */ +__attribute__((always_inline)) static inline bool I2cReg_GetModuleEnableStatus(const I2cRegType *obj) +{ + bool tRtn = false; + + if((obj->ENABLE_STATUS & I2C_ENABLE_STATUS_EN_MASK) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief sets the duration about spike length + * + * ,measured in I2C_clk cycles, of the longest spike in the SCL or SDA lines that will be filtered out by the spike suppression logic + * + * \param[in] obj: base address for the i2cinstance + * \param[in] SpikeLen: the duration about spike length + * \return: void + */ +__attribute__((always_inline)) static inline void I2cReg_SetSpikeLen(I2cRegType *obj, uint8_t spikeLen) +{ + uint32_t tRegValue = obj->SPKLEN; + + obj->SPKLEN = (((uint32_t)spikeLen << I2C_SPKLEN_LEN_SHIFT) | ((~I2C_SPKLEN_LEN_MASK) & tRegValue)); +} + +/*! \brief Gets the duration,measured in I2C_clk cycles + * + * this function get the spike length ticks + * + * \param[in] obj: base address for the i2cinstance + * \return: the duration,measured in I2C_clk cycles + */ +__attribute__((always_inline)) static inline uint8_t I2cReg_GetSpikeLen(const I2cRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->SPKLEN & I2C_SPKLEN_LEN_MASK) >> I2C_SPKLEN_LEN_SHIFT) & 0xFF); + + return tRtn; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _I2C_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/i2sm_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/i2sm_reg.h new file mode 100644 index 0000000..ad20c90 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/i2sm_reg.h @@ -0,0 +1,702 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _I2SM_REG_H_ +#define _I2SM_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the I2SM Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* IER Bit Fields */ +#define I2SM_IER_EN_MASK (0x01u) +#define I2SM_IER_EN_SHIFT (0u) +#define I2SM_IER_EN_WIDTH (1u) + +/* ITER Bit Fields */ +#define I2SM_ITER_TXEN_MASK (0x01u) +#define I2SM_ITER_TXEN_SHIFT (0u) +#define I2SM_ITER_TXEN_WIDTH (1u) + +/* CER Bit Fields */ +#define I2SM_CER_CLKEN_MASK (0x01u) +#define I2SM_CER_CLKEN_SHIFT (0u) +#define I2SM_CER_CLKEN_WIDTH (1u) + +/* CCR Bit Fields */ +#define I2SM_CCR_WSS_MASK (0x18u) +#define I2SM_CCR_WSS_SHIFT (3u) +#define I2SM_CCR_WSS_WIDTH (2u) +#define I2SM_CCR_SCLKG_MASK (0x07u) +#define I2SM_CCR_SCLKG_SHIFT (0u) +#define I2SM_CCR_SCLKG_WIDTH (3u) + +/* TXFFR Bit Fields */ +#define I2SM_TXFFR_TXFFR_MASK (0x01u) +#define I2SM_TXFFR_TXFFR_SHIFT (0u) +#define I2SM_TXFFR_TXFFR_WIDTH (1u) + +/* LTHR0 Bit Fields */ +#define I2SM_LTHR0_LTHR0_MASK (0xFFFFFFFFu) +#define I2SM_LTHR0_LTHR0_SHIFT (0u) +#define I2SM_LTHR0_LTHR0_WIDTH (32u) + +/* RTHR0 Bit Fields */ +#define I2SM_RTHR0_RTHR0_MASK (0xFFFFFFFFu) +#define I2SM_RTHR0_RTHR0_SHIFT (0u) +#define I2SM_RTHR0_RTHR0_WIDTH (32u) + +/* TER0 Bit Fields */ +#define I2SM_TER0_TXCHEN0_MASK (0x01u) +#define I2SM_TER0_TXCHEN0_SHIFT (0u) +#define I2SM_TER0_TXCHEN0_WIDTH (1u) + +/* TCR0 Bit Fields */ +#define I2SM_TCR0_TX_WLEN_MASK (0x07u) +#define I2SM_TCR0_TX_WLEN_SHIFT (0u) +#define I2SM_TCR0_TX_WLEN_WIDTH (3u) + +/* ISR0 Bit Fields */ +#define I2SM_ISR0_TXFO_MASK (0x20u) +#define I2SM_ISR0_TXFO_SHIFT (5u) +#define I2SM_ISR0_TXFO_WIDTH (1u) +#define I2SM_ISR0_TXFE_MASK (0x10u) +#define I2SM_ISR0_TXFE_SHIFT (4u) +#define I2SM_ISR0_TXFE_WIDTH (1u) + +/* IMR0 Bit Fields */ +#define I2SM_IMR0_TXFOM_MASK (0x20u) +#define I2SM_IMR0_TXFOM_SHIFT (5u) +#define I2SM_IMR0_TXFOM_WIDTH (1u) +#define I2SM_IMR0_TXFEM_MASK (0x10u) +#define I2SM_IMR0_TXFEM_SHIFT (4u) +#define I2SM_IMR0_TXFEM_WIDTH (1u) + +/* TOR0 Bit Fields */ +#define I2SM_TOR0_TXCHO_MASK (0x01u) +#define I2SM_TOR0_TXCHO_SHIFT (0u) +#define I2SM_TOR0_TXCHO_WIDTH (1u) + +/* TFCR0 Bit Fields */ +#define I2SM_TFCR0_TFCR0_MASK (0x0Fu) +#define I2SM_TFCR0_TFCR0_SHIFT (0u) +#define I2SM_TFCR0_TFCR0_WIDTH (4u) + +/* TFF0 Bit Fields */ +#define I2SM_TFF0_TXCHFR0_MASK (0x01u) +#define I2SM_TFF0_TXCHFR0_SHIFT (0u) +#define I2SM_TFF0_TXCHFR0_WIDTH (1u) + +/* TXDMA Bit Fields */ +#define I2SM_TXDMA_TXDMA_MASK (0xFFFFFFFFu) +#define I2SM_TXDMA_TXDMA_SHIFT (0u) +#define I2SM_TXDMA_TXDMA_WIDTH (32u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of I2SM registers + */ +typedef struct _I2smRegType_ +{ + volatile uint32_t IER; /*!< module enable, offset: 0x00 */ + uint32_t RESERVED0[1]; /*!< Reserverd block, offset: 0x04 */ + volatile uint32_t ITER; /*!< transmit block enable, offset: 0x08 */ + volatile uint32_t CER; /*!< clock enable, offset: 0x0C */ + volatile uint32_t CCR; /*!< clock configuration register, offset: 0x10 */ + uint32_t RESERVED1[1]; /*!< Reserverd block, offset: 0x14 */ + volatile uint32_t TXFFR; /*!< TX FIFO reset, offset: 0x18 */ + uint32_t RESERVED2[1]; /*!< Reserverd block, offset: 0x1C */ + volatile uint32_t LTHR0; /*!< left stereo data, offset: 0x20 */ + volatile uint32_t RTHR0; /*!< right stereo data, offset: 0x24 */ + uint32_t RESERVED3[1]; /*!< Reserverd block, offset: 0x28 */ + volatile uint32_t TER0; /*!< transmit channel enable, offset: 0x2C */ + uint32_t RESERVED4[1]; /*!< Reserverd block, offset: 0x30 */ + volatile uint32_t TCR0; /*!< transmit configuration, offset: 0x34 */ + volatile uint32_t ISR0; /*!< interrupt status, offset: 0x38 */ + volatile uint32_t IMR0; /*!< interrupt mask, offset: 0x3C */ + uint32_t RESERVED5[1]; /*!< Reserverd block, offset: 0x40 */ + volatile uint32_t TOR0; /*!< transmit overrun status, offset: 0x44 */ + uint32_t RESERVED6[1]; /*!< Reserverd block, offset: 0x48 */ + volatile uint32_t TFCR0; /*!< TX FIFO configuration, offset: 0x4C */ + uint32_t RESERVED7[1]; /*!< Reserverd block, offset: 0x50 */ + volatile uint32_t TFF0; /*!< TX FIFO flush, offset: 0x54 */ + uint32_t RESERVED8[92]; /*!< Reserverd block, offset: 0x58 */ + volatile uint32_t TXDMA; /*!< Transmit DMA register, offset: 0x1C8 */ +} I2smRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the IP enable + * + * This function gets the current IP enable. + * + * \param[in] obj : pointer to I2SM register instance + * \return IP enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetIerEn(const I2smRegType *obj) +{ + return ((obj->IER & I2SM_IER_EN_MASK) >> I2SM_IER_EN_SHIFT); +} + +/*! \brief Sets the IP enable + * + * This function sets the IP enable. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of IP enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void I2smReg_SetIerEn(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IER; + + tmp &= ~I2SM_IER_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_IER_EN_SHIFT)) & I2SM_IER_EN_MASK); + obj->IER = tmp; +} + +/*! \brief Gets the transmit block enable + * + * This function gets the current transmit block enable. + * It enables or disables the transmit. + * + * \param[in] obj : pointer to I2SM register instance + * \return transmit block enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetIterTxEn(const I2smRegType *obj) +{ + return ((obj->ITER & I2SM_ITER_TXEN_MASK) >> I2SM_ITER_TXEN_SHIFT); +} + +/*! \brief Sets the transmit block enable + * + * This function sets the transmit block enable. + * It enables or disables the transmit. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of transmit block enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void I2smReg_SetIterTxEn(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ITER; + + tmp &= ~I2SM_ITER_TXEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_ITER_TXEN_SHIFT)) & I2SM_ITER_TXEN_MASK); + obj->ITER = tmp; +} + +/*! \brief Gets the master clock generation enable + * + * This function gets the current master clock generation enable. + * + * \param[in] obj : pointer to I2SM register instance + * \return master clock generation enable + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetCerClkEn(const I2smRegType *obj) +{ + return ((obj->CER & I2SM_CER_CLKEN_MASK) >> I2SM_CER_CLKEN_SHIFT); +} + +/*! \brief Sets the master clock generation enable + * + * This function sets the master clock generation enable. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of master clock generation enable + */ +__attribute__((always_inline)) static inline void I2smReg_SetCerClkEn(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CER; + + tmp &= ~I2SM_CER_CLKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_CER_CLKEN_SHIFT)) & I2SM_CER_CLKEN_MASK); + obj->CER = tmp; +} + +/*! \brief Gets the left/right channel period + * + * This function gets the current left/right channel period. + * It is used to program the number of sclk cycles for which ws_out stays in the left or right sample mode. + * The I2S Clock Generation block must be disabled (CER[0] = 0) prior to any changes in this value. + * + * \param[in] obj : pointer to I2SM register instance + * \return left/right channel period + * - 0h : 16 sclk cycles + * - 1h : 24 sclk cycles + * - 2h : 32 sclk cycles + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetCcrWss(const I2smRegType *obj) +{ + return ((obj->CCR & I2SM_CCR_WSS_MASK) >> I2SM_CCR_WSS_SHIFT); +} + +/*! \brief Sets the left/right channel period + * + * This function sets the left/right channel period. + * It is used to program the number of sclk cycles for which ws_out stays in the left or right sample mode. + * The I2S Clock Generation block must be disabled (CER[0] = 0) prior to any changes in this value. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of left/right channel period + * - 0h : 16 sclk cycles + * - 1h : 24 sclk cycles + * - 2h : 32 sclk cycles + */ +__attribute__((always_inline)) static inline void I2smReg_SetCcrWss(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CCR; + + tmp &= ~I2SM_CCR_WSS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_CCR_WSS_SHIFT)) & I2SM_CCR_WSS_MASK); + obj->CCR = tmp; +} + +/*! \brief Gets the clock gate period + * + * This function gets the current clock gate period. + * It is used to program the gating of sclk. + * The programmed gating value must be less than or equal to the largest configured/ programmed audio resolution + * to prevent the truncating of RX/TX data. + * The I2S Clock Generation block must be disabled (CER[0] = 0) before making any changes in this value. + * + * \param[in] obj : pointer to I2SM register instance + * \return clock gate period + * - 0h : disabled + * - 1h : gating after 12 sclk cycles + * - 2h : gating after 16 sclk cycles + * - 3h : gating after 20 sclk cycles + * - 4h : gating after 24 sclk cycles + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetCcrSclkg(const I2smRegType *obj) +{ + return ((obj->CCR & I2SM_CCR_SCLKG_MASK) >> I2SM_CCR_SCLKG_SHIFT); +} + +/*! \brief Sets the clock gate period + * + * This function sets the clock gate period. + * It is used to program the gating of sclk. + * The programmed gating value must be less than or equal to the largest configured/ programmed audio resolution + * to prevent the truncating of RX/TX data. + * The I2S Clock Generation block must be disabled (CER[0] = 0) before making any changes in this value. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of clock gate period + * - 0h : disabled + * - 1h : gating after 12 sclk cycles + * - 2h : gating after 16 sclk cycles + * - 3h : gating after 20 sclk cycles + * - 4h : gating after 24 sclk cycles + */ +__attribute__((always_inline)) static inline void I2smReg_SetCcrSclkg(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CCR; + + tmp &= ~I2SM_CCR_SCLKG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_CCR_SCLKG_SHIFT)) & I2SM_CCR_SCLKG_MASK); + obj->CCR = tmp; +} + +/*! \brief Sets the TX FIFO reset + * + * This function sets the TX FIFO reset. + * Writing a 1 to this register flushes all the TX FIFOs (this is a self clearing bit). + * The Transmitter Block must be disabled prior to writing this bit. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of TX FIFO reset + * - 0b : does not flush the TX FIFO + * - 1b : flush the TX FIFO + */ +__attribute__((always_inline)) static inline void I2smReg_SetTxffrTxFFR(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->TXFFR; + + tmp &= ~I2SM_TXFFR_TXFFR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_TXFFR_TXFFR_SHIFT)) & I2SM_TXFFR_TXFFR_MASK); + obj->TXFFR = tmp; +} + +/*! \brief Sets the left stereo data + * + * This function sets the left stereo data. + * The left stereo data to be transmitted serially through the transmit channel output (sdox) is written through this register. + * Writing is a two-stage process: + * 1. A write to this register passes the left stereo sample to the transmitter. + * 2. This MUST be followed by writing the right stereo sample to the RTHRx register + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of left stereo data + */ +__attribute__((always_inline)) static inline void I2smReg_SetLthr0Lthr0(I2smRegType *obj, uint32_t value) +{ + uint32_t tmp = obj->LTHR0; + + tmp &= ~I2SM_LTHR0_LTHR0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_LTHR0_LTHR0_SHIFT)) & I2SM_LTHR0_LTHR0_MASK); + obj->LTHR0 = tmp; +} + +/*! \brief Sets the right stereo data + * + * This function sets the right stereo data. + * The right stereo data to be transmitted serially through the + * transmit channel output (sdox) is written through this register. + * Writing is a two-stage process: + * 1. A left stereo sample MUST be written to the LTHRx register. + * 2. A write to this register passes the right stereo sample to the transmitte + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of right stereo data + */ +__attribute__((always_inline)) static inline void I2smReg_SetRthr0Rthr0(I2smRegType *obj, uint32_t value) +{ + uint32_t tmp = obj->RTHR0; + + tmp &= ~I2SM_RTHR0_RTHR0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_RTHR0_RTHR0_SHIFT)) & I2SM_RTHR0_RTHR0_MASK); + obj->RTHR0 = tmp; +} + +/*! \brief Gets the transmit channel enable + * + * This function gets the current transmit channel enable. + * + * \param[in] obj : pointer to I2SM register instance + * \return transmit channel enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetTer0TxChEn0(const I2smRegType *obj) +{ + return ((obj->TER0 & I2SM_TER0_TXCHEN0_MASK) >> I2SM_TER0_TXCHEN0_SHIFT); +} + +/*! \brief Sets the transmit channel enable + * + * This function sets the transmit channel enable. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of transmit channel enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void I2smReg_SetTer0TxChEn0(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->TER0; + + tmp &= ~I2SM_TER0_TXCHEN0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_TER0_TXCHEN0_SHIFT)) & I2SM_TER0_TXCHEN0_MASK); + obj->TER0 = tmp; +} + +/*! \brief Gets the transmit data width + * + * This function gets the current transmit data width. + * These bits are used to program the data resolution of the transmitter and ensures the MSB of the data is transmitted first. + * + * \param[in] obj : pointer to I2SM register instance + * \return transmit data width + * - 0h : ignore + * - 1h : 12bit data + * - 2h : 16bit data + * - 3h : 20bit data + * - 4h : 24bit data + * - 5h : 32bit data + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetTcr0TxWLen(const I2smRegType *obj) +{ + return ((obj->TCR0 & I2SM_TCR0_TX_WLEN_MASK) >> I2SM_TCR0_TX_WLEN_SHIFT); +} + +/*! \brief Sets the transmit data width + * + * This function sets the transmit data width. + * These bits are used to program the data resolution of the transmitter and ensures the MSB of the data is transmitted first. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of transmit data width + * - 0h : ignore + * - 1h : 12bit data + * - 2h : 16bit data + * - 3h : 20bit data + * - 4h : 24bit data + * - 5h : 32bit data + */ +__attribute__((always_inline)) static inline void I2smReg_SetTcr0TxWLen(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->TCR0; + + tmp &= ~I2SM_TCR0_TX_WLEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_TCR0_TX_WLEN_SHIFT)) & I2SM_TCR0_TX_WLEN_MASK); + obj->TCR0 = tmp; +} + +/*! \brief Gets the TX FIFO write status + * + * This function gets the current TX FIFO write status. + * + * \param[in] obj : pointer to I2SM register instance + * \return TX FIFO write status + * - 0b : TX FIFO write valid + * - 1b : TX FIFO write overrun + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetIsr0TxFO(const I2smRegType *obj) +{ + return ((obj->ISR0 & I2SM_ISR0_TXFO_MASK) >> I2SM_ISR0_TXFO_SHIFT); +} + +/*! \brief Gets the TX FIFO reached trigger level + * + * This function gets the current TX FIFO reached trigger level. + * This bit specifies whether the TX FIFO trigger level has reached or not. TX FIFO is empty. + * + * \param[in] obj : pointer to I2SM register instance + * \return TX FIFO reached trigger level + * - 0b : TX FIFO trigger level is reached + * - 1b : TX FIFO trigger level is not reached + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetIsr0TxFE(const I2smRegType *obj) +{ + return ((obj->ISR0 & I2SM_ISR0_TXFE_MASK) >> I2SM_ISR0_TXFE_SHIFT); +} + +/*! \brief Gets the TX FIFO overrun interrupt mask + * + * This function gets the current TX FIFO overrun interrupt mask. + * + * \param[in] obj : pointer to I2SM register instance + * \return TX FIFO overrun interrupt mask + * - 0b : unmasks TX FIFO overrun interrupt + * - 1b : mask TX FIFO overrun interrupt + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetImr0TxFom(const I2smRegType *obj) +{ + return ((obj->IMR0 & I2SM_IMR0_TXFOM_MASK) >> I2SM_IMR0_TXFOM_SHIFT); +} + +/*! \brief Sets the TX FIFO overrun interrupt mask + * + * This function sets the TX FIFO overrun interrupt mask. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of TX FIFO overrun interrupt mask + * - 0b : unmasks TX FIFO overrun interrupt + * - 1b : mask TX FIFO overrun interrupt + */ +__attribute__((always_inline)) static inline void I2smReg_SetImr0TxFom(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IMR0; + + tmp &= ~I2SM_IMR0_TXFOM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_IMR0_TXFOM_SHIFT)) & I2SM_IMR0_TXFOM_MASK); + obj->IMR0 = tmp; +} + +/*! \brief Gets the TX FIFO empty interrupt mask + * + * This function gets the current TX FIFO empty interrupt mask. + * + * \param[in] obj : pointer to I2SM register instance + * \return TX FIFO empty interrupt mask + * - 0b : unmasks TX FIFO empty interrupt + * - 1b : mask TX FIFO empty interrupt + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetImr0TxFem(const I2smRegType *obj) +{ + return ((obj->IMR0 & I2SM_IMR0_TXFEM_MASK) >> I2SM_IMR0_TXFEM_SHIFT); +} + +/*! \brief Sets the TX FIFO empty interrupt mask + * + * This function sets the TX FIFO empty interrupt mask. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of TX FIFO empty interrupt mask + * - 0b : unmasks TX FIFO empty interrupt + * - 1b : mask TX FIFO empty interrupt + */ +__attribute__((always_inline)) static inline void I2smReg_SetImr0TxFem(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IMR0; + + tmp &= ~I2SM_IMR0_TXFEM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_IMR0_TXFEM_SHIFT)) & I2SM_IMR0_TXFEM_MASK); + obj->IMR0 = tmp; +} + +/*! \brief Gets the TX FIFO write overrun + * + * This function gets the current TX FIFO write overrun. + * + * \param[in] obj : pointer to I2SM register instance + * \return TX FIFO write overrun + * - 0b : TX FIFO write valid + * - 1b : TX FIFO write overrun + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetTor0TxChO(const I2smRegType *obj) +{ + return ((obj->TOR0 & I2SM_TOR0_TXCHO_MASK) >> I2SM_TOR0_TXCHO_SHIFT); +} + +/*! \brief Sets the TX FIFO write overrun + * + * This function sets the TX FIFO write overrun. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of TX FIFO write overrun + * - 0b : TX FIFO write valid + * - 1b : TX FIFO write overrun + */ +__attribute__((always_inline)) static inline void I2smReg_SetTor0TxChO(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->TOR0; + + tmp &= ~I2SM_TOR0_TXCHO_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_TOR0_TXCHO_SHIFT)) & I2SM_TOR0_TXCHO_MASK); + obj->TOR0 = tmp; +} + +/*! \brief Gets the FIFO level trigger + * + * This function gets the current FIFO level trigger. + * When the FIFO level reaches the register, interrupt triggers. + * These bits program the trigger level in the RX FIFO at which the Received Data Available interrupt is generated. + * Trigger Level = Programmed Value + 1 + * If an illegal value is programmed, these bits saturate to (I2S_RX_FIFO_x - 1). + * The channel must be disabled prior to any changes in this value (that is, RER0[0] = 0). + * + * \param[in] obj : pointer to I2SM register instance + * \return FIFO level trigger + * - 0h : 1 + * - 1h : 2 + * - 2h : 3 + * - 3h : 4 + * - 4h : 5 + * - 5h : 6 + * - 6h : 7 + * - 7h : 8 + * - ... + * - Fh : 16 + */ +__attribute__((always_inline)) static inline uint8_t I2smReg_GetTfcr0Tfcr0(const I2smRegType *obj) +{ + return ((obj->TFCR0 & I2SM_TFCR0_TFCR0_MASK) >> I2SM_TFCR0_TFCR0_SHIFT); +} + +/*! \brief Sets the FIFO level trigger + * + * This function sets the FIFO level trigger. + * When the FIFO level reaches the register, interrupt triggers. + * These bits program the trigger level in the RX FIFO at which the Received Data Available interrupt is generated. + * Trigger Level = Programmed Value + 1 + * If an illegal value is programmed, these bits saturate to (I2S_RX_FIFO_x - 1). + * The channel must be disabled prior to any changes in this value (that is, RER0[0] = 0). + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of FIFO level trigger + * - 0h : 1 + * - 1h : 2 + * - 2h : 3 + * - 3h : 4 + * - 4h : 5 + * - 5h : 6 + * - 6h : 7 + * - 7h : 8 + * - ... + * - Fh : 16 + */ +__attribute__((always_inline)) static inline void I2smReg_SetTfcr0Tfcr0(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->TFCR0; + + tmp &= ~I2SM_TFCR0_TFCR0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_TFCR0_TFCR0_SHIFT)) & I2SM_TFCR0_TFCR0_MASK); + obj->TFCR0 = tmp; +} + +/*! \brief Sets the TX FIFO flush + * + * This function sets the TX FIFO flush. + * Writing a 1 to this register flushes channel's TX FIFO (This is a self clearing bit.). + * The TX channel or block must be disabled prior to writing to this bit. + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of TX FIFO flush + * - 0b : Does not flush an individual TX FIFO + * - 1b : flush an individual TX FIFO + */ +__attribute__((always_inline)) static inline void I2smReg_SetTff0TxChfr0(I2smRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->TFF0; + + tmp &= ~I2SM_TFF0_TXCHFR0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_TFF0_TXCHFR0_SHIFT)) & I2SM_TFF0_TXCHFR0_MASK); + obj->TFF0 = tmp; +} + +/*! \brief Sets the Transmitter Block DMA Register + * + * This function sets the Transmitter Block DMA Register. + * The register bits can be used to cycle repeatedly through the enabled Transmit channels (from lowest numbered to + * highest) to allow writing of stereo data pairs + * + * \param[in] obj : pointer to I2SM register instance + * \param[in] value : the value of Transmitter Block DMA Register + */ +__attribute__((always_inline)) static inline void I2smReg_SetTxDmaTxDma(I2smRegType *obj, uint32_t value) +{ + uint32_t tmp = obj->TXDMA; + + tmp &= ~I2SM_TXDMA_TXDMA_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SM_TXDMA_TXDMA_SHIFT)) & I2SM_TXDMA_TXDMA_MASK); + obj->TXDMA = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _I2SM_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/i2ss_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/i2ss_reg.h new file mode 100644 index 0000000..d815bf7 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/i2ss_reg.h @@ -0,0 +1,549 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _I2SS_REG_H_ +#define _I2SS_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the I2SS Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* IER Bit Fields */ +#define I2SS_IER_EN_MASK (0x01u) +#define I2SS_IER_EN_SHIFT (0u) +#define I2SS_IER_EN_WIDTH (1u) + +/* IRER Bit Fields */ +#define I2SS_IRER_RXEN_MASK (0x01u) +#define I2SS_IRER_RXEN_SHIFT (0u) +#define I2SS_IRER_RXEN_WIDTH (1u) + +/* RXFFR Bit Fields */ +#define I2SS_RXFFR_RXFFR_MASK (0x01u) +#define I2SS_RXFFR_RXFFR_SHIFT (0u) +#define I2SS_RXFFR_RXFFR_WIDTH (1u) + +/* LRBR0 Bit Fields */ +#define I2SS_LRBR0_LRBR0_MASK (0x01u) +#define I2SS_LRBR0_LRBR0_SHIFT (0u) +#define I2SS_LRBR0_LRBR0_WIDTH (1u) + +/* RRBR0 Bit Fields */ +#define I2SS_RRBR0_RRBR0_MASK (0x01u) +#define I2SS_RRBR0_RRBR0_SHIFT (0u) +#define I2SS_RRBR0_RRBR0_WIDTH (1u) + +/* RER0 Bit Fields */ +#define I2SS_RER0_CH0_MASK (0x01u) +#define I2SS_RER0_CH0_SHIFT (0u) +#define I2SS_RER0_CH0_WIDTH (1u) + +/* RCR0 Bit Fields */ +#define I2SS_RCR0_RX_WLEN_MASK (0x07u) +#define I2SS_RCR0_RX_WLEN_SHIFT (0u) +#define I2SS_RCR0_RX_WLEN_WIDTH (3u) + +/* ISR0 Bit Fields */ +#define I2SS_ISR0_RXFO_MASK (0x02u) +#define I2SS_ISR0_RXFO_SHIFT (1u) +#define I2SS_ISR0_RXFO_WIDTH (1u) +#define I2SS_ISR0_RXDA_MASK (0x01u) +#define I2SS_ISR0_RXDA_SHIFT (0u) +#define I2SS_ISR0_RXDA_WIDTH (1u) + +/* IMR0 Bit Fields */ +#define I2SS_IMR0_RXFOM_MASK (0x02u) +#define I2SS_IMR0_RXFOM_SHIFT (1u) +#define I2SS_IMR0_RXFOM_WIDTH (1u) +#define I2SS_IMR0_RXDAM_MASK (0x01u) +#define I2SS_IMR0_RXDAM_SHIFT (0u) +#define I2SS_IMR0_RXDAM_WIDTH (1u) + +/* ROR0 Bit Fields */ +#define I2SS_ROR0_RXCHO_MASK (0x01u) +#define I2SS_ROR0_RXCHO_SHIFT (0u) +#define I2SS_ROR0_RXCHO_WIDTH (1u) + +/* RFCR0 Bit Fields */ +#define I2SS_RFCR0_RXCHDT_MASK (0x0Fu) +#define I2SS_RFCR0_RXCHDT_SHIFT (0u) +#define I2SS_RFCR0_RXCHDT_WIDTH (4u) + +/* RFF0 Bit Fields */ +#define I2SS_RFF0_RXCHFR0_MASK (0x01u) +#define I2SS_RFF0_RXCHFR0_SHIFT (0u) +#define I2SS_RFF0_RXCHFR0_WIDTH (1u) + +/* RXDMA Bit Fields */ +#define I2SS_RXDMA_RXDMA_MASK (0xFFFFFFFFu) +#define I2SS_RXDMA_RXDMA_SHIFT (0u) +#define I2SS_RXDMA_RXDMA_WIDTH (32u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of I2SS registers + */ +typedef struct _I2ssRegType_ +{ + volatile uint32_t IER; /*!< module enable, offset: 0x00 */ + volatile uint32_t IRER; /*!< receiver block enable, offset: 0x04 */ + uint32_t RESERVED0[3]; /*!< Reserverd block, offset: 0x08 */ + volatile uint32_t RXFFR; /*!< RX FIFO reset, offset: 0x14 */ + uint32_t RESERVED1[2]; /*!< Reserverd block, offset: 0x18 */ + const volatile uint32_t LRBR0; /*!< left receive buffer, offset: 0x20 */ + const volatile uint32_t RRBR0; /*!< right receive buffer, offset: 0x24 */ + volatile uint32_t RER0; /*!< receive channel0 enable, offset: 0x28 */ + uint32_t RESERVED2[1]; /*!< Reserverd block, offset: 0x2C */ + volatile uint32_t RCR0; /*!< receive configuration, offset: 0x30 */ + uint32_t RESERVED3[1]; /*!< Reserverd block, offset: 0x34 */ + const volatile uint32_t ISR0; /*!< interrupt status, offset: 0x38 */ + volatile uint32_t IMR0; /*!< interrupt mask, offset: 0x3C */ + volatile uint32_t ROR0; /*!< receive overrun, offset: 0x40 */ + uint32_t RESERVED4[1]; /*!< Reserverd block, offset: 0x44 */ + volatile uint32_t RFCR0; /*!< RX FIFO configuration, offset: 0x48 */ + uint32_t RESERVED5[1]; /*!< Reserverd block, offset: 0x4C */ + volatile uint32_t RFF0; /*!< RX FIFO flush, offset: 0x50 */ + uint32_t RESERVED6[91]; /*!< Reserverd block, offset: 0x54 */ + const volatile uint32_t RXDMA; /*!< Receive DMA register, offset: 0x1C0 */ +} I2ssRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the IP enable + * + * This function gets the current IP enable. + * + * \param[in] obj : pointer to I2SS register instance + * \return IP enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetIerEn(const I2ssRegType *obj) +{ + return ((obj->IER & I2SS_IER_EN_MASK) >> I2SS_IER_EN_SHIFT); +} + +/*! \brief Sets the IP enable + * + * This function sets the IP enable. + * + * \param[in] obj : pointer to I2SS register instance + * \param[in] value : the value of IP enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void I2ssReg_SetIerEn(I2ssRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IER; + + tmp &= ~I2SS_IER_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SS_IER_EN_SHIFT)) & I2SS_IER_EN_MASK); + obj->IER = tmp; +} + +/*! \brief Gets the receiver block enable + * + * This function gets the current receiver block enable. + * It enables or disables the receiver. + * + * \param[in] obj : pointer to I2SS register instance + * \return receiver block enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetIrerRxEn(const I2ssRegType *obj) +{ + return ((obj->IRER & I2SS_IRER_RXEN_MASK) >> I2SS_IRER_RXEN_SHIFT); +} + +/*! \brief Sets the receiver block enable + * + * This function sets the receiver block enable. + * It enables or disables the receiver. + * + * \param[in] obj : pointer to I2SS register instance + * \param[in] value : the value of receiver block enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void I2ssReg_SetIrerRxEn(I2ssRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IRER; + + tmp &= ~I2SS_IRER_RXEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SS_IRER_RXEN_SHIFT)) & I2SS_IRER_RXEN_MASK); + obj->IRER = tmp; +} + +/*! \brief Sets the RX FIFO reset + * + * This function sets the RX FIFO reset. + * Writing a 1 to this register flushes all the FIFOs (this is a self clearing bit). + * The Transmitter Block must be disabled prior to writing this bit. + * + * \param[in] obj : pointer to I2SS register instance + * \param[in] value : the value of RX FIFO reset + * - 0b : does not flush the FIFO + * - 1b : flush the FIFO + */ +__attribute__((always_inline)) static inline void I2ssReg_SetRxffrRxffr(I2ssRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RXFFR; + + tmp &= ~I2SS_RXFFR_RXFFR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SS_RXFFR_RXFFR_SHIFT)) & I2SS_RXFFR_RXFFR_MASK); + obj->RXFFR = tmp; +} + +/*! \brief Gets the left stereo data + * + * This function gets the current left stereo data. + * The left stereo data received serially from the receive channel input + * + * \param[in] obj : pointer to I2SS register instance + * \return left stereo data + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetLrbr0Lrbr0(const I2ssRegType *obj) +{ + return ((obj->LRBR0 & I2SS_LRBR0_LRBR0_MASK) >> I2SS_LRBR0_LRBR0_SHIFT); +} + +/*! \brief Gets the right stereo data + * + * This function gets the current right stereo data. + * The right stereo data received serially from the receive channel input + * + * \param[in] obj : pointer to I2SS register instance + * \return right stereo data + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetRrbr0Rrbr0(const I2ssRegType *obj) +{ + return ((obj->RRBR0 & I2SS_RRBR0_RRBR0_MASK) >> I2SS_RRBR0_RRBR0_SHIFT); +} + +/*! \brief Gets the receive channel enable + * + * This function gets the current receive channel enable. + * + * \param[in] obj : pointer to I2SS register instance + * \return receive channel enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetRer0Ch0(const I2ssRegType *obj) +{ + return ((obj->RER0 & I2SS_RER0_CH0_MASK) >> I2SS_RER0_CH0_SHIFT); +} + +/*! \brief Sets the receive channel enable + * + * This function sets the receive channel enable. + * + * \param[in] obj : pointer to I2SS register instance + * \param[in] value : the value of receive channel enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void I2ssReg_SetRer0Ch0(I2ssRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RER0; + + tmp &= ~I2SS_RER0_CH0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SS_RER0_CH0_SHIFT)) & I2SS_RER0_CH0_MASK); + obj->RER0 = tmp; +} + +/*! \brief Gets the receive data width + * + * This function gets the current receive data width. + * These bits are used to program the data resolution of the receiver and ensures the MSB of the data is transmitted first. + * + * \param[in] obj : pointer to I2SS register instance + * \return receive data width + * - 0h : ignore + * - 1h : 12bit data + * - 2h : 16bit data + * - 3h : 20bit data + * - 4h : 24bit data + * - 5h : 32bit data + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetRcr0RxWLen(const I2ssRegType *obj) +{ + return ((obj->RCR0 & I2SS_RCR0_RX_WLEN_MASK) >> I2SS_RCR0_RX_WLEN_SHIFT); +} + +/*! \brief Sets the receive data width + * + * This function sets the receive data width. + * These bits are used to program the data resolution of the receiver and ensures the MSB of the data is transmitted first. + * + * \param[in] obj : pointer to I2SS register instance + * \param[in] value : the value of receive data width + * - 0h : ignore + * - 1h : 12bit data + * - 2h : 16bit data + * - 3h : 20bit data + * - 4h : 24bit data + * - 5h : 32bit data + */ +__attribute__((always_inline)) static inline void I2ssReg_SetRcr0RxWLen(I2ssRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RCR0; + + tmp &= ~I2SS_RCR0_RX_WLEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SS_RCR0_RX_WLEN_SHIFT)) & I2SS_RCR0_RX_WLEN_MASK); + obj->RCR0 = tmp; +} + +/*! \brief Gets the RX FIFO data overrun interrupt + * + * This function gets the current RX FIFO data overrun interrupt. + * Incoming data lost due to a full RX FIFO. + * + * \param[in] obj : pointer to I2SS register instance + * \return RX FIFO data overrun interrupt + * - 0b : RX FIFO write valid + * - 1b : RX FIFO write overrun + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetIsr0RxFo(const I2ssRegType *obj) +{ + return ((obj->ISR0 & I2SS_ISR0_RXFO_MASK) >> I2SS_ISR0_RXFO_SHIFT); +} + +/*! \brief Gets the Status of Receive Data Available interrupt + * + * This function gets the current Status of Receive Data Available interrupt. + * This bit denotes the status of the RX FIFO trigger level. + * + * \param[in] obj : pointer to I2SS register instance + * \return Status of Receive Data Available interrupt + * - 0b : RX FIFO trigger level is reached + * - 1b : RX FIFO trigger level is not reached + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetIsr0RxDa(const I2ssRegType *obj) +{ + return ((obj->ISR0 & I2SS_ISR0_RXDA_MASK) >> I2SS_ISR0_RXDA_SHIFT); +} + +/*! \brief Gets the RX FIFO overrun interrupt mask + * + * This function gets the current RX FIFO overrun interrupt mask. + * + * \param[in] obj : pointer to I2SS register instance + * \return RX FIFO overrun interrupt mask + * - 0b : unmasks RX FIFO overrun interrupt + * - 1b : mask RX FIFO overrun interrupt + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetImr0RxFom(const I2ssRegType *obj) +{ + return ((obj->IMR0 & I2SS_IMR0_RXFOM_MASK) >> I2SS_IMR0_RXFOM_SHIFT); +} + +/*! \brief Sets the RX FIFO overrun interrupt mask + * + * This function sets the RX FIFO overrun interrupt mask. + * + * \param[in] obj : pointer to I2SS register instance + * \param[in] value : the value of RX FIFO overrun interrupt mask + * - 0b : unmasks RX FIFO overrun interrupt + * - 1b : mask RX FIFO overrun interrupt + */ +__attribute__((always_inline)) static inline void I2ssReg_SetImr0RxFom(I2ssRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IMR0; + + tmp &= ~I2SS_IMR0_RXFOM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SS_IMR0_RXFOM_SHIFT)) & I2SS_IMR0_RXFOM_MASK); + obj->IMR0 = tmp; +} + +/*! \brief Gets the Mask RX FIFO Data Available interrupt. + * + * This function gets the current Mask RX FIFO Data Available interrupt. + * This bit masks or unmasks an RX FIFO Data Available interrupt. + * + * \param[in] obj : pointer to I2SS register instance + * \return Mask RX FIFO Data Available interrupt. + * - 1b : Masks RX FIFO data available interrupt + * - 0b : Unmasks RX FIFO data available interrupt + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetImr0RxDam(const I2ssRegType *obj) +{ + return ((obj->IMR0 & I2SS_IMR0_RXDAM_MASK) >> I2SS_IMR0_RXDAM_SHIFT); +} + +/*! \brief Sets the Mask RX FIFO Data Available interrupt. + * + * This function sets the Mask RX FIFO Data Available interrupt. + * This bit masks or unmasks an RX FIFO Data Available interrupt. + * + * \param[in] obj : pointer to I2SS register instance + * \param[in] value : the value of Mask RX FIFO Data Available interrupt. + * - 1b : Masks RX FIFO data available interrupt + * - 0b : Unmasks RX FIFO data available interrupt + */ +__attribute__((always_inline)) static inline void I2ssReg_SetImr0RxDam(I2ssRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IMR0; + + tmp &= ~I2SS_IMR0_RXDAM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SS_IMR0_RXDAM_SHIFT)) & I2SS_IMR0_RXDAM_MASK); + obj->IMR0 = tmp; +} + +/*! \brief Gets the RX FIFO write overrun + * + * This function gets the current RX FIFO write overrun. + * + * \param[in] obj : pointer to I2SS register instance + * \return RX FIFO write overrun + * - 0b : RX FIFO write valid + * - 1b : RX FIFO write overrun + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetRor0RxChO(const I2ssRegType *obj) +{ + return ((obj->ROR0 & I2SS_ROR0_RXCHO_MASK) >> I2SS_ROR0_RXCHO_SHIFT); +} + +/*! \brief Sets the RX FIFO write overrun + * + * This function sets the RX FIFO write overrun. + * + * \param[in] obj : pointer to I2SS register instance + * \param[in] value : the value of RX FIFO write overrun + * - 0b : RX FIFO write valid + * - 1b : RX FIFO write overrun + */ +__attribute__((always_inline)) static inline void I2ssReg_SetRor0RxChO(I2ssRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ROR0; + + tmp &= ~I2SS_ROR0_RXCHO_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SS_ROR0_RXCHO_SHIFT)) & I2SS_ROR0_RXCHO_MASK); + obj->ROR0 = tmp; +} + +/*! \brief Gets the FIFO level trigger interrupt + * + * This function gets the current FIFO level trigger interrupt. + * When the FIFO level reaches the register, interrupt triggers. + * + * \param[in] obj : pointer to I2SS register instance + * \return FIFO level trigger interrupt + * - 0h : 1 + * - 1h : 2 + * - 2h : 3 + * - 3h : 4 + * - 4h : 5 + * - 5h : 6 + * - 6h : 7 + * - 7h : 8 + * - ... + * - Fh : 16 + */ +__attribute__((always_inline)) static inline uint8_t I2ssReg_GetRfcr0RxChdt(const I2ssRegType *obj) +{ + return ((obj->RFCR0 & I2SS_RFCR0_RXCHDT_MASK) >> I2SS_RFCR0_RXCHDT_SHIFT); +} + +/*! \brief Sets the FIFO level trigger interrupt + * + * This function sets the FIFO level trigger interrupt. + * When the FIFO level reaches the register, interrupt triggers. + * + * \param[in] obj : pointer to I2SS register instance + * \param[in] value : the value of FIFO level trigger interrupt + * - 0h : 1 + * - 1h : 2 + * - 2h : 3 + * - 3h : 4 + * - 4h : 5 + * - 5h : 6 + * - 6h : 7 + * - 7h : 8 + * - ... + * - Fh : 16 + */ +__attribute__((always_inline)) static inline void I2ssReg_SetRfcr0RxChdt(I2ssRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RFCR0; + + tmp &= ~I2SS_RFCR0_RXCHDT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SS_RFCR0_RXCHDT_SHIFT)) & I2SS_RFCR0_RXCHDT_MASK); + obj->RFCR0 = tmp; +} + +/*! \brief Sets the RX FIFO flush + * + * This function sets the RX FIFO flush. + * Writing a 1 to this register flushes an individual RX FIFO (This is a self clearing bit.). + * A Rx channel or block must be disabled prior to writing to this bit. + * + * \param[in] obj : pointer to I2SS register instance + * \param[in] value : the value of RX FIFO flush + * - 0b : Does not flush an individual RX FIFO + * - 1b : flush an individual RX FIFO + */ +__attribute__((always_inline)) static inline void I2ssReg_SetRff0RxChfr0(I2ssRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RFF0; + + tmp &= ~I2SS_RFF0_RXCHFR0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << I2SS_RFF0_RXCHFR0_SHIFT)) & I2SS_RFF0_RXCHFR0_MASK); + obj->RFF0 = tmp; +} + +/*! \brief Gets the Receive Block DMA Register + * + * This function gets the current Receive Block DMA Register. + * These bits are used to cycle repeatedly through the enabled receive channels (from lowest numbered to highest), + * reading stereo data pairs + * + * \param[in] obj : pointer to I2SS register instance + * \return Receive Block DMA Register + */ +__attribute__((always_inline)) static inline uint32_t I2ssReg_GetRxDmaRxDma(const I2ssRegType *obj) +{ + return ((obj->RXDMA & I2SS_RXDMA_RXDMA_MASK) >> I2SS_RXDMA_RXDMA_SHIFT); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _I2SS_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/lpit_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/lpit_reg.h new file mode 100644 index 0000000..51dd74e --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/lpit_reg.h @@ -0,0 +1,813 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _LPIT_REG_H_ +#define _LPIT_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the LPIT (Low Power Interrupt Timer) Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* Size of TMR Registers Arrays */ +#define LPIT_TMR_COUNT (4) + +/* VERID Bit Fields */ +#define LPIT_VERID_VERID_MASK (0xFFFFFFFFu) +#define LPIT_VERID_VERID_SHIFT (0u) +#define LPIT_VERID_VERID_WIDTH (32u) + +/* PARAM Bit Fields */ +#define LPIT_PARAM_CHANNEL_MASK (0xFFu) +#define LPIT_PARAM_CHANNEL_SHIFT (0u) +#define LPIT_PARAM_CHANNEL_WIDTH (8u) +#define LPIT_PARAM_EXT_TRIG_MASK (0xFF00u) +#define LPIT_PARAM_EXT_TRIG_SHIFT (8u) +#define LPIT_PARAM_EXT_TRIG_WIDTH (8u) + +/* MCR Bit Fields */ +#define LPIT_MCR_M_CEN_MASK (0x1u) +#define LPIT_MCR_M_CEN_SHIFT (0u) +#define LPIT_MCR_M_CEN_WIDTH (1u) +#define LPIT_MCR_LP_EN_MASK (0x4u) +#define LPIT_MCR_LP_EN_SHIFT (2u) +#define LPIT_MCR_LP_EN_WIDTH (1u) +#define LPIT_MCR_DBG_EN_MASK (0x8u) +#define LPIT_MCR_DBG_EN_SHIFT (3u) +#define LPIT_MCR_DBG_EN_WIDTH (1u) + +/* MSR Bit Fields */ +#define LPIT_MSR_TIF0_MASK (0x1u) +#define LPIT_MSR_TIF0_SHIFT (0u) +#define LPIT_MSR_TIF0_WIDTH (1u) +#define LPIT_MSR_TIF1_MASK (0x2u) +#define LPIT_MSR_TIF1_SHIFT (1u) +#define LPIT_MSR_TIF1_WIDTH (1u) +#define LPIT_MSR_TIF2_MASK (0x4u) +#define LPIT_MSR_TIF2_SHIFT (2u) +#define LPIT_MSR_TIF2_WIDTH (1u) +#define LPIT_MSR_TIF3_MASK (0x8u) +#define LPIT_MSR_TIF3_SHIFT (3u) +#define LPIT_MSR_TIF3_WIDTH (1u) + +/* MIER Bit Fields */ +#define LPIT_MIER_TIE0_MASK (0x1u) +#define LPIT_MIER_TIE0_SHIFT (0u) +#define LPIT_MIER_TIE0_WIDTH (1u) +#define LPIT_MIER_TIE1_MASK (0x2u) +#define LPIT_MIER_TIE1_SHIFT (1u) +#define LPIT_MIER_TIE1_WIDTH (1u) +#define LPIT_MIER_TIE2_MASK (0x4u) +#define LPIT_MIER_TIE2_SHIFT (2u) +#define LPIT_MIER_TIE2_WIDTH (1u) +#define LPIT_MIER_TIE3_MASK (0x8u) +#define LPIT_MIER_TIE3_SHIFT (3u) +#define LPIT_MIER_TIE3_WIDTH (1u) + +/* SETTEN Bit Fields */ +#define LPIT_SETTEN_SET_T_EN_0_MASK (0x1u) +#define LPIT_SETTEN_SET_T_EN_0_SHIFT (0u) +#define LPIT_SETTEN_SET_T_EN_0_WIDTH (1u) +#define LPIT_SETTEN_SET_T_EN_1_MASK (0x2u) +#define LPIT_SETTEN_SET_T_EN_1_SHIFT (1u) +#define LPIT_SETTEN_SET_T_EN_1_WIDTH (1u) +#define LPIT_SETTEN_SET_T_EN_2_MASK (0x4u) +#define LPIT_SETTEN_SET_T_EN_2_SHIFT (2u) +#define LPIT_SETTEN_SET_T_EN_2_WIDTH (1u) +#define LPIT_SETTEN_SET_T_EN_3_MASK (0x8u) +#define LPIT_SETTEN_SET_T_EN_3_SHIFT (3u) +#define LPIT_SETTEN_SET_T_EN_3_WIDTH (1u) + +/* CLRTEN Bit Fields */ +#define LPIT_CLRTEN_CLR_T_EN_0_MASK (0x1u) +#define LPIT_CLRTEN_CLR_T_EN_0_SHIFT (0u) +#define LPIT_CLRTEN_CLR_T_EN_0_WIDTH (1u) +#define LPIT_CLRTEN_CLR_T_EN_1_MASK (0x2u) +#define LPIT_CLRTEN_CLR_T_EN_1_SHIFT (1u) +#define LPIT_CLRTEN_CLR_T_EN_1_WIDTH (1u) +#define LPIT_CLRTEN_CLR_T_EN_2_MASK (0x4u) +#define LPIT_CLRTEN_CLR_T_EN_2_SHIFT (2u) +#define LPIT_CLRTEN_CLR_T_EN_2_WIDTH (1u) +#define LPIT_CLRTEN_CLR_T_EN_3_MASK (0x8u) +#define LPIT_CLRTEN_CLR_T_EN_3_SHIFT (3u) +#define LPIT_CLRTEN_CLR_T_EN_3_WIDTH (1u) + +/* TMR_TVAL Bit Fields */ +#define LPIT_TMR_TVAL_TMR_VAL_MASK (0xFFFFFFFFu) +#define LPIT_TMR_TVAL_TMR_VAL_SHIFT (0u) +#define LPIT_TMR_TVAL_TMR_VAL_WIDTH (32u) + +/* TMR_CVAL Bit Fields */ +#define LPIT_TMR_CVAL_TMR_CUR_VAL_MASK (0xFFFFFFFFu) +#define LPIT_TMR_CVAL_TMR_CUR_VAL_SHIFT (0u) +#define LPIT_TMR_CVAL_TMR_CUR_VAL_WIDTH (32u) + +/* TMR_TCTRL Bit Fields */ +#define LPIT_TMR_TCTRL_T_EN_MASK (0x1u) +#define LPIT_TMR_TCTRL_T_EN_SHIFT (0u) +#define LPIT_TMR_TCTRL_T_EN_WIDTH (1u) +#define LPIT_TMR_TCTRL_CHAIN_MASK (0x2u) +#define LPIT_TMR_TCTRL_CHAIN_SHIFT (1u) +#define LPIT_TMR_TCTRL_CHAIN_WIDTH (1u) +#define LPIT_TMR_TCTRL_MODE_MASK (0xCu) +#define LPIT_TMR_TCTRL_MODE_SHIFT (2u) +#define LPIT_TMR_TCTRL_MODE_WIDTH (2u) +#define LPIT_TMR_TCTRL_TSOT_MASK (0x10000u) +#define LPIT_TMR_TCTRL_TSOT_SHIFT (16u) +#define LPIT_TMR_TCTRL_TSOT_WIDTH (1u) +#define LPIT_TMR_TCTRL_TSOI_MASK (0x20000u) +#define LPIT_TMR_TCTRL_TSOI_SHIFT (17u) +#define LPIT_TMR_TCTRL_TSOI_WIDTH (1u) +#define LPIT_TMR_TCTRL_TROT_MASK (0x40000u) +#define LPIT_TMR_TCTRL_TROT_SHIFT (18u) +#define LPIT_TMR_TCTRL_TROT_WIDTH (1u) +#define LPIT_TMR_TCTRL_TRG_SRC_MASK (0x800000u) +#define LPIT_TMR_TCTRL_TRG_SRC_SHIFT (23u) +#define LPIT_TMR_TCTRL_TRG_SRC_WIDTH (1u) +#define LPIT_TMR_TCTRL_TRG_SEL_MASK (0xF000000u) +#define LPIT_TMR_TCTRL_TRG_SEL_SHIFT (24u) +#define LPIT_TMR_TCTRL_TRG_SEL_WIDTH (4u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of LPIT registers + */ +typedef struct _LpitRegType_ +{ + const volatile uint32_t VERID; /*!< Version ID Register, offset: 0x0 */ + const volatile uint32_t PARAM; /*!< Parameter Register, offset: 0x4 */ + volatile uint32_t MCR; /*!< Module Control Register, offset: 0x8 */ + volatile uint32_t MSR; /*!< Module Status Register, offset: 0xC */ + volatile uint32_t MIER; /*!< Module Interrupt Enable Register, offset: 0x10 */ + volatile uint32_t SETTEN; /*!< Set Timer Enable Register, offset: 0x14 */ + volatile uint32_t CLRTEN; /*!< Clear Timer Enable Register, offset: 0x18 */ + uint32_t RESERVED; /*!< Reserved register, offset: 0x1C */ + struct + { /* offset: 0x20, array step: 0x10 */ + volatile uint32_t TVAL; /*!< Timer Value Register, array offset: 0x20, array step: 0x10 */ + const volatile uint32_t CVAL; /*!< Current Timer Value, array offset: 0x24, array step: 0x10 */ + volatile uint32_t TCTRL; /*!< Timer Control Register, array offset: 0x28, array step: 0x10 */ + uint32_t RESERVED; /*!< Reserved register, offset: 0x2C */ + } TMR[LPIT_TMR_COUNT]; +} LpitRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Get the version ID of LPIT module. + * + * This function returns the version ID of LPIT module of this chip + * + * \param[in] obj : pointer to LPIT register instance + * \return the version ID + */ +__attribute__((always_inline)) static inline uint32_t LpitReg_GetVersion(const LpitRegType *obj) +{ + return ((obj->VERID & LPIT_VERID_VERID_MASK) >> LPIT_VERID_VERID_SHIFT); +} + +/*! \brief Get the number of Timer Channels. + * + * This function returns the number of Timer Channels in this device + * + * \param[in] obj : pointer to LPIT register instance + * \return the number of Timer Channels + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetTimerChannelNum(const LpitRegType *obj) +{ + return ((obj->PARAM & LPIT_PARAM_CHANNEL_MASK) >> LPIT_PARAM_CHANNEL_SHIFT); +} + +/*! \brief Get the number of external triggers input. + * + * This function returns the external triggers implemented in this device + * + * \param[in] obj : pointer to LPIT register instance + * \return the number of external triggers input + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetExtTriggerNum(const LpitRegType *obj) +{ + return ((obj->PARAM & LPIT_PARAM_EXT_TRIG_MASK) >> LPIT_PARAM_EXT_TRIG_SHIFT); +} + +/*! \brief Enables the LPIT module. + * + * This function enables the functional clock of LPIT module (it does not + * affect the system clock gating control). + * + * \note The M_CEN bit must be asserted when accessing these registers: + * - Module Status Register (MSR) + * - Set Timer Enable Register (SETTEN) + * - Clear Timer Enable Register (CLRTEN) + * - Timer Value Registers (TVALn) + * - Current Timer Value Registers (CVALn) + * - Timer Control Registers (TCTRLn) + * Accessing the above mentioned registers while M_CEN = '0', will assert a transfer error for that bus cycle. + * - 0 : those registers above write disable + * - 1 : those registers above write enable + * + * \param[in] obj : pointer to LPIT register instance + */ +__attribute__((always_inline)) static inline void LpitReg_Enable(LpitRegType *obj) +{ + uint32_t tmp = obj->MCR; + + tmp &= ~LPIT_MCR_M_CEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(1u)) << LPIT_MCR_M_CEN_SHIFT)) & LPIT_MCR_M_CEN_MASK); + obj->MCR = tmp; +} + +/*! \brief Disable the LPIT module. + * + * This function disables functional clock of LPIT module (it does not + * affect the system clock gating control). + * + * \note The M_CEN bit must be asserted when accessing these registers: + * - Module Status Register (MSR) + * - Set Timer Enable Register (SETTEN) + * - Clear Timer Enable Register (CLRTEN) + * - Timer Value Registers (TVALn) + * - Current Timer Value Registers (CVALn) + * - Timer Control Registers (TCTRLn) + * Acessing the above mentioned registers while M_CEN = '0', will assert a transfer error for that bus cycle. + * - 0 : those registers above write disable + * - 1 : those registers above write enable + * + * \param[in] obj : pointer to LPIT register instance + */ +__attribute__((always_inline)) static inline void LpitReg_Disable(LpitRegType *obj) +{ + uint32_t tmp = obj->MCR; + + tmp &= ~LPIT_MCR_M_CEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(0u)) << LPIT_MCR_M_CEN_SHIFT)) & LPIT_MCR_M_CEN_MASK); + obj->MCR = tmp; +} + +/*! \brief Get the current command of LowPower Mode + * + * This function returns the current command of LowPower Mode + * + * \param[in] obj : pointer to LPIT register instance + * \return the current command of LP Mode + * - 0 : stop timer channels in LowPower mode + * - 1 : allow timer channels to continue to run in LP mode + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetLpModeCmd(const LpitRegType *obj) +{ + return ((obj->MCR & LPIT_MCR_LP_EN_MASK) >> LPIT_MCR_LP_EN_SHIFT); +} + +/*! \brief Sets operation of LPIT in LowPower Mode. + * + * When the device enters debug mode, the timer channels may or may not be frozen, + * based on the configuration of this function. The LPIT must use an external or + * internal clock source which remains operating during LowPower mode + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] value : the current command of LowPower Mode + * - 0 : stop timer channels in LP mode + * - 1 : allow timer channels to continue to run in LP mode + */ +__attribute__((always_inline)) static inline void LpitReg_SetLpModeCmd(LpitRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MCR; + + tmp &= ~LPIT_MCR_LP_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << LPIT_MCR_LP_EN_SHIFT)) & LPIT_MCR_LP_EN_MASK); + obj->MCR = tmp; +} + +/*! \brief Get the current command of debug mode + * + * This function returns the current command of debug mode + * + * \param[in] obj : pointer to LPIT register instance + * \return the current command of debug mode + * - 0 : stop timer channels in debug mode + * - 1 : allow timer channels to continue to run in debug mode + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetDebugModeCmd(const LpitRegType *obj) +{ + return ((obj->MCR & LPIT_MCR_DBG_EN_MASK) >> LPIT_MCR_DBG_EN_SHIFT); +} + +/*! \brief Sets operation of LPIT in debug mode. + * + * When the device enters debug mode, the timer channels may or may not be frozen, + * based on the configuration of this function. This is intended to aid software development, + * allowing the developer to halt the processor, investigate the current state of + * the system (for example, the timer channel values), and continue the operation. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] value : the current command of debug mode + * - 0 : stop timer channels in debug mode + * - 1 : allow timer channels to continue to run in debug mode + */ +__attribute__((always_inline)) static inline void LpitReg_SetDebugModeCmd(LpitRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MCR; + + tmp &= ~LPIT_MCR_DBG_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << LPIT_MCR_DBG_EN_SHIFT)) & LPIT_MCR_DBG_EN_MASK); + obj->MCR = tmp; +} + +/*! \brief Gets the interrupt flag of timer channels. + * + * This function gets current interrupt flag of timer channels. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] mask : the interrupt flag getting mask that decides which channels will be got interrupt flag. + * For example: + * - with mask = 0x01u then the interrupt flag of channel 0 only will be got + * - with mask = 0x02u then the interrupt flag of channel 1 only will be got + * - with mask = 0x03u then the interrupt flags of channel 0 and channel 1 will be got + * \return the interrupt flag of timer channels. + */ +__attribute__((always_inline)) static inline uint32_t LpitReg_GetInterruptFlag(const LpitRegType *obj, uint32_t mask) +{ + return (obj->MSR) & mask; +} + +/*! \brief Clears the interrupt flag of timer channels. + * + * This function clears current interrupt flag of timer channels. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] mask : the interrupt flag getting mask that decides which channels will be got interrupt flag. + * For example: + * - with mask = 0x01u then the interrupt flag of channel 0 only will be cleared + * - with mask = 0x02u then the interrupt flag of channel 1 only will be cleared + * - with mask = 0x03u then the interrupt flags of channel 0 and channel 1 will be cleared + */ +__attribute__((always_inline)) static inline void LpitReg_ClearInterruptFlag(LpitRegType *obj, uint32_t mask) +{ + /* Write 1 to clear the interrupt flag. */ + obj->MSR = mask; +} + +/*! \brief Enables the interrupt generation for timer channels. + * + * This function allows enabling interrupt generation for timer channels simultaneously. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] mask : the interrupt enabling mask that decides which channels will be enabled interrupt. + * For example: + * - with mask = 0x01u then will enable interrupt for channel 0 only + * - with mask = 0x02u then will enable interrupt for channel 1 only + * - with mask = 0x03u then will enable interrupt for channel 0 and channel 1 + */ +__attribute__((always_inline)) static inline void LpitReg_EnableInterruptTimerChannels(LpitRegType *obj, uint32_t mask) +{ + obj->MIER |= mask; +} + +/*! \brief Clears the interrupt flag of timer channels. + * + * This function allows disabling interrupt generation for timer channels simultaneously. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] mask : the interrupt disabling mask that decides which channels will be disabled interrupt. + * For example: + * - with mask = 0x01u then will disable interrupt for channel 0 only + * - with mask = 0x02u then will disable interrupt for channel 1 only + * - with mask = 0x03u then will disable interrupt for channel 0 and channel 1 + */ +__attribute__((always_inline)) static inline void LpitReg_DisableInterruptTimerChannels(LpitRegType *obj, uint32_t mask) +{ + obj->MIER &= ~mask; +} + +/*! \brief Starts the timer channel counting. + * + * This function allows starting timer channels simultaneously. + * After calling this function, timer channels are going operate depend on mode and + * control bits which controls timer channel start, reload and restart. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] mask : timer channels starting mask that decides which channels will be started + * For example: + * - with mask = 0x01U then channel 0 will be started + * - with mask = 0x02U then channel 1 will be started + * - with mask = 0x03U then channel 0 and channel 1 will be started + */ +__attribute__((always_inline)) static inline void LpitReg_StartTimerChannels(LpitRegType *obj, uint32_t mask) +{ + obj->SETTEN |= mask; +} + +/*! \brief Stops the timer channel from counting. + * + * This function allows stop timer channels simultaneously from counting. + * Timer channels reload their periods respectively after the next time + * they call the LPIT_DRV_StartTimerChannels. Note that: In 32-bit Trigger Accumulator + * mode, the counter will load on the first trigger rising edge. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] mask : timer channels stopping mask that decides which channels will be stopped + * For example: + * - with mask = 0x01U then channel 0 will be stopped + * - with mask = 0x02U then channel 1 will be stopped + * - with mask = 0x03U then channel 0 and channel 1 will be stopped + */ +__attribute__((always_inline)) static inline void LpitReg_StopTimerChannels(LpitRegType *obj, uint32_t mask) +{ + obj->CLRTEN |= mask; +} + +/*! \brief Gets the timer channel period in count unit. + * + * This function returns current period of timer channel given as argument. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \return timer channel period in count unit + */ +__attribute__((always_inline)) static inline uint32_t LpitReg_GetTimerPeriodByCount(const LpitRegType *obj, uint8_t channel) +{ + return obj->TMR[channel].TVAL; +} + +/*! \brief Sets the timer channel period in count unit. + * + * This function sets the timer channel period in count unit. + * - In compare mode: Timer Value (TMR_VAL) is the timer channel start value. + * - The timer will count down until the timer reaches 0, then the timer will generate + * an interrupt and load the Timer Value register (TVALn) value again. + * - Writing a new value to the Timer Value register (TVALn) will not restart the timer channel; + * instead the new value will be loaded after the timer expires. + * - To abort the current timer cycle and start a timer period with a new value, the timer channel must be disabled and enabled again. + * - In capture mode: whenever the trigger asserts, the Timer Value register stores the inverse of the counter value. + - 00000000h : Invalid load value in compare mode + - 00000001h : Invalid load value in compare mode + - 00000002h-ffffffffh : In compare mode: the value to be loaded; in capture mode, the value of the timer + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \param[in] count : timer channel period in count unit + */ +__attribute__((always_inline)) static inline void LpitReg_SetTimerPeriodByCount(LpitRegType *obj, uint8_t channel, uint32_t count) +{ + obj->TMR[channel].TVAL = count; +} + +/*! \brief Gets the current timer channel counting value. + * + * This function returns the real-time timer channel counting value, the value in + * a range from 0 to timer channel period. + * Need to make sure the running time does not exceed the timer channel period. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \return current timer channel counting value + */ +__attribute__((always_inline)) static inline uint32_t LpitReg_GetCurrentTimerCount(const LpitRegType *obj, uint8_t channel) +{ + return obj->TMR[channel].CVAL; +} + +/*! \brief Gets current state of time channel enable + * + * This function gets the current state of time channel enable + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \return the current state of time channel enable + * - 0 : timer Channel is disabled, counter reset to 0xffff_ffff + * - 1 : timer Channel is enabled + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetTimerChannelEnable(const LpitRegType *obj, uint8_t channel) +{ + return ((obj->TMR[channel].TCTRL & LPIT_TMR_TCTRL_T_EN_MASK) >> LPIT_TMR_TCTRL_T_EN_SHIFT); +} + +/*! \brief Enables or disables the Timer Channel + * + * This function enables or disables the Timer Channel + * + * \note If this bit is set, SET_T_EN_n will also be set + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \param[in] enable : operation mode of timer channel + * - 0 : timer Channel is disabled, counter reset to 0xffff_ffff + * - 1 : timer Channel is enabled + */ +__attribute__((always_inline)) static inline void LpitReg_SetTimerChannelEnable(LpitRegType *obj, uint8_t channel, uint8_t enable) +{ + uint32_t tmp = obj->TMR[channel].TCTRL; + + tmp &= ~LPIT_TMR_TCTRL_T_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(enable)) << LPIT_TMR_TCTRL_T_EN_SHIFT)) & LPIT_TMR_TCTRL_T_EN_MASK); + obj->TMR[channel].TCTRL = tmp; +} + +/*! \brief Gets current state of timer channel chaining. + * + * This function gets the current state of timer channel chaining. + * When enabled, the timer channel will decrement when timer channel N-1 trigger asserts. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \return the current state of timer channel chaining + * - 0 : Channel Chaining is disabled. The channel timer runs independently. + * - 1 : Channel Chaining is enabled. The timer decrements on the previous channel's timeout. + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetTimerChannelChainCmd(const LpitRegType *obj, uint8_t channel) +{ + return ((obj->TMR[channel].TCTRL & LPIT_TMR_TCTRL_CHAIN_MASK) >> LPIT_TMR_TCTRL_CHAIN_SHIFT); +} + +/*! \brief Sets timer channel chaining. + * + * This function sets the timer channel to be chained or not chained. + * When enabled, the timer channel will decrement when timer channel N-1 trigger asserts. + * + * \note Timer channel 0 cannot be chained. + * + * \note If this bit is set, SET_T_EN_n will also be set + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \param[in] isChannelChained : timer channel chaining + * - 0 : Channel Chaining is disabled. The channel timer runs independently. + * - 1 : Channel Chaining is enabled. The timer decrements on the previous channel's timeout. + */ +__attribute__((always_inline)) static inline void LpitReg_SetTimerChannelChainCmd(LpitRegType *obj, uint8_t channel, uint8_t isChannelChained) +{ + uint32_t tmp = obj->TMR[channel].TCTRL; + + tmp &= ~LPIT_TMR_TCTRL_CHAIN_MASK; + tmp |= (((uint32_t)(((uint32_t)(isChannelChained)) << LPIT_TMR_TCTRL_CHAIN_SHIFT)) & LPIT_TMR_TCTRL_CHAIN_MASK); + obj->TMR[channel].TCTRL = tmp; +} + +/*! \brief Gets current operation mode of timer channel. + * + * This function gets current operation mode of the timer channel given as argument. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \return operation mode of timer channel + * - 0 : 32-bit Periodic Counter + * - 1 : Dual 16-bit Periodic Counter + * - 2 : 32-bit Trigger Accumulator + * - 3 : 32-bit Trigger Input Capture + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetTimerChannelModeCmd(const LpitRegType *obj, uint8_t channel) +{ + return ((obj->TMR[channel].TCTRL & LPIT_TMR_TCTRL_MODE_MASK) >> LPIT_TMR_TCTRL_MODE_SHIFT); +} + +/*! \brief Sets operation mode of timer channel + * + * This function sets the timer channel operation mode which control how + * the timer channel decrements. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \param[in] mode : operation mode of timer channel + * - 0 : 32-bit Periodic Counter + * - 1 : Dual 16-bit Periodic Counter + * - 2 : 32-bit Trigger Accumulator + * - 3 : 32-bit Trigger Input Capture + */ +__attribute__((always_inline)) static inline void LpitReg_SetTimerChannelModeCmd(LpitRegType *obj, uint8_t channel, uint8_t mode) +{ + uint32_t tmp = obj->TMR[channel].TCTRL; + + tmp &= ~LPIT_TMR_TCTRL_MODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(mode)) << LPIT_TMR_TCTRL_MODE_SHIFT)) & LPIT_TMR_TCTRL_MODE_MASK); + obj->TMR[channel].TCTRL = tmp; +} + +/*! \brief Gets current command of timer channel start on trigger. + * + * This function gets current command of timer channel start on trigger. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \return current command of timer channel start on trigger. + * - 0 : Timer starts to decrement immediately based on the restart condition + * (controlled by the Timer Stop On Interrupt bit (TSOI)) + * - 1 : Timer starts to decrement when a rising edge on a selected trigger is detected + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetStartOnTriggerCmd(const LpitRegType *obj, uint8_t channel) +{ + return ((obj->TMR[channel].TCTRL & LPIT_TMR_TCTRL_TSOT_MASK) >> LPIT_TMR_TCTRL_TSOT_SHIFT); +} + +/*! \brief Sets timer channel start on trigger. + * + * This function sets the timer channel to starts/don't start on trigger. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \param[in] isStartOnTrigger : timer channel start on trigger + * - 0 : Timer starts to decrement immediately based on the restart condition + * (controlled by the Timer Stop On Interrupt bit (TSOI)) + * - 1 : Timer starts to decrement when a rising edge on a selected trigger is detected + */ +__attribute__((always_inline)) static inline void LpitReg_SetStartOnTriggerCmd(LpitRegType *obj, uint8_t channel, uint8_t isStartOnTrigger) +{ + uint32_t tmp = obj->TMR[channel].TCTRL; + + tmp &= ~LPIT_TMR_TCTRL_TSOT_MASK; + tmp |= (((uint32_t)(((uint32_t)(isStartOnTrigger)) << LPIT_TMR_TCTRL_TSOT_SHIFT)) & LPIT_TMR_TCTRL_TSOT_MASK); + obj->TMR[channel].TCTRL = tmp; +} + +/*! \brief Gets current command of timer channel stop on interrupt. + * + * This function gets current command of timer channel stop on interrupt. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \return current command of timer channel stop on interrupt. + * - 0 : the channel timer does not stop after timeout + * - 1 : The channel timer will stop after a timeout, + * and the channel timer will restart based on Timer Start On Trigger bit (TSOT). + * When TSOT = 0, the channel timer will restart after a rising edge on the Timer Enable bit (T_EN) is detected + * (which means that the timer channel is disabled and then enabled). + * When TSOT = 1, the channel timer will restart after a rising edge on the selected trigger is detected. + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetStopOnInterruptCmd(const LpitRegType *obj, uint8_t channel) +{ + return ((obj->TMR[channel].TCTRL & LPIT_TMR_TCTRL_TSOI_MASK) >> LPIT_TMR_TCTRL_TSOI_SHIFT); +} + +/*! \brief Sets timer channel stop on interrupt. + * + * This function sets the timer channel to stop or don't stop after it times out. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \param[in] isStopOnInterrupt : timer channel stop on interrupt + * - 0 : the channel timer does not stop after timeout + * - 1 : The channel timer will stop after a timeout, + * and the channel timer will restart based on Timer Start On Trigger bit (TSOT). + * When TSOT = 0, the channel timer will restart after a rising edge on the Timer Enable bit (T_EN) is detected + * (which means that the timer channel is disabled and then enabled). + * When TSOT = 1, the channel timer will restart after a rising edge on the selected trigger is detected. + */ +__attribute__((always_inline)) static inline void LpitReg_SetStopOnInterruptCmd(LpitRegType *obj, uint8_t channel, uint8_t isStopOnInterrupt) +{ + uint32_t tmp = obj->TMR[channel].TCTRL; + + tmp &= ~LPIT_TMR_TCTRL_TSOI_MASK; + tmp |= (((uint32_t)(((uint32_t)(isStopOnInterrupt)) << LPIT_TMR_TCTRL_TSOI_SHIFT)) & LPIT_TMR_TCTRL_TSOI_MASK); + obj->TMR[channel].TCTRL = tmp; +} + +/*! \brief Gets current command of timer channel reload on trigger. + * + * This function gets current command of timer channel reload on trigger. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \return current command of timer channel reload on trigger. + * - 0 : timer will not reload on the selected trigger + * - 1 : timer will reload on the selected trigger + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetReloadOnTriggerCmd(const LpitRegType *obj, uint8_t channel) +{ + return ((obj->TMR[channel].TCTRL & LPIT_TMR_TCTRL_TROT_MASK) >> LPIT_TMR_TCTRL_TROT_SHIFT); +} + +/*! \brief Sets timer channel reload on trigger. + * + * This function sets the timer channel to reload/don't reload on trigger. + * When set, the LPIT timer will reload when a rising edge is detected on the selected trigger input. + * The trigger input is ignored if the LPIT is disabled during debug mode (DBGEN = 0) or LowPower mode + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \param[in] isReloadOnTrigger : timer channel reload on trigger + * - 0 : timer will not reload on the selected trigger + * - 1 : timer will reload on the selected trigger + */ +__attribute__((always_inline)) static inline void LpitReg_SetReloadOnTriggerCmd(LpitRegType *obj, uint8_t channel, uint8_t isReloadOnTrigger) +{ + uint32_t tmp = obj->TMR[channel].TCTRL; + + tmp &= ~LPIT_TMR_TCTRL_TROT_MASK; + tmp |= (((uint32_t)(((uint32_t)(isReloadOnTrigger)) << LPIT_TMR_TCTRL_TROT_SHIFT)) & LPIT_TMR_TCTRL_TROT_MASK); + obj->TMR[channel].TCTRL = tmp; +} + +/*! \brief Gets current command of timer channel trigger source. + * + * This function gets current command of timer channel trigger source. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \return current trigger source of timer channel. + * - 0 : selects external triggers + * - 1 : selects internal triggers + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetTriggerSourceCmd(const LpitRegType *obj, uint8_t channel) +{ + return ((obj->TMR[channel].TCTRL & LPIT_TMR_TCTRL_TRG_SRC_MASK) >> LPIT_TMR_TCTRL_TRG_SRC_SHIFT); +} + +/*! \brief Sets trigger source of timer channel. + * + * This function sets trigger source of the timer channel to be internal or external trigger. + * Selects between internal or external trigger sources. The trigger to be used is selected using the TRG_SRC and TRG_SEL bits. + * Refer to the chip configuration section for available external trigger options. + * If a channel does not have an associated external trigger, then set the Trigger Source bit (TRG_SRC) = 1. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \param[in] triggerSource : timer channel reload on trigger + * - 0 : selects external triggers + * - 1 : selects internal triggers + */ +__attribute__((always_inline)) static inline void LpitReg_SetTriggerSourceCmd(LpitRegType *obj, uint8_t channel, uint8_t triggerSource) +{ + uint32_t tmp = obj->TMR[channel].TCTRL; + + tmp &= ~LPIT_TMR_TCTRL_TRG_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(triggerSource)) << LPIT_TMR_TCTRL_TRG_SRC_SHIFT)) & LPIT_TMR_TCTRL_TRG_SRC_MASK); + obj->TMR[channel].TCTRL = tmp; +} + +/*! \brief Gets the selection of the trigger to use for starting and/or reloading the LPIT timer. + * + * This function gets the selection of the trigger to use for starting and/or reloading the LPIT timer. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \return current selection. + * - 0 ~ 3 : timer channel 0 ~ 3 trigger source is selected + * - 4 ~ 15 : reserved + */ +__attribute__((always_inline)) static inline uint8_t LpitReg_GetTriggerSelectCmd(const LpitRegType *obj, uint8_t channel) +{ + return ((obj->TMR[channel].TCTRL & LPIT_TMR_TCTRL_TRG_SEL_MASK) >> LPIT_TMR_TCTRL_TRG_SEL_SHIFT); +} + +/*! \brief Selects the trigger to use for starting and/or reloading the LPIT timer. + * + * This function selects the trigger to use for starting and/or reloading the LPIT timer. + * + * The TRG_SEL field selects one trigger from the set of internal or external triggers + * that are selected by the Trigger Source bit (TRG_SRC) + * Recall that the TRG_SRC bit selects between internal and external trigger signals for each channel + * + * \note The Trigger Select field should only be changed when the LPIT timer channel is disabled. + * + * \param[in] obj : pointer to LPIT register instance + * \param[in] channel : timer channel number + * \param[in] triggerChannelSelect : selection of the trigger + * - 0 ~ 3 : timer channel 0 ~ 3 trigger source is selected + * - 4 ~ 15 : reserved + */ +__attribute__((always_inline)) static inline void LpitReg_SetTriggerSelectCmd(LpitRegType *obj, uint8_t channel, uint8_t triggerChannelSelect) +{ + uint32_t tmp = obj->TMR[channel].TCTRL; + + tmp &= ~LPIT_TMR_TCTRL_TRG_SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(triggerChannelSelect)) << LPIT_TMR_TCTRL_TRG_SEL_SHIFT)) & LPIT_TMR_TCTRL_TRG_SEL_MASK); + obj->TMR[channel].TCTRL = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _LPIT_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/lptmr_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/lptmr_reg.h new file mode 100644 index 0000000..9cf66a3 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/lptmr_reg.h @@ -0,0 +1,555 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _LPTMR_REG_H_ +#define _LPTMR_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the LPTMR (Low Power Timer) Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* CSR Bit Fields */ +#define LPTMR_CSR_TEN_MASK (0x1u) +#define LPTMR_CSR_TEN_SHIFT (0u) +#define LPTMR_CSR_TEN_WIDTH (1u) +#define LPTMR_CSR_TMS_MASK (0x2u) +#define LPTMR_CSR_TMS_SHIFT (1u) +#define LPTMR_CSR_TMS_WIDTH (1u) +#define LPTMR_CSR_TFC_MASK (0x4u) +#define LPTMR_CSR_TFC_SHIFT (2u) +#define LPTMR_CSR_TFC_WIDTH (1u) +#define LPTMR_CSR_TPP_MASK (0x8u) +#define LPTMR_CSR_TPP_SHIFT (3u) +#define LPTMR_CSR_TPP_WIDTH (1u) +#define LPTMR_CSR_TPS_MASK (0x30u) +#define LPTMR_CSR_TPS_SHIFT (4u) +#define LPTMR_CSR_TPS_WIDTH (2u) +#define LPTMR_CSR_TIE_MASK (0x40u) +#define LPTMR_CSR_TIE_SHIFT (6u) +#define LPTMR_CSR_TIE_WIDTH (1u) +#define LPTMR_CSR_TCF_MASK (0x80u) +#define LPTMR_CSR_TCF_SHIFT (7u) +#define LPTMR_CSR_TCF_WIDTH (1u) +#define LPTMR_CSR_TDRE_MASK (0x100u) +#define LPTMR_CSR_TDRE_SHIFT (8u) +#define LPTMR_CSR_TDRE_WIDTH (1u) + +/* PSR Bit Fields */ +#define LPTMR_PSR_PBYP_MASK (0x4u) +#define LPTMR_PSR_PBYP_SHIFT (2u) +#define LPTMR_PSR_PBYP_WIDTH (1u) +#define LPTMR_PSR_PRESCALE_MASK (0x78u) +#define LPTMR_PSR_PRESCALE_SHIFT (3u) +#define LPTMR_PSR_PRESCALE_WIDTH (4u) + +/* CMR Bit Fields */ +#define LPTMR_CMR_COMPARE_MASK (0xFFFFu) +#define LPTMR_CMR_COMPARE_SHIFT (0u) +#define LPTMR_CMR_COMPARE_WIDTH (16u) + +/* CNR Bit Fields */ +#define LPTMR_CNR_COUNTER_MASK (0xFFFFu) +#define LPTMR_CNR_COUNTER_SHIFT (0u) +#define LPTMR_CNR_COUNTER_WIDTH (16u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of LPTMR registers + */ +typedef struct _LptmrRegType_ +{ + volatile uint32_t CSR; /*!< Low Power Timer Control Status Register, offset: 0x0 */ + volatile uint32_t PSR; /*!< Low Power Timer Prescale Register, offset: 0x4 */ + volatile uint32_t CMR; /*!< Low Power Timer Compare Register, offset: 0x8 */ + volatile uint32_t CNR; /*!< Low Power Timer Counter Register, offset: 0xC */ +} LptmrRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Get the Enable state. + * + * This function get the enable state of LPTMR. + * When TEN is clear, it resets the LPTMR internal logic, including the CNR and TCF. + * When TEN is set, the LPTMR is enabled. + * + * \param[in] obj : pointer to LPTMR register instance + * \return the state of the LPTMR + * - 0 : LPTMR is disabled and internal logic is reset. + * - 1 : LPTMR is enabled. + */ +__attribute__((always_inline)) static inline uint8_t LptmrReg_GetEnable(const LptmrRegType *obj) +{ + return ((obj->CSR & LPTMR_CSR_TEN_MASK) >> LPTMR_CSR_TEN_SHIFT); +} + +/*! \brief Set the 32 bits of LPTMR data register + * + * This function write new data to LPTMR calculator + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to LPTMR register instance + * \param[in] value : the state of the LPTMR + * - 0 : LPTMR is disabled and internal logic is reset. + * - 1 : LPTMR is enabled. + */ +__attribute__((always_inline)) static inline void LptmrReg_SetEnable(LptmrRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CSR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~(LPTMR_CSR_TEN_MASK | LPTMR_CSR_TCF_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << LPTMR_CSR_TEN_SHIFT)) & LPTMR_CSR_TEN_MASK); + obj->CSR = tmp; +} + +/*! \brief Get current Work Mode. + * + * This function returns the currently configured Work Mode for the LPTMR. + * + * \param[in] obj : pointer to LPTMR register instance + * \return Work Mode + * - 0 : Timer Counter Mode + * - 1 : Pulse Counter Mode + */ +__attribute__((always_inline)) static inline uint8_t LptmrReg_GetWorkMode(const LptmrRegType *obj) +{ + return ((obj->CSR & LPTMR_CSR_TMS_MASK) >> LPTMR_CSR_TMS_SHIFT); +} + +/*! \brief Set the Work Mode of LPTMR + * + * This function configures the Work Mode for the LPTMR. + * + * \note TMS must be altered only when the LPTMR is disabled. + * + * \param[in] obj : pointer to LPTMR register instance + * \param[in] value : the work mode of the LPTMR + * - 0 : Timer Counter Mode. + * - 1 : Pulse Counter Mode. + */ +__attribute__((always_inline)) static inline void LptmrReg_SetWorkMode(LptmrRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CSR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~(LPTMR_CSR_TMS_MASK | LPTMR_CSR_TCF_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << LPTMR_CSR_TMS_SHIFT)) & LPTMR_CSR_TMS_MASK); + obj->CSR = tmp; +} + +/*! \brief Get Free Running state + * + * This function checks whether the Free Running feature of the LPTMR is enabled or disabled. + * When clear, TFC configures the CNR to reset whenever TCF is set. + * When set, TFC configures the CNR to reset on overflow + * + * \param[in] obj : pointer to LPTMR register instance + * \return free running mode state + * - 0 : CNR is reset whenever TCF is set + * - 1 : CNR is reset on overflow + */ +__attribute__((always_inline)) static inline uint8_t LptmrReg_GetFreeRunning(const LptmrRegType *obj) +{ + return ((obj->CSR & LPTMR_CSR_TFC_MASK) >> LPTMR_CSR_TFC_SHIFT); +} + +/*! \brief Set the Free Running state + * + * This function configures the Free Running state for the LPTMR. + * When clear, TFC configures the CNR to reset whenever TCF is set. + * When set, TFC configures the CNR to reset on overflow + * + * \note TFC must be altered only when the LPTMR is disabled. + * + * \param[in] obj : pointer to LPTMR register instance + * \param[in] value : free running mode state + * - 0 : CNR is reset whenever TCF is set + * - 1 : CNR is reset on overflow + */ +__attribute__((always_inline)) static inline void LptmrReg_SetFreeRunning(LptmrRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CSR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~(LPTMR_CSR_TFC_MASK | LPTMR_CSR_TCF_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << LPTMR_CSR_TFC_SHIFT)) & LPTMR_CSR_TFC_MASK); + obj->CSR = tmp; +} + +/*! \brief Get Pin Polarity for Pulse Counter Mode + * + * This function returns the configured pin polarity that triggers an increment + * in Pulse Counter Mode. + * + * \param[in] obj : pointer to LPTMR register instance + * \return the pin polarity for Pulse Counter Mode + * - 0 : Pulse Counter input source is active-high, and the CNR increments on the rising-edge. + * - 1 : Pulse Counter input source is active-low, and the CNR increments on the falling-edge. + */ +__attribute__((always_inline)) static inline uint8_t LptmrReg_GetPinPolarity(const LptmrRegType *obj) +{ + return ((obj->CSR & LPTMR_CSR_TPP_MASK) >> LPTMR_CSR_TPP_SHIFT); +} + +/*! \brief Set Pin Polarity for Pulse Counter Mode + * + * This function configures the pin polarity that triggers an increment in Pulse + * Counter Mode. This feature can be configured only when the LPTMR is disabled. + * + * \note TPP must be changed only when the LPTMR is disabled. + * + * \param[in] obj : pointer to LPTMR register instance + * \param[in] value : the pin polarity to count in Pulse Counter Mode + * - 0 : Pulse Counter input source is active-high, and the CNR increments on the rising-edge. + * - 1 : Pulse Counter input source is active-low, and the CNR increments on the falling-edge. + */ +__attribute__((always_inline)) static inline void LptmrReg_SetPinPolarity(LptmrRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CSR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~(LPTMR_CSR_TPP_MASK | LPTMR_CSR_TCF_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << LPTMR_CSR_TPP_SHIFT)) & LPTMR_CSR_TPP_MASK); + obj->CSR = tmp; +} + +/*! \brief Get the Pin select for Counter Mode + * + * This function returns the configured Input Pin for Pulse Counter Mode. + * The input connections vary by device. See the chip configuration information + * about connections to these inputs. + * + * \param[in] obj : pointer to LPTMR register instance + * \return pin selection + * - 0 : Pulse counter input 0 is selected. + * - 1 : Pulse counter input 1 is selected. + * - 2 : Pulse counter input 2 is selected. + * - 3 : Pulse counter input 3 is selected. + */ +__attribute__((always_inline)) static inline uint8_t LptmrReg_GetPinSelect(const LptmrRegType *obj) +{ + return ((obj->CSR & LPTMR_CSR_TPS_MASK) >> LPTMR_CSR_TPS_SHIFT); +} + +/*! \brief Set the Pin selection for Pulse Counter Mode + * + * This function configures the input source to be used in Pulse Counter mode. + * The input connections vary by device. See the chip configuration information + * about connections to these inputs. + * + * \note TPS must be altered only when the LPTMR is disabled. + * + * \param[in] obj : pointer to LPTMR register instance + * \param[in] value : pin selection + * - 0 : Pulse counter input 0 is selected. + * - 1 : Pulse counter input 1 is selected. + * - 2 : Pulse counter input 2 is selected. + * - 3 : Pulse counter input 3 is selected. + */ +__attribute__((always_inline)) static inline void LptmrReg_SetPinSelect(LptmrRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CSR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~(LPTMR_CSR_TPS_MASK | LPTMR_CSR_TCF_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << LPTMR_CSR_TPS_SHIFT)) & LPTMR_CSR_TPS_MASK); + obj->CSR = tmp; +} + +/*! \brief Get the Interrupt Enable state + * + * This function returns the Interrupt Enable state for the LPTMR. If enabled, + * an interrupt is generated when a Compare Match event occurs. + * + * \param[in] obj : pointer to LPTMR register instance + * \return interrupt enable state + * - 0 : timer interrupt disabled. + * - 1 : timer interrupt enabled. + */ +__attribute__((always_inline)) static inline uint8_t LptmrReg_GetInterruptEnable(const LptmrRegType *obj) +{ + return ((obj->CSR & LPTMR_CSR_TIE_MASK) >> LPTMR_CSR_TIE_SHIFT); +} + +/*! \brief Set the Interrupt Enable state + * + * This function configures the Interrupt Enable state for the LPTMR. If enabled, + * an interrupt is generated when a Compare Match event occurs. + * + * \note Either TIE or TDRE can be valid at the same time. + * \note Must be altered only when the LPTMR is disabled. + * + * \param[in] obj : pointer to LPTMR register instance + * \param[in] value : The new state for the interrupt + * - 0 : disable Interrupt. + * - 1 : enable Interrupt. + */ +__attribute__((always_inline)) static inline void LptmrReg_SetInterrupt(LptmrRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CSR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~(LPTMR_CSR_TIE_MASK | LPTMR_CSR_TCF_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << LPTMR_CSR_TIE_SHIFT)) & LPTMR_CSR_TIE_MASK); + obj->CSR = tmp; +} + +/*! \brief Get the Compare Flag state + * + * This function checks whether a Compare Match event has occurred or if there is + * an Interrupt Pending. + * TCF is set when the LPTMR is enabled and the CNR equals the CMR and increments. + * TCF is cleared when the LPTMR is disabled or a logic 1 is written to it. + * + * \param[in] obj : pointer to LPTMR register instance + * \return the Compare Flag state + * - 0 : the value of CNR is not equal to CMR and increments. + * - 1 : the value of CNR is equal to CMR and increments. + */ +__attribute__((always_inline)) static inline uint8_t LptmrReg_GetCompareFlag(const LptmrRegType *obj) +{ + return ((obj->CSR & LPTMR_CSR_TCF_MASK) >> LPTMR_CSR_TCF_SHIFT); +} + +/*! \brief Clear the Compare Flag + * + * This function clears the Compare Flag/Interrupt Pending state. + * TCF is set when the LPTMR is enabled and the CNR equals the CMR and increments. + * TCF is cleared when the LPTMR is disabled or a logic 1 is written to it. + * + * \note Ensure to clear this field before enabling the Timer interrupt or DMA request. + * + * \param[in] obj : pointer to LPTMR register instance + */ +__attribute__((always_inline)) static inline void LptmrReg_ClearCompareFlag(LptmrRegType *obj) +{ + uint32_t tmp = obj->CSR; + tmp |= (LPTMR_CSR_TCF_MASK); + obj->CSR = tmp; + /* Read back to avoid problem */ + (void)obj->CSR; +} + +/*! \brief Get the DMA Request Enable Flag + * + * This function checks whether a DMA Request feature of the LPTMR is enabled. + * The DMA Request is issued when a Compare Match is asserted. + * If enabled, the Compare Match/Interrupt Pending flag is cleared when + * the DMA controller is done. + * + * \param[in] obj : pointer to LPTMR register instance + * \return DMA Request enable + * - 0 : timer DMA Request disabled. + * - 1 : timer DMA Request enabled. + */ +__attribute__((always_inline)) static inline uint8_t LptmrReg_GetDmaRequest(const LptmrRegType *obj) +{ + return ((obj->CSR & LPTMR_CSR_TDRE_MASK) >> LPTMR_CSR_TDRE_SHIFT); +} + +/*! \brief Configure the DMA Request Enable Flag state + * + * This function configures the DMA Request feature of the LPTMR. + * If enabled, a DMA Request is issued when the Compare Match event occurs. + * If enabled, the Compare Match/Interrupt Pending flag is cleared when the DMA controller is done. + * + * \note Either TIE or TDRE can be valid at the same time. + * \note Must be altered only when the LPTMR is disabled. + * + * \param[in] obj : pointer to LPTMR register instance + * \param[in] value : the new state for DMA Request Enable Flag + * - 0 : disable DMA Request + * - 1 : enable DMA Request + */ +__attribute__((always_inline)) static inline void LptmrReg_SetDmaRequest(LptmrRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CSR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~(LPTMR_CSR_TDRE_MASK | LPTMR_CSR_TCF_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << LPTMR_CSR_TDRE_SHIFT)) & LPTMR_CSR_TDRE_MASK); + obj->CSR = tmp; +} + +/*! \brief Get the Prescaler/Glitch Filter Bypass enable state + * + * This function checks whether the Prescaler/Glitch Filter Bypass is enabled. + * When PBYP is set, the selected prescaler clock in Time Counter mode or + * selected input source in Pulse Counter mode directly clocks the CNR. + * When PBYP is clear, the CNR is clocked by the output of the prescaler/glitch filter. + * + * \param[in] obj : pointer to LPTMR register instance + * \return the Prescaler Bypass state + * - 0 : prescaler/glitch filter is used. + * - 1 : prescaler/glitch filter is bypassed. + */ +__attribute__((always_inline)) static inline uint8_t LptmrReg_GetBypass(const LptmrRegType *obj) +{ + return ((obj->PSR & LPTMR_PSR_PBYP_MASK) >> LPTMR_PSR_PBYP_SHIFT); +} + +/*! \brief Configure the Prescaler/Glitch Filter Bypass enable state + * + * This function configures the Prescaler/Glitch filter Bypass. + * + * \note Must be altered only when the LPTMR is disabled. + * + * \param[in] obj : pointer to LPTMR register instance + * \param[in] value : the new Prescaler/Glitch Filter Bypass state + * - 0 : use rescaler/glitch filter + * - 1 : bypass rescaler/glitch filter + */ +__attribute__((always_inline)) static inline void LptmrReg_SetBypass(LptmrRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PSR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~(LPTMR_PSR_PBYP_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << LPTMR_PSR_PBYP_SHIFT)) & LPTMR_PSR_PBYP_MASK); + obj->PSR = tmp; +} + +/*! \brief Get Prescaler/Glitch Filter divider value + * + * This function returns the currently configured Prescaler/Glitch Filter divider value. + * Prescale Value configures the size of the Prescaler in Time Counter mode or width of the + * glitch filter in Pulse Counter mode. + * The width of the glitch filter can vary by 1 cycle due to synchronization of the pulse counter input. + * + * \param[in] obj : pointer to LPTMR register instance + * \return the Prescaler/Glitch filter value + * - 0 : Prescaler divides the prescaler clock by 2; glitch filter does not support this configuration. + * - 1 : Prescaler divides the prescaler clock by 4; glitch filter recognizes change on input pin after 2 rising clock edges. + * - 2 : Prescaler divides the prescaler clock by 8; glitch filter recognizes change on input pin after 4 rising clock edges. + * - 3 : Prescaler divides the prescaler clock by 16; glitch filter recognizes change on input pin after 8 rising clock edges. + * - 4 : Prescaler divides the prescaler clock by 32; glitch filter recognizes change on input pin after 16 rising clock edges. + * - 5 : Prescaler divides the prescaler clock by 64; glitch filter recognizes change on input pin after 32 rising clock edges. + * - 6 : Prescaler divides the prescaler clock by 128; glitch filter recognizes change on input pin after 64 rising clock edges. + * - 7 : Prescaler divides the prescaler clock by 256; glitch filter recognizes change on input pin after 128 rising clock edges. + * - 8 : Prescaler divides the prescaler clock by 512; glitch filter recognizes change on input pin after 256 rising clock edges. + * - 9 : Prescaler divides the prescaler clock by 1024; glitch filter recognizes change on input pin after 512 rising clock edges. + * - 10 : Prescaler divides the prescaler clock by 2048; glitch filter recognizes change on input pin after 1024 rising clock edges. + * - 11 : Prescaler divides the prescaler clock by 4096; glitch filter recognizes change on input pin after 2048 rising clock edges. + * - 12 : Prescaler divides the prescaler clock by 8192; glitch filter recognizes change on input pin after 4096 rising clock edges. + * - 13 : Prescaler divides the prescaler clock by 16,384; glitch filter recognizes change on input pin after 8192 rising clock edges. + * - 14 : Prescaler divides the prescaler clock by 32,768; glitch filter recognizes change on input pin after 16,384 rising clock edges. + * - 15 : Prescaler divides the prescaler clock by 65,536; glitch filter recognizes change on input pin after 32,768 rising clock edges. + */ +__attribute__((always_inline)) static inline uint8_t LptmrReg_GetPrescaler(const LptmrRegType *obj) +{ + return ((obj->PSR & LPTMR_PSR_PRESCALE_MASK) >> LPTMR_PSR_PRESCALE_SHIFT); +} + +/*! \brief Configure the Prescaler/Glitch Filter divider value + * + * This function configures the value for the Prescaler/Glitch Filter. + * + * \note Must be altered only when the LPTMR is disabled. + * + * \param[in] obj : pointer to LPTMR register instance + * \param[in] value : the new Prescaler value + * - 0 : Prescaler divides the prescaler clock by 2; glitch filter does not support this configuration. + * - 1 : Prescaler divides the prescaler clock by 4; glitch filter recognizes change on input pin after 2 rising clock edges. + * - 2 : Prescaler divides the prescaler clock by 8; glitch filter recognizes change on input pin after 4 rising clock edges. + * - 3 : Prescaler divides the prescaler clock by 16; glitch filter recognizes change on input pin after 8 rising clock edges. + * - 4 : Prescaler divides the prescaler clock by 32; glitch filter recognizes change on input pin after 16 rising clock edges. + * - 5 : Prescaler divides the prescaler clock by 64; glitch filter recognizes change on input pin after 32 rising clock edges. + * - 6 : Prescaler divides the prescaler clock by 128; glitch filter recognizes change on input pin after 64 rising clock edges. + * - 7 : Prescaler divides the prescaler clock by 256; glitch filter recognizes change on input pin after 128 rising clock edges. + * - 8 : Prescaler divides the prescaler clock by 512; glitch filter recognizes change on input pin after 256 rising clock edges. + * - 9 : Prescaler divides the prescaler clock by 1024; glitch filter recognizes change on input pin after 512 rising clock edges. + * - 10 : Prescaler divides the prescaler clock by 2048; glitch filter recognizes change on input pin after 1024 rising clock edges. + * - 11 : Prescaler divides the prescaler clock by 4096; glitch filter recognizes change on input pin after 2048 rising clock edges. + * - 12 : Prescaler divides the prescaler clock by 8192; glitch filter recognizes change on input pin after 4096 rising clock edges. + * - 13 : Prescaler divides the prescaler clock by 16,384; glitch filter recognizes change on input pin after 8192 rising clock edges. + * - 14 : Prescaler divides the prescaler clock by 32,768; glitch filter recognizes change on input pin after 16,384 rising clock edges. + * - 15 : Prescaler divides the prescaler clock by 65,536; glitch filter recognizes change on input pin after 32,768 rising clock edges. + */ +__attribute__((always_inline)) static inline void LptmrReg_SetPrescaler(LptmrRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PSR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~(LPTMR_PSR_PRESCALE_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << LPTMR_PSR_PRESCALE_SHIFT)) & LPTMR_PSR_PRESCALE_MASK); + obj->PSR = tmp; +} + +/*! \brief Get the Compare Value + * + * This function returns the current Compare Value. + * + * \param[in] obj : pointer to LPTMR register instance + * \return the Compare Value + */ +__attribute__((always_inline)) static inline uint16_t LptmrReg_GetCompareValue(const LptmrRegType *obj) +{ + return ((obj->CMR & LPTMR_CMR_COMPARE_MASK) >> LPTMR_CMR_COMPARE_SHIFT); +} + +/*! \brief Configure the Prescaler/Glitch Filter Bypass enable state + * + * This function configures the Compare Value. If set to 0, the Compare Match + * event and the hardware trigger assert and remain asserted until the timer is + * disabled. + * + * \note Must be altered only when the LPTMR is disabled. + * + * \param[in] obj : pointer to LPTMR register instance + * \param[in] value : the new Compare Value + */ +__attribute__((always_inline)) static inline void LptmrReg_SetCompareValue(LptmrRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->CMR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~(LPTMR_CMR_COMPARE_MASK); + tmp |= (((uint32_t)(((uint32_t)(value)) << LPTMR_CMR_COMPARE_SHIFT)) & LPTMR_CMR_COMPARE_MASK); + obj->CMR = tmp; +} + +/*! \brief Get the current Counter Value + * + * This function returns the Counter Value. + * The CNR returns the current value of the LPTMR counter at the time this register was last written. + * Cannot write directly. + * + * \param[in] obj : pointer to LPTMR register instance + * \return the Counter Value + */ +__attribute__((always_inline)) static inline uint16_t LptmrReg_GetCounterValue(const LptmrRegType *obj) +{ + return ((obj->CNR & LPTMR_CNR_COUNTER_MASK) >> LPTMR_CNR_COUNTER_SHIFT); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _LPTMR_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/mft_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/mft_reg.h new file mode 100644 index 0000000..96e45e8 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/mft_reg.h @@ -0,0 +1,8583 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MFT_REG_H_ +#define _MFT_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the MFT Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* Total number of MFT channels */ +#define MFT_CHANNEL_NUM (8) +/* Pair number of Deadtime channels */ +#define MFT_DEADTIME_PAIR (MFT_CHANNEL_NUM / 2) +/* Pair number of Deadtime channels */ +#define MFT_FAULT_INPUT_NUM (4) + +/* SC Bit Fields */ +#define MFT_SC_FLTPS_MASK (0xF000000u) +#define MFT_SC_FLTPS_SHIFT (24u) +#define MFT_SC_FLTPS_WIDTH (4u) +#define MFT_SC_PWMEN7_MASK (0x800000u) +#define MFT_SC_PWMEN7_SHIFT (23u) +#define MFT_SC_PWMEN7_WIDTH (1u) +#define MFT_SC_PWMEN6_MASK (0x400000u) +#define MFT_SC_PWMEN6_SHIFT (22u) +#define MFT_SC_PWMEN6_WIDTH (1u) +#define MFT_SC_PWMEN5_MASK (0x200000u) +#define MFT_SC_PWMEN5_SHIFT (21u) +#define MFT_SC_PWMEN5_WIDTH (1u) +#define MFT_SC_PWMEN4_MASK (0x100000u) +#define MFT_SC_PWMEN4_SHIFT (20u) +#define MFT_SC_PWMEN4_WIDTH (1u) +#define MFT_SC_PWMEN3_MASK (0x80000u) +#define MFT_SC_PWMEN3_SHIFT (19u) +#define MFT_SC_PWMEN3_WIDTH (1u) +#define MFT_SC_PWMEN2_MASK (0x40000u) +#define MFT_SC_PWMEN2_SHIFT (18u) +#define MFT_SC_PWMEN2_WIDTH (1u) +#define MFT_SC_PWMEN1_MASK (0x20000u) +#define MFT_SC_PWMEN1_SHIFT (17u) +#define MFT_SC_PWMEN1_WIDTH (1u) +#define MFT_SC_PWMEN0_MASK (0x10000u) +#define MFT_SC_PWMEN0_SHIFT (16u) +#define MFT_SC_PWMEN0_WIDTH (1u) +#define MFT_SC_TOF_MASK (0x200u) +#define MFT_SC_TOF_SHIFT (9u) +#define MFT_SC_TOF_WIDTH (1u) +#define MFT_SC_TOIE_MASK (0x100u) +#define MFT_SC_TOIE_SHIFT (8u) +#define MFT_SC_TOIE_WIDTH (1u) +#define MFT_SC_RF_MASK (0x80u) +#define MFT_SC_RF_SHIFT (7u) +#define MFT_SC_RF_WIDTH (1u) +#define MFT_SC_RIE_MASK (0x40u) +#define MFT_SC_RIE_SHIFT (6u) +#define MFT_SC_RIE_WIDTH (1u) +#define MFT_SC_CPWMS_MASK (0x20u) +#define MFT_SC_CPWMS_SHIFT (5u) +#define MFT_SC_CPWMS_WIDTH (1u) +#define MFT_SC_CLKS_MASK (0x18u) +#define MFT_SC_CLKS_SHIFT (3u) +#define MFT_SC_CLKS_WIDTH (2u) +#define MFT_SC_PS_MASK (0x07u) +#define MFT_SC_PS_SHIFT (0u) +#define MFT_SC_PS_WIDTH (3u) + +/* CNT Bit Fields */ +#define MFT_CNT_COUNT_MASK (0xFFFFu) +#define MFT_CNT_COUNT_SHIFT (0u) +#define MFT_CNT_COUNT_WIDTH (16u) + +/* MODULO Bit Fields */ +#define MFT_MODULO_MOD_MASK (0xFFFFu) +#define MFT_MODULO_MOD_SHIFT (0u) +#define MFT_MODULO_MOD_WIDTH (16u) + +/* CSC Bit Fields */ +#define MFT_CSC_CHOV_MASK (0x400u) +#define MFT_CSC_CHOV_SHIFT (10u) +#define MFT_CSC_CHOV_WIDTH (1u) +#define MFT_CSC_CHIS_MASK (0x200u) +#define MFT_CSC_CHIS_SHIFT (9u) +#define MFT_CSC_CHIS_WIDTH (1u) +#define MFT_CSC_TRIGMODE_MASK (0x100u) +#define MFT_CSC_TRIGMODE_SHIFT (8u) +#define MFT_CSC_TRIGMODE_WIDTH (1u) +#define MFT_CSC_CHF_MASK (0x80u) +#define MFT_CSC_CHF_SHIFT (7u) +#define MFT_CSC_CHF_WIDTH (1u) +#define MFT_CSC_CHIE_MASK (0x40u) +#define MFT_CSC_CHIE_SHIFT (6u) +#define MFT_CSC_CHIE_WIDTH (1u) +#define MFT_CSC_MSB_MASK (0x20u) +#define MFT_CSC_MSB_SHIFT (5u) +#define MFT_CSC_MSB_WIDTH (1u) +#define MFT_CSC_MSA_MASK (0x10u) +#define MFT_CSC_MSA_SHIFT (4u) +#define MFT_CSC_MSA_WIDTH (1u) +#define MFT_CSC_ELSB_MASK (0x08u) +#define MFT_CSC_ELSB_SHIFT (3u) +#define MFT_CSC_ELSB_WIDTH (1u) +#define MFT_CSC_ELSA_MASK (0x04u) +#define MFT_CSC_ELSA_SHIFT (2u) +#define MFT_CSC_ELSA_WIDTH (1u) +#define MFT_CSC_ICRST_MASK (0x02u) +#define MFT_CSC_ICRST_SHIFT (1u) +#define MFT_CSC_ICRST_WIDTH (1u) +#define MFT_CSC_DMA_MASK (0x01u) +#define MFT_CSC_DMA_SHIFT (0u) +#define MFT_CSC_DMA_WIDTH (1u) + +/* CV Bit Fields */ +#define MFT_CV_VAL_MASK (0xFFFFu) +#define MFT_CV_VAL_SHIFT (0u) +#define MFT_CV_VAL_WIDTH (16u) + +/* CNTIN Bit Fields */ +#define MFT_CNTIN_CNTINIT_MASK (0xFFFFu) +#define MFT_CNTIN_CNTINIT_SHIFT (0u) +#define MFT_CNTIN_CNTINIT_WIDTH (16u) + +/* STATUS Bit Fields */ +#define MFT_STATUS_CH7F_MASK (0x80u) +#define MFT_STATUS_CH7F_SHIFT (7u) +#define MFT_STATUS_CH7F_WIDTH (1u) +#define MFT_STATUS_CH6F_MASK (0x40u) +#define MFT_STATUS_CH6F_SHIFT (6u) +#define MFT_STATUS_CH6F_WIDTH (1u) +#define MFT_STATUS_CH5F_MASK (0x20u) +#define MFT_STATUS_CH5F_SHIFT (5u) +#define MFT_STATUS_CH5F_WIDTH (1u) +#define MFT_STATUS_CH4F_MASK (0x10u) +#define MFT_STATUS_CH4F_SHIFT (4u) +#define MFT_STATUS_CH4F_WIDTH (1u) +#define MFT_STATUS_CH3F_MASK (0x08u) +#define MFT_STATUS_CH3F_SHIFT (3u) +#define MFT_STATUS_CH3F_WIDTH (1u) +#define MFT_STATUS_CH2F_MASK (0x04u) +#define MFT_STATUS_CH2F_SHIFT (2u) +#define MFT_STATUS_CH2F_WIDTH (1u) +#define MFT_STATUS_CH1F_MASK (0x02u) +#define MFT_STATUS_CH1F_SHIFT (1u) +#define MFT_STATUS_CH1F_WIDTH (1u) +#define MFT_STATUS_CH0F_MASK (0x01u) +#define MFT_STATUS_CH0F_SHIFT (0u) +#define MFT_STATUS_CH0F_WIDTH (1u) + +/* MODE Bit Fields */ +#define MFT_MODE_FAULTIE_MASK (0x80u) +#define MFT_MODE_FAULTIE_SHIFT (7u) +#define MFT_MODE_FAULTIE_WIDTH (1u) +#define MFT_MODE_FAULTM_MASK (0x60u) +#define MFT_MODE_FAULTM_SHIFT (5u) +#define MFT_MODE_FAULTM_WIDTH (2u) +#define MFT_MODE_CAPTEST_MASK (0x10u) +#define MFT_MODE_CAPTEST_SHIFT (4u) +#define MFT_MODE_CAPTEST_WIDTH (1u) +#define MFT_MODE_PWMSYNC_MASK (0x08u) +#define MFT_MODE_PWMSYNC_SHIFT (3u) +#define MFT_MODE_PWMSYNC_WIDTH (1u) +#define MFT_MODE_WPDIS_MASK (0x04u) +#define MFT_MODE_WPDIS_SHIFT (2u) +#define MFT_MODE_WPDIS_WIDTH (1u) +#define MFT_MODE_INIT_MASK (0x02u) +#define MFT_MODE_INIT_SHIFT (1u) +#define MFT_MODE_INIT_WIDTH (1u) +#define MFT_MODE_MFTEN_MASK (0x01u) +#define MFT_MODE_MFTEN_SHIFT (0u) +#define MFT_MODE_MFTEN_WIDTH (1u) + +/* SYNC Bit Fields */ +#define MFT_SYNC_SWSYNC_MASK (0x80u) +#define MFT_SYNC_SWSYNC_SHIFT (7u) +#define MFT_SYNC_SWSYNC_WIDTH (1u) +#define MFT_SYNC_TRIG2_MASK (0x40u) +#define MFT_SYNC_TRIG2_SHIFT (6u) +#define MFT_SYNC_TRIG2_WIDTH (1u) +#define MFT_SYNC_TRIG1_MASK (0x20u) +#define MFT_SYNC_TRIG1_SHIFT (5u) +#define MFT_SYNC_TRIG1_WIDTH (1u) +#define MFT_SYNC_TRIG0_MASK (0x10u) +#define MFT_SYNC_TRIG0_SHIFT (4u) +#define MFT_SYNC_TRIG0_WIDTH (1u) +#define MFT_SYNC_SYNCHOM_MASK (0x08u) +#define MFT_SYNC_SYNCHOM_SHIFT (3u) +#define MFT_SYNC_SYNCHOM_WIDTH (1u) +#define MFT_SYNC_REINIT_MASK (0x04u) +#define MFT_SYNC_REINIT_SHIFT (2u) +#define MFT_SYNC_REINIT_WIDTH (1u) +#define MFT_SYNC_CNTMAX_MASK (0x02u) +#define MFT_SYNC_CNTMAX_SHIFT (1u) +#define MFT_SYNC_CNTMAX_WIDTH (1u) +#define MFT_SYNC_CNTMIN_MASK (0x01u) +#define MFT_SYNC_CNTMIN_SHIFT (0u) +#define MFT_SYNC_CNTMIN_WIDTH (1u) + +/* OUTINIT Bit Fields */ +#define MFT_OUTINIT_CH7OI_MASK (0x80u) +#define MFT_OUTINIT_CH7OI_SHIFT (7u) +#define MFT_OUTINIT_CH7OI_WIDTH (1u) +#define MFT_OUTINIT_CH6OI_MASK (0x40u) +#define MFT_OUTINIT_CH6OI_SHIFT (6u) +#define MFT_OUTINIT_CH6OI_WIDTH (1u) +#define MFT_OUTINIT_CH5OI_MASK (0x20u) +#define MFT_OUTINIT_CH5OI_SHIFT (5u) +#define MFT_OUTINIT_CH5OI_WIDTH (1u) +#define MFT_OUTINIT_CH4OI_MASK (0x10u) +#define MFT_OUTINIT_CH4OI_SHIFT (4u) +#define MFT_OUTINIT_CH4OI_WIDTH (1u) +#define MFT_OUTINIT_CH3OI_MASK (0x08u) +#define MFT_OUTINIT_CH3OI_SHIFT (3u) +#define MFT_OUTINIT_CH3OI_WIDTH (1u) +#define MFT_OUTINIT_CH2OI_MASK (0x04u) +#define MFT_OUTINIT_CH2OI_SHIFT (2u) +#define MFT_OUTINIT_CH2OI_WIDTH (1u) +#define MFT_OUTINIT_CH1OI_MASK (0x02u) +#define MFT_OUTINIT_CH1OI_SHIFT (1u) +#define MFT_OUTINIT_CH1OI_WIDTH (1u) +#define MFT_OUTINIT_CH0OI_MASK (0x01u) +#define MFT_OUTINIT_CH0OI_SHIFT (0u) +#define MFT_OUTINIT_CH0OI_WIDTH (1u) + +/* OUTMASK Bit Fields */ +#define MFT_OUTMASK_CH7OM_MASK (0x80u) +#define MFT_OUTMASK_CH7OM_SHIFT (7u) +#define MFT_OUTMASK_CH7OM_WIDTH (1u) +#define MFT_OUTMASK_CH6OM_MASK (0x40u) +#define MFT_OUTMASK_CH6OM_SHIFT (6u) +#define MFT_OUTMASK_CH6OM_WIDTH (1u) +#define MFT_OUTMASK_CH5OM_MASK (0x20u) +#define MFT_OUTMASK_CH5OM_SHIFT (5u) +#define MFT_OUTMASK_CH5OM_WIDTH (1u) +#define MFT_OUTMASK_CH4OM_MASK (0x10u) +#define MFT_OUTMASK_CH4OM_SHIFT (4u) +#define MFT_OUTMASK_CH4OM_WIDTH (1u) +#define MFT_OUTMASK_CH3OM_MASK (0x08u) +#define MFT_OUTMASK_CH3OM_SHIFT (3u) +#define MFT_OUTMASK_CH3OM_WIDTH (1u) +#define MFT_OUTMASK_CH2OM_MASK (0x04u) +#define MFT_OUTMASK_CH2OM_SHIFT (2u) +#define MFT_OUTMASK_CH2OM_WIDTH (1u) +#define MFT_OUTMASK_CH1OM_MASK (0x02u) +#define MFT_OUTMASK_CH1OM_SHIFT (1u) +#define MFT_OUTMASK_CH1OM_WIDTH (1u) +#define MFT_OUTMASK_CH0OM_MASK (0x01u) +#define MFT_OUTMASK_CH0OM_SHIFT (0u) +#define MFT_OUTMASK_CH0OM_WIDTH (1u) + +/* COMBINE Bit Fields */ +#define MFT_COMBINE_MCOMBINE3_MASK (0x80000000u) +#define MFT_COMBINE_MCOMBINE3_SHIFT (31u) +#define MFT_COMBINE_MCOMBINE3_WIDTH (1u) +#define MFT_COMBINE_FAULTEN3_MASK (0x40000000u) +#define MFT_COMBINE_FAULTEN3_SHIFT (30u) +#define MFT_COMBINE_FAULTEN3_WIDTH (1u) +#define MFT_COMBINE_SYNCEN3_MASK (0x20000000u) +#define MFT_COMBINE_SYNCEN3_SHIFT (29u) +#define MFT_COMBINE_SYNCEN3_WIDTH (1u) +#define MFT_COMBINE_DTEN3_MASK (0x10000000u) +#define MFT_COMBINE_DTEN3_SHIFT (28u) +#define MFT_COMBINE_DTEN3_WIDTH (1u) +#define MFT_COMBINE_DECAP3_MASK (0x8000000u) +#define MFT_COMBINE_DECAP3_SHIFT (27u) +#define MFT_COMBINE_DECAP3_WIDTH (1u) +#define MFT_COMBINE_DECAPEN3_MASK (0x4000000u) +#define MFT_COMBINE_DECAPEN3_SHIFT (26u) +#define MFT_COMBINE_DECAPEN3_WIDTH (1u) +#define MFT_COMBINE_COMP3_MASK (0x2000000u) +#define MFT_COMBINE_COMP3_SHIFT (25u) +#define MFT_COMBINE_COMP3_WIDTH (1u) +#define MFT_COMBINE_COMBINE3_MASK (0x1000000u) +#define MFT_COMBINE_COMBINE3_SHIFT (24u) +#define MFT_COMBINE_COMBINE3_WIDTH (1u) +#define MFT_COMBINE_MCOMBINE2_MASK (0x800000u) +#define MFT_COMBINE_MCOMBINE2_SHIFT (23u) +#define MFT_COMBINE_MCOMBINE2_WIDTH (1u) +#define MFT_COMBINE_FAULTEN2_MASK (0x400000u) +#define MFT_COMBINE_FAULTEN2_SHIFT (22u) +#define MFT_COMBINE_FAULTEN2_WIDTH (1u) +#define MFT_COMBINE_SYNCEN2_MASK (0x200000u) +#define MFT_COMBINE_SYNCEN2_SHIFT (21u) +#define MFT_COMBINE_SYNCEN2_WIDTH (1u) +#define MFT_COMBINE_DTEN2_MASK (0x100000u) +#define MFT_COMBINE_DTEN2_SHIFT (20u) +#define MFT_COMBINE_DTEN2_WIDTH (1u) +#define MFT_COMBINE_DECAP2_MASK (0x80000u) +#define MFT_COMBINE_DECAP2_SHIFT (19u) +#define MFT_COMBINE_DECAP2_WIDTH (1u) +#define MFT_COMBINE_DECAPEN2_MASK (0x40000u) +#define MFT_COMBINE_DECAPEN2_SHIFT (18u) +#define MFT_COMBINE_DECAPEN2_WIDTH (1u) +#define MFT_COMBINE_COMP2_MASK (0x20000u) +#define MFT_COMBINE_COMP2_SHIFT (17u) +#define MFT_COMBINE_COMP2_WIDTH (1u) +#define MFT_COMBINE_COMBINE2_MASK (0x10000u) +#define MFT_COMBINE_COMBINE2_SHIFT (16u) +#define MFT_COMBINE_COMBINE2_WIDTH (1u) +#define MFT_COMBINE_MCOMBINE1_MASK (0x8000u) +#define MFT_COMBINE_MCOMBINE1_SHIFT (15u) +#define MFT_COMBINE_MCOMBINE1_WIDTH (1u) +#define MFT_COMBINE_FAULTEN1_MASK (0x4000u) +#define MFT_COMBINE_FAULTEN1_SHIFT (14u) +#define MFT_COMBINE_FAULTEN1_WIDTH (1u) +#define MFT_COMBINE_SYNCEN1_MASK (0x2000u) +#define MFT_COMBINE_SYNCEN1_SHIFT (13u) +#define MFT_COMBINE_SYNCEN1_WIDTH (1u) +#define MFT_COMBINE_DTEN1_MASK (0x1000u) +#define MFT_COMBINE_DTEN1_SHIFT (12u) +#define MFT_COMBINE_DTEN1_WIDTH (1u) +#define MFT_COMBINE_DECAP1_MASK (0x800u) +#define MFT_COMBINE_DECAP1_SHIFT (11u) +#define MFT_COMBINE_DECAP1_WIDTH (1u) +#define MFT_COMBINE_DECAPEN1_MASK (0x400u) +#define MFT_COMBINE_DECAPEN1_SHIFT (10u) +#define MFT_COMBINE_DECAPEN1_WIDTH (1u) +#define MFT_COMBINE_COMP1_MASK (0x200u) +#define MFT_COMBINE_COMP1_SHIFT (9u) +#define MFT_COMBINE_COMP1_WIDTH (1u) +#define MFT_COMBINE_COMBINE1_MASK (0x100u) +#define MFT_COMBINE_COMBINE1_SHIFT (8u) +#define MFT_COMBINE_COMBINE1_WIDTH (1u) +#define MFT_COMBINE_MCOMBINE0_MASK (0x80u) +#define MFT_COMBINE_MCOMBINE0_SHIFT (7u) +#define MFT_COMBINE_MCOMBINE0_WIDTH (1u) +#define MFT_COMBINE_FAULTEN0_MASK (0x40u) +#define MFT_COMBINE_FAULTEN0_SHIFT (6u) +#define MFT_COMBINE_FAULTEN0_WIDTH (1u) +#define MFT_COMBINE_SYNCEN0_MASK (0x20u) +#define MFT_COMBINE_SYNCEN0_SHIFT (5u) +#define MFT_COMBINE_SYNCEN0_WIDTH (1u) +#define MFT_COMBINE_DTEN0_MASK (0x10u) +#define MFT_COMBINE_DTEN0_SHIFT (4u) +#define MFT_COMBINE_DTEN0_WIDTH (1u) +#define MFT_COMBINE_DECAP0_MASK (0x08u) +#define MFT_COMBINE_DECAP0_SHIFT (3u) +#define MFT_COMBINE_DECAP0_WIDTH (1u) +#define MFT_COMBINE_DECAPEN0_MASK (0x04u) +#define MFT_COMBINE_DECAPEN0_SHIFT (2u) +#define MFT_COMBINE_DECAPEN0_WIDTH (1u) +#define MFT_COMBINE_COMP0_MASK (0x02u) +#define MFT_COMBINE_COMP0_SHIFT (1u) +#define MFT_COMBINE_COMP0_WIDTH (1u) +#define MFT_COMBINE_COMBINE0_MASK (0x01u) +#define MFT_COMBINE_COMBINE0_SHIFT (0u) +#define MFT_COMBINE_COMBINE0_WIDTH (1u) + +/* DEADTIME Bit Fields */ +#define MFT_DEADTIME_DTVALEX_MASK (0xF0000u) +#define MFT_DEADTIME_DTVALEX_SHIFT (16u) +#define MFT_DEADTIME_DTVALEX_WIDTH (4u) +#define MFT_DEADTIME_DTPS_MASK (0xC0u) +#define MFT_DEADTIME_DTPS_SHIFT (6u) +#define MFT_DEADTIME_DTPS_WIDTH (2u) +#define MFT_DEADTIME_DTVAL_MASK (0x3Fu) +#define MFT_DEADTIME_DTVAL_SHIFT (0u) +#define MFT_DEADTIME_DTVAL_WIDTH (6u) + +/* EXTTRIG Bit Fields */ +#define MFT_EXTTRIG_CH7TRIG_MASK (0x200u) +#define MFT_EXTTRIG_CH7TRIG_SHIFT (9u) +#define MFT_EXTTRIG_CH7TRIG_WIDTH (1u) +#define MFT_EXTTRIG_CH6TRIG_MASK (0x100u) +#define MFT_EXTTRIG_CH6TRIG_SHIFT (8u) +#define MFT_EXTTRIG_CH6TRIG_WIDTH (1u) +#define MFT_EXTTRIG_TRIGF_MASK (0x80u) +#define MFT_EXTTRIG_TRIGF_SHIFT (7u) +#define MFT_EXTTRIG_TRIGF_WIDTH (1u) +#define MFT_EXTTRIG_INITTRIGEN_MASK (0x40u) +#define MFT_EXTTRIG_INITTRIGEN_SHIFT (6u) +#define MFT_EXTTRIG_INITTRIGEN_WIDTH (1u) +#define MFT_EXTTRIG_CH1TRIG_MASK (0x20u) +#define MFT_EXTTRIG_CH1TRIG_SHIFT (5u) +#define MFT_EXTTRIG_CH1TRIG_WIDTH (1u) +#define MFT_EXTTRIG_CH0TRIG_MASK (0x10u) +#define MFT_EXTTRIG_CH0TRIG_SHIFT (4u) +#define MFT_EXTTRIG_CH0TRIG_WIDTH (1u) +#define MFT_EXTTRIG_CH5TRIG_MASK (0x08u) +#define MFT_EXTTRIG_CH5TRIG_SHIFT (3u) +#define MFT_EXTTRIG_CH5TRIG_WIDTH (1u) +#define MFT_EXTTRIG_CH4TRIG_MASK (0x04u) +#define MFT_EXTTRIG_CH4TRIG_SHIFT (2u) +#define MFT_EXTTRIG_CH4TRIG_WIDTH (1u) +#define MFT_EXTTRIG_CH3TRIG_MASK (0x02u) +#define MFT_EXTTRIG_CH3TRIG_SHIFT (1u) +#define MFT_EXTTRIG_CH3TRIG_WIDTH (1u) +#define MFT_EXTTRIG_CH2TRIG_MASK (0x01u) +#define MFT_EXTTRIG_CH2TRIG_SHIFT (0u) +#define MFT_EXTTRIG_CH2TRIG_WIDTH (1u) + +/* POL Bit Fields */ +#define MFT_POL_POL7_MASK (0x80u) +#define MFT_POL_POL7_SHIFT (7u) +#define MFT_POL_POL7_WIDTH (1u) +#define MFT_POL_POL6_MASK (0x40u) +#define MFT_POL_POL6_SHIFT (6u) +#define MFT_POL_POL6_WIDTH (1u) +#define MFT_POL_POL5_MASK (0x20u) +#define MFT_POL_POL5_SHIFT (5u) +#define MFT_POL_POL5_WIDTH (1u) +#define MFT_POL_POL4_MASK (0x10u) +#define MFT_POL_POL4_SHIFT (4u) +#define MFT_POL_POL4_WIDTH (1u) +#define MFT_POL_POL3_MASK (0x08u) +#define MFT_POL_POL3_SHIFT (3u) +#define MFT_POL_POL3_WIDTH (1u) +#define MFT_POL_POL2_MASK (0x04u) +#define MFT_POL_POL2_SHIFT (2u) +#define MFT_POL_POL2_WIDTH (1u) +#define MFT_POL_POL1_MASK (0x02u) +#define MFT_POL_POL1_SHIFT (1u) +#define MFT_POL_POL1_WIDTH (1u) +#define MFT_POL_POL0_MASK (0x01u) +#define MFT_POL_POL0_SHIFT (0u) +#define MFT_POL_POL0_WIDTH (1u) + +/* FMS Bit Fields */ +#define MFT_FMS_FAULTF_MASK (0x80u) +#define MFT_FMS_FAULTF_SHIFT (7u) +#define MFT_FMS_FAULTF_WIDTH (1u) +#define MFT_FMS_WPEN_MASK (0x40u) +#define MFT_FMS_WPEN_SHIFT (6u) +#define MFT_FMS_WPEN_WIDTH (1u) +#define MFT_FMS_FAULTIN_MASK (0x20u) +#define MFT_FMS_FAULTIN_SHIFT (5u) +#define MFT_FMS_FAULTIN_WIDTH (1u) +#define MFT_FMS_FAULTF3_MASK (0x08u) +#define MFT_FMS_FAULTF3_SHIFT (3u) +#define MFT_FMS_FAULTF3_WIDTH (1u) +#define MFT_FMS_FAULTF2_MASK (0x04u) +#define MFT_FMS_FAULTF2_SHIFT (2u) +#define MFT_FMS_FAULTF2_WIDTH (1u) +#define MFT_FMS_FAULTF1_MASK (0x02u) +#define MFT_FMS_FAULTF1_SHIFT (1u) +#define MFT_FMS_FAULTF1_WIDTH (1u) +#define MFT_FMS_FAULTF0_MASK (0x01u) +#define MFT_FMS_FAULTF0_SHIFT (0u) +#define MFT_FMS_FAULTF0_WIDTH (1u) + +/* FILTER Bit Fields */ +#define MFT_FILTER_CH3FVAL_MASK (0xF000u) +#define MFT_FILTER_CH3FVAL_SHIFT (12u) +#define MFT_FILTER_CH3FVAL_WIDTH (4u) +#define MFT_FILTER_CH2FVAL_MASK (0xF00u) +#define MFT_FILTER_CH2FVAL_SHIFT (8u) +#define MFT_FILTER_CH2FVAL_WIDTH (4u) +#define MFT_FILTER_CH1FVAL_MASK (0xF0u) +#define MFT_FILTER_CH1FVAL_SHIFT (4u) +#define MFT_FILTER_CH1FVAL_WIDTH (4u) +#define MFT_FILTER_CH0FVAL_MASK (0x0Fu) +#define MFT_FILTER_CH0FVAL_SHIFT (0u) +#define MFT_FILTER_CH0FVAL_WIDTH (4u) + +/* FLTCTRL Bit Fields */ +#define MFT_FLTCTRL_FSTATE_MASK (0x8000u) +#define MFT_FLTCTRL_FSTATE_SHIFT (15u) +#define MFT_FLTCTRL_FSTATE_WIDTH (1u) +#define MFT_FLTCTRL_FFVAL_MASK (0xF00u) +#define MFT_FLTCTRL_FFVAL_SHIFT (8u) +#define MFT_FLTCTRL_FFVAL_WIDTH (4u) +#define MFT_FLTCTRL_FFLTR3EN_MASK (0x80u) +#define MFT_FLTCTRL_FFLTR3EN_SHIFT (7u) +#define MFT_FLTCTRL_FFLTR3EN_WIDTH (1u) +#define MFT_FLTCTRL_FFLTR2EN_MASK (0x40u) +#define MFT_FLTCTRL_FFLTR2EN_SHIFT (6u) +#define MFT_FLTCTRL_FFLTR2EN_WIDTH (1u) +#define MFT_FLTCTRL_FFLTR1EN_MASK (0x20u) +#define MFT_FLTCTRL_FFLTR1EN_SHIFT (5u) +#define MFT_FLTCTRL_FFLTR1EN_WIDTH (1u) +#define MFT_FLTCTRL_FFLTR0EN_MASK (0x10u) +#define MFT_FLTCTRL_FFLTR0EN_SHIFT (4u) +#define MFT_FLTCTRL_FFLTR0EN_WIDTH (1u) +#define MFT_FLTCTRL_FAULT3EN_MASK (0x08u) +#define MFT_FLTCTRL_FAULT3EN_SHIFT (3u) +#define MFT_FLTCTRL_FAULT3EN_WIDTH (1u) +#define MFT_FLTCTRL_FAULT2EN_MASK (0x04u) +#define MFT_FLTCTRL_FAULT2EN_SHIFT (2u) +#define MFT_FLTCTRL_FAULT2EN_WIDTH (1u) +#define MFT_FLTCTRL_FAULT1EN_MASK (0x02u) +#define MFT_FLTCTRL_FAULT1EN_SHIFT (1u) +#define MFT_FLTCTRL_FAULT1EN_WIDTH (1u) +#define MFT_FLTCTRL_FAULT0EN_MASK (0x01u) +#define MFT_FLTCTRL_FAULT0EN_SHIFT (0u) +#define MFT_FLTCTRL_FAULT0EN_WIDTH (1u) + +/* QDCTRL Bit Fields */ +#define MFT_QDCTRL_PHZCOF_MASK (0x1000u) +#define MFT_QDCTRL_PHZCOF_SHIFT (12) +#define MFT_QDCTRL_PHZCOF_WIDTH (1) +#define MFT_QDCTRL_PHZMODE_MASK (0xC00u) +#define MFT_QDCTRL_PHZMODE_SHIFT (10) +#define MFT_QDCTRL_PHZMODE_WIDTH (2) +#define MFT_QDCTRL_PHZPOL_MASK (0x200u) +#define MFT_QDCTRL_PHZPOL_SHIFT (9) +#define MFT_QDCTRL_PHZPOL_WIDTH (1) +#define MFT_QDCTRL_PHZFLTREN_MASK (0x100u) +#define MFT_QDCTRL_PHZFLTREN_SHIFT (8) +#define MFT_QDCTRL_PHZFLTREN_WIDTH (1) +#define MFT_QDCTRL_PHAFLTREN_MASK (0x80u) +#define MFT_QDCTRL_PHAFLTREN_SHIFT (7u) +#define MFT_QDCTRL_PHAFLTREN_WIDTH (1u) +#define MFT_QDCTRL_PHBFLTREN_MASK (0x40u) +#define MFT_QDCTRL_PHBFLTREN_SHIFT (6u) +#define MFT_QDCTRL_PHBFLTREN_WIDTH (1u) +#define MFT_QDCTRL_PHAPOL_MASK (0x20u) +#define MFT_QDCTRL_PHAPOL_SHIFT (5u) +#define MFT_QDCTRL_PHAPOL_WIDTH (1u) +#define MFT_QDCTRL_PHBPOL_MASK (0x10u) +#define MFT_QDCTRL_PHBPOL_SHIFT (4u) +#define MFT_QDCTRL_PHBPOL_WIDTH (1u) +#define MFT_QDCTRL_QUADMODE_MASK (0x08u) +#define MFT_QDCTRL_QUADMODE_SHIFT (3u) +#define MFT_QDCTRL_QUADMODE_WIDTH (1u) +#define MFT_QDCTRL_QUADIR_MASK (0x04u) +#define MFT_QDCTRL_QUADIR_SHIFT (2u) +#define MFT_QDCTRL_QUADIR_WIDTH (1u) +#define MFT_QDCTRL_TOFDIR_MASK (0x02u) +#define MFT_QDCTRL_TOFDIR_SHIFT (1u) +#define MFT_QDCTRL_TOFDIR_WIDTH (1u) +#define MFT_QDCTRL_QUADEN_MASK (0x01u) +#define MFT_QDCTRL_QUADEN_SHIFT (0u) +#define MFT_QDCTRL_QUADEN_WIDTH (1u) + +/* CONF Bit Fields */ +#define MFT_CONF_ITRIGR_MASK (0x800u) +#define MFT_CONF_ITRIGR_SHIFT (11u) +#define MFT_CONF_ITRIGR_WIDTH (1u) +#define MFT_CONF_GTBEOUT_MASK (0x400u) +#define MFT_CONF_GTBEOUT_SHIFT (10u) +#define MFT_CONF_GTBEOUT_WIDTH (1u) +#define MFT_CONF_GTBEEN_MASK (0x200u) +#define MFT_CONF_GTBEEN_SHIFT (9u) +#define MFT_CONF_GTBEEN_WIDTH (1u) +#define MFT_CONF_BDMMODE_MASK (0xC0u) +#define MFT_CONF_BDMMODE_SHIFT (6u) +#define MFT_CONF_BDMMODE_WIDTH (2u) +#define MFT_CONF_LDFQ_MASK (0x1Fu) +#define MFT_CONF_LDFQ_SHIFT (0u) +#define MFT_CONF_LDFQ_WIDTH (5u) + +/* FLTPOL Bit Fields */ +#define MFT_FLTPOL_FLT3POL_MASK (0x08u) +#define MFT_FLTPOL_FLT3POL_SHIFT (3u) +#define MFT_FLTPOL_FLT3POL_WIDTH (1u) +#define MFT_FLTPOL_FLT2POL_MASK (0x04u) +#define MFT_FLTPOL_FLT2POL_SHIFT (2u) +#define MFT_FLTPOL_FLT2POL_WIDTH (1u) +#define MFT_FLTPOL_FLT1POL_MASK (0x02u) +#define MFT_FLTPOL_FLT1POL_SHIFT (1u) +#define MFT_FLTPOL_FLT1POL_WIDTH (1u) +#define MFT_FLTPOL_FLT0POL_MASK (0x01u) +#define MFT_FLTPOL_FLT0POL_SHIFT (0u) +#define MFT_FLTPOL_FLT0POL_WIDTH (1u) + +/* SYNCONF Bit Fields */ +#define MFT_SYNCONF_HWSOC_MASK (0x100000u) +#define MFT_SYNCONF_HWSOC_SHIFT (20u) +#define MFT_SYNCONF_HWSOC_WIDTH (1u) +#define MFT_SYNCONF_HWINVC_MASK (0x80000u) +#define MFT_SYNCONF_HWINVC_SHIFT (19u) +#define MFT_SYNCONF_HWINVC_WIDTH (1u) +#define MFT_SYNCONF_HWOM_MASK (0x40000u) +#define MFT_SYNCONF_HWOM_SHIFT (18u) +#define MFT_SYNCONF_HWOM_WIDTH (1u) +#define MFT_SYNCONF_HWWRBUF_MASK (0x20000u) +#define MFT_SYNCONF_HWWRBUF_SHIFT (17u) +#define MFT_SYNCONF_HWWRBUF_WIDTH (1u) +#define MFT_SYNCONF_HWRSTCNT_MASK (0x10000u) +#define MFT_SYNCONF_HWRSTCNT_SHIFT (16u) +#define MFT_SYNCONF_HWRSTCNT_WIDTH (1u) +#define MFT_SYNCONF_SWSOC_MASK (0x1000u) +#define MFT_SYNCONF_SWSOC_SHIFT (12u) +#define MFT_SYNCONF_SWSOC_WIDTH (1u) +#define MFT_SYNCONF_SWINVC_MASK (0x800u) +#define MFT_SYNCONF_SWINVC_SHIFT (11u) +#define MFT_SYNCONF_SWINVC_WIDTH (1u) +#define MFT_SYNCONF_SWOM_MASK (0x400u) +#define MFT_SYNCONF_SWOM_SHIFT (10u) +#define MFT_SYNCONF_SWOM_WIDTH (1u) +#define MFT_SYNCONF_SWWRBUF_MASK (0x200u) +#define MFT_SYNCONF_SWWRBUF_SHIFT (9u) +#define MFT_SYNCONF_SWWRBUF_WIDTH (1u) +#define MFT_SYNCONF_SWRSTCNT_MASK (0x100u) +#define MFT_SYNCONF_SWRSTCNT_SHIFT (8u) +#define MFT_SYNCONF_SWRSTCNT_WIDTH (1u) +#define MFT_SYNCONF_SYNCMODE_MASK (0x80u) +#define MFT_SYNCONF_SYNCMODE_SHIFT (7u) +#define MFT_SYNCONF_SYNCMODE_WIDTH (1u) +#define MFT_SYNCONF_SWOC_MASK (0x20u) +#define MFT_SYNCONF_SWOC_SHIFT (5u) +#define MFT_SYNCONF_SWOC_WIDTH (1u) +#define MFT_SYNCONF_INVC_MASK (0x10u) +#define MFT_SYNCONF_INVC_SHIFT (4u) +#define MFT_SYNCONF_INVC_WIDTH (1u) +#define MFT_SYNCONF_CNTINC_MASK (0x04u) +#define MFT_SYNCONF_CNTINC_SHIFT (2u) +#define MFT_SYNCONF_CNTINC_WIDTH (1u) +#define MFT_SYNCONF_HWTRIGMODE_MASK (0x01u) +#define MFT_SYNCONF_HWTRIGMODE_SHIFT (0u) +#define MFT_SYNCONF_HWTRIGMODE_WIDTH (1u) + +/* INVCTRL Bit Fields */ +#define MFT_INVCTRL_INV3EN_MASK (0x08u) +#define MFT_INVCTRL_INV3EN_SHIFT (3u) +#define MFT_INVCTRL_INV3EN_WIDTH (1u) +#define MFT_INVCTRL_INV2EN_MASK (0x04u) +#define MFT_INVCTRL_INV2EN_SHIFT (2u) +#define MFT_INVCTRL_INV2EN_WIDTH (1u) +#define MFT_INVCTRL_INV1EN_MASK (0x02u) +#define MFT_INVCTRL_INV1EN_SHIFT (1u) +#define MFT_INVCTRL_INV1EN_WIDTH (1u) +#define MFT_INVCTRL_INV0EN_MASK (0x01u) +#define MFT_INVCTRL_INV0EN_SHIFT (0u) +#define MFT_INVCTRL_INV0EN_WIDTH (1u) + +/* SWOCTRL Bit Fields */ +#define MFT_SWOCTRL_CH7OCV_MASK (0x8000u) +#define MFT_SWOCTRL_CH7OCV_SHIFT (15u) +#define MFT_SWOCTRL_CH7OCV_WIDTH (1u) +#define MFT_SWOCTRL_CH6OCV_MASK (0x4000u) +#define MFT_SWOCTRL_CH6OCV_SHIFT (14u) +#define MFT_SWOCTRL_CH6OCV_WIDTH (1u) +#define MFT_SWOCTRL_CH5OCV_MASK (0x2000u) +#define MFT_SWOCTRL_CH5OCV_SHIFT (13u) +#define MFT_SWOCTRL_CH5OCV_WIDTH (1u) +#define MFT_SWOCTRL_CH4OCV_MASK (0x1000u) +#define MFT_SWOCTRL_CH4OCV_SHIFT (12u) +#define MFT_SWOCTRL_CH4OCV_WIDTH (1u) +#define MFT_SWOCTRL_CH3OCV_MASK (0x800u) +#define MFT_SWOCTRL_CH3OCV_SHIFT (11u) +#define MFT_SWOCTRL_CH3OCV_WIDTH (1u) +#define MFT_SWOCTRL_CH2OCV_MASK (0x400u) +#define MFT_SWOCTRL_CH2OCV_SHIFT (10u) +#define MFT_SWOCTRL_CH2OCV_WIDTH (1u) +#define MFT_SWOCTRL_CH1OCV_MASK (0x200u) +#define MFT_SWOCTRL_CH1OCV_SHIFT (9u) +#define MFT_SWOCTRL_CH1OCV_WIDTH (1u) +#define MFT_SWOCTRL_CH0OCV_MASK (0x100u) +#define MFT_SWOCTRL_CH0OCV_SHIFT (8u) +#define MFT_SWOCTRL_CH0OCV_WIDTH (1u) +#define MFT_SWOCTRL_CH7OC_MASK (0x80u) +#define MFT_SWOCTRL_CH7OC_SHIFT (7u) +#define MFT_SWOCTRL_CH7OC_WIDTH (1u) +#define MFT_SWOCTRL_CH6OC_MASK (0x40u) +#define MFT_SWOCTRL_CH6OC_SHIFT (6u) +#define MFT_SWOCTRL_CH6OC_WIDTH (1u) +#define MFT_SWOCTRL_CH5OC_MASK (0x20u) +#define MFT_SWOCTRL_CH5OC_SHIFT (5u) +#define MFT_SWOCTRL_CH5OC_WIDTH (1u) +#define MFT_SWOCTRL_CH4OC_MASK (0x10u) +#define MFT_SWOCTRL_CH4OC_SHIFT (4u) +#define MFT_SWOCTRL_CH4OC_WIDTH (1u) +#define MFT_SWOCTRL_CH3OC_MASK (0x08u) +#define MFT_SWOCTRL_CH3OC_SHIFT (3u) +#define MFT_SWOCTRL_CH3OC_WIDTH (1u) +#define MFT_SWOCTRL_CH2OC_MASK (0x04u) +#define MFT_SWOCTRL_CH2OC_SHIFT (2u) +#define MFT_SWOCTRL_CH2OC_WIDTH (1u) +#define MFT_SWOCTRL_CH1OC_MASK (0x02u) +#define MFT_SWOCTRL_CH1OC_SHIFT (1u) +#define MFT_SWOCTRL_CH1OC_WIDTH (1u) +#define MFT_SWOCTRL_CH0OC_MASK (0x01u) +#define MFT_SWOCTRL_CH0OC_SHIFT (0u) +#define MFT_SWOCTRL_CH0OC_WIDTH (1u) + +/* PWMLOAD Bit Fields */ +#define MFT_PWMLOAD_GLDOK_MASK (0x800u) +#define MFT_PWMLOAD_GLDOK_SHIFT (11u) +#define MFT_PWMLOAD_GLDOK_WIDTH (1u) +#define MFT_PWMLOAD_GLEN_MASK (0x400u) +#define MFT_PWMLOAD_GLEN_SHIFT (10u) +#define MFT_PWMLOAD_GLEN_WIDTH (1u) +#define MFT_PWMLOAD_LDOK_MASK (0x200u) +#define MFT_PWMLOAD_LDOK_SHIFT (9u) +#define MFT_PWMLOAD_LDOK_WIDTH (1u) +#define MFT_PWMLOAD_HCSEL_MASK (0x100u) +#define MFT_PWMLOAD_HCSEL_SHIFT (8u) +#define MFT_PWMLOAD_HCSEL_WIDTH (1u) +#define MFT_PWMLOAD_CH7SEL_MASK (0x80u) +#define MFT_PWMLOAD_CH7SEL_SHIFT (7u) +#define MFT_PWMLOAD_CH7SEL_WIDTH (1u) +#define MFT_PWMLOAD_CH6SEL_MASK (0x40u) +#define MFT_PWMLOAD_CH6SEL_SHIFT (6u) +#define MFT_PWMLOAD_CH6SEL_WIDTH (1u) +#define MFT_PWMLOAD_CH5SEL_MASK (0x20u) +#define MFT_PWMLOAD_CH5SEL_SHIFT (5u) +#define MFT_PWMLOAD_CH5SEL_WIDTH (1u) +#define MFT_PWMLOAD_CH4SEL_MASK (0x10u) +#define MFT_PWMLOAD_CH4SEL_SHIFT (4u) +#define MFT_PWMLOAD_CH4SEL_WIDTH (1u) +#define MFT_PWMLOAD_CH3SEL_MASK (0x08u) +#define MFT_PWMLOAD_CH3SEL_SHIFT (3u) +#define MFT_PWMLOAD_CH3SEL_WIDTH (1u) +#define MFT_PWMLOAD_CH2SEL_MASK (0x04u) +#define MFT_PWMLOAD_CH2SEL_SHIFT (2u) +#define MFT_PWMLOAD_CH2SEL_WIDTH (1u) +#define MFT_PWMLOAD_CH1SEL_MASK (0x02u) +#define MFT_PWMLOAD_CH1SEL_SHIFT (1u) +#define MFT_PWMLOAD_CH1SEL_WIDTH (1u) +#define MFT_PWMLOAD_CH0SEL_MASK (0x01u) +#define MFT_PWMLOAD_CH0SEL_SHIFT (0u) +#define MFT_PWMLOAD_CH0SEL_WIDTH (1u) + +/* HCR Bit Fields */ +#define MFT_HCR_HCVAL_MASK (0xFFFFu) +#define MFT_HCR_HCVAL_SHIFT (0u) +#define MFT_HCR_HCVAL_WIDTH (16u) + +/* PAIR_DEADTIME Bit Fields */ +#define MFT_PAIR_DEADTIME_DTVALEX_MASK (0xF0000u) +#define MFT_PAIR_DEADTIME_DTVALEX_SHIFT (16u) +#define MFT_PAIR_DEADTIME_DTVALEX_WIDTH (4u) +#define MFT_PAIR_DEADTIME_DTPS_MASK (0xC0u) +#define MFT_PAIR_DEADTIME_DTPS_SHIFT (6u) +#define MFT_PAIR_DEADTIME_DTPS_WIDTH (2u) +#define MFT_PAIR_DEADTIME_DTVAL_MASK (0x3Fu) +#define MFT_PAIR_DEADTIME_DTVAL_SHIFT (0u) +#define MFT_PAIR_DEADTIME_DTVAL_WIDTH (6u) + +/* MOD_MIRROR Bit Fields */ +#define MFT_MOD_MIRROR_MOD_M_MASK (0xFFFF0000u) +#define MFT_MOD_MIRROR_MOD_M_SHIFT (16u) +#define MFT_MOD_MIRROR_MOD_M_WIDTH (16u) +#define MFT_MOD_MIRROR_FRACMOD_M_MASK (0xF800u) +#define MFT_MOD_MIRROR_FRACMOD_M_SHIFT (11u) +#define MFT_MOD_MIRROR_FRACMOD_M_WIDTH (5u) + +/* CV_MIRROR Bit Fields */ +#define MFT_CV_MIRROR_VAL_M_MASK (0xFFFF0000u) +#define MFT_CV_MIRROR_VAL_M_SHIFT (16u) +#define MFT_CV_MIRROR_VAL_M_WIDTH (16u) +#define MFT_CV_MIRROR_FRACVAL_MASK (0xF800u) +#define MFT_CV_MIRROR_FRACVAL_SHIFT (11u) +#define MFT_CV_MIRROR_FRACVAL_WIDTH (5u) + +/* SIM_OBE Bit Fields */ +#define MFT_SIM_OBE_OBE_MASK (0x01u) +#define MFT_SIM_OBE_OBE_SHIFT (0u) +#define MFT_SIM_OBE_OBE_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +typedef struct _MftRegType_ +{ + volatile uint32_t SC; /*!< Status And Control, offset: 0x00 */ + volatile uint32_t CNT; /*!< Counter, offset: 0x04 */ + volatile uint32_t MODULO; /*!< Modulo, offset: 0x08 */ + struct + { + volatile uint32_t CSC; /*!< Channel Status And Control */ + volatile uint32_t CV; /*!< Channel Value */ + } CH[MFT_CHANNEL_NUM]; /*!< channels, offset: 0x0C */ + volatile uint32_t CNTIN; /*!< Counter Initial Value, offset: 0x4C */ + volatile uint32_t STATUS; /*!< Capture And Compare Status, offset: 0x50 */ + volatile uint32_t MODE; /*!< Features Mode Selection, offset: 0x54 */ + volatile uint32_t SYNC; /*!< Synchronization, offset: 0x58 */ + volatile uint32_t OUTINIT; /*!< Initial State For Channels Output, offset: 0x5C */ + volatile uint32_t OUTMASK; /*!< Output Mask, offset: 0x60 */ + volatile uint32_t COMBINE; /*!< Function For Linked Channels, offset: 0x64 */ + volatile uint32_t DEADTIME; /*!< Deadtime Configuration, offset: 0x68 */ + volatile uint32_t EXTTRIG; /*!< MFT External Trigger, offset: 0x6C */ + volatile uint32_t POL; /*!< Channels Polarity, offset: 0x70 */ + volatile uint32_t FMS; /*!< Fault Mode Status, offset: 0x74 */ + volatile uint32_t FILTER; /*!< Input Capture Filter Control, offset: 0x78 */ + volatile uint32_t FLTCTRL; /*!< Fault Control, offset: 0x7C */ + volatile uint32_t QDCTRL; /*!< Quadrature Decoder Control And Status, offset: 0x80 */ + volatile uint32_t CONF; /*!< Configuration, offset: 0x84 */ + volatile uint32_t FLTPOL; /*!< MFT Fault Input Polarity, offset: 0x88 */ + volatile uint32_t SYNCONF; /*!< Synchronization Configuration, offset: 0x8C */ + volatile uint32_t INVCTRL; /*!< MFT Inverting Control, offset: 0x90 */ + volatile uint32_t SWOCTRL; /*!< MFT Software Output Control, offset: 0x94 */ + volatile uint32_t PWMLOAD; /*!< MFT PWM Load, offset: 0x98 */ + volatile uint32_t HCR; /*!< Half Cycle Register, offset: 0x9C */ + struct + { + volatile uint32_t DEADTIME; /*!< Pair Deadtime Configuration */ + } PAIR[MFT_DEADTIME_PAIR]; /*!< Pairs, offset: 0xA0 */ + volatile uint32_t MOD_MIRROR; /*!< Mirror of Modulo Value, offset: 0xB0 */ + struct + { + volatile uint32_t CV; /*!< Mirror of Channel Match Value */ + } MIRROR[MFT_CHANNEL_NUM]; /*!< Mirror registers, offset: 0xB4 */ + uint32_t RESERVED[1]; /*!< Reserverd block, offset: 0xD4 */ + volatile uint32_t SIM_OBE; /*!< SIM Output Enable, offset: 0xD8 */ +} MftRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the Filter Prescaler + * + * This function gets the current Filter Prescaler. + * The bits FLTPS selects the clock prescaler used in the MFT filters: + * - channel input filters + * - fault inputs filters + * - quadrature decoder phase A and B inputs filters + * Writing to the bits FLTPS has immediate effect. + * + * \param[in] obj : pointer to MFT register instance + * \return Filter Prescaler + * - 0000b : Divide by 1 + * - 0001b : Divide by 2 + * - 0010b : Divide by 3 + * - 0011b : Divide by 4 + * - 0100b : Divide by 5 + * - 0101b : Divide by 6 + * - 0110b : Divide by 7 + * - 0111b : Divide by 8 + * - 1000b : Divide by 9 + * - 1001b : Divide by 10 + * - 1010b : Divide by 11 + * - 1011b : Divide by 12 + * - 1100b : Divide by 13 + * - 1101b : Divide by 14 + * - 1110b : Divide by 15 + * - 1111b : Divide by 16 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScFltPs(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_FLTPS_MASK) >> MFT_SC_FLTPS_SHIFT); +} + +/*! \brief Sets the Filter Prescaler + * + * This function sets the Filter Prescaler. + * The bits FLTPS selects the clock prescaler used in the MFT filters: + * - channel input filters + * - fault inputs filters + * - quadrature decoder phase A and B inputs filters + * Writing to the bits FLTPS has immediate effect. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Filter Prescaler + * - 0000b : Divide by 1 + * - 0001b : Divide by 2 + * - 0010b : Divide by 3 + * - 0011b : Divide by 4 + * - 0100b : Divide by 5 + * - 0101b : Divide by 6 + * - 0110b : Divide by 7 + * - 0111b : Divide by 8 + * - 1000b : Divide by 9 + * - 1001b : Divide by 10 + * - 1010b : Divide by 11 + * - 1011b : Divide by 12 + * - 1100b : Divide by 13 + * - 1101b : Divide by 14 + * - 1110b : Divide by 15 + * - 1111b : Divide by 16 + */ +__attribute__((always_inline)) static inline void MftReg_SetScFltPs(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_FLTPS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_FLTPS_SHIFT)) & MFT_SC_FLTPS_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Channel 7 PWM enable bit + * + * This function gets the current Channel 7 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 7 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScPwmEn7(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_PWMEN7_MASK) >> MFT_SC_PWMEN7_SHIFT); +} + +/*! \brief Sets the Channel 7 PWM enable bit + * + * This function sets the Channel 7 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 7 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetScPwmEn7(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_PWMEN7_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_PWMEN7_SHIFT)) & MFT_SC_PWMEN7_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Channel 6 PWM enable bit + * + * This function gets the current Channel 6 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 6 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScPwmEn6(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_PWMEN6_MASK) >> MFT_SC_PWMEN6_SHIFT); +} + +/*! \brief Sets the Channel 6 PWM enable bit + * + * This function sets the Channel 6 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 6 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetScPwmEn6(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_PWMEN6_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_PWMEN6_SHIFT)) & MFT_SC_PWMEN6_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Channel 5 PWM enable bit + * + * This function gets the current Channel 5 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 5 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScPwmEn5(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_PWMEN5_MASK) >> MFT_SC_PWMEN5_SHIFT); +} + +/*! \brief Sets the Channel 5 PWM enable bit + * + * This function sets the Channel 5 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 5 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetScPwmEn5(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_PWMEN5_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_PWMEN5_SHIFT)) & MFT_SC_PWMEN5_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Channel 4 PWM enable bit + * + * This function gets the current Channel 4 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 4 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScPwmEn4(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_PWMEN4_MASK) >> MFT_SC_PWMEN4_SHIFT); +} + +/*! \brief Sets the Channel 4 PWM enable bit + * + * This function sets the Channel 4 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 4 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetScPwmEn4(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_PWMEN4_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_PWMEN4_SHIFT)) & MFT_SC_PWMEN4_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Channel 3 PWM enable bit + * + * This function gets the current Channel 3 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 3 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScPwmEn3(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_PWMEN3_MASK) >> MFT_SC_PWMEN3_SHIFT); +} + +/*! \brief Sets the Channel 3 PWM enable bit + * + * This function sets the Channel 3 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 3 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetScPwmEn3(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_PWMEN3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_PWMEN3_SHIFT)) & MFT_SC_PWMEN3_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Channel 2 PWM enable bit + * + * This function gets the current Channel 2 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 2 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScPwmEn2(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_PWMEN2_MASK) >> MFT_SC_PWMEN2_SHIFT); +} + +/*! \brief Sets the Channel 2 PWM enable bit + * + * This function sets the Channel 2 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 2 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetScPwmEn2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_PWMEN2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_PWMEN2_SHIFT)) & MFT_SC_PWMEN2_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Channel 1 PWM enable bit + * + * This function gets the current Channel 1 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 1 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScPwmEn1(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_PWMEN1_MASK) >> MFT_SC_PWMEN1_SHIFT); +} + +/*! \brief Sets the Channel 1 PWM enable bit + * + * This function sets the Channel 1 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 1 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetScPwmEn1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_PWMEN1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_PWMEN1_SHIFT)) & MFT_SC_PWMEN1_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Channel 0 PWM enable bit + * + * This function gets the current Channel 0 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 0 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScPwmEn0(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_PWMEN0_MASK) >> MFT_SC_PWMEN0_SHIFT); +} + +/*! \brief Sets the Channel 0 PWM enable bit + * + * This function sets the Channel 0 PWM enable bit. + * This bit enables the PWM channel output. This bit should be set to 0 (output disabled) when an input mode is used. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 0 PWM enable bit + * - 0b : Channel output port is disabled. + * - 1b : Channel output port is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetScPwmEn0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_PWMEN0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_PWMEN0_SHIFT)) & MFT_SC_PWMEN0_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Timer Overflow Flag + * + * This function gets the current Timer Overflow Flag. + * Set by hardware when the MFT counter passes the value in the MOD register. The TOF bit is cleared by + * reading the SC register while TOF is set and then writing a 0 to TOF bit. Writing a 1 to TOF has no effect. + * If another MFT overflow occurs between the read and write operations, the write operation has no effect; + * therefore, TOF remains set indicating an overflow has occurred. In this case, a TOF interrupt request is + * not lost due to the clearing sequence for a previous TOF. + * + * \param[in] obj : pointer to MFT register instance + * \return Timer Overflow Flag + * - 0b : MFT counter has not overflowed. + * - 1b : MFT counter has overflowed. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScTof(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_TOF_MASK) >> MFT_SC_TOF_SHIFT); +} + +/*! \brief Sets the Timer Overflow Flag + * + * This function sets the Timer Overflow Flag. + * Set by hardware when the MFT counter passes the value in the MOD register. The TOF bit is cleared by + * reading the SC register while TOF is set and then writing a 0 to TOF bit. Writing a 1 to TOF has no effect. + * If another MFT overflow occurs between the read and write operations, the write operation has no effect; + * therefore, TOF remains set indicating an overflow has occurred. In this case, a TOF interrupt request is + * not lost due to the clearing sequence for a previous TOF. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Timer Overflow Flag + * - 0b : clear the flag + * - 1b : No effect + */ +__attribute__((always_inline)) static inline void MftReg_SetScTof(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_TOF_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_TOF_SHIFT)) & MFT_SC_TOF_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Timer Overflow Interrupt Enable + * + * This function gets the current Timer Overflow Interrupt Enable. + * Enables MFT overflow interrupts. + * + * \param[in] obj : pointer to MFT register instance + * \return Timer Overflow Interrupt Enable + * - 0b : Disable TOF interrupts. Use software polling. + * - 1b : Enable TOF interrupts. An interrupt is generated when TOF equals one. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScToie(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_TOIE_MASK) >> MFT_SC_TOIE_SHIFT); +} + +/*! \brief Sets the Timer Overflow Interrupt Enable + * + * This function sets the Timer Overflow Interrupt Enable. + * Enables MFT overflow interrupts. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Timer Overflow Interrupt Enable + * - 0b : Disable TOF interrupts. Use software polling. + * - 1b : Enable TOF interrupts. An interrupt is generated when TOF equals one. + */ +__attribute__((always_inline)) static inline void MftReg_SetScToie(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_TOIE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_TOIE_SHIFT)) & MFT_SC_TOIE_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Reload Flag + * + * This function gets the current Reload Flag. + * The RF bit is set at each selected reload point. See Reload Points. + * The RF bit is cleared by reading the SC register while RF is set and then writing a 0 to RF bit. Writing 1 to + * RF has no effect. If another selected reload point happens between the read and write operations, the + * write operation has no effect; therefore, RF remains set. + * + * \param[in] obj : pointer to MFT register instance + * \return Reload Flag + * - 0b : A selected reload point did not happen + * - 1b : A selected reload point happened + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScRf(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_RF_MASK) >> MFT_SC_RF_SHIFT); +} + +/*! \brief Sets the Reload Flag + * + * This function sets the Reload Flag. + * The RF bit is set at each selected reload point. See Reload Points. + * The RF bit is cleared by reading the SC register while RF is set and then writing a 0 to RF bit. Writing 1 to + * RF has no effect. If another selected reload point happens between the read and write operations, the + * write operation has no effect; therefore, RF remains set. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Reload Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetScRf(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_RF_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_RF_SHIFT)) & MFT_SC_RF_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Reload Point Interrupt Enable + * + * This function gets the current Reload Point Interrupt Enable. + * Enables the reload point interrupt. + * + * \param[in] obj : pointer to MFT register instance + * \return Reload Point Interrupt Enable + * - 0b : Reload point interrupt is disabled. + * - 1b : Reload point interrupt is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScRie(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_RIE_MASK) >> MFT_SC_RIE_SHIFT); +} + +/*! \brief Sets the Reload Point Interrupt Enable + * + * This function sets the Reload Point Interrupt Enable. + * Enables the reload point interrupt. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Reload Point Interrupt Enable + * - 0b : Reload point interrupt is disabled. + * - 1b : Reload point interrupt is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetScRie(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_RIE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_RIE_SHIFT)) & MFT_SC_RIE_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Center-Aligned PWM Select + * + * This function gets the current Center-Aligned PWM Select. + * Selects CPWM mode. This mode configures the MFT to operate in Up-Down Counting mode. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Center-Aligned PWM Select + * - 0b : MFT counter operates in Up Counting mode. + * - 1b : MFT counter operates in Up-Down Counting mode. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScCPwms(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_CPWMS_MASK) >> MFT_SC_CPWMS_SHIFT); +} + +/*! \brief Sets the Center-Aligned PWM Select + * + * This function sets the Center-Aligned PWM Select. + * Selects CPWM mode. This mode configures the MFT to operate in Up-Down Counting mode. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Center-Aligned PWM Select + * - 0b : MFT counter operates in Up Counting mode. + * - 1b : MFT counter operates in Up-Down Counting mode. + */ +__attribute__((always_inline)) static inline void MftReg_SetScCPwms(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_CPWMS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_CPWMS_SHIFT)) & MFT_SC_CPWMS_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Clock Source Selection + * + * This function gets the current Clock Source Selection. + * Selects one of the three MFT counter clock sources. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Clock Source Selection + * - 00b : No clock selected. This in effect disables the MFT counter. + * - 01b : MFT input clock + * - 10b : Fixed frequency + * - 11b : External clock + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScClks(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_CLKS_MASK) >> MFT_SC_CLKS_SHIFT); +} + +/*! \brief Sets the Clock Source Selection + * + * This function sets the Clock Source Selection. + * Selects one of the three MFT counter clock sources. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Clock Source Selection + * - 00b : No clock selected. This in effect disables the MFT counter. + * - 01b : MFT input clock + * - 10b : Fixed frequency + * - 11b : External clock + */ +__attribute__((always_inline)) static inline void MftReg_SetScClks(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_CLKS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_CLKS_SHIFT)) & MFT_SC_CLKS_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Prescale Factor Selection + * + * This function gets the current Prescale Factor Selection. + * Selects one of 8 division factors for the clock source selected by CLKS. The new prescaler factor affects + * the clock source on the next MFT input clock cycle after the new value is updated into the register bits. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Prescale Factor Selection + * - 000b : Divide by 1 + * - 001b : Divide by 2 + * - 010b : Divide by 4 + * - 011b : Divide by 8 + * - 100b : Divide by 16 + * - 101b : Divide by 32 + * - 110b : Divide by 64 + * - 111b : Divide by 128 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetScPs(const MftRegType *obj) +{ + return ((obj->SC & MFT_SC_PS_MASK) >> MFT_SC_PS_SHIFT); +} + +/*! \brief Sets the Prescale Factor Selection + * + * This function sets the Prescale Factor Selection. + * Selects one of 8 division factors for the clock source selected by CLKS. The new prescaler factor affects + * the clock source on the next MFT input clock cycle after the new value is updated into the register bits. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Prescale Factor Selection + * - 000b : Divide by 1 + * - 001b : Divide by 2 + * - 010b : Divide by 4 + * - 011b : Divide by 8 + * - 100b : Divide by 16 + * - 101b : Divide by 32 + * - 110b : Divide by 64 + * - 111b : Divide by 128 + */ +__attribute__((always_inline)) static inline void MftReg_SetScPs(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~MFT_SC_PS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SC_PS_SHIFT)) & MFT_SC_PS_MASK); + obj->SC = tmp; +} + +/*! \brief Gets the Counter Value + * + * This function gets the current Counter Value. + * The CNT register contains the MFT counter value. + * Reset clears the CNT register. Writing any value to COUNT updates the counter with its initial value, CNTIN + * + * \param[in] obj : pointer to MFT register instance + * \return Counter Value + */ +__attribute__((always_inline)) static inline uint16_t MftReg_GetCntCount(const MftRegType *obj) +{ + return ((obj->CNT & MFT_CNT_COUNT_MASK) >> MFT_CNT_COUNT_SHIFT); +} + +/*! \brief Sets the Counter Value + * + * This function sets the current Counter Value. + * The CNT register contains the MFT counter value. + * Reset clears the CNT register. Writing any value to COUNT updates the counter with its initial value, CNTIN + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : Counter Value + */ +__attribute__((always_inline)) static inline void MftReg_SetCntCount(MftRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->CNT; + + tmp &= ~MFT_CNT_COUNT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CNT_COUNT_SHIFT)) & MFT_CNT_COUNT_MASK); + obj->CNT = tmp; +} + +/*! \brief Gets the Modulo Value + * + * This function gets the current Modulo Value. + * Writes to the MOD register are done on its write buffer. + * The MOD register is updated with its write buffer value according to Registers updated from write buffers. + * If MFTEN = 0, a write to SC register resets manually this write coherency mechanism + * + * \param[in] obj : pointer to MFT register instance + * \return Modulo Value + */ +__attribute__((always_inline)) static inline uint16_t MftReg_GetModuloMod(const MftRegType *obj) +{ + return ((obj->MODULO & MFT_MODULO_MOD_MASK) >> MFT_MODULO_MOD_SHIFT); +} + +/*! \brief Sets the Modulo Value + * + * This function sets the Modulo Value. + * Writes to the MOD register are done on its write buffer. + * The MOD register is updated with its write buffer value according to Registers updated from write buffers. + * If MFTEN = 0, a write to SC register resets manually this write coherency mechanism + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Modulo Value + */ +__attribute__((always_inline)) static inline void MftReg_SetModuloMod(MftRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->MODULO; + + tmp &= ~MFT_MODULO_MOD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_MODULO_MOD_SHIFT)) & MFT_MODULO_MOD_MASK); + obj->MODULO = tmp; +} + +/*! \brief Gets the Channel (n) Output Value + * + * This function gets the current Channel (n) Output Value. + * The CHOV bit has the final value of the channel (n) output. + * + * \note The CHOV bit should be ignored when the channel (n) is not in an output mode. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Channel (n) Output Value + * - 0b : The channel (n) output is zero. + * - 1b : The channel (n) output is one. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscChov(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_CHOV_MASK) >> MFT_CSC_CHOV_SHIFT); +} + +/*! \brief Gets the Channel (n) Input State + * + * This function gets the current Channel (n) Input State. + * The CHIS bit has the value of the channel (n) input after the double-sampling or the filtering (if the + * channel (n) filter is enabled) both them are inside the MFT. + * + * \note The CHIS bit should be ignored when the channel (n) is not in an input mode. + * + * \note When the pair channels is on dual edge mode, the channel (n+1) CHIS bit is the channel (n+1) + * input value and not the channel (n) input value (this signal is the input signal used by the dual + * edge mode). + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Channel (n) Input State + * - 0b : The channel (n) input is zero. + * - 1b : The channel (n) input is one. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscChis(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_CHIS_MASK) >> MFT_CSC_CHIS_SHIFT); +} + +/*! \brief Gets the Trigger mode control + * + * This function gets the current Trigger mode control. + * This bit controls the trigger generation on MFT channel outputs. This mode is allowed only if when MFT + * channel is configured to EPWM or CPWM modes. If a match in the channel occurs, a trigger pulse with + * one MFT clock cycle width will be generated in the channel output. See Channel trigger output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Trigger mode control + * - 0b : Channel outputs will generate the normal PWM outputs without generating a pulse. + * - 1b : If a match in the channel occurs, a trigger generation on channel output will happen. + * The trigger pulse width has one MFT clock cycle. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscTrigMode(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_TRIGMODE_MASK) >> MFT_CSC_TRIGMODE_SHIFT); +} + +/*! \brief Sets the Trigger mode control + * + * This function sets the Trigger mode control. + * This bit controls the trigger generation on MFT channel outputs. This mode is allowed only if when MFT + * channel is configured to EPWM or CPWM modes. If a match in the channel occurs, a trigger pulse with + * one MFT clock cycle width will be generated in the channel output. See Channel trigger output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of Trigger mode control + * - 0b : Channel outputs will generate the normal PWM outputs without generating a pulse. + * - 1b : If a match in the channel occurs, a trigger generation on channel output will happen. + * The trigger pulse width has one MFT clock cycle. + */ +__attribute__((always_inline)) static inline void MftReg_SetCscTrigMode(MftRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->CH[channel].CSC; + + tmp &= ~MFT_CSC_TRIGMODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CSC_TRIGMODE_SHIFT)) & MFT_CSC_TRIGMODE_MASK); + obj->CH[channel].CSC = tmp; +} + +/*! \brief Gets the Channel (n) Flag + * + * This function gets the current Channel (n) Flag. + * Set by hardware when an event occurs on the channel (n). CHF is cleared by reading the CnSC register + * while CHF is set and then writing a 0 to the CHF bit. Writing a 1 to CHF has no effect. + * If another event occurs between the read and write operations, the write operation has no effect; + * therefore, CHF remains set indicating an event has occurred. In this case a CHF interrupt request is not + * lost due to the clearing sequence for a previous CHF. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Channel (n) Flag + * - 0b : No channel (n) event has occurred. + * - 1b : A channel (n) event has occurred. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscChf(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_CHF_MASK) >> MFT_CSC_CHF_SHIFT); +} + +/*! \brief Sets the Channel (n) Flag + * + * This function sets the Channel (n) Flag. + * Set by hardware when an event occurs on the channel (n). CHF is cleared by reading the CnSC register + * while CHF is set and then writing a 0 to the CHF bit. Writing a 1 to CHF has no effect. + * If another event occurs between the read and write operations, the write operation has no effect; + * therefore, CHF remains set indicating an event has occurred. In this case a CHF interrupt request is not + * lost due to the clearing sequence for a previous CHF. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of Channel (n) Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetCscChf(MftRegType *obj, uint8_t channel, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->CH[channel].CSC; + + tmp &= ~MFT_CSC_CHF_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CSC_CHF_SHIFT)) & MFT_CSC_CHF_MASK); + obj->CH[channel].CSC = tmp; +} + +/*! \brief Gets the Channel (n) Interrupt Enable + * + * This function gets the current Channel (n) Interrupt Enable. + * Enables channel (n) interrupt. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Channel (n) Interrupt Enable + * - 0b : Disable channel (n) interrupt. Use software polling. + * - 1b : Enable channel (n) interrupt. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscChie(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_CHIE_MASK) >> MFT_CSC_CHIE_SHIFT); +} + +/*! \brief Sets the Channel (n) Interrupt Enable + * + * This function sets the Channel (n) Interrupt Enable. + * Enables channel (n) interrupt. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of Channel (n) Interrupt Enable + * - 0b : Disable channel (n) interrupt. Use software polling. + * - 1b : Enable channel (n) interrupt. + */ +__attribute__((always_inline)) static inline void MftReg_SetCscChie(MftRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->CH[channel].CSC; + + tmp &= ~MFT_CSC_CHIE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CSC_CHIE_SHIFT)) & MFT_CSC_CHIE_MASK); + obj->CH[channel].CSC = tmp; +} + +/*! \brief Gets the Channel (n) Mode Select + * + * This function gets the current Channel (n) Mode Select. + * Used on the selection of the channel (n) mode. See Channel Modes. +This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Channel (n) Mode Select + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscMsb(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_MSB_MASK) >> MFT_CSC_MSB_SHIFT); +} + +/*! \brief Sets the Channel (n) Mode Select + * + * This function sets the Channel (n) Mode Select. + * Used on the selection of the channel (n) mode. See Channel Modes. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of Channel (n) Mode Select + */ +__attribute__((always_inline)) static inline void MftReg_SetCscMsb(MftRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->CH[channel].CSC; + + tmp &= ~MFT_CSC_MSB_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CSC_MSB_SHIFT)) & MFT_CSC_MSB_MASK); + obj->CH[channel].CSC = tmp; +} + +/*! \brief Gets the Channel (n) Mode Select + * + * This function gets the current Channel (n) Mode Select. + * Used on the selection of the channel (n) mode. See Channel Modes. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Channel (n) Mode Select + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscMsa(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_MSA_MASK) >> MFT_CSC_MSA_SHIFT); +} + +/*! \brief Sets the Channel (n) Mode Select + * + * This function sets the Channel (n) Mode Select. + * Used on the selection of the channel (n) mode. See Channel Modes. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of Channel (n) Mode Select + */ +__attribute__((always_inline)) static inline void MftReg_SetCscMsa(MftRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->CH[channel].CSC; + + tmp &= ~MFT_CSC_MSA_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CSC_MSA_SHIFT)) & MFT_CSC_MSA_MASK); + obj->CH[channel].CSC = tmp; +} + +/*! \brief Gets the Channel (n) Edge or Level Select + * + * This function gets the current Channel (n) Edge or Level Select. + * Used on the selection of the channel (n) mode. See Channel Modes. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Channel (n) Edge or Level Select + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscElsb(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_ELSB_MASK) >> MFT_CSC_ELSB_SHIFT); +} + +/*! \brief Sets the Channel (n) Edge or Level Select + * + * This function sets the Channel (n) Edge or Level Select. + * Used on the selection of the channel (n) mode. See Channel Modes. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of Channel (n) Edge or Level Select + */ +__attribute__((always_inline)) static inline void MftReg_SetCscElsb(MftRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->CH[channel].CSC; + + tmp &= ~MFT_CSC_ELSB_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CSC_ELSB_SHIFT)) & MFT_CSC_ELSB_MASK); + obj->CH[channel].CSC = tmp; +} + +/*! \brief Gets the Channel (n) Edge or Level Select + * + * This function gets the current Channel (n) Edge or Level Select. + * Used on the selection of the channel (n) mode. See Channel Modes. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Channel (n) Edge or Level Select + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscElsa(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_ELSA_MASK) >> MFT_CSC_ELSA_SHIFT); +} + +/*! \brief Sets the Channel (n) Edge or Level Select + * + * This function sets the Channel (n) Edge or Level Select. + * Used on the selection of the channel (n) mode. See Channel Modes. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of Channel (n) Edge or Level Select + */ +__attribute__((always_inline)) static inline void MftReg_SetCscElsa(MftRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->CH[channel].CSC; + + tmp &= ~MFT_CSC_ELSA_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CSC_ELSA_SHIFT)) & MFT_CSC_ELSA_MASK); + obj->CH[channel].CSC = tmp; +} + +/*! \brief Gets the MFT counter reset by the selected input capture event + * + * This function gets the current MFT counter reset by the selected input capture event. + * MFT counter reset is driven by the selected event of the channel (n) in the Input Capture mode. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return MFT counter reset by the selected input capture event + * - 0b : MFT counter is not reset when the selected channel (n) input event is detected. + * - 1b : MFT counter is reset when the selected channel (n) input event is detected. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscIcrst(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_ICRST_MASK) >> MFT_CSC_ICRST_SHIFT); +} + +/*! \brief Sets the MFT counter reset by the selected input capture event + * + * This function sets the MFT counter reset by the selected input capture event. + * MFT counter reset is driven by the selected event of the channel (n) in the Input Capture mode. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of MFT counter reset by the selected input capture event + * - 0b : MFT counter is not reset when the selected channel (n) input event is detected. + * - 1b : MFT counter is reset when the selected channel (n) input event is detected. + */ +__attribute__((always_inline)) static inline void MftReg_SetCscIcrst(MftRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->CH[channel].CSC; + + tmp &= ~MFT_CSC_ICRST_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CSC_ICRST_SHIFT)) & MFT_CSC_ICRST_MASK); + obj->CH[channel].CSC = tmp; +} + +/*! \brief Gets the DMA Enable + * + * This function gets the current DMA Enable. + * Enables DMA transfers for the channel. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return DMA Enable + * - 0b : Disable DMA transfers. + * - 1b : Enable DMA transfers. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCscDma(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CSC & MFT_CSC_DMA_MASK) >> MFT_CSC_DMA_SHIFT); +} + +/*! \brief Sets the DMA Enable + * + * This function sets the DMA Enable. + * Enables DMA transfers for the channel. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of DMA Enable + * - 0b : Disable DMA transfers. + * - 1b : Enable DMA transfers. + */ +__attribute__((always_inline)) static inline void MftReg_SetCscDma(MftRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->CH[channel].CSC; + + tmp &= ~MFT_CSC_DMA_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CSC_DMA_SHIFT)) & MFT_CSC_DMA_MASK); + obj->CH[channel].CSC = tmp; +} + +/*! \brief Gets the Channel Value + * + * This function gets the current Channel Value. + * Captured MFT counter value of the input modes or the match value for the output modes + * In Input Capture , Capture Test, and Dual Edge Capture modes, any write to a CnV register is ignored. + * In output modes, writes to the CnV register are done on its write buffer + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Channel Value + */ +__attribute__((always_inline)) static inline uint16_t MftReg_GetCvVal(const MftRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CV & MFT_CV_VAL_MASK) >> MFT_CV_VAL_SHIFT); +} + +/*! \brief Sets the Channel Value + * + * This function sets the current Channel Value. + * Captured MFT counter value of the input modes or the match value for the output modes + * In Input Capture , Capture Test, and Dual Edge Capture modes, any write to a CnV register is ignored. + * In output modes, writes to the CnV register are done on its write buffer + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : Channel Value + */ +__attribute__((always_inline)) static inline void MftReg_SetCvVal(MftRegType *obj, uint8_t channel, uint16_t value) +{ + uint32_t tmp = obj->CH[channel].CV; + + tmp &= ~MFT_CV_VAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CV_VAL_SHIFT)) & MFT_CV_VAL_MASK); + obj->CH[channel].CV = tmp; +} + +/*! \brief Gets the Initial Value Of The MFT Counter + * + * This function gets the current Initial Value Of The MFT Counter. + * Writing to the CNTIN register latches the value into a buffer. + * The CNTIN register is updated with the value of its write buffer according to Registers updated from write buffers + * + * \param[in] obj : pointer to MFT register instance + * \return Initial Value Of The MFT Counter + */ +__attribute__((always_inline)) static inline uint16_t MftReg_GetCntInCntInit(const MftRegType *obj) +{ + return ((obj->CNTIN & MFT_CNTIN_CNTINIT_MASK) >> MFT_CNTIN_CNTINIT_SHIFT); +} + +/*! \brief Sets the Initial Value Of The MFT Counter + * + * This function sets the Initial Value Of The MFT Counter. + * Writing to the CNTIN register latches the value into a buffer. + * The CNTIN register is updated with the value of its write buffer according to Registers updated from write buffers + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Initial Value Of The MFT Counter + */ +__attribute__((always_inline)) static inline void MftReg_SetCntInCntInit(MftRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->CNTIN; + + tmp &= ~MFT_CNTIN_CNTINIT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CNTIN_CNTINIT_SHIFT)) & MFT_CNTIN_CNTINIT_MASK); + obj->CNTIN = tmp; +} + +/*! \brief Gets the Channel 7 Flag + * + * This function gets the current Channel 7 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 7 Flag + * - 0b : No channel event has occurred. + * - 1b : A channel event has occurred. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetStatusCh7F(const MftRegType *obj) +{ + return ((obj->STATUS & MFT_STATUS_CH7F_MASK) >> MFT_STATUS_CH7F_SHIFT); +} + +/*! \brief Sets the Channel 7 Flag + * + * This function sets the Channel 7 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 7 Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetStatusCh7F(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->STATUS; + + tmp &= ~MFT_STATUS_CH7F_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_STATUS_CH7F_SHIFT)) & MFT_STATUS_CH7F_MASK); + obj->STATUS = tmp; +} + +/*! \brief Gets the Channel 6 Flag + * + * This function gets the current Channel 6 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 6 Flag + * - 0b : No channel event has occurred. + * - 1b : A channel event has occurred. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetStatusCh6F(const MftRegType *obj) +{ + return ((obj->STATUS & MFT_STATUS_CH6F_MASK) >> MFT_STATUS_CH6F_SHIFT); +} + +/*! \brief Sets the Channel 6 Flag + * + * This function sets the Channel 6 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 6 Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetStatusCh6F(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->STATUS; + + tmp &= ~MFT_STATUS_CH6F_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_STATUS_CH6F_SHIFT)) & MFT_STATUS_CH6F_MASK); + obj->STATUS = tmp; +} + +/*! \brief Gets the Channel 5 Flag + * + * This function gets the current Channel 5 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 5 Flag + * - 0b : No channel event has occurred. + * - 1b : A channel event has occurred. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetStatusCh5F(const MftRegType *obj) +{ + return ((obj->STATUS & MFT_STATUS_CH5F_MASK) >> MFT_STATUS_CH5F_SHIFT); +} + +/*! \brief Sets the Channel 5 Flag + * + * This function sets the Channel 5 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 5 Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetStatusCh5F(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->STATUS; + + tmp &= ~MFT_STATUS_CH5F_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_STATUS_CH5F_SHIFT)) & MFT_STATUS_CH5F_MASK); + obj->STATUS = tmp; +} + +/*! \brief Gets the Channel 4 Flag + * + * This function gets the current Channel 4 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 4 Flag + * - 0b : No channel event has occurred. + * - 1b : A channel event has occurred. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetStatusCh4F(const MftRegType *obj) +{ + return ((obj->STATUS & MFT_STATUS_CH4F_MASK) >> MFT_STATUS_CH4F_SHIFT); +} + +/*! \brief Sets the Channel 4 Flag + * + * This function sets the Channel 4 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 4 Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetStatusCh4F(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->STATUS; + + tmp &= ~MFT_STATUS_CH4F_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_STATUS_CH4F_SHIFT)) & MFT_STATUS_CH4F_MASK); + obj->STATUS = tmp; +} + +/*! \brief Gets the Channel 3 Flag + * + * This function gets the current Channel 3 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 3 Flag + * - 0b : No channel event has occurred. + * - 1b : A channel event has occurred. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetStatusCh3F(const MftRegType *obj) +{ + return ((obj->STATUS & MFT_STATUS_CH3F_MASK) >> MFT_STATUS_CH3F_SHIFT); +} + +/*! \brief Sets the Channel 3 Flag + * + * This function sets the Channel 3 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 3 Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetStatusCh3F(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->STATUS; + + tmp &= ~MFT_STATUS_CH3F_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_STATUS_CH3F_SHIFT)) & MFT_STATUS_CH3F_MASK); + obj->STATUS = tmp; +} + +/*! \brief Gets the Channel 2 Flag + * + * This function gets the current Channel 2 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 2 Flag + * - 0b : No channel event has occurred. + * - 1b : A channel event has occurred. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetStatusCh2F(const MftRegType *obj) +{ + return ((obj->STATUS & MFT_STATUS_CH2F_MASK) >> MFT_STATUS_CH2F_SHIFT); +} + +/*! \brief Sets the Channel 2 Flag + * + * This function sets the Channel 2 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 2 Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetStatusCh2F(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->STATUS; + + tmp &= ~MFT_STATUS_CH2F_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_STATUS_CH2F_SHIFT)) & MFT_STATUS_CH2F_MASK); + obj->STATUS = tmp; +} + +/*! \brief Gets the Channel 1 Flag + * + * This function gets the current Channel 1 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 1 Flag + * - 0b : No channel event has occurred. + * - 1b : A channel event has occurred. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetStatusCh1F(const MftRegType *obj) +{ + return ((obj->STATUS & MFT_STATUS_CH1F_MASK) >> MFT_STATUS_CH1F_SHIFT); +} + +/*! \brief Sets the Channel 1 Flag + * + * This function sets the Channel 1 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 1 Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetStatusCh1F(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->STATUS; + + tmp &= ~MFT_STATUS_CH1F_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_STATUS_CH1F_SHIFT)) & MFT_STATUS_CH1F_MASK); + obj->STATUS = tmp; +} + +/*! \brief Gets the Channel 0 Flag + * + * This function gets the current Channel 0 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 0 Flag + * - 0b : No channel event has occurred. + * - 1b : A channel event has occurred. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetStatusCh0F(const MftRegType *obj) +{ + return ((obj->STATUS & MFT_STATUS_CH0F_MASK) >> MFT_STATUS_CH0F_SHIFT); +} + +/*! \brief Sets the Channel 0 Flag + * + * This function sets the Channel 0 Flag. + * See the register description. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 0 Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetStatusCh0F(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->STATUS; + + tmp &= ~MFT_STATUS_CH0F_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_STATUS_CH0F_SHIFT)) & MFT_STATUS_CH0F_MASK); + obj->STATUS = tmp; +} + +/*! \brief Gets the Fault Interrupt Enable + * + * This function gets the current Fault Interrupt Enable. + * Enables the generation of an interrupt when a fault is detected by MFT and the MFT fault control is enabled. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Interrupt Enable + * - 0b : Fault control interrupt is disabled. + * - 1b : Fault control interrupt is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetModeFaultIE(const MftRegType *obj) +{ + return ((obj->MODE & MFT_MODE_FAULTIE_MASK) >> MFT_MODE_FAULTIE_SHIFT); +} + +/*! \brief Sets the Fault Interrupt Enable + * + * This function sets the Fault Interrupt Enable. + * Enables the generation of an interrupt when a fault is detected by MFT and the MFT fault control is enabled. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Interrupt Enable + * - 0b : Fault control interrupt is disabled. + * - 1b : Fault control interrupt is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetModeFaultIE(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MODE; + + tmp &= ~MFT_MODE_FAULTIE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_MODE_FAULTIE_SHIFT)) & MFT_MODE_FAULTIE_MASK); + obj->MODE = tmp; +} + +/*! \brief Gets the Fault Control Mode + * + * This function gets the current Fault Control Mode. + * Defines the MFT fault control mode. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Control Mode + * - 00b : Fault control is disabled for all channels. + * - 01b : Fault control is enabled for even channels only (channels 0, 2, 4, and 6), and the selected mode is the manual fault clearing. + * - 10b : Fault control is enabled for all channels, and the selected mode is the manual fault clearing. + * - 11b : Fault control is enabled for all channels, and the selected mode is the automatic fault clearing. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetModeFaultM(const MftRegType *obj) +{ + return ((obj->MODE & MFT_MODE_FAULTM_MASK) >> MFT_MODE_FAULTM_SHIFT); +} + +/*! \brief Sets the Fault Control Mode + * + * This function sets the Fault Control Mode. + * Defines the MFT fault control mode. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Control Mode + * - 00b : Fault control is disabled for all channels. + * - 01b : Fault control is enabled for even channels only (channels 0, 2, 4, and 6), and the selected mode is the manual fault clearing. + * - 10b : Fault control is enabled for all channels, and the selected mode is the manual fault clearing. + * - 11b : Fault control is enabled for all channels, and the selected mode is the automatic fault clearing. + */ +__attribute__((always_inline)) static inline void MftReg_SetModeFaultM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MODE; + + tmp &= ~MFT_MODE_FAULTM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_MODE_FAULTM_SHIFT)) & MFT_MODE_FAULTM_MASK); + obj->MODE = tmp; +} + +/*! \brief Gets the Capture Test Mode Enable + * + * This function gets the current Capture Test Mode Enable. + * Enables the capture test mode. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Capture Test Mode Enable + * - 0b : Capture test mode is disabled. + * - 1b : Capture test mode is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetModeCapTest(const MftRegType *obj) +{ + return ((obj->MODE & MFT_MODE_CAPTEST_MASK) >> MFT_MODE_CAPTEST_SHIFT); +} + +/*! \brief Sets the Capture Test Mode Enable + * + * This function sets the Capture Test Mode Enable. + * Enables the capture test mode. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Capture Test Mode Enable + * - 0b : Capture test mode is disabled. + * - 1b : Capture test mode is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetModeCapTest(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MODE; + + tmp &= ~MFT_MODE_CAPTEST_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_MODE_CAPTEST_SHIFT)) & MFT_MODE_CAPTEST_MASK); + obj->MODE = tmp; +} + +/*! \brief Gets the PWM Synchronization Mode + * + * This function gets the current PWM Synchronization Mode. + * Selects which triggers can be used by MOD, CnV, OUTMASK, and MFT counter synchronization. + * The PWMSYNC bit configures the synchronization when SYNCMODE is 0. + * + * \param[in] obj : pointer to MFT register instance + * \return PWM Synchronization Mode + * - 0b : No restrictions. Software and hardware triggers can be used by + * MOD, CnV, OUTMASK, and MFT counter synchronization. + * - 1b : Software trigger can only be used by MOD and CnV synchronization, + * and hardware triggers can only be used by OUTMASK and MFT counter synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetModePwmSync(const MftRegType *obj) +{ + return ((obj->MODE & MFT_MODE_PWMSYNC_MASK) >> MFT_MODE_PWMSYNC_SHIFT); +} + +/*! \brief Sets the PWM Synchronization Mode + * + * This function sets the PWM Synchronization Mode. + * Selects which triggers can be used by MOD, CnV, OUTMASK, and MFT counter synchronization. The PWMSYNC bit configures the synchronization + * when SYNCMODE is 0. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of PWM Synchronization Mode + * - 0b : No restrictions. Software and hardware triggers can be used by + * MOD, CnV, OUTMASK, and MFT counter synchronization. + * - 1b : Software trigger can only be used by MOD and CnV synchronization, + * and hardware triggers can only be used by OUTMASK and MFT counter synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetModePwmSync(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MODE; + + tmp &= ~MFT_MODE_PWMSYNC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_MODE_PWMSYNC_SHIFT)) & MFT_MODE_PWMSYNC_MASK); + obj->MODE = tmp; +} + +/*! \brief Gets the Write Protection Disable + * + * This function gets the current Write Protection Disable. + * When write protection is enabled (WPDIS = 0), write protected bits cannot be written. When write + * protection is disabled (WPDIS = 1), write protected bits can be written. The WPDIS bit is the negation of + * the WPEN bit. WPDIS is cleared when 1 is written to WPEN. WPDIS is set when WPEN bit is read as a 1 + * and then 1 is written to WPDIS. Writing 0 to WPDIS has no effect. + * + * \param[in] obj : pointer to MFT register instance + * \return Write Protection Disable + * - 0b : Write protection is enabled. + * - 1b : Write protection is disabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetModeWpDis(const MftRegType *obj) +{ + return ((obj->MODE & MFT_MODE_WPDIS_MASK) >> MFT_MODE_WPDIS_SHIFT); +} + +/*! \brief Sets the Write Protection Disable + * + * This function sets the Write Protection Disable. + * When write protection is enabled (WPDIS = 0), write protected bits cannot be written. When write + * protection is disabled (WPDIS = 1), write protected bits can be written. The WPDIS bit is the negation of + * the WPEN bit. WPDIS is cleared when 1 is written to WPEN. WPDIS is set when WPEN bit is read as a 1 + * and then 1 is written to WPDIS. Writing 0 to WPDIS has no effect. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Write Protection Disable + * - 0b : Write protection is enabled. + * - 1b : Write protection is disabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetModeWpDis(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MODE; + + tmp &= ~MFT_MODE_WPDIS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_MODE_WPDIS_SHIFT)) & MFT_MODE_WPDIS_MASK); + obj->MODE = tmp; +} + +/*! \brief Sets the Initialize The Channels Output + * + * This function sets the Initialize The Channels Output. + * When a 1 is written to INIT bit the channels output is initialized according to the state of their + * corresponding bit in the OUTINIT register. Writing a 0 to INIT bit has no effect. + * The INIT bit is always read as 0 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Initialize The Channels Output + */ +__attribute__((always_inline)) static inline void MftReg_SetModeInit(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MODE; + + tmp &= ~MFT_MODE_INIT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_MODE_INIT_SHIFT)) & MFT_MODE_INIT_MASK); + obj->MODE = tmp; +} + +/*! \brief Gets the MFT Enable + * + * This function gets the current MFT Enable. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return MFT Enable + * - 0b : TPM compatibility. Free running counter and synchronization compatible with TPM. + * - 1b : Free running counter and synchronization are different from TPM behavior. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetModeMftEn(const MftRegType *obj) +{ + return ((obj->MODE & MFT_MODE_MFTEN_MASK) >> MFT_MODE_MFTEN_SHIFT); +} + +/*! \brief Sets the MFT Enable + * + * This function sets the MFT Enable. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of MFT Enable + * - 0b : TPM compatibility. Free running counter and synchronization compatible with TPM. + * - 1b : Free running counter and synchronization are different from TPM behavior. + */ +__attribute__((always_inline)) static inline void MftReg_SetModeMftEn(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MODE; + + tmp &= ~MFT_MODE_MFTEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_MODE_MFTEN_SHIFT)) & MFT_MODE_MFTEN_MASK); + obj->MODE = tmp; +} + +/*! \brief Gets the PWM Synchronization Software Trigger + * + * This function gets the current PWM Synchronization Software Trigger. + * Selects the software trigger as the PWM synchronization trigger. + * The software trigger happens when a 1 is written to SWSYNC bit. + * + * \param[in] obj : pointer to MFT register instance + * \return PWM Synchronization Software Trigger + * - 0b : Software trigger is not selected. + * - 1b : Software trigger is selected. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSyncSwSync(const MftRegType *obj) +{ + return ((obj->SYNC & MFT_SYNC_SWSYNC_MASK) >> MFT_SYNC_SWSYNC_SHIFT); +} + +/*! \brief Sets the PWM Synchronization Software Trigger + * + * This function sets the PWM Synchronization Software Trigger. + * Selects the software trigger as the PWM synchronization trigger. + * The software trigger happens when a 1 is written to SWSYNC bit. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of PWM Synchronization Software Trigger + * - 0b : Software trigger is not selected. + * - 1b : Software trigger is selected. + */ +__attribute__((always_inline)) static inline void MftReg_SetSyncSwSync(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNC; + + tmp &= ~MFT_SYNC_SWSYNC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNC_SWSYNC_SHIFT)) & MFT_SYNC_SWSYNC_MASK); + obj->SYNC = tmp; +} + +/*! \brief Gets the PWM Synchronization Hardware Trigger 2 + * + * This function gets the current PWM Synchronization Hardware Trigger 2. + * Enables hardware trigger 2 to the PWM synchronization. + * Hardware trigger 2 happens when a rising edge is detected at the trigger 2 input signal. + * + * \param[in] obj : pointer to MFT register instance + * \return PWM Synchronization Hardware Trigger 2 + * - 0b : Trigger is disabled. + * - 1b : Trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSyncTrig2(const MftRegType *obj) +{ + return ((obj->SYNC & MFT_SYNC_TRIG2_MASK) >> MFT_SYNC_TRIG2_SHIFT); +} + +/*! \brief Sets the PWM Synchronization Hardware Trigger 2 + * + * This function sets the PWM Synchronization Hardware Trigger 2. + * Enables hardware trigger 2 to the PWM synchronization. + * Hardware trigger 2 happens when a rising edge is detected at the trigger 2 input signal. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of PWM Synchronization Hardware Trigger 2 + * - 0b : Trigger is disabled. + * - 1b : Trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetSyncTrig2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNC; + + tmp &= ~MFT_SYNC_TRIG2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNC_TRIG2_SHIFT)) & MFT_SYNC_TRIG2_MASK); + obj->SYNC = tmp; +} + +/*! \brief Gets the PWM Synchronization Hardware Trigger 1 + * + * This function gets the current PWM Synchronization Hardware Trigger 1. + * Enables hardware trigger 1 to the PWM synchronization. + * Hardware trigger 1 happens when a rising edge is detected at the trigger 1 input signal. + * + * \param[in] obj : pointer to MFT register instance + * \return PWM Synchronization Hardware Trigger 1 + * - 0b : Trigger is disabled. + * - 1b : Trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSyncTrig1(const MftRegType *obj) +{ + return ((obj->SYNC & MFT_SYNC_TRIG1_MASK) >> MFT_SYNC_TRIG1_SHIFT); +} + +/*! \brief Sets the PWM Synchronization Hardware Trigger 1 + * + * This function sets the PWM Synchronization Hardware Trigger 1. + * Enables hardware trigger 1 to the PWM synchronization. + * Hardware trigger 1 happens when a rising edge is detected at the trigger 1 input signal. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of PWM Synchronization Hardware Trigger 1 + * - 0b : Trigger is disabled. + * - 1b : Trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetSyncTrig1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNC; + + tmp &= ~MFT_SYNC_TRIG1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNC_TRIG1_SHIFT)) & MFT_SYNC_TRIG1_MASK); + obj->SYNC = tmp; +} + +/*! \brief Gets the PWM Synchronization Hardware Trigger 0 + * + * This function gets the current PWM Synchronization Hardware Trigger 0. + * Enables hardware trigger 0 to the PWM synchronization. + * Hardware trigger 0 occurs when a rising edge is detected at the trigger 0 input signal. + * + * \param[in] obj : pointer to MFT register instance + * \return PWM Synchronization Hardware Trigger 0 + * - 0b : Trigger is disabled. + * - 1b : Trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSyncTrig0(const MftRegType *obj) +{ + return ((obj->SYNC & MFT_SYNC_TRIG0_MASK) >> MFT_SYNC_TRIG0_SHIFT); +} + +/*! \brief Sets the PWM Synchronization Hardware Trigger 0 + * + * This function sets the PWM Synchronization Hardware Trigger 0. + * Enables hardware trigger 0 to the PWM synchronization. + * Hardware trigger 0 occurs when a rising edge is detected at the trigger 0 input signal. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of PWM Synchronization Hardware Trigger 0 + * - 0b : Trigger is disabled. + * - 1b : Trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetSyncTrig0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNC; + + tmp &= ~MFT_SYNC_TRIG0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNC_TRIG0_SHIFT)) & MFT_SYNC_TRIG0_MASK); + obj->SYNC = tmp; +} + +/*! \brief Gets the Output Mask Synchronization + * + * This function gets the current Output Mask Synchronization. + * Selects when the OUTMASK register is updated with the value of its buffer. + * + * \param[in] obj : pointer to MFT register instance + * \return Output Mask Synchronization + * - 0b : OUTMASK register is updated with the value of its buffer in all rising edges of the MFT input clock. + * - 1b : OUTMASK register is updated with the value of its buffer only by the PWM synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSyncSynchOM(const MftRegType *obj) +{ + return ((obj->SYNC & MFT_SYNC_SYNCHOM_MASK) >> MFT_SYNC_SYNCHOM_SHIFT); +} + +/*! \brief Sets the Output Mask Synchronization + * + * This function sets the Output Mask Synchronization. + * Selects when the OUTMASK register is updated with the value of its buffer. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Output Mask Synchronization + * - 0b : OUTMASK register is updated with the value of its buffer in all rising edges of the MFT input clock. + * - 1b : OUTMASK register is updated with the value of its buffer only by the PWM synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSyncSynchOM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNC; + + tmp &= ~MFT_SYNC_SYNCHOM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNC_SYNCHOM_SHIFT)) & MFT_SYNC_SYNCHOM_MASK); + obj->SYNC = tmp; +} + +/*! \brief Gets the MFT Counter Reinitialization by Synchronization + * + * This function gets the current MFT Counter Reinitialization by Synchronization. + * Determines if the MFT counter is reinitialized when the selected trigger for the synchronization is detected + * (MFT counter synchronization). The REINIT bit configures the synchronization when SYNCMODE is zero. + * + * \param[in] obj : pointer to MFT register instance + * \return MFT Counter Reinitialization by Synchronization + * - 0b : MFT counter continues to count normally. + * - 1b : MFT counter is updated with its initial value when the selected trigger is detected. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSyncReInit(const MftRegType *obj) +{ + return ((obj->SYNC & MFT_SYNC_REINIT_MASK) >> MFT_SYNC_REINIT_SHIFT); +} + +/*! \brief Sets the MFT Counter Reinitialization by Synchronization + * + * This function sets the MFT Counter Reinitialization by Synchronization. + * Determines if the MFT counter is reinitialized when the selected trigger for the synchronization is detected + * (MFT counter synchronization). The REINIT bit configures the synchronization when SYNCMODE is zero. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of MFT Counter Reinitialization by Synchronization + * - 0b : MFT counter continues to count normally. + * - 1b : MFT counter is updated with its initial value when the selected trigger is detected. + */ +__attribute__((always_inline)) static inline void MftReg_SetSyncReInit(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNC; + + tmp &= ~MFT_SYNC_REINIT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNC_REINIT_SHIFT)) & MFT_SYNC_REINIT_MASK); + obj->SYNC = tmp; +} + +/*! \brief Gets the Maximum Loading Point Enable + * + * This function gets the current Maximum Loading Point Enable. + * Selects the maximum loading point to PWM synchronization (Synchronization Points). + * If CNTMAX is 1, the selected loading point is when the MFT counter reaches its maximum value (MOD register). + * + * \param[in] obj : pointer to MFT register instance + * \return Maximum Loading Point Enable + * - 0b : The maximum loading point is disabled. + * - 1b : The maximum loading point is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSyncCntMax(const MftRegType *obj) +{ + return ((obj->SYNC & MFT_SYNC_CNTMAX_MASK) >> MFT_SYNC_CNTMAX_SHIFT); +} + +/*! \brief Sets the Maximum Loading Point Enable + * + * This function sets the Maximum Loading Point Enable. + * Selects the maximum loading point to PWM synchronization (Synchronization Points). + * If CNTMAX is 1, the selected loading point is when the MFT counter reaches its maximum value (MOD register). + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Maximum Loading Point Enable + * - 0b : The maximum loading point is disabled. + * - 1b : The maximum loading point is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetSyncCntMax(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNC; + + tmp &= ~MFT_SYNC_CNTMAX_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNC_CNTMAX_SHIFT)) & MFT_SYNC_CNTMAX_MASK); + obj->SYNC = tmp; +} + +/*! \brief Gets the Minimum Loading Point Enable + * + * This function gets the current Minimum Loading Point Enable. + * Selects the minimum loading point to PWM synchronization (Synchronization Points). + * If CNTMIN is 1, the selected loading point is when the MFT counter reaches its minimum value (CNTIN register). + * + * \param[in] obj : pointer to MFT register instance + * \return Minimum Loading Point Enable + * - 0b : The minimum loading point is disabled. + * - 1b : The minimum loading point is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSyncCntMin(const MftRegType *obj) +{ + return ((obj->SYNC & MFT_SYNC_CNTMIN_MASK) >> MFT_SYNC_CNTMIN_SHIFT); +} + +/*! \brief Sets the Minimum Loading Point Enable + * + * This function sets the Minimum Loading Point Enable. + * Selects the minimum loading point to PWM synchronization (Synchronization Points). + * If CNTMIN is 1, the selected loading point is when the MFT counter reaches its minimum value (CNTIN register). + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Minimum Loading Point Enable + * - 0b : The minimum loading point is disabled. + * - 1b : The minimum loading point is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetSyncCntMin(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNC; + + tmp &= ~MFT_SYNC_CNTMIN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNC_CNTMIN_SHIFT)) & MFT_SYNC_CNTMIN_MASK); + obj->SYNC = tmp; +} + +/*! \brief Gets the Channel 7 Output Initialization Value + * + * This function gets the current Channel 7 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 7 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutInitCh7OI(const MftRegType *obj) +{ + return ((obj->OUTINIT & MFT_OUTINIT_CH7OI_MASK) >> MFT_OUTINIT_CH7OI_SHIFT); +} + +/*! \brief Sets the Channel 7 Output Initialization Value + * + * This function sets the Channel 7 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 7 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutInitCh7OI(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTINIT; + + tmp &= ~MFT_OUTINIT_CH7OI_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTINIT_CH7OI_SHIFT)) & MFT_OUTINIT_CH7OI_MASK); + obj->OUTINIT = tmp; +} + +/*! \brief Gets the Channel 6 Output Initialization Value + * + * This function gets the current Channel 6 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 6 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutInitCh6OI(const MftRegType *obj) +{ + return ((obj->OUTINIT & MFT_OUTINIT_CH6OI_MASK) >> MFT_OUTINIT_CH6OI_SHIFT); +} + +/*! \brief Sets the Channel 6 Output Initialization Value + * + * This function sets the Channel 6 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 6 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutInitCh6OI(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTINIT; + + tmp &= ~MFT_OUTINIT_CH6OI_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTINIT_CH6OI_SHIFT)) & MFT_OUTINIT_CH6OI_MASK); + obj->OUTINIT = tmp; +} + +/*! \brief Gets the Channel 5 Output Initialization Value + * + * This function gets the current Channel 5 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 5 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutInitCh5OI(const MftRegType *obj) +{ + return ((obj->OUTINIT & MFT_OUTINIT_CH5OI_MASK) >> MFT_OUTINIT_CH5OI_SHIFT); +} + +/*! \brief Sets the Channel 5 Output Initialization Value + * + * This function sets the Channel 5 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 5 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutInitCh5OI(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTINIT; + + tmp &= ~MFT_OUTINIT_CH5OI_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTINIT_CH5OI_SHIFT)) & MFT_OUTINIT_CH5OI_MASK); + obj->OUTINIT = tmp; +} + +/*! \brief Gets the Channel 4 Output Initialization Value + * + * This function gets the current Channel 4 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 4 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutInitCh4OI(const MftRegType *obj) +{ + return ((obj->OUTINIT & MFT_OUTINIT_CH4OI_MASK) >> MFT_OUTINIT_CH4OI_SHIFT); +} + +/*! \brief Sets the Channel 4 Output Initialization Value + * + * This function sets the Channel 4 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 4 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutInitCh4OI(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTINIT; + + tmp &= ~MFT_OUTINIT_CH4OI_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTINIT_CH4OI_SHIFT)) & MFT_OUTINIT_CH4OI_MASK); + obj->OUTINIT = tmp; +} + +/*! \brief Gets the Channel 3 Output Initialization Value + * + * This function gets the current Channel 3 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 3 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutInitCh3OI(const MftRegType *obj) +{ + return ((obj->OUTINIT & MFT_OUTINIT_CH3OI_MASK) >> MFT_OUTINIT_CH3OI_SHIFT); +} + +/*! \brief Sets the Channel 3 Output Initialization Value + * + * This function sets the Channel 3 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 3 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutInitCh3OI(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTINIT; + + tmp &= ~MFT_OUTINIT_CH3OI_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTINIT_CH3OI_SHIFT)) & MFT_OUTINIT_CH3OI_MASK); + obj->OUTINIT = tmp; +} + +/*! \brief Gets the Channel 2 Output Initialization Value + * + * This function gets the current Channel 2 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 2 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutInitCh2OI(const MftRegType *obj) +{ + return ((obj->OUTINIT & MFT_OUTINIT_CH2OI_MASK) >> MFT_OUTINIT_CH2OI_SHIFT); +} + +/*! \brief Sets the Channel 2 Output Initialization Value + * + * This function sets the Channel 2 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 2 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutInitCh2OI(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTINIT; + + tmp &= ~MFT_OUTINIT_CH2OI_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTINIT_CH2OI_SHIFT)) & MFT_OUTINIT_CH2OI_MASK); + obj->OUTINIT = tmp; +} + +/*! \brief Gets the Channel 1 Output Initialization Value + * + * This function gets the current Channel 1 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 1 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutInitCh1OI(const MftRegType *obj) +{ + return ((obj->OUTINIT & MFT_OUTINIT_CH1OI_MASK) >> MFT_OUTINIT_CH1OI_SHIFT); +} + +/*! \brief Sets the Channel 1 Output Initialization Value + * + * This function sets the Channel 1 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 1 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutInitCh1OI(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTINIT; + + tmp &= ~MFT_OUTINIT_CH1OI_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTINIT_CH1OI_SHIFT)) & MFT_OUTINIT_CH1OI_MASK); + obj->OUTINIT = tmp; +} + +/*! \brief Gets the Channel 0 Output Initialization Value + * + * This function gets the current Channel 0 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 0 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutInitCh0OI(const MftRegType *obj) +{ + return ((obj->OUTINIT & MFT_OUTINIT_CH0OI_MASK) >> MFT_OUTINIT_CH0OI_SHIFT); +} + +/*! \brief Sets the Channel 0 Output Initialization Value + * + * This function sets the Channel 0 Output Initialization Value. + * Selects the value that is forced into the channel output when the initialization occurs. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 0 Output Initialization Value + * - 0b : The initialization value is 0. + * - 1b : The initialization value is 1. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutInitCh0OI(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTINIT; + + tmp &= ~MFT_OUTINIT_CH0OI_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTINIT_CH0OI_SHIFT)) & MFT_OUTINIT_CH0OI_MASK); + obj->OUTINIT = tmp; +} + +/*! \brief Gets the Channel 7 Output Mask + * + * This function gets the current Channel 7 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 7 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutMaskCh7OM(const MftRegType *obj) +{ + return ((obj->OUTMASK & MFT_OUTMASK_CH7OM_MASK) >> MFT_OUTMASK_CH7OM_SHIFT); +} + +/*! \brief Sets the Channel 7 Output Mask + * + * This function sets the Channel 7 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 7 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutMaskCh7OM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTMASK; + + tmp &= ~MFT_OUTMASK_CH7OM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTMASK_CH7OM_SHIFT)) & MFT_OUTMASK_CH7OM_MASK); + obj->OUTMASK = tmp; +} + +/*! \brief Gets the Channel 6 Output Mask + * + * This function gets the current Channel 6 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 6 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutMaskCh6OM(const MftRegType *obj) +{ + return ((obj->OUTMASK & MFT_OUTMASK_CH6OM_MASK) >> MFT_OUTMASK_CH6OM_SHIFT); +} + +/*! \brief Sets the Channel 6 Output Mask + * + * This function sets the Channel 6 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 6 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutMaskCh6OM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTMASK; + + tmp &= ~MFT_OUTMASK_CH6OM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTMASK_CH6OM_SHIFT)) & MFT_OUTMASK_CH6OM_MASK); + obj->OUTMASK = tmp; +} + +/*! \brief Gets the Channel 5 Output Mask + * + * This function gets the current Channel 5 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 5 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutMaskCh5OM(const MftRegType *obj) +{ + return ((obj->OUTMASK & MFT_OUTMASK_CH5OM_MASK) >> MFT_OUTMASK_CH5OM_SHIFT); +} + +/*! \brief Sets the Channel 5 Output Mask + * + * This function sets the Channel 5 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 5 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutMaskCh5OM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTMASK; + + tmp &= ~MFT_OUTMASK_CH5OM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTMASK_CH5OM_SHIFT)) & MFT_OUTMASK_CH5OM_MASK); + obj->OUTMASK = tmp; +} + +/*! \brief Gets the Channel 4 Output Mask + * + * This function gets the current Channel 4 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 4 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutMaskCh4OM(const MftRegType *obj) +{ + return ((obj->OUTMASK & MFT_OUTMASK_CH4OM_MASK) >> MFT_OUTMASK_CH4OM_SHIFT); +} + +/*! \brief Sets the Channel 4 Output Mask + * + * This function sets the Channel 4 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 4 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutMaskCh4OM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTMASK; + + tmp &= ~MFT_OUTMASK_CH4OM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTMASK_CH4OM_SHIFT)) & MFT_OUTMASK_CH4OM_MASK); + obj->OUTMASK = tmp; +} + +/*! \brief Gets the Channel 3 Output Mask + * + * This function gets the current Channel 3 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 3 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutMaskCh3OM(const MftRegType *obj) +{ + return ((obj->OUTMASK & MFT_OUTMASK_CH3OM_MASK) >> MFT_OUTMASK_CH3OM_SHIFT); +} + +/*! \brief Sets the Channel 3 Output Mask + * + * This function sets the Channel 3 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 3 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutMaskCh3OM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTMASK; + + tmp &= ~MFT_OUTMASK_CH3OM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTMASK_CH3OM_SHIFT)) & MFT_OUTMASK_CH3OM_MASK); + obj->OUTMASK = tmp; +} + +/*! \brief Gets the Channel 2 Output Mask + * + * This function gets the current Channel 2 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 2 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutMaskCh2OM(const MftRegType *obj) +{ + return ((obj->OUTMASK & MFT_OUTMASK_CH2OM_MASK) >> MFT_OUTMASK_CH2OM_SHIFT); +} + +/*! \brief Sets the Channel 2 Output Mask + * + * This function sets the Channel 2 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 2 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutMaskCh2OM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTMASK; + + tmp &= ~MFT_OUTMASK_CH2OM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTMASK_CH2OM_SHIFT)) & MFT_OUTMASK_CH2OM_MASK); + obj->OUTMASK = tmp; +} + +/*! \brief Gets the Channel 1 Output Mask + * + * This function gets the current Channel 1 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 1 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutMaskCh1OM(const MftRegType *obj) +{ + return ((obj->OUTMASK & MFT_OUTMASK_CH1OM_MASK) >> MFT_OUTMASK_CH1OM_SHIFT); +} + +/*! \brief Sets the Channel 1 Output Mask + * + * This function sets the Channel 1 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 1 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutMaskCh1OM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTMASK; + + tmp &= ~MFT_OUTMASK_CH1OM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTMASK_CH1OM_SHIFT)) & MFT_OUTMASK_CH1OM_MASK); + obj->OUTMASK = tmp; +} + +/*! \brief Gets the Channel 0 Output Mask + * + * This function gets the current Channel 0 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 0 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetOutMaskCh0OM(const MftRegType *obj) +{ + return ((obj->OUTMASK & MFT_OUTMASK_CH0OM_MASK) >> MFT_OUTMASK_CH0OM_SHIFT); +} + +/*! \brief Sets the Channel 0 Output Mask + * + * This function sets the Channel 0 Output Mask. + * Defines if the channel output is masked or unmasked. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 0 Output Mask + * - 0b : Channel output is not masked. It continues to operate normally. + * - 1b : Channel output is masked. It is forced to its inactive state. + */ +__attribute__((always_inline)) static inline void MftReg_SetOutMaskCh0OM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OUTMASK; + + tmp &= ~MFT_OUTMASK_CH0OM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_OUTMASK_CH0OM_SHIFT)) & MFT_OUTMASK_CH0OM_MASK); + obj->OUTMASK = tmp; +} + +/*! \brief Gets the Modified Combine Mode For n = 6 + * + * This function gets the current Modified Combine Mode For n = 6. + * Used on the selection of the modified combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Modified Combine Mode For n = 6 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineMCombine3(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_MCOMBINE3_MASK) >> MFT_COMBINE_MCOMBINE3_SHIFT); +} + +/*! \brief Sets the Modified Combine Mode For n = 6 + * + * This function sets the Modified Combine Mode For n = 6. + * Used on the selection of the modified combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Modified Combine Mode For n = 6 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineMCombine3(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_MCOMBINE3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_MCOMBINE3_SHIFT)) & MFT_COMBINE_MCOMBINE3_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Fault Control Enable For n = 6 + * + * This function gets the current Fault Control Enable For n = 6. + * Enables the fault control in channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Control Enable For n = 6 + * - 0b : The fault control in this pair of channels is disabled. + * - 1b : The fault control in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineFaultEn3(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_FAULTEN3_MASK) >> MFT_COMBINE_FAULTEN3_SHIFT); +} + +/*! \brief Sets the Fault Control Enable For n = 6 + * + * This function sets the Fault Control Enable For n = 6. + * Enables the fault control in channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Control Enable For n = 6 + * - 0b : The fault control in this pair of channels is disabled. + * - 1b : The fault control in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineFaultEn3(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_FAULTEN3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_FAULTEN3_SHIFT)) & MFT_COMBINE_FAULTEN3_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Synchronization Enable For n = 6 + * + * This function gets the current Synchronization Enable For n = 6. + * Enables PWM synchronization of registers C(n)V and C(n+1)V. + * + * \param[in] obj : pointer to MFT register instance + * \return Synchronization Enable For n = 6 + * - 0b : The PWM synchronization in this pair of channels is disabled. + * - 1b : The PWM synchronization in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineSyncEn3(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_SYNCEN3_MASK) >> MFT_COMBINE_SYNCEN3_SHIFT); +} + +/*! \brief Sets the Synchronization Enable For n = 6 + * + * This function sets the Synchronization Enable For n = 6. + * Enables PWM synchronization of registers C(n)V and C(n+1)V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Synchronization Enable For n = 6 + * - 0b : The PWM synchronization in this pair of channels is disabled. + * - 1b : The PWM synchronization in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineSyncEn3(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_SYNCEN3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_SYNCEN3_SHIFT)) & MFT_COMBINE_SYNCEN3_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Deadtime Enable For n = 6 + * + * This function gets the current Deadtime Enable For n = 6. + * Enables the deadtime insertion in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Deadtime Enable For n = 6 + * - 0b : The deadtime insertion in this pair of channels is disabled. + * - 1b : The deadtime insertion in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDtEn3(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DTEN3_MASK) >> MFT_COMBINE_DTEN3_SHIFT); +} + +/*! \brief Sets the Deadtime Enable For n = 6 + * + * This function sets the Deadtime Enable For n = 6. + * Enables the deadtime insertion in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Deadtime Enable For n = 6 + * - 0b : The deadtime insertion in this pair of channels is disabled. + * - 1b : The deadtime insertion in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDtEn3(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DTEN3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DTEN3_SHIFT)) & MFT_COMBINE_DTEN3_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Dual Edge Capture Mode Captures For n = 6 + * + * This function gets the current Dual Edge Capture Mode Captures For n = 6. + * Enables the capture of the MFT counter value according to the channel (n) input event and the + * configuration of the dual edge capture bits. + * This field applies only when DECAPEN = 1. + * DECAP bit is cleared automatically by hardware if dual edge capture ¨C one-shot mode is selected and + * when the capture of channel (n+1) event is made. + * + * \param[in] obj : pointer to MFT register instance + * \return Dual Edge Capture Mode Captures For n = 6 + * - 0b : The dual edge captures are inactive. + * - 1b : The dual edge captures are active. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDecap3(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DECAP3_MASK) >> MFT_COMBINE_DECAP3_SHIFT); +} + +/*! \brief Sets the Dual Edge Capture Mode Captures For n = 6 + * + * This function sets the Dual Edge Capture Mode Captures For n = 6. + * Enables the capture of the MFT counter value according to the channel (n) input event and the + * configuration of the dual edge capture bits. + * This field applies only when DECAPEN = 1. + * DECAP bit is cleared automatically by hardware if dual edge capture ¨C one-shot mode is selected and + * when the capture of channel (n+1) event is made. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Dual Edge Capture Mode Captures For n = 6 + * - 0b : The dual edge captures are inactive. + * - 1b : The dual edge captures are active. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDecap3(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DECAP3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DECAP3_SHIFT)) & MFT_COMBINE_DECAP3_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Dual Edge Capture Mode Enable For n = 6 + * + * This function gets the current Dual Edge Capture Mode Enable For n = 6. + * Enables the Dual Edge Capture mode in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Dual Edge Capture Mode Enable For n = 6 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDecapEn3(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DECAPEN3_MASK) >> MFT_COMBINE_DECAPEN3_SHIFT); +} + +/*! \brief Sets the Dual Edge Capture Mode Enable For n = 6 + * + * This function sets the Dual Edge Capture Mode Enable For n = 6. + * Enables the Dual Edge Capture mode in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Dual Edge Capture Mode Enable For n = 6 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDecapEn3(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DECAPEN3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DECAPEN3_SHIFT)) & MFT_COMBINE_DECAPEN3_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Complement Of Channel (n) for n = 6 + * + * This function gets the current Complement Of Channel (n) for n = 6. + * In Complementary mode the channel (n+1) output is the inverse of the channel (n) output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Complement Of Channel (n) for n = 6 + * - 0b : If the channels (n) and (n+1) are in Combine Mode or Modified Combine PWM Mode, + * the channel (n+1) output is the same as the channel (n) output. + * If the channel (n+1) is in Output Compare Mode, EPWM or CPWM, + * the channel (n+1) output is independent from channel (n) output. + * - 1b : The channel (n+1) output is the complement of the channel (n) output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineComp3(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_COMP3_MASK) >> MFT_COMBINE_COMP3_SHIFT); +} + +/*! \brief Sets the Complement Of Channel (n) for n = 6 + * + * This function sets the Complement Of Channel (n) for n = 6. + * In Complementary mode the channel (n+1) output is the inverse of the channel (n) output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Complement Of Channel (n) for n = 6 + * - 0b : If the channels (n) and (n+1) are in Combine Mode or Modified Combine PWM Mode, + * the channel (n+1) output is the same as the channel (n) output. + * If the channel (n+1) is in Output Compare Mode, EPWM or CPWM, + * the channel (n+1) output is independent from channel (n) output. + * - 1b : The channel (n+1) output is the complement of the channel (n) output. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineComp3(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_COMP3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_COMP3_SHIFT)) & MFT_COMBINE_COMP3_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Combine Channels For n = 6 + * + * This function gets the current Combine Channels For n = 6. + * Used on the selection of the combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Combine Channels For n = 6 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineCombine3(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_COMBINE3_MASK) >> MFT_COMBINE_COMBINE3_SHIFT); +} + +/*! \brief Sets the Combine Channels For n = 6 + * + * This function sets the Combine Channels For n = 6. + * Used on the selection of the combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Combine Channels For n = 6 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineCombine3(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_COMBINE3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_COMBINE3_SHIFT)) & MFT_COMBINE_COMBINE3_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Modified Combine Mode For n = 4 + * + * This function gets the current Modified Combine Mode For n = 4. + * Used on the selection of the modified combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Modified Combine Mode For n = 4 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineMCombine2(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_MCOMBINE2_MASK) >> MFT_COMBINE_MCOMBINE2_SHIFT); +} + +/*! \brief Sets the Modified Combine Mode For n = 4 + * + * This function sets the Modified Combine Mode For n = 4. + * Used on the selection of the modified combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Modified Combine Mode For n = 4 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineMCombine2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_MCOMBINE2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_MCOMBINE2_SHIFT)) & MFT_COMBINE_MCOMBINE2_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Fault Control Enable For n = 4 + * + * This function gets the current Fault Control Enable For n = 4. + * Enables the fault control in channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Control Enable For n = 4 + * - 0b : The fault control in this pair of channels is disabled. + * - 1b : The fault control in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineFaultEn2(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_FAULTEN2_MASK) >> MFT_COMBINE_FAULTEN2_SHIFT); +} + +/*! \brief Sets the Fault Control Enable For n = 4 + * + * This function sets the Fault Control Enable For n = 4. + * Enables the fault control in channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Control Enable For n = 4 + * - 0b : The fault control in this pair of channels is disabled. + * - 1b : The fault control in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineFaultEn2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_FAULTEN2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_FAULTEN2_SHIFT)) & MFT_COMBINE_FAULTEN2_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Synchronization Enable For n = 4 + * + * This function gets the current Synchronization Enable For n = 4. + * Enables PWM synchronization of registers C(n)V and C(n+1)V. + * + * \param[in] obj : pointer to MFT register instance + * \return Synchronization Enable For n = 4 + * - 0b : The PWM synchronization in this pair of channels is disabled. + * - 1b : The PWM synchronization in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineSyncEn2(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_SYNCEN2_MASK) >> MFT_COMBINE_SYNCEN2_SHIFT); +} + +/*! \brief Sets the Synchronization Enable For n = 4 + * + * This function sets the Synchronization Enable For n = 4. + * Enables PWM synchronization of registers C(n)V and C(n+1)V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Synchronization Enable For n = 4 + * - 0b : The PWM synchronization in this pair of channels is disabled. + * - 1b : The PWM synchronization in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineSyncEn2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_SYNCEN2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_SYNCEN2_SHIFT)) & MFT_COMBINE_SYNCEN2_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Deadtime Enable For n = 4 + * + * This function gets the current Deadtime Enable For n = 4. + * Enables the deadtime insertion in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Deadtime Enable For n = 4 + * - 0b : The deadtime insertion in this pair of channels is disabled. + * - 1b : The deadtime insertion in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDtEn2(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DTEN2_MASK) >> MFT_COMBINE_DTEN2_SHIFT); +} + +/*! \brief Sets the Deadtime Enable For n = 4 + * + * This function sets the Deadtime Enable For n = 4. + * Enables the deadtime insertion in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Deadtime Enable For n = 4 + * - 0b : The deadtime insertion in this pair of channels is disabled. + * - 1b : The deadtime insertion in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDtEn2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DTEN2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DTEN2_SHIFT)) & MFT_COMBINE_DTEN2_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Dual Edge Capture Mode Captures For n = 4 + * + * This function gets the current Dual Edge Capture Mode Captures For n = 4. + * Enables the capture of the MFT counter value according to the channel (n) input event and the + * configuration of the dual edge capture bits. + * This field applies only when DECAPEN = 1. + * DECAP bit is cleared automatically by hardware if dual edge capture ¨C one-shot mode is selected and + * when the capture of channel (n+1) event is made. + * + * \param[in] obj : pointer to MFT register instance + * \return Dual Edge Capture Mode Captures For n = 4 + * - 0b : The dual edge captures are inactive. + * - 1b : The dual edge captures are active. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDecap2(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DECAP2_MASK) >> MFT_COMBINE_DECAP2_SHIFT); +} + +/*! \brief Sets the Dual Edge Capture Mode Captures For n = 4 + * + * This function sets the Dual Edge Capture Mode Captures For n = 4. + * Enables the capture of the MFT counter value according to the channel (n) input event and the + * configuration of the dual edge capture bits. + * This field applies only when DECAPEN = 1. + * DECAP bit is cleared automatically by hardware if dual edge capture ¨C one-shot mode is selected and + * when the capture of channel (n+1) event is made. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Dual Edge Capture Mode Captures For n = 4 + * - 0b : The dual edge captures are inactive. + * - 1b : The dual edge captures are active. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDecap2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DECAP2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DECAP2_SHIFT)) & MFT_COMBINE_DECAP2_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Dual Edge Capture Mode Enable For n = 4 + * + * This function gets the current Dual Edge Capture Mode Enable For n = 4. + * Enables the Dual Edge Capture mode in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Dual Edge Capture Mode Enable For n = 4 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDecapEn2(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DECAPEN2_MASK) >> MFT_COMBINE_DECAPEN2_SHIFT); +} + +/*! \brief Sets the Dual Edge Capture Mode Enable For n = 4 + * + * This function sets the Dual Edge Capture Mode Enable For n = 4. + * Enables the Dual Edge Capture mode in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Dual Edge Capture Mode Enable For n = 4 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDecapEn2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DECAPEN2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DECAPEN2_SHIFT)) & MFT_COMBINE_DECAPEN2_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Complement Of Channel (n) for n = 4 + * + * This function gets the current Complement Of Channel (n) for n = 4. + * In Complementary mode the channel (n+1) output is the inverse of the channel (n) output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Complement Of Channel (n) for n = 4 + * - 0b : If the channels (n) and (n+1) are in Combine Mode or Modified Combine PWM Mode, + * the channel (n+1) output is the same as the channel (n) output. + * If the channel (n+1) is in Output Compare Mode, EPWM or CPWM, + * the channel (n+1) output is independent from channel (n) output. + * - 1b : The channel (n+1) output is the complement of the channel (n) output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineComp2(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_COMP2_MASK) >> MFT_COMBINE_COMP2_SHIFT); +} + +/*! \brief Sets the Complement Of Channel (n) for n = 4 + * + * This function sets the Complement Of Channel (n) for n = 4. + * In Complementary mode the channel (n+1) output is the inverse of the channel (n) output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Complement Of Channel (n) for n = 4 + * - 0b : If the channels (n) and (n+1) are in Combine Mode or Modified Combine PWM Mode, + * the channel (n+1) output is the same as the channel (n) output. + * If the channel (n+1) is in Output Compare Mode, EPWM or CPWM, + * the channel (n+1) output is independent from channel (n) output. + * - 1b : The channel (n+1) output is the complement of the channel (n) output. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineComp2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_COMP2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_COMP2_SHIFT)) & MFT_COMBINE_COMP2_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Combine Channels For n = 4 + * + * This function gets the current Combine Channels For n = 4. + * Used on the selection of the combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Combine Channels For n = 4 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineCombine2(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_COMBINE2_MASK) >> MFT_COMBINE_COMBINE2_SHIFT); +} + +/*! \brief Sets the Combine Channels For n = 4 + * + * This function sets the Combine Channels For n = 4. + * Used on the selection of the combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Combine Channels For n = 4 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineCombine2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_COMBINE2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_COMBINE2_SHIFT)) & MFT_COMBINE_COMBINE2_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Modified Combine Mode For n = 2 + * + * This function gets the current Modified Combine Mode For n = 2. + * Used on the selection of the modified combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Modified Combine Mode For n = 2 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineMCombine1(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_MCOMBINE1_MASK) >> MFT_COMBINE_MCOMBINE1_SHIFT); +} + +/*! \brief Sets the Modified Combine Mode For n = 2 + * + * This function sets the Modified Combine Mode For n = 2. + * Used on the selection of the modified combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Modified Combine Mode For n = 2 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineMCombine1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_MCOMBINE1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_MCOMBINE1_SHIFT)) & MFT_COMBINE_MCOMBINE1_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Fault Control Enable For n = 2 + * + * This function gets the current Fault Control Enable For n = 2. + * Enables the fault control in channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Control Enable For n = 2 + * - 0b : The fault control in this pair of channels is disabled. + * - 1b : The fault control in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineFaultEn1(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_FAULTEN1_MASK) >> MFT_COMBINE_FAULTEN1_SHIFT); +} + +/*! \brief Sets the Fault Control Enable For n = 2 + * + * This function sets the Fault Control Enable For n = 2. + * Enables the fault control in channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Control Enable For n = 2 + * - 0b : The fault control in this pair of channels is disabled. + * - 1b : The fault control in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineFaultEn1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_FAULTEN1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_FAULTEN1_SHIFT)) & MFT_COMBINE_FAULTEN1_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Synchronization Enable For n = 2 + * + * This function gets the current Synchronization Enable For n = 2. + * Enables PWM synchronization of registers C(n)V and C(n+1)V. + * + * \param[in] obj : pointer to MFT register instance + * \return Synchronization Enable For n = 2 + * - 0b : The PWM synchronization in this pair of channels is disabled. + * - 1b : The PWM synchronization in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineSyncEn1(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_SYNCEN1_MASK) >> MFT_COMBINE_SYNCEN1_SHIFT); +} + +/*! \brief Sets the Synchronization Enable For n = 2 + * + * This function sets the Synchronization Enable For n = 2. + * Enables PWM synchronization of registers C(n)V and C(n+1)V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Synchronization Enable For n = 2 + * - 0b : The PWM synchronization in this pair of channels is disabled. + * - 1b : The PWM synchronization in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineSyncEn1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_SYNCEN1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_SYNCEN1_SHIFT)) & MFT_COMBINE_SYNCEN1_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Deadtime Enable For n = 2 + * + * This function gets the current Deadtime Enable For n = 2. + * Enables the deadtime insertion in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Deadtime Enable For n = 2 + * - 0b : The deadtime insertion in this pair of channels is disabled. + * - 1b : The deadtime insertion in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDtEn1(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DTEN1_MASK) >> MFT_COMBINE_DTEN1_SHIFT); +} + +/*! \brief Sets the Deadtime Enable For n = 2 + * + * This function sets the Deadtime Enable For n = 2. + * Enables the deadtime insertion in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Deadtime Enable For n = 2 + * - 0b : The deadtime insertion in this pair of channels is disabled. + * - 1b : The deadtime insertion in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDtEn1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DTEN1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DTEN1_SHIFT)) & MFT_COMBINE_DTEN1_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Dual Edge Capture Mode Captures For n = 2 + * + * This function gets the current Dual Edge Capture Mode Captures For n = 2. + * Enables the capture of the MFT counter value according to the channel (n) input event and the + * configuration of the dual edge capture bits. + * This field applies only when DECAPEN = 1. + * DECAP bit is cleared automatically by hardware if dual edge capture ¨C one-shot mode is selected and + * when the capture of channel (n+1) event is made. + * + * \param[in] obj : pointer to MFT register instance + * \return Dual Edge Capture Mode Captures For n = 2 + * - 0b : The dual edge captures are inactive. + * - 1b : The dual edge captures are active. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDecap1(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DECAP1_MASK) >> MFT_COMBINE_DECAP1_SHIFT); +} + +/*! \brief Sets the Dual Edge Capture Mode Captures For n = 2 + * + * This function sets the Dual Edge Capture Mode Captures For n = 2. + * Enables the capture of the MFT counter value according to the channel (n) input event and the + * configuration of the dual edge capture bits. + * This field applies only when DECAPEN = 1. + * DECAP bit is cleared automatically by hardware if dual edge capture ¨C one-shot mode is selected and + * when the capture of channel (n+1) event is made. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Dual Edge Capture Mode Captures For n = 2 + * - 0b : The dual edge captures are inactive. + * - 1b : The dual edge captures are active. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDecap1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DECAP1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DECAP1_SHIFT)) & MFT_COMBINE_DECAP1_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Dual Edge Capture Mode Enable For n = 2 + * + * This function gets the current Dual Edge Capture Mode Enable For n = 2. + * Enables the Dual Edge Capture mode in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Dual Edge Capture Mode Enable For n = 2 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDecapEn1(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DECAPEN1_MASK) >> MFT_COMBINE_DECAPEN1_SHIFT); +} + +/*! \brief Sets the Dual Edge Capture Mode Enable For n = 2 + * + * This function sets the Dual Edge Capture Mode Enable For n = 2. + * Enables the Dual Edge Capture mode in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Dual Edge Capture Mode Enable For n = 2 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDecapEn1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DECAPEN1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DECAPEN1_SHIFT)) & MFT_COMBINE_DECAPEN1_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Complement Of Channel (n) for n = 2 + * + * This function gets the current Complement Of Channel (n) for n = 2. + * In Complementary mode the channel (n+1) output is the inverse of the channel (n) output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Complement Of Channel (n) for n = 2 + * - 0b : If the channels (n) and (n+1) are in Combine Mode or Modified Combine PWM Mode, + * the channel (n+1) output is the same as the channel (n) output. + * If the channel (n+1) is in Output Compare Mode, EPWM or CPWM, + * the channel (n+1) output is independent from channel (n) output. + * - 1b : The channel (n+1) output is the complement of the channel (n) output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineComp1(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_COMP1_MASK) >> MFT_COMBINE_COMP1_SHIFT); +} + +/*! \brief Sets the Complement Of Channel (n) for n = 2 + * + * This function sets the Complement Of Channel (n) for n = 2. + * In Complementary mode the channel (n+1) output is the inverse of the channel (n) output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Complement Of Channel (n) for n = 2 + * - 0b : If the channels (n) and (n+1) are in Combine Mode or Modified Combine PWM Mode, + * the channel (n+1) output is the same as the channel (n) output. + * If the channel (n+1) is in Output Compare Mode, EPWM or CPWM, + * the channel (n+1) output is independent from channel (n) output. + * - 1b : The channel (n+1) output is the complement of the channel (n) output. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineComp1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_COMP1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_COMP1_SHIFT)) & MFT_COMBINE_COMP1_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Combine Channels For n = 2 + * + * This function gets the current Combine Channels For n = 2. + * Used on the selection of the combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Combine Channels For n = 2 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineCombine1(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_COMBINE1_MASK) >> MFT_COMBINE_COMBINE1_SHIFT); +} + +/*! \brief Sets the Combine Channels For n = 2 + * + * This function sets the Combine Channels For n = 2. + * Used on the selection of the combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Combine Channels For n = 2 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineCombine1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_COMBINE1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_COMBINE1_SHIFT)) & MFT_COMBINE_COMBINE1_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Modified Combine Mode For n = 0 + * + * This function gets the current Modified Combine Mode For n = 0. + * Used on the selection of the modified combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Modified Combine Mode For n = 0 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineMCombine0(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_MCOMBINE0_MASK) >> MFT_COMBINE_MCOMBINE0_SHIFT); +} + +/*! \brief Sets the Modified Combine Mode For n = 0 + * + * This function sets the Modified Combine Mode For n = 0. + * Used on the selection of the modified combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Modified Combine Mode For n = 0 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineMCombine0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_MCOMBINE0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_MCOMBINE0_SHIFT)) & MFT_COMBINE_MCOMBINE0_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Fault Control Enable For n = 0 + * + * This function gets the current Fault Control Enable For n = 0. + * Enables the fault control in channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Control Enable For n = 0 + * - 0b : The fault control in this pair of channels is disabled. + * - 1b : The fault control in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineFaultEn0(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_FAULTEN0_MASK) >> MFT_COMBINE_FAULTEN0_SHIFT); +} + +/*! \brief Sets the Fault Control Enable For n = 0 + * + * This function sets the Fault Control Enable For n = 0. + * Enables the fault control in channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Control Enable For n = 0 + * - 0b : The fault control in this pair of channels is disabled. + * - 1b : The fault control in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineFaultEn0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_FAULTEN0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_FAULTEN0_SHIFT)) & MFT_COMBINE_FAULTEN0_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Synchronization Enable For n = 0 + * + * This function gets the current Synchronization Enable For n = 0. + * Enables PWM synchronization of registers C(n)V and C(n+1)V. + * + * \param[in] obj : pointer to MFT register instance + * \return Synchronization Enable For n = 0 + * - 0b : The PWM synchronization in this pair of channels is disabled. + * - 1b : The PWM synchronization in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineSyncEn0(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_SYNCEN0_MASK) >> MFT_COMBINE_SYNCEN0_SHIFT); +} + +/*! \brief Sets the Synchronization Enable For n = 0 + * + * This function sets the Synchronization Enable For n = 0. + * Enables PWM synchronization of registers C(n)V and C(n+1)V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Synchronization Enable For n = 0 + * - 0b : The PWM synchronization in this pair of channels is disabled. + * - 1b : The PWM synchronization in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineSyncEn0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_SYNCEN0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_SYNCEN0_SHIFT)) & MFT_COMBINE_SYNCEN0_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Deadtime Enable For n = 0 + * + * This function gets the current Deadtime Enable For n = 0. + * Enables the deadtime insertion in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Deadtime Enable For n = 0 + * - 0b : The deadtime insertion in this pair of channels is disabled. + * - 1b : The deadtime insertion in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDtEn0(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DTEN0_MASK) >> MFT_COMBINE_DTEN0_SHIFT); +} + +/*! \brief Sets the Deadtime Enable For n = 0 + * + * This function sets the Deadtime Enable For n = 0. + * Enables the deadtime insertion in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Deadtime Enable For n = 0 + * - 0b : The deadtime insertion in this pair of channels is disabled. + * - 1b : The deadtime insertion in this pair of channels is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDtEn0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DTEN0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DTEN0_SHIFT)) & MFT_COMBINE_DTEN0_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Dual Edge Capture Mode Captures For n = 0 + * + * This function gets the current Dual Edge Capture Mode Captures For n = 0. + * Enables the capture of the MFT counter value according to the channel (n) input event and the + * configuration of the dual edge capture bits. + * This field applies only when DECAPEN = 1. + * DECAP bit is cleared automatically by hardware if dual edge capture ¨C one-shot mode is selected and + * when the capture of channel (n+1) event is made. + * + * \param[in] obj : pointer to MFT register instance + * \return Dual Edge Capture Mode Captures For n = 0 + * - 0b : The dual edge captures are inactive. + * - 1b : The dual edge captures are active. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDecap0(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DECAP0_MASK) >> MFT_COMBINE_DECAP0_SHIFT); +} + +/*! \brief Sets the Dual Edge Capture Mode Captures For n = 0 + * + * This function sets the Dual Edge Capture Mode Captures For n = 0. + * Enables the capture of the MFT counter value according to the channel (n) input event and the + * configuration of the dual edge capture bits. + * This field applies only when DECAPEN = 1. + * DECAP bit is cleared automatically by hardware if dual edge capture ¨C one-shot mode is selected and + * when the capture of channel (n+1) event is made. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Dual Edge Capture Mode Captures For n = 0 + * - 0b : The dual edge captures are inactive. + * - 1b : The dual edge captures are active. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDecap0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DECAP0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DECAP0_SHIFT)) & MFT_COMBINE_DECAP0_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Dual Edge Capture Mode Enable For n = 0 + * + * This function gets the current Dual Edge Capture Mode Enable For n = 0. + * Enables the Dual Edge Capture mode in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Dual Edge Capture Mode Enable For n = 0 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineDecapEn0(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_DECAPEN0_MASK) >> MFT_COMBINE_DECAPEN0_SHIFT); +} + +/*! \brief Sets the Dual Edge Capture Mode Enable For n = 0 + * + * This function sets the Dual Edge Capture Mode Enable For n = 0. + * Enables the Dual Edge Capture mode in the channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Dual Edge Capture Mode Enable For n = 0 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineDecapEn0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_DECAPEN0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_DECAPEN0_SHIFT)) & MFT_COMBINE_DECAPEN0_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Complement Of Channel (n) for n = 0 + * + * This function gets the current Complement Of Channel (n) for n = 0. + * In Complementary mode the channel (n+1) output is the inverse of the channel (n) output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Complement Of Channel (n) for n = 0 + * - 0b : If the channels (n) and (n+1) are in Combine Mode or Modified Combine PWM Mode, + * the channel (n+1) output is the same as the channel (n) output. + * If the channel (n+1) is in Output Compare Mode, EPWM or CPWM, + * the channel (n+1) output is independent from channel (n) output. + * - 1b : The channel (n+1) output is the complement of the channel (n) output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineComp0(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_COMP0_MASK) >> MFT_COMBINE_COMP0_SHIFT); +} + +/*! \brief Sets the Complement Of Channel (n) for n = 0 + * + * This function sets the Complement Of Channel (n) for n = 0. + * In Complementary mode the channel (n+1) output is the inverse of the channel (n) output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Complement Of Channel (n) for n = 0 + * - 0b : If the channels (n) and (n+1) are in Combine Mode or Modified Combine PWM Mode, + * the channel (n+1) output is the same as the channel (n) output. + * If the channel (n+1) is in Output Compare Mode, EPWM or CPWM, + * the channel (n+1) output is independent from channel (n) output. + * - 1b : The channel (n+1) output is the complement of the channel (n) output. + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineComp0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_COMP0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_COMP0_SHIFT)) & MFT_COMBINE_COMP0_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Combine Channels For n = 0 + * + * This function gets the current Combine Channels For n = 0. + * Used on the selection of the combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Combine Channels For n = 0 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCombineCombine0(const MftRegType *obj) +{ + return ((obj->COMBINE & MFT_COMBINE_COMBINE0_MASK) >> MFT_COMBINE_COMBINE0_SHIFT); +} + +/*! \brief Sets the Combine Channels For n = 0 + * + * This function sets the Combine Channels For n = 0. + * Used on the selection of the combine mode for channels (n) and (n+1). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Combine Channels For n = 0 + */ +__attribute__((always_inline)) static inline void MftReg_SetCombineCombine0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->COMBINE; + + tmp &= ~MFT_COMBINE_COMBINE0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_COMBINE_COMBINE0_SHIFT)) & MFT_COMBINE_COMBINE0_MASK); + obj->COMBINE = tmp; +} + +/*! \brief Gets the Extended Deadtime Value + * + * This function gets the current Extended Deadtime Value. + * This field is a bit extension of the DTVAL field. It defines the 4 most significant bits of the deadtime value. + * The maximum deadtime value is extended to 1023 using the concatenation {DTVALEX, DTVAL}. + * Deadtime insert value = (DTPS * {DTVALEX, DTVAL}). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \note If full compatibility is needed with previous software versions, write 0 to DTVALEX bits + * + * \param[in] obj : pointer to MFT register instance + * \return Extended Deadtime Value + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetDeadTimeDtValEx(const MftRegType *obj) +{ + return ((obj->DEADTIME & MFT_DEADTIME_DTVALEX_MASK) >> MFT_DEADTIME_DTVALEX_SHIFT); +} + +/*! \brief Sets the Extended Deadtime Value + * + * This function sets the Extended Deadtime Value. + * This field is a bit extension of the DTVAL field. It defines the 4 most significant bits of the deadtime value. + * The maximum deadtime value is extended to 1023 using the concatenation {DTVALEX, DTVAL}. + * Deadtime insert value = (DTPS * {DTVALEX, DTVAL}). + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \note If full compatibility is needed with previous software versions, write 0 to DTVALEX bits + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Extended Deadtime Value + */ +__attribute__((always_inline)) static inline void MftReg_SetDeadTimeDtValEx(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DEADTIME; + + tmp &= ~MFT_DEADTIME_DTVALEX_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_DEADTIME_DTVALEX_SHIFT)) & MFT_DEADTIME_DTVALEX_MASK); + obj->DEADTIME = tmp; +} + +/*! \brief Gets the Deadtime Prescaler Value + * + * This function gets the current Deadtime Prescaler Value. + * Selects the division factor of the MFT input clock. This prescaled clock is used by the deadtime counter. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Deadtime Prescaler Value + * - 0xb : Divide the MFT input clock by 1. + * - 10b : Divide the MFT input clock by 4. + * - 11b : Divide the MFT input clock by 16. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetDeadTimeDtPs(const MftRegType *obj) +{ + return ((obj->DEADTIME & MFT_DEADTIME_DTPS_MASK) >> MFT_DEADTIME_DTPS_SHIFT); +} + +/*! \brief Sets the Deadtime Prescaler Value + * + * This function sets the Deadtime Prescaler Value. + * Selects the division factor of the MFT input clock. This prescaled clock is used by the deadtime counter. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Deadtime Prescaler Value + * - 0xb : Divide the MFT input clock by 1. + * - 10b : Divide the MFT input clock by 4. + * - 11b : Divide the MFT input clock by 16. + */ +__attribute__((always_inline)) static inline void MftReg_SetDeadTimeDtPs(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DEADTIME; + + tmp &= ~MFT_DEADTIME_DTPS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_DEADTIME_DTPS_SHIFT)) & MFT_DEADTIME_DTPS_MASK); + obj->DEADTIME = tmp; +} + +/*! \brief Gets the Deadtime Value + * + * This function gets the current Deadtime Value. + * Selects the deadtime value. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Deadtime Value + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetDeadTimeDtVal(const MftRegType *obj) +{ + return ((obj->DEADTIME & MFT_DEADTIME_DTVAL_MASK) >> MFT_DEADTIME_DTVAL_SHIFT); +} + +/*! \brief Sets the Deadtime Value + * + * This function sets the Deadtime Value. + * Selects the deadtime value. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Deadtime Value + */ +__attribute__((always_inline)) static inline void MftReg_SetDeadTimeDtVal(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DEADTIME; + + tmp &= ~MFT_DEADTIME_DTVAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_DEADTIME_DTVAL_SHIFT)) & MFT_DEADTIME_DTVAL_MASK); + obj->DEADTIME = tmp; +} + +/*! \brief Gets the Channel 7 External Trigger Enable + * + * This function gets the current Channel 7 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 7 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetExtTrigCh7Trig(const MftRegType *obj) +{ + return ((obj->EXTTRIG & MFT_EXTTRIG_CH7TRIG_MASK) >> MFT_EXTTRIG_CH7TRIG_SHIFT); +} + +/*! \brief Sets the Channel 7 External Trigger Enable + * + * This function sets the Channel 7 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 7 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetExtTrigCh7Trig(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTTRIG; + + tmp &= ~MFT_EXTTRIG_CH7TRIG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_EXTTRIG_CH7TRIG_SHIFT)) & MFT_EXTTRIG_CH7TRIG_MASK); + obj->EXTTRIG = tmp; +} + +/*! \brief Gets the Channel 6 External Trigger Enable + * + * This function gets the current Channel 6 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 6 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetExtTrigCh6Trig(const MftRegType *obj) +{ + return ((obj->EXTTRIG & MFT_EXTTRIG_CH6TRIG_MASK) >> MFT_EXTTRIG_CH6TRIG_SHIFT); +} + +/*! \brief Sets the Channel 6 External Trigger Enable + * + * This function sets the Channel 6 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 6 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetExtTrigCh6Trig(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTTRIG; + + tmp &= ~MFT_EXTTRIG_CH6TRIG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_EXTTRIG_CH6TRIG_SHIFT)) & MFT_EXTTRIG_CH6TRIG_MASK); + obj->EXTTRIG = tmp; +} + +/*! \brief Gets the Channel Trigger Flag + * + * This function gets the current Channel Trigger Flag. + * Set by hardware when a channel trigger is generated. + * Clear TRIGF by reading EXTTRIG while TRIGF is set and then writing a 0 to TRIGF. + * Writing a 1 to TRIGF has no effect. + * If another channel trigger is generated before the clearing sequence is completed, + * the sequence is reset so TRIGF remains set after the clear sequence is completed for the earlier TRIGF. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel Trigger Flag + * - 0b : No channel trigger was generated. + * - 1b : A channel trigger was generated. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetExtTrigTrigF(const MftRegType *obj) +{ + return ((obj->EXTTRIG & MFT_EXTTRIG_TRIGF_MASK) >> MFT_EXTTRIG_TRIGF_SHIFT); +} + +/*! \brief Sets the Channel Trigger Flag + * + * This function sets the Channel Trigger Flag. + * Set by hardware when a channel trigger is generated. + * Clear TRIGF by reading EXTTRIG while TRIGF is set and then writing a 0 to TRIGF. + * Writing a 1 to TRIGF has no effect. + * If another channel trigger is generated before the clearing sequence is completed, + * the sequence is reset so TRIGF remains set after the clear sequence is completed for the earlier TRIGF. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel Trigger Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetExtTrigTrigF(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->EXTTRIG; + + tmp &= ~MFT_EXTTRIG_TRIGF_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_EXTTRIG_TRIGF_SHIFT)) & MFT_EXTTRIG_TRIGF_MASK); + obj->EXTTRIG = tmp; +} + +/*! \brief Gets the Initialization Trigger Enable + * + * This function gets the current Initialization Trigger Enable. + * Enables the generation of the trigger when the MFT counter is equal to the CNTIN register. + * + * \param[in] obj : pointer to MFT register instance + * \return Initialization Trigger Enable + * - 0b : The generation of initialization trigger is disabled. + * - 1b : The generation of initialization trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetExtTrigInitTrigEn(const MftRegType *obj) +{ + return ((obj->EXTTRIG & MFT_EXTTRIG_INITTRIGEN_MASK) >> MFT_EXTTRIG_INITTRIGEN_SHIFT); +} + +/*! \brief Sets the Initialization Trigger Enable + * + * This function sets the Initialization Trigger Enable. + * Enables the generation of the trigger when the MFT counter is equal to the CNTIN register. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Initialization Trigger Enable + * - 0b : The generation of initialization trigger is disabled. + * - 1b : The generation of initialization trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetExtTrigInitTrigEn(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTTRIG; + + tmp &= ~MFT_EXTTRIG_INITTRIGEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_EXTTRIG_INITTRIGEN_SHIFT)) & MFT_EXTTRIG_INITTRIGEN_MASK); + obj->EXTTRIG = tmp; +} + +/*! \brief Gets the Channel 1 External Trigger Enable + * + * This function gets the current Channel 1 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 1 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetExtTrigCh1Trig(const MftRegType *obj) +{ + return ((obj->EXTTRIG & MFT_EXTTRIG_CH1TRIG_MASK) >> MFT_EXTTRIG_CH1TRIG_SHIFT); +} + +/*! \brief Sets the Channel 1 External Trigger Enable + * + * This function sets the Channel 1 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 1 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetExtTrigCh1Trig(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTTRIG; + + tmp &= ~MFT_EXTTRIG_CH1TRIG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_EXTTRIG_CH1TRIG_SHIFT)) & MFT_EXTTRIG_CH1TRIG_MASK); + obj->EXTTRIG = tmp; +} + +/*! \brief Gets the Channel 0 External Trigger Enable + * + * This function gets the current Channel 0 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 0 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetExtTrigCh0Trig(const MftRegType *obj) +{ + return ((obj->EXTTRIG & MFT_EXTTRIG_CH0TRIG_MASK) >> MFT_EXTTRIG_CH0TRIG_SHIFT); +} + +/*! \brief Sets the Channel 0 External Trigger Enable + * + * This function sets the Channel 0 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 0 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetExtTrigCh0Trig(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTTRIG; + + tmp &= ~MFT_EXTTRIG_CH0TRIG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_EXTTRIG_CH0TRIG_SHIFT)) & MFT_EXTTRIG_CH0TRIG_MASK); + obj->EXTTRIG = tmp; +} + +/*! \brief Gets the Channel 5 External Trigger Enable + * + * This function gets the current Channel 5 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 5 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetExtTrigCh5Trig(const MftRegType *obj) +{ + return ((obj->EXTTRIG & MFT_EXTTRIG_CH5TRIG_MASK) >> MFT_EXTTRIG_CH5TRIG_SHIFT); +} + +/*! \brief Sets the Channel 5 External Trigger Enable + * + * This function sets the Channel 5 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 5 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetExtTrigCh5Trig(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTTRIG; + + tmp &= ~MFT_EXTTRIG_CH5TRIG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_EXTTRIG_CH5TRIG_SHIFT)) & MFT_EXTTRIG_CH5TRIG_MASK); + obj->EXTTRIG = tmp; +} + +/*! \brief Gets the Channel 4 External Trigger Enable + * + * This function gets the current Channel 4 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 4 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetExtTrigCh4Trig(const MftRegType *obj) +{ + return ((obj->EXTTRIG & MFT_EXTTRIG_CH4TRIG_MASK) >> MFT_EXTTRIG_CH4TRIG_SHIFT); +} + +/*! \brief Sets the Channel 4 External Trigger Enable + * + * This function sets the Channel 4 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 4 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetExtTrigCh4Trig(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTTRIG; + + tmp &= ~MFT_EXTTRIG_CH4TRIG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_EXTTRIG_CH4TRIG_SHIFT)) & MFT_EXTTRIG_CH4TRIG_MASK); + obj->EXTTRIG = tmp; +} + +/*! \brief Gets the Channel 3 External Trigger Enable + * + * This function gets the current Channel 3 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 3 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetExtTrigCh3Trig(const MftRegType *obj) +{ + return ((obj->EXTTRIG & MFT_EXTTRIG_CH3TRIG_MASK) >> MFT_EXTTRIG_CH3TRIG_SHIFT); +} + +/*! \brief Sets the Channel 3 External Trigger Enable + * + * This function sets the Channel 3 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 3 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetExtTrigCh3Trig(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTTRIG; + + tmp &= ~MFT_EXTTRIG_CH3TRIG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_EXTTRIG_CH3TRIG_SHIFT)) & MFT_EXTTRIG_CH3TRIG_MASK); + obj->EXTTRIG = tmp; +} + +/*! \brief Gets the Channel 2 External Trigger Enable + * + * This function gets the current Channel 2 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 2 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetExtTrigCh2Trig(const MftRegType *obj) +{ + return ((obj->EXTTRIG & MFT_EXTTRIG_CH2TRIG_MASK) >> MFT_EXTTRIG_CH2TRIG_SHIFT); +} + +/*! \brief Sets the Channel 2 External Trigger Enable + * + * This function sets the Channel 2 External Trigger Enable. + * Enables the generation of the external trigger when MFT counter = C2V. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 2 External Trigger Enable + * - 0b : The generation of this external trigger is disabled. + * - 1b : The generation of this external trigger is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetExtTrigCh2Trig(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTTRIG; + + tmp &= ~MFT_EXTTRIG_CH2TRIG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_EXTTRIG_CH2TRIG_SHIFT)) & MFT_EXTTRIG_CH2TRIG_MASK); + obj->EXTTRIG = tmp; +} + +/*! \brief Gets the Channel 7 Polarity + * + * This function gets the current Channel 7 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 7 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPolPol7(const MftRegType *obj) +{ + return ((obj->POL & MFT_POL_POL7_MASK) >> MFT_POL_POL7_SHIFT); +} + +/*! \brief Sets the Channel 7 Polarity + * + * This function sets the Channel 7 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 7 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline void MftReg_SetPolPol7(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->POL; + + tmp &= ~MFT_POL_POL7_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_POL_POL7_SHIFT)) & MFT_POL_POL7_MASK); + obj->POL = tmp; +} + +/*! \brief Gets the Channel 6 Polarity + * + * This function gets the current Channel 6 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 6 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPolPol6(const MftRegType *obj) +{ + return ((obj->POL & MFT_POL_POL6_MASK) >> MFT_POL_POL6_SHIFT); +} + +/*! \brief Sets the Channel 6 Polarity + * + * This function sets the Channel 6 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 6 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline void MftReg_SetPolPol6(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->POL; + + tmp &= ~MFT_POL_POL6_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_POL_POL6_SHIFT)) & MFT_POL_POL6_MASK); + obj->POL = tmp; +} + +/*! \brief Gets the Channel 5 Polarity + * + * This function gets the current Channel 5 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 5 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPolPol5(const MftRegType *obj) +{ + return ((obj->POL & MFT_POL_POL5_MASK) >> MFT_POL_POL5_SHIFT); +} + +/*! \brief Sets the Channel 5 Polarity + * + * This function sets the Channel 5 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 5 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline void MftReg_SetPolPol5(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->POL; + + tmp &= ~MFT_POL_POL5_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_POL_POL5_SHIFT)) & MFT_POL_POL5_MASK); + obj->POL = tmp; +} + +/*! \brief Gets the Channel 4 Polarity + * + * This function gets the current Channel 4 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 4 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPolPol4(const MftRegType *obj) +{ + return ((obj->POL & MFT_POL_POL4_MASK) >> MFT_POL_POL4_SHIFT); +} + +/*! \brief Sets the Channel 4 Polarity + * + * This function sets the Channel 4 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 4 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline void MftReg_SetPolPol4(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->POL; + + tmp &= ~MFT_POL_POL4_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_POL_POL4_SHIFT)) & MFT_POL_POL4_MASK); + obj->POL = tmp; +} + +/*! \brief Gets the Channel 3 Polarity + * + * This function gets the current Channel 3 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 3 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPolPol3(const MftRegType *obj) +{ + return ((obj->POL & MFT_POL_POL3_MASK) >> MFT_POL_POL3_SHIFT); +} + +/*! \brief Sets the Channel 3 Polarity + * + * This function sets the Channel 3 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 3 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline void MftReg_SetPolPol3(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->POL; + + tmp &= ~MFT_POL_POL3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_POL_POL3_SHIFT)) & MFT_POL_POL3_MASK); + obj->POL = tmp; +} + +/*! \brief Gets the Channel 2 Polarity + * + * This function gets the current Channel 2 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 2 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPolPol2(const MftRegType *obj) +{ + return ((obj->POL & MFT_POL_POL2_MASK) >> MFT_POL_POL2_SHIFT); +} + +/*! \brief Sets the Channel 2 Polarity + * + * This function sets the Channel 2 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 2 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline void MftReg_SetPolPol2(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->POL; + + tmp &= ~MFT_POL_POL2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_POL_POL2_SHIFT)) & MFT_POL_POL2_MASK); + obj->POL = tmp; +} + +/*! \brief Gets the Channel 1 Polarity + * + * This function gets the current Channel 1 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 1 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPolPol1(const MftRegType *obj) +{ + return ((obj->POL & MFT_POL_POL1_MASK) >> MFT_POL_POL1_SHIFT); +} + +/*! \brief Sets the Channel 1 Polarity + * + * This function sets the Channel 1 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 1 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline void MftReg_SetPolPol1(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->POL; + + tmp &= ~MFT_POL_POL1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_POL_POL1_SHIFT)) & MFT_POL_POL1_MASK); + obj->POL = tmp; +} + +/*! \brief Gets the Channel 0 Polarity + * + * This function gets the current Channel 0 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 0 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPolPol0(const MftRegType *obj) +{ + return ((obj->POL & MFT_POL_POL0_MASK) >> MFT_POL_POL0_SHIFT); +} + +/*! \brief Sets the Channel 0 Polarity + * + * This function sets the Channel 0 Polarity. + * Defines the polarity of the channel output. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 0 Polarity + * - 0b : The channel polarity is active high. + * - 1b : The channel polarity is active low. + */ +__attribute__((always_inline)) static inline void MftReg_SetPolPol0(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->POL; + + tmp &= ~MFT_POL_POL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_POL_POL0_SHIFT)) & MFT_POL_POL0_MASK); + obj->POL = tmp; +} + +/*! \brief Gets the Fault Detection Flag + * + * This function gets the current Fault Detection Flag. + * Represents the logic OR of the FAULTF bit of each enabled fault input. + * Clear FAULTF by reading the FMS register while FAULTF is set and then writing a 0 to FAULTF + * while there is no existing fault condition at the enabled fault inputs. Writing a 1 to FAULTF has no effect. + * If another fault condition is detected in an enabled fault input before the clearing sequence is completed, + * the sequence is reset so FAULTF remains set after the clearing sequence is completed for the earlier fault condition. + * FAULTF is also cleared when FAULTF bit of each enabled fault input is cleared. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Detection Flag + * - 0b : No fault condition was detected. + * - 1b : A fault condition was detected. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFmsFaultF(const MftRegType *obj) +{ + return ((obj->FMS & MFT_FMS_FAULTF_MASK) >> MFT_FMS_FAULTF_SHIFT); +} + +/*! \brief Sets the Fault Detection Flag + * + * This function sets the Fault Detection Flag. + * Represents the logic OR of the FAULTF bit of each enabled fault input. + * Clear FAULTF by reading the FMS register while FAULTF is set and then writing a 0 to FAULTF + * while there is no existing fault condition at the enabled fault inputs. Writing a 1 to FAULTF has no effect. + * If another fault condition is detected in an enabled fault input before the clearing sequence is completed, + * the sequence is reset so FAULTF remains set after the clearing sequence is completed for the earlier fault condition. + * FAULTF is also cleared when FAULTF bit of each enabled fault input is cleared. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Detection Flag + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetFmsFaultF(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->FMS; + + tmp &= ~MFT_FMS_FAULTF_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FMS_FAULTF_SHIFT)) & MFT_FMS_FAULTF_MASK); + obj->FMS = tmp; +} + +/*! \brief Gets the Write Protection Enable + * + * This function gets the current Write Protection Enable. + * The WPEN bit is the negation of the WPDIS bit. WPEN is set when 1 is written to it. WPEN is cleared + * when WPEN bit is read as a 1 and then 1 is written to WPDIS. Writing 0 to WPEN has no effect. + * + * \param[in] obj : pointer to MFT register instance + * \return Write Protection Enable + * - 0b : Write protection is disabled. Write protected bits can be written. + * - 1b : Write protection is enabled. Write protected bits cannot be written. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFmsWpEn(const MftRegType *obj) +{ + return ((obj->FMS & MFT_FMS_WPEN_MASK) >> MFT_FMS_WPEN_SHIFT); +} + +/*! \brief Sets the Write Protection Enable + * + * This function sets the Write Protection Enable. + * The WPEN bit is the negation of the WPDIS bit. WPEN is set when 1 is written to it. WPEN is cleared + * when WPEN bit is read as a 1 and then 1 is written to WPDIS. Writing 0 to WPEN has no effect. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Write Protection Enable + * - 0b : Write protection is disabled. Write protected bits can be written. + * - 1b : Write protection is enabled. Write protected bits cannot be written. + */ +__attribute__((always_inline)) static inline void MftReg_SetFmsWpEn(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FMS; + + tmp &= ~MFT_FMS_WPEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FMS_WPEN_SHIFT)) & MFT_FMS_WPEN_MASK); + obj->FMS = tmp; +} + +/*! \brief Gets the Fault Inputs + * + * This function gets the current Fault Inputs. + * Represents the logic OR of the enabled fault inputs after their filter (if their filter is enabled) + * when fault control is enabled. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Inputs + * - 0b : The logic OR of the enabled fault inputs is 0. + * - 1b : The logic OR of the enabled fault inputs is 1. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFmsFaultIn(const MftRegType *obj) +{ + return ((obj->FMS & MFT_FMS_FAULTIN_MASK) >> MFT_FMS_FAULTIN_SHIFT); +} + +/*! \brief Gets the Fault Detection Flag 3 + * + * This function gets the current Fault Detection Flag 3. + * Set by hardware when fault control is enabled, + * the corresponding fault input is enabled and a fault condition is detected at the fault input. + * Clear FAULTF3 by reading the FMS register while FAULTF3 is set and then writing a 0 to FAULTF3 + * while there is no existing fault condition at the corresponding fault input. Writing a 1 to FAULTF3 has no effect. + * FAULTF3 bit is also cleared when FAULTF bit is cleared. + * If another fault condition is detected at the corresponding fault input before the clearing sequence is completed, + * the sequence is reset so FAULTF3 remains set after the clearing sequence is completed for the earlier fault condition + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Detection Flag 3 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFmsFaultF3(const MftRegType *obj) +{ + return ((obj->FMS & MFT_FMS_FAULTF3_MASK) >> MFT_FMS_FAULTF3_SHIFT); +} + +/*! \brief Sets the Fault Detection Flag 3 + * + * This function sets the Fault Detection Flag 3. + * Set by hardware when fault control is enabled, + * the corresponding fault input is enabled and a fault condition is detected at the fault input. + * Clear FAULTF3 by reading the FMS register while FAULTF3 is set and then writing a 0 to FAULTF3 + * while there is no existing fault condition at the corresponding fault input. Writing a 1 to FAULTF3 has no effect. + * FAULTF3 bit is also cleared when FAULTF bit is cleared. + * If another fault condition is detected at the corresponding fault input before the clearing sequence is completed, + * the sequence is reset so FAULTF3 remains set after the clearing sequence is completed for the earlier fault condition + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Detection Flag 3 + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetFmsFaultF3(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->FMS; + + tmp &= ~MFT_FMS_FAULTF3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FMS_FAULTF3_SHIFT)) & MFT_FMS_FAULTF3_MASK); + obj->FMS = tmp; +} + +/*! \brief Gets the Fault Detection Flag 2 + * + * This function gets the current Fault Detection Flag 2. + * Set by hardware when fault control is enabled, + * the corresponding fault input is enabled and a fault condition is detected at the fault input. + * Clear FAULTF2 by reading the FMS register while FAULTF2 is set and then writing a 0 to FAULTF2 + * while there is no existing fault condition at the corresponding fault input. Writing a 1 to FAULTF2 has no effect. + * FAULTF2 bit is also cleared when FAULTF bit is cleared. + * If another fault condition is detected at the corresponding fault input before the clearing sequence is completed, + * the sequence is reset so FAULTF2 remains set after the clearing sequence is completed for the earlier fault condition + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Detection Flag 2 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFmsFaultF2(const MftRegType *obj) +{ + return ((obj->FMS & MFT_FMS_FAULTF2_MASK) >> MFT_FMS_FAULTF2_SHIFT); +} + +/*! \brief Sets the Fault Detection Flag 2 + * + * This function sets the Fault Detection Flag 2. + * Set by hardware when fault control is enabled, + * the corresponding fault input is enabled and a fault condition is detected at the fault input. + * Clear FAULTF2 by reading the FMS register while FAULTF2 is set and then writing a 0 to FAULTF2 + * while there is no existing fault condition at the corresponding fault input. Writing a 1 to FAULTF2 has no effect. + * FAULTF2 bit is also cleared when FAULTF bit is cleared. + * If another fault condition is detected at the corresponding fault input before the clearing sequence is completed, + * the sequence is reset so FAULTF2 remains set after the clearing sequence is completed for the earlier fault condition + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Detection Flag 2 + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetFmsFaultF2(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->FMS; + + tmp &= ~MFT_FMS_FAULTF2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FMS_FAULTF2_SHIFT)) & MFT_FMS_FAULTF2_MASK); + obj->FMS = tmp; +} + +/*! \brief Gets the Fault Detection Flag 1 + * + * This function gets the current Fault Detection Flag 1. + * Set by hardware when fault control is enabled, + * the corresponding fault input is enabled and a fault condition is detected at the fault input. + * Clear FAULTF1 by reading the FMS register while FAULTF1 is set and then writing a 0 to FAULTF1 + * while there is no existing fault condition at the corresponding fault input. Writing a 1 to FAULTF1 has no effect. + * FAULTF1 bit is also cleared when FAULTF bit is cleared. + * If another fault condition is detected at the corresponding fault input before the clearing sequence is completed, + * the sequence is reset so FAULTF1 remains set after the clearing sequence is completed for the earlier fault condition + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Detection Flag 1 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFmsFaultF1(const MftRegType *obj) +{ + return ((obj->FMS & MFT_FMS_FAULTF1_MASK) >> MFT_FMS_FAULTF1_SHIFT); +} + +/*! \brief Sets the Fault Detection Flag 1 + * + * This function sets the Fault Detection Flag 1. + * Set by hardware when fault control is enabled, + * the corresponding fault input is enabled and a fault condition is detected at the fault input. + * Clear FAULTF1 by reading the FMS register while FAULTF1 is set and then writing a 0 to FAULTF1 + * while there is no existing fault condition at the corresponding fault input. Writing a 1 to FAULTF1 has no effect. + * FAULTF1 bit is also cleared when FAULTF bit is cleared. + * If another fault condition is detected at the corresponding fault input before the clearing sequence is completed, + * the sequence is reset so FAULTF1 remains set after the clearing sequence is completed for the earlier fault condition + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Detection Flag 1 + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetFmsFaultF1(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->FMS; + + tmp &= ~MFT_FMS_FAULTF1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FMS_FAULTF1_SHIFT)) & MFT_FMS_FAULTF1_MASK); + obj->FMS = tmp; +} + +/*! \brief Gets the Fault Detection Flag 0 + * + * This function gets the current Fault Detection Flag 0. + * Set by hardware when fault control is enabled, + * the corresponding fault input is enabled and a fault condition is detected at the fault input. + * Clear FAULTF0 by reading the FMS register while FAULTF0 is set and then writing a 0 to FAULTF0 + * while there is no existing fault condition at the corresponding fault input. Writing a 1 to FAULTF0 has no effect. + * FAULTF0 bit is also cleared when FAULTF bit is cleared. + * If another fault condition is detected at the corresponding fault input before the clearing sequence is completed, + * the sequence is reset so FAULTF0 remains set after the clearing sequence is completed for the earlier fault condition + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Detection Flag 0 + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFmsFaultF0(const MftRegType *obj) +{ + return ((obj->FMS & MFT_FMS_FAULTF0_MASK) >> MFT_FMS_FAULTF0_SHIFT); +} + +/*! \brief Sets the Fault Detection Flag 0 + * + * This function sets the Fault Detection Flag 0. + * Set by hardware when fault control is enabled, + * the corresponding fault input is enabled and a fault condition is detected at the fault input. + * Clear FAULTF0 by reading the FMS register while FAULTF0 is set and then writing a 0 to FAULTF0 + * while there is no existing fault condition at the corresponding fault input. Writing a 1 to FAULTF0 has no effect. + * FAULTF0 bit is also cleared when FAULTF bit is cleared. + * If another fault condition is detected at the corresponding fault input before the clearing sequence is completed, + * the sequence is reset so FAULTF0 remains set after the clearing sequence is completed for the earlier fault condition + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Detection Flag 0 + * - 0b : clear the flag + * - 1b : no effect + */ +__attribute__((always_inline)) static inline void MftReg_SetFmsFaultF0(MftRegType *obj, uint8_t value) +{ + /* Write 1 has no effect */ + if(value != 0) + { + return; + } + + uint32_t tmp = obj->FMS; + + tmp &= ~MFT_FMS_FAULTF0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FMS_FAULTF0_SHIFT)) & MFT_FMS_FAULTF0_MASK); + obj->FMS = tmp; +} + +/*! \brief Gets the Channel 3 Input Filter + * + * This function gets the current Channel 3 Input Filter. + * Selects the filter value for the channel input. + * The filter is disabled when the value is zero + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 3 Input Filter + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFilterCh3FVal(const MftRegType *obj) +{ + return ((obj->FILTER & MFT_FILTER_CH3FVAL_MASK) >> MFT_FILTER_CH3FVAL_SHIFT); +} + +/*! \brief Sets the Channel 3 Input Filter + * + * This function sets the Channel 3 Input Filter. + * Selects the filter value for the channel input. + * The filter is disabled when the value is zero + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 3 Input Filter + */ +__attribute__((always_inline)) static inline void MftReg_SetFilterCh3FVal(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FILTER; + + tmp &= ~MFT_FILTER_CH3FVAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FILTER_CH3FVAL_SHIFT)) & MFT_FILTER_CH3FVAL_MASK); + obj->FILTER = tmp; +} + +/*! \brief Gets the Channel 2 Input Filter + * + * This function gets the current Channel 2 Input Filter. + * Selects the filter value for the channel input. + * The filter is disabled when the value is zero + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 2 Input Filter + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFilterCh2FVal(const MftRegType *obj) +{ + return ((obj->FILTER & MFT_FILTER_CH2FVAL_MASK) >> MFT_FILTER_CH2FVAL_SHIFT); +} + +/*! \brief Sets the Channel 2 Input Filter + * + * This function sets the Channel 2 Input Filter. + * Selects the filter value for the channel input. + * The filter is disabled when the value is zero + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 2 Input Filter + */ +__attribute__((always_inline)) static inline void MftReg_SetFilterCh2FVal(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FILTER; + + tmp &= ~MFT_FILTER_CH2FVAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FILTER_CH2FVAL_SHIFT)) & MFT_FILTER_CH2FVAL_MASK); + obj->FILTER = tmp; +} + +/*! \brief Gets the Channel 1 Input Filter + * + * This function gets the current Channel 1 Input Filter. + * Selects the filter value for the channel input. + * The filter is disabled when the value is zero + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 1 Input Filter + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFilterCh1FVal(const MftRegType *obj) +{ + return ((obj->FILTER & MFT_FILTER_CH1FVAL_MASK) >> MFT_FILTER_CH1FVAL_SHIFT); +} + +/*! \brief Sets the Channel 1 Input Filter + * + * This function sets the Channel 1 Input Filter. + * Selects the filter value for the channel input. + * The filter is disabled when the value is zero + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 1 Input Filter + */ +__attribute__((always_inline)) static inline void MftReg_SetFilterCh1FVal(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FILTER; + + tmp &= ~MFT_FILTER_CH1FVAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FILTER_CH1FVAL_SHIFT)) & MFT_FILTER_CH1FVAL_MASK); + obj->FILTER = tmp; +} + +/*! \brief Gets the Channel 0 Input Filter + * + * This function gets the current Channel 0 Input Filter. + * Selects the filter value for the channel input. + * The filter is disabled when the value is zero + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 0 Input Filter + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFilterCh0FVal(const MftRegType *obj) +{ + return ((obj->FILTER & MFT_FILTER_CH0FVAL_MASK) >> MFT_FILTER_CH0FVAL_SHIFT); +} + +/*! \brief Sets the Channel 0 Input Filter + * + * This function sets the Channel 0 Input Filter. + * Selects the filter value for the channel input. + * The filter is disabled when the value is zero + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 0 Input Filter + */ +__attribute__((always_inline)) static inline void MftReg_SetFilterCh0FVal(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FILTER; + + tmp &= ~MFT_FILTER_CH0FVAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FILTER_CH0FVAL_SHIFT)) & MFT_FILTER_CH0FVAL_MASK); + obj->FILTER = tmp; +} + +/*! \brief Gets the Fault output state + * + * This function gets the current Fault output state. + * This configuration allows to put the MFT outputs tri-stated when a fault event is ongoing. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault output state + * - 0b : MFT outputs will be placed into safe values when fault events in ongoing (defined by POL bits). + * - 1b : MFT outputs will be tri-stated when fault event is ongoing + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltCtrlFstate(const MftRegType *obj) +{ + return ((obj->FLTCTRL & MFT_FLTCTRL_FSTATE_MASK) >> MFT_FLTCTRL_FSTATE_SHIFT); +} + +/*! \brief Sets the Fault output state + * + * This function sets the Fault output state. + * This configuration allows to put the MFT outputs tri-stated when a fault event is ongoing. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault output state + * - 0b : MFT outputs will be placed into safe values when fault events in ongoing (defined by POL bits). + * - 1b : MFT outputs will be tri-stated when fault event is ongoing + */ +__attribute__((always_inline)) static inline void MftReg_SetFltCtrlFstate(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTCTRL; + + tmp &= ~MFT_FLTCTRL_FSTATE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTCTRL_FSTATE_SHIFT)) & MFT_FLTCTRL_FSTATE_MASK); + obj->FLTCTRL = tmp; +} + +/*! \brief Gets the Fault Input Filter + * + * This function gets the current Fault Input Filter. + * Selects the filter value for the fault inputs. + * The fault filter is disabled when the value is zero. + * + * \note Writing to this field has immediate effect and must be done only when the fault contro + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input Filter + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltCtrlFFVal(const MftRegType *obj) +{ + return ((obj->FLTCTRL & MFT_FLTCTRL_FFVAL_MASK) >> MFT_FLTCTRL_FFVAL_SHIFT); +} + +/*! \brief Sets the Fault Input Filter + * + * This function sets the Fault Input Filter. + * Selects the filter value for the fault inputs. + * The fault filter is disabled when the value is zero. + * + * \note Writing to this field has immediate effect and must be done only when the fault contro + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input Filter + */ +__attribute__((always_inline)) static inline void MftReg_SetFltCtrlFFVal(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTCTRL; + + tmp &= ~MFT_FLTCTRL_FFVAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTCTRL_FFVAL_SHIFT)) & MFT_FLTCTRL_FFVAL_MASK); + obj->FLTCTRL = tmp; +} + +/*! \brief Gets the Fault Input 3 Filter Enable + * + * This function gets the current Fault Input 3 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 3 Filter Enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltCtrlFFltr3En(const MftRegType *obj) +{ + return ((obj->FLTCTRL & MFT_FLTCTRL_FFLTR3EN_MASK) >> MFT_FLTCTRL_FFLTR3EN_SHIFT); +} + +/*! \brief Sets the Fault Input 3 Filter Enable + * + * This function sets the Fault Input 3 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 3 Filter Enable + */ +__attribute__((always_inline)) static inline void MftReg_SetFltCtrlFFltr3En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTCTRL; + + tmp &= ~MFT_FLTCTRL_FFLTR3EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTCTRL_FFLTR3EN_SHIFT)) & MFT_FLTCTRL_FFLTR3EN_MASK); + obj->FLTCTRL = tmp; +} + +/*! \brief Gets the Fault Input 2 Filter Enable + * + * This function gets the current Fault Input 2 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 2 Filter Enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltCtrlFFltr2En(const MftRegType *obj) +{ + return ((obj->FLTCTRL & MFT_FLTCTRL_FFLTR2EN_MASK) >> MFT_FLTCTRL_FFLTR2EN_SHIFT); +} + +/*! \brief Sets the Fault Input 2 Filter Enable + * + * This function sets the Fault Input 2 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 2 Filter Enable + */ +__attribute__((always_inline)) static inline void MftReg_SetFltCtrlFFltr2En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTCTRL; + + tmp &= ~MFT_FLTCTRL_FFLTR2EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTCTRL_FFLTR2EN_SHIFT)) & MFT_FLTCTRL_FFLTR2EN_MASK); + obj->FLTCTRL = tmp; +} + +/*! \brief Gets the Fault Input 1 Filter Enable + * + * This function gets the current Fault Input 1 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 1 Filter Enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltCtrlFFltr1En(const MftRegType *obj) +{ + return ((obj->FLTCTRL & MFT_FLTCTRL_FFLTR1EN_MASK) >> MFT_FLTCTRL_FFLTR1EN_SHIFT); +} + +/*! \brief Sets the Fault Input 1 Filter Enable + * + * This function sets the Fault Input 1 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 1 Filter Enable + */ +__attribute__((always_inline)) static inline void MftReg_SetFltCtrlFFltr1En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTCTRL; + + tmp &= ~MFT_FLTCTRL_FFLTR1EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTCTRL_FFLTR1EN_SHIFT)) & MFT_FLTCTRL_FFLTR1EN_MASK); + obj->FLTCTRL = tmp; +} + +/*! \brief Gets the Fault Input 0 Filter Enable + * + * This function gets the current Fault Input 0 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 0 Filter Enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltCtrlFFltr0En(const MftRegType *obj) +{ + return ((obj->FLTCTRL & MFT_FLTCTRL_FFLTR0EN_MASK) >> MFT_FLTCTRL_FFLTR0EN_SHIFT); +} + +/*! \brief Sets the Fault Input 0 Filter Enable + * + * This function sets the Fault Input 0 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 0 Filter Enable + */ +__attribute__((always_inline)) static inline void MftReg_SetFltCtrlFFltr0En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTCTRL; + + tmp &= ~MFT_FLTCTRL_FFLTR0EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTCTRL_FFLTR0EN_SHIFT)) & MFT_FLTCTRL_FFLTR0EN_MASK); + obj->FLTCTRL = tmp; +} + +/*! \brief Gets the Fault Input 3 Filter Enable + * + * This function gets the current Fault Input 3 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 3 Filter Enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltCtrlFault3En(const MftRegType *obj) +{ + return ((obj->FLTCTRL & MFT_FLTCTRL_FAULT3EN_MASK) >> MFT_FLTCTRL_FAULT3EN_SHIFT); +} + +/*! \brief Sets the Fault Input 3 Filter Enable + * + * This function sets the Fault Input 3 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 3 Filter Enable + */ +__attribute__((always_inline)) static inline void MftReg_SetFltCtrlFault3En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTCTRL; + + tmp &= ~MFT_FLTCTRL_FAULT3EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTCTRL_FAULT3EN_SHIFT)) & MFT_FLTCTRL_FAULT3EN_MASK); + obj->FLTCTRL = tmp; +} + +/*! \brief Gets the Fault Input 2 Filter Enable + * + * This function gets the current Fault Input 2 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 2 Filter Enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltCtrlFault2En(const MftRegType *obj) +{ + return ((obj->FLTCTRL & MFT_FLTCTRL_FAULT2EN_MASK) >> MFT_FLTCTRL_FAULT2EN_SHIFT); +} + +/*! \brief Sets the Fault Input 2 Filter Enable + * + * This function sets the Fault Input 2 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 2 Filter Enable + */ +__attribute__((always_inline)) static inline void MftReg_SetFltCtrlFault2En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTCTRL; + + tmp &= ~MFT_FLTCTRL_FAULT2EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTCTRL_FAULT2EN_SHIFT)) & MFT_FLTCTRL_FAULT2EN_MASK); + obj->FLTCTRL = tmp; +} + +/*! \brief Gets the Fault Input 1 Filter Enable + * + * This function gets the current Fault Input 1 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 1 Filter Enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltCtrlFault1En(const MftRegType *obj) +{ + return ((obj->FLTCTRL & MFT_FLTCTRL_FAULT1EN_MASK) >> MFT_FLTCTRL_FAULT1EN_SHIFT); +} + +/*! \brief Sets the Fault Input 1 Filter Enable + * + * This function sets the Fault Input 1 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 1 Filter Enable + */ +__attribute__((always_inline)) static inline void MftReg_SetFltCtrlFault1En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTCTRL; + + tmp &= ~MFT_FLTCTRL_FAULT1EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTCTRL_FAULT1EN_SHIFT)) & MFT_FLTCTRL_FAULT1EN_MASK); + obj->FLTCTRL = tmp; +} + +/*! \brief Gets the Fault Input 0 Filter Enable + * + * This function gets the current Fault Input 0 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 0 Filter Enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltCtrlFault0En(const MftRegType *obj) +{ + return ((obj->FLTCTRL & MFT_FLTCTRL_FAULT0EN_MASK) >> MFT_FLTCTRL_FAULT0EN_SHIFT); +} + +/*! \brief Sets the Fault Input 0 Filter Enable + * + * This function sets the Fault Input 0 Filter Enable. + * Enables the filter for the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 0 Filter Enable + */ +__attribute__((always_inline)) static inline void MftReg_SetFltCtrlFault0En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTCTRL; + + tmp &= ~MFT_FLTCTRL_FAULT0EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTCTRL_FAULT0EN_SHIFT)) & MFT_FLTCTRL_FAULT0EN_MASK); + obj->FLTCTRL = tmp; +} + +/*! \brief Gets the Phase Z Input Filter Enable + * + * This function gets the current Phase Z Input Filter Enable. + * Enables the filter for the quadrature decoder phase Z input. + * The filter value for the phase Z input is defined by the CH0FVAL field of FILTER. + * The phase Z filter is also disabled when CH0FVAL is zero + * + * \param[in] obj : pointer to MFT register instance + * \return Phase Z Input Filter Enable + * - 0 : disable + * - 1 : enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlPhzFltrEn(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_PHZFLTREN_MASK) >> MFT_QDCTRL_PHZFLTREN_SHIFT); +} + +/*! \brief Sets the Phase Z Input Filter Enable + * + * This function sets the Phase Z Input Filter Enable. + * Enables the filter for the quadrature decoder phase Z input. + * The filter value for the phase Z input is defined by the CH0FVAL field of FILTER. + * The phase Z filter is also disabled when CH0FVAL is zero + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Phase Z Input Filter Enable + * - 0 : disable + * - 1 : enable + */ +__attribute__((always_inline)) static inline void MftReg_SetQDCtrlPhzFltrEn(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->QDCTRL; + + tmp &= ~MFT_QDCTRL_PHZFLTREN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_QDCTRL_PHZFLTREN_SHIFT)) & MFT_QDCTRL_PHZFLTREN_MASK); + obj->QDCTRL = tmp; +} + +/*! \brief Gets the Phase Z Input Polarity + * + * This function gets the current Phase Z Input Polarity. + * Selects the polarity for the quadrature decoder phase Z input. + * + * \param[in] obj : pointer to MFT register instance + * \return Phase A Input Polarity + * - 0b : Normal polarity. Phase Z input signal is not inverted + * before identifying the rising and falling edges of this signal. + * - 1b : Inverted polarity. Phase Z input signal is inverted + * before identifying the rising and falling edges of this signal. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlPhzPol(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_PHZPOL_MASK) >> MFT_QDCTRL_PHZPOL_SHIFT); +} + +/*! \brief Sets the Phase Z Input Polarity + * + * This function sets the Phase Z Input Polarity. + * Selects the polarity for the quadrature decoder phase Z input. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Phase Z Input Polarity + * - 0b : Normal polarity. Phase Z input signal is not inverted + * before identifying the rising and falling edges of this signal. + * - 1b : Inverted polarity. Phase Z input signal is inverted + * before identifying the rising and falling edges of this signal. + */ +__attribute__((always_inline)) static inline void MftReg_SetQDCtrlPhzPol(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->QDCTRL; + + tmp &= ~MFT_QDCTRL_PHZPOL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_QDCTRL_PHZPOL_SHIFT)) & MFT_QDCTRL_PHZPOL_MASK); + obj->QDCTRL = tmp; +} + +/*! \brief Gets the Phase Z Clearing Mode + * + * This function gets the Phase Z Clearing Mode. + * Selects the condition in which phase Z input signal clears the counter. + * + * \param[in] obj : pointer to MFT register instance + * \return Phase Z clear Mode + * - 00b : phase Z input does not reset the counter. + * - 01b : every effective edge of phase Z input resets the counter + * (Reseting does not happen immediately, but after the first or + * recorded phase A or phase B input edge). + * - 10b : phase Z input resets the counter only once + * (Reseting does not happen immediately, but after the first + * phase A or phase B input edge). + * - 11b : Clear immediately when the effective edge of Phase Z signal comes. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlPhzClearMode(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_PHZMODE_MASK) >> MFT_QDCTRL_PHZMODE_SHIFT); +} + +/*! \brief Sets the Phase Z Clearing Mode + * + * This function sets the Phase Z Clearing Mode. + * Selects the condition in which phase Z input signal clears the counter. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Phase Z Clearing Mode + * - 00b : phase Z input does not reset the counter. + * - 01b : every effective edge of phase Z input resets the counter + * (Reseting does not happen immediately, but after the first or + * recorded phase A or phase B input edge). + * - 10b : phase Z input resets the counter only once + * (Reseting does not happen immediately, but after the first + * phase A or phase B input edge). + * - 11b : Clear immediately when the effective edge of Phase Z signal comes. + * + */ +__attribute__((always_inline)) static inline void MftReg_SetQDCtrlPhzClearMode(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->QDCTRL; + + tmp &= ~MFT_QDCTRL_PHZMODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_QDCTRL_PHZMODE_SHIFT)) & MFT_QDCTRL_PHZMODE_MASK); + obj->QDCTRL = tmp; +} + +/*! \brief Gets the Phase Z First has occurred status + * + * This function gets the Phase Z First index pulse has occurred status. + * + * \param[in] obj : pointer to MFT register instance + * \return Phase Z First occurred status + * - 0b : phase Z clearing once has not happened + * - 1b : phase Z clearing once has happened + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlPhzFirstHappened(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_PHZCOF_MASK) >> MFT_QDCTRL_PHZCOF_SHIFT); +} + +/*! \brief Clear the Phase Z has occurred status + * + * This function clear the Phase Z First index pulse has occurred status. + * + * \param[in] obj : pointer to MFT register instance + */ +__attribute__((always_inline)) static inline void MftReg_ClearQDCtrlPhzFirstHappend(MftRegType *obj) +{ + uint32_t tmp = obj->QDCTRL; + + tmp &= ~MFT_QDCTRL_PHZCOF_MASK; + tmp |= (((uint32_t)(((uint32_t)(1)) << MFT_QDCTRL_PHZCOF_SHIFT)) & MFT_QDCTRL_PHZCOF_MASK); + obj->QDCTRL = tmp; +} + +/*! \brief Gets the Phase A Input Filter Enable + * + * This function gets the current Phase A Input Filter Enable. + * Enables the filter for the quadrature decoder phase A input. + * The filter value for the phase A input is defined by the CH0FVAL field of FILTER. + * The phase A filter is also disabled when CH0FVAL is zero + * + * \param[in] obj : pointer to MFT register instance + * \return Phase A Input Filter Enable + * - 0 : disable + * - 1 : enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlPhaFltrEn(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_PHAFLTREN_MASK) >> MFT_QDCTRL_PHAFLTREN_SHIFT); +} + +/*! \brief Sets the Phase A Input Filter Enable + * + * This function sets the Phase A Input Filter Enable. + * Enables the filter for the quadrature decoder phase A input. + * The filter value for the phase A input is defined by the CH0FVAL field of FILTER. + * The phase A filter is also disabled when CH0FVAL is zero + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Phase A Input Filter Enable + * - 0 : disable + * - 1 : enable + */ +__attribute__((always_inline)) static inline void MftReg_SetQDCtrlPhaFltrEn(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->QDCTRL; + + tmp &= ~MFT_QDCTRL_PHAFLTREN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_QDCTRL_PHAFLTREN_SHIFT)) & MFT_QDCTRL_PHAFLTREN_MASK); + obj->QDCTRL = tmp; +} + +/*! \brief Gets the Phase B Input Filter Enable + * + * This function gets the current Phase B Input Filter Enable. + * Enables the filter for the quadrature decoder phase B input. + * The filter value for the phase B input is defined by the CH1FVAL field of FILTER. + * The phase B filter is also disabled when CH1FVAL is zero + * + * \param[in] obj : pointer to MFT register instance + * \return Phase B Input Filter Enable + * - 0 : disable + * - 1 : enable + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlPhbFltrEn(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_PHBFLTREN_MASK) >> MFT_QDCTRL_PHBFLTREN_SHIFT); +} + +/*! \brief Sets the Phase B Input Filter Enable + * + * This function sets the Phase B Input Filter Enable. + * Enables the filter for the quadrature decoder phase B input. + * The filter value for the phase B input is defined by the CH1FVAL field of FILTER. + * The phase B filter is also disabled when CH1FVAL is zero + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Phase B Input Filter Enable + * - 0 : disable + * - 1 : enable + */ +__attribute__((always_inline)) static inline void MftReg_SetQDCtrlPhbFltrEn(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->QDCTRL; + + tmp &= ~MFT_QDCTRL_PHBFLTREN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_QDCTRL_PHBFLTREN_SHIFT)) & MFT_QDCTRL_PHBFLTREN_MASK); + obj->QDCTRL = tmp; +} + +/*! \brief Gets the Phase A Input Polarity + * + * This function gets the current Phase A Input Polarity. + * Selects the polarity for the quadrature decoder phase A input. + * + * \param[in] obj : pointer to MFT register instance + * \return Phase A Input Polarity + * - 0b : Normal polarity. Phase A input signal is not inverted + * before identifying the rising and falling edges of this signal. + * - 1b : Inverted polarity. Phase A input signal is inverted + * before identifying the rising and falling edges of this signal. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlPhaPol(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_PHAPOL_MASK) >> MFT_QDCTRL_PHAPOL_SHIFT); +} + +/*! \brief Sets the Phase A Input Polarity + * + * This function sets the Phase A Input Polarity. + * Selects the polarity for the quadrature decoder phase A input. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Phase A Input Polarity + * - 0b : Normal polarity. Phase A input signal is not inverted + * before identifying the rising and falling edges of this signal. + * - 1b : Inverted polarity. Phase A input signal is inverted + * before identifying the rising and falling edges of this signal. + */ +__attribute__((always_inline)) static inline void MftReg_SetQDCtrlPhaPol(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->QDCTRL; + + tmp &= ~MFT_QDCTRL_PHAPOL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_QDCTRL_PHAPOL_SHIFT)) & MFT_QDCTRL_PHAPOL_MASK); + obj->QDCTRL = tmp; +} + +/*! \brief Gets the Phase B Input Polarity + * + * This function gets the current Phase B Input Polarity. + * Selects the polarity for the quadrature decoder phase B input. + * + * \param[in] obj : pointer to MFT register instance + * \return Phase B Input Polarity + * - 0b : Normal polarity. Phase B input signal is not inverted + * before identifying the rising and falling edges of this signal. + * - 1b : Inverted polarity. Phase B input signal is inverted + * before identifying the rising and falling edges of this signal. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlPhbPol(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_PHBPOL_MASK) >> MFT_QDCTRL_PHBPOL_SHIFT); +} + +/*! \brief Sets the Phase B Input Polarity + * + * This function sets the Phase B Input Polarity. + * Selects the polarity for the quadrature decoder phase B input. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Phase B Input Polarity + * - 0b : Normal polarity. Phase B input signal is not inverted + * before identifying the rising and falling edges of this signal. + * - 1b : Inverted polarity. Phase B input signal is inverted + * before identifying the rising and falling edges of this signal. + */ +__attribute__((always_inline)) static inline void MftReg_SetQDCtrlPhbPol(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->QDCTRL; + + tmp &= ~MFT_QDCTRL_PHBPOL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_QDCTRL_PHBPOL_SHIFT)) & MFT_QDCTRL_PHBPOL_MASK); + obj->QDCTRL = tmp; +} + +/*! \brief Gets the Quadrature Decoder Mode + * + * This function gets the current Quadrature Decoder Mode. + * Selects the encoding mode used in the Quadrature Decoder mode. + * + * \param[in] obj : pointer to MFT register instance + * \return Quadrature Decoder Mode + * - 0b : Phase A and phase B encoding mode. + * - 1b : Count and direction encoding mode. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlQuadMode(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_QUADMODE_MASK) >> MFT_QDCTRL_QUADMODE_SHIFT); +} + +/*! \brief Sets the Quadrature Decoder Mode + * + * This function sets the Quadrature Decoder Mode. + * Selects the encoding mode used in the Quadrature Decoder mode. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Quadrature Decoder Mode + * - 0b : Phase A and phase B encoding mode. + * - 1b : Count and direction encoding mode. + */ +__attribute__((always_inline)) static inline void MftReg_SetQDCtrlQuadMode(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->QDCTRL; + + tmp &= ~MFT_QDCTRL_QUADMODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_QDCTRL_QUADMODE_SHIFT)) & MFT_QDCTRL_QUADMODE_MASK); + obj->QDCTRL = tmp; +} + +/*! \brief Gets the MFT Counter Direction In Quadrature Decoder Mode + * + * This function gets the current MFT Counter Direction In Quadrature Decoder Mode. + * Indicates the counting direction. + * + * \param[in] obj : pointer to MFT register instance + * \return MFT Counter Direction In Quadrature Decoder Mode + * - 0b : Counting direction is decreasing (MFT counter decrement). + * - 1b : Counting direction is increasing (MFT counter increment). + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlQuaDir(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_QUADIR_MASK) >> MFT_QDCTRL_QUADIR_SHIFT); +} + +/*! \brief Gets the Timer Overflow Direction In Quadrature Decoder Mode + * + * This function gets the current Timer Overflow Direction In Quadrature Decoder Mode. + * Indicates if the TOF bit was set on the top or the bottom of counting. + * + * \param[in] obj : pointer to MFT register instance + * \return Timer Overflow Direction In Quadrature Decoder Mode + * - 0b : TOF bit was set on the bottom of counting. + * There was an MFT counter decrement and MFT counter changes + * from its minimum value (CNTIN register) to its maximum value (MOD register). + * - 1b : TOF bit was set on the top of counting. + * There was an MFT counter increment and MFT counter changes + * from its maximum value (MOD register) to its minimum value (CNTIN register). + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlTorDir(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_TOFDIR_MASK) >> MFT_QDCTRL_TOFDIR_SHIFT); +} + +/*! \brief Gets the Quadrature Decoder Mode Enable + * + * This function gets the current Quadrature Decoder Mode Enable. + * Enables the Quadrature Decoder mode. + * In this mode, the phase A and B input signals control the MFT counter direction. + * The Quadrature Decoder mode has precedence over the other modes. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Quadrature Decoder Mode Enable + * - 0b : Quadrature Decoder mode is disabled. + * - 1b : Quadrature Decoder mode is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetQDCtrlQuadEn(const MftRegType *obj) +{ + return ((obj->QDCTRL & MFT_QDCTRL_QUADEN_MASK) >> MFT_QDCTRL_QUADEN_SHIFT); +} + +/*! \brief Sets the Quadrature Decoder Mode Enable + * + * This function sets the Quadrature Decoder Mode Enable. + * Enables the Quadrature Decoder mode. + * In this mode, the phase A and B input signals control the MFT counter direction. + * The Quadrature Decoder mode has precedence over the other modes. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Quadrature Decoder Mode Enable + * - 0b : Quadrature Decoder mode is disabled. + * - 1b : Quadrature Decoder mode is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetQDCtrlQuadEn(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->QDCTRL; + + tmp &= ~MFT_QDCTRL_QUADEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_QDCTRL_QUADEN_SHIFT)) & MFT_QDCTRL_QUADEN_MASK); + obj->QDCTRL = tmp; +} + +/*! \brief Gets the Initialization trigger on Reload Point + * + * This function gets the current Initialization trigger on Reload Point. + * This bit controls whether an initialization trigger is generated when a reload point configured by + * PWMLOAD register is reached considering the MFT_CONF[LDFQ] settings. + * + * \param[in] obj : pointer to MFT register instance + * \return Initialization trigger on Reload Point + * - 0b : Initialization trigger is generated on counter wrap events. + * - 1b : Initialization trigger is generated when a reload point is reached. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetConfITrigR(const MftRegType *obj) +{ + return ((obj->CONF & MFT_CONF_ITRIGR_MASK) >> MFT_CONF_ITRIGR_SHIFT); +} + +/*! \brief Sets the Initialization trigger on Reload Point + * + * This function sets the Initialization trigger on Reload Point. + * This bit controls whether an initialization trigger is generated when a reload point configured by + * PWMLOAD register is reached considering the MFT_CONF[LDFQ] settings. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Initialization trigger on Reload Point + * - 0b : Initialization trigger is generated on counter wrap events. + * - 1b : Initialization trigger is generated when a reload point is reached. + */ +__attribute__((always_inline)) static inline void MftReg_SetConfITrigR(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CONF; + + tmp &= ~MFT_CONF_ITRIGR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CONF_ITRIGR_SHIFT)) & MFT_CONF_ITRIGR_MASK); + obj->CONF = tmp; +} + +/*! \brief Gets the Global Time Base Output + * + * This function gets the current Global Time Base Output. + * Enables the global time base signal generation to other MFTs. + * + * \param[in] obj : pointer to MFT register instance + * \return Global Time Base Output + * - 0b : A global time base signal generation is disabled. + * - 1b : A global time base signal generation is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetConfGtbeOut(const MftRegType *obj) +{ + return ((obj->CONF & MFT_CONF_GTBEOUT_MASK) >> MFT_CONF_GTBEOUT_SHIFT); +} + +/*! \brief Sets the Global Time Base Output + * + * This function sets the Global Time Base Output. + * Enables the global time base signal generation to other MFTs. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Global Time Base Output + * - 0b : A global time base signal generation is disabled. + * - 1b : A global time base signal generation is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetConfGtbeOut(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CONF; + + tmp &= ~MFT_CONF_GTBEOUT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CONF_GTBEOUT_SHIFT)) & MFT_CONF_GTBEOUT_MASK); + obj->CONF = tmp; +} + +/*! \brief Gets the Global Time Base Enable + * + * This function gets the current Global Time Base Enable. + * Configures the MFT to use an external global time base signal that is generated by another MFT. + * + * \param[in] obj : pointer to MFT register instance + * \return Global Time Base Enable + * - 0b : Use of an external global time base is disabled. + * - 1b : Use of an external global time base is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetConfGtbeEn(const MftRegType *obj) +{ + return ((obj->CONF & MFT_CONF_GTBEEN_MASK) >> MFT_CONF_GTBEEN_SHIFT); +} + +/*! \brief Sets the Global Time Base Enable + * + * This function sets the Global Time Base Enable. + * Configures the MFT to use an external global time base signal that is generated by another MFT. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Global Time Base Enable + * - 0b : Use of an external global time base is disabled. + * - 1b : Use of an external global time base is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetConfGtbeEn(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CONF; + + tmp &= ~MFT_CONF_GTBEEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CONF_GTBEEN_SHIFT)) & MFT_CONF_GTBEEN_MASK); + obj->CONF = tmp; +} + +/*! \brief Gets the Debug Mode + * + * This function gets the current Debug Mode. + * Selects the MFT behavior in Debug mod + * + * \param[in] obj : pointer to MFT register instance + * \return Debug Mode + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetConfBdmMode(const MftRegType *obj) +{ + return ((obj->CONF & MFT_CONF_BDMMODE_MASK) >> MFT_CONF_BDMMODE_SHIFT); +} + +/*! \brief Sets the Debug Mode + * + * This function sets the Debug Mode. + * Selects the MFT behavior in Debug mod + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Debug Mode + */ +__attribute__((always_inline)) static inline void MftReg_SetConfBdmMode(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CONF; + + tmp &= ~MFT_CONF_BDMMODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CONF_BDMMODE_SHIFT)) & MFT_CONF_BDMMODE_MASK); + obj->CONF = tmp; +} + +/*! \brief Gets the Frequency of the Reload Opportunities + * + * This function gets the current Frequency of the Reload Opportunities. + * The LDFQ[4:0] bits define the number of enabled reload opportunities should happen + * until an enabled reload opportunity becomes a reload point. See Reload Points + * LDFQ = 0: All reload opportunities are reload points. + * LDFQ = 1: There is a reload point each 2 reload oportunities. + * LDFQ = 2: There is a reload point each 3 reload oportunities. + * LDFQ = 3: There is a reload point each 4 reload oportunities. + * This pattern continues up to a maximum of 32 + * + * \param[in] obj : pointer to MFT register instance + * \return Frequency of the Reload Opportunities + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetConfLdfq(const MftRegType *obj) +{ + return ((obj->CONF & MFT_CONF_LDFQ_MASK) >> MFT_CONF_LDFQ_SHIFT); +} + +/*! \brief Sets the Frequency of the Reload Opportunities + * + * This function sets the Frequency of the Reload Opportunities. + * The LDFQ[4:0] bits define the number of enabled reload opportunities should happen + * until an enabled reload opportunity becomes a reload point. See Reload Points + * LDFQ = 0: All reload opportunities are reload points. + * LDFQ = 1: There is a reload point each 2 reload oportunities. + * LDFQ = 2: There is a reload point each 3 reload oportunities. + * LDFQ = 3: There is a reload point each 4 reload oportunities. + * This pattern continues up to a maximum of 32 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Frequency of the Reload Opportunities + */ +__attribute__((always_inline)) static inline void MftReg_SetConfLdfq(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CONF; + + tmp &= ~MFT_CONF_LDFQ_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CONF_LDFQ_SHIFT)) & MFT_CONF_LDFQ_MASK); + obj->CONF = tmp; +} + +/*! \brief Gets the Fault Input 3 Polarity + * + * This function gets the current Fault Input 3 Polarity. + * Defines the polarity of the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 3 Polarity + * - 0b : The fault input polarity is active high. A 1 at the fault input indicates a fault. + * - 1b : The fault input polarity is active low. A 0 at the fault input indicates a fault. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltPolFlt3Pol(const MftRegType *obj) +{ + return ((obj->FLTPOL & MFT_FLTPOL_FLT3POL_MASK) >> MFT_FLTPOL_FLT3POL_SHIFT); +} + +/*! \brief Sets the Fault Input 3 Polarity + * + * This function sets the Fault Input 3 Polarity. + * Defines the polarity of the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 3 Polarity + * - 0b : The fault input polarity is active high. A 1 at the fault input indicates a fault. + * - 1b : The fault input polarity is active low. A 0 at the fault input indicates a fault. + */ +__attribute__((always_inline)) static inline void MftReg_SetFltPolFlt3Pol(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTPOL; + + tmp &= ~MFT_FLTPOL_FLT3POL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTPOL_FLT3POL_SHIFT)) & MFT_FLTPOL_FLT3POL_MASK); + obj->FLTPOL = tmp; +} + +/*! \brief Gets the Fault Input 2 Polarity + * + * This function gets the current Fault Input 2 Polarity. + * Defines the polarity of the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 2 Polarity + * - 0b : The fault input polarity is active high. A 1 at the fault input indicates a fault. + * - 1b : The fault input polarity is active low. A 0 at the fault input indicates a fault. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltPolFlt2Pol(const MftRegType *obj) +{ + return ((obj->FLTPOL & MFT_FLTPOL_FLT2POL_MASK) >> MFT_FLTPOL_FLT2POL_SHIFT); +} + +/*! \brief Sets the Fault Input 2 Polarity + * + * This function sets the Fault Input 2 Polarity. + * Defines the polarity of the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 2 Polarity + * - 0b : The fault input polarity is active high. A 1 at the fault input indicates a fault. + * - 1b : The fault input polarity is active low. A 0 at the fault input indicates a fault. + */ +__attribute__((always_inline)) static inline void MftReg_SetFltPolFlt2Pol(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTPOL; + + tmp &= ~MFT_FLTPOL_FLT2POL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTPOL_FLT2POL_SHIFT)) & MFT_FLTPOL_FLT2POL_MASK); + obj->FLTPOL = tmp; +} + +/*! \brief Gets the Fault Input 1 Polarity + * + * This function gets the current Fault Input 1 Polarity. + * Defines the polarity of the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 1 Polarity + * - 0b : The fault input polarity is active high. A 1 at the fault input indicates a fault. + * - 1b : The fault input polarity is active low. A 0 at the fault input indicates a fault. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltPolFlt1Pol(const MftRegType *obj) +{ + return ((obj->FLTPOL & MFT_FLTPOL_FLT1POL_MASK) >> MFT_FLTPOL_FLT1POL_SHIFT); +} + +/*! \brief Sets the Fault Input 1 Polarity + * + * This function sets the Fault Input 1 Polarity. + * Defines the polarity of the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 1 Polarity + * - 0b : The fault input polarity is active high. A 1 at the fault input indicates a fault. + * - 1b : The fault input polarity is active low. A 0 at the fault input indicates a fault. + */ +__attribute__((always_inline)) static inline void MftReg_SetFltPolFlt1Pol(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTPOL; + + tmp &= ~MFT_FLTPOL_FLT1POL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTPOL_FLT1POL_SHIFT)) & MFT_FLTPOL_FLT1POL_MASK); + obj->FLTPOL = tmp; +} + +/*! \brief Gets the Fault Input 0 Polarity + * + * This function gets the current Fault Input 0 Polarity. + * Defines the polarity of the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \return Fault Input 0 Polarity + * - 0b : The fault input polarity is active high. A 1 at the fault input indicates a fault. + * - 1b : The fault input polarity is active low. A 0 at the fault input indicates a fault. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetFltPolFlt0Pol(const MftRegType *obj) +{ + return ((obj->FLTPOL & MFT_FLTPOL_FLT0POL_MASK) >> MFT_FLTPOL_FLT0POL_SHIFT); +} + +/*! \brief Sets the Fault Input 0 Polarity + * + * This function sets the Fault Input 0 Polarity. + * Defines the polarity of the fault input. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Fault Input 0 Polarity + * - 0b : The fault input polarity is active high. A 1 at the fault input indicates a fault. + * - 1b : The fault input polarity is active low. A 0 at the fault input indicates a fault. + */ +__attribute__((always_inline)) static inline void MftReg_SetFltPolFlt0Pol(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLTPOL; + + tmp &= ~MFT_FLTPOL_FLT0POL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_FLTPOL_FLT0POL_SHIFT)) & MFT_FLTPOL_FLT0POL_MASK); + obj->FLTPOL = tmp; +} + +/*! \brief Gets the Software output control synchronization is activated by a hardware trigger + * + * This function gets the current Software output control synchronization is activated by a hardware trigger. + * + * \param[in] obj : pointer to MFT register instance + * \return Software output control synchronization is activated by a hardware trigger + * - 0b : A hardware trigger does not activate the SWOCTRL register synchronization. + * - 1b : A hardware trigger activates the SWOCTRL register synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfHwSoc(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_HWSOC_MASK) >> MFT_SYNCONF_HWSOC_SHIFT); +} + +/*! \brief Sets the Software output control synchronization is activated by a hardware trigger + * + * This function sets the Software output control synchronization is activated by a hardware trigger. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Software output control synchronization is activated by a hardware trigger + * - 0b : A hardware trigger does not activate the SWOCTRL register synchronization. + * - 1b : A hardware trigger activates the SWOCTRL register synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfHwSoc(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_HWSOC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_HWSOC_SHIFT)) & MFT_SYNCONF_HWSOC_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the Inverting control synchronization is activated by a hardware trigger + * + * This function gets the current Inverting control synchronization is activated by a hardware trigger. + * + * \param[in] obj : pointer to MFT register instance + * \return Inverting control synchronization is activated by a hardware trigger + * - 0b : A hardware trigger does not activate the INVCTRL register synchronization. + * - 1b : A hardware trigger activates the INVCTRL register synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfHwInvC(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_HWINVC_MASK) >> MFT_SYNCONF_HWINVC_SHIFT); +} + +/*! \brief Sets the Inverting control synchronization is activated by a hardware trigger + * + * This function sets the Inverting control synchronization is activated by a hardware trigger. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Inverting control synchronization is activated by a hardware trigger + * - 0b : A hardware trigger does not activate the INVCTRL register synchronization. + * - 1b : A hardware trigger activates the INVCTRL register synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfHwInvC(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_HWINVC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_HWINVC_SHIFT)) & MFT_SYNCONF_HWINVC_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the Output mask synchronization is activated by a hardware trigger + * + * This function gets the current Output mask synchronization is activated by a hardware trigger. + * + * \param[in] obj : pointer to MFT register instance + * \return Output mask synchronization is activated by a hardware trigger + * - 0b : A hardware trigger does not activate the OUTMASK register synchronization. + * - 1b : A hardware trigger activates the OUTMASK register synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfHwOM(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_HWOM_MASK) >> MFT_SYNCONF_HWOM_SHIFT); +} + +/*! \brief Sets the Output mask synchronization is activated by a hardware trigger + * + * This function sets the Output mask synchronization is activated by a hardware trigger. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Output mask synchronization is activated by a hardware trigger + * - 0b : A hardware trigger does not activate the OUTMASK register synchronization. + * - 1b : A hardware trigger activates the OUTMASK register synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfHwOM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_HWOM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_HWOM_SHIFT)) & MFT_SYNCONF_HWOM_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the MOD, HCR, CNTIN, and CV registers synchronization is activated by a hardware trigger + * + * This function gets the current MOD, HCR, CNTIN, and CV registers synchronization is activated by a hardware trigger. + * + * \param[in] obj : pointer to MFT register instance + * \return MOD, HCR, CNTIN, and CV registers synchronization is activated by a hardware trigger + * - 0b : A hardware trigger does not activate MOD, HCR, CNTIN, and CV registers synchronization. + * - 1b : A hardware trigger activates MOD, HCR, CNTIN, and CV registers synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfHwWrbuf(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_HWWRBUF_MASK) >> MFT_SYNCONF_HWWRBUF_SHIFT); +} + +/*! \brief Sets the MOD, HCR, CNTIN, and CV registers synchronization is activated by a hardware trigger + * + * This function sets the MOD, HCR, CNTIN, and CV registers synchronization is activated by a hardware trigger. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of MOD, HCR, CNTIN, and CV registers synchronization is activated by a hardware trigger + * - 0b : A hardware trigger does not activate MOD, HCR, CNTIN, and CV registers synchronization. + * - 1b : A hardware trigger activates MOD, HCR, CNTIN, and CV registers synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfHwWrbuf(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_HWWRBUF_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_HWWRBUF_SHIFT)) & MFT_SYNCONF_HWWRBUF_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the MFT counter synchronization is activated by a hardware trigger + * + * This function gets the current MFT counter synchronization is activated by a hardware trigger. + * + * \param[in] obj : pointer to MFT register instance + * \return MFT counter synchronization is activated by a hardware trigger + * - 0b : A hardware trigger does not activate the MFT counter synchronization. + * - 1b : A hardware trigger activates the MFT counter synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfHwRstCnt(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_HWRSTCNT_MASK) >> MFT_SYNCONF_HWRSTCNT_SHIFT); +} + +/*! \brief Sets the MFT counter synchronization is activated by a hardware trigger + * + * This function sets the MFT counter synchronization is activated by a hardware trigger. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of MFT counter synchronization is activated by a hardware trigger + * - 0b : A hardware trigger does not activate the MFT counter synchronization. + * - 1b : A hardware trigger activates the MFT counter synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfHwRstCnt(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_HWRSTCNT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_HWRSTCNT_SHIFT)) & MFT_SYNCONF_HWRSTCNT_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the Software output control synchronization is activated by the software trigger + * + * This function gets the current Software output control synchronization is activated by the software trigger. + * + * \param[in] obj : pointer to MFT register instance + * \return Software output control synchronization is activated by the software trigger + * - 0b : The software trigger does not activate the SWOCTRL register synchronization. + * - 1b : The software trigger activates the SWOCTRL register synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfSwSoc(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_SWSOC_MASK) >> MFT_SYNCONF_SWSOC_SHIFT); +} + +/*! \brief Sets the Software output control synchronization is activated by the software trigger + * + * This function sets the Software output control synchronization is activated by the software trigger. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Software output control synchronization is activated by the software trigger + * - 0b : The software trigger does not activate the SWOCTRL register synchronization. + * - 1b : The software trigger activates the SWOCTRL register synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfSwSoc(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_SWSOC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_SWSOC_SHIFT)) & MFT_SYNCONF_SWSOC_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the Inverting control synchronization is activated by the software trigger + * + * This function gets the current Inverting control synchronization is activated by the software trigger. + * + * \param[in] obj : pointer to MFT register instance + * \return Inverting control synchronization is activated by the software trigger + * - 0b : The software trigger does not activate the INVCTRL register synchronization. + * - 1b : The software trigger activates the INVCTRL register synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfSwInvC(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_SWINVC_MASK) >> MFT_SYNCONF_SWINVC_SHIFT); +} + +/*! \brief Sets the Inverting control synchronization is activated by the software trigger + * + * This function sets the Inverting control synchronization is activated by the software trigger. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Inverting control synchronization is activated by the software trigger + * - 0b : The software trigger does not activate the INVCTRL register synchronization. + * - 1b : The software trigger activates the INVCTRL register synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfSwInvC(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_SWINVC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_SWINVC_SHIFT)) & MFT_SYNCONF_SWINVC_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the Output mask synchronization is activated by the software trigger + * + * This function gets the current Output mask synchronization is activated by the software trigger. + * + * \param[in] obj : pointer to MFT register instance + * \return Output mask synchronization is activated by the software trigger + * - 0b : The software trigger does not activate the OUTMASK register synchronization. + * - 1b : The software trigger activates the OUTMASK register synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfSwOM(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_SWOM_MASK) >> MFT_SYNCONF_SWOM_SHIFT); +} + +/*! \brief Sets the Output mask synchronization is activated by the software trigger + * + * This function sets the Output mask synchronization is activated by the software trigger. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Output mask synchronization is activated by the software trigger + * - 0b : The software trigger does not activate the OUTMASK register synchronization. + * - 1b : The software trigger activates the OUTMASK register synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfSwOM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_SWOM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_SWOM_SHIFT)) & MFT_SYNCONF_SWOM_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the MOD, HCR, CNTIN, and CV registers synchronization is activated by the software trigger + * + * This function gets the current MOD, HCR, CNTIN, and CV registers synchronization is activated by the software trigger. + * + * \param[in] obj : pointer to MFT register instance + * \return MOD, HCR, CNTIN, and CV registers synchronization is activated by the software trigger + * - 0b : The software trigger does not activate MOD, HCR, CNTIN, and CV registers synchronization. + * - 1b : The software trigger activates MOD, HCR, CNTIN, and CV registers synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfSwWrbuf(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_SWWRBUF_MASK) >> MFT_SYNCONF_SWWRBUF_SHIFT); +} + +/*! \brief Sets the MOD, HCR, CNTIN, and CV registers synchronization is activated by the software trigger + * + * This function sets the MOD, HCR, CNTIN, and CV registers synchronization is activated by the software trigger. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of MOD, HCR, CNTIN, and CV registers synchronization is activated by the software trigger + * - 0b : The software trigger does not activate MOD, HCR, CNTIN, and CV registers synchronization. + * - 1b : The software trigger activates MOD, HCR, CNTIN, and CV registers synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfSwWrbuf(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_SWWRBUF_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_SWWRBUF_SHIFT)) & MFT_SYNCONF_SWWRBUF_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the MFT counter synchronization is activated by the software trigger + * + * This function gets the current MFT counter synchronization is activated by the software trigger. + * + * \param[in] obj : pointer to MFT register instance + * \return MFT counter synchronization is activated by the software trigger + * - 0b : The software trigger does not activate the MFT counter synchronization. + * - 1b : The software trigger activates the MFT counter synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfSwRstCnt(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_SWRSTCNT_MASK) >> MFT_SYNCONF_SWRSTCNT_SHIFT); +} + +/*! \brief Sets the MFT counter synchronization is activated by the software trigger + * + * This function sets the MFT counter synchronization is activated by the software trigger. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of MFT counter synchronization is activated by the software trigger + * - 0b : The software trigger does not activate the MFT counter synchronization. + * - 1b : The software trigger activates the MFT counter synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfSwRstCnt(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_SWRSTCNT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_SWRSTCNT_SHIFT)) & MFT_SYNCONF_SWRSTCNT_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the Synchronization Mode + * + * This function gets the current Synchronization Mode. + * Selects the PWM Synchronization mode. + * + * \param[in] obj : pointer to MFT register instance + * \return Synchronization Mode + * - 0b : Legacy PWM synchronization is selected. + * - 1b : Enhanced PWM synchronization is selected. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfSyncMode(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_SYNCMODE_MASK) >> MFT_SYNCONF_SYNCMODE_SHIFT); +} + +/*! \brief Sets the Synchronization Mode + * + * This function sets the Synchronization Mode. + * Selects the PWM Synchronization mode. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Synchronization Mode + * - 0b : Legacy PWM synchronization is selected. + * - 1b : Enhanced PWM synchronization is selected. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfSyncMode(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_SYNCMODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_SYNCMODE_SHIFT)) & MFT_SYNCONF_SYNCMODE_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the SWOCTRL Register Synchronization + * + * This function gets the current SWOCTRL Register Synchronization. + * + * \param[in] obj : pointer to MFT register instance + * \return SWOCTRL Register Synchronization + * - 0b : SWOCTRL register is updated with its buffer value at all rising edges of MFT input clock. + * - 1b : SWOCTRL register is updated with its buffer value by the PWM synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfSwOC(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_SWOC_MASK) >> MFT_SYNCONF_SWOC_SHIFT); +} + +/*! \brief Sets the SWOCTRL Register Synchronization + * + * This function sets the SWOCTRL Register Synchronization. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of SWOCTRL Register Synchronization + * - 0b : SWOCTRL register is updated with its buffer value at all rising edges of MFT input clock. + * - 1b : SWOCTRL register is updated with its buffer value by the PWM synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfSwOC(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_SWOC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_SWOC_SHIFT)) & MFT_SYNCONF_SWOC_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the INVCTRL Register Synchronization + * + * This function gets the current INVCTRL Register Synchronization. + * + * \param[in] obj : pointer to MFT register instance + * \return INVCTRL Register Synchronization + * - 0b : INVCTRL register is updated with its buffer value at all rising edges of MFT input clock. + * - 1b : INVCTRL register is updated with its buffer value by the PWM synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfInvC(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_INVC_MASK) >> MFT_SYNCONF_INVC_SHIFT); +} + +/*! \brief Sets the INVCTRL Register Synchronization + * + * This function sets the INVCTRL Register Synchronization. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of INVCTRL Register Synchronization + * - 0b : INVCTRL register is updated with its buffer value at all rising edges of MFT input clock. + * - 1b : INVCTRL register is updated with its buffer value by the PWM synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfInvC(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_INVC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_INVC_SHIFT)) & MFT_SYNCONF_INVC_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the CNTIN Register Synchronization + * + * This function gets the current CNTIN Register Synchronization. + * + * \param[in] obj : pointer to MFT register instance + * \return CNTIN Register Synchronization + * - 0b : CNTIN register is updated with its buffer value at all rising edges of MFT input clock. + * - 1b : CNTIN register is updated with its buffer value by the PWM synchronization. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfCntInC(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_CNTINC_MASK) >> MFT_SYNCONF_CNTINC_SHIFT); +} + +/*! \brief Sets the CNTIN Register Synchronization + * + * This function sets the CNTIN Register Synchronization. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of CNTIN Register Synchronization + * - 0b : CNTIN register is updated with its buffer value at all rising edges of MFT input clock. + * - 1b : CNTIN register is updated with its buffer value by the PWM synchronization. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfCntInC(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_CNTINC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_CNTINC_SHIFT)) & MFT_SYNCONF_CNTINC_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the Hardware Trigger Mode + * + * This function gets the current Hardware Trigger Mode. + * + * \param[in] obj : pointer to MFT register instance + * \return Hardware Trigger Mode + * - 0b : MFT clears the TRIGj bit when the hardware trigger j is detected, where j = 0, 1,2. + * - 1b : MFT does not clear the TRIGj bit when the hardware trigger j is detected, where j = 0, 1,2. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSynConfHwTrigMode(const MftRegType *obj) +{ + return ((obj->SYNCONF & MFT_SYNCONF_HWTRIGMODE_MASK) >> MFT_SYNCONF_HWTRIGMODE_SHIFT); +} + +/*! \brief Sets the Hardware Trigger Mode + * + * This function sets the Hardware Trigger Mode. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Hardware Trigger Mode + * - 0b : MFT clears the TRIGj bit when the hardware trigger j is detected, where j = 0, 1,2. + * - 1b : MFT does not clear the TRIGj bit when the hardware trigger j is detected, where j = 0, 1,2. + */ +__attribute__((always_inline)) static inline void MftReg_SetSynConfHwTrigMode(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNCONF; + + tmp &= ~MFT_SYNCONF_HWTRIGMODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SYNCONF_HWTRIGMODE_SHIFT)) & MFT_SYNCONF_HWTRIGMODE_MASK); + obj->SYNCONF = tmp; +} + +/*! \brief Gets the Pair Channels 3 Inverting Enable + * + * This function gets the current Pair Channels 3 Inverting Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Pair Channels 3 Inverting Enable + * - 0b : Inverting is disabled. + * - 1b : Inverting is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetInvCtrlInv3En(const MftRegType *obj) +{ + return ((obj->INVCTRL & MFT_INVCTRL_INV3EN_MASK) >> MFT_INVCTRL_INV3EN_SHIFT); +} + +/*! \brief Sets the Pair Channels 3 Inverting Enable + * + * This function sets the Pair Channels 3 Inverting Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Pair Channels 3 Inverting Enable + * - 0b : Inverting is disabled. + * - 1b : Inverting is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetInvCtrlInv3En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->INVCTRL; + + tmp &= ~MFT_INVCTRL_INV3EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_INVCTRL_INV3EN_SHIFT)) & MFT_INVCTRL_INV3EN_MASK); + obj->INVCTRL = tmp; +} + +/*! \brief Gets the Pair Channels 2 Inverting Enable + * + * This function gets the current Pair Channels 2 Inverting Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Pair Channels 2 Inverting Enable + * - 0b : Inverting is disabled. + * - 1b : Inverting is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetInvCtrlInv2En(const MftRegType *obj) +{ + return ((obj->INVCTRL & MFT_INVCTRL_INV2EN_MASK) >> MFT_INVCTRL_INV2EN_SHIFT); +} + +/*! \brief Sets the Pair Channels 2 Inverting Enable + * + * This function sets the Pair Channels 2 Inverting Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Pair Channels 2 Inverting Enable + * - 0b : Inverting is disabled. + * - 1b : Inverting is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetInvCtrlInv2En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->INVCTRL; + + tmp &= ~MFT_INVCTRL_INV2EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_INVCTRL_INV2EN_SHIFT)) & MFT_INVCTRL_INV2EN_MASK); + obj->INVCTRL = tmp; +} + +/*! \brief Gets the Pair Channels 1 Inverting Enable + * + * This function gets the current Pair Channels 1 Inverting Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Pair Channels 1 Inverting Enable + * - 0b : Inverting is disabled. + * - 1b : Inverting is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetInvCtrlInv1En(const MftRegType *obj) +{ + return ((obj->INVCTRL & MFT_INVCTRL_INV1EN_MASK) >> MFT_INVCTRL_INV1EN_SHIFT); +} + +/*! \brief Sets the Pair Channels 1 Inverting Enable + * + * This function sets the Pair Channels 1 Inverting Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Pair Channels 1 Inverting Enable + * - 0b : Inverting is disabled. + * - 1b : Inverting is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetInvCtrlInv1En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->INVCTRL; + + tmp &= ~MFT_INVCTRL_INV1EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_INVCTRL_INV1EN_SHIFT)) & MFT_INVCTRL_INV1EN_MASK); + obj->INVCTRL = tmp; +} + +/*! \brief Gets the Pair Channels 0 Inverting Enable + * + * This function gets the current Pair Channels 0 Inverting Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Pair Channels 0 Inverting Enable + * - 0b : Inverting is disabled. + * - 1b : Inverting is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetInvCtrlInv0En(const MftRegType *obj) +{ + return ((obj->INVCTRL & MFT_INVCTRL_INV0EN_MASK) >> MFT_INVCTRL_INV0EN_SHIFT); +} + +/*! \brief Sets the Pair Channels 0 Inverting Enable + * + * This function sets the Pair Channels 0 Inverting Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Pair Channels 0 Inverting Enable + * - 0b : Inverting is disabled. + * - 1b : Inverting is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetInvCtrlInv0En(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->INVCTRL; + + tmp &= ~MFT_INVCTRL_INV0EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_INVCTRL_INV0EN_SHIFT)) & MFT_INVCTRL_INV0EN_MASK); + obj->INVCTRL = tmp; +} + +/*! \brief Gets the Channel 7 Software Output Control Value + * + * This function gets the current Channel 7 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 7 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh7Ocv(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH7OCV_MASK) >> MFT_SWOCTRL_CH7OCV_SHIFT); +} + +/*! \brief Sets the Channel 7 Software Output Control Value + * + * This function sets the Channel 7 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 7 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh7Ocv(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH7OCV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH7OCV_SHIFT)) & MFT_SWOCTRL_CH7OCV_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 6 Software Output Control Value + * + * This function gets the current Channel 6 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 6 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh6Ocv(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH6OCV_MASK) >> MFT_SWOCTRL_CH6OCV_SHIFT); +} + +/*! \brief Sets the Channel 6 Software Output Control Value + * + * This function sets the Channel 6 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 6 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh6Ocv(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH6OCV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH6OCV_SHIFT)) & MFT_SWOCTRL_CH6OCV_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 5 Software Output Control Value + * + * This function gets the current Channel 5 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 5 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh5Ocv(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH5OCV_MASK) >> MFT_SWOCTRL_CH5OCV_SHIFT); +} + +/*! \brief Sets the Channel 5 Software Output Control Value + * + * This function sets the Channel 5 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 5 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh5Ocv(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH5OCV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH5OCV_SHIFT)) & MFT_SWOCTRL_CH5OCV_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 4 Software Output Control Value + * + * This function gets the current Channel 4 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 4 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh4Ocv(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH4OCV_MASK) >> MFT_SWOCTRL_CH4OCV_SHIFT); +} + +/*! \brief Sets the Channel 4 Software Output Control Value + * + * This function sets the Channel 4 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 4 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh4Ocv(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH4OCV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH4OCV_SHIFT)) & MFT_SWOCTRL_CH4OCV_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 3 Software Output Control Value + * + * This function gets the current Channel 3 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 3 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh3Ocv(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH3OCV_MASK) >> MFT_SWOCTRL_CH3OCV_SHIFT); +} + +/*! \brief Sets the Channel 3 Software Output Control Value + * + * This function sets the Channel 3 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 3 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh3Ocv(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH3OCV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH3OCV_SHIFT)) & MFT_SWOCTRL_CH3OCV_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 2 Software Output Control Value + * + * This function gets the current Channel 2 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 2 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh2Ocv(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH2OCV_MASK) >> MFT_SWOCTRL_CH2OCV_SHIFT); +} + +/*! \brief Sets the Channel 2 Software Output Control Value + * + * This function sets the Channel 2 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 2 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh2Ocv(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH2OCV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH2OCV_SHIFT)) & MFT_SWOCTRL_CH2OCV_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 1 Software Output Control Value + * + * This function gets the current Channel 1 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 1 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh1Ocv(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH1OCV_MASK) >> MFT_SWOCTRL_CH1OCV_SHIFT); +} + +/*! \brief Sets the Channel 1 Software Output Control Value + * + * This function sets the Channel 1 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 1 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh1Ocv(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH1OCV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH1OCV_SHIFT)) & MFT_SWOCTRL_CH1OCV_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 0 Software Output Control Value + * + * This function gets the current Channel 0 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 0 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh0Ocv(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH0OCV_MASK) >> MFT_SWOCTRL_CH0OCV_SHIFT); +} + +/*! \brief Sets the Channel 0 Software Output Control Value + * + * This function sets the Channel 0 Software Output Control Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 0 Software Output Control Value + * - 0b : The software output control forces 0 to the channel output. + * - 1b : The software output control forces 1 to the channel output. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh0Ocv(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH0OCV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH0OCV_SHIFT)) & MFT_SWOCTRL_CH0OCV_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 7 Software Output Control Enable + * + * This function gets the current Channel 7 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 7 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh7Oc(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH7OC_MASK) >> MFT_SWOCTRL_CH7OC_SHIFT); +} + +/*! \brief Sets the Channel 7 Software Output Control Enable + * + * This function sets the Channel 7 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 7 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh7Oc(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH7OC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH7OC_SHIFT)) & MFT_SWOCTRL_CH7OC_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 6 Software Output Control Enable + * + * This function gets the current Channel 6 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 6 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh6Oc(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH6OC_MASK) >> MFT_SWOCTRL_CH6OC_SHIFT); +} + +/*! \brief Sets the Channel 6 Software Output Control Enable + * + * This function sets the Channel 6 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 6 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh6Oc(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH6OC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH6OC_SHIFT)) & MFT_SWOCTRL_CH6OC_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 5 Software Output Control Enable + * + * This function gets the current Channel 5 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 5 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh5Oc(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH5OC_MASK) >> MFT_SWOCTRL_CH5OC_SHIFT); +} + +/*! \brief Sets the Channel 5 Software Output Control Enable + * + * This function sets the Channel 5 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 5 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh5Oc(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH5OC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH5OC_SHIFT)) & MFT_SWOCTRL_CH5OC_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 4 Software Output Control Enable + * + * This function gets the current Channel 4 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 4 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh4Oc(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH4OC_MASK) >> MFT_SWOCTRL_CH4OC_SHIFT); +} + +/*! \brief Sets the Channel 4 Software Output Control Enable + * + * This function sets the Channel 4 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 4 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh4Oc(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH4OC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH4OC_SHIFT)) & MFT_SWOCTRL_CH4OC_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 3 Software Output Control Enable + * + * This function gets the current Channel 3 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 3 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh3Oc(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH3OC_MASK) >> MFT_SWOCTRL_CH3OC_SHIFT); +} + +/*! \brief Sets the Channel 3 Software Output Control Enable + * + * This function sets the Channel 3 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 3 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh3Oc(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH3OC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH3OC_SHIFT)) & MFT_SWOCTRL_CH3OC_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 2 Software Output Control Enable + * + * This function gets the current Channel 2 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 2 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh2Oc(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH2OC_MASK) >> MFT_SWOCTRL_CH2OC_SHIFT); +} + +/*! \brief Sets the Channel 2 Software Output Control Enable + * + * This function sets the Channel 2 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 2 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh2Oc(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH2OC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH2OC_SHIFT)) & MFT_SWOCTRL_CH2OC_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 1 Software Output Control Enable + * + * This function gets the current Channel 1 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 1 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh1Oc(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH1OC_MASK) >> MFT_SWOCTRL_CH1OC_SHIFT); +} + +/*! \brief Sets the Channel 1 Software Output Control Enable + * + * This function sets the Channel 1 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 1 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh1Oc(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH1OC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH1OC_SHIFT)) & MFT_SWOCTRL_CH1OC_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Gets the Channel 0 Software Output Control Enable + * + * This function gets the current Channel 0 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 0 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSwOCtrlCh0Oc(const MftRegType *obj) +{ + return ((obj->SWOCTRL & MFT_SWOCTRL_CH0OC_MASK) >> MFT_SWOCTRL_CH0OC_SHIFT); +} + +/*! \brief Sets the Channel 0 Software Output Control Enable + * + * This function sets the Channel 0 Software Output Control Enable. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 0 Software Output Control Enable + * - 0b : The channel output is not affected by software output control. + * - 1b : The channel output is affected by software output control. + */ +__attribute__((always_inline)) static inline void MftReg_SetSwOCtrlCh0Oc(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SWOCTRL; + + tmp &= ~MFT_SWOCTRL_CH0OC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SWOCTRL_CH0OC_SHIFT)) & MFT_SWOCTRL_CH0OC_MASK); + obj->SWOCTRL = tmp; +} + +/*! \brief Sets the Global Load OK + * + * This function sets the Global Load OK. + * This bit controls the global load mechanism. + * It generates a pulse at MFT module global load output with one MFT clock cycle width, + * which is used to set LDOK bits of MFT and other modules (including other MFTs). + * This bit is self-cleared and read value is always zero. + * The global load mechanism depends on SoC specific information. Refer to MFT SoC specific information to more details. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Global Load OK + * - 0b : No action. + * - 1b : LDOK bit is set. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadGLdOk(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_GLDOK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_GLDOK_SHIFT)) & MFT_PWMLOAD_GLDOK_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Global Load Enable + * + * This function gets the current Global Load Enable. + * This bit enables the global load mechanism implemented by GLDOK. If GLEN bit is set, then an external + * event on the MFT global load input sets the LDOK bit. The clear of the LDOK bit is done by CPU writes '0' + * to the bit. + * + * \param[in] obj : pointer to MFT register instance + * \return Global Load Enable + * - 0b : Global Load Ok disabled. + * - 1b : Global Load OK enabled. A pulse event on the module global load input sets the LDOK bit. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadGLEn(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_GLEN_MASK) >> MFT_PWMLOAD_GLEN_SHIFT); +} + +/*! \brief Sets the Global Load Enable + * + * This function sets the Global Load Enable. + * This bit enables the global load mechanism implemented by GLDOK. If GLEN bit is set, then an external + * event on the MFT global load input sets the LDOK bit. The clear of the LDOK bit is done by CPU writes '0' + * to the bit. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Global Load Enable + * - 0b : Global Load Ok disabled. + * - 1b : Global Load OK enabled. A pulse event on the module global load input sets the LDOK bit. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadGLEn(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_GLEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_GLEN_SHIFT)) & MFT_PWMLOAD_GLEN_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Load Enable + * + * This function gets the current Load Enable. + * Enables the loading of the MOD, CNTIN, HCR and CV registers with the values of their buffers. + * The LDOK bit can also be set by the Global Load mechanism if GLEN bit is enabled. + * + * \param[in] obj : pointer to MFT register instance + * \return Load Enable + * - 0b : Loading updated values is disabled. + * - 1b : Loading updated values is enabled. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadLdOk(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_LDOK_MASK) >> MFT_PWMLOAD_LDOK_SHIFT); +} + +/*! \brief Sets the Load Enable + * + * This function sets the Load Enable. + * Enables the loading of the MOD, CNTIN, HCR and CV registers with the values of their buffers. + * The LDOK bit can also be set by the Global Load mechanism if GLEN bit is enabled. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Load Enable + * - 0b : Loading updated values is disabled. + * - 1b : Loading updated values is enabled. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadLdOk(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_LDOK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_LDOK_SHIFT)) & MFT_PWMLOAD_LDOK_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Half Cycle Select + * + * This function gets the current Half Cycle Select. + * This bit enables the half cycle match as a reload oportunity. A half cycle is defined by when the MFT + * counter matches the HCR register. + * + * \param[in] obj : pointer to MFT register instance + * \return Half Cycle Select + * - 0b : Half cycle reload is disabled and it is not considered as a reload opportunity. + * - 1b : Half cycle reload is enabled and it is considered as a reload opportunity. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadHCSel(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_HCSEL_MASK) >> MFT_PWMLOAD_HCSEL_SHIFT); +} + +/*! \brief Sets the Half Cycle Select + * + * This function sets the Half Cycle Select. + * This bit enables the half cycle match as a reload oportunity. A half cycle is defined by when the MFT + * counter matches the HCR register. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Half Cycle Select + * - 0b : Half cycle reload is disabled and it is not considered as a reload opportunity. + * - 1b : Half cycle reload is enabled and it is considered as a reload opportunity. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadHCSel(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_HCSEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_HCSEL_SHIFT)) & MFT_PWMLOAD_HCSEL_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Channel 7 Select + * + * This function gets the current Channel 7 Select. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 7 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadCh7Sel(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_CH7SEL_MASK) >> MFT_PWMLOAD_CH7SEL_SHIFT); +} + +/*! \brief Sets the Channel 7 Select + * + * This function sets the Channel 7 Select. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 7 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadCh7Sel(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_CH7SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_CH7SEL_SHIFT)) & MFT_PWMLOAD_CH7SEL_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Channel 6 Select + * + * This function gets the current Channel 6 Select. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 6 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadCh6Sel(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_CH6SEL_MASK) >> MFT_PWMLOAD_CH6SEL_SHIFT); +} + +/*! \brief Sets the Channel 6 Select + * + * This function sets the Channel 6 Select. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 6 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadCh6Sel(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_CH6SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_CH6SEL_SHIFT)) & MFT_PWMLOAD_CH6SEL_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Channel 5 Select + * + * This function gets the current Channel 5 Select. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 5 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadCh5Sel(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_CH5SEL_MASK) >> MFT_PWMLOAD_CH5SEL_SHIFT); +} + +/*! \brief Sets the Channel 5 Select + * + * This function sets the Channel 5 Select. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 5 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadCh5Sel(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_CH5SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_CH5SEL_SHIFT)) & MFT_PWMLOAD_CH5SEL_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Channel 4 Select + * + * This function gets the current Channel 4 Select. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 4 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadCh4Sel(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_CH4SEL_MASK) >> MFT_PWMLOAD_CH4SEL_SHIFT); +} + +/*! \brief Sets the Channel 4 Select + * + * This function sets the Channel 4 Select. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 4 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadCh4Sel(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_CH4SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_CH4SEL_SHIFT)) & MFT_PWMLOAD_CH4SEL_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Channel 3 Select + * + * This function gets the current Channel 3 Select. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 3 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadCh3Sel(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_CH3SEL_MASK) >> MFT_PWMLOAD_CH3SEL_SHIFT); +} + +/*! \brief Sets the Channel 3 Select + * + * This function sets the Channel 3 Select. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 3 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadCh3Sel(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_CH3SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_CH3SEL_SHIFT)) & MFT_PWMLOAD_CH3SEL_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Channel 2 Select + * + * This function gets the current Channel 2 Select. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 2 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadCh2Sel(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_CH2SEL_MASK) >> MFT_PWMLOAD_CH2SEL_SHIFT); +} + +/*! \brief Sets the Channel 2 Select + * + * This function sets the Channel 2 Select. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 2 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadCh2Sel(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_CH2SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_CH2SEL_SHIFT)) & MFT_PWMLOAD_CH2SEL_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Channel 1 Select + * + * This function gets the current Channel 1 Select. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 1 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadCh1Sel(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_CH1SEL_MASK) >> MFT_PWMLOAD_CH1SEL_SHIFT); +} + +/*! \brief Sets the Channel 1 Select + * + * This function sets the Channel 1 Select. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 1 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadCh1Sel(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_CH1SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_CH1SEL_SHIFT)) & MFT_PWMLOAD_CH1SEL_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Channel 0 Select + * + * This function gets the current Channel 0 Select. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel 0 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPwmLoadCh0Sel(const MftRegType *obj) +{ + return ((obj->PWMLOAD & MFT_PWMLOAD_CH0SEL_MASK) >> MFT_PWMLOAD_CH0SEL_SHIFT); +} + +/*! \brief Sets the Channel 0 Select + * + * This function sets the Channel 0 Select. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel 0 Select + * - 0b : Channel match is not included as a reload opportunity. + * - 1b : Channel match is included as a reload opportunity. + */ +__attribute__((always_inline)) static inline void MftReg_SetPwmLoadCh0Sel(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWMLOAD; + + tmp &= ~MFT_PWMLOAD_CH0SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PWMLOAD_CH0SEL_SHIFT)) & MFT_PWMLOAD_CH0SEL_MASK); + obj->PWMLOAD = tmp; +} + +/*! \brief Gets the Half Cycle Value + * + * This function gets the current Half Cycle Value. + * + * \param[in] obj : pointer to MFT register instance + * \return Half Cycle Value + */ +__attribute__((always_inline)) static inline uint16_t MftReg_GetHcrHCVal(const MftRegType *obj) +{ + return ((obj->HCR & MFT_HCR_HCVAL_MASK) >> MFT_HCR_HCVAL_SHIFT); +} + +/*! \brief Sets the Half Cycle Value + * + * This function sets the Half Cycle Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Half Cycle Value + */ +__attribute__((always_inline)) static inline void MftReg_SetHcrHCVal(MftRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->HCR; + + tmp &= ~MFT_HCR_HCVAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_HCR_HCVAL_SHIFT)) & MFT_HCR_HCVAL_MASK); + obj->HCR = tmp; +} + +/*! \brief Gets the Extended Deadtime Value + * + * This function gets the current Extended Deadtime Value. + * This field is a bit extension of the DTVAL field. It defines the 4 most significant bits of the deadtime value. + * The maximum deadtime value is extended to 1023 using the concatenation {DTVALEX, DTVAL}. + * Deadtime insert value = (DTPS * {DTVALEX, DTVAL}). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] pairIndex : the pair index + * \return Extended Deadtime Value + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPairDeadTimeDtValEx(const MftRegType *obj, uint8_t pairIndex) +{ + return ((obj->PAIR[pairIndex].DEADTIME & MFT_PAIR_DEADTIME_DTVALEX_MASK) >> MFT_PAIR_DEADTIME_DTVALEX_SHIFT); +} + +/*! \brief Sets the Extended Deadtime Value + * + * This function sets the Extended Deadtime Value. + * This field is a bit extension of the DTVAL field. It defines the 4 most significant bits of the deadtime value. + * The maximum deadtime value is extended to 1023 using the concatenation {DTVALEX, DTVAL}. + * Deadtime insert value = (DTPS * {DTVALEX, DTVAL}). + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] pairIndex : the pair index + * \param[in] value : the value of Extended Deadtime Value + */ +__attribute__((always_inline)) static inline void MftReg_SetPairDeadTimeDtValEx(MftRegType *obj, uint8_t pairIndex, uint8_t value) +{ + uint32_t tmp = obj->PAIR[pairIndex].DEADTIME; + + tmp &= ~MFT_PAIR_DEADTIME_DTVALEX_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PAIR_DEADTIME_DTVALEX_SHIFT)) & MFT_PAIR_DEADTIME_DTVALEX_MASK); + obj->PAIR[pairIndex].DEADTIME = tmp; +} + +/*! \brief Gets the Deadtime Prescaler Value + * + * This function gets the current Deadtime Prescaler Value. + * Selects the division factor of the MFT input clock. This prescaled clock is used by the deadtime counter. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] pairIndex : the pair index + * \return Deadtime Prescaler Value + * - 0xb : Divide the MFT input clock by 1. + * - 10b : Divide the MFT input clock by 4. + * - 11b : Divide the MFT input clock by 16. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPairDeadTimeDtPs(const MftRegType *obj, uint8_t pairIndex) +{ + return ((obj->PAIR[pairIndex].DEADTIME & MFT_PAIR_DEADTIME_DTPS_MASK) >> MFT_PAIR_DEADTIME_DTPS_SHIFT); +} + +/*! \brief Sets the Deadtime Prescaler Value + * + * This function sets the Deadtime Prescaler Value. + * Selects the division factor of the MFT input clock. This prescaled clock is used by the deadtime counter. + * This field is write protected. It can be written only when MODE[WPDIS] = 1. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] pairIndex : the pair index + * \param[in] value : the value of Deadtime Prescaler Value + * - 0xb : Divide the MFT input clock by 1. + * - 10b : Divide the MFT input clock by 4. + * - 11b : Divide the MFT input clock by 16. + */ +__attribute__((always_inline)) static inline void MftReg_SetPairDeadTimeDtPs(MftRegType *obj, uint8_t pairIndex, uint8_t value) +{ + uint32_t tmp = obj->PAIR[pairIndex].DEADTIME; + + tmp &= ~MFT_PAIR_DEADTIME_DTPS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PAIR_DEADTIME_DTPS_SHIFT)) & MFT_PAIR_DEADTIME_DTPS_MASK); + obj->PAIR[pairIndex].DEADTIME = tmp; +} + +/*! \brief Gets the Deadtime Value + * + * This function gets the current Deadtime Value. + * Selects the deadtime value. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] pairIndex : the pair index + * \return Deadtime Value + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetPairDeadTimeDtVal(const MftRegType *obj, uint8_t pairIndex) +{ + return ((obj->PAIR[pairIndex].DEADTIME & MFT_PAIR_DEADTIME_DTVAL_MASK) >> MFT_PAIR_DEADTIME_DTVAL_SHIFT); +} + +/*! \brief Sets the Deadtime Value + * + * This function sets the Deadtime Value. + * Selects the deadtime value. + * This field is write protected. It can be written only when MODE[WPDIS] = 1 + * + * \param[in] obj : pointer to MFT register instance + * \param[in] pairIndex : the pair index + * \param[in] value : the value of Deadtime Value + */ +__attribute__((always_inline)) static inline void MftReg_SetPairDeadTimeDtVal(MftRegType *obj, uint8_t pairIndex, uint8_t value) +{ + uint32_t tmp = obj->PAIR[pairIndex].DEADTIME; + + tmp &= ~MFT_PAIR_DEADTIME_DTVAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_PAIR_DEADTIME_DTVAL_SHIFT)) & MFT_PAIR_DEADTIME_DTVAL_MASK); + obj->PAIR[pairIndex].DEADTIME = tmp; +} + +/*! \brief Gets the Mirror of the Modulo Integer Value + * + * This function gets the current Mirror of the Modulo Integer Value. + * See the field MOD of the register MOD + * + * \param[in] obj : pointer to MFT register instance + * \return Mirror of the Modulo Integer Value + */ +__attribute__((always_inline)) static inline uint16_t MftReg_GetModMirrorModM(const MftRegType *obj) +{ + return ((obj->MOD_MIRROR & MFT_MOD_MIRROR_MOD_M_MASK) >> MFT_MOD_MIRROR_MOD_M_SHIFT); +} + +/*! \brief Sets the Mirror of the Modulo Integer Value + * + * This function sets the Mirror of the Modulo Integer Value. + * See the field MOD of the register MOD + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Mirror of the Modulo Integer Value + */ +__attribute__((always_inline)) static inline void MftReg_SetModMirrorModM(MftRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->MOD_MIRROR; + + tmp &= ~MFT_MOD_MIRROR_MOD_M_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_MOD_MIRROR_MOD_M_SHIFT)) & MFT_MOD_MIRROR_MOD_M_MASK); + obj->MOD_MIRROR = tmp; +} + +/*! \brief Gets the Modulo Fractional Value + * + * This function gets the current Modulo Fractional Value. + * The modulo fractional value is used in the PWM period dithering. + * This value is added to an internal accumulator at the end of each PWM period. + * Writes to the field FRACMOD are done on its write buffer. + * The FRACMOD is updated with its write buffer value according to Registers updated from write buffers. + * If MFTEN = 0, a write to SC register resets manually this write coherency mechanism + * + * \param[in] obj : pointer to MFT register instance + * \return Modulo Fractional Value + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetModMirrorFracModM(const MftRegType *obj) +{ + return ((obj->MOD_MIRROR & MFT_MOD_MIRROR_FRACMOD_M_MASK) >> MFT_MOD_MIRROR_FRACMOD_M_SHIFT); +} + +/*! \brief Sets the Modulo Fractional Value + * + * This function sets the Modulo Fractional Value. + * The modulo fractional value is used in the PWM period dithering. + * This value is added to an internal accumulator at the end of each PWM period. + * Writes to the field FRACMOD are done on its write buffer. + * The FRACMOD is updated with its write buffer value according to Registers updated from write buffers. + * If MFTEN = 0, a write to SC register resets manually this write coherency mechanism + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Modulo Fractional Value + */ +__attribute__((always_inline)) static inline void MftReg_SetModMirrorFracModM(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MOD_MIRROR; + + tmp &= ~MFT_MOD_MIRROR_FRACMOD_M_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_MOD_MIRROR_FRACMOD_M_SHIFT)) & MFT_MOD_MIRROR_FRACMOD_M_MASK); + obj->MOD_MIRROR = tmp; +} + +/*! \brief Gets the Mirror of the Channel Match Integer Value + * + * This function gets the current Mirror of the Channel Match Integer Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Mirror of the Channel Match Integer Value + */ +__attribute__((always_inline)) static inline uint16_t MftReg_GetCvMirrorValM(const MftRegType *obj, uint8_t channel) +{ + return ((obj->MIRROR[channel].CV & MFT_CV_MIRROR_VAL_M_MASK) >> MFT_CV_MIRROR_VAL_M_SHIFT); +} + +/*! \brief Sets the Mirror of the Channel Match Integer Value + * + * This function sets the Mirror of the Channel Match Integer Value. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of Mirror of the Channel Match Integer Value + */ +__attribute__((always_inline)) static inline void MftReg_SetCvMirrorValM(MftRegType *obj, uint8_t channel, uint16_t value) +{ + uint32_t tmp = obj->MIRROR[channel].CV; + + tmp &= ~MFT_CV_MIRROR_VAL_M_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CV_MIRROR_VAL_M_SHIFT)) & MFT_CV_MIRROR_VAL_M_MASK); + obj->MIRROR[channel].CV = tmp; +} + +/*! \brief Gets the Channel Match Fractional Value + * + * This function gets the current Channel Match Fractional Value. + * The channel match fractional value is used in the PWM edge dithering. + * This value is added to the channel internal accumulator at the end of each PWM period. + * Writes to the field FRACVAL are done on its write buffer. + * The FRACVAL is updated with its write buffer value according to Registers updated from write buffers. + * If MFTEN = 0, a write to CnSC register resets manually this write coherency mechanism + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \return Channel Match Fractional Value + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetCvMirrorFracVal(const MftRegType *obj, uint8_t channel) +{ + return ((obj->MIRROR[channel].CV & MFT_CV_MIRROR_FRACVAL_MASK) >> MFT_CV_MIRROR_FRACVAL_SHIFT); +} + +/*! \brief Sets the Channel Match Fractional Value + * + * This function sets the Channel Match Fractional Value. + * The channel match fractional value is used in the PWM edge dithering. + * This value is added to the channel internal accumulator at the end of each PWM period. + * Writes to the field FRACVAL are done on its write buffer. + * The FRACVAL is updated with its write buffer value according to Registers updated from write buffers. + * If MFTEN = 0, a write to CnSC register resets manually this write coherency mechanism + * + * \param[in] obj : pointer to MFT register instance + * \param[in] channel : the channel index + * \param[in] value : the value of Channel Match Fractional Value + */ +__attribute__((always_inline)) static inline void MftReg_SetCvMirrorFracVal(MftRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->MIRROR[channel].CV; + + tmp &= ~MFT_CV_MIRROR_FRACVAL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_CV_MIRROR_FRACVAL_SHIFT)) & MFT_CV_MIRROR_FRACVAL_MASK); + obj->MIRROR[channel].CV = tmp; +} + +/*! \brief Gets the Channel Output Enable Signal + * + * This function gets the current Channel Output Enable Signal. + * + * \param[in] obj : pointer to MFT register instance + * \return Channel Output Enable Signal + * - 0b : The MFT channel output is put to safe state when the MFT counter is enabled and the MFT + * channel output is enabled by Fault Control (MFT_MODE[FAULTM]!=2'b00 and + * MFT_FLTCTRL[FSTATE]=1'b0) and PWM is enabled (MFT_SC[PWMENn] = 1'b1). + * Otherwise the channel output is tristated. + * - 1b : The MFT channel output state is retained when the channel is in output mode. + * The output channel is tristated when the channel is in input capture [DECAPEN=1'b0, COMBINE=1'b0, + * MSnB:MSnA=2'b00] or dual edge capture mode [DECAPEN=1'b1]. + */ +__attribute__((always_inline)) static inline uint8_t MftReg_GetSimObeObe(const MftRegType *obj) +{ + return ((obj->SIM_OBE & MFT_SIM_OBE_OBE_MASK) >> MFT_SIM_OBE_OBE_SHIFT); +} + +/*! \brief Sets the Channel Output Enable Signal + * + * This function sets the Channel Output Enable Signal. + * + * \param[in] obj : pointer to MFT register instance + * \param[in] value : the value of Channel Output Enable Signal + * - 0b : The MFT channel output is put to safe state when the MFT counter is enabled and the MFT + * channel output is enabled by Fault Control (MFT_MODE[FAULTM]!=2'b00 and + * MFT_FLTCTRL[FSTATE]=1'b0) and PWM is enabled (MFT_SC[PWMENn] = 1'b1). Otherwise the + * channel output is tristated. + * - 1b : The MFT channel output state is retained when the channel is in output mode. The output + * channel is tristated when the channel is in input capture [DECAPEN=1'b0, COMBINE=1'b0, + * MSnB:MSnA=2'b00] or dual edge capture mode [DECAPEN=1'b1]. + */ +__attribute__((always_inline)) static inline void MftReg_SetSimObeObe(MftRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SIM_OBE; + + tmp &= ~MFT_SIM_OBE_OBE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << MFT_SIM_OBE_OBE_SHIFT)) & MFT_SIM_OBE_OBE_MASK); + obj->SIM_OBE = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _MFT_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/mpu_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/mpu_reg.h new file mode 100644 index 0000000..8c3da35 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/mpu_reg.h @@ -0,0 +1,1082 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MPU_REG_H_ +#define _MPU_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the MPU Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +/* Error Value */ +#define MPU_RES_ERR (0xFFu) +/* Size of Reserved Registers Arrays */ +#define MPU_REG_EADR_RESEERVED_CONUT (3) +#define MPU_REG_RGDN_RESEERVED_CONUT (0x38) +#define MPU_REG_AACN_RESEERVED_CONUT (0x20) + + +/* Size of Slave Port Arrays */ +#define MPU_SLVPORT_COUNT (2) + +/* Size of Region Descption Arrays */ +#define MPU_REGIONDESC_COUNT (8) + +/* Size of Region Descption Alternate Access Control Arrays */ +#define MPU_REGIONDESCAAC_COUNT (8) + +/* Slave Port Number Set */ +#define MPU_SLVPORT3 (3) +#define MPU_SLVPORT2 (2) +#define MPU_SLVPORT1 (1) +#define MPU_SLVPORT0 (0) + +/* CESR Bit Fields */ +#define MPU_CESR_VLD_MASK (0x1u) +#define MPU_CESR_VLD_SHIFT (0u) +#define MPU_CESR_VLD_WIDTH (1u) +#define MPU_CESR_NRGD_MASK (0xF00u) +#define MPU_CESR_NRGD_SHIFT (8u) +#define MPU_CESR_NRGD_WIDTH (4u) +#define MPU_CESR_NSP_MASK (0xF000u) +#define MPU_CESR_NSP_SHIFT (12u) +#define MPU_CESR_NSP_WIDTH (4u) +#define MPU_CESR_HRL_MASK (0xF0000u) +#define MPU_CESR_HRL_SHIFT (16u) +#define MPU_CESR_HRL_WIDTH (4u) +#define MPU_CESR_SPERR3_MASK (0x10000000u) +#define MPU_CESR_SPERR3_SHIFT (28u) +#define MPU_CESR_SPERR3_WIDTH (1u) +#define MPU_CESR_SPERR2_MASK (0x20000000u) +#define MPU_CESR_SPERR2_SHIFT (29u) +#define MPU_CESR_SPERR2_WIDTH (1u) +#define MPU_CESR_SPERR1_MASK (0x40000000u) +#define MPU_CESR_SPERR1_SHIFT (30u) +#define MPU_CESR_SPERR1_WIDTH (1u) +#define MPU_CESR_SPERR0_MASK (0x80000000u) +#define MPU_CESR_SPERR0_SHIFT (31u) +#define MPU_CESR_SPERR0_WIDTH (1u) + +/* EARn(0~3) Bit Fields */ +#define MPU_EAR_EADDR_MASK (0xFFFFFFFFu) +#define MPU_EAR_EADDR_SHIFT (0u) +#define MPU_EAR_EADDR_WIDTH (32u) + +/* EDRn(0~3) Bit Fields */ +#define MPU_EDR_ERW_MASK (0x1u) +#define MPU_EDR_ERW_SHIFT (0u) +#define MPU_EDR_ERW_WIDTH (1u) +#define MPU_EDR_EATTR_MASK (0xEu) +#define MPU_EDR_EATTR_SHIFT (1u) +#define MPU_EDR_EATTR_WIDTH (3u) +#define MPU_EDR_EMN_MASK (0xF0u) +#define MPU_EDR_EMN_SHIFT (4u) +#define MPU_EDR_EMN_WIDTH (4u) +#define MPU_EDR_EPID_MASK (0xFF00u) +#define MPU_EDR_EPID_SHIFT (8u) +#define MPU_EDR_EPID_WIDTH (8u) +#define MPU_EDR_EACD_MASK (0xFFFF0000u) +#define MPU_EDR_EACD_SHIFT (16u) +#define MPU_EDR_EACD_WIDTH (16u) + +/* RGDn_WD0(0~15) Bit Fields */ +#define MPU_RGD_WD0_SRTADDR_MASK (0xFFFFFFE0u) +#define MPU_RGD_WD0_SRTADDR_SHIFT (0u) +#define MPU_RGD_WD0_SRTADDR_WIDTH (27u) + +/* RGDn_WD1(0~15) Bit Fields */ +#define MPU_RGD_WD1_ENDADDR_MASK (0xFFFFFFE0u) +#define MPU_RGD_WD1_ENDADDR_SHIFT (0u) +#define MPU_RGD_WD1_ENDADDR_WIDTH (27u) + +/* RGDn_WD2(0~15) Bit Fields */ +#define MPU_RGD_WD2_M0UM_MASK (0x7u) +#define MPU_RGD_WD2_M0UM_SHIFT (0u) +#define MPU_RGD_WD2_M0UM_WIDTH (3u) +#define MPU_RGD_WD2_M0SM_MASK (0x18u) +#define MPU_RGD_WD2_M0SM_SHIFT (3u) +#define MPU_RGD_WD2_M0SM_WIDTH (2u) +#define MPU_RGD_WD2_M0PE_MASK (0x20u) +#define MPU_RGD_WD2_M0PE_SHIFT (5u) +#define MPU_RGD_WD2_M0PE_WIDTH (1u) +#define MPU_RGD_WD2_M1UM_MASK (0x1C0u) +#define MPU_RGD_WD2_M1UM_SHIFT (6u) +#define MPU_RGD_WD2_M1UM_WIDTH (3u) +#define MPU_RGD_WD2_M1SM_MASK (0x600u) +#define MPU_RGD_WD2_M1SM_SHIFT (9u) +#define MPU_RGD_WD2_M1SM_WIDTH (2u) +#define MPU_RGD_WD2_M1PE_MASK (0x800u) +#define MPU_RGD_WD2_M1PE_SHIFT (11u) +#define MPU_RGD_WD2_M1PE_WIDTH (1u) +#define MPU_RGD_WD2_M2UM_MASK (0x7000u) +#define MPU_RGD_WD2_M2UM_SHIFT (12u) +#define MPU_RGD_WD2_M2UM_WIDTH (3u) +#define MPU_RGD_WD2_M2SM_MASK (0x18000u) +#define MPU_RGD_WD2_M2SM_SHIFT (15u) +#define MPU_RGD_WD2_M2SM_WIDTH (2u) +#define MPU_RGD_WD2_M3UM_MASK (0x1C0000u) +#define MPU_RGD_WD2_M3UM_SHIFT (18u) +#define MPU_RGD_WD2_M3UM_WIDTH (3u) +#define MPU_RGD_WD2_M3SM_MASK (0x600000u) +#define MPU_RGD_WD2_M3SM_SHIFT (21u) +#define MPU_RGD_WD2_M3SM_WIDTH (2u) + +/* RGDn_WD3(0~15) Bit Fields */ +#define MPU_RGD_WD3_VLD_MASK (0x1u) +#define MPU_RGD_WD3_VLD_SHIFT (0u) +#define MPU_RGD_WD3_VLD_WIDTH (1u) +#define MPU_RGD_WD3_PIDMASK_MASK (0xFF0000u) +#define MPU_RGD_WD3_PIDMASK_SHIFT (16u) +#define MPU_RGD_WD3_PIDMASK_WIDTH (8u) +#define MPU_RGD_WD3_PID_MASK (0xFF000000u) +#define MPU_RGD_WD3_PID_SHIFT (24u) +#define MPU_RGD_WD3_PID_WIDTH (8u) + +/* RGDAAC(0~15) Bit Fields */ +#define MPU_RGDAAC_M0UM_MASK (0x7u) +#define MPU_RGDAAC_M0UM_SHIFT (0u) +#define MPU_RGDAAC_M0UM_WIDTH (3u) +#define MPU_RGDAAC_M0SM_MASK (0x18u) +#define MPU_RGDAAC_M0SM_SHIFT (3u) +#define MPU_RGDAAC_M0SM_WIDTH (2u) +#define MPU_RGDAAC_M0PE_MASK (0x20u) +#define MPU_RGDAAC_M0PE_SHIFT (5u) +#define MPU_RGDAAC_M0PE_WIDTH (1u) +#define MPU_RGDAAC_M1UM_MASK (0x1C0u) +#define MPU_RGDAAC_M1UM_SHIFT (6u) +#define MPU_RGDAAC_M1UM_WIDTH (3u) +#define MPU_RGDAAC_M1SM_MASK (0x600u) +#define MPU_RGDAAC_M1SM_SHIFT (9u) +#define MPU_RGDAAC_M1SM_WIDTH (2u) +#define MPU_RGDAAC_M1PE_MASK (0x800u) +#define MPU_RGDAAC_M1PE_SHIFT (11u) +#define MPU_RGDAAC_M1PE_WIDTH (1u) +#define MPU_RGDAAC_M2UM_MASK (0x7000u) +#define MPU_RGDAAC_M2UM_SHIFT (12u) +#define MPU_RGDAAC_M2UM_WIDTH (3u) +#define MPU_RGDAAC_M2SM_MASK (0x18000u) +#define MPU_RGDAAC_M2SM_SHIFT (15u) +#define MPU_RGDAAC_M2SM_WIDTH (2u) +#define MPU_RGDAAC_M3UM_MASK (0x1C0000u) +#define MPU_RGDAAC_M3UM_SHIFT (18u) +#define MPU_RGDAAC_M3UM_WIDTH (3u) +#define MPU_RGDAAC_M3SM_MASK (0x600000u) +#define MPU_RGDAAC_M3SM_SHIFT (21u) +#define MPU_RGDAAC_M3SM_WIDTH (3u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of MPU registers + */ +typedef struct _MpuRegType_ +{ + volatile uint32_t CESR; /*!< Control, Error info and Mpu Enable Register, offset: 0x0 */ + uint32_t RESERVED0[MPU_REG_EADR_RESEERVED_CONUT]; /* Reserved Register, offset: 0x04, array step: 0x0C */ + struct + { /*!< offset: 0x10, array step: 0x08 */ + const volatile uint32_t EAR; /*!< Slave Port Error Register Address, offset: 0x10, array step: 0x08 */ + const volatile uint32_t EDR; /*!< Slave Port Error Detail Register, offset: 0x14, array step: 0x08 */ + } SLVPORT[MPU_SLVPORT_COUNT]; + uint32_t RESERVED1[MPU_REG_RGDN_RESEERVED_CONUT]; + struct + { /*!< offset: 0x100, array step: 0x10 */ + volatile uint32_t WORD0; /*!< Value of Access Start Register Address, offset: 0x100, array step: 0x10 */ + volatile uint32_t WORD1; /*!< Value of Access End Register Address, offset : 0x104, array step: 0x10 */ + volatile uint32_t WORD2; /*!< Configure of Master Access Rights Register, offset: 0x108, array step: 0x10 */ + volatile uint32_t WORD3; /*!< Configure of PID, PID Mask and Region Description valid, offset: 0x10C, array step: 0x10 */ + } RGD[MPU_REGIONDESC_COUNT]; + uint32_t RESERVED2[MPU_REG_AACN_RESEERVED_CONUT]; + volatile uint32_t + AAC[MPU_REGIONDESC_COUNT]; /*!< Configure of Master Alternate Access Rights Register, offset: 0x200, array step: 0x04 */ +} MpuRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ +/*! \brief Enables the MPU module. + * + * This function enables the functional of MPU module + * + * \param[in] obj : pointer to MPU register instance + * \param[in] enable State + * - 1 : Enable the MPU module. + * - 0 : Disable the MPU module. + * \return None + */ +__attribute__((always_inline)) static inline void MpuReg_GlobalEnable(MpuRegType *obj, uint8_t enable) +{ + uint32_t tmp = obj->CESR; + + tmp &= ~MPU_CESR_VLD_MASK; + tmp |= (((uint32_t)(enable ? 1u << MPU_CESR_VLD_SHIFT : 0u << MPU_CESR_VLD_SHIFT)) & MPU_CESR_VLD_MASK); + obj->CESR = tmp; +} + +/*! \brief Get MPU module status. + * + * This function get the functional of MPU module status + * + * \param[in] obj : pointer to MPU register instance + * \return MPU Global Enable valid or invalid + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetMpuGlobalEnableStatus(const MpuRegType *obj) +{ + return ((obj->CESR & MPU_CESR_VLD_MASK) >> MPU_CESR_VLD_SHIFT); +} + +/*! \brief Get Number of Region Description. + * + * This function get the Number of Region Description. + * + * \param[in] obj : pointer to MPU register instance + * \return the current command of debug mode + * - 0 : 8 of Region Description + * - 1 : 12 of Region Description + * - 2 : 16 of Region Description + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetNumOfRegionDesc(const MpuRegType *obj) +{ + return ((obj->CESR & MPU_CESR_NRGD_MASK) >> MPU_CESR_NRGD_SHIFT); +} + +/*! \brief Get Number of Slave Port. + * + * This function get the Number of Slave Port. + * + * \param[in] obj : pointer to MPU register instance + * \return the Number of Slave Port + * - 4 : default value is 4, other values are undefined + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetNumOfSlavePort(const MpuRegType *obj) +{ + return ((obj->CESR & MPU_CESR_NSP_MASK) >> MPU_CESR_NSP_SHIFT); +} + +/*! \brief Get Hardware Revision Level. + * + * This function get the Get Hardware Revision Level. + * + * \param[in] obj : pointer to MPU register instance + * \return the Hardware Revision Level + * - 1 : version of this chip + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetHwOfRevLvl(const MpuRegType *obj) +{ + return ((obj->CESR & MPU_CESR_HRL_MASK) >> MPU_CESR_HRL_SHIFT); +} + +/*! \brief Get Slave Port Error Status. + * + * This function get the Slave Port Error Status. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] port : set number of port + * \return the Hardware Revision Level + * - 1 : An error has occurred for slave port + * * - 0 : None error has occurred for slave port + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetSlvPortErrStatus(const MpuRegType *obj, uint8_t port) +{ + switch(port) + { + case MPU_SLVPORT3: + return ((obj->CESR & MPU_CESR_SPERR3_MASK) >> MPU_CESR_SPERR3_SHIFT); + case MPU_SLVPORT2: + return ((obj->CESR & MPU_CESR_SPERR2_MASK) >> MPU_CESR_SPERR2_SHIFT); + case MPU_SLVPORT1: + return ((obj->CESR & MPU_CESR_SPERR1_MASK) >> MPU_CESR_SPERR1_SHIFT); + case MPU_SLVPORT0: + return ((obj->CESR & MPU_CESR_SPERR0_MASK) >> MPU_CESR_SPERR0_SHIFT); + default: + return MPU_RES_ERR; + } +} + +/*! \brief Clear Slave Port Error status. + * + * This function clear the Slave Port Error Status. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] port : set number of port + */ +__attribute__((always_inline)) static inline void MpuReg_ClrSlvPortErrStatus(MpuRegType *obj, uint8_t port) +{ + switch(port) + { + case MPU_SLVPORT3: + obj->CESR |= MPU_CESR_SPERR3_MASK; + break; + case MPU_SLVPORT2: + obj->CESR |= MPU_CESR_SPERR2_MASK; + break; + case MPU_SLVPORT1: + obj->CESR |= MPU_CESR_SPERR1_MASK; + break; + case MPU_SLVPORT0: + obj->CESR |= MPU_CESR_SPERR0_MASK; + break; + default: + break; + } +} + +/*! \brief Get Slave Port Error Address. + * + * This function get the Slave Port Error Address. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] port : set number of port + * \return Error Address + * An error has occurred for slave port, return error address + */ +__attribute__((always_inline)) static inline uint32_t MpuReg_GetSlvPortErrAddr(const MpuRegType *obj, uint8_t port) +{ + return ((obj->SLVPORT[port].EAR & MPU_EAR_EADDR_MASK) >> MPU_EAR_EADDR_SHIFT); +} + +/*! \brief Get Slave Port Error Detail Type R/W. + * + * This function get the Slave Port Error Detail Type R/W. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] port : set number of port + * \return Error Type for R/W + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetSlvPortErrDetailERW(const MpuRegType *obj, uint8_t port) +{ + return ((obj->SLVPORT[port].EDR & MPU_EDR_ERW_MASK) >> MPU_EDR_ERW_SHIFT); +} + +/*! \brief Get Slave Port Error Detail Type Attribute. + * + * This function get the Slave Port Error Detail Type Attribute. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] port : set number of port + * \return Error Type for Attribute + * - 0 : Mode - User, Access - Instruction + * - 1 : Mode - User, Access - Data + * - 2 : Mode - privilege, Access - Instruction + * - 3 : Mode - privilege, Access - Data + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetSlvPortErrDetailEAttr(const MpuRegType *obj, uint8_t port) +{ + return ((obj->SLVPORT[port].EDR & MPU_EDR_EATTR_MASK) >> MPU_EDR_EATTR_SHIFT); +} + +/*! \brief Get Slave Port Error Detail Type ErrMasterNumber. + * + * This function get the Slave Port Error Detail Type ErrMasterNumber. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] port : set number of port + * \return Error Type for ErrMasterNumber + * - 0 : CPU CORE + * - 1 : DEBUG + * - 2 : CPU CORE + * - 3 : CPU CORE + * - 4 : DMA + * - 5 : CSE + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetSlvPortErrDetailEMN(const MpuRegType *obj, uint8_t port) +{ + return ((obj->SLVPORT[port].EDR & MPU_EDR_EMN_MASK) >> MPU_EDR_EMN_SHIFT); +} + +/*! \brief Get Error Process ID + * + * This function record error process identification. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] port : set number of port + * \return Error Type for Error Process ID Number. + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetSlvPortErrPID(const MpuRegType *obj, uint8_t port) +{ + return ((obj->SLVPORT[port].EDR & MPU_EDR_EPID_MASK) >> MPU_EDR_EPID_SHIFT); +} + +/*! \brief Get Access Region Error Description. + * + * This function record error process identification. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] port : set number of port + * \return Access Error Description. + * - 0 : Hit none region + * - one bit set : Hit protect single unoverlapping description + * - multi bit set : Hit protect multi overlapping description + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetSlvPortEACD(const MpuRegType *obj, uint8_t port) +{ + return (uint8_t)((obj->SLVPORT[port].EDR & MPU_EDR_EACD_MASK) >> MPU_EDR_EACD_SHIFT); +} + +/*! \brief Set Region Description Start Address. + * + * This function set region description start address. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] startAddr : protect start address + * \param[in] regDescNumber : Region Description number set + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetRegionDescStartAddr(MpuRegType *obj, uint32_t startAddr, uint8_t regDescNum) +{ + uint32_t tmp = obj->RGD[regDescNum].WORD0; + + tmp &= ~MPU_RGD_WD0_SRTADDR_MASK; + tmp |= (((uint32_t)((uint32_t)startAddr << MPU_RGD_WD0_SRTADDR_SHIFT)) & MPU_RGD_WD0_SRTADDR_MASK); + obj->RGD[regDescNum].WORD0 = tmp; +} + +/*! \brief Get Region Description Start Address. + * + * This function get region description start address. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] startAddr : protect start address + * \return current region description protect start address + * + */ +__attribute__((always_inline)) static inline uint32_t MpuReg_GetRegionDescStartAddr(const MpuRegType *obj, uint8_t regDescNum) +{ + return ((obj->RGD[regDescNum].WORD0 & MPU_RGD_WD0_SRTADDR_MASK) >> MPU_RGD_WD0_SRTADDR_SHIFT); +} + +/*! \brief Set Region Description End Address. + * + * This function set region description end address. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] endAddr : protect end address + * \param[in] regDescNum : Region Description number set + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetRegionDescEndAddr(MpuRegType *obj, uint32_t endAddr, uint8_t regDescNum) +{ + uint32_t tmp = obj->RGD[regDescNum].WORD1; + + tmp &= ~MPU_RGD_WD1_ENDADDR_MASK; + tmp |= (((uint32_t)((uint32_t)endAddr << MPU_RGD_WD1_ENDADDR_SHIFT)) & MPU_RGD_WD1_ENDADDR_MASK); + obj->RGD[regDescNum].WORD1 = tmp; +} + +/*! \brief Get Region Description End Address. + * + * This function get region description end address. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] endAddr : protect start address + * \return current region description protect end address + * + */ +__attribute__((always_inline)) static inline uint32_t MpuReg_GetRegionDescEndAddr(const MpuRegType *obj, uint8_t regDescNum) +{ + return ((obj->RGD[regDescNum].WORD1 & MPU_RGD_WD1_ENDADDR_MASK) >> MPU_RGD_WD1_ENDADDR_SHIFT); +} + +/*! \brief Set Region Description User Bus Masterx Authority mode. + * + * This function set region description user bus master authority mode. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master number + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * - 2 : Bus Master2 + * - 3 : Bus Master3 + * \param[in] userMode : Configure Masterx Access Authority bit[0/1/2] + * - 0 : Try to access may abort by error, and do not excute Access + * - 1 : Access will be grant + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetRegionDescUserAuthority(MpuRegType *obj, uint8_t regDescNum, uint8_t masterNo, uint8_t userMode) +{ + uint32_t tmp = obj->RGD[regDescNum].WORD2; + + switch(masterNo) + { + case 0: + tmp &= ~MPU_RGD_WD2_M0UM_MASK; /*!< Bus Master0 User mode */ + tmp |= (((uint32_t)((uint32_t)userMode << MPU_RGD_WD2_M0UM_SHIFT)) & MPU_RGD_WD2_M0UM_MASK); + obj->RGD[regDescNum].WORD2 = tmp; + break; + case 1: + tmp &= ~MPU_RGD_WD2_M1UM_MASK; /*!< Bus Master1 User mode */ + tmp |= (((uint32_t)((uint32_t)userMode << MPU_RGD_WD2_M1UM_SHIFT)) & MPU_RGD_WD2_M1UM_MASK); + obj->RGD[regDescNum].WORD2 = tmp; + break; + case 2: + tmp &= ~MPU_RGD_WD2_M2UM_MASK; /*!< Bus Master2 User mode */ + tmp |= (((uint32_t)((uint32_t)userMode << MPU_RGD_WD2_M2UM_SHIFT)) & MPU_RGD_WD2_M2UM_MASK); + obj->RGD[regDescNum].WORD2 = tmp; + break; + case 3: + tmp &= ~MPU_RGD_WD2_M3UM_MASK; /*!< Bus Master3 User mode */ + tmp |= (((uint32_t)((uint32_t)userMode << MPU_RGD_WD2_M3UM_SHIFT)) & MPU_RGD_WD2_M3UM_MASK); + obj->RGD[regDescNum].WORD2 = tmp; + break; + default: + break; + } +} + +/*! \brief Get Region Description User Bus Masterx Authority mode. + * + * This function get region description user bus master authority mode. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master number + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * - 2 : Bus Master2 + * - 3 : Bus Master3 + * \return Masterx Access Authority bit[0/1/2] + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetRegionDescUserAuthority(const MpuRegType *obj, uint8_t regDescNum, uint8_t masterNo) +{ + switch(masterNo) + { + case 0: + return ((obj->RGD[regDescNum].WORD2 & MPU_RGD_WD2_M0UM_MASK) >> MPU_RGD_WD2_M0UM_SHIFT); /*!< Bus Master0 User mode */ + case 1: + return ((obj->RGD[regDescNum].WORD2 & MPU_RGD_WD2_M1UM_MASK) >> MPU_RGD_WD2_M1UM_SHIFT); /*!< Bus Master1 User mode */ + case 2: + return ((obj->RGD[regDescNum].WORD2 & MPU_RGD_WD2_M2UM_MASK) >> MPU_RGD_WD2_M2UM_SHIFT); /*!< Bus Master2 User mode */ + case 3: + return ((obj->RGD[regDescNum].WORD2 & MPU_RGD_WD2_M3UM_MASK) >> MPU_RGD_WD2_M3UM_SHIFT); /*!< Bus Master3 User mode */ + default: + return MPU_RES_ERR; + } +} + +/*! \brief Set Region Description Privilege Bus Masterx Authority mode. + * + * This function set region description privilege bus master authority mode. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master number + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * - 2 : Bus Master2 + * - 3 : Bus Master3 + * \param[in] userMode : Configure Masterx Access Authority + * - 0 : R/W/X + * - 1 : R/X + * - 2 : R/W + * - 3 : same as user masterx + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetRegionDescPrivilegeAuthority(MpuRegType *obj, uint8_t regDescNum, uint8_t masterNo, uint8_t privilegeMode) +{ + uint32_t tmp = obj->RGD[regDescNum].WORD2; + + switch(masterNo) + { + case 0: + tmp &= ~MPU_RGD_WD2_M0SM_MASK; /*!< Bus Master0 Privilege mode */ + tmp |= (((uint32_t)((uint32_t)privilegeMode << MPU_RGD_WD2_M0SM_SHIFT)) & MPU_RGD_WD2_M0SM_MASK); + obj->RGD[regDescNum].WORD2 = tmp; + break; + case 1: + tmp &= ~MPU_RGD_WD2_M1SM_MASK; /*!< Bus Master1 Privilege mode */ + tmp |= (((uint32_t)((uint32_t)privilegeMode << MPU_RGD_WD2_M1SM_SHIFT)) & MPU_RGD_WD2_M1SM_MASK); + obj->RGD[regDescNum].WORD2 = tmp; + break; + case 2: + tmp &= ~MPU_RGD_WD2_M2SM_MASK; /*!< Bus Master2 Privilege mode */ + tmp |= (((uint32_t)((uint32_t)privilegeMode << MPU_RGD_WD2_M2SM_SHIFT)) & MPU_RGD_WD2_M2SM_MASK); + obj->RGD[regDescNum].WORD2 = tmp; + break; + case 3: + tmp &= ~MPU_RGD_WD2_M3SM_MASK; /*!< Bus Master3 Privilege mode */ + tmp |= (((uint32_t)((uint32_t)privilegeMode << MPU_RGD_WD2_M3SM_SHIFT)) & MPU_RGD_WD2_M3SM_MASK); + obj->RGD[regDescNum].WORD2 = tmp; + break; + default: + break; + } +} + +/*! \brief Get Region Description Privilege Bus Masterx Authority mode. + * + * This function get region description privilege bus master authority mode. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master number + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * - 2 : Bus Master2 + * - 3 : Bus Master3 + * \return Masterx Access Authority + * - 0 : R/W/X + * - 1 : R/X + * - 2 : R/W + * - 3 : same as user masterx + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetRegionDescPrivilegeAuthority(const MpuRegType *obj, uint8_t regDescNum, uint8_t masterNo) +{ + switch(masterNo) + { + case 0: + return ((obj->RGD[regDescNum].WORD2 & MPU_RGD_WD2_M0SM_MASK) >> MPU_RGD_WD2_M0SM_SHIFT); /*!< Bus Master0 Privilege mode */ + case 1: + return ((obj->RGD[regDescNum].WORD2 & MPU_RGD_WD2_M1SM_MASK) >> MPU_RGD_WD2_M1SM_SHIFT); /*!< Bus Master1 Privilege mode */ + case 2: + return ((obj->RGD[regDescNum].WORD2 & MPU_RGD_WD2_M2SM_MASK) >> MPU_RGD_WD2_M2SM_SHIFT); /*!< Bus Master2 Privilege mode */ + case 3: + return ((obj->RGD[regDescNum].WORD2 & MPU_RGD_WD2_M3SM_MASK) >> MPU_RGD_WD2_M3SM_SHIFT); /*!< Bus Master3 Privilege mode */ + default: + return MPU_RES_ERR; + } +} + +/*! \brief Set Evaluate if Processing include PID. + * + * This function set evaluate if processing include Process Identification. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master number + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * \param[in] pidMode : Configure Evaluate Process + * - 0 : Evaluate processing do not include PID + * - 1 : Evaluate processing include PID + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetRegionDescPIDFlagEnable(MpuRegType *obj, uint8_t regDescNum, uint8_t masterNo, uint8_t pidMode) +{ + uint32_t tmp = obj->RGD[regDescNum].WORD2; + + switch(masterNo) + { + case 0: + tmp &= ~MPU_RGD_WD2_M0PE_MASK; /*!< Bus Master0 PID mode */ + tmp |= (((uint32_t)((uint32_t)pidMode << MPU_RGD_WD2_M0PE_SHIFT)) & MPU_RGD_WD2_M0PE_MASK); + obj->RGD[regDescNum].WORD2 = tmp; + break; + case 1: + tmp &= ~MPU_RGD_WD2_M1PE_MASK; /*!< Bus Master1 PID mode */ + tmp |= (((uint32_t)((uint32_t)pidMode << MPU_RGD_WD2_M1PE_SHIFT)) & MPU_RGD_WD2_M1PE_MASK); + obj->RGD[regDescNum].WORD2 = tmp; + break; + default: + break; + } +} + +/*! \brief Get Evaluate Processing include PID. + * + * This function get evaluate processing include Process Identification. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master number + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * \return Evaluate Process + * - 0 : Evaluate processing do not include PID + * - 1 : Evaluate processing include PID + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetRegionDescPIDFlagEnableStatus(const MpuRegType *obj, uint8_t regDescNum, uint8_t masterNo) +{ + switch(masterNo) + { + case 0: + return ((obj->RGD[regDescNum].WORD2 & MPU_RGD_WD2_M0PE_MASK) >> MPU_RGD_WD2_M0PE_SHIFT); /*!< Bus Master0 PID mode */ + case 1: + return ((obj->RGD[regDescNum].WORD2 & MPU_RGD_WD2_M1PE_MASK) >> MPU_RGD_WD2_M1PE_SHIFT); /*!< Bus Master1 PID mode */ + default: + return MPU_RES_ERR; + } +} + +/*! \brief Set Region Description valid or invalid. + * + * This function set region description valid or not. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] valid : Configure Region Description + * - 0 : Region Description invalid + * - 1 : Region Description valid + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetRegionDescValid(MpuRegType *obj, uint8_t regDescNum, uint8_t valid) +{ + uint32_t tmp = obj->RGD[regDescNum].WORD3; + + tmp &= ~MPU_RGD_WD3_VLD_MASK; + tmp |= (((uint32_t)((uint32_t)valid << MPU_RGD_WD3_VLD_SHIFT)) & MPU_RGD_WD3_VLD_MASK); + obj->RGD[regDescNum].WORD3 = tmp; +} + +/*! \brief Get Region Description valid or invalid. + * + * This function get region description valid or not. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \return Region Description + * - 0 : Region Description invalid + * - 1 : Region Description valid + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetRegionDescValid(const MpuRegType *obj, uint8_t regDescNum) +{ + return ((obj->RGD[regDescNum].WORD3 & MPU_RGD_WD3_VLD_MASK) >> MPU_RGD_WD3_VLD_SHIFT); +} + +/*! \brief Set Processing Identification Mask. + * + * This function set processing identification mask. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] PIDMask : Configure Processing ID Mask + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetPIDMask(MpuRegType *obj, uint8_t regDescNum, uint8_t pidMask) +{ + uint32_t tmp = obj->RGD[regDescNum].WORD3; + + tmp &= ~MPU_RGD_WD3_PIDMASK_MASK; + tmp |= (((uint32_t)((uint32_t)pidMask << MPU_RGD_WD3_PIDMASK_SHIFT)) & MPU_RGD_WD3_PIDMASK_MASK); + obj->RGD[regDescNum].WORD3 = tmp; +} + +/*! \brief Get Processing Identification Mask. + * + * This function get processing identification mask. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \return Processing ID Mask value + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetPIDMask(const MpuRegType *obj, uint8_t regDescNum) +{ + return ((obj->RGD[regDescNum].WORD3 & MPU_RGD_WD3_PIDMASK_MASK) >> MPU_RGD_WD3_PIDMASK_SHIFT); +} + +/*! \brief Set Processing Identification. + * + * This function set processing identification. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] PID : Configure Processing ID Mask + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetPID(MpuRegType *obj, uint8_t regDescNum, uint8_t pid) +{ + uint32_t tmp = obj->RGD[regDescNum].WORD3; + + tmp &= ~MPU_RGD_WD3_PID_MASK; + tmp |= (((uint32_t)((uint32_t)pid << MPU_RGD_WD3_PID_SHIFT)) & MPU_RGD_WD3_PID_MASK); + obj->RGD[regDescNum].WORD3 = tmp; +} + +/*! \brief Get Processing Identification. + * + * This function get processing identification. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \return Processing ID value + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetPID(const MpuRegType *obj, uint8_t regDescNum) +{ + return ((obj->RGD[regDescNum].WORD3 & MPU_RGD_WD3_PID_MASK) >> MPU_RGD_WD3_PID_SHIFT); +} + +/*! \brief Set Region Description Alternate Access Control User Bus Masterx Authority mode. + * + * This function set region description alternate access control user bus master authority mode. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master Num + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * - 2 : Bus Master2 + * - 3 : Bus Master3 + * \param[in] aacUserMode : Configure Masterx Access Authority bit[0/1/2] + * - 0 : Try to access may abort by error, and do not excute Access + * - 1 : Access will be grant + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetRegionDescAACUserAuthority(MpuRegType *obj, uint8_t aacChnNum, uint8_t masterNo, uint8_t aacUserMode) +{ + uint32_t tmp = obj->AAC[aacChnNum]; + + switch(masterNo) + { + case 0: + tmp &= ~MPU_RGDAAC_M0UM_MASK; /*!< AAC Master0 User mode */ + tmp |= (((uint32_t)((uint32_t)aacUserMode << MPU_RGDAAC_M0UM_SHIFT)) & MPU_RGDAAC_M0UM_MASK); + obj->AAC[aacChnNum] = tmp; + break; + case 1: + tmp &= ~MPU_RGDAAC_M1UM_MASK; /*!< AAC Master1 User mode */ + tmp |= (((uint32_t)((uint32_t)aacUserMode << MPU_RGDAAC_M1UM_SHIFT)) & MPU_RGDAAC_M1UM_MASK); + obj->AAC[aacChnNum] = tmp; + break; + case 2: + tmp &= ~MPU_RGDAAC_M2UM_MASK; /*!< AAC Master2 User mode */ + tmp |= (((uint32_t)((uint32_t)aacUserMode << MPU_RGDAAC_M2UM_SHIFT)) & MPU_RGDAAC_M2UM_MASK); + obj->AAC[aacChnNum] = tmp; + break; + case 3: + tmp &= ~MPU_RGDAAC_M3UM_MASK; /*!< AAC Master2 User mode */ + tmp |= (((uint32_t)((uint32_t)aacUserMode << MPU_RGDAAC_M3UM_SHIFT)) & MPU_RGDAAC_M3UM_MASK); + obj->AAC[aacChnNum] = tmp; + break; + default: + break; + } +} + +/*! \brief Get Region Description Alternate Access Control User Bus Masterx Authority mode. + * + * This function get region description alternate access control user bus master authority mode. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master number + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * - 2 : Bus Master2 + * - 3 : Bus Master3 + * \return Masterx Access Authority bit[0/1/2] + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetRegionDescAACUserAuthority(const MpuRegType *obj, uint8_t aacChnNum, uint8_t masterNo) +{ + switch(masterNo) + { + case 0: + return (uint8_t)((obj->AAC[aacChnNum] & MPU_RGDAAC_M0UM_MASK) >> MPU_RGDAAC_M0UM_SHIFT); /*!< AAC Master0 User mode */ + case 1: + return (uint8_t)((obj->AAC[aacChnNum] & MPU_RGDAAC_M1UM_MASK) >> MPU_RGDAAC_M1UM_SHIFT); /*!< AAC Master1 User mode */ + case 2: + return (uint8_t)((obj->AAC[aacChnNum] & MPU_RGDAAC_M2UM_MASK) >> MPU_RGDAAC_M2UM_SHIFT); /*!< AAC Master2 User mode */ + case 3: + return (uint8_t)((obj->AAC[aacChnNum] & MPU_RGDAAC_M3UM_MASK) >> MPU_RGDAAC_M3UM_SHIFT); /*!< AAC Master3 User mode */ + default: + return MPU_RES_ERR; + } +} + +/*! \brief Set Region Description Alternate Access Control Privilege Bus Masterx Authority mode. + * + * This function set region description alternate access control privilege bus master authority mode. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master number + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * - 2 : Bus Master2 + * - 3 : Bus Master3 + * \param[in] aacPrivilegeMode : Configure Masterx Access Authority + * - 0 : R/W/X + * - 1 : R/X + * - 2 : R/W + * - 3 : same as user masterx + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetRegionDescAACPrivilegeAuthority(MpuRegType *obj, + uint8_t aacChnNum, + uint8_t masterNo, + uint8_t aacPrivilegeMode) +{ + uint32_t tmp = obj->AAC[aacChnNum]; + + switch(masterNo) + { + case 0: + tmp &= ~MPU_RGDAAC_M0SM_MASK; /*!< AAC Bus Master0 Privilege mode */ + tmp |= (((uint32_t)((uint32_t)aacPrivilegeMode << MPU_RGDAAC_M0SM_SHIFT)) & MPU_RGDAAC_M0SM_MASK); + obj->AAC[aacChnNum] = tmp; + break; + case 1: + tmp &= ~MPU_RGDAAC_M1SM_MASK; /*!< AAC Bus Master1 Privilege mode */ + tmp |= (((uint32_t)((uint32_t)aacPrivilegeMode << MPU_RGDAAC_M1SM_SHIFT)) & MPU_RGDAAC_M1SM_MASK); + obj->AAC[aacChnNum] = tmp; + break; + case 2: + tmp &= ~MPU_RGDAAC_M2SM_MASK; /*!< AAC Bus Master2 Privilege mode */ + tmp |= (((uint32_t)((uint32_t)aacPrivilegeMode << MPU_RGDAAC_M2SM_SHIFT)) & MPU_RGDAAC_M2SM_MASK); + obj->AAC[aacChnNum] = tmp; + break; + case 3: + tmp &= ~MPU_RGDAAC_M3SM_MASK; /*!< AAC Bus Master3 Privilege mode */ + tmp |= (((uint32_t)((uint32_t)aacPrivilegeMode << MPU_RGDAAC_M3SM_SHIFT)) & MPU_RGDAAC_M3SM_MASK); + obj->AAC[aacChnNum] = tmp; + break; + default: + break; + } +} + +/*! \brief Get Region Description Alternate Access Control Privilege Bus Masterx Authority mode. + * + * This function get region description alternate access control privilege bus master authority mode. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master Num + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * - 2 : Bus Master2 + * - 3 : Bus Master3 + * \return Masterx Access Authority + * - 0 : R/W/X + * - 1 : R/X + * - 2 : R/W + * - 3 : same as user masterx + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetRegionDescAACPrivilegeAuthority(const MpuRegType *obj, uint8_t aacChnNum, uint8_t masterNo) +{ + switch(masterNo) + { + case 0: + return ((obj->AAC[aacChnNum] & MPU_RGDAAC_M0SM_MASK) >> MPU_RGDAAC_M0SM_SHIFT); /*!< AAC Bus Master0 Privilege mode */ + case 1: + return ((obj->AAC[aacChnNum] & MPU_RGDAAC_M1SM_MASK) >> MPU_RGDAAC_M1SM_SHIFT); /*!< AAC Bus Master1 Privilege mode */ + case 2: + return ((obj->AAC[aacChnNum] & MPU_RGDAAC_M2SM_MASK) >> MPU_RGDAAC_M2SM_SHIFT); /*!< AAC Bus Master2 Privilege mode */ + case 3: + return ((obj->AAC[aacChnNum] & MPU_RGDAAC_M3SM_MASK) >> MPU_RGDAAC_M3SM_SHIFT); /*!< AAC Bus Master3 Privilege mode */ + default: + return MPU_RES_ERR; + } +} + +/*! \brief Set Evaluate Alternate Access Control if Processing include PID. + * + * This function set evaluate alternate access control if processing include Process Identification. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master number + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * \param[in] aacPIDMode : Configure Evaluate Process + * - 0 : Evaluate processing do not include PID + * - 1 : Evaluate processing include PID + * \return None + * + */ +__attribute__((always_inline)) static inline void MpuReg_SetRegionDescAACPIDFlagEnable(MpuRegType *obj, uint8_t aacChnNum, uint8_t masterNo, uint8_t aacPIDMode) +{ + uint32_t tmp = obj->AAC[aacChnNum]; + + switch(masterNo) + { + case 0: + tmp &= ~MPU_RGDAAC_M0PE_MASK; /*!< AAC Bus Master0 PID mode */ + tmp |= (((uint32_t)((uint32_t)aacPIDMode << MPU_RGDAAC_M0PE_SHIFT)) & MPU_RGDAAC_M0PE_MASK); + obj->AAC[aacChnNum] = tmp; + break; + case 1: + tmp &= ~MPU_RGDAAC_M1PE_MASK; /*!< AAC Bus Master1 PID mode */ + tmp |= (((uint32_t)((uint32_t)aacPIDMode << MPU_RGDAAC_M1PE_SHIFT)) & MPU_RGDAAC_M1PE_MASK); + obj->AAC[aacChnNum] = tmp; + break; + default: + break; + } +} + +/*! \brief Get Evaluate Alternate Access Control Processing include PID. + * + * This function get evaluate alternate access control processing include Process Identification. + * + * \param[in] obj : pointer to MPU register instance + * \param[in] regDescNum : Region Description number set + * \param[in] masterNo : Select Master number + * - 0 : Bus Master0 + * - 1 : Bus Master1 + * \return Evaluate Process + - 0 : Evaluate processing do not include PID + * - 1 : Evaluate processing include PID + * + */ +__attribute__((always_inline)) static inline uint8_t MpuReg_GetRegionDescAACPIDFlagEnableStatus(const MpuRegType *obj, uint8_t aacChnNum, uint8_t masterNo) +{ + switch(masterNo) + { + case 0: + return ((obj->AAC[aacChnNum] & MPU_RGDAAC_M0PE_MASK) >> MPU_RGDAAC_M0PE_SHIFT); /*!< AAC Bus Master0 PID mode */ + case 1: + return ((obj->AAC[aacChnNum] & MPU_RGDAAC_M0PE_MASK) >> MPU_RGDAAC_M0PE_SHIFT); /*!< AAC Bus Master1 PID mode */ + default: + return MPU_RES_ERR; + } +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _MPU_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/mscm_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/mscm_reg.h new file mode 100644 index 0000000..298fdca --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/mscm_reg.h @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MSCM_REG_H_ +#define _MSCM_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the MSCM Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* CPU_TYPE Bit Fields */ +#define MSCM_CPU_TYPE_TYPE_MASK (0xFFFFFF00u) +#define MSCM_CPU_TYPE_TYPE_SHIFT (8u) +#define MSCM_CPU_TYPE_TYPE_WIDTH (24u) +#define MSCM_CPU_TYPE_REVISION_MASK (0xFFu) +#define MSCM_CPU_TYPE_REVISION_SHIFT (0u) +#define MSCM_CPU_TYPE_REVISION_WIDTH (8u) + +/* CPU_NUM Bit Fields */ +#define MSCM_CPU_NUM_CPNX_MASK (0x01u) +#define MSCM_CPU_NUM_CPNX_SHIFT (0u) +#define MSCM_CPU_NUM_CPNX_WIDTH (1u) + +/* CPU_CNT Bit Fields */ +#define MSCM_CPU_CNT_PCNT_MASK (0x03u) +#define MSCM_CPU_CNT_PCNT_SHIFT (0u) +#define MSCM_CPU_CNT_PCNT_WIDTH (2u) + +/* CPU_CACHE Bit Fields */ +#define MSCM_CPU_CACHE_ICACHE_SIZE_MASK (0xFF000000u) +#define MSCM_CPU_CACHE_ICACHE_SIZE_SHIFT (24u) +#define MSCM_CPU_CACHE_ICACHE_SIZE_WIDTH (8u) +#define MSCM_CPU_CACHE_ICACHE_WAYS_MASK (0xFF0000u) +#define MSCM_CPU_CACHE_ICACHE_WAYS_SHIFT (16u) +#define MSCM_CPU_CACHE_ICACHE_WAYS_WIDTH (8u) +#define MSCM_CPU_CACHE_DCACHE_SIZE_MASK (0xFF00u) +#define MSCM_CPU_CACHE_DCACHE_SIZE_SHIFT (8u) +#define MSCM_CPU_CACHE_DCACHE_SIZE_WIDTH (8u) +#define MSCM_CPU_CACHE_DCACHE_WAYS_MASK (0xFFu) +#define MSCM_CPU_CACHE_DCACHE_WAYS_SHIFT (0u) +#define MSCM_CPU_CACHE_DCACHE_WAYS_WIDTH (8u) + +/* CPU_MEM Bit Fields */ +#define MSCM_CPU_MEM_SRAMU_SIZE_MASK (0xFF000000u) +#define MSCM_CPU_MEM_SRAMU_SIZE_SHIFT (24u) +#define MSCM_CPU_MEM_SRAMU_SIZE_WIDTH (8u) +#define MSCM_CPU_MEM_SRAML_SIZE_MASK (0xFF00u) +#define MSCM_CPU_MEM_SRAML_SIZE_SHIFT (8u) +#define MSCM_CPU_MEM_SRAML_SIZE_WIDTH (8u) + +/* CPU_CFG Bit Fields */ +#define MSCM_CPU_CFG_BUS_PORTS_MASK (0x300u) +#define MSCM_CPU_CFG_BUS_PORTS_SHIFT (8u) +#define MSCM_CPU_CFG_BUS_PORTS_WIDTH (2u) +#define MSCM_CPU_CFG_BB_MASK (0x40u) +#define MSCM_CPU_CFG_BB_SHIFT (6u) +#define MSCM_CPU_CFG_BB_WIDTH (1u) +#define MSCM_CPU_CFG_SMPU_MASK (0x20u) +#define MSCM_CPU_CFG_SMPU_SHIFT (5u) +#define MSCM_CPU_CFG_SMPU_WIDTH (1u) +#define MSCM_CPU_CFG_MMU_MASK (0x10u) +#define MSCM_CPU_CFG_MMU_SHIFT (4u) +#define MSCM_CPU_CFG_MMU_WIDTH (1u) +#define MSCM_CPU_CFG_TRUST_ZONE_MASK (0x08u) +#define MSCM_CPU_CFG_TRUST_ZONE_SHIFT (3u) +#define MSCM_CPU_CFG_TRUST_ZONE_WIDTH (1u) +#define MSCM_CPU_CFG_JAZ_MASK (0x04u) +#define MSCM_CPU_CFG_JAZ_SHIFT (2u) +#define MSCM_CPU_CFG_JAZ_WIDTH (1u) +#define MSCM_CPU_CFG_SIMD_MASK (0x02u) +#define MSCM_CPU_CFG_SIMD_SHIFT (1u) +#define MSCM_CPU_CFG_SIMD_WIDTH (1u) +#define MSCM_CPU_CFG_FPU_MASK (0x01u) +#define MSCM_CPU_CFG_FPU_SHIFT (0u) +#define MSCM_CPU_CFG_FPU_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of MSCM registers + */ +typedef struct _MscmRegType_ +{ + const volatile uint32_t CPU_TYPE; /*!< Processor info register, offset: 0x00 */ + const volatile uint32_t CPU_NUM; /*!< Process NUMBER, offset: 0x04 */ + uint32_t RESERVED0[1]; /*!< Reserverd block, offset: 0x08 */ + const volatile uint32_t CPU_CNT; /*!< Total number of processor cores, offset: 0x0C */ + const volatile uint32_t CPU_CACHE; /*!< CPU cache info register, offset: 0x10 */ + const volatile uint32_t CPU_MEM; /*!< System memory info register, offset: 0x14 */ + const volatile uint32_t CPU_CFG; /*!< CPU configuration register, offset: 0x18 */ +} MscmRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the CPU type name + * + * This function gets the current CPU type name. + * The default value 0x434D34 is ASICC of "CM4" + * + * \param[in] obj : pointer to MSCM register instance + * \return CPU type name + */ +__attribute__((always_inline)) static inline uint32_t MscmReg_GetCpuTypeType(const MscmRegType *obj) +{ + return ((obj->CPU_TYPE & MSCM_CPU_TYPE_TYPE_MASK) >> MSCM_CPU_TYPE_TYPE_SHIFT); +} + +/*! \brief Gets the revision of processor + * + * This function gets the current revision of processor. + * + * \param[in] obj : pointer to MSCM register instance + * \return revision of processor + * - 0b : r0p0 + * - 1b : r0p1 + * - other : reserved + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuTypeRevision(const MscmRegType *obj) +{ + return ((obj->CPU_TYPE & MSCM_CPU_TYPE_REVISION_MASK) >> MSCM_CPU_TYPE_REVISION_SHIFT); +} + +/*! \brief Gets the Processor x Number + * + * This function gets the current Processor x Number. + * This zero-filled word defines the logical processor number for CPUx. + * If single core configuration, then CPN = 0 + * + * \param[in] obj : pointer to MSCM register instance + * \return Processor x Number + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuNumCpnx(const MscmRegType *obj) +{ + return ((obj->CPU_NUM & MSCM_CPU_NUM_CPNX_MASK) >> MSCM_CPU_NUM_CPNX_SHIFT); +} + +/*! \brief Gets the Processor Count + * + * This function gets the current Processor Count. + * This read-only field defines the processor count for the chip configuration + * + * \param[in] obj : pointer to MSCM register instance + * \return Processor Count + * - 00b : single core + * - 01b : dual cores + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCntPCnt(const MscmRegType *obj) +{ + return ((obj->CPU_CNT & MSCM_CPU_CNT_PCNT_MASK) >> MSCM_CPU_CNT_PCNT_SHIFT); +} + +/*! \brief Gets the Instruction cache Size + * + * This function gets the current Instruction cache Size. + * ICACHE_SIZE=0 means no memory, else memory size(byte) is 2^(8+ICACHE_SIZE) + * + * \param[in] obj : pointer to MSCM register instance + * \return Instruction cache Size + * - 0h : no cache + * - 1h : 512 + * - 2h : 1K + * - 3h : 2K + * - 4h : 4K + * - 5h : 8K + * - 6h : 16K + * - 7h : 32K + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCacheICacheSize(const MscmRegType *obj) +{ + return ((obj->CPU_CACHE & MSCM_CPU_CACHE_ICACHE_SIZE_MASK) >> MSCM_CPU_CACHE_ICACHE_SIZE_SHIFT); +} + +/*! \brief Gets the Instruction cache Ways + * + * This function gets the current Instruction cache Ways. + * This read-only field provides the number of cache ways for the Instruction cache. + * + * \param[in] obj : pointer to MSCM register instance + * \return Instruction cache Ways + * - 0h : not present. + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCacheICacheWays(const MscmRegType *obj) +{ + return ((obj->CPU_CACHE & MSCM_CPU_CACHE_ICACHE_WAYS_MASK) >> MSCM_CPU_CACHE_ICACHE_WAYS_SHIFT); +} + +/*! \brief Gets the Data Cache Size + * + * This function gets the current Data Cache Size. + * DCACHE_SIZE=0 means no memory, else memory size(byte) is 2^(8+DCACHE_SIZE) + * + * \param[in] obj : pointer to MSCM register instance + * \return Data Cache Size + * - 0h : no cache + * - 1h : 512 + * - 2h : 1K + * - 3h : 2K + * - 4h : 4K + * - 5h : 8K + * - 6h : 16K + * - 7h : 32K + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCacheDCacheSize(const MscmRegType *obj) +{ + return ((obj->CPU_CACHE & MSCM_CPU_CACHE_DCACHE_SIZE_MASK) >> MSCM_CPU_CACHE_DCACHE_SIZE_SHIFT); +} + +/*! \brief Gets the Data Cache Ways + * + * This function gets the current Data Cache Ways. + * This read-only field provides the number of cache ways for the Data Cache. + * + * \param[in] obj : pointer to MSCM register instance + * \return Data Cache Ways + * - 0h : not present. + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCacheDCacheWays(const MscmRegType *obj) +{ + return ((obj->CPU_CACHE & MSCM_CPU_CACHE_DCACHE_WAYS_MASK) >> MSCM_CPU_CACHE_DCACHE_WAYS_SHIFT); +} + +/*! \brief Gets the SRAMU Size + * + * This function gets the current SRAMU Size. + * SRAMU_SIZE=0 means no memory,else memory size(byte) is 2^(8+SRAMU_SIZE) -4 + * + * \param[in] obj : pointer to MSCM register instance + * \return SRAMU Size + * - 0h : no sramu + * - 8h : 60Kbyte + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuMemSRamUSize(const MscmRegType *obj) +{ + return ((obj->CPU_MEM & MSCM_CPU_MEM_SRAMU_SIZE_MASK) >> MSCM_CPU_MEM_SRAMU_SIZE_SHIFT); +} + +/*! \brief Gets the SRAML Size + * + * This function gets the current SRAML Size. + * SRAML_SIZE=0 means no memory, else memory size(byte) is 2^(8+SRAML_SIZE) + * + * \param[in] obj : pointer to MSCM register instance + * \return SRAML Size + * - 0h : no cache + * - 1h : 512byte + * - 2h : 1Kbyte + * - 3h : 2Kbyte + * - 4h : 4Kbyte + * - 5h : 8Kbyte + * - 6h : 16Kbyte + * - 7h : 32Kbyte + * - 8h : 64Kbyte + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuMemSRamLSize(const MscmRegType *obj) +{ + return ((obj->CPU_MEM & MSCM_CPU_MEM_SRAML_SIZE_MASK) >> MSCM_CPU_MEM_SRAML_SIZE_SHIFT); +} + +/*! \brief Gets the System Bus Ports + * + * This function gets the current System Bus Ports. + * This field defines the number of physical connections to the system bus fabric for this processor + * + * \param[in] obj : pointer to MSCM register instance + * \return System Bus Ports + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCfgBusPorts(const MscmRegType *obj) +{ + return ((obj->CPU_CFG & MSCM_CPU_CFG_BUS_PORTS_MASK) >> MSCM_CPU_CFG_BUS_PORTS_SHIFT); +} + +/*! \brief Gets the Bit Banding enable + * + * This function gets the current Bit Banding enable. + * This field defines if the processor supports "bit banding". + * + * \param[in] obj : pointer to MSCM register instance + * \return Bit Banding enable + * - 0b : Bit Banding is not supported. + * - 1b : Bit Banding is supported. + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCfgBB(const MscmRegType *obj) +{ + return ((obj->CPU_CFG & MSCM_CPU_CFG_BB_MASK) >> MSCM_CPU_CFG_BB_SHIFT); +} + +/*! \brief Gets the Core Memory Protection unit + * + * This function gets the current Core Memory Protection unit. + * This field indicates if the core memory protection hardware is included in the processor. + * + * \param[in] obj : pointer to MSCM register instance + * \return Core Memory Protection unit + * - 0b : Core Memory Protection is not included. + * - 1b : Core Memory Protection is included. + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCfgSmpu(const MscmRegType *obj) +{ + return ((obj->CPU_CFG & MSCM_CPU_CFG_SMPU_MASK) >> MSCM_CPU_CFG_SMPU_SHIFT); +} + +/*! \brief Gets the Memory Management Unit + * + * This function gets the current Memory Management Unit. + * This field indicates if the virtual memory management capabilities are supported in the processor. + * + * \param[in] obj : pointer to MSCM register instance + * \return Memory Management Unit + * - 0b : MMU support is not included. + * - 1b : MMU support is included. + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCfgMmu(const MscmRegType *obj) +{ + return ((obj->CPU_CFG & MSCM_CPU_CFG_MMU_MASK) >> MSCM_CPU_CFG_MMU_SHIFT); +} + +/*! \brief Gets the Trust Zone + * + * This function gets the current Trust Zone. + * This field indicates if the Trust Zone capabilities are supported in the processor.. + * + * \param[in] obj : pointer to MSCM register instance + * \return Trust Zone + * - 0b : Trust Zone support is not included. + * - 1b : Trust Zone support is included. + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCfgTrustZone(const MscmRegType *obj) +{ + return ((obj->CPU_CFG & MSCM_CPU_CFG_TRUST_ZONE_MASK) >> MSCM_CPU_CFG_TRUST_ZONE_SHIFT); +} + +/*! \brief Gets the Jazelle support + * + * This function gets the current Jazelle support. + * This field indicates if Jazelle hardware is supported in the processor. + * + * \param[in] obj : pointer to MSCM register instance + * \return Jazelle support + * - 0b : Jazelle support is not included. + * - 1b : Jazelle support is included. + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCfgJaz(const MscmRegType *obj) +{ + return ((obj->CPU_CFG & MSCM_CPU_CFG_JAZ_MASK) >> MSCM_CPU_CFG_JAZ_SHIFT); +} + +/*! \brief Gets the SIMD/NEON instruction support + * + * This function gets the current SIMD/NEON instruction support. + * This field indicates if the instruction set extensions supporting SIMD and/or NEON capabilities + * are supported in the processor. + * + * \param[in] obj : pointer to MSCM register instance + * \return SIMD/NEON instruction support + * - 0b : SIMD/NEON support is not included. + * - 1b : SIMD/NEON support is included. + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCfgSimd(const MscmRegType *obj) +{ + return ((obj->CPU_CFG & MSCM_CPU_CFG_SIMD_MASK) >> MSCM_CPU_CFG_SIMD_SHIFT); +} + +/*! \brief Gets the FPU support + * + * This function gets the current FPU support. + * + * \param[in] obj : pointer to MSCM register instance + * \return FPU support + * - 0b : FPU support is not included. + * - 1b : FPU support is included. + */ +__attribute__((always_inline)) static inline uint8_t MscmReg_GetCpuCfgFpu(const MscmRegType *obj) +{ + return ((obj->CPU_CFG & MSCM_CPU_CFG_FPU_MASK) >> MSCM_CPU_CFG_FPU_SHIFT); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _MSCM_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/pcc0_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/pcc0_reg.h new file mode 100644 index 0000000..21e40f0 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/pcc0_reg.h @@ -0,0 +1,1261 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PCC0_REG_H_ +#define _PCC0_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the PCC0 Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* CMP Bit Fields */ +#define PCC0_CMP_SRC_MASK (0x10000u) +#define PCC0_CMP_SRC_SHIFT (16u) +#define PCC0_CMP_SRC_WIDTH (1u) +#define PCC0_CMP_CKEN_MASK (0x10u) +#define PCC0_CMP_CKEN_SHIFT (4u) +#define PCC0_CMP_CKEN_WIDTH (1u) +#define PCC0_CMP_SWR_MASK (0x01u) +#define PCC0_CMP_SWR_SHIFT (0u) +#define PCC0_CMP_SWR_WIDTH (1u) + +/* PORTA Bit Fields */ +#define PCC0_PORTA_CKEN_MASK (0x10u) +#define PCC0_PORTA_CKEN_SHIFT (4u) +#define PCC0_PORTA_CKEN_WIDTH (1u) +#define PCC0_PORTA_SWR_MASK (0x01u) +#define PCC0_PORTA_SWR_SHIFT (0u) +#define PCC0_PORTA_SWR_WIDTH (1u) + +/* PORTB Bit Fields */ +#define PCC0_PORTB_CKEN_MASK (0x10u) +#define PCC0_PORTB_CKEN_SHIFT (4u) +#define PCC0_PORTB_CKEN_WIDTH (1u) +#define PCC0_PORTB_SWR_MASK (0x01u) +#define PCC0_PORTB_SWR_SHIFT (0u) +#define PCC0_PORTB_SWR_WIDTH (1u) + +/* PORTC Bit Fields */ +#define PCC0_PORTC_CKEN_MASK (0x10u) +#define PCC0_PORTC_CKEN_SHIFT (4u) +#define PCC0_PORTC_CKEN_WIDTH (1u) +#define PCC0_PORTC_SWR_MASK (0x01u) +#define PCC0_PORTC_SWR_SHIFT (0u) +#define PCC0_PORTC_SWR_WIDTH (1u) + +/* PORTD Bit Fields */ +#define PCC0_PORTD_CKEN_MASK (0x10u) +#define PCC0_PORTD_CKEN_SHIFT (4u) +#define PCC0_PORTD_CKEN_WIDTH (1u) +#define PCC0_PORTD_SWR_MASK (0x01u) +#define PCC0_PORTD_SWR_SHIFT (0u) +#define PCC0_PORTD_SWR_WIDTH (1u) + +/* PORTE Bit Fields */ +#define PCC0_PORTE_CKEN_MASK (0x10u) +#define PCC0_PORTE_CKEN_SHIFT (4u) +#define PCC0_PORTE_CKEN_WIDTH (1u) +#define PCC0_PORTE_SWR_MASK (0x01u) +#define PCC0_PORTE_SWR_SHIFT (0u) +#define PCC0_PORTE_SWR_WIDTH (1u) + +/* LPTMR Bit Fields */ +#define PCC0_LPTMR_SRC_MASK (0x70000u) +#define PCC0_LPTMR_SRC_SHIFT (16u) +#define PCC0_LPTMR_SRC_WIDTH (3u) +#define PCC0_LPTMR_DIV_MASK (0x700u) +#define PCC0_LPTMR_DIV_SHIFT (8u) +#define PCC0_LPTMR_DIV_WIDTH (3u) +#define PCC0_LPTMR_CKEN_MASK (0x10u) +#define PCC0_LPTMR_CKEN_SHIFT (4u) +#define PCC0_LPTMR_CKEN_WIDTH (1u) +#define PCC0_LPTMR_SWR_MASK (0x01u) +#define PCC0_LPTMR_SWR_SHIFT (0u) +#define PCC0_LPTMR_SWR_WIDTH (1u) + +/* LPIT Bit Fields */ +#define PCC0_LPIT_SRC_MASK (0x30000u) +#define PCC0_LPIT_SRC_SHIFT (16u) +#define PCC0_LPIT_SRC_WIDTH (2u) +#define PCC0_LPIT_CKEN_MASK (0x10u) +#define PCC0_LPIT_CKEN_SHIFT (4u) +#define PCC0_LPIT_CKEN_WIDTH (1u) +#define PCC0_LPIT_SWR_MASK (0x01u) +#define PCC0_LPIT_SWR_SHIFT (0u) +#define PCC0_LPIT_SWR_WIDTH (1u) + +/* RTC_CNT Bit Fields */ +#define PCC0_RTC_CNT_SRC_MASK (0x30000u) +#define PCC0_RTC_CNT_SRC_SHIFT (16u) +#define PCC0_RTC_CNT_SRC_WIDTH (2u) +#define PCC0_RTC_CNT_CKEN_MASK (0x10u) +#define PCC0_RTC_CNT_CKEN_SHIFT (4u) +#define PCC0_RTC_CNT_CKEN_WIDTH (1u) + +/* WDG Bit Fields */ +#define PCC0_WDG_SWR_MASK (0x01u) +#define PCC0_WDG_SWR_SHIFT (0u) +#define PCC0_WDG_SWR_WIDTH (1u) + +/* PORTA_FLT Bit Fields */ +#define PCC0_PORTA_FLT_SRC_MASK (0x10000u) +#define PCC0_PORTA_FLT_SRC_SHIFT (16u) +#define PCC0_PORTA_FLT_SRC_WIDTH (1u) + +/* PORTB_FLT Bit Fields */ +#define PCC0_PORTB_FLT_SRC_MASK (0x10000u) +#define PCC0_PORTB_FLT_SRC_SHIFT (16u) +#define PCC0_PORTB_FLT_SRC_WIDTH (1u) + +/* PORTC_FLT Bit Fields */ +#define PCC0_PORTC_FLT_SRC_MASK (0x10000u) +#define PCC0_PORTC_FLT_SRC_SHIFT (16u) +#define PCC0_PORTC_FLT_SRC_WIDTH (1u) + +/* PORTD_FLT Bit Fields */ +#define PCC0_PORTD_FLT_SRC_MASK (0x10000u) +#define PCC0_PORTD_FLT_SRC_SHIFT (16u) +#define PCC0_PORTD_FLT_SRC_WIDTH (1u) + +/* PORTE_FLT Bit Fields */ +#define PCC0_PORTE_FLT_SRC_MASK (0x10000u) +#define PCC0_PORTE_FLT_SRC_SHIFT (16u) +#define PCC0_PORTE_FLT_SRC_WIDTH (1u) + +/* LPO32 Bit Fields */ +#define PCC0_LPO32_CKEN_MASK (0x10u) +#define PCC0_LPO32_CKEN_SHIFT (4u) +#define PCC0_LPO32_CKEN_WIDTH (1u) + +/* LPO1 Bit Fields */ +#define PCC0_LPO1_CKEN_MASK (0x10u) +#define PCC0_LPO1_CKEN_SHIFT (4u) +#define PCC0_LPO1_CKEN_WIDTH (1u) + +/* LOCK Bit Fields */ +#define PCC0_LOCK_LOCK_MASK (0x01u) +#define PCC0_LOCK_LOCK_SHIFT (0u) +#define PCC0_LOCK_LOCK_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of PCC0 registers + */ +typedef struct _Pcc0RegType_ +{ + uint32_t RESERVED0[1]; /*!< Reserved register, offset: 0x0 */ + volatile uint32_t CMP; /*!< CMP clock and software reset control register, offset: 0x4 */ + volatile uint32_t PORTA; /*!< PORTA clock and software reset control register, offset: 0x8 */ + volatile uint32_t PORTB; /*!< PORTB clock and software reset control register, offset: 0xC */ + volatile uint32_t PORTC; /*!< PORTC clock and software reset control register, offset: 0x10 */ + volatile uint32_t PORTD; /*!< PORTD clock and software reset control register, offset: 0x14 */ + volatile uint32_t PORTE; /*!< PORTE clock and software reset control register, offset: 0x18 */ + volatile uint32_t LPTMR; /*!< LPTMR clock and software reset control register, offset: 0x1C */ + volatile uint32_t LPIT; /*!< LPIT clock and software reset control register, offset: 0x20 */ + uint32_t RESERVED1[1]; /*!< Reserved register, offset: 0x24 */ + volatile uint32_t RTC_CNT; /*!< RTC clock and software reset control register, offset: 0x28 */ + volatile uint32_t WDG; /*!< WDG clock and software reset control register, offset: 0x2C */ + volatile uint32_t PORTA_FLT; /*!< PORTA digital filter clock and software reset control register, offset: 0x30 */ + volatile uint32_t PORTB_FLT; /*!< PORTB digital filter clock and software reset control register, offset: 0x34 */ + volatile uint32_t PORTC_FLT; /*!< PORTC digital filter clock and software reset control register, offset: 0x38 */ + volatile uint32_t PORTD_FLT; /*!< PORTD digital filter clock and software reset control register, offset: 0x3C */ + volatile uint32_t PORTE_FLT; /*!< PORTE digital filter clock and software reset control register, offset: 0x40 */ + volatile uint32_t LPO32; /*!< LPO32 clock and software reset control register, offset: 0x44 */ + volatile uint32_t LPO1; /*!< LPO1 clock and software reset control register, offset: 0x48 */ + uint32_t RESERVED2[13]; /*!< Reserved register, offset: 0x4C */ + volatile uint32_t KEY; /*!< PCC module unlock/lock control, offset: 0x80 */ + const volatile uint32_t LOCK; /*!< PCC module unlock/lock status, offset: 0x84 */ +} Pcc0RegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the CMP module function clock source + * + * This function gets the current CMP module function clock source. + * In RUN mode, the source should be clk_core. In STOP and STANDBY mode, the source may be changed to clk_lptmr. + * + * \param[in] obj : pointer to PCC0 register instance + * \return CMP module function clock source + * - 0b : clk_core + * - 1b : clk_lptmr + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetCmpSrc(const Pcc0RegType *obj) +{ + return ((obj->CMP & PCC0_CMP_SRC_MASK) >> PCC0_CMP_SRC_SHIFT); +} + +/*! \brief Sets the CMP module function clock source + * + * This function sets the CMP module function clock source. + * In RUN mode, the source should be clk_core. In STOP and STANDBY mode, the source may be changed to clk_lptmr. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of CMP module function clock source + * - 0b : clk_core + * - 1b : clk_lptmr + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetCmpSrc(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CMP; + + tmp &= ~PCC0_CMP_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_CMP_SRC_SHIFT)) & PCC0_CMP_SRC_MASK); + obj->CMP = tmp; +} + +/*! \brief Gets the CMP module clock enable for both config clock and function + * + * This function gets the current CMP module clock enable for both config clock and function . + * + * \param[in] obj : pointer to PCC0 register instance + * \return CMP module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetCmpCkEn(const Pcc0RegType *obj) +{ + return ((obj->CMP & PCC0_CMP_CKEN_MASK) >> PCC0_CMP_CKEN_SHIFT); +} + +/*! \brief Sets the CMP module clock enable for both config clock and function + * + * This function sets the CMP module clock enable for both config clock and function . + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of CMP module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetCmpCkEn(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CMP; + + tmp &= ~PCC0_CMP_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_CMP_CKEN_SHIFT)) & PCC0_CMP_CKEN_MASK); + obj->CMP = tmp; +} + +/*! \brief Gets the CMP0 module software reset for both config clock domain and function clock domain + * + * This function gets the current CMP0 module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \return CMP0 module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetCmpSwR(const Pcc0RegType *obj) +{ + return ((obj->CMP & PCC0_CMP_SWR_MASK) >> PCC0_CMP_SWR_SHIFT); +} + +/*! \brief Sets the CMP0 module software reset for both config clock domain and function clock domain + * + * This function sets the CMP0 module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of CMP0 module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetCmpSwR(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CMP; + + tmp &= ~PCC0_CMP_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_CMP_SWR_SHIFT)) & PCC0_CMP_SWR_MASK); + obj->CMP = tmp; +} + +/*! \brief Gets the PORTA module clock enable for both config clock and function + * + * This function gets the current PORTA module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTA module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortACkEn(const Pcc0RegType *obj) +{ + return ((obj->PORTA & PCC0_PORTA_CKEN_MASK) >> PCC0_PORTA_CKEN_SHIFT); +} + +/*! \brief Sets the PORTA module clock enable for both config clock and function + * + * This function sets the PORTA module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTA module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortACkEn(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTA; + + tmp &= ~PCC0_PORTA_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTA_CKEN_SHIFT)) & PCC0_PORTA_CKEN_MASK); + obj->PORTA = tmp; +} + +/*! \brief Gets the PORTA module software reset for both config clock domain and function clock domain + * + * This function gets the current PORTA module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTA module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortASwR(const Pcc0RegType *obj) +{ + return ((obj->PORTA & PCC0_PORTA_SWR_MASK) >> PCC0_PORTA_SWR_SHIFT); +} + +/*! \brief Sets the PORTA module software reset for both config clock domain and function clock domain + * + * This function sets the PORTA module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTA module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortASwR(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTA; + + tmp &= ~PCC0_PORTA_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTA_SWR_SHIFT)) & PCC0_PORTA_SWR_MASK); + obj->PORTA = tmp; +} + +/*! \brief Gets the PORTB module clock enable for both config clock and function + * + * This function gets the current PORTB module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTB module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortBCkEn(const Pcc0RegType *obj) +{ + return ((obj->PORTB & PCC0_PORTB_CKEN_MASK) >> PCC0_PORTB_CKEN_SHIFT); +} + +/*! \brief Sets the PORTB module clock enable for both config clock and function + * + * This function sets the PORTB module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTB module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortBCkEn(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTB; + + tmp &= ~PCC0_PORTB_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTB_CKEN_SHIFT)) & PCC0_PORTB_CKEN_MASK); + obj->PORTB = tmp; +} + +/*! \brief Gets the PORTB module software reset for both config clock domain and function clock domain + * + * This function gets the current PORTB module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTB module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortBSwR(const Pcc0RegType *obj) +{ + return ((obj->PORTB & PCC0_PORTB_SWR_MASK) >> PCC0_PORTB_SWR_SHIFT); +} + +/*! \brief Sets the PORTB module software reset for both config clock domain and function clock domain + * + * This function sets the PORTB module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTB module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortBSwR(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTB; + + tmp &= ~PCC0_PORTB_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTB_SWR_SHIFT)) & PCC0_PORTB_SWR_MASK); + obj->PORTB = tmp; +} + +/*! \brief Gets the PORTC module clock enable for both config clock and function + * + * This function gets the current PORTC module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTC module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortCCkEn(const Pcc0RegType *obj) +{ + return ((obj->PORTC & PCC0_PORTC_CKEN_MASK) >> PCC0_PORTC_CKEN_SHIFT); +} + +/*! \brief Sets the PORTC module clock enable for both config clock and function + * + * This function sets the PORTC module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTC module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortCCkEn(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTC; + + tmp &= ~PCC0_PORTC_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTC_CKEN_SHIFT)) & PCC0_PORTC_CKEN_MASK); + obj->PORTC = tmp; +} + +/*! \brief Gets the PORTC module software reset for both config clock domain and function clock domain + * + * This function gets the current PORTC module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTC module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortCSwR(const Pcc0RegType *obj) +{ + return ((obj->PORTC & PCC0_PORTC_SWR_MASK) >> PCC0_PORTC_SWR_SHIFT); +} + +/*! \brief Sets the PORTC module software reset for both config clock domain and function clock domain + * + * This function sets the PORTC module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTC module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortCSwR(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTC; + + tmp &= ~PCC0_PORTC_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTC_SWR_SHIFT)) & PCC0_PORTC_SWR_MASK); + obj->PORTC = tmp; +} + +/*! \brief Gets the PORTD module clock enable for both config clock and function + * + * This function gets the current PORTD module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTD module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortDCkEn(const Pcc0RegType *obj) +{ + return ((obj->PORTD & PCC0_PORTD_CKEN_MASK) >> PCC0_PORTD_CKEN_SHIFT); +} + +/*! \brief Sets the PORTD module clock enable for both config clock and function + * + * This function sets the PORTD module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTD module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortDCkEn(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTD; + + tmp &= ~PCC0_PORTD_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTD_CKEN_SHIFT)) & PCC0_PORTD_CKEN_MASK); + obj->PORTD = tmp; +} + +/*! \brief Gets the PORTD module software reset for both config clock domain and function clock domain + * + * This function gets the current PORTD module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTD module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortDSwR(const Pcc0RegType *obj) +{ + return ((obj->PORTD & PCC0_PORTD_SWR_MASK) >> PCC0_PORTD_SWR_SHIFT); +} + +/*! \brief Sets the PORTD module software reset for both config clock domain and function clock domain + * + * This function sets the PORTD module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTD module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortDSwR(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTD; + + tmp &= ~PCC0_PORTD_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTD_SWR_SHIFT)) & PCC0_PORTD_SWR_MASK); + obj->PORTD = tmp; +} + +/*! \brief Gets the PORTE module clock enable for both config clock and function + * + * This function gets the current PORTE module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTE module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortECkEn(const Pcc0RegType *obj) +{ + return ((obj->PORTE & PCC0_PORTE_CKEN_MASK) >> PCC0_PORTE_CKEN_SHIFT); +} + +/*! \brief Sets the PORTE module clock enable for both config clock and function + * + * This function sets the PORTE module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTE module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortECkEn(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTE; + + tmp &= ~PCC0_PORTE_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTE_CKEN_SHIFT)) & PCC0_PORTE_CKEN_MASK); + obj->PORTE = tmp; +} + +/*! \brief Gets the PORTE module software reset for both config clock domain and function clock domain + * + * This function gets the current PORTE module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTE module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortESwR(const Pcc0RegType *obj) +{ + return ((obj->PORTE & PCC0_PORTE_SWR_MASK) >> PCC0_PORTE_SWR_SHIFT); +} + +/*! \brief Sets the PORTE module software reset for both config clock domain and function clock domain + * + * This function sets the PORTE module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTE module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortESwR(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTE; + + tmp &= ~PCC0_PORTE_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTE_SWR_SHIFT)) & PCC0_PORTE_SWR_MASK); + obj->PORTE = tmp; +} + +/*! \brief Gets the LPTMR module function clock source + * + * This function gets the current LPTMR module function clock source. + * This register should be changed after the clock is disabled at least 2 pre-changed clock cycles + * and 2 after-changed clock cycles. + * + * \param[in] obj : pointer to PCC0 register instance + * \return LPTMR module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_lpo128 + * - 4h : clk_lpo1 + * - 5h : clk_lpo32 + * - 6h : RTC_CLKIN from PAD_PTA7 + * - 7h : clk_sirc_div + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetLptmrSrc(const Pcc0RegType *obj) +{ + return ((obj->LPTMR & PCC0_LPTMR_SRC_MASK) >> PCC0_LPTMR_SRC_SHIFT); +} + +/*! \brief Sets the LPTMR module function clock source + * + * This function sets the LPTMR module function clock source. + * This register should be changed after the clock is disabled at least 2 pre-changed clock cycles + * and 2 after-changed clock cycles. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of LPTMR module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_lpo128 + * - 4h : clk_lpo1 + * - 5h : clk_lpo32 + * - 6h : RTC_CLKIN from PAD_PTA7 + * - 7h : clk_sirc_div + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetLptmrSrc(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPTMR; + + tmp &= ~PCC0_LPTMR_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_LPTMR_SRC_SHIFT)) & PCC0_LPTMR_SRC_MASK); + obj->LPTMR = tmp; +} + +/*! \brief Gets the LPTMR module function clock divide ratio + * + * This function gets the current LPTMR module function clock divide ratio . + * This register should be changed after the clock is disabled at least 2 pre-changed clock cycles + * and 2 after-changed clock cycles. + * + * \param[in] obj : pointer to PCC0 register instance + * \return LPTMR module function clock divide ratio + * - 0h : 1 + * - 1h : 2 + * - 2h : 3 + * - 3h : 4 + * - 4h : 5 + * - 5h : 6 + * - 6h : 7 + * - 7h : 8 + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetLptmrDiv(const Pcc0RegType *obj) +{ + return ((obj->LPTMR & PCC0_LPTMR_DIV_MASK) >> PCC0_LPTMR_DIV_SHIFT); +} + +/*! \brief Sets the LPTMR module function clock divide ratio + * + * This function sets the LPTMR module function clock divide ratio . + * This register should be changed after the clock is disabled at least 2 pre-changed clock cycles + * and 2 after-changed clock cycles. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of LPTMR module function clock divide ratio + * - 0h : 1 + * - 1h : 2 + * - 2h : 3 + * - 3h : 4 + * - 4h : 5 + * - 5h : 6 + * - 6h : 7 + * - 7h : 8 + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetLptmrDiv(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPTMR; + + tmp &= ~PCC0_LPTMR_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_LPTMR_DIV_SHIFT)) & PCC0_LPTMR_DIV_MASK); + obj->LPTMR = tmp; +} + +/*! \brief Gets the LPTMR module clock enable for both config clock and function clock + * + * This function gets the current LPTMR module clock enable for both config clock and function clock. + * + * \param[in] obj : pointer to PCC0 register instance + * \return LPTMR module clock enable for both config clock and function clock + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetLptmrCken(const Pcc0RegType *obj) +{ + return ((obj->LPTMR & PCC0_LPTMR_CKEN_MASK) >> PCC0_LPTMR_CKEN_SHIFT); +} + +/*! \brief Sets the LPTMR module clock enable for both config clock and function clock + * + * This function sets the LPTMR module clock enable for both config clock and function clock. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of LPTMR module clock enable for both config clock and function clock + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetLptmrCken(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPTMR; + + tmp &= ~PCC0_LPTMR_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_LPTMR_CKEN_SHIFT)) & PCC0_LPTMR_CKEN_MASK); + obj->LPTMR = tmp; +} + +/*! \brief Gets the LPTMR module software reset for both config clock domain and function clock domain + * + * This function gets the current LPTMR module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \return LPTMR module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetLptmrSwR(const Pcc0RegType *obj) +{ + return ((obj->LPTMR & PCC0_LPTMR_SWR_MASK) >> PCC0_LPTMR_SWR_SHIFT); +} + +/*! \brief Sets the LPTMR module software reset for both config clock domain and function clock domain + * + * This function sets the LPTMR module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of LPTMR module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetLptmrSwR(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPTMR; + + tmp &= ~PCC0_LPTMR_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_LPTMR_SWR_SHIFT)) & PCC0_LPTMR_SWR_MASK); + obj->LPTMR = tmp; +} + +/*! \brief Gets the LPIT module function clock source + * + * This function gets the current LPIT module function clock source. + * This register should be changed after the clock is disabled at least 2 pre-changed clock cycles + * and 2 after-changed clock cycles. + * + * \param[in] obj : pointer to PCC0 register instance + * \return LPIT module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_pll_div + * - 2h : clk_sosc_div + * - 3h : clk_lpo128 + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetLpitSrc(const Pcc0RegType *obj) +{ + return ((obj->LPIT & PCC0_LPIT_SRC_MASK) >> PCC0_LPIT_SRC_SHIFT); +} + +/*! \brief Sets the LPIT module function clock source + * + * This function sets the LPIT module function clock source. + * This register should be changed after the clock is disabled at least 2 pre-changed clock cycles + * and 2 after-changed clock cycles. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of LPIT module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_pll_div + * - 2h : clk_sosc_div + * - 3h : clk_lpo128 + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetLpitSrc(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPIT; + + tmp &= ~PCC0_LPIT_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_LPIT_SRC_SHIFT)) & PCC0_LPIT_SRC_MASK); + obj->LPIT = tmp; +} + +/*! \brief Gets the LPIT module clock enable for both config clock and function + * + * This function gets the current LPIT module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \return LPIT module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetLpitCken(const Pcc0RegType *obj) +{ + return ((obj->LPIT & PCC0_LPIT_CKEN_MASK) >> PCC0_LPIT_CKEN_SHIFT); +} + +/*! \brief Sets the LPIT module clock enable for both config clock and function + * + * This function sets the LPIT module clock enable for both config clock and function. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of LPIT module clock enable for both config clock and function + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetLpitCken(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPIT; + + tmp &= ~PCC0_LPIT_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_LPIT_CKEN_SHIFT)) & PCC0_LPIT_CKEN_MASK); + obj->LPIT = tmp; +} + +/*! \brief Gets the LPIT module software reset for both config clock domain and function clock domain + * + * This function gets the current LPIT module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \return LPIT module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetLpitSwR(const Pcc0RegType *obj) +{ + return ((obj->LPIT & PCC0_LPIT_SWR_MASK) >> PCC0_LPIT_SWR_SHIFT); +} + +/*! \brief Sets the LPIT module software reset for both config clock domain and function clock domain + * + * This function sets the LPIT module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of LPIT module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetLpitSwR(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPIT; + + tmp &= ~PCC0_LPIT_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_LPIT_SWR_SHIFT)) & PCC0_LPIT_SWR_MASK); + obj->LPIT = tmp; +} + +/*! \brief Gets the RTC module clock source select + * + * This function gets the current RTC module clock source select. + * This register should be changed after the clock is disabled at least 2 pre-changed clock cycles + * and 2 after-changed clock cycles. + * + * \param[in] obj : pointer to PCC0 register instance + * \return RTC module clock source select + * - 0h : clk_lpo32 + * - 1h : PAD RTC_CLKIN + * - 2h : lpo1 + * - 3h : lpo1 + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetRtcCntSrc(const Pcc0RegType *obj) +{ + return ((obj->RTC_CNT & PCC0_RTC_CNT_SRC_MASK) >> PCC0_RTC_CNT_SRC_SHIFT); +} + +/*! \brief Sets the RTC module clock source select + * + * This function sets the RTC module clock source select. + * This register should be changed after the clock is disabled at least 2 pre-changed clock cycles + * and 2 after-changed clock cycles. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of RTC module clock source select + * - 0h : clk_lpo32 + * - 1h : PAD RTC_CLKIN + * - 2h : lpo1 + * - 3h : lpo1 + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetRtcCntSrc(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RTC_CNT; + + tmp &= ~PCC0_RTC_CNT_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_RTC_CNT_SRC_SHIFT)) & PCC0_RTC_CNT_SRC_MASK); + obj->RTC_CNT = tmp; +} + +/*! \brief Gets the RTC module clock enable for both config clock and function clock + * + * This function gets the current RTC module clock enable for both config clock and function clock. + * + * \param[in] obj : pointer to PCC0 register instance + * \return RTC module clock enable for both config clock and function clock + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetRtcCntCken(const Pcc0RegType *obj) +{ + return ((obj->RTC_CNT & PCC0_RTC_CNT_CKEN_MASK) >> PCC0_RTC_CNT_CKEN_SHIFT); +} + +/*! \brief Sets the RTC module clock enable for both config clock and function clock + * + * This function sets the RTC module clock enable for both config clock and function clock. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of RTC module clock enable for both config clock and function clock + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetRtcCntCken(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RTC_CNT; + + tmp &= ~PCC0_RTC_CNT_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_RTC_CNT_CKEN_SHIFT)) & PCC0_RTC_CNT_CKEN_MASK); + obj->RTC_CNT = tmp; +} + +/*! \brief Gets the WDG module software reset for both config clock domain and function clock domain + * + * This function gets the current WDG module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \return WDG module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetWdgSwR(const Pcc0RegType *obj) +{ + return ((obj->WDG & PCC0_WDG_SWR_MASK) >> PCC0_WDG_SWR_SHIFT); +} + +/*! \brief Sets the WDG module software reset for both config clock domain and function clock domain + * + * This function sets the WDG module software reset for both config clock domain and function clock domain. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of WDG module software reset for both config clock domain and function clock domain + * - 0b : not reset + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetWdgSwR(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->WDG; + + tmp &= ~PCC0_WDG_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_WDG_SWR_SHIFT)) & PCC0_WDG_SWR_MASK); + obj->WDG = tmp; +} + +/*! \brief Gets the PORTA digital filter clock source + * + * This function gets the current PORTA digital filter clock source. + * Changing the filter clock source must be done only when all digital filters are disabled. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTA digital filter clock source + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortAFltSrc(const Pcc0RegType *obj) +{ + return ((obj->PORTA_FLT & PCC0_PORTA_FLT_SRC_MASK) >> PCC0_PORTA_FLT_SRC_SHIFT); +} + +/*! \brief Sets the PORTA digital filter clock source + * + * This function sets the PORTA digital filter clock source. + * Changing the filter clock source must be done only when all digital filters are disabled. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTA digital filter clock source + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortAFltSrc(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTA_FLT; + + tmp &= ~PCC0_PORTA_FLT_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTA_FLT_SRC_SHIFT)) & PCC0_PORTA_FLT_SRC_MASK); + obj->PORTA_FLT = tmp; +} + +/*! \brief Gets the PORTB digital filter clock source + * + * This function gets the current PORTB digital filter clock source. + * Changing the filter clock source must be done only when all digital filters are disabled. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTB digital filter clock source + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortBFltSrc(const Pcc0RegType *obj) +{ + return ((obj->PORTB_FLT & PCC0_PORTB_FLT_SRC_MASK) >> PCC0_PORTB_FLT_SRC_SHIFT); +} + +/*! \brief Sets the PORTB digital filter clock source + * + * This function sets the PORTB digital filter clock source. + * Changing the filter clock source must be done only when all digital filters are disabled. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTB digital filter clock source + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortBFltSrc(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTB_FLT; + + tmp &= ~PCC0_PORTB_FLT_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTB_FLT_SRC_SHIFT)) & PCC0_PORTB_FLT_SRC_MASK); + obj->PORTB_FLT = tmp; +} + +/*! \brief Gets the PORTC digital filter clock source + * + * This function gets the current PORTC digital filter clock source. + * Changing the filter clock source must be done only when all digital filters are disabled. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTC digital filter clock source + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortCFltSrc(const Pcc0RegType *obj) +{ + return ((obj->PORTC_FLT & PCC0_PORTC_FLT_SRC_MASK) >> PCC0_PORTC_FLT_SRC_SHIFT); +} + +/*! \brief Sets the PORTC digital filter clock source + * + * This function sets the PORTC digital filter clock source. + * Changing the filter clock source must be done only when all digital filters are disabled. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTC digital filter clock source + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortCFltSrc(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTC_FLT; + + tmp &= ~PCC0_PORTC_FLT_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTC_FLT_SRC_SHIFT)) & PCC0_PORTC_FLT_SRC_MASK); + obj->PORTC_FLT = tmp; +} + +/*! \brief Gets the PORTD digital filter clock source + * + * This function gets the current PORTD digital filter clock source. + * Changing the filter clock source must be done only when all digital filters are disabled. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTD digital filter clock source + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortDFltSrc(const Pcc0RegType *obj) +{ + return ((obj->PORTD_FLT & PCC0_PORTD_FLT_SRC_MASK) >> PCC0_PORTD_FLT_SRC_SHIFT); +} + +/*! \brief Sets the PORTD digital filter clock source + * + * This function sets the PORTD digital filter clock source. + * Changing the filter clock source must be done only when all digital filters are disabled. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTD digital filter clock source + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortDFltSrc(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTD_FLT; + + tmp &= ~PCC0_PORTD_FLT_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTD_FLT_SRC_SHIFT)) & PCC0_PORTD_FLT_SRC_MASK); + obj->PORTD_FLT = tmp; +} + +/*! \brief Gets the PORTE digital filter clock source + * + * This function gets the current PORTE digital filter clock source. + * Changing the filter clock source must be done only when all digital filters are disabled. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PORTE digital filter clock source + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetPortEFltSrc(const Pcc0RegType *obj) +{ + return ((obj->PORTE_FLT & PCC0_PORTE_FLT_SRC_MASK) >> PCC0_PORTE_FLT_SRC_SHIFT); +} + +/*! \brief Sets the PORTE digital filter clock source + * + * This function sets the PORTE digital filter clock source. + * Changing the filter clock source must be done only when all digital filters are disabled. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PORTE digital filter clock source + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetPortEFltSrc(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PORTE_FLT; + + tmp &= ~PCC0_PORTE_FLT_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_PORTE_FLT_SRC_SHIFT)) & PCC0_PORTE_FLT_SRC_MASK); + obj->PORTE_FLT = tmp; +} + +/*! \brief Gets the clk_lpo32 enable + * + * This function gets the current clk_lpo32 enable. + * + * \param[in] obj : pointer to PCC0 register instance + * \return clk_lpo32 enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetLpo32Cken(const Pcc0RegType *obj) +{ + return ((obj->LPO32 & PCC0_LPO32_CKEN_MASK) >> PCC0_LPO32_CKEN_SHIFT); +} + +/*! \brief Sets the clk_lpo32 enable + * + * This function sets the clk_lpo32 enable. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of clk_lpo32 enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetLpo32Cken(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPO32; + + tmp &= ~PCC0_LPO32_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_LPO32_CKEN_SHIFT)) & PCC0_LPO32_CKEN_MASK); + obj->LPO32 = tmp; +} + +/*! \brief Gets the clk_lpo1 enable + * + * This function gets the current clk_lpo1 enable. + * + * \param[in] obj : pointer to PCC0 register instance + * \return clk_lpo1 enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetLpo1Cken(const Pcc0RegType *obj) +{ + return ((obj->LPO1 & PCC0_LPO1_CKEN_MASK) >> PCC0_LPO1_CKEN_SHIFT); +} + +/*! \brief Sets the clk_lpo1 enable + * + * This function sets the clk_lpo1 enable. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of clk_lpo1 enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetLpo1Cken(Pcc0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPO1; + + tmp &= ~PCC0_LPO1_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC0_LPO1_CKEN_SHIFT)) & PCC0_LPO1_CKEN_MASK); + obj->LPO1 = tmp; +} + +/*! \brief Sets the PCC register unlock key + * + * This function sets the PCC register unlock key. + * Registers in PCC is locked by default. Before writing registers in pcc, write unlock key to this register. + * + * \param[in] obj : pointer to PCC0 register instance + * \param[in] value : the value of PCC register unlock key + * - 0x55534552 : unlock(USER), user key + * - other : lock + */ +__attribute__((always_inline)) static inline void Pcc0Reg_SetKey(Pcc0RegType *obj, uint32_t value) +{ + obj->KEY = value; +} + +/*! \brief Gets the PCC register unlock key + * + * This function gets the current PCC register unlock key. + * Registers in PCC is locked by default. Before writing registers in pcc, write unlock key to this register. + * + * \param[in] obj : pointer to PCC0 register instance + * \return PCC register unlock key + * - 0b : unlock + * - 1b : lock + */ +__attribute__((always_inline)) static inline uint8_t Pcc0Reg_GetLock(const Pcc0RegType *obj) +{ + return ((obj->LOCK & PCC0_LOCK_LOCK_MASK) >> PCC0_LOCK_LOCK_SHIFT); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _PCC0_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/pcc1_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/pcc1_reg.h new file mode 100644 index 0000000..3575fb5 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/pcc1_reg.h @@ -0,0 +1,2728 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PCC1_REG_H_ +#define _PCC1_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the PCC1 Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* DMA Bit Fields */ +#define PCC1_DMA_CKEN_MASK (0x10u) +#define PCC1_DMA_CKEN_SHIFT (4u) +#define PCC1_DMA_CKEN_WIDTH (1u) +#define PCC1_DMA_SWR_MASK (0x01u) +#define PCC1_DMA_SWR_SHIFT (0u) +#define PCC1_DMA_SWR_WIDTH (1u) + +/* MSCM Bit Fields */ +#define PCC1_MSCM_CKEN_MASK (0x10u) +#define PCC1_MSCM_CKEN_SHIFT (4u) +#define PCC1_MSCM_CKEN_WIDTH (1u) +#define PCC1_MSCM_SWR_MASK (0x01u) +#define PCC1_MSCM_SWR_SHIFT (0u) +#define PCC1_MSCM_SWR_WIDTH (1u) + +/* CRC Bit Fields */ +#define PCC1_CRC_CKEN_MASK (0x10u) +#define PCC1_CRC_CKEN_SHIFT (4u) +#define PCC1_CRC_CKEN_WIDTH (1u) +#define PCC1_CRC_SWR_MASK (0x01u) +#define PCC1_CRC_SWR_SHIFT (0u) +#define PCC1_CRC_SWR_WIDTH (1u) + +/* EIM Bit Fields */ +#define PCC1_EIM_CKEN_MASK (0x10u) +#define PCC1_EIM_CKEN_SHIFT (4u) +#define PCC1_EIM_CKEN_WIDTH (1u) +#define PCC1_EIM_SWR_MASK (0x01u) +#define PCC1_EIM_SWR_SHIFT (0u) +#define PCC1_EIM_SWR_WIDTH (1u) + +/* ERM Bit Fields */ +#define PCC1_ERM_CKEN_MASK (0x10u) +#define PCC1_ERM_CKEN_SHIFT (4u) +#define PCC1_ERM_CKEN_WIDTH (1u) +#define PCC1_ERM_SWR_MASK (0x01u) +#define PCC1_ERM_SWR_SHIFT (0u) +#define PCC1_ERM_SWR_WIDTH (1u) + +/* FHU Bit Fields */ +#define PCC1_FHU_CKEN_MASK (0x10u) +#define PCC1_FHU_CKEN_SHIFT (4u) +#define PCC1_FHU_CKEN_WIDTH (1u) +#define PCC1_FHU_SWR_MASK (0x01u) +#define PCC1_FHU_SWR_SHIFT (0u) +#define PCC1_FHU_SWR_WIDTH (1u) + +/* ADC Bit Fields */ +#define PCC1_ADC_SRC_MASK (0x30000u) +#define PCC1_ADC_SRC_SHIFT (16u) +#define PCC1_ADC_SRC_WIDTH (2u) +#define PCC1_ADC_DIV_MASK (0x300u) +#define PCC1_ADC_DIV_SHIFT (8u) +#define PCC1_ADC_DIV_WIDTH (2u) +#define PCC1_ADC_CKEN_MASK (0x10u) +#define PCC1_ADC_CKEN_SHIFT (4u) +#define PCC1_ADC_CKEN_WIDTH (1u) +#define PCC1_ADC_SWR_MASK (0x01u) +#define PCC1_ADC_SWR_SHIFT (0u) +#define PCC1_ADC_SWR_WIDTH (1u) + +/* PDB Bit Fields */ +#define PCC1_PDB_CKEN_MASK (0x10u) +#define PCC1_PDB_CKEN_SHIFT (4u) +#define PCC1_PDB_CKEN_WIDTH (1u) +#define PCC1_PDB_SWR_MASK (0x01u) +#define PCC1_PDB_SWR_SHIFT (0u) +#define PCC1_PDB_SWR_WIDTH (1u) + +/* SPI0 Bit Fields */ +#define PCC1_SPI0_SRC_MASK (0x30000u) +#define PCC1_SPI0_SRC_SHIFT (16u) +#define PCC1_SPI0_SRC_WIDTH (2u) +#define PCC1_SPI0_CKEN_MASK (0x10u) +#define PCC1_SPI0_CKEN_SHIFT (4u) +#define PCC1_SPI0_CKEN_WIDTH (1u) +#define PCC1_SPI0_SWR_MASK (0x01u) +#define PCC1_SPI0_SWR_SHIFT (0u) +#define PCC1_SPI0_SWR_WIDTH (1u) + +/* SPI1 Bit Fields */ +#define PCC1_SPI1_SRC_MASK (0x30000u) +#define PCC1_SPI1_SRC_SHIFT (16u) +#define PCC1_SPI1_SRC_WIDTH (2u) +#define PCC1_SPI1_CKEN_MASK (0x10u) +#define PCC1_SPI1_CKEN_SHIFT (4u) +#define PCC1_SPI1_CKEN_WIDTH (1u) +#define PCC1_SPI1_SWR_MASK (0x01u) +#define PCC1_SPI1_SWR_SHIFT (0u) +#define PCC1_SPI1_SWR_WIDTH (1u) + +/* UART0 Bit Fields */ +#define PCC1_UART0_SRC_MASK (0x30000u) +#define PCC1_UART0_SRC_SHIFT (16u) +#define PCC1_UART0_SRC_WIDTH (2u) +#define PCC1_UART0_CKEN_MASK (0x10u) +#define PCC1_UART0_CKEN_SHIFT (4u) +#define PCC1_UART0_CKEN_WIDTH (1u) +#define PCC1_UART0_SWR_MASK (0x01u) +#define PCC1_UART0_SWR_SHIFT (0u) +#define PCC1_UART0_SWR_WIDTH (1u) + +/* UART1 Bit Fields */ +#define PCC1_UART1_SRC_MASK (0x30000u) +#define PCC1_UART1_SRC_SHIFT (16u) +#define PCC1_UART1_SRC_WIDTH (2u) +#define PCC1_UART1_CKEN_MASK (0x10u) +#define PCC1_UART1_CKEN_SHIFT (4u) +#define PCC1_UART1_CKEN_WIDTH (1u) +#define PCC1_UART1_SWR_MASK (0x01u) +#define PCC1_UART1_SWR_SHIFT (0u) +#define PCC1_UART1_SWR_WIDTH (1u) + +/* UART2 Bit Fields */ +#define PCC1_UART2_SRC_MASK (0x30000u) +#define PCC1_UART2_SRC_SHIFT (16u) +#define PCC1_UART2_SRC_WIDTH (2u) +#define PCC1_UART2_CKEN_MASK (0x10u) +#define PCC1_UART2_CKEN_SHIFT (4u) +#define PCC1_UART2_CKEN_WIDTH (1u) +#define PCC1_UART2_SWR_MASK (0x01u) +#define PCC1_UART2_SWR_SHIFT (0u) +#define PCC1_UART2_SWR_WIDTH (1u) + +/* CAN Bit Fields */ +#define PCC1_CAN_CFG_CKEN_MASK (0x20u) +#define PCC1_CAN_CFG_CKEN_SHIFT (5u) +#define PCC1_CAN_CFG_CKEN_WIDTH (1u) +#define PCC1_CAN_CKEN_MASK (0x10u) +#define PCC1_CAN_CKEN_SHIFT (4u) +#define PCC1_CAN_CKEN_WIDTH (1u) +#define PCC1_CAN_SWR_MASK (0x01u) +#define PCC1_CAN_SWR_SHIFT (0u) +#define PCC1_CAN_SWR_WIDTH (1u) + +/* I2C Bit Fields */ +#define PCC1_I2C_SRC_MASK (0x30000u) +#define PCC1_I2C_SRC_SHIFT (16u) +#define PCC1_I2C_SRC_WIDTH (2u) +#define PCC1_I2C_CKEN_MASK (0x10u) +#define PCC1_I2C_CKEN_SHIFT (4u) +#define PCC1_I2C_CKEN_WIDTH (1u) +#define PCC1_I2C_SWR_MASK (0x01u) +#define PCC1_I2C_SWR_SHIFT (0u) +#define PCC1_I2C_SWR_WIDTH (1u) + +/* I2SM Bit Fields */ +#define PCC1_I2SM_SRC_MASK (0x30000u) +#define PCC1_I2SM_SRC_SHIFT (16u) +#define PCC1_I2SM_SRC_WIDTH (2u) +#define PCC1_I2SM_DIV_MASK (0x3F00u) +#define PCC1_I2SM_DIV_SHIFT (8u) +#define PCC1_I2SM_DIV_WIDTH (6u) +#define PCC1_I2SM_CKEN_MASK (0x10u) +#define PCC1_I2SM_CKEN_SHIFT (4u) +#define PCC1_I2SM_CKEN_WIDTH (1u) +#define PCC1_I2SM_SWR_MASK (0x01u) +#define PCC1_I2SM_SWR_SHIFT (0u) +#define PCC1_I2SM_SWR_WIDTH (1u) + +/* I2SS Bit Fields */ +#define PCC1_I2SS_CKEN_MASK (0x10u) +#define PCC1_I2SS_CKEN_SHIFT (4u) +#define PCC1_I2SS_CKEN_WIDTH (1u) +#define PCC1_I2SS_SWR_MASK (0x01u) +#define PCC1_I2SS_SWR_SHIFT (0u) +#define PCC1_I2SS_SWR_WIDTH (1u) + +/* PWM0 Bit Fields */ +#define PCC1_PWM0_CKEN_MASK (0x10u) +#define PCC1_PWM0_CKEN_SHIFT (4u) +#define PCC1_PWM0_CKEN_WIDTH (1u) +#define PCC1_PWM0_SWR_MASK (0x01u) +#define PCC1_PWM0_SWR_SHIFT (0u) +#define PCC1_PWM0_SWR_WIDTH (1u) + +/* PWM1 Bit Fields */ +#define PCC1_PWM1_CKEN_MASK (0x10u) +#define PCC1_PWM1_CKEN_SHIFT (4u) +#define PCC1_PWM1_CKEN_WIDTH (1u) +#define PCC1_PWM1_SWR_MASK (0x01u) +#define PCC1_PWM1_SWR_SHIFT (0u) +#define PCC1_PWM1_SWR_WIDTH (1u) + +/* MFT0 Bit Fields */ +#define PCC1_MFT0_CKEN_MASK (0x10u) +#define PCC1_MFT0_CKEN_SHIFT (4u) +#define PCC1_MFT0_CKEN_WIDTH (1u) +#define PCC1_MFT0_SWR_MASK (0x01u) +#define PCC1_MFT0_SWR_SHIFT (0u) +#define PCC1_MFT0_SWR_WIDTH (1u) + +/* MFT1 Bit Fields */ +#define PCC1_MFT1_CKEN_MASK (0x10u) +#define PCC1_MFT1_CKEN_SHIFT (4u) +#define PCC1_MFT1_CKEN_WIDTH (1u) +#define PCC1_MFT1_SWR_MASK (0x01u) +#define PCC1_MFT1_SWR_SHIFT (0u) +#define PCC1_MFT1_SWR_WIDTH (1u) + +/* GPIO Bit Fields */ +#define PCC1_GPIO_SWR_MASK (0x01u) +#define PCC1_GPIO_SWR_SHIFT (0u) +#define PCC1_GPIO_SWR_WIDTH (1u) + +/* CMUS Bit Fields */ +#define PCC1_CMUS_CKEN_MASK (0x10u) +#define PCC1_CMUS_CKEN_SHIFT (4u) +#define PCC1_CMUS_CKEN_WIDTH (1u) +#define PCC1_CMUS_SWR_MASK (0x01u) +#define PCC1_CMUS_SWR_SHIFT (0u) +#define PCC1_CMUS_SWR_WIDTH (1u) + +/* CMUP Bit Fields */ +#define PCC1_CMUP_CKEN_MASK (0x10u) +#define PCC1_CMUP_CKEN_SHIFT (4u) +#define PCC1_CMUP_CKEN_WIDTH (1u) +#define PCC1_CMUP_SWR_MASK (0x01u) +#define PCC1_CMUP_SWR_SHIFT (0u) +#define PCC1_CMUP_SWR_WIDTH (1u) + +/* EXT_MFT0 Bit Fields */ +#define PCC1_EXT_MFT0_SRC_MASK (0x70000u) +#define PCC1_EXT_MFT0_SRC_SHIFT (16u) +#define PCC1_EXT_MFT0_SRC_WIDTH (3u) + +/* EXT_MFT1 Bit Fields */ +#define PCC1_EXT_MFT1_SRC_MASK (0x70000u) +#define PCC1_EXT_MFT1_SRC_SHIFT (16u) +#define PCC1_EXT_MFT1_SRC_WIDTH (3u) + +/* FIX_MFT0 Bit Fields */ +#define PCC1_FIX_MFT0_SRC_MASK (0x10000u) +#define PCC1_FIX_MFT0_SRC_SHIFT (16u) +#define PCC1_FIX_MFT0_SRC_WIDTH (1u) + +/* FIX_MFT1 Bit Fields */ +#define PCC1_FIX_MFT1_SRC_MASK (0x10000u) +#define PCC1_FIX_MFT1_SRC_SHIFT (16u) +#define PCC1_FIX_MFT1_SRC_WIDTH (1u) + +/* FLS_CTL Bit Fields */ +#define PCC1_FLS_CTL_CNT_SRC_MASK (0x30000u) +#define PCC1_FLS_CTL_CNT_SRC_SHIFT (16u) +#define PCC1_FLS_CTL_CNT_SRC_WIDTH (2u) +#define PCC1_FLS_CTL_CNT_DIV_MASK (0xF00u) +#define PCC1_FLS_CTL_CNT_DIV_SHIFT (8u) +#define PCC1_FLS_CTL_CNT_DIV_WIDTH (4u) +#define PCC1_FLS_CTL_CKEN_MASK (0x10u) +#define PCC1_FLS_CTL_CKEN_SHIFT (4u) +#define PCC1_FLS_CTL_CKEN_WIDTH (1u) +#define PCC1_FLS_CTL_SWR_MASK (0x01u) +#define PCC1_FLS_CTL_SWR_SHIFT (0u) +#define PCC1_FLS_CTL_SWR_WIDTH (1u) + +/* MPU Bit Fields */ +#define PCC1_MPU_CKEN_MASK (0x10u) +#define PCC1_MPU_CKEN_SHIFT (4u) +#define PCC1_MPU_CKEN_WIDTH (1u) +#define PCC1_MPU_SWR_MASK (0x01u) +#define PCC1_MPU_SWR_SHIFT (0u) +#define PCC1_MPU_SWR_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of PCC1 registers + */ +typedef struct _Pcc1RegType_ +{ + volatile uint32_t DMA; /*!< DMA clock and software reset control register, offset: 0x0 */ + volatile uint32_t MSCM; /*!< MSCM clock and software reset control register, offset: 0x4 */ + uint32_t RESERVED0[2]; /*!< Reserved register, offset: 0x8 */ + volatile uint32_t CRC; /*!< CRC clock and software reset control register, offset: 0x10 */ + volatile uint32_t EIM; /*!< EIM clock and software reset control register, offset: 0x14 */ + volatile uint32_t ERM; /*!< ERM clock and software reset control register, offset: 0x18 */ + volatile uint32_t FHU; /*!< FHU clock and software reset control register, offset: 0x1C */ + volatile uint32_t ADC; /*!< ADC clock and software reset control register, offset: 0x20 */ + uint32_t RESERVED1[1]; /*!< Reserved register, offset: 0x24 */ + volatile uint32_t PDB; /*!< PDB clock and software reset control register, offset: 0x28 */ + uint32_t RESERVED2[1]; /*!< Reserved register, offset: 0x2C */ + volatile uint32_t SPI0; /*!< SPI0 clock and software reset control register, offset: 0x30 */ + volatile uint32_t SPI1; /*!< SPI1 clock and software reset control register, offset: 0x34 */ + uint32_t RESERVED3[2]; /*!< Reserved register, offset: 0x38 */ + volatile uint32_t UART0; /*!< UART0 clock and software reset control register, offset: 0x40 */ + volatile uint32_t UART1; /*!< UART1 clock and software reset control register, offset: 0x44 */ + volatile uint32_t UART2; /*!< UART2 clock and software reset control register, offset: 0x48 */ + uint32_t RESERVED4[1]; /*!< Reserved register, offset: 0x4C */ + volatile uint32_t CAN; /*!< CAN clock and software reset control register, offset: 0x50 */ + uint32_t RESERVED5[3]; /*!< Reserved register, offset: 0x54 */ + volatile uint32_t I2C; /*!< I2C clock and software reset control register, offset: 0x60 */ + volatile uint32_t I2SM; /*!< I2SM clock and software reset control register, offset: 0x64 */ + volatile uint32_t I2SS; /*!< I2SS clock and software reset control register, offset: 0x68 */ + volatile uint32_t PWM0; /*!< PWM0 clock and software reset control register, offset: 0x6C */ + volatile uint32_t PWM1; /*!< PWM1 clock and software reset control register, offset: 0x70 */ + uint32_t RESERVED6[3]; /*!< Reserved register, offset: 0x74 */ + volatile uint32_t MFT0; /*!< MFT0 clock and software reset control register, offset: 0x80 */ + volatile uint32_t MFT1; /*!< MFT1 clock and software reset control register, offset: 0x84 */ + uint32_t RESERVED7[2]; /*!< Reserved register, offset: 0x88 */ + volatile uint32_t GPIO; /*!< GPIO clock and software reset control register, offset: 0x90 */ + volatile uint32_t CMUS; /*!< CMUS clock and software reset control register, offset: 0x94 */ + uint32_t RESERVED8[1]; /*!< Reserved register, offset: 0x98 */ + volatile uint32_t CMUP; /*!< CMUP clock and software reset control register, offset: 0x9C */ + volatile uint32_t EXT_MFT0; /*!< MFT0 external clock and software reset control register, offset: 0xA0 */ + volatile uint32_t EXT_MFT1; /*!< MFT1 external clock and software reset control register, offset: 0xA4 */ + uint32_t RESERVED9[6]; /*!< Reserved register, offset: 0xA8 */ + volatile uint32_t FIX_MFT0; /*!< MFT0 fix clock and software reset control register, offset: 0xC0 */ + volatile uint32_t FIX_MFT1; /*!< MFT1 fix clock and software reset control register, offset: 0xC4 */ + volatile uint32_t FLS_CTL; /*!< CMUP clock and software reset control register, offset: 0xC8 */ + volatile uint32_t MPU; /*!< MPU clock and software reset control register, offset: 0xCC */ +} Pcc1RegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the DMA clock enable + * + * This function gets the current DMA clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return DMA clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetDmaCkEn(const Pcc1RegType *obj) +{ + return ((obj->DMA & PCC1_DMA_CKEN_MASK) >> PCC1_DMA_CKEN_SHIFT); +} + +/*! \brief Sets the DMA clock enable + * + * This function sets the DMA clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of DMA clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetDmaCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DMA; + + tmp &= ~PCC1_DMA_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_DMA_CKEN_SHIFT)) & PCC1_DMA_CKEN_MASK); + obj->DMA = tmp; +} + +/*! \brief Gets the DMA software reset + * + * This function gets the current DMA software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return DMA software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetDmaSwR(const Pcc1RegType *obj) +{ + return ((obj->DMA & PCC1_DMA_SWR_MASK) >> PCC1_DMA_SWR_SHIFT); +} + +/*! \brief Sets the DMA software reset + * + * This function sets the DMA software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of DMA software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetDmaSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DMA; + + tmp &= ~PCC1_DMA_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_DMA_SWR_SHIFT)) & PCC1_DMA_SWR_MASK); + obj->DMA = tmp; +} + +/*! \brief Gets the MSCM clock enable + * + * This function gets the current MSCM clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MSCM clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetMscmCkEn(const Pcc1RegType *obj) +{ + return ((obj->MSCM & PCC1_MSCM_CKEN_MASK) >> PCC1_MSCM_CKEN_SHIFT); +} + +/*! \brief Sets the MSCM clock enable + * + * This function sets the MSCM clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MSCM clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetMscmCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MSCM; + + tmp &= ~PCC1_MSCM_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_MSCM_CKEN_SHIFT)) & PCC1_MSCM_CKEN_MASK); + obj->MSCM = tmp; +} + +/*! \brief Gets the MSCM software reset + * + * This function gets the current MSCM software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MSCM software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetMscmSwR(const Pcc1RegType *obj) +{ + return ((obj->MSCM & PCC1_MSCM_SWR_MASK) >> PCC1_MSCM_SWR_SHIFT); +} + +/*! \brief Sets the MSCM software reset + * + * This function sets the MSCM software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MSCM software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetMscmSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MSCM; + + tmp &= ~PCC1_MSCM_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_MSCM_SWR_SHIFT)) & PCC1_MSCM_SWR_MASK); + obj->MSCM = tmp; +} + +/*! \brief Gets the CRC clock enable + * + * This function gets the current CRC clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return CRC clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetCrcCkEn(const Pcc1RegType *obj) +{ + return ((obj->CRC & PCC1_CRC_CKEN_MASK) >> PCC1_CRC_CKEN_SHIFT); +} + +/*! \brief Sets the CRC clock enable + * + * This function sets the CRC clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of CRC clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetCrcCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CRC; + + tmp &= ~PCC1_CRC_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_CRC_CKEN_SHIFT)) & PCC1_CRC_CKEN_MASK); + obj->CRC = tmp; +} + +/*! \brief Gets the CRC software reset + * + * This function gets the current CRC software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return CRC software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetCrcSwR(const Pcc1RegType *obj) +{ + return ((obj->CRC & PCC1_CRC_SWR_MASK) >> PCC1_CRC_SWR_SHIFT); +} + +/*! \brief Sets the CRC software reset + * + * This function sets the CRC software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of CRC software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetCrcSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CRC; + + tmp &= ~PCC1_CRC_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_CRC_SWR_SHIFT)) & PCC1_CRC_SWR_MASK); + obj->CRC = tmp; +} + +/*! \brief Gets the EIM clock enable + * + * This function gets the current EIM clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return EIM clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetEimCkEn(const Pcc1RegType *obj) +{ + return ((obj->EIM & PCC1_EIM_CKEN_MASK) >> PCC1_EIM_CKEN_SHIFT); +} + +/*! \brief Sets the EIM clock enable + * + * This function sets the EIM clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of EIM clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetEimCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EIM; + + tmp &= ~PCC1_EIM_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_EIM_CKEN_SHIFT)) & PCC1_EIM_CKEN_MASK); + obj->EIM = tmp; +} + +/*! \brief Gets the EIM software reset + * + * This function gets the current EIM software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return EIM software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetEimSwR(const Pcc1RegType *obj) +{ + return ((obj->EIM & PCC1_EIM_SWR_MASK) >> PCC1_EIM_SWR_SHIFT); +} + +/*! \brief Sets the EIM software reset + * + * This function sets the EIM software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of EIM software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetEimSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EIM; + + tmp &= ~PCC1_EIM_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_EIM_SWR_SHIFT)) & PCC1_EIM_SWR_MASK); + obj->EIM = tmp; +} + +/*! \brief Gets the ERM clock enable + * + * This function gets the current ERM clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return ERM clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetErmCkEn(const Pcc1RegType *obj) +{ + return ((obj->ERM & PCC1_ERM_CKEN_MASK) >> PCC1_ERM_CKEN_SHIFT); +} + +/*! \brief Sets the ERM clock enable + * + * This function sets the ERM clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of ERM clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetErmCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ERM; + + tmp &= ~PCC1_ERM_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_ERM_CKEN_SHIFT)) & PCC1_ERM_CKEN_MASK); + obj->ERM = tmp; +} + +/*! \brief Gets the ERM software reset + * + * This function gets the current ERM software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return ERM software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetErmSwR(const Pcc1RegType *obj) +{ + return ((obj->ERM & PCC1_ERM_SWR_MASK) >> PCC1_ERM_SWR_SHIFT); +} + +/*! \brief Sets the ERM software reset + * + * This function sets the ERM software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of ERM software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetErmSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ERM; + + tmp &= ~PCC1_ERM_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_ERM_SWR_SHIFT)) & PCC1_ERM_SWR_MASK); + obj->ERM = tmp; +} + +/*! \brief Gets the FHU clock enable + * + * This function gets the current FHU clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return FHU clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetFhuCkEn(const Pcc1RegType *obj) +{ + return ((obj->FHU & PCC1_FHU_CKEN_MASK) >> PCC1_FHU_CKEN_SHIFT); +} + +/*! \brief Sets the FHU clock enable + * + * This function sets the FHU clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of FHU clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetFhuCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FHU; + + tmp &= ~PCC1_FHU_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_FHU_CKEN_SHIFT)) & PCC1_FHU_CKEN_MASK); + obj->FHU = tmp; +} + +/*! \brief Gets the FHU software reset + * + * This function gets the current FHU software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return FHU software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetFhuSwR(const Pcc1RegType *obj) +{ + return ((obj->FHU & PCC1_FHU_SWR_MASK) >> PCC1_FHU_SWR_SHIFT); +} + +/*! \brief Sets the FHU software reset + * + * This function sets the FHU software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of FHU software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetFhuSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FHU; + + tmp &= ~PCC1_FHU_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_FHU_SWR_SHIFT)) & PCC1_FHU_SWR_MASK); + obj->FHU = tmp; +} + +/*! \brief Gets the ADC0 module function clock source + * + * This function gets the current ADC0 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return ADC0 module function clock source + * - 0h : clk_sirc + * - 1h : clk_sosc + * - 2h : clk_pll + * - 3h : clk_sirc + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetAdcSrc(const Pcc1RegType *obj) +{ + return ((obj->ADC & PCC1_ADC_SRC_MASK) >> PCC1_ADC_SRC_SHIFT); +} + +/*! \brief Sets the ADC0 module function clock source + * + * This function sets the ADC0 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of ADC0 module function clock source + * - 0h : clk_sirc + * - 1h : clk_sosc + * - 2h : clk_pll + * - 3h : clk_sirc + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetAdcSrc(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~PCC1_ADC_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_ADC_SRC_SHIFT)) & PCC1_ADC_SRC_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the module function clock divide ration + * + * This function gets the current module function clock divide ration. + * + * \param[in] obj : pointer to PCC1 register instance + * \return module function clock divide ration + * - 0h : 1 + * - 1h : 2 + * - 2h : 4 + * - 3h : 8 + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetAdcDiv(const Pcc1RegType *obj) +{ + return ((obj->ADC & PCC1_ADC_DIV_MASK) >> PCC1_ADC_DIV_SHIFT); +} + +/*! \brief Sets the module function clock divide ration + * + * This function sets the module function clock divide ration. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of module function clock divide ration + * - 0h : 1 + * - 1h : 2 + * - 2h : 4 + * - 3h : 8 + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetAdcDiv(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~PCC1_ADC_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_ADC_DIV_SHIFT)) & PCC1_ADC_DIV_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the ADC0 clock enable + * + * This function gets the current ADC0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return ADC0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetAdcCkEn(const Pcc1RegType *obj) +{ + return ((obj->ADC & PCC1_ADC_CKEN_MASK) >> PCC1_ADC_CKEN_SHIFT); +} + +/*! \brief Sets the ADC0 clock enable + * + * This function sets the ADC0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of ADC0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetAdcCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~PCC1_ADC_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_ADC_CKEN_SHIFT)) & PCC1_ADC_CKEN_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the ADC0 software reset + * + * This function gets the current ADC0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return ADC0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetAdcSwR(const Pcc1RegType *obj) +{ + return ((obj->ADC & PCC1_ADC_SWR_MASK) >> PCC1_ADC_SWR_SHIFT); +} + +/*! \brief Sets the ADC0 software reset + * + * This function sets the ADC0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of ADC0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetAdcSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~PCC1_ADC_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_ADC_SWR_SHIFT)) & PCC1_ADC_SWR_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the PDB0 clock enable + * + * This function gets the current PDB0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return PDB0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetPdbCkEn(const Pcc1RegType *obj) +{ + return ((obj->PDB & PCC1_PDB_CKEN_MASK) >> PCC1_PDB_CKEN_SHIFT); +} + +/*! \brief Sets the PDB0 clock enable + * + * This function sets the PDB0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of PDB0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetPdbCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PDB; + + tmp &= ~PCC1_PDB_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_PDB_CKEN_SHIFT)) & PCC1_PDB_CKEN_MASK); + obj->PDB = tmp; +} + +/*! \brief Gets the PDB0 software reset + * + * This function gets the current PDB0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return PDB0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetPdbSwR(const Pcc1RegType *obj) +{ + return ((obj->PDB & PCC1_PDB_SWR_MASK) >> PCC1_PDB_SWR_SHIFT); +} + +/*! \brief Sets the PDB0 software reset + * + * This function sets the PDB0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of PDB0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetPdbSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PDB; + + tmp &= ~PCC1_PDB_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_PDB_SWR_SHIFT)) & PCC1_PDB_SWR_MASK); + obj->PDB = tmp; +} + +/*! \brief Gets the SPI0 module function clock source + * + * This function gets the current SPI0 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return SPI0 module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetSpi0Src(const Pcc1RegType *obj) +{ + return ((obj->SPI0 & PCC1_SPI0_SRC_MASK) >> PCC1_SPI0_SRC_SHIFT); +} + +/*! \brief Sets the SPI0 module function clock source + * + * This function sets the SPI0 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of SPI0 module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetSpi0Src(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SPI0; + + tmp &= ~PCC1_SPI0_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_SPI0_SRC_SHIFT)) & PCC1_SPI0_SRC_MASK); + obj->SPI0 = tmp; +} + +/*! \brief Gets the SPI0 clock enable + * + * This function gets the current SPI0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return SPI0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetSpi0CkEn(const Pcc1RegType *obj) +{ + return ((obj->SPI0 & PCC1_SPI0_CKEN_MASK) >> PCC1_SPI0_CKEN_SHIFT); +} + +/*! \brief Sets the SPI0 clock enable + * + * This function sets the SPI0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of SPI0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetSpi0CkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SPI0; + + tmp &= ~PCC1_SPI0_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_SPI0_CKEN_SHIFT)) & PCC1_SPI0_CKEN_MASK); + obj->SPI0 = tmp; +} + +/*! \brief Gets the SPI0 software reset + * + * This function gets the current SPI0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return SPI0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetSpi0SwR(const Pcc1RegType *obj) +{ + return ((obj->SPI0 & PCC1_SPI0_SWR_MASK) >> PCC1_SPI0_SWR_SHIFT); +} + +/*! \brief Sets the SPI0 software reset + * + * This function sets the SPI0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of SPI0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetSpi0SwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SPI0; + + tmp &= ~PCC1_SPI0_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_SPI0_SWR_SHIFT)) & PCC1_SPI0_SWR_MASK); + obj->SPI0 = tmp; +} + +/*! \brief Gets the SPI1 module function clock source + * + * This function gets the current SPI1 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return SPI1 module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetSpi1Src(const Pcc1RegType *obj) +{ + return ((obj->SPI1 & PCC1_SPI1_SRC_MASK) >> PCC1_SPI1_SRC_SHIFT); +} + +/*! \brief Sets the SPI1 module function clock source + * + * This function sets the SPI1 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of SPI1 module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetSpi1Src(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SPI1; + + tmp &= ~PCC1_SPI1_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_SPI1_SRC_SHIFT)) & PCC1_SPI1_SRC_MASK); + obj->SPI1 = tmp; +} + +/*! \brief Gets the SPI1 clock enable + * + * This function gets the current SPI1 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return SPI1 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetSpi1CkEn(const Pcc1RegType *obj) +{ + return ((obj->SPI1 & PCC1_SPI1_CKEN_MASK) >> PCC1_SPI1_CKEN_SHIFT); +} + +/*! \brief Sets the SPI1 clock enable + * + * This function sets the SPI1 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of SPI1 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetSpi1CkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SPI1; + + tmp &= ~PCC1_SPI1_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_SPI1_CKEN_SHIFT)) & PCC1_SPI1_CKEN_MASK); + obj->SPI1 = tmp; +} + +/*! \brief Gets the SPI1 software reset + * + * This function gets the current SPI1 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return SPI1 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetSpi1SwR(const Pcc1RegType *obj) +{ + return ((obj->SPI1 & PCC1_SPI1_SWR_MASK) >> PCC1_SPI1_SWR_SHIFT); +} + +/*! \brief Sets the SPI1 software reset + * + * This function sets the SPI1 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of SPI1 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetSpi1SwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SPI1; + + tmp &= ~PCC1_SPI1_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_SPI1_SWR_SHIFT)) & PCC1_SPI1_SWR_MASK); + obj->SPI1 = tmp; +} + +/*! \brief Gets the UART0 module function clock source + * + * This function gets the current UART0 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return UART0 module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetUart0Src(const Pcc1RegType *obj) +{ + return ((obj->UART0 & PCC1_UART0_SRC_MASK) >> PCC1_UART0_SRC_SHIFT); +} + +/*! \brief Sets the UART0 module function clock source + * + * This function sets the UART0 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of UART0 module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetUart0Src(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->UART0; + + tmp &= ~PCC1_UART0_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_UART0_SRC_SHIFT)) & PCC1_UART0_SRC_MASK); + obj->UART0 = tmp; +} + +/*! \brief Gets the UART0 clock enable + * + * This function gets the current UART0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return UART0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetUart0CkEn(const Pcc1RegType *obj) +{ + return ((obj->UART0 & PCC1_UART0_CKEN_MASK) >> PCC1_UART0_CKEN_SHIFT); +} + +/*! \brief Sets the UART0 clock enable + * + * This function sets the UART0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of UART0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetUart0CkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->UART0; + + tmp &= ~PCC1_UART0_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_UART0_CKEN_SHIFT)) & PCC1_UART0_CKEN_MASK); + obj->UART0 = tmp; +} + +/*! \brief Gets the UART0 software reset + * + * This function gets the current UART0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return UART0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetUart0SwR(const Pcc1RegType *obj) +{ + return ((obj->UART0 & PCC1_UART0_SWR_MASK) >> PCC1_UART0_SWR_SHIFT); +} + +/*! \brief Sets the UART0 software reset + * + * This function sets the UART0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of UART0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetUart0SwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->UART0; + + tmp &= ~PCC1_UART0_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_UART0_SWR_SHIFT)) & PCC1_UART0_SWR_MASK); + obj->UART0 = tmp; +} + +/*! \brief Gets the UART1 module function clock source + * + * This function gets the current UART1 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return UART1 module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetUart1Src(const Pcc1RegType *obj) +{ + return ((obj->UART1 & PCC1_UART1_SRC_MASK) >> PCC1_UART1_SRC_SHIFT); +} + +/*! \brief Sets the UART1 module function clock source + * + * This function sets the UART1 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of UART1 module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetUart1Src(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->UART1; + + tmp &= ~PCC1_UART1_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_UART1_SRC_SHIFT)) & PCC1_UART1_SRC_MASK); + obj->UART1 = tmp; +} + +/*! \brief Gets the UART1 clock enable + * + * This function gets the current UART1 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return UART1 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetUart1CkEn(const Pcc1RegType *obj) +{ + return ((obj->UART1 & PCC1_UART1_CKEN_MASK) >> PCC1_UART1_CKEN_SHIFT); +} + +/*! \brief Sets the UART1 clock enable + * + * This function sets the UART1 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of UART1 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetUart1CkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->UART1; + + tmp &= ~PCC1_UART1_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_UART1_CKEN_SHIFT)) & PCC1_UART1_CKEN_MASK); + obj->UART1 = tmp; +} + +/*! \brief Gets the UART1 software reset + * + * This function gets the current UART1 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return UART1 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetUart1SwR(const Pcc1RegType *obj) +{ + return ((obj->UART1 & PCC1_UART1_SWR_MASK) >> PCC1_UART1_SWR_SHIFT); +} + +/*! \brief Sets the UART1 software reset + * + * This function sets the UART1 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of UART1 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetUart1SwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->UART1; + + tmp &= ~PCC1_UART1_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_UART1_SWR_SHIFT)) & PCC1_UART1_SWR_MASK); + obj->UART1 = tmp; +} + +/*! \brief Gets the UART2 module function clock source + * + * This function gets the current UART2 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return UART2 module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetUart2Src(const Pcc1RegType *obj) +{ + return ((obj->UART2 & PCC1_UART2_SRC_MASK) >> PCC1_UART2_SRC_SHIFT); +} + +/*! \brief Sets the UART2 module function clock source + * + * This function sets the UART2 module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of UART2 module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetUart2Src(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->UART2; + + tmp &= ~PCC1_UART2_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_UART2_SRC_SHIFT)) & PCC1_UART2_SRC_MASK); + obj->UART2 = tmp; +} + +/*! \brief Gets the UART2 clock enable + * + * This function gets the current UART2 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return UART2 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetUart2CkEn(const Pcc1RegType *obj) +{ + return ((obj->UART2 & PCC1_UART2_CKEN_MASK) >> PCC1_UART2_CKEN_SHIFT); +} + +/*! \brief Sets the UART2 clock enable + * + * This function sets the UART2 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of UART2 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetUart2CkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->UART2; + + tmp &= ~PCC1_UART2_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_UART2_CKEN_SHIFT)) & PCC1_UART2_CKEN_MASK); + obj->UART2 = tmp; +} + +/*! \brief Gets the UART2 software reset + * + * This function gets the current UART2 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return UART2 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetUart2SwR(const Pcc1RegType *obj) +{ + return ((obj->UART2 & PCC1_UART2_SWR_MASK) >> PCC1_UART2_SWR_SHIFT); +} + +/*! \brief Sets the UART2 software reset + * + * This function sets the UART2 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of UART2 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetUart2SwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->UART2; + + tmp &= ~PCC1_UART2_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_UART2_SWR_SHIFT)) & PCC1_UART2_SWR_MASK); + obj->UART2 = tmp; +} + +/*! \brief Gets the CAN configure clock enable + * + * This function gets the current CAN configure clock enable. + * It works for both function clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return CAN configure clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetCanCfgCkEn(const Pcc1RegType *obj) +{ + return ((obj->CAN & PCC1_CAN_CFG_CKEN_MASK) >> PCC1_CAN_CFG_CKEN_SHIFT); +} + +/*! \brief Sets the CAN configure clock enable + * + * This function sets the CAN configure clock enable. + * It works for both function clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of CAN configure clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetCanCfgCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CAN; + + tmp &= ~PCC1_CAN_CFG_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_CAN_CFG_CKEN_SHIFT)) & PCC1_CAN_CFG_CKEN_MASK); + obj->CAN = tmp; +} + +/*! \brief Gets the CAN work clock enable + * + * This function gets the current CAN work clock enable. + * It works for both function clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return CAN work clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetCanCkEn(const Pcc1RegType *obj) +{ + return ((obj->CAN & PCC1_CAN_CKEN_MASK) >> PCC1_CAN_CKEN_SHIFT); +} + +/*! \brief Sets the CAN work clock enable + * + * This function sets the CAN work clock enable. + * It works for both function clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of CAN work clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetCanCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CAN; + + tmp &= ~PCC1_CAN_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_CAN_CKEN_SHIFT)) & PCC1_CAN_CKEN_MASK); + obj->CAN = tmp; +} + +/*! \brief Gets the CAN software reset + * + * This function gets the current CAN software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return CAN software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetCanSwR(const Pcc1RegType *obj) +{ + return ((obj->CAN & PCC1_CAN_SWR_MASK) >> PCC1_CAN_SWR_SHIFT); +} + +/*! \brief Sets the CAN software reset + * + * This function sets the CAN software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of CAN software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetCanSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CAN; + + tmp &= ~PCC1_CAN_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_CAN_SWR_SHIFT)) & PCC1_CAN_SWR_MASK); + obj->CAN = tmp; +} + +/*! \brief Gets the I2C module function clock source + * + * This function gets the current I2C module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return I2C module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetI2CSrc(const Pcc1RegType *obj) +{ + return ((obj->I2C & PCC1_I2C_SRC_MASK) >> PCC1_I2C_SRC_SHIFT); +} + +/*! \brief Sets the I2C module function clock source + * + * This function sets the I2C module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of I2C module function clock source + * - 0h : clk_sirc_div + * - 1h : clk_sosc_div + * - 2h : clk_pll_div + * - 3h : clk_sirc_div + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetI2CSrc(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2C; + + tmp &= ~PCC1_I2C_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_I2C_SRC_SHIFT)) & PCC1_I2C_SRC_MASK); + obj->I2C = tmp; +} + +/*! \brief Gets the I2C clock enable + * + * This function gets the current I2C clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return I2C clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetI2CCkEn(const Pcc1RegType *obj) +{ + return ((obj->I2C & PCC1_I2C_CKEN_MASK) >> PCC1_I2C_CKEN_SHIFT); +} + +/*! \brief Sets the I2C clock enable + * + * This function sets the I2C clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of I2C clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetI2CCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2C; + + tmp &= ~PCC1_I2C_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_I2C_CKEN_SHIFT)) & PCC1_I2C_CKEN_MASK); + obj->I2C = tmp; +} + +/*! \brief Gets the I2C software reset + * + * This function gets the current I2C software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return I2C software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetI2CSwR(const Pcc1RegType *obj) +{ + return ((obj->I2C & PCC1_I2C_SWR_MASK) >> PCC1_I2C_SWR_SHIFT); +} + +/*! \brief Sets the I2C software reset + * + * This function sets the I2C software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of I2C software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetI2CSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2C; + + tmp &= ~PCC1_I2C_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_I2C_SWR_SHIFT)) & PCC1_I2C_SWR_MASK); + obj->I2C = tmp; +} + +/*! \brief Gets the I2SM module function clock source + * + * This function gets the current I2SM module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return I2SM module function clock source + * - 0h : clk_sirc + * - 1h : clk_sosc + * - 2h : clk_pll + * - 3h : clk_sirc + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetI2SMSrc(const Pcc1RegType *obj) +{ + return ((obj->I2SM & PCC1_I2SM_SRC_MASK) >> PCC1_I2SM_SRC_SHIFT); +} + +/*! \brief Sets the I2SM module function clock source + * + * This function sets the I2SM module function clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of I2SM module function clock source + * - 0h : clk_sirc + * - 1h : clk_sosc + * - 2h : clk_pll + * - 3h : clk_sirc + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetI2SMSrc(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2SM; + + tmp &= ~PCC1_I2SM_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_I2SM_SRC_SHIFT)) & PCC1_I2SM_SRC_MASK); + obj->I2SM = tmp; +} + +/*! \brief Gets the I2S MST module clock divide ratio + * + * This function gets the current I2S MST module clock divide ratio. + * + * \param[in] obj : pointer to PCC1 register instance + * \return I2S MST module clock divide ratio + * - 0h : 2 + * - 1h : 2 + * - 2h : 3 + * . + * . + * . + * - 63h : 64 + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetI2SMDiv(const Pcc1RegType *obj) +{ + return ((obj->I2SM & PCC1_I2SM_DIV_MASK) >> PCC1_I2SM_DIV_SHIFT); +} + +/*! \brief Sets the I2S MST module clock divide ratio + * + * This function sets the I2S MST module clock divide ratio. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of I2S MST module clock divide ratio + * - 0h : 2 + * - 1h : 2 + * - 2h : 3 + * . + * . + * . + * - 63h : 64 + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetI2SMDiv(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2SM; + + tmp &= ~PCC1_I2SM_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_I2SM_DIV_SHIFT)) & PCC1_I2SM_DIV_MASK); + obj->I2SM = tmp; +} + +/*! \brief Gets the I2S master clock enable + * + * This function gets the current I2S master clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return I2S master clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetI2SMCkEn(const Pcc1RegType *obj) +{ + return ((obj->I2SM & PCC1_I2SM_CKEN_MASK) >> PCC1_I2SM_CKEN_SHIFT); +} + +/*! \brief Sets the I2S master clock enable + * + * This function sets the I2S master clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of I2S master clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetI2SMCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2SM; + + tmp &= ~PCC1_I2SM_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_I2SM_CKEN_SHIFT)) & PCC1_I2SM_CKEN_MASK); + obj->I2SM = tmp; +} + +/*! \brief Gets the I2S MASTER software reset + * + * This function gets the current I2S MASTER software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return I2S MASTER software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetI2SMSwR(const Pcc1RegType *obj) +{ + return ((obj->I2SM & PCC1_I2SM_SWR_MASK) >> PCC1_I2SM_SWR_SHIFT); +} + +/*! \brief Sets the I2S MASTER software reset + * + * This function sets the I2S MASTER software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of I2S MASTER software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetI2SMSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2SM; + + tmp &= ~PCC1_I2SM_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_I2SM_SWR_SHIFT)) & PCC1_I2SM_SWR_MASK); + obj->I2SM = tmp; +} + +/*! \brief Gets the I2S slave clock enable + * + * This function gets the current I2S slave clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return I2S slave clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetI2SSCkEn(const Pcc1RegType *obj) +{ + return ((obj->I2SS & PCC1_I2SS_CKEN_MASK) >> PCC1_I2SS_CKEN_SHIFT); +} + +/*! \brief Sets the I2S slave clock enable + * + * This function sets the I2S slave clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of I2S slave clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetI2SSCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2SS; + + tmp &= ~PCC1_I2SS_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_I2SS_CKEN_SHIFT)) & PCC1_I2SS_CKEN_MASK); + obj->I2SS = tmp; +} + +/*! \brief Gets the I2S SLAVE software reset + * + * This function gets the current I2S SLAVE software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return I2S SLAVE software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetI2SSSwR(const Pcc1RegType *obj) +{ + return ((obj->I2SS & PCC1_I2SS_SWR_MASK) >> PCC1_I2SS_SWR_SHIFT); +} + +/*! \brief Sets the I2S SLAVE software reset + * + * This function sets the I2S SLAVE software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of I2S SLAVE software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetI2SSSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2SS; + + tmp &= ~PCC1_I2SS_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_I2SS_SWR_SHIFT)) & PCC1_I2SS_SWR_MASK); + obj->I2SS = tmp; +} + +/*! \brief Gets the PWM0 clock enable + * + * This function gets the current PWM0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return PWM0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetPwm0CkEn(const Pcc1RegType *obj) +{ + return ((obj->PWM0 & PCC1_PWM0_CKEN_MASK) >> PCC1_PWM0_CKEN_SHIFT); +} + +/*! \brief Sets the PWM0 clock enable + * + * This function sets the PWM0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of PWM0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetPwm0CkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWM0; + + tmp &= ~PCC1_PWM0_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_PWM0_CKEN_SHIFT)) & PCC1_PWM0_CKEN_MASK); + obj->PWM0 = tmp; +} + +/*! \brief Gets the PWM0 software reset + * + * This function gets the current PWM0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return PWM0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetPwm0SwR(const Pcc1RegType *obj) +{ + return ((obj->PWM0 & PCC1_PWM0_SWR_MASK) >> PCC1_PWM0_SWR_SHIFT); +} + +/*! \brief Sets the PWM0 software reset + * + * This function sets the PWM0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of PWM0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetPwm0SwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWM0; + + tmp &= ~PCC1_PWM0_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_PWM0_SWR_SHIFT)) & PCC1_PWM0_SWR_MASK); + obj->PWM0 = tmp; +} + +/*! \brief Gets the PWM1 clock enable + * + * This function gets the current PWM1 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return PWM1 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetPwm1CkEn(const Pcc1RegType *obj) +{ + return ((obj->PWM1 & PCC1_PWM1_CKEN_MASK) >> PCC1_PWM1_CKEN_SHIFT); +} + +/*! \brief Sets the PWM1 clock enable + * + * This function sets the PWM1 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of PWM1 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetPwm1CkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWM1; + + tmp &= ~PCC1_PWM1_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_PWM1_CKEN_SHIFT)) & PCC1_PWM1_CKEN_MASK); + obj->PWM1 = tmp; +} + +/*! \brief Gets the PWM1 software reset + * + * This function gets the current PWM1 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return PWM1 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetPwm1SwR(const Pcc1RegType *obj) +{ + return ((obj->PWM1 & PCC1_PWM1_SWR_MASK) >> PCC1_PWM1_SWR_SHIFT); +} + +/*! \brief Sets the PWM1 software reset + * + * This function sets the PWM1 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of PWM1 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetPwm1SwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWM1; + + tmp &= ~PCC1_PWM1_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_PWM1_SWR_SHIFT)) & PCC1_PWM1_SWR_MASK); + obj->PWM1 = tmp; +} + +/*! \brief Gets the MFT0 clock enable + * + * This function gets the current MFT0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MFT0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetMft0CkEn(const Pcc1RegType *obj) +{ + return ((obj->MFT0 & PCC1_MFT0_CKEN_MASK) >> PCC1_MFT0_CKEN_SHIFT); +} + +/*! \brief Sets the MFT0 clock enable + * + * This function sets the MFT0 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MFT0 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetMft0CkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT0; + + tmp &= ~PCC1_MFT0_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_MFT0_CKEN_SHIFT)) & PCC1_MFT0_CKEN_MASK); + obj->MFT0 = tmp; +} + +/*! \brief Gets the MFT0 software reset + * + * This function gets the current MFT0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MFT0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetMft0SwR(const Pcc1RegType *obj) +{ + return ((obj->MFT0 & PCC1_MFT0_SWR_MASK) >> PCC1_MFT0_SWR_SHIFT); +} + +/*! \brief Sets the MFT0 software reset + * + * This function sets the MFT0 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MFT0 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetMft0SwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT0; + + tmp &= ~PCC1_MFT0_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_MFT0_SWR_SHIFT)) & PCC1_MFT0_SWR_MASK); + obj->MFT0 = tmp; +} + +/*! \brief Gets the MFT1 clock enable + * + * This function gets the current MFT1 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MFT1 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetMft1CkEn(const Pcc1RegType *obj) +{ + return ((obj->MFT1 & PCC1_MFT1_CKEN_MASK) >> PCC1_MFT1_CKEN_SHIFT); +} + +/*! \brief Sets the MFT1 clock enable + * + * This function sets the MFT1 clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MFT1 clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetMft1CkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT1; + + tmp &= ~PCC1_MFT1_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_MFT1_CKEN_SHIFT)) & PCC1_MFT1_CKEN_MASK); + obj->MFT1 = tmp; +} + +/*! \brief Gets the MFT1 software reset + * + * This function gets the current MFT1 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MFT1 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetMft1SwR(const Pcc1RegType *obj) +{ + return ((obj->MFT1 & PCC1_MFT1_SWR_MASK) >> PCC1_MFT1_SWR_SHIFT); +} + +/*! \brief Sets the MFT1 software reset + * + * This function sets the MFT1 software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MFT1 software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetMft1SwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT1; + + tmp &= ~PCC1_MFT1_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_MFT1_SWR_SHIFT)) & PCC1_MFT1_SWR_MASK); + obj->MFT1 = tmp; +} + +/*! \brief Gets the GPIO software reset + * + * This function gets the current GPIO software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return GPIO software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetGpioSwR(const Pcc1RegType *obj) +{ + return ((obj->GPIO & PCC1_GPIO_SWR_MASK) >> PCC1_GPIO_SWR_SHIFT); +} + +/*! \brief Sets the GPIO software reset + * + * This function sets the GPIO software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of GPIO software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetGpioSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->GPIO; + + tmp &= ~PCC1_GPIO_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_GPIO_SWR_SHIFT)) & PCC1_GPIO_SWR_MASK); + obj->GPIO = tmp; +} + +/*! \brief Gets the CMUS clock enable + * + * This function gets the current CMUS clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return CMUS clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetCmusCkEn(const Pcc1RegType *obj) +{ + return ((obj->CMUS & PCC1_CMUS_CKEN_MASK) >> PCC1_CMUS_CKEN_SHIFT); +} + +/*! \brief Sets the CMUS clock enable + * + * This function sets the CMUS clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of CMUS clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetCmusCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CMUS; + + tmp &= ~PCC1_CMUS_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_CMUS_CKEN_SHIFT)) & PCC1_CMUS_CKEN_MASK); + obj->CMUS = tmp; +} + +/*! \brief Gets the CMUS software reset + * + * This function gets the current CMUS software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return CMUS software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetCmusSwR(const Pcc1RegType *obj) +{ + return ((obj->CMUS & PCC1_CMUS_SWR_MASK) >> PCC1_CMUS_SWR_SHIFT); +} + +/*! \brief Sets the CMUS software reset + * + * This function sets the CMUS software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of CMUS software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetCmusSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CMUS; + + tmp &= ~PCC1_CMUS_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_CMUS_SWR_SHIFT)) & PCC1_CMUS_SWR_MASK); + obj->CMUS = tmp; +} + +/*! \brief Gets the CMUP clock enable + * + * This function gets the current CMUP clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return CMUP clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetCmupCkEn(const Pcc1RegType *obj) +{ + return ((obj->CMUP & PCC1_CMUP_CKEN_MASK) >> PCC1_CMUP_CKEN_SHIFT); +} + +/*! \brief Sets the CMUP clock enable + * + * This function sets the CMUP clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of CMUP clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetCmupCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CMUP; + + tmp &= ~PCC1_CMUP_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_CMUP_CKEN_SHIFT)) & PCC1_CMUP_CKEN_MASK); + obj->CMUP = tmp; +} + +/*! \brief Gets the CMUP software reset + * + * This function gets the current CMUP software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return CMUP software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetCmupSwR(const Pcc1RegType *obj) +{ + return ((obj->CMUP & PCC1_CMUP_SWR_MASK) >> PCC1_CMUP_SWR_SHIFT); +} + +/*! \brief Sets the CMUP software reset + * + * This function sets the CMUP software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of CMUP software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetCmupSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CMUP; + + tmp &= ~PCC1_CMUP_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_CMUP_SWR_SHIFT)) & PCC1_CMUP_SWR_MASK); + obj->CMUP = tmp; +} + +/*! \brief Gets the MFT0 external clock source + * + * This function gets the current MFT0 external clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MFT0 external clock source + * - 0h : TCLK0 + * - 1h : TCLK1 + * - 2h : TCLK2 + * - 3h : clk_sirc_div_mft + * - 4h : clk_sosc_div_mft + * - 5h : clk_pll_div_mft + * - 6h : clk_sirc_div_mft + * - 7h : clk_sirc_div_mft + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetExtMft0Src(const Pcc1RegType *obj) +{ + return ((obj->EXT_MFT0 & PCC1_EXT_MFT0_SRC_MASK) >> PCC1_EXT_MFT0_SRC_SHIFT); +} + +/*! \brief Sets the MFT0 external clock source + * + * This function sets the MFT0 external clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MFT0 external clock source + * - 0h : TCLK0 + * - 1h : TCLK1 + * - 2h : TCLK2 + * - 3h : clk_sirc_div_mft + * - 4h : clk_sosc_div_mft + * - 5h : clk_pll_div_mft + * - 6h : clk_sirc_div_mft + * - 7h : clk_sirc_div_mft + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetExtMft0Src(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXT_MFT0; + + tmp &= ~PCC1_EXT_MFT0_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_EXT_MFT0_SRC_SHIFT)) & PCC1_EXT_MFT0_SRC_MASK); + obj->EXT_MFT0 = tmp; +} + +/*! \brief Gets the MFT1 external clock source + * + * This function gets the current MFT1 external clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MFT1 external clock source + * - 0h : TCLK0 + * - 1h : TCLK1 + * - 2h : TCLK2 + * - 3h : clk_sirc_div_mft + * - 4h : clk_sosc_div_mft + * - 5h : clk_pll_div_mft + * - 6h : clk_sirc_div_mft + * - 7h : clk_sirc_div_mft + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetExtMft1Src(const Pcc1RegType *obj) +{ + return ((obj->EXT_MFT1 & PCC1_EXT_MFT1_SRC_MASK) >> PCC1_EXT_MFT1_SRC_SHIFT); +} + +/*! \brief Sets the MFT1 external clock source + * + * This function sets the MFT1 external clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MFT1 external clock source + * - 0h : TCLK0 + * - 1h : TCLK1 + * - 2h : TCLK2 + * - 3h : clk_sirc_div_mft + * - 4h : clk_sosc_div_mft + * - 5h : clk_pll_div_mft + * - 6h : clk_sirc_div_mft + * - 7h : clk_sirc_div_mft + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetExtMft1Src(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXT_MFT1; + + tmp &= ~PCC1_EXT_MFT1_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_EXT_MFT1_SRC_SHIFT)) & PCC1_EXT_MFT1_SRC_MASK); + obj->EXT_MFT1 = tmp; +} + +/*! \brief Gets the MFT0 fix clock source + * + * This function gets the current MFT0 fix clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MFT0 fix clock source + * - 0b : clk_lpo32 + * - 1b : RTC_CLKIN + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetFixMft0Src(const Pcc1RegType *obj) +{ + return ((obj->FIX_MFT0 & PCC1_FIX_MFT0_SRC_MASK) >> PCC1_FIX_MFT0_SRC_SHIFT); +} + +/*! \brief Sets the MFT0 fix clock source + * + * This function sets the MFT0 fix clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MFT0 fix clock source + * - 0b : clk_lpo32 + * - 1b : RTC_CLKIN + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetFixMft0Src(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FIX_MFT0; + + tmp &= ~PCC1_FIX_MFT0_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_FIX_MFT0_SRC_SHIFT)) & PCC1_FIX_MFT0_SRC_MASK); + obj->FIX_MFT0 = tmp; +} + +/*! \brief Gets the MFT1 fix clock source + * + * This function gets the current MFT1 fix clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MFT1 fix clock source + * - 0b : clk_lpo32 + * - 1b : RTC_CLKIN + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetFixMft1Src(const Pcc1RegType *obj) +{ + return ((obj->FIX_MFT1 & PCC1_FIX_MFT1_SRC_MASK) >> PCC1_FIX_MFT1_SRC_SHIFT); +} + +/*! \brief Sets the MFT1 fix clock source + * + * This function sets the MFT1 fix clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MFT1 fix clock source + * - 0b : clk_lpo32 + * - 1b : RTC_CLKIN + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetFixMft1Src(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FIX_MFT1; + + tmp &= ~PCC1_FIX_MFT1_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_FIX_MFT1_SRC_SHIFT)) & PCC1_FIX_MFT1_SRC_MASK); + obj->FIX_MFT1 = tmp; +} + +/*! \brief Gets the flash_ctrl module counter clock source + * + * This function gets the current flash_ctrl module counter clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \return flash_ctrl module counter clock source + * - 0h : clk_sirc + * - 1h : clk_sosc + * - 2h : clk_pll + * - 3h : clk_sirc + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetFlsCtlCntSrc(const Pcc1RegType *obj) +{ + return ((obj->FLS_CTL & PCC1_FLS_CTL_CNT_SRC_MASK) >> PCC1_FLS_CTL_CNT_SRC_SHIFT); +} + +/*! \brief Sets the flash_ctrl module counter clock source + * + * This function sets the flash_ctrl module counter clock source. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of flash_ctrl module counter clock source + * - 0h : clk_sirc + * - 1h : clk_sosc + * - 2h : clk_pll + * - 3h : clk_sirc + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetFlsCtlCntSrc(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLS_CTL; + + tmp &= ~PCC1_FLS_CTL_CNT_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_FLS_CTL_CNT_SRC_SHIFT)) & PCC1_FLS_CTL_CNT_SRC_MASK); + obj->FLS_CTL = tmp; +} + +/*! \brief Gets the FLS_CTRL modulecounter clock divide ratio + * + * This function gets the current FLS_CTRL modulecounter clock divide ratio. + * + * \param[in] obj : pointer to PCC1 register instance + * \return FLS_CTRL modulecounter clock divide ratio + * - 0h : 1 + * - 1h : 2 + * - 2h : 3 + * . + * . + * . + * - Fh : 16 + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetFlsCtlCntDiv(const Pcc1RegType *obj) +{ + return ((obj->FLS_CTL & PCC1_FLS_CTL_CNT_DIV_MASK) >> PCC1_FLS_CTL_CNT_DIV_SHIFT); +} + +/*! \brief Sets the FLS_CTRL modulecounter clock divide ratio + * + * This function sets the FLS_CTRL modulecounter clock divide ratio. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of FLS_CTRL modulecounter clock divide ratio + * - 0h : 1 + * - 1h : 2 + * - 2h : 3 + * . + * . + * . + * - Fh : 16 + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetFlsCtlCntDiv(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLS_CTL; + + tmp &= ~PCC1_FLS_CTL_CNT_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_FLS_CTL_CNT_DIV_SHIFT)) & PCC1_FLS_CTL_CNT_DIV_MASK); + obj->FLS_CTL = tmp; +} + +/*! \brief Gets the FLS_CTL clock enable + * + * This function gets the current FLS_CTL clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return FLS_CTL clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetFlsCtlCkEn(const Pcc1RegType *obj) +{ + return ((obj->FLS_CTL & PCC1_FLS_CTL_CKEN_MASK) >> PCC1_FLS_CTL_CKEN_SHIFT); +} + +/*! \brief Sets the FLS_CTL clock enable + * + * This function sets the FLS_CTL clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of FLS_CTL clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetFlsCtlCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLS_CTL; + + tmp &= ~PCC1_FLS_CTL_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_FLS_CTL_CKEN_SHIFT)) & PCC1_FLS_CTL_CKEN_MASK); + obj->FLS_CTL = tmp; +} + +/*! \brief Gets the FLS_CTL software reset + * + * This function gets the current FLS_CTL software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return FLS_CTL software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetFlsCtlSwR(const Pcc1RegType *obj) +{ + return ((obj->FLS_CTL & PCC1_FLS_CTL_SWR_MASK) >> PCC1_FLS_CTL_SWR_SHIFT); +} + +/*! \brief Sets the FLS_CTL software reset + * + * This function sets the FLS_CTL software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of FLS_CTL software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetFlsCtlSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLS_CTL; + + tmp &= ~PCC1_FLS_CTL_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_FLS_CTL_SWR_SHIFT)) & PCC1_FLS_CTL_SWR_MASK); + obj->FLS_CTL = tmp; +} + +/*! \brief Gets the MPU clock enable + * + * This function gets the current MPU clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MPU clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetMpuCkEn(const Pcc1RegType *obj) +{ + return ((obj->MPU & PCC1_MPU_CKEN_MASK) >> PCC1_MPU_CKEN_SHIFT); +} + +/*! \brief Sets the MPU clock enable + * + * This function sets the MPU clock enable. + * It works for both function clock and configure clock. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MPU clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetMpuCkEn(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MPU; + + tmp &= ~PCC1_MPU_CKEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_MPU_CKEN_SHIFT)) & PCC1_MPU_CKEN_MASK); + obj->MPU = tmp; +} + +/*! \brief Gets the MPU software reset + * + * This function gets the current MPU software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \return MPU software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline uint8_t Pcc1Reg_GetMpuSwR(const Pcc1RegType *obj) +{ + return ((obj->MPU & PCC1_MPU_SWR_MASK) >> PCC1_MPU_SWR_SHIFT); +} + +/*! \brief Sets the MPU software reset + * + * This function sets the MPU software reset. + * It works for both function clock domain and configure clock domain. + * + * \param[in] obj : pointer to PCC1 register instance + * \param[in] value : the value of MPU software reset + * - 0b : normal + * - 1b : reset + */ +__attribute__((always_inline)) static inline void Pcc1Reg_SetMpuSwR(Pcc1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MPU; + + tmp &= ~PCC1_MPU_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PCC1_MPU_SWR_SHIFT)) & PCC1_MPU_SWR_MASK); + obj->MPU = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _PCC1_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/pdb_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/pdb_reg.h new file mode 100644 index 0000000..2feaabf --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/pdb_reg.h @@ -0,0 +1,1032 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PDB_REG_H_ +#define _PDB_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the PDB (Programmable Delay Block) Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* PDB - Size of Registers Arrays */ +#define PDB_CH_COUNT (2u) +#define PDB_DLY_COUNT (8u) +#define PDB_PODLY_COUNT (1u) + +/* SC Bit Fields */ +#define PDB_SC_LDMOD_MASK (0xC0000u) +#define PDB_SC_LDMOD_SHIFT (18u) +#define PDB_SC_LDMOD_WIDTH (2u) +#define PDB_SC_PDBEIE_MASK (0x20000u) +#define PDB_SC_PDBEIE_SHIFT (17u) +#define PDB_SC_PDBEIE_WIDTH (1u) +#define PDB_SC_SWTRIG_MASK (0x10000u) +#define PDB_SC_SWTRIG_SHIFT (16u) +#define PDB_SC_SWTRIG_WIDTH (1u) +#define PDB_SC_DMAEN_MASK (0x8000u) +#define PDB_SC_DMAEN_SHIFT (15u) +#define PDB_SC_DMAEN_WIDTH (1u) +#define PDB_SC_PRESCALER_MASK (0x7000u) +#define PDB_SC_PRESCALER_SHIFT (12u) +#define PDB_SC_PRESCALER_WIDTH (3u) +#define PDB_SC_TRGSEL_MASK (0xF00u) +#define PDB_SC_TRGSEL_SHIFT (8u) +#define PDB_SC_TRGSEL_WIDTH (4u) +#define PDB_SC_PDBEN_MASK (0x80u) +#define PDB_SC_PDBEN_SHIFT (7u) +#define PDB_SC_PDBEN_WIDTH (1u) +#define PDB_SC_PDBIF_MASK (0x40u) +#define PDB_SC_PDBIF_SHIFT (6u) +#define PDB_SC_PDBIF_WIDTH (1u) +#define PDB_SC_PDBIE_MASK (0x20u) +#define PDB_SC_PDBIE_SHIFT (5u) +#define PDB_SC_PDBIE_WIDTH (1u) +#define PDB_SC_MULT_MASK (0xCu) +#define PDB_SC_MULT_SHIFT (2u) +#define PDB_SC_MULT_WIDTH (2u) +#define PDB_SC_CONT_MASK (0x2u) +#define PDB_SC_CONT_SHIFT (1u) +#define PDB_SC_CONT_WIDTH (1u) +#define PDB_SC_LDOK_MASK (0x1u) +#define PDB_SC_LDOK_SHIFT (0u) +#define PDB_SC_LDOK_WIDTH (1u) + +/* MOD Bit Fields */ +#define PDB_MOD_MOD_MASK (0xFFFFu) +#define PDB_MOD_MOD_SHIFT (0u) +#define PDB_MOD_MOD_WIDTH (16u) + +/* CNT Bit Fields */ +#define PDB_CNT_CNT_MASK (0xFFFFu) +#define PDB_CNT_CNT_SHIFT (0u) +#define PDB_CNT_CNT_WIDTH (16u) + +/* IDLY Bit Fields */ +#define PDB_IDLY_IDLY_MASK (0xFFFFu) +#define PDB_IDLY_IDLY_SHIFT (0u) +#define PDB_IDLY_IDLY_WIDTH (16u) + +/* CHnC1 Bit Fields */ +#define PDB_CHnC1_BB_MASK (0xFF0000u) +#define PDB_CHnC1_BB_SHIFT (16u) +#define PDB_CHnC1_BB_WIDTH (8u) +#define PDB_CHnC1_TOS_MASK (0xFF00u) +#define PDB_CHnC1_TOS_SHIFT (8u) +#define PDB_CHnC1_TOS_WIDTH (8u) +#define PDB_CHnC1_EN_MASK (0xFFu) +#define PDB_CHnC1_EN_SHIFT (0u) +#define PDB_CHnC1_EN_WIDTH (8u) + +/* CHnS Bit Fields */ +#define PDB_CHnS_CF_MASK (0xFF0000u) +#define PDB_CHnS_CF_SHIFT (16u) +#define PDB_CHnS_CF_WIDTH (8u) +#define PDB_CHnS_ERR_MASK (0xFFu) +#define PDB_CHnS_ERR_SHIFT (0u) +#define PDB_CHnS_ERR_WIDTH (8u) + +/* CHnDLY Bit Fields */ +#define PDB_CHnDLY_DLY_MASK (0xFFFFu) +#define PDB_CHnDLY_DLY_SHIFT (0u) +#define PDB_CHnDLY_DLY_WIDTH (16u) + +/* POEN Bit Fields */ +#define PDB_POEN_POEN_MASK (0xFFu) +#define PDB_POEN_POEN_SHIFT (0u) +#define PDB_POEN_POEN_WIDTH (8u) + +/* POnDLY Bit Fields */ +#define PDB_POnDLY_DLY1_MASK (0xFFFF0000u) +#define PDB_POnDLY_DLY1_SHIFT (16u) +#define PDB_POnDLY_DLY1_WIDTH (16u) +#define PDB_POnDLY_DLY2_MASK (0xFFFFu) +#define PDB_POnDLY_DLY2_SHIFT (0u) +#define PDB_POnDLY_DLY2_WIDTH (16u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of PDB registers + */ +typedef struct _PdbRegType_ +{ + volatile uint32_t SC; /*!< status and control register, offset: 0000H */ + volatile uint32_t MOD; /*!< modulus register, offset: 0004H */ + volatile uint32_t CNT; /*!< counter register, offset: 0008H */ + volatile uint32_t IDLY; /*!< interrupt delay register, offset: 000CH */ + struct { + volatile uint32_t C1; /*!< channel n control register, offset: 0010H + n*0028H */ + volatile uint32_t S; /*!< channel n status register, offset: 0014H + n*0028H*/ + volatile uint32_t DLY[PDB_DLY_COUNT]; /*!< channel n delay register, offset: 0018H + n*0028H*/ + }CH[PDB_CH_COUNT]; + uint32_t RESERVED[76]; /*!< Reserved register, offset: 0060H */ + volatile uint32_t POEN; /*!< pulse out enable register, offset: 0190H */ + volatile uint32_t PODLY[PDB_PODLY_COUNT]; /*!< pulse out delay register, offset: 0194H */ + +} PdbRegType; + + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Get the current PDB LDMOD register configuration + * + * This function gets the current PDB LDMOD register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB LDMOD register configuration. + * - 00b: The internal registers are loaded with the values from their buffers, immediately after 1 is written to LDOK. + * - 01b: The internal registers are loaded with the values from their buffers when the PDB counter (CNT) = MOD + 1 CNT delay elapsed, after 1 is written to LDOK. + * - 10b: The internal registers are loaded with the values from their buffers when a trigger input event is detected, after 1 is written to LDOK. + * - 11b: The internal registers are loaded with the values from their buffers when either the PDB counter (CNT) = MOD + 1 CNT delay elapsed, or a trigger + * input event is detected, after 1 is written to LDOK. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetLdmodReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_LDMOD_MASK) >> PDB_SC_LDMOD_SHIFT); +} + +/*! \brief Set PDB LDMODR configuration + * + * This function writes new configuration to PDB LDMODR register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB LDMODR register configuration + * - 00b: The internal registers are loaded with the values from their buffers, immediately after 1 is written to LDOK. + * - 01b: The internal registers are loaded with the values from their buffers when the PDB counter (CNT) = MOD + 1 CNT delay elapsed, after 1 is written to LDOK. + * - 10b: The internal registers are loaded with the values from their buffers when a trigger input event is detected, after 1 is written to LDOK. + * - 11b: The internal registers are loaded with the values from their buffers when either the PDB counter (CNT) = MOD + 1 CNT delay elapsed, or a trigger + * input event is detected, after 1 is written to LDOK. + */ +__attribute__((always_inline)) static inline void PdbReg_SetLdmodReg(PdbRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_LDMOD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_SC_LDMOD_SHIFT)) & PDB_SC_LDMOD_MASK); + obj->SC = tmp; +} + +/*! \brief Get the current PDB PDBEIE register configuration + * + * This function gets the current PDB PDBEIE register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB PDBEIE register configuration. + * - 0b: PDB sequence error interrupt disabled. + * - 1b: PDB sequence error interrupt enabled. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetPdbeieReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_PDBEIE_MASK) >> PDB_SC_PDBEIE_SHIFT); +} + +/*! \brief Set PDB PDBEIE configuration + * + * This function writes new configuration to PDB PDBEIE register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB PDBEIE register configuration + * - 0b: PDB sequence error interrupt disabled. + * - 1b: PDB sequence error interrupt enabled. + */ +__attribute__((always_inline)) static inline void PdbReg_SetPdbeieReg(PdbRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_PDBEIE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_SC_PDBEIE_SHIFT)) & PDB_SC_PDBEIE_MASK); + obj->SC = tmp; +} + +/*! \brief Software Trigger + * + * When PDB is enabled and the software trigger is selected as the trigger input source, + * writing 1 to SWTRIG resets and restarts the counter. + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + */ +__attribute__((always_inline)) static inline void PdbReg_SwtrigReg(PdbRegType *obj) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_SWTRIG_MASK; + tmp &= ~PDB_SC_LDOK_MASK; + tmp |= (((uint32_t)(((uint32_t)(1u)) << PDB_SC_SWTRIG_SHIFT)) & PDB_SC_SWTRIG_MASK); + obj->SC = tmp; +} + +/*! \brief Get the current PDB DMAEN register configuration + * + * This function gets the current PDB DMAEN register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB DMAEN register configuration. + * - 0b: DMA disabled. + * - 1b: DMA enabled. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetDmaenReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_PDBEIE_MASK) >> PDB_SC_PDBEIE_SHIFT); +} + +/*! \brief Set PDB DMAEN configuration + * + * This function writes new configuration to PDB DMAEN register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB DMAEN register configuration + * - 0b: DMA disabled. + * - 1b: DMA enabled. + */ +__attribute__((always_inline)) static inline void PdbReg_SetDmaenReg(PdbRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_DMAEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_SC_DMAEN_SHIFT)) & PDB_SC_DMAEN_MASK); + obj->SC = tmp; +} + +/*! \brief Get the current PDB PRESCALER register configuration + * + * This function gets the current PDB PRESCALER register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB PRESCALER register configuration. + * - 000b: Counting uses the peripheral clock divided by MULT (the multiplication factor). + * - 001b: Counting uses the peripheral clock divided by 2 x MULT (the multiplication factor). + * - 010b: Counting uses the peripheral clock divided by 4 x MULT (the multiplication factor). + * - 011b: Counting uses the peripheral clock divided by 8 x MULT (the multiplication factor). + * - 100b: Counting uses the peripheral clock divided by 16 x MULT (the multiplication factor). + * - 101b: Counting uses the peripheral clock divided by 32 x MULT (the multiplication factor). + * - 110b: Counting uses the peripheral clock divided by 64 x MULT (the multiplication factor). + * - 111b: Counting uses the peripheral clock divided by 128 x MULT (the multiplication factor). + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetPrescalerReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_PRESCALER_MASK) >> PDB_SC_PRESCALER_SHIFT); +} + +/*! \brief Set PDB PRESCALER configuration + * + * This function writes new configuration to PDB PRESCALER register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB PRESCALER register configuration + * - 000b: Counting uses the peripheral clock divided by MULT (the multiplication factor). + * - 001b: Counting uses the peripheral clock divided by 2 x MULT (the multiplication factor). + * - 010b: Counting uses the peripheral clock divided by 4 x MULT (the multiplication factor). + * - 011b: Counting uses the peripheral clock divided by 8 x MULT (the multiplication factor). + * - 100b: Counting uses the peripheral clock divided by 16 x MULT (the multiplication factor). + * - 101b: Counting uses the peripheral clock divided by 32 x MULT (the multiplication factor). + * - 110b: Counting uses the peripheral clock divided by 64 x MULT (the multiplication factor). + * - 111b: Counting uses the peripheral clock divided by 128 x MULT (the multiplication factor). + */ +__attribute__((always_inline)) static inline void PdbReg_SetPrescalerReg(PdbRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_PRESCALER_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_SC_PRESCALER_SHIFT)) & PDB_SC_PRESCALER_MASK); + obj->SC = tmp; +} + +/*! \brief Get the current PDB TRGSEL register configuration + * + * This function gets the current PDB TRGSEL register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB TRGSEL register configuration. + * - 0000b: Trigger-In 0 is selected. + * - 0001b: Trigger-In 1 is selected. + * - 0010b: Trigger-In 2 is selected. + * - 0011b: Trigger-In 3 is selected. + * - 0100b: Trigger-In 4 is selected. + * - 0101b: Trigger-In 5 is selected. + * - 0110b: Trigger-In 6 is selected. + * - 0111b: Trigger-In 7 is selected. + * - 1000b: Trigger-In 8 is selected. + * - 1001b: Trigger-In 9 is selected. + * - 1010b: Trigger-In 10 is selected. + * - 1011b: Trigger-In 11 is selected. + * - 1100b: Trigger-In 12 is selected. + * - 1101b: Trigger-In 13 is selected. + * - 1110b: Trigger-In 14 is selected. + * - 1111b: Software trigger is selected. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetTrgselReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_TRGSEL_MASK) >> PDB_SC_TRGSEL_SHIFT); +} + +/*! \brief Set PDB TRGSEL configuration + * + * This function writes new configuration to PDB TRGSEL register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB TRGSEL register configuration + * - 0000b: Trigger-In 0 is selected. + * - 0001b: Trigger-In 1 is selected. + * - 0010b: Trigger-In 2 is selected. + * - 0011b: Trigger-In 3 is selected. + * - 0100b: Trigger-In 4 is selected. + * - 0101b: Trigger-In 5 is selected. + * - 0110b: Trigger-In 6 is selected. + * - 0111b: Trigger-In 7 is selected. + * - 1000b: Trigger-In 8 is selected. + * - 1001b: Trigger-In 9 is selected. + * - 1010b: Trigger-In 10 is selected. + * - 1011b: Trigger-In 11 is selected. + * - 1100b: Trigger-In 12 is selected. + * - 1101b: Trigger-In 13 is selected. + * - 1110b: Trigger-In 14 is selected. + * - 1111b: Software trigger is selected. + */ +__attribute__((always_inline)) static inline void PdbReg_SetTrgselReg(PdbRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_TRGSEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_SC_TRGSEL_SHIFT)) & PDB_SC_TRGSEL_MASK); + obj->SC = tmp; +} + +/*! \brief Get the current PDB PDBEN register configuration + * + * This function gets the current PDB PDBEN register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB PDBEN register configuration. + * - 0b: PDB disabled. Counter is off. + * - 1b: PDB enabled. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetPdbenReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_PDBEN_MASK) >> PDB_SC_PDBEN_SHIFT); +} + +/*! \brief Set PDB PDBEN configuration + * + * This function writes new configuration to PDB PDBEN register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB PDBEN register configuration + * - 0b: PDB disabled. Counter is off. + * - 1b: PDB enabled. + */ +__attribute__((always_inline)) static inline void PdbReg_SetPdbenReg(PdbRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_PDBEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_SC_PDBEN_SHIFT)) & PDB_SC_PDBEN_MASK); + obj->SC = tmp; +} + +/*! \brief Get the current PDB PDBIF register configuration + * + * This function gets the current PDB PDBIF register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB PDBEN register configuration. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetPdbifReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_PDBIF_MASK) >> PDB_SC_PDBIF_SHIFT); +} + +/*! \brief Clear PDB PDBIF + * + * This function clear PDB PDBIF register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * Write 0 to clear PDBIF. + * Writing 1 to PDBIF has no effect. + * + * \param[in] obj : pointer to PDB register instance + */ +__attribute__((always_inline)) static inline void PdbReg_ClrPdbifReg(PdbRegType *obj) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_PDBIF_MASK; + obj->SC = tmp; +} + +/*! \brief Get the current PDB PDBIE register configuration + * + * This function gets the current PDB PDBIE register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB PDBIE register configuration. + * - 0b: PDB interrupt disabled. + * - 1b: PDB interrupt enabled. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetPdbieReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_PDBIE_MASK) >> PDB_SC_PDBIE_SHIFT); +} + +/*! \brief Set PDB PDBIE configuration + * + * This function writes new configuration to PDB PDBIE register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB PDBIE register configuration + * - 0b: PDB interrupt disabled. + * - 1b: PDB interrupt enabled. + */ +__attribute__((always_inline)) static inline void PdbReg_SetPdbieReg(PdbRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_PDBIE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_SC_PDBIE_SHIFT)) & PDB_SC_PDBIE_MASK); + obj->SC = tmp; +} + +/*! \brief Get the current PDB MULT register configuration + * + * This function gets the current PDB MULT register configuration. + * If data size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB MULT register configuration. + * - 00b: Multiplication factor is 1. + * - 01b: Multiplication factor is 10. + * - 10b: Multiplication factor is 20. + * - 11b: Multiplication factor is 40. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetMultReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_MULT_MASK) >> PDB_SC_MULT_SHIFT); +} + +/*! \brief Set PDB MULT configuration + * + * This function writes new configuration to PDB MULT register + * If configuration size is less than 32 bits, the least significant bits are used for + * the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB MULT register configuration + * - 00b: Multiplication factor is 1. + * - 01b: Multiplication factor is 10. + * - 10b: Multiplication factor is 20. + * - 11b: Multiplication factor is 40. + */ +__attribute__((always_inline)) static inline void PdbReg_SetMultReg(PdbRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_MULT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_SC_MULT_SHIFT)) & PDB_SC_MULT_MASK); + obj->SC = tmp; +} + +/*! \brief Get the current PDB CONT register configuration + * + * This function gets the current PDB CONT register configuration. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB CONT register configuration. + * - 0b: PDB operation in One-Shot mode + * - 1b: PDB operation in Continuous mode + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetContReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_CONT_MASK) >> PDB_SC_CONT_SHIFT); +} + +/*! \brief Set PDB CONT configuration + * + * This function writes new configuration to PDB CONT register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB CONT register configuration + * - 0b: PDB operation in One-Shot mode + * - 1b: PDB operation in Continuous mode + */ +__attribute__((always_inline)) static inline void PdbReg_SetContReg(PdbRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_CONT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_SC_CONT_SHIFT)) & PDB_SC_CONT_MASK); + obj->SC = tmp; +} + +/*! \brief Get the current PDB LDOK state + * + * This function gets the current PDB LDOK state. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB LDOK register configuration. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetLdokReg(const PdbRegType *obj) +{ + return ((obj->SC & PDB_SC_LDOK_MASK) >> PDB_SC_LDOK_SHIFT); +} + +/*! \brief Start PDB Load + * + * This function writing 1 to LDOK bit updates the MOD, IDLY, CHnDLYm, and POyDLY registers. + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * Writing 1 to LDOK bit updates the MOD, IDLY, CHnDLYm, and POyDLY registers with the values previously written to their internal buffers (and stored there). + * The new values of MOD, IDLY, CHnDLYm, and POyDLY registers will take effect according to the setting of the LDMOD field (Load Mode Select). + * Before 1 is written to the LDOK field, the values in the internal buffers of these registers are not effective. + * LDOK can be written only when PDBEN is set, or LDOK can be written at the same time when PDBEN is written to 1. + * LDOK is automatically cleared when the values in the internal buffers are loaded into the registers or when PDBEN bit (PDB Enable) is cleared. + * Writing 0 to LDOK has no effect. + * \param[in] obj : pointer to PDB register instance + */ +__attribute__((always_inline)) static inline void PdbReg_StartLoadReg(PdbRegType *obj) +{ + uint32_t tmp = obj->SC; + + tmp &= ~PDB_SC_LDOK_MASK; + tmp |= (((uint32_t)(((uint32_t)(1u)) << PDB_SC_LDOK_SHIFT)) & PDB_SC_LDOK_MASK); + obj->SC = tmp; +} + +/*! \brief Get the current PDB MOD register configuration + * + * This function gets the current PDB MOD register configuration. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB MOD register configuration. + * Specifies the period of the counter. When the counter reaches this value, it will be reset back to zero. + * If the PDB is in Continuous mode, the count begins anew. + * Reading this field returns the value of the internal register that is effective for the current cycle of PDB. + */ +__attribute__((always_inline)) static inline uint16_t PdbReg_GetModReg(const PdbRegType *obj) +{ + return ((obj->MOD & PDB_MOD_MOD_MASK) >> PDB_MOD_MOD_SHIFT); +} + +/*! \brief Set PDB MOD configuration + * + * This function writes new configuration to PDB MOD register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB MOD register configuration + */ +__attribute__((always_inline)) static inline void PdbReg_SetModReg(PdbRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->MOD; + + tmp &= ~PDB_MOD_MOD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_MOD_MOD_SHIFT)) & PDB_MOD_MOD_MASK); + obj->MOD = tmp; +} + +/*! \brief Get the current PDB CNT register + * + * This function gets the contains the current value of the counter. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \return the current PDB counter. + */ +__attribute__((always_inline)) static inline uint16_t PdbReg_GetCntReg(const PdbRegType *obj) +{ + return ((obj->CNT & PDB_CNT_CNT_MASK) >> PDB_CNT_CNT_SHIFT); +} + +/*! \brief Get the current PDB IDLY register configuration + * + * This function gets the current PDB IDLY register configuration. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * Specifies the delay value to schedule the PDB interrupt. + * It can be used to schedule an independent interrupt at some point in the PDB cycle. + * If enabled, a PDB interrupt is generated, when the counter is equal to the IDLY. Reading this field returns the value + * of internal register that is effective for the current cycle of the PDB. + * \param[in] obj : pointer to PDB register instance + * \return the current PDB IDLY register configuration. + */ +__attribute__((always_inline)) static inline uint16_t PdbReg_GetIdlyReg(const PdbRegType *obj) +{ + return ((obj->IDLY & PDB_IDLY_IDLY_MASK) >> PDB_IDLY_IDLY_SHIFT); +} + +/*! \brief Set PDB IDLY configuration + * + * This function writes new configuration to PDB IDLY register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB IDLY register configuration + */ +__attribute__((always_inline)) static inline void PdbReg_SetIdlyReg(PdbRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->IDLY; + + tmp &= ~PDB_IDLY_IDLY_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_IDLY_IDLY_SHIFT)) & PDB_IDLY_IDLY_MASK); + obj->IDLY = tmp; +} + +/*! \brief Get the current PDB CHnC1[BB] register configuration + * + * This function gets the current PDB CHnC1[BB] register configuration. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] chn : channel number + * + * |---------|---------|-----|---------|---------| + * |CH7_state|CH6_state|.....|CH1_state|CH0_state| + * |---------|---------|-----|---------|---------| + * - 0b: PDB channel's corresponding pre-trigger back-to-back operation disabled. + * - 1b: PDB channel's corresponding pre-trigger back-to-back operation enabled. + * \return the current PDB CHnC1[BB] register configuration. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetChnBbReg(const PdbRegType *obj,uint8_t chn) +{ + return ((obj->CH[chn].C1 & PDB_CHnC1_BB_MASK) >> PDB_CHnC1_BB_SHIFT); +} + +/*! \brief Set PDB CHnC1[BB] configuration + * + * This function writes new configuration to PDB CHnC1[BB] register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * + * |---------|---------|-----|---------|---------| + * |CH7_state|CH6_state|.....|CH1_state|CH0_state| + * |---------|---------|-----|---------|---------| + * - 0b: PDB channel's corresponding pre-trigger back-to-back operation disabled. + * - 1b: PDB channel's corresponding pre-trigger back-to-back operation enabled. + * \param[in] value : expected PDB CHnC1[BB] register configuration + * + * \param[in] chn : channel number + */ +__attribute__((always_inline)) static inline void PdbReg_SetChnBbReg(PdbRegType *obj, uint8_t value,uint8_t chn) +{ + uint32_t tmp = obj->CH[chn].C1; + + tmp &= ~PDB_CHnC1_BB_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_CHnC1_BB_SHIFT)) & PDB_CHnC1_BB_MASK); + obj->CH[chn].C1= tmp; +} + +/*! \brief Get the current PDB CHnC1[TOS] register configuration + * + * This function gets the current PDB CHnC1[TOS] register configuration. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] chn : channel number + * + * |---------|---------|-----|---------|---------| + * |CH7_state|CH6_state|.....|CH1_state|CH0_state| + * |---------|---------|-----|---------|---------| + * - 0b: PDB channel's corresponding pre-trigger is in bypassed mode. The pre-trigger asserts one peripheral clock cycle after a rising edge + is detected on selected trigger input source or software trigger is selected and SWTRIG is written with 1. + * - 1b: PDB channel's corresponding pre-trigger asserts when the counter reaches the channel delay register plus one peripheral clock cycle + after a rising edge is detected on selected trigger input source or software trigger is selected and SWTRIG is written with 1. + * \return the current PDB CHnC1[TOS] register configuration. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetChnTosReg(const PdbRegType *obj,uint8_t chn) +{ + return ((obj->CH[chn].C1 & PDB_CHnC1_TOS_MASK) >> PDB_CHnC1_TOS_SHIFT); +} + +/*! \brief Set PDB CHnC1[TOS] configuration + * + * This function writes new configuration to PDB CHnC1[TOS] register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * + * |---------|---------|-----|---------|---------| + * |CH7_state|CH6_state|.....|CH1_state|CH0_state| + * |---------|---------|-----|---------|---------| + * - 0b: PDB channel's corresponding pre-trigger is in bypassed mode. The pre-trigger asserts one peripheral clock cycle after a rising edge + is detected on selected trigger input source or software trigger is selected and SWTRIG is written with 1. + * - 1b: PDB channel's corresponding pre-trigger asserts when the counter reaches the channel delay register plus one peripheral clock cycle + after a rising edge is detected on selected trigger input source or software trigger is selected and SWTRIG is written with 1. + * \param[in] value : expected PDB CHnC1[TOS] register configuration + * \param[in] chn : channel number + */ +__attribute__((always_inline)) static inline void PdbReg_SetChnTosReg(PdbRegType *obj, uint8_t value,uint8_t chn) +{ + uint32_t tmp = obj->CH[chn].C1; + + tmp &= ~PDB_CHnC1_TOS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_CHnC1_TOS_SHIFT)) & PDB_CHnC1_TOS_MASK); + obj->CH[chn].C1= tmp; +} + +/*! \brief Get the current PDB CHnC1[EN] register configuration + * + * This function gets the current PDB CHnC1[EN] register configuration. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] chn : channel number + * + * |---------|---------|-----|---------|---------| + * |CH7_state|CH6_state|.....|CH1_state|CH0_state| + * |---------|---------|-----|---------|---------| + * - 0b: PDB channel's corresponding pre-trigger disabled. + * * 1b: PDB channel's corresponding pre-trigger enabled. + * \return the current PDB CHnC1[EN] register configuration. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetChnEnReg(const PdbRegType *obj,uint8_t chn) +{ + return ((obj->CH[chn].C1 & PDB_CHnC1_EN_MASK) >> PDB_CHnC1_EN_SHIFT); +} + +/*! \brief Set PDB CHnC1[EN] configuration + * + * This function writes new configuration to PDB CHnC1[EN] register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * + * |---------|---------|-----|---------|---------| + * |CH7_state|CH6_state|.....|CH1_state|CH0_state| + * |---------|---------|-----|---------|---------| + * - 0b: PDB channel's corresponding pre-trigger disabled. + * * 1b: PDB channel's corresponding pre-trigger enabled. + * + * \param[in] value : expected PDB CHnC1[EN] register configuration + * \param[in] chn : channel number + */ +__attribute__((always_inline)) static inline void PdbReg_SetChnEnReg(PdbRegType *obj, uint8_t value,uint8_t chn) +{ + uint32_t tmp = obj->CH[chn].C1; + + tmp &= ~PDB_CHnC1_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_CHnC1_EN_SHIFT)) & PDB_CHnC1_EN_MASK); + obj->CH[chn].C1= tmp; +} + +/*! \brief Get the current PDB CHnS[CF] register. + * + * This function gets the current PDB CHnS[CF] register. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] chn : channel number + * + * |---------|---------|-----|---------|---------| + * |CH7_state|CH6_state|.....|CH1_state|CH0_state| + * |---------|---------|-----|---------|---------| + * \return the current PDB CHnS[CF] register. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetChnCfReg(const PdbRegType *obj,uint8_t chn) +{ + return ((obj->CH[chn].S & PDB_CHnS_CF_MASK) >> PDB_CHnS_CF_SHIFT); +} + +/*! \brief clear PDB CHnS[CF]. + * + * This function writes new configuration to PDB CHnS[CF] register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * Write 0 to clear CHn[preCH[0-7]]CF. + * \param[in] obj : pointer to PDB register instance + * \param[in] chn : channel number + */ +__attribute__((always_inline)) static inline void PdbReg_ClrChnCfReg(PdbRegType *obj,uint8_t chn) +{ + uint32_t tmp = obj->CH[chn].S; + tmp &= ~PDB_CHnS_CF_MASK; + obj->CH[chn].S= tmp; +} + +/*! \brief Get the current PDB CHnS[ERR] register. + * + * This function gets the current PDB CHnS[ERR] register. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] chn : channel number + * + * |---------|---------|-----|---------|---------| + * |CH7_state|CH6_state|.....|CH1_state|CH0_state| + * |---------|---------|-----|---------|---------| + * - 0b: Sequence error not detected on PDB channel's corresponding pre-trigger. + * - 1b: Sequence error detected on PDB channel's corresponding pre-trigger. + * \return the current PDB CHnS[ERR] register. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetChnErrReg(const PdbRegType *obj,uint8_t chn) +{ + return ((obj->CH[chn].S & PDB_CHnS_ERR_MASK) >> PDB_CHnS_ERR_SHIFT); +} + +/*! \brief clear PDB CHnS[ERR] configuration + * + * This function writes new configuration to PDB CHnS[ERR] register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * Write 0 to clear CHn[preCH[0-7]]ERR. + * \param[in] obj : pointer to PDB register instance + * \param[in] chn : channel number + */ +__attribute__((always_inline)) static inline void PdbReg_ClrChnErrReg(PdbRegType *obj,uint8_t chn) +{ + uint32_t tmp = obj->CH[chn].S; + tmp &= ~PDB_CHnS_ERR_MASK; + obj->CH[chn].S= tmp; +} + +/*! \brief Get the current PDB CHnDLY[DLY] register. + * + * This function gets the current PDB CHnDLY[DLY] register. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * Reading these bits returns the value of internal register that is effective for the current PDB cycle. + * \param[in] obj : pointer to PDB register instance + * \param[in] chn : channel number + * \param[in] preChn : pre-trigger number + * \return the current PDB CHnDLY[DLY] register. + */ +__attribute__((always_inline)) static inline uint16_t PdbReg_GetChnDlyReg(const PdbRegType *obj,uint8_t chn, uint8_t preChn) +{ + return ((obj->CH[chn].DLY[preChn] & PDB_CHnDLY_DLY_MASK) >> PDB_CHnDLY_DLY_SHIFT); +} + +/*! \brief Set PDB CHnDLY[DLY] configuration + * + * This function writes new configuration to PDB CHnDLY[DLY] register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB CHnDLY[DLY] register configuration + * \param[in] chn : channel number + * \param[in] preChn : pre-trigger number + */ +__attribute__((always_inline)) static inline void PdbReg_SetChnDlyReg(PdbRegType *obj, uint16_t value,uint8_t chn, uint8_t preChn) +{ + uint32_t tmp = obj->CH[chn].DLY[preChn]; + + tmp &= ~PDB_CHnDLY_DLY_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_CHnDLY_DLY_SHIFT)) & PDB_CHnDLY_DLY_MASK); + obj->CH[chn].DLY[preChn]= tmp; +} + +/*! \brief Get the current PDB POEN register. + * + * This function gets the current PDB POEN register. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * + * |---------|---------|-----|---------|---------| + * |CH7_state|CH6_state|.....|CH1_state|CH0_state| + * |---------|---------|-----|---------|---------| + * - 0b: PDB Pulse-Out disabled + * - 1b: PDB Pulse-Out enabled + * \return the current PDB POEN register. + */ +__attribute__((always_inline)) static inline uint8_t PdbReg_GetPoenReg(const PdbRegType *obj) +{ + return ((obj->POEN & PDB_POEN_POEN_MASK) >> PDB_POEN_POEN_SHIFT); +} + +/*! \brief Set PDB POEN configuration + * + * This function writes new configuration to PDB POEN register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * + * |---------|---------|-----|---------|---------| + * |CH7_state|CH6_state|.....|CH1_state|CH0_state| + * |---------|---------|-----|---------|---------| + * - 0b: PDB Pulse-Out disabled + * - 1b: PDB Pulse-Out enabled + * \param[in] value : expected PDB POEN register configuration + */ +__attribute__((always_inline)) static inline void PdbReg_SetPoenReg(PdbRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->POEN; + + tmp &= ~PDB_POEN_POEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PDB_POEN_POEN_SHIFT)) & PDB_POEN_POEN_MASK); + obj->POEN = tmp; +} + +/*! \brief Get the current PDB POnDLY[DLY1] register. + * + * This function gets the current PDB POnDLY[DLY1] register. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * Reading these bits returns the value of internal register that is effective for the current PDB cycle. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] Pon : PO number + * \return the current PDB POnDLY[DLY1] register. + */ +__attribute__((always_inline)) static inline uint16_t PdbReg_GetPonDly1Reg(const PdbRegType *obj,uint8_t Pon) +{ + return ((obj->PODLY[Pon] & PDB_POnDLY_DLY1_MASK) >> PDB_POnDLY_DLY1_SHIFT); +} + +/*! \brief Get the current PDB POnDLY[DLY2] register. + * + * This function gets the current PDB POnDLY[DLY2] register. + * If data size is less than 32 bits, the least significant bits are used for the correct value. + * Reading these bits returns the value of internal register that is effective for the current PDB cycle. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] Pon : PO number + * \return the current PDB POnDLY[DLY2] register. + */ +__attribute__((always_inline)) static inline uint16_t PdbReg_GetPonDly2Reg(const PdbRegType *obj,uint8_t Pon) +{ + return ((obj->PODLY[Pon] & PDB_POnDLY_DLY2_MASK) >> PDB_POnDLY_DLY2_SHIFT); +} + +/*! \brief Set PDB POnDLY configuration + * + * This function writes new configuration to PDB POnDLY[DLY1] register + * If configuration size is less than 32 bits, the least significant bits are used for the correct value. + * + * \param[in] obj : pointer to PDB register instance + * \param[in] value : expected PDB POnDLY register configuration(bit0~15 is DLY2,bit 16~31 is DLY1) + * \param[in] Pon : PO number + */ +__attribute__((always_inline)) static inline void PdbReg_SetPonDlyReg(PdbRegType *obj, uint32_t value,uint8_t Pon) +{ + obj->PODLY[Pon] = value; +} +#ifdef __cplusplus +} +#endif /* extern "C" */ + + +#endif /* _PDB_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/pmc_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/pmc_reg.h new file mode 100644 index 0000000..bac415b --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/pmc_reg.h @@ -0,0 +1,781 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PMC_REG_H_ +#define _PMC_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the PMC Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* GLB_CTRL Bit Fields */ +#define PMC_GLB_CTRL_CPU_RETION_EN_MASK (0x20u) +#define PMC_GLB_CTRL_CPU_RETION_EN_SHIFT (5u) +#define PMC_GLB_CTRL_CPU_RETION_EN_WIDTH (1u) +#define PMC_GLB_CTRL_STOP_EN_MASK (0x04u) +#define PMC_GLB_CTRL_STOP_EN_SHIFT (2u) +#define PMC_GLB_CTRL_STOP_EN_WIDTH (1u) +#define PMC_GLB_CTRL_STDBY_EN_MASK (0x02u) +#define PMC_GLB_CTRL_STDBY_EN_SHIFT (1u) +#define PMC_GLB_CTRL_STDBY_EN_WIDTH (1u) + +/* DAINTF_CTRL Bit Fields */ +#define PMC_DAINTF_CTRL_EN_FLDO_VDET_MASK (0x80000u) +#define PMC_DAINTF_CTRL_EN_FLDO_VDET_SHIFT (19u) +#define PMC_DAINTF_CTRL_EN_FLDO_VDET_WIDTH (1u) +#define PMC_DAINTF_CTRL_SEL_LVW_MASK (0xC000u) +#define PMC_DAINTF_CTRL_SEL_LVW_SHIFT (14u) +#define PMC_DAINTF_CTRL_SEL_LVW_WIDTH (2u) +#define PMC_DAINTF_CTRL_EN_LVW_MASK (0x2000u) +#define PMC_DAINTF_CTRL_EN_LVW_SHIFT (13u) +#define PMC_DAINTF_CTRL_EN_LVW_WIDTH (1u) +#define PMC_DAINTF_CTRL_EN_LVD_MASK (0x1000u) +#define PMC_DAINTF_CTRL_EN_LVD_SHIFT (12u) +#define PMC_DAINTF_CTRL_EN_LVD_WIDTH (1u) +#define PMC_DAINTF_CTRL_OTP_EN_MASK (0x80u) +#define PMC_DAINTF_CTRL_OTP_EN_SHIFT (7u) +#define PMC_DAINTF_CTRL_OTP_EN_WIDTH (1u) + +/* WAKUP_FLG Bit Fields */ +#define PMC_WAKUP_FLG_CMP_WAKUP_EVT_FLG_MASK (0x400u) +#define PMC_WAKUP_FLG_CMP_WAKUP_EVT_FLG_SHIFT (10u) +#define PMC_WAKUP_FLG_CMP_WAKUP_EVT_FLG_WIDTH (1u) +#define PMC_WAKUP_FLG_LPTMR_WAKUP_EVT_FLG_MASK (0x200u) +#define PMC_WAKUP_FLG_LPTMR_WAKUP_EVT_FLG_SHIFT (9u) +#define PMC_WAKUP_FLG_LPTMR_WAKUP_EVT_FLG_WIDTH (1u) +#define PMC_WAKUP_FLG_LPIT_WAKUP_EVT_FLG_MASK (0x100u) +#define PMC_WAKUP_FLG_LPIT_WAKUP_EVT_FLG_SHIFT (8u) +#define PMC_WAKUP_FLG_LPIT_WAKUP_EVT_FLG_WIDTH (1u) +#define PMC_WAKUP_FLG_RTC_WAKUP_EVT_FLG_MASK (0x40u) +#define PMC_WAKUP_FLG_RTC_WAKUP_EVT_FLG_SHIFT (6u) +#define PMC_WAKUP_FLG_RTC_WAKUP_EVT_FLG_WIDTH (1u) +#define PMC_WAKUP_FLG_EXTRST_WAKUP_EVT_FLG_MASK (0x20u) +#define PMC_WAKUP_FLG_EXTRST_WAKUP_EVT_FLG_SHIFT (5u) +#define PMC_WAKUP_FLG_EXTRST_WAKUP_EVT_FLG_WIDTH (1u) +#define PMC_WAKUP_FLG_PORTE_WAKUP_EVT_FLG_MASK (0x10u) +#define PMC_WAKUP_FLG_PORTE_WAKUP_EVT_FLG_SHIFT (4u) +#define PMC_WAKUP_FLG_PORTE_WAKUP_EVT_FLG_WIDTH (1u) +#define PMC_WAKUP_FLG_PORTD_WAKUP_EVT_FLG_MASK (0x08u) +#define PMC_WAKUP_FLG_PORTD_WAKUP_EVT_FLG_SHIFT (3u) +#define PMC_WAKUP_FLG_PORTD_WAKUP_EVT_FLG_WIDTH (1u) +#define PMC_WAKUP_FLG_PORTC_WAKUP_EVT_FLG_MASK (0x04u) +#define PMC_WAKUP_FLG_PORTC_WAKUP_EVT_FLG_SHIFT (2u) +#define PMC_WAKUP_FLG_PORTC_WAKUP_EVT_FLG_WIDTH (1u) +#define PMC_WAKUP_FLG_PORTB_WAKUP_EVT_FLG_MASK (0x02u) +#define PMC_WAKUP_FLG_PORTB_WAKUP_EVT_FLG_SHIFT (1u) +#define PMC_WAKUP_FLG_PORTB_WAKUP_EVT_FLG_WIDTH (1u) +#define PMC_WAKUP_FLG_PORTA_WAKUP_EVT_FLG_MASK (0x01u) +#define PMC_WAKUP_FLG_PORTA_WAKUP_EVT_FLG_SHIFT (0u) +#define PMC_WAKUP_FLG_PORTA_WAKUP_EVT_FLG_WIDTH (1u) + +/* STATUS Bit Fields */ +#define PMC_STATUS_RUN_MODE_MASK (0x20u) +#define PMC_STATUS_RUN_MODE_SHIFT (5u) +#define PMC_STATUS_RUN_MODE_WIDTH (1u) +#define PMC_STATUS_STDBY_ABORT_STS_MASK (0x10u) +#define PMC_STATUS_STDBY_ABORT_STS_SHIFT (4u) +#define PMC_STATUS_STDBY_ABORT_STS_WIDTH (1u) +#define PMC_STATUS_PAD_KEEP_MASK (0x02u) +#define PMC_STATUS_PAD_KEEP_SHIFT (1u) +#define PMC_STATUS_PAD_KEEP_WIDTH (1u) +#define PMC_STATUS_LOCK_MASK (0x01u) +#define PMC_STATUS_LOCK_SHIFT (0u) +#define PMC_STATUS_LOCK_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of PMC registers + */ +typedef struct _PmcRegType_ +{ + volatile uint32_t GLB_CTRL; /*!< wakeup source regsiter, offset: 0x0 */ + uint32_t RESERVED0[2]; /*!< Reserverd block, offset: 0x04 */ + volatile uint32_t DAINTF_CTRL; /*!< digital to analog interface control signal register, offset: 0xC */ + uint32_t RESERVED1[1]; /*!< Reserverd block, offset: 0x10 */ + volatile uint32_t WAKUP_FLG; /*!< wake up flag register, offset: 0x14 */ + volatile uint32_t STATUS; /*!< status register register, offset: 0x18 */ + uint32_t RESERVED2[13]; /*!< Reserverd block, offset: 0x1C */ + volatile uint32_t KEY; /*!< key register, offset: 0x50 */ +} PmcRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the CPU retention enable + * + * This function gets the current CPU retention enable. + * enable the PMC cpu retention function, when lock function disable this register can write access. + * CPU after reset then start to excute instruction from the begining when exit standby mode + * or CPU start to excute instruction from the states before enter standby mode when exit standby mode. + * + * \param[in] obj : pointer to PMC register instance + * \return CPU retention enable + * - 0 : excute instruction from the begining. + * - 1 : excute instruction from the states before enter standby mode. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetGlbCtrlCpuRetionEn(const PmcRegType *obj) +{ + return ((obj->GLB_CTRL & PMC_GLB_CTRL_CPU_RETION_EN_MASK) >> PMC_GLB_CTRL_CPU_RETION_EN_SHIFT); +} + +/*! \brief Sets the CPU retention enable + * + * This function sets the CPU retention enable. + * enable the PMC cpu retention function, when lock function disable this register can write access. + * CPU after reset then start to excute instruction from the begining when exit standby mode + * or CPU start to excute instruction from the states before enter standby mode when exit standby mode. + * + * \param[in] obj : pointer to PMC register instance + * \param[in] value : the value of CPU retention enable + * - 0 : excute instruction from the begining. + * - 1 : excute instruction from the states before enter standby mode. + */ +__attribute__((always_inline)) static inline void PmcReg_SetGlbCtrlCpuRetionEn(PmcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->GLB_CTRL; + + tmp &= ~PMC_GLB_CTRL_CPU_RETION_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PMC_GLB_CTRL_CPU_RETION_EN_SHIFT)) & PMC_GLB_CTRL_CPU_RETION_EN_MASK); + obj->GLB_CTRL = tmp; +} + +/*! \brief Gets the Stop mode enable + * + * This function gets the current Stop mode enable. + * PMC stop mode enable, when lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \return Stop mode enable + * - 0 : stop mode disable. + * - 1 : stop mode enable. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetGlbCtrlStopEn(const PmcRegType *obj) +{ + return ((obj->GLB_CTRL & PMC_GLB_CTRL_STOP_EN_MASK) >> PMC_GLB_CTRL_STOP_EN_SHIFT); +} + +/*! \brief Sets the Stop mode enable + * + * This function sets the Stop mode enable. + * PMC stop mode enable, when lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \param[in] value : the value of Stop mode enable + * - 0 : stop mode disable. + * - 1 : stop mode enable. + */ +__attribute__((always_inline)) static inline void PmcReg_SetGlbCtrlStopEn(PmcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->GLB_CTRL; + + tmp &= ~PMC_GLB_CTRL_STOP_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PMC_GLB_CTRL_STOP_EN_SHIFT)) & PMC_GLB_CTRL_STOP_EN_MASK); + obj->GLB_CTRL = tmp; +} + +/*! \brief Gets the standby mode enable + * + * This function gets the current standby mode enable. + * PMC standby mode enable, when lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \return standby mode enable + * - 0 : standby mode disable. + * - 1 : standby mode enable. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetGlbCtrlStdbyEn(const PmcRegType *obj) +{ + return ((obj->GLB_CTRL & PMC_GLB_CTRL_STDBY_EN_MASK) >> PMC_GLB_CTRL_STDBY_EN_SHIFT); +} + +/*! \brief Sets the standby mode enable + * + * This function sets the standby mode enable. + * PMC standby mode enable, when lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \param[in] value : the value of standby mode enable + * - 0 : standby mode disable. + * - 1 : standby mode enable. + */ +__attribute__((always_inline)) static inline void PmcReg_SetGlbCtrlStdbyEn(PmcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->GLB_CTRL; + + tmp &= ~PMC_GLB_CTRL_STDBY_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PMC_GLB_CTRL_STDBY_EN_SHIFT)) & PMC_GLB_CTRL_STDBY_EN_MASK); + obj->GLB_CTRL = tmp; +} + +/*! \brief Gets the Flash LDO(FLDO) voltage detect control + * + * This function gets the current Flash LDO(FLDO) voltage detect control. + * when write lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \return Flash LDO(FLDO) voltage detect control + * - 1 : Enable voltage detect. + * - 0 : Disable voltage detect. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetDAIntfCtrlEnFldoVDet(const PmcRegType *obj) +{ + return ((obj->DAINTF_CTRL & PMC_DAINTF_CTRL_EN_FLDO_VDET_MASK) >> PMC_DAINTF_CTRL_EN_FLDO_VDET_SHIFT); +} + +/*! \brief Sets the Flash LDO(FLDO) voltage detect control + * + * This function sets the Flash LDO(FLDO) voltage detect control. + * when write lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \param[in] value : the value of Flash LDO(FLDO) voltage detect control + * - 1 : Enable voltage detect. + * - 0 : Disable voltage detect. + */ +__attribute__((always_inline)) static inline void PmcReg_SetDAIntfCtrlEnFldoVDet(PmcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DAINTF_CTRL; + + tmp &= ~PMC_DAINTF_CTRL_EN_FLDO_VDET_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PMC_DAINTF_CTRL_EN_FLDO_VDET_SHIFT)) & PMC_DAINTF_CTRL_EN_FLDO_VDET_MASK); + obj->DAINTF_CTRL = tmp; +} + +/*! \brief Gets the Low voltage warning(LVW) level select + * + * This function gets the current Low voltage warning(LVW) level select. + * when write lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \return Low voltage warning(LVW) level select + * - 00b : V_LVW1. + * - 01b : V_LVW2. + * - 01b : V_LVW3. + * - 11b : Not defined. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetDAIntfCtrlSelLvw(const PmcRegType *obj) +{ + return ((obj->DAINTF_CTRL & PMC_DAINTF_CTRL_SEL_LVW_MASK) >> PMC_DAINTF_CTRL_SEL_LVW_SHIFT); +} + +/*! \brief Sets the Low voltage warning(LVW) level select + * + * This function sets the Low voltage warning(LVW) level select. + * when write lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \param[in] value : the value of Low voltage warning(LVW) level select + * - 00b : V_LVW1. + * - 01b : V_LVW2. + * - 01b : V_LVW3. + * - 11b : Not defined. + */ +__attribute__((always_inline)) static inline void PmcReg_SetDAIntfCtrlSelLvw(PmcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DAINTF_CTRL; + + tmp &= ~PMC_DAINTF_CTRL_SEL_LVW_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PMC_DAINTF_CTRL_SEL_LVW_SHIFT)) & PMC_DAINTF_CTRL_SEL_LVW_MASK); + obj->DAINTF_CTRL = tmp; +} + +/*! \brief Gets the Low voltage detect warning(LVW) control + * + * This function gets the current Low voltage detect warning(LVW) control. + * when write lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \return Low voltage detect warning(LVW) control + * - 0b : Disable low voltage warning. + * - 1b : Enable low voltage warning. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetDAIntfCtrlEnLvw(const PmcRegType *obj) +{ + return ((obj->DAINTF_CTRL & PMC_DAINTF_CTRL_EN_LVW_MASK) >> PMC_DAINTF_CTRL_EN_LVW_SHIFT); +} + +/*! \brief Sets the Low voltage detect warning(LVW) control + * + * This function sets the Low voltage detect warning(LVW) control. + * when write lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \param[in] value : the value of Low voltage detect warning(LVW) control + * - 0b : Disable low voltage warning. + * - 1b : Enable low voltage warning. + */ +__attribute__((always_inline)) static inline void PmcReg_SetDAIntfCtrlEnLvw(PmcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DAINTF_CTRL; + + tmp &= ~PMC_DAINTF_CTRL_EN_LVW_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PMC_DAINTF_CTRL_EN_LVW_SHIFT)) & PMC_DAINTF_CTRL_EN_LVW_MASK); + obj->DAINTF_CTRL = tmp; +} + +/*! \brief Gets the Low voltage detect enable control + * + * This function gets the current Low voltage detect enable control. + * when write lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \return Low voltage detect enable control + * - 0b : Disable low voltage detect. + * - 1b : Enable low voltage detect. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetDAIntfCtrlEnLvd(const PmcRegType *obj) +{ + return ((obj->DAINTF_CTRL & PMC_DAINTF_CTRL_EN_LVD_MASK) >> PMC_DAINTF_CTRL_EN_LVD_SHIFT); +} + +/*! \brief Sets the Low voltage detect enable control + * + * This function sets the Low voltage detect enable control. + * when write lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \param[in] value : the value of Low voltage detect enable control + * - 0b : Disable low voltage detect. + * - 1b : Enable low voltage detect. + */ +__attribute__((always_inline)) static inline void PmcReg_SetDAIntfCtrlEnLvd(PmcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DAINTF_CTRL; + + tmp &= ~PMC_DAINTF_CTRL_EN_LVD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PMC_DAINTF_CTRL_EN_LVD_SHIFT)) & PMC_DAINTF_CTRL_EN_LVD_MASK); + obj->DAINTF_CTRL = tmp; +} + +/*! \brief Gets the OTP function enable control + * + * This function gets the current OTP function enable control. + * when write lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \return OTP function enable control + * - 0 : Disable. + * - 1 : Enable. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetDAIntfCtrlOtpEn(const PmcRegType *obj) +{ + return ((obj->DAINTF_CTRL & PMC_DAINTF_CTRL_OTP_EN_MASK) >> PMC_DAINTF_CTRL_OTP_EN_SHIFT); +} + +/*! \brief Sets the OTP function enable control + * + * This function sets the OTP function enable control. + * when write lock function disable this register can write access. + * + * \param[in] obj : pointer to PMC register instance + * \param[in] value : the value of OTP function enable control + * - 0 : Disable. + * - 1 : Enable. + */ +__attribute__((always_inline)) static inline void PmcReg_SetDAIntfCtrlOtpEn(PmcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DAINTF_CTRL; + + tmp &= ~PMC_DAINTF_CTRL_OTP_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PMC_DAINTF_CTRL_OTP_EN_SHIFT)) & PMC_DAINTF_CTRL_OTP_EN_MASK); + obj->DAINTF_CTRL = tmp; +} + +/*! \brief Gets the cmp wake up event flag + * + * This function gets the current cmp wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + * \return cmp wake up event flag + * - 0 : cmp wake up event flag not exist. + * - 1 : cmp wake up event flag exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetWakupFlgCmpWakupEvtFlag(const PmcRegType *obj) +{ + return ((obj->WAKUP_FLG & PMC_WAKUP_FLG_CMP_WAKUP_EVT_FLG_MASK) >> PMC_WAKUP_FLG_CMP_WAKUP_EVT_FLG_SHIFT); +} + +/*! \brief Sets the cmp wake up event flag + * + * This function sets the cmp wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearWakupFlgCmpWakupEvtFlag(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->WAKUP_FLG = (((uint32_t)(((uint32_t)(1)) << PMC_WAKUP_FLG_CMP_WAKUP_EVT_FLG_SHIFT)) & PMC_WAKUP_FLG_CMP_WAKUP_EVT_FLG_MASK); +} + +/*! \brief Gets the lptmr wake up event flag + * + * This function gets the current lptmr wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + * \return lptmr wake up event flag + * - 0 : lptmr wake up event flag not exist. + * - 1 : lptmr wake up event flag exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetWakupFlgLptmrWakupEvtFlg(const PmcRegType *obj) +{ + return ((obj->WAKUP_FLG & PMC_WAKUP_FLG_LPTMR_WAKUP_EVT_FLG_MASK) >> PMC_WAKUP_FLG_LPTMR_WAKUP_EVT_FLG_SHIFT); +} + +/*! \brief Sets the lptmr wake up event flag + * + * This function sets the lptmr wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearWakupFlgLptmrWakupEvtFlg(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->WAKUP_FLG = (((uint32_t)(((uint32_t)(1)) << PMC_WAKUP_FLG_LPTMR_WAKUP_EVT_FLG_SHIFT)) & PMC_WAKUP_FLG_LPTMR_WAKUP_EVT_FLG_MASK); +} + +/*! \brief Gets the low power interrupt timer wake up event flag + * + * This function gets the current low power interrupt timer wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + * \return low power interrupt timer wake up event flag + * - 0 : lpit wake up event flag not exist. + * - 1 : lpit wake up event flag exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetWakupFlgLpitWakupEvtFlg(const PmcRegType *obj) +{ + return ((obj->WAKUP_FLG & PMC_WAKUP_FLG_LPIT_WAKUP_EVT_FLG_MASK) >> PMC_WAKUP_FLG_LPIT_WAKUP_EVT_FLG_SHIFT); +} + +/*! \brief Sets the low power interrupt timer wake up event flag + * + * This function sets the low power interrupt timer wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearWakupFlgLpitWakupEvtFlg(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->WAKUP_FLG = (((uint32_t)(((uint32_t)(1)) << PMC_WAKUP_FLG_LPIT_WAKUP_EVT_FLG_SHIFT)) & PMC_WAKUP_FLG_LPIT_WAKUP_EVT_FLG_MASK); +} + +/*! \brief Gets the real time clock wake up event flag + * + * This function gets the current real time clock wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + * \return real time clock wake up event flag + * - 0 : rtc wake up event flag not exist. + * - 1 : rtc wake up event flag exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetWakupFlgRtcWakupEvtFlg(const PmcRegType *obj) +{ + return ((obj->WAKUP_FLG & PMC_WAKUP_FLG_RTC_WAKUP_EVT_FLG_MASK) >> PMC_WAKUP_FLG_RTC_WAKUP_EVT_FLG_SHIFT); +} + +/*! \brief Sets the real time clock wake up event flag + * + * This function sets the real time clock wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearWakupFlgRtcWakupEvtFlg(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->WAKUP_FLG = (((uint32_t)(((uint32_t)(1)) << PMC_WAKUP_FLG_RTC_WAKUP_EVT_FLG_SHIFT)) & PMC_WAKUP_FLG_RTC_WAKUP_EVT_FLG_MASK); +} + +/*! \brief Gets the External reset wake up event flag + * + * This function gets the current External reset wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + * \return External reset wake up event flag + * - 0 : extrst wake up event flag not exist. + * - 1 : extrst wake up event flag exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetWakupFlgExtrstWakupEvtFlg(const PmcRegType *obj) +{ + return ((obj->WAKUP_FLG & PMC_WAKUP_FLG_EXTRST_WAKUP_EVT_FLG_MASK) >> PMC_WAKUP_FLG_EXTRST_WAKUP_EVT_FLG_SHIFT); +} + +/*! \brief Sets the External reset wake up event flag + * + * This function sets the External reset wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearWakupFlgExtrstWakupEvtFlg(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->WAKUP_FLG = (((uint32_t)(((uint32_t)(1)) << PMC_WAKUP_FLG_EXTRST_WAKUP_EVT_FLG_SHIFT)) & PMC_WAKUP_FLG_EXTRST_WAKUP_EVT_FLG_MASK); +} + +/*! \brief Gets the port E wake up event flag + * + * This function gets the current port E wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + * \return port E wake up event flag + * - 0 : porte wake up event flag not exist. + * - 1 : porte wake up event flag exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetWakupFlgPortEWakupEvtFlg(const PmcRegType *obj) +{ + return ((obj->WAKUP_FLG & PMC_WAKUP_FLG_PORTE_WAKUP_EVT_FLG_MASK) >> PMC_WAKUP_FLG_PORTE_WAKUP_EVT_FLG_SHIFT); +} + +/*! \brief Sets the port E wake up event flag + * + * This function sets the port E wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearWakupFlgPortEWakupEvtFlg(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->WAKUP_FLG = (((uint32_t)(((uint32_t)(1)) << PMC_WAKUP_FLG_PORTE_WAKUP_EVT_FLG_SHIFT)) & PMC_WAKUP_FLG_PORTE_WAKUP_EVT_FLG_MASK); +} + +/*! \brief Gets the port D wake up event flag + * + * This function gets the current port D wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + * \return port D wake up event flag + * - 0 : portd wake up event flag not exist. + * - 1 : portd wake up event flag exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetWakupFlgPortDWakupEvtFlg(const PmcRegType *obj) +{ + return ((obj->WAKUP_FLG & PMC_WAKUP_FLG_PORTD_WAKUP_EVT_FLG_MASK) >> PMC_WAKUP_FLG_PORTD_WAKUP_EVT_FLG_SHIFT); +} + +/*! \brief Sets the port D wake up event flag + * + * This function sets the port D wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearWakupFlgPortDWakupEvtFlg(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->WAKUP_FLG = (((uint32_t)(((uint32_t)(1)) << PMC_WAKUP_FLG_PORTD_WAKUP_EVT_FLG_SHIFT)) & PMC_WAKUP_FLG_PORTD_WAKUP_EVT_FLG_MASK); +} + +/*! \brief Gets the port C wake up event flag + * + * This function gets the current port C wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + * \return port C wake up event flag + * - 0 : portc wake up event flag not exist. + * - 1 : portc wake up event flag exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetWakupFlgPortCWakupEvtFlg(const PmcRegType *obj) +{ + return ((obj->WAKUP_FLG & PMC_WAKUP_FLG_PORTC_WAKUP_EVT_FLG_MASK) >> PMC_WAKUP_FLG_PORTC_WAKUP_EVT_FLG_SHIFT); +} + +/*! \brief Sets the port C wake up event flag + * + * This function sets the port C wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearWakupFlgPortCWakupEvtFlg(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->WAKUP_FLG = (((uint32_t)(((uint32_t)(1)) << PMC_WAKUP_FLG_PORTC_WAKUP_EVT_FLG_SHIFT)) & PMC_WAKUP_FLG_PORTC_WAKUP_EVT_FLG_MASK); +} + +/*! \brief Gets the port B wake up event flag + * + * This function gets the current port B wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + * \return port B wake up event flag + * - 0 : portb wake up event flag not exist. + * - 1 : portb wake up event flag exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetWakupFlgPortBWakupEvtFlg(const PmcRegType *obj) +{ + return ((obj->WAKUP_FLG & PMC_WAKUP_FLG_PORTB_WAKUP_EVT_FLG_MASK) >> PMC_WAKUP_FLG_PORTB_WAKUP_EVT_FLG_SHIFT); +} + +/*! \brief Sets the port B wake up event flag + * + * This function sets the port B wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearWakupFlgPortBWakupEvtFlg(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->WAKUP_FLG = (((uint32_t)(((uint32_t)(1)) << PMC_WAKUP_FLG_PORTB_WAKUP_EVT_FLG_SHIFT)) & PMC_WAKUP_FLG_PORTB_WAKUP_EVT_FLG_MASK); +} + +/*! \brief Gets the port A wake up event flag + * + * This function gets the current port A wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + * \return port A wake up event flag + * - 0 : porta wake up event flag not exist. + * - 1 : porta wake up event flag exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetWakupFlgPortAWakupEvtFlg(const PmcRegType *obj) +{ + return ((obj->WAKUP_FLG & PMC_WAKUP_FLG_PORTA_WAKUP_EVT_FLG_MASK) >> PMC_WAKUP_FLG_PORTA_WAKUP_EVT_FLG_SHIFT); +} + +/*! \brief Sets the port A wake up event flag + * + * This function sets the port A wake up event flag. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearWakupFlgPortAWakupEvtFlg(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->WAKUP_FLG = (((uint32_t)(((uint32_t)(1)) << PMC_WAKUP_FLG_PORTA_WAKUP_EVT_FLG_SHIFT)) & PMC_WAKUP_FLG_PORTA_WAKUP_EVT_FLG_MASK); +} + +/*! \brief Gets the normal run mode status + * + * This function gets the current normal run mode status. + * + * \param[in] obj : pointer to PMC register instance + * \return normal run mode status + * - 0 : normal run mode status not exist. + * - 1 : normal run mode status exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetStatusRunMode(const PmcRegType *obj) +{ + return ((obj->STATUS & PMC_STATUS_RUN_MODE_MASK) >> PMC_STATUS_RUN_MODE_SHIFT); +} + +/*! \brief Gets the standby abort status + * + * This function gets the current standby abort status. + * + * \param[in] obj : pointer to PMC register instance + * \return standby abort status + * - 0 : standby abort status not exist. + * - 1 : standby abort status exist. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetStatusStdbyAbortSts(const PmcRegType *obj) +{ + return ((obj->STATUS & PMC_STATUS_STDBY_ABORT_STS_MASK) >> PMC_STATUS_STDBY_ABORT_STS_SHIFT); +} + +/*! \brief Sets the standby abort status + * + * This function sets the standby abort status. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearStatusStdbyAbortSts(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->STATUS = (((uint32_t)(((uint32_t)(1)) << PMC_STATUS_STDBY_ABORT_STS_SHIFT)) & PMC_STATUS_STDBY_ABORT_STS_MASK); +} + +/*! \brief Gets the pad keep status + * + * This function gets the current pad keep status. + * + * \param[in] obj : pointer to PMC register instance + * \return pad keep status + * - 0 : pad keep disable. + * - 1 : pad keep enable. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetStatusPadKeep(const PmcRegType *obj) +{ + return ((obj->STATUS & PMC_STATUS_PAD_KEEP_MASK) >> PMC_STATUS_PAD_KEEP_SHIFT); +} + +/*! \brief Sets the pad keep status + * + * This function sets the pad keep status. + * + * \param[in] obj : pointer to PMC register instance + */ +__attribute__((always_inline)) static inline void PmcReg_ClearStatusPadKeep(PmcRegType *obj) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + obj->STATUS = (((uint32_t)(((uint32_t)(1)) << PMC_STATUS_PAD_KEEP_SHIFT)) & PMC_STATUS_PAD_KEEP_MASK); +} + +/*! \brief Gets the key lock enable + * + * This function gets the current key lock enable. + * + * \param[in] obj : pointer to PMC register instance + * \return key lock enable + * - 0 : disable. + * - 1 : enable. + */ +__attribute__((always_inline)) static inline uint8_t PmcReg_GetStatusKeyLock(const PmcRegType *obj) +{ + return ((obj->STATUS & PMC_STATUS_LOCK_MASK) >> PMC_STATUS_LOCK_SHIFT); +} + +/*! \brief Sets the PMC key lock enable + * + * This function sets the PMC key lock enable. + * pmc write public function register hit key, the initial confirm key is 0x20220509, + * when cpu write data is 0x20220509, PMC public function register lock is invalid, + * CPU can write the pmc public function register. + * When cpu write data is not equal 0x20220509, PMC public register function lock is valid, + * CPU can not write the pmc function register + * + * \param[in] obj : pointer to PMC register instance + * \param[in] value : the value of PMC key lock enable + * - 0x20220509 : unlock + * - others : lock + */ +__attribute__((always_inline)) static inline void PmcReg_SetKey(PmcRegType *obj, uint32_t value) +{ + obj->KEY = value; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _PMC_REG_H_ */ \ No newline at end of file diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/port_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/port_reg.h new file mode 100644 index 0000000..cc3f1e7 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/port_reg.h @@ -0,0 +1,761 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PORT_REG_H_ +#define _PORT_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the PORT Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* Length of PCR register array */ +#define PORT_PCR_COUNT (18U) + +/* PCR Bit Fields */ +#define PORT_PCR_ISF_MASK (0x1000000u) +#define PORT_PCR_ISF_SHIFT (24u) +#define PORT_PCR_ISF_WIDTH (1u) +#define PORT_PCR_IRQ_CFG_MASK (0xF0000u) +#define PORT_PCR_IRQ_CFG_SHIFT (16u) +#define PORT_PCR_IRQ_CFG_WIDTH (4u) +#define PORT_PCR_LOCK_MASK (0x8000u) +#define PORT_PCR_LOCK_SHIFT (15u) +#define PORT_PCR_LOCK_WIDTH (1u) +#define PORT_PCR_MUX_MASK (0x700u) +#define PORT_PCR_MUX_SHIFT (8u) +#define PORT_PCR_MUX_WIDTH (3u) +#define PORT_PCR_ODE_MASK (0x80u) +#define PORT_PCR_ODE_SHIFT (7u) +#define PORT_PCR_ODE_WIDTH (1u) +#define PORT_PCR_DRV_STR_MASK (0x40u) +#define PORT_PCR_DRV_STR_SHIFT (6u) +#define PORT_PCR_DRV_STR_WIDTH (1u) +#define PORT_PCR_SR_MASK (0x20u) +#define PORT_PCR_SR_SHIFT (5u) +#define PORT_PCR_SR_WIDTH (1u) +#define PORT_PCR_PAS_FLT_MASK (0x10u) +#define PORT_PCR_PAS_FLT_SHIFT (4u) +#define PORT_PCR_PAS_FLT_WIDTH (1u) +#define PORT_PCR_AEN_MASK (0x04u) +#define PORT_PCR_AEN_SHIFT (2u) +#define PORT_PCR_AEN_WIDTH (1u) +#define PORT_PCR_PDE_MASK (0x02u) +#define PORT_PCR_PDE_SHIFT (1u) +#define PORT_PCR_PDE_WIDTH (1u) +#define PORT_PCR_PUE_MASK (0x01u) +#define PORT_PCR_PUE_SHIFT (0u) +#define PORT_PCR_PUE_WIDTH (1u) + +/* GPCLR Bit Fields */ +#define PORT_GPCLR_LDAT_MASK (0xFFFF0000u) +#define PORT_GPCLR_LDAT_SHIFT (16u) +#define PORT_GPCLR_LDAT_WIDTH (16u) +#define PORT_GPCLR_LWEN_MASK (0xFFFFu) +#define PORT_GPCLR_LWEN_SHIFT (0u) +#define PORT_GPCLR_LWEN_WIDTH (16u) + +/* GPCHR Bit Fields */ +#define PORT_GPCHR_HDAT_MASK (0xFFFF0000u) +#define PORT_GPCHR_HDAT_SHIFT (16u) +#define PORT_GPCHR_HDAT_WIDTH (16u) +#define PORT_GPCHR_HWEN_MASK (0xFFFFu) +#define PORT_GPCHR_HWEN_SHIFT (0u) +#define PORT_GPCHR_HWEN_WIDTH (16u) + +/* GICLR Bit Fields */ +#define PORT_GICLR_INT_LDAT_MASK (0xFFFF0000u) +#define PORT_GICLR_INT_LDAT_SHIFT (16u) +#define PORT_GICLR_INT_LDAT_WIDTH (16u) +#define PORT_GICLR_INT_LWEN_MASK (0xFFFFu) +#define PORT_GICLR_INT_LWEN_SHIFT (0u) +#define PORT_GICLR_INT_LWEN_WIDTH (16u) + +/* GICHR Bit Fields */ +#define PORT_GICHR_INT_HDAT_MASK (0xFFFF0000u) +#define PORT_GICHR_INT_HDAT_SHIFT (16u) +#define PORT_GICHR_INT_HDAT_WIDTH (16u) +#define PORT_GICHR_INT_HWEN_MASK (0xFFFFu) +#define PORT_GICHR_INT_HWEN_SHIFT (0u) +#define PORT_GICHR_INT_HWEN_WIDTH (16u) + +/* DFWR Bit Fields */ +#define PORT_DFWR_LEN_MASK (0x1Fu) +#define PORT_DFWR_LEN_SHIFT (0u) +#define PORT_DFWR_LEN_WIDTH (5u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of PORT registers + */ +typedef struct _PortRegType_ +{ + volatile uint32_t PCR[PORT_PCR_COUNT]; /*!< PORT control, offset: 0x00 */ + uint32_t RESERVED0[14]; /*!< Reserved registers, offset: 0x48 */ + volatile uint32_t GPCLR; /*!< Global Pin Control Low bits, offset: 0x80 */ + volatile uint32_t GPCHR; /*!< Global pin control high bits, offset: 0x84 */ + volatile uint32_t GICLR; /*!< Global Interrupt Control Low, offset: 0x88 */ + volatile uint32_t GICHR; /*!< Global Interrupt Control High, offset: 0x8C */ + uint32_t RESERVED1[4]; /*!< Reserved registers, offset: 0x90 */ + volatile uint32_t ISFR; /*!< Interrupt Status Flag, offset: 0xA0 */ + uint32_t RESERVED2[7]; /*!< Reserved registers, offset: 0xA4 */ + volatile uint32_t DFER; /*!< Digital Filter Enable, offset: 0xC0 */ + uint32_t RESERVED3; /*!< Reserved register, offset: 0xC4 */ + volatile uint32_t DFWR; /*!< Digital Filter Width, offset: 0xC8 */ +} PortRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the Interrupt Status Flag + * + * This function gets the current Interrupt Status Flag. + * The pin interrupt configuration is valid in all digital pin muxing modes. + * + * \note If the pin is configured to generate a DMA request, + * then the corresponding flag will be cleared automatically at the completion of the requested DMA transfer. + * Otherwise, the flag remains set until a logic 1 is written to the flag. + * If the pin is configured for a level sensitive interrupt and the pin remains asserted, + * then the flag is set again immediately after it is cleared. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return Interrupt Status Flag + * - 0b : Configured interrupt is not detected. + * - 1b : Configured interrupt is detected. + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrIsf(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_ISF_MASK) >> PORT_PCR_ISF_SHIFT); +} + +/*! \brief Sets the Interrupt Status Flag + * + * This function sets the Interrupt Status Flag. + * The pin interrupt configuration is valid in all digital pin muxing modes. + * + * \note If the pin is configured to generate a DMA request, + * then the corresponding flag will be cleared automatically at the completion of the requested DMA transfer. + * Otherwise, the flag remains set until a logic 1 is written to the flag. + * If the pin is configured for a level sensitive interrupt and the pin remains asserted, + * then the flag is set again immediately after it is cleared. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of Interrupt Status Flag + * - 0b : Configured interrupt is not detected. + * - 1b : Configured interrupt is detected. + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrIsf(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_ISF_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_ISF_SHIFT)) & PORT_PCR_ISF_MASK); + obj->PCR[pin] = tmp; + /* Read back to avoid problem */ + (void)obj->PCR[pin]; +} + +/*! \brief Gets the Interrupt Configuration + * + * This function gets the current Interrupt Configuration. + * The pin interrupt configuration is valid in all digital pin muxing modes. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return Interrupt Configuration + * - 0000b : Interrupt Status Flag (ISF) is disabled. + * - 0001b : ISF flag and DMA request on rising edge. + * - 0010b : ISF flag and DMA request on falling edge. + * - 0011b : ISF flag and DMA request on either edge. + * - 0100b : Reserved. + * - 0101b : Reserved. + * - 0110b : Reserved. + * - 0111b : Reserved. + * - 1000b : ISF flag and Interrupt when logic 0. + * - 1001b : ISF flag and Interrupt on rising-edge. + * - 1010b : ISF flag and Interrupt on falling-edge. + * - 1011b : ISF flag and Interrupt on either edge. + * - 1100b : ISF flag and Interrupt when logic 1. + * - 1101b : Reserved. + * - 1110b : Reserved. + * - 1111b : Reserved + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrIrqCfg(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_IRQ_CFG_MASK) >> PORT_PCR_IRQ_CFG_SHIFT); +} + +/*! \brief Sets the Interrupt Configuration + * + * This function sets the Interrupt Configuration. + * The pin interrupt configuration is valid in all digital pin muxing modes. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of Interrupt Configuration + * - 0000b : Interrupt Status Flag (ISF) is disabled. + * - 0001b : ISF flag and DMA request on rising edge. + * - 0010b : ISF flag and DMA request on falling edge. + * - 0011b : ISF flag and DMA request on either edge. + * - 0100b : Reserved. + * - 0101b : Reserved. + * - 0110b : Reserved. + * - 0111b : Reserved. + * - 1000b : ISF flag and Interrupt when logic 0. + * - 1001b : ISF flag and Interrupt on rising-edge. + * - 1010b : ISF flag and Interrupt on falling-edge. + * - 1011b : ISF flag and Interrupt on either edge. + * - 1100b : ISF flag and Interrupt when logic 1. + * - 1101b : Reserved. + * - 1110b : Reserved. + * - 1111b : Reserved + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrIrqCfg(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_IRQ_CFG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_IRQ_CFG_SHIFT)) & PORT_PCR_IRQ_CFG_MASK); + obj->PCR[pin] = tmp; +} + +/*! \brief Gets the Lock Register + * + * This function gets the current Lock Register. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return Lock Register + * - 0b : Pin Control Register fields [15:0] are not locked. + * - 1b : Pin Control Register fields [15:0] are locked and cannot be updated until the next system reset + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrLock(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_LOCK_MASK) >> PORT_PCR_LOCK_SHIFT); +} + +/*! \brief Sets the Lock Register + * + * This function sets the Lock Register. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of Lock Register + * - 0b : Pin Control Register fields [15:0] are not locked. + * - 1b : Pin Control Register fields [15:0] are locked and cannot be updated until the next system reset + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrLock(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_LOCK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_LOCK_SHIFT)) & PORT_PCR_LOCK_MASK); + obj->PCR[pin] = tmp; +} + +/*! \brief Gets the Pin Mux Control + * + * This function gets the current Pin Mux Control. + * Not all pins support all pin muxing slots. + * Unimplemented pin muxing slots are reserved and may result in configuring the pin for a different pin muxing slot. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return Pin Mux Control + * - 000b : Pin disabled (Alternative 0) (analog). + * - 001b : Alternative 1 (GPIO). + * - 010b : Alternative 2 (chip-specific). + * - 011b : Alternative 3 (chip-specific). + * - 100b : Alternative 4 (chip-specific). + * - 101b : Alternative 5 (chip-specific). + * - 110b : Alternative 6 (chip-specific). + * - 111b : Alternative 7 (chip-specific) + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrMux(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_MUX_MASK) >> PORT_PCR_MUX_SHIFT); +} + +/*! \brief Sets the Pin Mux Control + * + * This function sets the Pin Mux Control. + * Not all pins support all pin muxing slots. + * Unimplemented pin muxing slots are reserved and may result in configuring the pin for a different pin muxing slot. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of Pin Mux Control + * - 000b : Pin disabled (Alternative 0) (analog). + * - 001b : Alternative 1 (GPIO). + * - 010b : Alternative 2 (chip-specific). + * - 011b : Alternative 3 (chip-specific). + * - 100b : Alternative 4 (chip-specific). + * - 101b : Alternative 5 (chip-specific). + * - 110b : Alternative 6 (chip-specific). + * - 111b : Alternative 7 (chip-specific) + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrMux(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_MUX_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_MUX_SHIFT)) & PORT_PCR_MUX_MASK); + obj->PCR[pin] = tmp; +} + +/*! \brief Gets the Open drain enable + * + * This function gets the current Open drain enable. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return Open drain enable + * - 0b : push pull + * - 1b : open drain + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrOde(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_ODE_MASK) >> PORT_PCR_ODE_SHIFT); +} + +/*! \brief Sets the Open drain enable + * + * This function sets the Open drain enable. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of Open drain enable + * - 0b : push pull + * - 1b : open drain + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrOde(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_ODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_ODE_SHIFT)) & PORT_PCR_ODE_MASK); + obj->PCR[pin] = tmp; +} + +/*! \brief Gets the Drive Strength Enable + * + * This function gets the current Drive Strength Enable. + * Drive strength configuration is valid in all digital pin muxing modes. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return Drive Strength Enable + * - 0b : Low drive strength is configured on the corresponding pin, if pin is configured as a digital output. + * - 1b : High drive strength is configured on the corresponding pin, if pin is configured as a digital output. + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrDrvStr(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_DRV_STR_MASK) >> PORT_PCR_DRV_STR_SHIFT); +} + +/*! \brief Sets the Drive Strength Enable + * + * This function sets the Drive Strength Enable. + * Drive strength configuration is valid in all digital pin muxing modes. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of Drive Strength Enable + * - 0b : Low drive strength is configured on the corresponding pin, if pin is configured as a digital output. + * - 1b : High drive strength is configured on the corresponding pin, if pin is configured as a digital output. + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrDrvStr(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_DRV_STR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_DRV_STR_SHIFT)) & PORT_PCR_DRV_STR_MASK); + obj->PCR[pin] = tmp; +} + +/*! \brief Gets the slew rate + * + * This function gets the current slew rate. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return slew rate + * - 0b : slow slew rate + * - 1b : fast slew rate + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrSr(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_SR_MASK) >> PORT_PCR_SR_SHIFT); +} + +/*! \brief Sets the slew rate + * + * This function sets the slew rate. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of slew rate + * - 0b : slow slew rate + * - 1b : fast slew rate + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrSr(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_SR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_SR_SHIFT)) & PORT_PCR_SR_MASK); + obj->PCR[pin] = tmp; +} + +/*! \brief Gets the Passive Filter Enable + * + * This function gets the current Passive Filter Enable. + * Passive filter configuration is valid in all digital pin muxing modes. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return Passive Filter Enable + * - 0b : Passive input filter is disabled on the corresponding pin. + * - 1b : Passive input filter is enabled on the corresponding pin, if the pin is configured as a digital input. + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrPasFlt(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_PAS_FLT_MASK) >> PORT_PCR_PAS_FLT_SHIFT); +} + +/*! \brief Sets the Passive Filter Enable + * + * This function sets the Passive Filter Enable. + * Passive filter configuration is valid in all digital pin muxing modes. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of Passive Filter Enable + * - 0b : Passive input filter is disabled on the corresponding pin. + * - 1b : Passive input filter is enabled on the corresponding pin, if the pin is configured as a digital input. + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrPasFlt(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_PAS_FLT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_PAS_FLT_SHIFT)) & PORT_PCR_PAS_FLT_MASK); + obj->PCR[pin] = tmp; +} + +/*! \brief Gets the Analog mode enable + * + * This function gets the current Analog mode enable. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return Analog mode enable + * - 0b : analog mode is disabled on the corresponding pin + * - 1b : analog mode is enabled on the corresponding pin + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrAen(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_AEN_MASK) >> PORT_PCR_AEN_SHIFT); +} + +/*! \brief Sets the Analog mode enable + * + * This function sets the Analog mode enable. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of Analog mode enable + * - 0b : analog mode is disabled on the corresponding pin + * - 1b : analog mode is enabled on the corresponding pin + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrAen(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_AEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_AEN_SHIFT)) & PORT_PCR_AEN_MASK); + obj->PCR[pin] = tmp; +} + +/*! \brief Gets the Pull down enable + * + * This function gets the current Pull down enable. + * Pull configuration is valid in all digital pin muxing modes. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return Pull down enable + * - 0b : Internal pulldown resistor is disabled + * - 1b : Internal pulldown resistor is enabled + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrPde(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_PDE_MASK) >> PORT_PCR_PDE_SHIFT); +} + +/*! \brief Sets the Pull down enable + * + * This function sets the Pull down enable. + * Pull configuration is valid in all digital pin muxing modes. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of Pull down enable + * - 0b : Internal pulldown resistor is disabled + * - 1b : Internal pulldown resistor is enabled + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrPde(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_PDE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_PDE_SHIFT)) & PORT_PCR_PDE_MASK); + obj->PCR[pin] = tmp; +} + +/*! \brief Gets the Pull up enable + * + * This function gets the current Pull up enable. + * Pull configuration is valid in all digital pin muxing modes. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \return Pull up enable + * - 0b : Internal pullup resistor is disabled + * - 1b : Internal pullup resistor is enabled + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetPcrPue(const PortRegType *obj, uint32_t pin) +{ + return ((obj->PCR[pin] & PORT_PCR_PUE_MASK) >> PORT_PCR_PUE_SHIFT); +} + +/*! \brief Sets the Pull up enable + * + * This function sets the Pull up enable. + * Pull configuration is valid in all digital pin muxing modes. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] pin : pin number + * \param[in] value : the value of Pull up enable + * - 0b : Internal pullup resistor is disabled + * - 1b : Internal pullup resistor is enabled + */ +__attribute__((always_inline)) static inline void PortReg_SetPcrPue(PortRegType *obj, uint32_t pin, uint8_t value) +{ + uint32_t tmp = obj->PCR[pin]; + + tmp &= ~PORT_PCR_PUE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_PCR_PUE_SHIFT)) & PORT_PCR_PUE_MASK); + obj->PCR[pin] = tmp; +} + +/*! \brief Sets the Global Pin Control register low 16 bits + * + * This function sets the Global Pin Control register low 16 bits + * Write value that is written to all Pin Control Registers bits [15:0] that are selected by GPWE + * + * \param[in] obj : pointer to PORT register instance + * \param[in] value : the value of Global Pin Write Data and write Enable + */ +__attribute__((always_inline)) static inline void PortReg_SetGpclr(PortRegType *obj, uint32_t value) +{ + obj->GPCLR = value; +} + +/*! \brief Sets the global Pin Control register high 16 bits + * + * This function sets the global Pin Control register high 16 bits. + * Write value that is written to all Pin Control Registers bits [15:0] that are selected by GPWE + * + * \param[in] obj : pointer to PORT register instance + * \param[in] value : the value of global write data and write enable + */ +__attribute__((always_inline)) static inline void PortReg_SetGpchr(PortRegType *obj, uint32_t value) +{ + obj->GPCHR = value; +} + +/*! \brief Sets the Global Interrupt register low 16 bits + * + * This function sets the Global Interrupt register low 16 bits. + * Write value that is written to all Pin Control Registers bits [31:16] that are selected by [15:0] + * + * \param[in] obj : pointer to PORT register instance + * \param[in] value : the value of Global Interrupt write data and write enable + */ +__attribute__((always_inline)) static inline void PortReg_SetGiclrInt(PortRegType *obj, uint32_t value) +{ + obj->GICLR = value; +} + +/*! \brief Sets the Global Interrupt register high 16 bits + * + * This function sets the Global Interrupt register high 16 bits. + * Write value that is written to all Pin Control Registers bits [31:16] that are selected by [15:0] + * + * \param[in] obj : pointer to PORT register instance + * \param[in] value : the value of Global Interrupt write data and enable + */ +__attribute__((always_inline)) static inline void PortReg_SetGichrInt(PortRegType *obj, uint32_t value) +{ + obj->GICHR = value; +} + +/*! \brief Gets the Interrupt Status Flag + * + * This function gets the current Interrupt Status Flag. + * Each bit in the field indicates the detection of the configured interrupt of the same number as the field. + * + * \note If the pin is configured to generate a DMA request, + * then the corresponding flag will be cleared automatically at the completion of the requested DMA transfer. + * Otherwise, the flag remains set until a logic 1 is written to the flag. + * If the pin is configured for a level sensitive interrupt and the pin remains asserted, + * then the flag is set again immediately after it is cleared. + * + * \param[in] obj : pointer to PORT register instance + * \return Interrupt Status Flag + * - 0b : Configured interrupt is not detected. + * - 1b : Configured interrupt is detected. + */ +__attribute__((always_inline)) static inline uint32_t PortReg_GetIsfrIsf(const PortRegType *obj) +{ + return obj->ISFR; +} + +/*! \brief Sets the Interrupt Status Flag + * + * This function sets the Interrupt Status Flag. + * Each bit in the field indicates the detection of the configured interrupt of the same number as the field. + * + * \note If the pin is configured to generate a DMA request, + * then the corresponding flag will be cleared automatically at the completion of the requested DMA transfer. + * Otherwise, the flag remains set until a logic 1 is written to the flag. + * If the pin is configured for a level sensitive interrupt and the pin remains asserted, + * then the flag is set again immediately after it is cleared. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] value : the value of Interrupt Status Flag + * - 0b : corresponding interrupt is not cleared. + * - 1b : corresponding interrupt is cleared. + */ +__attribute__((always_inline)) static inline void PortReg_SetIsfrIsf(PortRegType *obj, uint32_t value) +{ + obj->ISFR = value; + /* Read back to avoid problem */ + (void)obj->ISFR; +} + +/*! \brief Gets the Digital Filter Enable + * + * This function gets the current Digital Filter Enable. + * The digital filter configuration is valid in all digital pin muxing modes. + * The output of each digital filter is reset to zero at system reset and whenever the digital filter is disabled. + * Each bit in the field enables the digital filter of the same number as the field. + * + * \param[in] obj : pointer to PORT register instance + * \return Digital Filter Enable + * - 0b : Digital filter is disabled on the corresponding pin and output of the digital filter is reset to zero. + * - 1b : Digital filter is enabled on the corresponding pin, if the pin is configured as a digital input. + */ +__attribute__((always_inline)) static inline uint32_t PortReg_GetDferEn(const PortRegType *obj) +{ + return obj->DFER; +} + +/*! \brief Sets the Digital Filter Enable + * + * This function sets the Digital Filter Enable. + * The digital filter configuration is valid in all digital pin muxing modes. + * The output of each digital filter is reset to zero at system reset and whenever the digital filter is disabled. + * Each bit in the field enables the digital filter of the same number as the field. + * + * \param[in] obj : pointer to PORT register instance + * \param[in] value : the value of Digital Filter Enable + * - 0b : Digital filter is disabled on the corresponding pin and output of the digital filter is reset to zero. + * - 1b : Digital filter is enabled on the corresponding pin, if the pin is configured as a digital input. + */ +__attribute__((always_inline)) static inline void PortReg_SetDferEn(PortRegType *obj, uint32_t value) +{ + obj->DFER = value; +} + +/*! \brief Gets the Filter Length + * + * This function gets the current Filter Length. + * The digital filter configuration is valid in all digital pin muxing modes. + * Configures the maximum size of the glitches, in clock cycles, + * that the digital filter absorbs for the enabled digital filters. + * Glitches that are longer than this register setting will pass through the digital filter, + * and glitches that are equal to or less than this register setting are filtered. + * Changing the filter length must be done only after all filters are disable + * + * \param[in] obj : pointer to PORT register instance + * \return Filter Length + */ +__attribute__((always_inline)) static inline uint8_t PortReg_GetDfwrLen(const PortRegType *obj) +{ + return ((obj->DFWR & PORT_DFWR_LEN_MASK) >> PORT_DFWR_LEN_SHIFT); +} + +/*! \brief Sets the Filter Length + * + * This function sets the Filter Length. + * The digital filter configuration is valid in all digital pin muxing modes. + * Configures the maximum size of the glitches, in clock cycles, + * that the digital filter absorbs for the enabled digital filters. + * Glitches that are longer than this register setting will pass through the digital filter, + * and glitches that are equal to or less than this register setting are filtered. + * Changing the filter length must be done only after all filters are disable + * + * \param[in] obj : pointer to PORT register instance + * \param[in] value : the value of Filter Length + */ +__attribute__((always_inline)) static inline void PortReg_SetDfwrLen(PortRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DFWR; + + tmp &= ~PORT_DFWR_LEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PORT_DFWR_LEN_SHIFT)) & PORT_DFWR_LEN_MASK); + obj->DFWR = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _PORT_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/pwmlite_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/pwmlite_reg.h new file mode 100644 index 0000000..c8f8031 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/pwmlite_reg.h @@ -0,0 +1,429 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _PWMLITE_REG_H_ +#define _PWMLITE_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the PWMLITE Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/*! The number of PWMLITE channels */ +#define PWMLITE_CHANNEL_NUM (6) + +/* CTRL Bit Fields */ +#define PWMLITE_CTRL_SYNC_MODE_MASK (0x02u) +#define PWMLITE_CTRL_SYNC_MODE_SHIFT (1u) +#define PWMLITE_CTRL_SYNC_MODE_WIDTH (1u) +#define PWMLITE_CTRL_EN_MASK (0x01u) +#define PWMLITE_CTRL_EN_SHIFT (0u) +#define PWMLITE_CTRL_EN_WIDTH (1u) + +/* PRD Bit Fields */ +#define PWMLITE_PRD_PERIOD_MASK (0xFFFFFFFFu) +#define PWMLITE_PRD_PERIOD_SHIFT (0u) +#define PWMLITE_PRD_PERIOD_WIDTH (32u) + +/* STOP Bit Fields */ +#define PWMLITE_STOP_PAUSE_MASK (0x01u) +#define PWMLITE_STOP_PAUSE_SHIFT (0u) +#define PWMLITE_STOP_PAUSE_WIDTH (1u) + +/* SYNC Bit Fields */ +#define PWMLITE_SYNC_START_MASK (0x02u) +#define PWMLITE_SYNC_START_SHIFT (1u) +#define PWMLITE_SYNC_START_WIDTH (1u) +#define PWMLITE_SYNC_STATUS_MASK (0x01u) +#define PWMLITE_SYNC_STATUS_SHIFT (0u) +#define PWMLITE_SYNC_STATUS_WIDTH (1u) + +/* CH_CTRL Bit Fields */ +#define PWMLITE_CH_CTRL_CTRL1_MASK (0x0Cu) +#define PWMLITE_CH_CTRL_CTRL1_SHIFT (2u) +#define PWMLITE_CH_CTRL_CTRL1_WIDTH (2u) +#define PWMLITE_CH_CTRL_CTRL0_MASK (0x03u) +#define PWMLITE_CH_CTRL_CTRL0_SHIFT (0u) +#define PWMLITE_CH_CTRL_CTRL0_WIDTH (2u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of PWMLITE registers + */ +typedef struct _PwmLiteRegType_ +{ + volatile uint32_t CTRL; /*!< PWMLITE control, offset: 0x00 */ + volatile uint32_t PRD; /*!< PWMLITE counter period, offset: 0x04 */ + volatile uint32_t STOP; /*!< pause module register, offset: 0x08 */ + volatile uint32_t SYNC; /*!< register sync control and status, offset: 0x0C */ + struct + { + volatile uint32_t CTRL; /*!< channel n control, offset: 0x00 */ + volatile uint32_t THR0; /*!< channel n threshold0, offset: 0x04 */ + volatile uint32_t THR1; /*!< channel n threshold1, offset: 0x08 */ + uint32_t RESERVED0[1]; /*!< Reserverd block, offset: 0x0C */ + } CH[PWMLITE_CHANNEL_NUM]; +} PwmLiteRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the register update mode + * + * This function gets the current register update mode. + * + * \param[in] obj : pointer to PWMLITE register instance + * \return register update mode + * - 0b : async update, update when the register is configured + * - 1b : sync update + */ +__attribute__((always_inline)) static inline uint8_t PwmLiteReg_GetCtrlSyncMode(const PwmLiteRegType *obj) +{ + return ((obj->CTRL & PWMLITE_CTRL_SYNC_MODE_MASK) >> PWMLITE_CTRL_SYNC_MODE_SHIFT); +} + +/*! \brief Sets the register update mode + * + * This function sets the register update mode. + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] value : the value of register update mode + * - 0b : async update,update when the register is configured + * - 1b : sync update + */ +__attribute__((always_inline)) static inline void PwmLiteReg_SetCtrlSyncMode(PwmLiteRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL; + + tmp &= ~PWMLITE_CTRL_SYNC_MODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PWMLITE_CTRL_SYNC_MODE_SHIFT)) & PWMLITE_CTRL_SYNC_MODE_MASK); + obj->CTRL = tmp; +} + +/*! \brief Gets the pwm module enable + * + * This function gets the current pwm module enable. + * + * \param[in] obj : pointer to PWMLITE register instance + * \return pwm module enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t PwmLiteReg_GetCtrlEn(const PwmLiteRegType *obj) +{ + return ((obj->CTRL & PWMLITE_CTRL_EN_MASK) >> PWMLITE_CTRL_EN_SHIFT); +} + +/*! \brief Sets the pwm module enable + * + * This function sets the pwm module enable. + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] value : the value of pwm module enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void PwmLiteReg_SetCtrlEn(PwmLiteRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CTRL; + + tmp &= ~PWMLITE_CTRL_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PWMLITE_CTRL_EN_SHIFT)) & PWMLITE_CTRL_EN_MASK); + obj->CTRL = tmp; +} + +/*! \brief Gets the pwm counter period + * + * This function gets the current pwm counter period. + * + * \note This value should be > 0, if configured 0, the real period is 0x100000000. + * + * \param[in] obj : pointer to PWMLITE register instance + * \return pwm counter period + * - 0h : 0xFFFFFFFF + * - 1 : 1 + * - 2 : 2 + * ... + * - 0xFFFFFFFF : 0xFFFFFFFF + */ +__attribute__((always_inline)) static inline uint32_t PwmLiteReg_GetPrdPeriod(const PwmLiteRegType *obj) +{ + return ((obj->PRD & PWMLITE_PRD_PERIOD_MASK) >> PWMLITE_PRD_PERIOD_SHIFT); +} + +/*! \brief Sets the pwm counter period + * + * This function sets the pwm counter period. + * + * \note This value should be > 0, if configured 0, the real period is 0x100000000. + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] value : the value of pwm counter period + * - 0h : 0xFFFF_FFFF + * - 1h : 1 + * - 2h : 2 + * ... + * - 0xFFFFFFFF : 0xFFFFFFFF + */ +__attribute__((always_inline)) static inline void PwmLiteReg_SetPrdPeriod(PwmLiteRegType *obj, uint32_t value) +{ + uint32_t tmp = obj->PRD; + + tmp &= ~PWMLITE_PRD_PERIOD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PWMLITE_PRD_PERIOD_SHIFT)) & PWMLITE_PRD_PERIOD_MASK); + obj->PRD = tmp; +} + +/*! \brief Gets the pwm module pause + * + * This function gets the current pwm module pause. + * + * \param[in] obj : pointer to PWMLITE register instance + * \return pwm module pause + * - 0b : counter is working + * - 1b : stop counter + */ +__attribute__((always_inline)) static inline uint8_t PwmLiteReg_GetStopPause(const PwmLiteRegType *obj) +{ + return ((obj->STOP & PWMLITE_STOP_PAUSE_MASK) >> PWMLITE_STOP_PAUSE_SHIFT); +} + +/*! \brief Sets the pwm module pause + * + * This function sets the pwm module pause. + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] value : the value of pwm module pause + * - 0b : counter is working + * - 1b : stop counter + */ +__attribute__((always_inline)) static inline void PwmLiteReg_SetStopPause(PwmLiteRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->STOP; + + tmp &= ~PWMLITE_STOP_PAUSE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PWMLITE_STOP_PAUSE_SHIFT)) & PWMLITE_STOP_PAUSE_MASK); + obj->STOP = tmp; +} + +/*! \brief Sets the update register action + * + * This function sets the update register action. + * write to this register shall cause all registers take effect when counter reaches the PWM_PRD register + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] value : the value of update register action + */ +__attribute__((always_inline)) static inline void PwmLiteReg_SetSyncStart(PwmLiteRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SYNC; + + tmp &= ~PWMLITE_SYNC_START_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PWMLITE_SYNC_START_SHIFT)) & PWMLITE_SYNC_START_MASK); + obj->SYNC = tmp; +} + +/*! \brief Gets the configuration update status + * + * This function gets the current configuration update status. + * + * \param[in] obj : pointer to PWMLITE register instance + * \return configuration update status + * - 0b : update done + * - 1b : during update + */ +__attribute__((always_inline)) static inline uint8_t PwmLiteReg_GetSyncStatus(const PwmLiteRegType *obj) +{ + return ((obj->SYNC & PWMLITE_SYNC_STATUS_MASK) >> PWMLITE_SYNC_STATUS_SHIFT); +} + +/*! \brief Gets the action when counter reaches threshold1 + * + * This function gets the current action when counter reaches threshold1. + * When channel counter reaches the threshold PWMn_THR1, pwm output should be one of the following + * - 0h : keep + * - 1h : low + * - 2h : high + * - 3h : toggle + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] channel : the channel number, 0-7 + * \return action when counter reaches threshold1 + * - 0h : keep + * - 1h : low + * - 2h : high + * - 3h : toggle + */ +__attribute__((always_inline)) static inline uint8_t PwmLiteReg_GetChCtrl1(const PwmLiteRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CTRL & PWMLITE_CH_CTRL_CTRL1_MASK) >> PWMLITE_CH_CTRL_CTRL1_SHIFT); +} + +/*! \brief Sets the action when counter reaches threshold1 + * + * This function sets the action when counter reaches threshold1. + * When channel counter reaches the threshold PWMn_THR1, pwm output should be one of the following + * - 0h : keep + * - 1h : low + * - 2h : high + * - 3h : toggle + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] channel : the channel number, 0-7 + * \param[in] value : the value of action when counter reaches threshold1 + * - 0h : keep + * - 1h : low + * - 2h : high + * - 3h : toggle + */ +__attribute__((always_inline)) static inline void PwmLiteReg_SetChCtrl1(PwmLiteRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->CH[channel].CTRL; + + tmp &= ~PWMLITE_CH_CTRL_CTRL1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PWMLITE_CH_CTRL_CTRL1_SHIFT)) & PWMLITE_CH_CTRL_CTRL1_MASK); + obj->CH[channel].CTRL = tmp; +} + +/*! \brief Gets the action when counter reaches threshold0 + * + * This function gets the current action when counter reaches threshold0. + * When channel counter reaches the threshold PWM0_THR0, pwm output should be one of the following + * - 0h : keep + * - 1h : low + * - 2h : high + * - 3h : toggle + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] channel : the channel number, 0-7 + * \return action when counter reaches threshold0 + * - 0h : keep + * - 1h : low + * - 2h : high + * - 3h : toggle + */ +__attribute__((always_inline)) static inline uint8_t PwmLiteReg_GetChCtrl0(const PwmLiteRegType *obj, uint8_t channel) +{ + return ((obj->CH[channel].CTRL & PWMLITE_CH_CTRL_CTRL0_MASK) >> PWMLITE_CH_CTRL_CTRL0_SHIFT); +} + +/*! \brief Sets the action when counter reaches threshold0 + * + * This function sets the action when counter reaches threshold0. + * When channel counter reaches the threshold PWM0_THR0, pwm output should be one of the following + * - 0h : keep + * - 1h : low + * - 2h : high + * - 3h : toggle + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] channel : the channel number, 0-7 + * \param[in] value : the value of action when counter reaches threshold0 + * - 0h : keep + * - 1h : low + * - 2h : high + * - 3h : toggle + */ +__attribute__((always_inline)) static inline void PwmLiteReg_SetChCtrl0(PwmLiteRegType *obj, uint8_t channel, uint8_t value) +{ + uint32_t tmp = obj->CH[channel].CTRL; + + tmp &= ~PWMLITE_CH_CTRL_CTRL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << PWMLITE_CH_CTRL_CTRL0_SHIFT)) & PWMLITE_CH_CTRL_CTRL0_MASK); + obj->CH[channel].CTRL = tmp; +} + +/*! \brief Gets the channel threshold0 + * + * This function gets the current channel threshold0. + * This value should be > 0, if configured 0, the real threshold is PWM_PR + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] channel : the channel number, 0-7 + * \return channel threshold0 + */ +__attribute__((always_inline)) static inline uint32_t PwmLiteReg_GetChThr0(const PwmLiteRegType *obj, uint8_t channel) +{ + return obj->CH[channel].THR0; +} + +/*! \brief Sets the channel threshold0 + * + * This function sets the channel threshold0. + * This value should be > 0, if configured 0, the real threshold is PWM_PR + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] channel : the channel number, 0-7 + * \param[in] value : the value of channel threshold0 + */ +__attribute__((always_inline)) static inline void PwmLiteReg_SetChThr0(PwmLiteRegType *obj, uint8_t channel, uint32_t value) +{ + obj->CH[channel].THR0 = value; +} + +/*! \brief Gets the channel threshold1 + * + * This function gets the current channel threshold1. + * This value should be > 0, if configured 0, the real threshold is PWM_PR + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] channel : the channel number, 0-7 + * \return channel threshold1 + */ +__attribute__((always_inline)) static inline uint32_t PwmLiteReg_GetChThr1(const PwmLiteRegType *obj, uint8_t channel) +{ + return obj->CH[channel].THR1; +} + +/*! \brief Sets the channel threshold1 + * + * This function sets the channel threshold1. + * This value should be > 0, if configured 0, the real threshold is PWM_PR + * + * \param[in] obj : pointer to PWMLITE register instance + * \param[in] channel : the channel number, 0-7 + * \param[in] value : the value of channel threshold1 + */ +__attribute__((always_inline)) static inline void PwmLiteReg_SetChThr1(PwmLiteRegType *obj, uint8_t channel, uint32_t value) +{ + obj->CH[channel].THR1 = value; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _PWMLITE_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/rcm_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/rcm_reg.h new file mode 100644 index 0000000..f19af84 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/rcm_reg.h @@ -0,0 +1,1326 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _RCM_REG_H_ +#define _RCM_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the RCM Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* RST_FLAG Bit Fields */ +#define RCM_RST_FLAG_POR_RST_MASK (0x2000u) +#define RCM_RST_FLAG_POR_RST_SHIFT (13u) +#define RCM_RST_FLAG_POR_RST_WIDTH (1u) +#define RCM_RST_FLAG_LVR_RST_MASK (0x1000u) +#define RCM_RST_FLAG_LVR_RST_SHIFT (12u) +#define RCM_RST_FLAG_LVR_RST_WIDTH (1u) +#define RCM_RST_FLAG_FLS_INITIAL_MASK (0x800u) +#define RCM_RST_FLAG_FLS_INITIAL_SHIFT (11u) +#define RCM_RST_FLAG_FLS_INITIAL_WIDTH (1u) +#define RCM_RST_FLAG_STDBY_EXIT_F_MASK (0x400u) +#define RCM_RST_FLAG_STDBY_EXIT_F_SHIFT (10u) +#define RCM_RST_FLAG_STDBY_EXIT_F_WIDTH (1u) +#define RCM_RST_FLAG_FHU_RESET_F_MASK (0x200u) +#define RCM_RST_FLAG_FHU_RESET_F_SHIFT (9u) +#define RCM_RST_FLAG_FHU_RESET_F_WIDTH (1u) +#define RCM_RST_FLAG_CMU_SOSC_F_MASK (0x100u) +#define RCM_RST_FLAG_CMU_SOSC_F_SHIFT (8u) +#define RCM_RST_FLAG_CMU_SOSC_F_WIDTH (1u) +#define RCM_RST_FLAG_CMU_PLL_F_MASK (0x80u) +#define RCM_RST_FLAG_CMU_PLL_F_SHIFT (7u) +#define RCM_RST_FLAG_CMU_PLL_F_WIDTH (1u) +#define RCM_RST_FLAG_PLL_LOSS_F_MASK (0x20u) +#define RCM_RST_FLAG_PLL_LOSS_F_SHIFT (5u) +#define RCM_RST_FLAG_PLL_LOSS_F_WIDTH (1u) +#define RCM_RST_FLAG_MDMAP_RST_F_MASK (0x10u) +#define RCM_RST_FLAG_MDMAP_RST_F_SHIFT (4u) +#define RCM_RST_FLAG_MDMAP_RST_F_WIDTH (1u) +#define RCM_RST_FLAG_PIN_RST_F_MASK (0x08u) +#define RCM_RST_FLAG_PIN_RST_F_SHIFT (3u) +#define RCM_RST_FLAG_PIN_RST_F_WIDTH (1u) +#define RCM_RST_FLAG_LOCKUP_RST_F_MASK (0x04u) +#define RCM_RST_FLAG_LOCKUP_RST_F_SHIFT (2u) +#define RCM_RST_FLAG_LOCKUP_RST_F_WIDTH (1u) +#define RCM_RST_FLAG_SYS_RST_F_MASK (0x02u) +#define RCM_RST_FLAG_SYS_RST_F_SHIFT (1u) +#define RCM_RST_FLAG_SYS_RST_F_WIDTH (1u) +#define RCM_RST_FLAG_WDG_RST_F_MASK (0x01u) +#define RCM_RST_FLAG_WDG_RST_F_SHIFT (0u) +#define RCM_RST_FLAG_WDG_RST_F_WIDTH (1u) + +/* RST_SFLAG Bit Fields */ +#define RCM_RST_SFLAG_POR_RST_SF_MASK (0x2000u) +#define RCM_RST_SFLAG_POR_RST_SF_SHIFT (13u) +#define RCM_RST_SFLAG_POR_RST_SF_WIDTH (1u) +#define RCM_RST_SFLAG_LVR_RST_SF_MASK (0x1000u) +#define RCM_RST_SFLAG_LVR_RST_SF_SHIFT (12u) +#define RCM_RST_SFLAG_LVR_RST_SF_WIDTH (1u) +#define RCM_RST_SFLAG_FLS_INITIAL_SF_MASK (0x800u) +#define RCM_RST_SFLAG_FLS_INITIAL_SF_SHIFT (11u) +#define RCM_RST_SFLAG_FLS_INITIAL_SF_WIDTH (1u) +#define RCM_RST_SFLAG_STDBY_EXIT_SF_MASK (0x400u) +#define RCM_RST_SFLAG_STDBY_EXIT_SF_SHIFT (10u) +#define RCM_RST_SFLAG_STDBY_EXIT_SF_WIDTH (1u) +#define RCM_RST_SFLAG_FHU_RESET_SF_MASK (0x200u) +#define RCM_RST_SFLAG_FHU_RESET_SF_SHIFT (9u) +#define RCM_RST_SFLAG_FHU_RESET_SF_WIDTH (1u) +#define RCM_RST_SFLAG_CMU_SOSC_SF_MASK (0x100u) +#define RCM_RST_SFLAG_CMU_SOSC_SF_SHIFT (8u) +#define RCM_RST_SFLAG_CMU_SOSC_SF_WIDTH (1u) +#define RCM_RST_SFLAG_CMU_PLL_SF_MASK (0x80u) +#define RCM_RST_SFLAG_CMU_PLL_SF_SHIFT (7u) +#define RCM_RST_SFLAG_CMU_PLL_SF_WIDTH (1u) +#define RCM_RST_SFLAG_PLL_LOSS_SF_MASK (0x20u) +#define RCM_RST_SFLAG_PLL_LOSS_SF_SHIFT (5u) +#define RCM_RST_SFLAG_PLL_LOSS_SF_WIDTH (1u) +#define RCM_RST_SFLAG_MDMAP_RST_SF_MASK (0x10u) +#define RCM_RST_SFLAG_MDMAP_RST_SF_SHIFT (4u) +#define RCM_RST_SFLAG_MDMAP_RST_SF_WIDTH (1u) +#define RCM_RST_SFLAG_PIN_RST_SF_MASK (0x08u) +#define RCM_RST_SFLAG_PIN_RST_SF_SHIFT (3u) +#define RCM_RST_SFLAG_PIN_RST_SF_WIDTH (1u) +#define RCM_RST_SFLAG_LOCKUP_RST_SF_MASK (0x04u) +#define RCM_RST_SFLAG_LOCKUP_RST_SF_SHIFT (2u) +#define RCM_RST_SFLAG_LOCKUP_RST_SF_WIDTH (1u) +#define RCM_RST_SFLAG_SYS_RST_SF_MASK (0x02u) +#define RCM_RST_SFLAG_SYS_RST_SF_SHIFT (1u) +#define RCM_RST_SFLAG_SYS_RST_SF_WIDTH (1u) +#define RCM_RST_SFLAG_WDG_RST_SF_MASK (0x01u) +#define RCM_RST_SFLAG_WDG_RST_SF_SHIFT (0u) +#define RCM_RST_SFLAG_WDG_RST_SF_WIDTH (1u) + +/* RST_CTRL Bit Fields */ +#define RCM_RST_CTRL_LOCKUP_EN_MASK (0x20000u) +#define RCM_RST_CTRL_LOCKUP_EN_SHIFT (17u) +#define RCM_RST_CTRL_LOCKUP_EN_WIDTH (1u) +#define RCM_RST_CTRL_PLL_LOSS_EN_MASK (0x10000u) +#define RCM_RST_CTRL_PLL_LOSS_EN_SHIFT (16u) +#define RCM_RST_CTRL_PLL_LOSS_EN_WIDTH (1u) +#define RCM_RST_CTRL_CMU_SOSC_IE_MASK (0x1000u) +#define RCM_RST_CTRL_CMU_SOSC_IE_SHIFT (12u) +#define RCM_RST_CTRL_CMU_SOSC_IE_WIDTH (1u) +#define RCM_RST_CTRL_CMU_PLL_IE_MASK (0x800u) +#define RCM_RST_CTRL_CMU_PLL_IE_SHIFT (11u) +#define RCM_RST_CTRL_CMU_PLL_IE_WIDTH (1u) +#define RCM_RST_CTRL_PLL_LOSS_IE_MASK (0x200u) +#define RCM_RST_CTRL_PLL_LOSS_IE_SHIFT (9u) +#define RCM_RST_CTRL_PLL_LOSS_IE_WIDTH (1u) +#define RCM_RST_CTRL_MDMAP_RST_IE_MASK (0x100u) +#define RCM_RST_CTRL_MDMAP_RST_IE_SHIFT (8u) +#define RCM_RST_CTRL_MDMAP_RST_IE_WIDTH (1u) +#define RCM_RST_CTRL_PIN_RST_IE_MASK (0x80u) +#define RCM_RST_CTRL_PIN_RST_IE_SHIFT (7u) +#define RCM_RST_CTRL_PIN_RST_IE_WIDTH (1u) +#define RCM_RST_CTRL_SYS_RST_IE_MASK (0x20u) +#define RCM_RST_CTRL_SYS_RST_IE_SHIFT (5u) +#define RCM_RST_CTRL_SYS_RST_IE_WIDTH (1u) +#define RCM_RST_CTRL_WDG_RST_IE_MASK (0x10u) +#define RCM_RST_CTRL_WDG_RST_IE_SHIFT (4u) +#define RCM_RST_CTRL_WDG_RST_IE_WIDTH (1u) +#define RCM_RST_CTRL_GLOBAL_IE_MASK (0x04u) +#define RCM_RST_CTRL_GLOBAL_IE_SHIFT (2u) +#define RCM_RST_CTRL_GLOBAL_IE_WIDTH (1u) +#define RCM_RST_CTRL_RST_DELAY_MASK (0x03u) +#define RCM_RST_CTRL_RST_DELAY_SHIFT (0u) +#define RCM_RST_CTRL_RST_DELAY_WIDTH (2u) + +/* EXTRST Bit Fields */ +#define RCM_EXTRST_FLT_LEN_MASK (0x1F00u) +#define RCM_EXTRST_FLT_LEN_SHIFT (8u) +#define RCM_EXTRST_FLT_LEN_WIDTH (5u) +#define RCM_EXTRST_FLT_CK_MASK (0x10u) +#define RCM_EXTRST_FLT_CK_SHIFT (4u) +#define RCM_EXTRST_FLT_CK_WIDTH (1u) +#define RCM_EXTRST_FLT_EN_MASK (0x01u) +#define RCM_EXTRST_FLT_EN_SHIFT (0u) +#define RCM_EXTRST_FLT_EN_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of RCM registers + */ +typedef struct _RcmRegType_ +{ + const volatile uint32_t RST_FLAG; /*!< Recent reset flag, offset: 0x0 */ + volatile uint32_t RST_SFLAG; /*!< Sticky reset flag, offset: 0x4 */ + volatile uint32_t RST_CTRL; /*!< Reset control register, offset: 0x8 */ + volatile uint32_t EXTRST; /*!< External reset register, offset: 0xC */ + uint32_t RESERVED0[28]; /*!< Reserved register, offset: 0x10 */ + volatile uint32_t KEY; /*!< RCM lock/unlock key register, offset: 0x80 */ + const volatile uint32_t LOCK; /*!< RCM unlock/lock flag, offset: 0x84 */ +} RcmRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the power up reset flag + * + * This function gets the current power up reset flag. + * Indicates a reset has been caused by power up reset. + * + * \param[in] obj : pointer to RCM register instance + * \return power up reset flag + * - 0b : Reset not caused by power up reset + * - 1b : Reset caused by power up reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagPor(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_POR_RST_MASK) >> RCM_RST_FLAG_POR_RST_SHIFT); +} + +/*! \brief Gets the low power reset flag + * + * This function gets the current low power reset flag. + * Indicates a reset has been caused by low power reset. + * + * \param[in] obj : pointer to RCM register instance + * \return low power reset flag + * - 0b : Reset not caused by low power reset + * - 1b : Reset caused by low power reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagLvr(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_LVR_RST_MASK) >> RCM_RST_FLAG_LVR_RST_SHIFT); +} + +/*! \brief Gets the Flash initial reset flag + * + * This function gets the current Flash initial reset flag. + * Indicates a reset has been caused by Flash initial reset. + * + * \param[in] obj : pointer to RCM register instance + * \return Flash initial reset flag + * - 0b : Reset not caused by Flash initial reset + * - 1b : Reset caused by Flash initial reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagFlsInitial(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_FLS_INITIAL_MASK) >> RCM_RST_FLAG_FLS_INITIAL_SHIFT); +} + +/*! \brief Gets the exit standby mode reset flag + * + * This function gets the current exit standby mode reset flag. + * Indicates a reset has been caused by standby exit reset. + * + * \param[in] obj : pointer to RCM register instance + * \return exit standby mode reset flag + * - 0b : Reset not caused by standby exit reset + * - 1b : Reset caused by standby exit reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagStdbyExit(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_STDBY_EXIT_F_MASK) >> RCM_RST_FLAG_STDBY_EXIT_F_SHIFT); +} + +/*! \brief Gets the FHU reset flag + * + * This function gets the current FHU reset flag. + * Indicates a reset has been caused by FHU reset. + * + * \param[in] obj : pointer to RCM register instance + * \return FHU reset flag + * - 0b : Reset not caused by FHU reset + * - 1b : Reset caused by FHU reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagFhu(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_FHU_RESET_F_MASK) >> RCM_RST_FLAG_FHU_RESET_F_SHIFT); +} + +/*! \brief Gets the SOSC clock monitor reset flag + * + * This function gets the current SOSC clock monitor reset flag. + * Indicates a reset has been caused by CMU SOSC reset. + * + * \param[in] obj : pointer to RCM register instance + * \return SOSC clock monitor reset flag + * - 0b : Reset not caused by CMU SOSC reset + * - 1b : Reset caused by CMU SOSC reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagCmuSosc(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_CMU_SOSC_F_MASK) >> RCM_RST_FLAG_CMU_SOSC_F_SHIFT); +} + +/*! \brief Gets the PLL clock monitor reset flag + * + * This function gets the current PLL clock monitor reset flag. + * Indicates a reset has been caused by CMU PLL reset. + * + * \param[in] obj : pointer to RCM register instance + * \return PLL clock monitor reset flag + * - 0b : Reset not caused by CMU PLL reset + * - 1b : Reset caused by CMU PLL reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagCmuPll(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_CMU_PLL_F_MASK) >> RCM_RST_FLAG_CMU_PLL_F_SHIFT); +} + +/*! \brief Gets the PLL lock loss reset flag + * + * This function gets the current PLL lock loss reset flag. + * Indicates a reset has been caused by PLL loss lock reset. + * + * \param[in] obj : pointer to RCM register instance + * \return PLL lock loss reset flag + * - 0b : Reset not caused by PLL lock loss reset + * - 1b : Reset caused by PLL lock loss reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagPllLoss(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_PLL_LOSS_F_MASK) >> RCM_RST_FLAG_PLL_LOSS_F_SHIFT); +} + +/*! \brief Gets the MDMAP reset flag + * + * This function gets the current MDMAP reset flag. + * Indicates a reset has been caused by MDMAP system reset. + * + * \param[in] obj : pointer to RCM register instance + * \return MDMAP reset flag + * - 0b : Reset not caused by MDMAP system reset + * - 1b : Reset caused by MDMAP system reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagMdmap(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_MDMAP_RST_F_MASK) >> RCM_RST_FLAG_MDMAP_RST_F_SHIFT); +} + +/*! \brief Gets the External PIN reset flag + * + * This function gets the current External PIN reset flag. + * Indicates a reset has been caused by an active-low level on the external RESET (RESET_b) pin. + * + * \param[in] obj : pointer to RCM register instance + * \return External PIN reset flag + * - 0b : Reset not caused by external reset pin + * - 1b : Reset caused by external reset pin + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagPin(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_PIN_RST_F_MASK) >> RCM_RST_FLAG_PIN_RST_F_SHIFT); +} + +/*! \brief Gets the Core Lockup reset flag + * + * This function gets the current Core Lockup reset flag. + * Indicates a reset has been caused by the Arm core indication of a LOCKUP event. + * + * \param[in] obj : pointer to RCM register instance + * \return Core Lockup reset flag + * - 0b : Reset not caused by core LOCKUP event + * - 1b : Reset caused by core LOCKUP event + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagLockup(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_LOCKUP_RST_F_MASK) >> RCM_RST_FLAG_LOCKUP_RST_F_SHIFT); +} + +/*! \brief Gets the CPU Software reset flag + * + * This function gets the current CPU Software reset flag. + * Indicates a reset has been caused by software setting of SYSRESETREQ bit in + * Application Interrupt and Reset Control Register in the Arm core. + * + * \param[in] obj : pointer to RCM register instance + * \return CPU Software reset flag + * - 0b : Reset not caused by software setting of SYSRESETREQ bit + * - 1b : Reset caused by software setting of SYSRESETREQ bit + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagSys(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_SYS_RST_F_MASK) >> RCM_RST_FLAG_SYS_RST_F_SHIFT); +} + +/*! \brief Gets the Watchdog reset flag + * + * This function gets the current Watchdog reset flag. + * Indicates a reset has been caused by the watchdog timer timing out. + * This reset source can be blocked by disabling the watchdog. + * + * \param[in] obj : pointer to RCM register instance + * \return Watchdog reset flag + * - 0b : Reset not caused by watchdog timeout + * - 1b : Reset caused by watchdog timeout + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstFlagWdg(const RcmRegType *obj) +{ + return ((obj->RST_FLAG & RCM_RST_FLAG_WDG_RST_F_MASK) >> RCM_RST_FLAG_WDG_RST_F_SHIFT); +} + +/*! \brief Gets the Sticky power up reset flag + * + * This function gets the current Sticky power up reset flag. + * Indicates a reset has been caused by power up reset. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky power up reset flag + * - 0b : Reset not caused by power up reset + * - 1b : Reset caused by power up reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagPor(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_POR_RST_SF_MASK) >> RCM_RST_SFLAG_POR_RST_SF_SHIFT); +} + +/*! \brief Sets the Sticky power up reset flag + * + * This function sets the Sticky power up reset flag. + * Indicates a reset has been caused by power up reset. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky power up reset flag + * - 0b : Reset not caused by power up reset + * - 1b : Reset caused by power up reset + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagPor(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_POR_RST_SF_SHIFT)) & RCM_RST_SFLAG_POR_RST_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky low power reset flag + * + * This function gets the current Sticky low power reset flag. + * Indicates a reset has been caused by low power reset. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky low power reset flag + * - 0b : Reset not caused by low power reset + * - 1b : Reset caused by low power reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagLvr(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_LVR_RST_SF_MASK) >> RCM_RST_SFLAG_LVR_RST_SF_SHIFT); +} + +/*! \brief Sets the Sticky low power reset flag + * + * This function sets the Sticky low power reset flag. + * Indicates a reset has been caused by low power reset. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky low power reset flag + * - 0b : Reset not caused by low power reset + * - 1b : Reset caused by low power reset + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagLvr(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_LVR_RST_SF_SHIFT)) & RCM_RST_SFLAG_LVR_RST_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky Flash initial reset flag + * + * This function gets the current Sticky Flash initial reset flag. + * Indicates a reset has been caused by Flash initial reset. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky Flash initial reset flag + * - 0b : Reset not caused by Flash initial reset + * - 1b : Reset caused by Flash initial reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagFlsInitial(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_FLS_INITIAL_SF_MASK) >> RCM_RST_SFLAG_FLS_INITIAL_SF_SHIFT); +} + +/*! \brief Sets the Sticky Flash initial reset flag + * + * This function sets the Sticky Flash initial reset flag. + * Indicates a reset has been caused by Flash initial reset. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky Flash initial reset flag + * - 0b : Reset not caused by Flash initial reset + * - 1b : Reset caused by Flash initial reset + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagFlsInitial(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_FLS_INITIAL_SF_SHIFT)) & RCM_RST_SFLAG_FLS_INITIAL_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky exit standby mode reset flag + * + * This function gets the current Sticky exit standby mode reset flag. + * Indicates a reset has been caused by standby exit reset. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky exit standby mode reset flag + * - 0b : Reset not caused by standby exit reset + * - 1b : Reset caused by standby exit reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagStdbyExit(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_STDBY_EXIT_SF_MASK) >> RCM_RST_SFLAG_STDBY_EXIT_SF_SHIFT); +} + +/*! \brief Sets the Sticky exit standby mode reset flag + * + * This function sets the Sticky exit standby mode reset flag. + * Indicates a reset has been caused by standby exit reset. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky exit standby mode reset flag + * - 0b : Reset not caused by standby exit reset + * - 1b : Reset caused by standby exit reset + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagStdbyExit(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_STDBY_EXIT_SF_SHIFT)) & RCM_RST_SFLAG_STDBY_EXIT_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky FHU reset flag + * + * This function gets the current Sticky FHU reset flag. + * Indicates a reset has been caused by FHU reset. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky FHU reset flag + * - 0b : Reset not caused by FHU reset + * - 1b : Reset caused by FHU reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagFhu(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_FHU_RESET_SF_MASK) >> RCM_RST_SFLAG_FHU_RESET_SF_SHIFT); +} + +/*! \brief Sets the Sticky FHU reset flag + * + * This function sets the Sticky FHU reset flag. + * Indicates a reset has been caused by FHU reset. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky FHU reset flag + * - 0b : Reset not caused by FHU reset + * - 1b : Reset caused by FHU reset + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagFhu(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_FHU_RESET_SF_SHIFT)) & RCM_RST_SFLAG_FHU_RESET_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky SOSC clock monitor reset flag + * + * This function gets the current Sticky SOSC clock monitor reset flag. + * Indicates a reset has been caused by CMU SOSC reset. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky SOSC clock monitor reset flag + * - 0b : Reset not caused by CMU SOSC reset + * - 1b : Reset caused by CMU SOSC reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagCmuSosc(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_CMU_SOSC_SF_MASK) >> RCM_RST_SFLAG_CMU_SOSC_SF_SHIFT); +} + +/*! \brief Sets the Sticky SOSC clock monitor reset flag + * + * This function sets the Sticky SOSC clock monitor reset flag. + * Indicates a reset has been caused by CMU SOSC reset. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky SOSC clock monitor reset flag + * - 0b : Reset not caused by CMU SOSC reset + * - 1b : Reset caused by CMU SOSC reset + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagCmuSosc(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_CMU_SOSC_SF_SHIFT)) & RCM_RST_SFLAG_CMU_SOSC_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky PLL clock monitor reset flag + * + * This function gets the current Sticky PLL clock monitor reset flag. + * Indicates a reset has been caused by CMU PLL reset. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky PLL clock monitor reset flag + * - 0b : Reset not caused by CMU PLL reset + * - 1b : Reset caused by CMU PLL reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagCmuPll(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_CMU_PLL_SF_MASK) >> RCM_RST_SFLAG_CMU_PLL_SF_SHIFT); +} + +/*! \brief Sets the Sticky PLL clock monitor reset flag + * + * This function sets the Sticky PLL clock monitor reset flag. + * Indicates a reset has been caused by CMU PLL reset. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky PLL clock monitor reset flag + * - 0b : Reset not caused by CMU PLL reset + * - 1b : Reset caused by CMU PLL reset + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagCmuPll(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_CMU_PLL_SF_SHIFT)) & RCM_RST_SFLAG_CMU_PLL_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky PLL lock loss reset flag + * + * This function gets the current Sticky PLL lock loss reset flag. + * Indicates a reset has been caused by PLL loss lock reset. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky PLL lock loss reset flag + * - 0b : Reset not caused by PLL lock loss reset + * - 1b : Reset caused by PLL lock loss reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagPllLoss(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_PLL_LOSS_SF_MASK) >> RCM_RST_SFLAG_PLL_LOSS_SF_SHIFT); +} + +/*! \brief Sets the Sticky PLL lock loss reset flag + * + * This function sets the Sticky PLL lock loss reset flag. + * Indicates a reset has been caused by PLL loss lock reset. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky PLL lock loss reset flag + * - 0b : Reset not caused by PLL lock loss reset + * - 1b : Reset caused by PLL lock loss reset + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagPllLoss(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_PLL_LOSS_SF_SHIFT)) & RCM_RST_SFLAG_PLL_LOSS_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky MDMAP reset flag + * + * This function gets the current Sticky MDMAP reset flag. + * Indicates a reset has been caused by MDMAP system reset. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky MDMAP reset flag + * - 0b : Reset not caused by MDMAP system reset + * - 1b : Reset caused by MDMAP system reset + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagMdmap(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_MDMAP_RST_SF_MASK) >> RCM_RST_SFLAG_MDMAP_RST_SF_SHIFT); +} + +/*! \brief Sets the Sticky MDMAP reset flag + * + * This function sets the Sticky MDMAP reset flag. + * Indicates a reset has been caused by MDMAP system reset. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky MDMAP reset flag + * - 0b : Reset not caused by MDMAP system reset + * - 1b : Reset caused by MDMAP system reset + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagMdmap(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_MDMAP_RST_SF_SHIFT)) & RCM_RST_SFLAG_MDMAP_RST_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky External PIN reset flag + * + * This function gets the current Sticky External PIN reset flag. + * Indicates a reset has been caused by an active-low level on the external RESET (RESET_b) pin. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky External PIN reset flag + * - 0b : Reset not caused by external reset pin + * - 1b : Reset caused by external reset pin + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagPin(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_PIN_RST_SF_MASK) >> RCM_RST_SFLAG_PIN_RST_SF_SHIFT); +} + +/*! \brief Sets the Sticky External PIN reset flag + * + * This function sets the Sticky External PIN reset flag. + * Indicates a reset has been caused by an active-low level on the external RESET (RESET_b) pin. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky External PIN reset flag + * - 0b : Reset not caused by external reset pin + * - 1b : Reset caused by external reset pin + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagPin(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_PIN_RST_SF_SHIFT)) & RCM_RST_SFLAG_PIN_RST_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky Core Lockup reset flag + * + * This function gets the current Sticky Core Lockup reset flag. + * Indicates a reset has been caused by the Arm core indication of a LOCKUP event. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky Core Lockup reset flag + * - 0b : Reset not caused by core LOCKUP event + * - 1b : Reset caused by core LOCKUP event + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagLockup(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_LOCKUP_RST_SF_MASK) >> RCM_RST_SFLAG_LOCKUP_RST_SF_SHIFT); +} + +/*! \brief Sets the Sticky Core Lockup reset flag + * + * This function sets the Sticky Core Lockup reset flag. + * Indicates a reset has been caused by the Arm core indication of a LOCKUP event. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky Core Lockup reset flag + * - 0b : Reset not caused by core LOCKUP event + * - 1b : Reset caused by core LOCKUP event + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagLockup(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_LOCKUP_RST_SF_SHIFT)) & RCM_RST_SFLAG_LOCKUP_RST_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky CPU Software reset flag + * + * This function gets the current Sticky CPU Software reset flag. + * Indicates a reset has been caused by software setting of SYSRESETREQ bit in Application Interrupt + * and Reset Control Register in the Arm core. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky CPU Software reset flag + * - 0b : Reset not caused by software setting of SYSRESETREQ bit + * - 1b : Reset caused by software setting of SYSRESETREQ bit + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagSys(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_SYS_RST_SF_MASK) >> RCM_RST_SFLAG_SYS_RST_SF_SHIFT); +} + +/*! \brief Sets the Sticky CPU Software reset flag + * + * This function sets the Sticky CPU Software reset flag. + * Indicates a reset has been caused by software setting of SYSRESETREQ bit in Application Interrupt + * and Reset Control Register in the Arm core. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky CPU Software reset flag + * - 0b : Reset not caused by software setting of SYSRESETREQ bit + * - 1b : Reset caused by software setting of SYSRESETREQ bit + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagSys(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_SYS_RST_SF_SHIFT)) & RCM_RST_SFLAG_SYS_RST_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the Sticky Watchdog reset flag + * + * This function gets the current Sticky Watchdog reset flag. + * Indicates a reset has been caused by the watchdog timer timing out. + * This reset source can be blocked by disabling the watchdog. + * + * \param[in] obj : pointer to RCM register instance + * \return Sticky Watchdog reset flag + * - 0b : Reset not caused by watchdog timeout + * - 1b : Reset caused by watchdog timeout + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstSFlagWdg(const RcmRegType *obj) +{ + return ((obj->RST_SFLAG & RCM_RST_SFLAG_WDG_RST_SF_MASK) >> RCM_RST_SFLAG_WDG_RST_SF_SHIFT); +} + +/*! \brief Sets the Sticky Watchdog reset flag + * + * This function sets the Sticky Watchdog reset flag. + * Indicates a reset has been caused by the watchdog timer timing out. + * This reset source can be blocked by disabling the watchdog. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Sticky Watchdog reset flag + * - 0b : Reset not caused by watchdog timeout + * - 1b : Reset caused by watchdog timeout + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstSFlagWdg(RcmRegType *obj, uint8_t value) +{ + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + uint32_t tmp = 0; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_SFLAG_WDG_RST_SF_SHIFT)) & RCM_RST_SFLAG_WDG_RST_SF_MASK); + obj->RST_SFLAG = tmp; +} + +/*! \brief Gets the lockup reset enable + * + * This function gets the current lockup reset enable. + * + * \param[in] obj : pointer to RCM register instance + * \return lockup reset enable + * - 0b : No reset or interrupt will be caused by LOCKUP. + * - 1b : Reset or interrupt will be caused by LOCKUP. + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlLockupEn(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_LOCKUP_EN_MASK) >> RCM_RST_CTRL_LOCKUP_EN_SHIFT); +} + +/*! \brief Sets the lockup reset enable + * + * This function sets the lockup reset enable. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of lockup reset enable + * - 0b : No reset or interrupt will be caused by LOCKUP. + * - 1b : Reset or interrupt will be caused by LOCKUP. + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlLockupEn(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_LOCKUP_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_LOCKUP_EN_SHIFT)) & RCM_RST_CTRL_LOCKUP_EN_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the PLL lock loss reset enable + * + * This function gets the current PLL lock loss reset enable. + * + * \param[in] obj : pointer to RCM register instance + * \return PLL lock loss reset enable + * - 0b : No reset or interrupt will be caused by PLL lock loss. + * - 1b : Reset or interrupt will be caused by PLL lock loss. + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlPllLossEn(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_PLL_LOSS_EN_MASK) >> RCM_RST_CTRL_PLL_LOSS_EN_SHIFT); +} + +/*! \brief Sets the PLL lock loss reset enable + * + * This function sets the PLL lock loss reset enable. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of PLL lock loss reset enable + * - 0b : No reset or interrupt will be caused by PLL lock loss. + * - 1b : Reset or interrupt will be caused by PLL lock loss. + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlPllLossEn(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_PLL_LOSS_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_PLL_LOSS_EN_SHIFT)) & RCM_RST_CTRL_PLL_LOSS_EN_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the SOSC clock monitor interrupt enable + * + * This function gets the current SOSC clock monitor interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \return SOSC clock monitor interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlCmuSoscIE(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_CMU_SOSC_IE_MASK) >> RCM_RST_CTRL_CMU_SOSC_IE_SHIFT); +} + +/*! \brief Sets the SOSC clock monitor interrupt enable + * + * This function sets the SOSC clock monitor interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of SOSC clock monitor interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlCmuSoscIE(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_CMU_SOSC_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_CMU_SOSC_IE_SHIFT)) & RCM_RST_CTRL_CMU_SOSC_IE_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the PLL clock monitor interrupt enable + * + * This function gets the current PLL clock monitor interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \return PLL clock monitor interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlCmuPllIE(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_CMU_PLL_IE_MASK) >> RCM_RST_CTRL_CMU_PLL_IE_SHIFT); +} + +/*! \brief Sets the PLL clock monitor interrupt enable + * + * This function sets the PLL clock monitor interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of PLL clock monitor interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlCmuPllIE(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_CMU_PLL_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_CMU_PLL_IE_SHIFT)) & RCM_RST_CTRL_CMU_PLL_IE_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the PLL loss reset interrupt enable + * + * This function gets the current PLL loss reset interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \return PLL loss reset interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlPllLossIE(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_PLL_LOSS_IE_MASK) >> RCM_RST_CTRL_PLL_LOSS_IE_SHIFT); +} + +/*! \brief Sets the PLL loss reset interrupt enable + * + * This function sets the PLL loss reset interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of PLL loss reset interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlPllLossIE(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_PLL_LOSS_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_PLL_LOSS_IE_SHIFT)) & RCM_RST_CTRL_PLL_LOSS_IE_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the MDMAP system reset interrupt enable + * + * This function gets the current MDMAP system reset interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \return MDMAP system reset interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlMdmapRstIE(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_MDMAP_RST_IE_MASK) >> RCM_RST_CTRL_MDMAP_RST_IE_SHIFT); +} + +/*! \brief Sets the MDMAP system reset interrupt enable + * + * This function sets the MDMAP system reset interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of MDMAP system reset interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlMdmapRstIE(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_MDMAP_RST_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_MDMAP_RST_IE_SHIFT)) & RCM_RST_CTRL_MDMAP_RST_IE_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the external reset pin interrupt enable + * + * This function gets the current external reset pin interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \return external reset pin interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlPinRstIE(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_PIN_RST_IE_MASK) >> RCM_RST_CTRL_PIN_RST_IE_SHIFT); +} + +/*! \brief Sets the external reset pin interrupt enable + * + * This function sets the external reset pin interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of external reset pin interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlPinRstIE(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_PIN_RST_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_PIN_RST_IE_SHIFT)) & RCM_RST_CTRL_PIN_RST_IE_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the CPU system reset interrupt enable + * + * This function gets the current CPU system reset interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \return CPU system reset interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlSysRstIE(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_SYS_RST_IE_MASK) >> RCM_RST_CTRL_SYS_RST_IE_SHIFT); +} + +/*! \brief Sets the CPU system reset interrupt enable + * + * This function sets the CPU system reset interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of CPU system reset interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlSysRstIE(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_SYS_RST_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_SYS_RST_IE_SHIFT)) & RCM_RST_CTRL_SYS_RST_IE_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the watchdog reset interrupt enable + * + * This function gets the current watchdog reset interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \return watchdog reset interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlWdgRstIE(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_WDG_RST_IE_MASK) >> RCM_RST_CTRL_WDG_RST_IE_SHIFT); +} + +/*! \brief Sets the watchdog reset interrupt enable + * + * This function sets the watchdog reset interrupt enable. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of watchdog reset interrupt enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlWdgRstIE(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_WDG_RST_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_WDG_RST_IE_SHIFT)) & RCM_RST_CTRL_WDG_RST_IE_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the Global Interrupt Enable + * + * This function gets the current Global Interrupt Enable. + * + * \note The individual interrupt-enable bits still need to be set to generate interrupts + * + * \param[in] obj : pointer to RCM register instance + * \return Global Interrupt Enable + * - 0b : All interrupt sources disabled. + * - 1b : All interrupt sources enabled. + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlGlobalIE(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_GLOBAL_IE_MASK) >> RCM_RST_CTRL_GLOBAL_IE_SHIFT); +} + +/*! \brief Sets the Global Interrupt Enable + * + * This function sets the Global Interrupt Enable. + * + * \note The individual interrupt-enable bits still need to be set to generate interrupts + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Global Interrupt Enable + * - 0b : All interrupt sources disabled. + * - 1b : All interrupt sources enabled. + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlGlobalIE(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_GLOBAL_IE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_GLOBAL_IE_SHIFT)) & RCM_RST_CTRL_GLOBAL_IE_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the Reset Delay Time + * + * This function gets the current Reset Delay Time. + * Configures the maximum reset delay time from when the interrupt is asserted and the system reset occurs. + * + * \param[in] obj : pointer to RCM register instance + * \return Reset Delay Time + * - 00b : 10 LPO cycles + * - 01b : 34 LPO cycles + * - 10b : 130 LPO cycles + * - 11b : 514 LPO cycles + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetRstCtrlRstDelay(const RcmRegType *obj) +{ + return ((obj->RST_CTRL & RCM_RST_CTRL_RST_DELAY_MASK) >> RCM_RST_CTRL_RST_DELAY_SHIFT); +} + +/*! \brief Sets the Reset Delay Time + * + * This function sets the Reset Delay Time. + * Configures the maximum reset delay time from when the interrupt is asserted and the system reset occurs. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of Reset Delay Time + * - 00b : 10 LPO cycles + * - 01b : 34 LPO cycles + * - 10b : 130 LPO cycles + * - 11b : 514 LPO cycles + */ +__attribute__((always_inline)) static inline void RcmReg_SetRstCtrlRstDelay(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->RST_CTRL; + + tmp &= ~RCM_RST_CTRL_RST_DELAY_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_RST_CTRL_RST_DELAY_SHIFT)) & RCM_RST_CTRL_RST_DELAY_MASK); + obj->RST_CTRL = tmp; +} + +/*! \brief Gets the external reset input digital filter length + * + * This function gets the current external reset input digital filter length. + * + * \param[in] obj : pointer to RCM register instance + * \return external reset input digital filter length + * - 00h : 1 + * - 01h : 2 + * - 02h : 3 + * ... + * - 1Fh : 32 + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetExtRstFltLen(const RcmRegType *obj) +{ + return ((obj->EXTRST & RCM_EXTRST_FLT_LEN_MASK) >> RCM_EXTRST_FLT_LEN_SHIFT); +} + +/*! \brief Sets the external reset input digital filter length + * + * This function sets the external reset input digital filter length. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of external reset input digital filter length + * - 00h : 1 + * - 01h : 2 + * - 02h : 3 + * ... + * - 1Fh : 32 + */ +__attribute__((always_inline)) static inline void RcmReg_SetExtRstFltLen(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTRST; + + tmp &= ~RCM_EXTRST_FLT_LEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_EXTRST_FLT_LEN_SHIFT)) & RCM_EXTRST_FLT_LEN_MASK); + obj->EXTRST = tmp; +} + +/*! \brief Gets the clock source of PIN Reset digital filter + * + * This function gets the current clock source of PIN Reset digital filter. + * This register should be changed after the clock is disabled at least 2 pre-changed clock cycles + * and 2 after-changed clock cycles. + * + * \param[in] obj : pointer to RCM register instance + * \return clock source of PIN Reset digital filter + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetExtRstFltCk(const RcmRegType *obj) +{ + return ((obj->EXTRST & RCM_EXTRST_FLT_CK_MASK) >> RCM_EXTRST_FLT_CK_SHIFT); +} + +/*! \brief Sets the clock source of PIN Reset digital filter + * + * This function sets the clock source of PIN Reset digital filter. + * This register should be changed after the clock is disabled at least 2 pre-changed clock cycles + * and 2 after-changed clock cycles. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of clock source of PIN Reset digital filter + * - 0b : clk_apb + * - 1b : clk_lpo128 + */ +__attribute__((always_inline)) static inline void RcmReg_SetExtRstFltCk(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTRST; + + tmp &= ~RCM_EXTRST_FLT_CK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_EXTRST_FLT_CK_SHIFT)) & RCM_EXTRST_FLT_CK_MASK); + obj->EXTRST = tmp; +} + +/*! \brief Gets the external reset input digital filter enable + * + * This function gets the current external reset input digital filter enable. + * Reset by Chip Por only + * + * \param[in] obj : pointer to RCM register instance + * \return external reset input digital filter enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t RcmReg_GetExtRstFltEn(const RcmRegType *obj) +{ + return ((obj->EXTRST & RCM_EXTRST_FLT_EN_MASK) >> RCM_EXTRST_FLT_EN_SHIFT); +} + +/*! \brief Sets the external reset input digital filter enable + * + * This function sets the external reset input digital filter enable. + * Reset by Chip Por only + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of external reset input digital filter enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void RcmReg_SetExtRstFltEn(RcmRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTRST; + + tmp &= ~RCM_EXTRST_FLT_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RCM_EXTRST_FLT_EN_SHIFT)) & RCM_EXTRST_FLT_EN_MASK); + obj->EXTRST = tmp; +} + +/*! \brief Sets the unlock key + * + * This function sets the unlock key. + * The RST/SCG/PCC registers in ALON power domain is locked by default. + * Before writing registers, write unlock key to this register. + * + * \param[in] obj : pointer to RCM register instance + * \param[in] value : the value of unlock key + * - 0x52434D4B : unlock + * - other : lock + */ +__attribute__((always_inline)) static inline void RcmReg_SetKey(RcmRegType *obj, uint32_t value) +{ + obj->KEY = value; +} + +/*! \brief Gets the RCM register lock flag + * + * This function gets the current RCM register lock flag. + * Registers in RCM is locked by default. Before writing registers in rcm, write unlock key. + * + * \param[in] obj : pointer to RCM register instance + * \return RCM register lock flag + * - 0b : unlock + * - 1b : lock + */ +__attribute__((always_inline)) static inline uint32_t RcmReg_GetLock(const RcmRegType *obj) +{ + return obj->LOCK; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _RCM_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/rtc_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/rtc_reg.h new file mode 100644 index 0000000..e7b26cc --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/rtc_reg.h @@ -0,0 +1,809 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _RTC_REG_H_ +#define _RTC_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the RTC (Real Time Clock) Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* TPR Bit Fields */ +#define RTC_TPR_TPR_MASK (0xFFFFu) +#define RTC_TPR_TPR_SHIFT (0u) +#define RTC_TPR_TPR_WIDTH (16u) + +/* CR Bit Fields */ +#define RTC_CR_CPE_MASK (0x1000000u) +#define RTC_CR_CPE_SHIFT (24u) +#define RTC_CR_CPE_WIDTH (1u) +#define RTC_CR_CLKO_MASK (0x200u) +#define RTC_CR_CLKO_SHIFT (9u) +#define RTC_CR_CLKO_WIDTH (1u) +#define RTC_CR_CPS_MASK (0x20u) +#define RTC_CR_CPS_SHIFT (5u) +#define RTC_CR_CPS_WIDTH (1u) +#define RTC_CR_UM_MASK (0x08u) +#define RTC_CR_UM_SHIFT (3u) +#define RTC_CR_UM_WIDTH (1u) +#define RTC_CR_SUP_MASK (0x04u) +#define RTC_CR_SUP_SHIFT (2u) +#define RTC_CR_SUP_WIDTH (1u) +#define RTC_CR_SWR_MASK (0x01u) +#define RTC_CR_SWR_SHIFT (0u) +#define RTC_CR_SWR_WIDTH (1u) + +/* SR Bit Fields */ +#define RTC_SR_TCE_MASK (0x10u) +#define RTC_SR_TCE_SHIFT (4u) +#define RTC_SR_TCE_WIDTH (1u) +#define RTC_SR_CSD_MASK (0x08u) +#define RTC_SR_CSD_SHIFT (3u) +#define RTC_SR_CSD_WIDTH (1u) +#define RTC_SR_TAF_MASK (0x04u) +#define RTC_SR_TAF_SHIFT (2u) +#define RTC_SR_TAF_WIDTH (1u) +#define RTC_SR_TOF_MASK (0x02u) +#define RTC_SR_TOF_SHIFT (1u) +#define RTC_SR_TOF_WIDTH (1u) +#define RTC_SR_TIF_MASK (0x01u) +#define RTC_SR_TIF_SHIFT (0u) +#define RTC_SR_TIF_WIDTH (1u) + +/* LR Bit Fields */ +#define RTC_LR_LRL_MASK (0x40u) +#define RTC_LR_LRL_SHIFT (6u) +#define RTC_LR_LRL_WIDTH (1u) +#define RTC_LR_SRL_MASK (0x20u) +#define RTC_LR_SRL_SHIFT (5u) +#define RTC_LR_SRL_WIDTH (1u) +#define RTC_LR_CRL_MASK (0x10u) +#define RTC_LR_CRL_SHIFT (4u) +#define RTC_LR_CRL_WIDTH (1u) + +/* IER Bit Fields */ +#define RTC_IER_TSIC_MASK (0x70000u) +#define RTC_IER_TSIC_SHIFT (16u) +#define RTC_IER_TSIC_WIDTH (3u) +#define RTC_IER_TSIE_MASK (0x10u) +#define RTC_IER_TSIE_SHIFT (4u) +#define RTC_IER_TSIE_WIDTH (1u) +#define RTC_IER_TAIE_MASK (0x04u) +#define RTC_IER_TAIE_SHIFT (2u) +#define RTC_IER_TAIE_WIDTH (1u) +#define RTC_IER_TIOE_MASK (0x02u) +#define RTC_IER_TIOE_SHIFT (1u) +#define RTC_IER_TIOE_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of RTC registers + */ +typedef struct _RtcRegType_ +{ + volatile uint32_t TSR; /*!< time second value register, offset: 0x0 */ + volatile uint32_t TPR; /*!< time prescaler value register, offset: 0x4 */ + volatile uint32_t TAR; /*!< time alarm value register, offset: 0x8 */ + uint32_t RESERVED; /*!< reserverd block, offset: 0xC */ + volatile uint32_t CR; /*!< control register, offset: 0x10 */ + volatile uint32_t SR; /*!< status register, offset: 0x14 */ + volatile uint32_t LR; /*!< lock register, offset: 0x18 */ + volatile uint32_t IER; /*!< interrupt config register, offset: 0x1C */ +} RtcRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the TSR value register + * + * This function gets the current TSR value register. + * When the time counter is enabled, the TSR is read only and increments once a second. + * The time counter will read as zero when SR[TOF] or SR[TIF] are set. + * When the time counter is disabled, the TSR can be read or written. + * Writing to the TSR when the time counter is disabled will clear the SR[TOF] and/or the SR[TIF]. + * Writing to TSR with zero is supported, but not recommended because TSR will read as zero when SR[TIF] or SR[TOF] + * are set (indicating the time is invalid) + * + * \param[in] obj : pointer to RTC register instance + * \return current TSR value + */ +__attribute__((always_inline)) static inline uint32_t RtcReg_GetTsr(const RtcRegType *obj) +{ + return obj->TSR; +} + +/*! \brief Sets the TSR value register + * + * This function sets the TSR value register. + * When the time counter is enabled, the TSR is read only and increments once a second. + * The time counter will read as zero when SR[TOF] or SR[TIF] are set. + * When the time counter is disabled, the TSR can be read or written. + * Writing to the TSR when the time counter is disabled will clear the SR[TOF] and/or the SR[TIF]. + * Writing to TSR with zero is supported, but not recommended because TSR will read as zero when SR[TIF] or SR[TOF] + * are set (indicating the time is invalid) + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of TSR register + */ +__attribute__((always_inline)) static inline void RtcReg_SetTsr(RtcRegType *obj, uint32_t value) +{ + obj->TSR = value; +} + +/*! \brief Gets the TPR value register + * + * This function gets the current TPR value register. + * When the time counter is enabled, the TPR is read only and increments every 32.768 kHz clock cycle. + * The time counter will read as zero when SR[TOF] or SR[TIF] are set. + * When the time counter is disabled, the TPR can be read or written. + * The TSR[TSR] increments when bit 14 of the TPR transitions from a logic one to a logic zero + * + * \param[in] obj : pointer to RTC register instance + * \return TPR value register + */ +__attribute__((always_inline)) static inline uint16_t RtcReg_GetTprTpr(const RtcRegType *obj) +{ + return ((obj->TPR & RTC_TPR_TPR_MASK) >> RTC_TPR_TPR_SHIFT); +} + +/*! \brief Sets the TPR value register + * + * This function sets the TPR value register. + * When the time counter is enabled, the TPR is read only and increments every 32.768 kHz clock cycle. + * The time counter will read as zero when SR[TOF] or SR[TIF] are set. + * When the time counter is disabled, the TPR can be read or written. + * The TSR[TSR] increments when bit 14 of the TPR transitions from a logic one to a logic zero + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of TPR value register + */ +__attribute__((always_inline)) static inline void RtcReg_SetTprTpr(RtcRegType *obj, uint16_t value) +{ + uint32_t tmp = obj->TPR; + + tmp &= ~RTC_TPR_TPR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_TPR_TPR_SHIFT)) & RTC_TPR_TPR_MASK); + obj->TPR = tmp; +} + +/*! \brief Gets the TAR value register + * + * This function gets the current TAR value register. + * When the time counter is enabled, the SR[TAF] is set whenever the TAR[TAR] equals the TSR[TSR] and the TSR[TSR] increments. + * Writing to the TAR clears the SR[TAF] + * + * \param[in] obj : pointer to RTC register instance + * \return TAR value register + */ +__attribute__((always_inline)) static inline uint32_t RtcReg_GetTar(const RtcRegType *obj) +{ + return obj->TAR; +} + +/*! \brief Sets the TAR value register + * + * This function sets the TAR value register. + * When the time counter is enabled, the SR[TAF] is set whenever the TAR[TAR] equals the TSR[TSR] and the TSR[TSR] increments. + * Writing to the TAR clears the SR[TAF] + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of TAR value register + */ +__attribute__((always_inline)) static inline void RtcReg_SetTar(RtcRegType *obj, uint32_t value) +{ + obj->TAR = value; +} + +/*! \brief Gets the Clock Pin Enable + * + * This function gets the current Clock Pin Enable. + * + * \param[in] obj : pointer to RTC register instance + * \return Clock Pin Enable + * - 0b : The RTC_CLKOUT function is disabled. + * - 1b : Enable RTC_CLKOUT function. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetCrCpe(const RtcRegType *obj) +{ + return ((obj->CR & RTC_CR_CPE_MASK) >> RTC_CR_CPE_SHIFT); +} + +/*! \brief Sets the Clock Pin Enable + * + * This function sets the Clock Pin Enable. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Clock Pin Enable + * - 0b : The RTC_CLKOUT function is disabled. + * - 1b : Enable RTC_CLKOUT function. + */ +__attribute__((always_inline)) static inline void RtcReg_SetCrCpe(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR; + + tmp &= ~RTC_CR_CPE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_CR_CPE_SHIFT)) & RTC_CR_CPE_MASK); + obj->CR = tmp; +} + +/*! \brief Gets the Clock Output + * + * This function gets the current Clock Output. + * + * \param[in] obj : pointer to RTC register instance + * \return Clock Output + * - 0b : The 32K/32.768KHz clock is output to other peripherals. + * - 1b : The 32K/32.768KHz clock is not output to other peripherals. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetCrClkO(const RtcRegType *obj) +{ + return ((obj->CR & RTC_CR_CLKO_MASK) >> RTC_CR_CLKO_SHIFT); +} + +/*! \brief Sets the Clock Output + * + * This function sets the Clock Output. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Clock Output + * - 0b : The 32K/32.768KHz clock is output to other peripherals. + * - 1b : The 32K/32.768KHz clock is not output to other peripherals. + */ +__attribute__((always_inline)) static inline void RtcReg_SetCrClkO(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR; + + tmp &= ~RTC_CR_CLKO_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_CR_CLKO_SHIFT)) & RTC_CR_CLKO_MASK); + obj->CR = tmp; +} + +/*! \brief Gets the Clock Pin Select + * + * This function gets the current Clock Pin Select. + * + * \param[in] obj : pointer to RTC register instance + * \return Clock Pin Select + * - 0b : The prescaler output clock (as configured by TSIC) is output on RTC_CLKOUT. + * - 1b : The RTC 32.768 kHz/32kHz clock is output on RTC_CLKOUT, provided it is output to other peripherals. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetCrCps(const RtcRegType *obj) +{ + return ((obj->CR & RTC_CR_CPS_MASK) >> RTC_CR_CPS_SHIFT); +} + +/*! \brief Sets the Clock Pin Select + * + * This function sets the Clock Pin Select. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Clock Pin Select + * - 0b : The prescaler output clock (as configured by TSIC) is output on RTC_CLKOUT. + * - 1b : The RTC 32.768 kHz/32kHz clock is output on RTC_CLKOUT, provided it is output to other peripherals. + */ +__attribute__((always_inline)) static inline void RtcReg_SetCrCps(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR; + + tmp &= ~RTC_CR_CPS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_CR_CPS_SHIFT)) & RTC_CR_CPS_MASK); + obj->CR = tmp; +} + +/*! \brief Gets the Update Mode + * + * This function gets the current Update Mode. + * when UM=0 and LR[SRL]=0, SR[TCE] can't be written + * when UM=1 and LR[SRL]=0, SR[TCE] can only be written when SR[TCE]=0 or SR[TIF]=1 or SR[TOF]=1. + * (when LR[SRL]=1, CR[UM] has no effect on SR[TCE]. In other words, in this situation, TCE can be written at any time) + * + * \param[in] obj : pointer to RTC register instance + * \return Update Mode + * - 0b : SR[TCE] register cannot be written when locked. + * - 1b : SR[TCE] register can be written when locked under limited conditions. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetCrUm(const RtcRegType *obj) +{ + return ((obj->CR & RTC_CR_UM_MASK) >> RTC_CR_UM_SHIFT); +} + +/*! \brief Sets the Update Mode + * + * This function sets the Update Mode. + * when UM=0 and LR[SRL]=0, SR[TCE] can't be written + * when UM=1 and LR[SRL]=0, SR[TCE] can only be written when SR[TCE]=0 or SR[TIF]=1 or SR[TOF]=1. + * (when LR[SRL]=1, CR[UM] has no effect on SR[TCE]. In other words, in this situation, TCE can be written at any time) + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Update Mode + * - 0b : SR[TCE] register cannot be written when locked. + * - 1b : SR[TCE] register can be written when locked under limited conditions. + */ +__attribute__((always_inline)) static inline void RtcReg_SetCrUm(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR; + + tmp &= ~RTC_CR_UM_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_CR_UM_SHIFT)) & RTC_CR_UM_MASK); + obj->CR = tmp; +} + +/*! \brief Gets the Supervisor Access + * + * This function gets the current Supervisor Access. + * + * \param[in] obj : pointer to RTC register instance + * \return Supervisor Access + * - 0b : Non-supervisor mode write accesses are not supported and generate a bus error. + * - 1b : Non-supervisor mode write accesses are supported. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetCrSup(const RtcRegType *obj) +{ + return ((obj->CR & RTC_CR_SUP_MASK) >> RTC_CR_SUP_SHIFT); +} + +/*! \brief Sets the Supervisor Access + * + * This function sets the Supervisor Access. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Supervisor Access + * - 0b : Non-supervisor mode write accesses are not supported and generate a bus error. + * - 1b : Non-supervisor mode write accesses are supported. + */ +__attribute__((always_inline)) static inline void RtcReg_SetCrSup(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR; + + tmp &= ~RTC_CR_SUP_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_CR_SUP_SHIFT)) & RTC_CR_SUP_MASK); + obj->CR = tmp; +} + +/*! \brief Gets the software reset + * + * This function gets the current software reset . + * + * \param[in] obj : pointer to RTC register instance + * \return software reset + * - 0b : no effect + * - 1b : reset all RTC registers except for the SWR bit. + * The SWR bit is cleared by POR and by software explicitly clearing it + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetCrSwr(const RtcRegType *obj) +{ + return ((obj->CR & RTC_CR_SWR_MASK) >> RTC_CR_SWR_SHIFT); +} + +/*! \brief Sets the software reset + * + * This function sets the software reset . + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of software reset + * - 0b : no effect + * - 1b : reset all RTC registers except for the SWR bit. + * The SWR bit is cleared by POR and by software explicitly clearing it + */ +__attribute__((always_inline)) static inline void RtcReg_SetCrSwr(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CR; + + tmp &= ~RTC_CR_SWR_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_CR_SWR_SHIFT)) & RTC_CR_SWR_MASK); + obj->CR = tmp; +} + +/*! \brief Gets the Time Counter Enable + * + * This function gets the current Time Counter Enable. + * When time counter is disabled the TSR register and TPR register are writeable, but do not increment. + * When time counter is enabled the TSR register and TPR register are not writeable, but increment. + * + * \param[in] obj : pointer to RTC register instance + * \return Time Counter Enable + * - 0b : Time counter is disabled. + * - 1b : Time counter is enabled. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetSrTce(const RtcRegType *obj) +{ + return ((obj->SR & RTC_SR_TCE_MASK) >> RTC_SR_TCE_SHIFT); +} + +/*! \brief Sets the Time Counter Enable + * + * This function sets the Time Counter Enable. + * When time counter is disabled the TSR register and TPR register are writeable, but do not increment. + * When time counter is enabled the TSR register and TPR register are not writeable, but increment. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Time Counter Enable + * - 0b : Time counter is disabled. + * - 1b : Time counter is enabled. + */ +__attribute__((always_inline)) static inline void RtcReg_SetSrTce(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SR; + + tmp &= ~RTC_SR_TCE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_SR_TCE_SHIFT)) & RTC_SR_TCE_MASK); + obj->SR = tmp; +} + +/*! \brief Gets the Time New Config Sync Done Enable + * + * This function gets the current Time New Config Sync Done Enable. + * when new config done, software should set this bit, but return 0 when software read now. + * this bit would be 1 when the new config sync done. Its means software can enable RTC again. + * + * \param[in] obj : pointer to RTC register instance + * \return Time New Config Sync Done Enable + * - 0b : Synchronization of New Config is Ongoing, Re-enable RTC is not allowed. + * - 1b : Synchronization of New Config is Done, Re-enable RTC is allowed. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetSrCsd(const RtcRegType *obj) +{ + return ((obj->SR & RTC_SR_CSD_MASK) >> RTC_SR_CSD_SHIFT); +} + +/*! \brief Sets the Time New Config Sync Done Enable + * + * This function gets the current Time New Config Sync Done Enable. + * when new config done, software should set this bit, but return 0 when software read now. + * this bit would be 1 when the new config sync done. Its means software can enable RTC again. + * + * \param[in] obj : pointer to RTC register instance + * \return Time New Config Sync Done Enable + * - 0b : Synchronization of New Config is Ongoing, Re-enable RTC is not allowed. + * - 1b : Synchronization of New Config is Done, Re-enable RTC is allowed. + */ +__attribute__((always_inline)) static inline void RtcReg_SetSrCsd(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SR; + + tmp &= ~RTC_SR_CSD_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_SR_CSD_SHIFT)) & RTC_SR_CSD_MASK); + obj->SR = tmp; +} + +/*! \brief Gets the Time Alarm Flag + * + * This function gets the current Time Alarm Flag. + * Time alarm flag is set when the TAR[TAR] equals the TSR[TSR] and the TSR[TSR] increments. + * This bit is cleared by writing the TAR register. + * + * \param[in] obj : pointer to RTC register instance + * \return Time Alarm Flag + * - 0b : Time alarm has not occurred. + * - 1b : Time alarm has occurred. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetSrTaf(const RtcRegType *obj) +{ + return ((obj->SR & RTC_SR_TAF_MASK) >> RTC_SR_TAF_SHIFT); +} + +/*! \brief Gets the Time Overflow Flag + * + * This function gets the current Time Overflow Flag. + * Time overflow flag is set when the time counter is enabled and overflows. + * This bit is cleared by writing the TSR register when the time counter is disabled. + * When this bit set, both counters keep incrementing so as TCE is set. + * + * \param[in] obj : pointer to RTC register instance + * \return Time Overflow Flag + * - 0b : Time overflow has not occurred. + * - 1b : Time overflow has occurred and time counter is read as zero + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetSrTof(const RtcRegType *obj) +{ + return ((obj->SR & RTC_SR_TOF_MASK) >> RTC_SR_TOF_SHIFT); +} + +/*! \brief Gets the Time Invalid Flag + * + * This function gets the current Time Invalid Flag. + * The time invalid flag is set on POR or software reset. + * This bit is cleared by writing the TSR register when the time counter is disabled. + * When this bit set, both counters keep incrementing so as TCE is set. + * + * \param[in] obj : pointer to RTC register instance + * \return Time Invalid Flag + * - 0b : Time is valid. + * - 1b : Time is invalid and time counter is read as zero + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetSrTif(const RtcRegType *obj) +{ + return ((obj->SR & RTC_SR_TIF_MASK) >> RTC_SR_TIF_SHIFT); +} + +/*! \brief Gets the Lock Register Lock + * + * This function gets the current Lock Register Lock. + * After being cleared, this bit can be set only by POR or software reset. + * + * \param[in] obj : pointer to RTC register instance + * \return Lock Register Lock + * - 0b : Lock Register is locked and writes are ignored. + * - 1b : Lock Register is not locked and writes complete as normal. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetLrLrl(const RtcRegType *obj) +{ + return ((obj->LR & RTC_LR_LRL_MASK) >> RTC_LR_LRL_SHIFT); +} + +/*! \brief Sets the Lock Register Lock + * + * This function sets the Lock Register Lock. + * After being cleared, this bit can be set only by POR or software reset. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Lock Register Lock + * - 0b : Lock Register is locked and writes are ignored. + * - 1b : Lock Register is not locked and writes complete as normal. + */ +__attribute__((always_inline)) static inline void RtcReg_SetLrLrl(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LR; + + tmp &= ~RTC_LR_LRL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_LR_LRL_SHIFT)) & RTC_LR_LRL_MASK); + obj->LR = tmp; +} + +/*! \brief Gets the status Register Lock + * + * This function gets the current status Register Lock. + * After being cleared, this bit can be set only by POR or software reset. + * + * \param[in] obj : pointer to RTC register instance + * \return status Register Lock + * - 0b : Status Register is locked and writes are ignored. + * - 1b : Status Register is not locked and writes complete as normal + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetLrSrl(const RtcRegType *obj) +{ + return ((obj->LR & RTC_LR_SRL_MASK) >> RTC_LR_SRL_SHIFT); +} + +/*! \brief Sets the status Register Lock + * + * This function sets the status Register Lock. + * After being cleared, this bit can be set only by POR or software reset. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of status Register Lock + * - 0b : Status Register is locked and writes are ignored. + * - 1b : Status Register is not locked and writes complete as normal + */ +__attribute__((always_inline)) static inline void RtcReg_SetLrSrl(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LR; + + tmp &= ~RTC_LR_SRL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_LR_SRL_SHIFT)) & RTC_LR_SRL_MASK); + obj->LR = tmp; +} + +/*! \brief Gets the Control Register Lock + * + * This function gets the current Control Register Lock. + * After being cleared, this bit can only be set by POR. + * + * \param[in] obj : pointer to RTC register instance + * \return Control Register Lock + * - 0b : Control Register is locked and writes are ignored. + * - 1b : Control Register is not locked and writes complete as normal. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetLrCrl(const RtcRegType *obj) +{ + return ((obj->LR & RTC_LR_CRL_MASK) >> RTC_LR_CRL_SHIFT); +} + +/*! \brief Sets the Control Register Lock + * + * This function sets the Control Register Lock. + * After being cleared, this bit can only be set by POR. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Control Register Lock + * - 0b : Control Register is locked and writes are ignored. + * - 1b : Control Register is not locked and writes complete as normal. + */ +__attribute__((always_inline)) static inline void RtcReg_SetLrCrl(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LR; + + tmp &= ~RTC_LR_CRL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_LR_CRL_SHIFT)) & RTC_LR_CRL_MASK); + obj->LR = tmp; +} + +/*! \brief Gets the Timer Seconds Interrupt Configuration + * + * This function gets the current Timer Seconds Interrupt Configuration. + * Configures the frequency of the RTC Seconds interrupt and the RTC_CLKOUT prescaler output. + * This field should only be altered when TSIE is clear. + * + * \param[in] obj : pointer to RTC register instance + * \return Timer Seconds Interrupt Configuration + * - 000b : 1 Hz. + * - 001b : 2 Hz. + * - 010b : 4 Hz. + * - 011b : 8 Hz. + * - 100b : 16 Hz. + * - 101b : 32 Hz. + * - 110b : 64 Hz. + * - 111b : 128 Hz + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetIerTsic(const RtcRegType *obj) +{ + return ((obj->IER & RTC_IER_TSIC_MASK) >> RTC_IER_TSIC_SHIFT); +} + +/*! \brief Sets the Timer Seconds Interrupt Configuration + * + * This function sets the Timer Seconds Interrupt Configuration. + * Configures the frequency of the RTC Seconds interrupt and the RTC_CLKOUT prescaler output. + * This field should only be altered when TSIE is clear. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Timer Seconds Interrupt Configuration + * - 000b : 1 Hz. + * - 001b : 2 Hz. + * - 010b : 4 Hz. + * - 011b : 8 Hz. + * - 100b : 16 Hz. + * - 101b : 32 Hz. + * - 110b : 64 Hz. + * - 111b : 128 Hz + */ +__attribute__((always_inline)) static inline void RtcReg_SetIerTsic(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IER; + + tmp &= ~RTC_IER_TSIC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_IER_TSIC_SHIFT)) & RTC_IER_TSIC_MASK); + obj->IER = tmp; +} + +/*! \brief Gets the Time Seconds Interrupt Enable + * + * This function gets the current Time Seconds Interrupt Enable. + * The seconds interrupt is an edge-sensitive interrupt with a dedicated interrupt vector. + * It is generated at least once a second and requires no software overhead (there is no corresponding status flag to clear). + * The frequency of the seconds interrupt is configured by TSIC. + * + * \param[in] obj : pointer to RTC register instance + * \return Time Seconds Interrupt Enable + * - 0b : Seconds interrupt is disabled. + * - 1b : Seconds interrupt is enabled. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetIerTsie(const RtcRegType *obj) +{ + return ((obj->IER & RTC_IER_TSIE_MASK) >> RTC_IER_TSIE_SHIFT); +} + +/*! \brief Sets the Time Seconds Interrupt Enable + * + * This function sets the Time Seconds Interrupt Enable. + * The seconds interrupt is an edge-sensitive interrupt with a dedicated interrupt vector. + * It is generated at least once a second and requires no software overhead (there is no corresponding status flag to clear). + * The frequency of the seconds interrupt is configured by TSIC. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Time Seconds Interrupt Enable + * - 0b : Seconds interrupt is disabled. + * - 1b : Seconds interrupt is enabled. + */ +__attribute__((always_inline)) static inline void RtcReg_SetIerTsie(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IER; + + tmp &= ~RTC_IER_TSIE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_IER_TSIE_SHIFT)) & RTC_IER_TSIE_MASK); + obj->IER = tmp; +} + +/*! \brief Gets the Time Alarm Interrupt Enable + * + * This function gets the current Time Alarm Interrupt Enable. + * + * \param[in] obj : pointer to RTC register instance + * \return Time Alarm Interrupt Enable + * - 0b : Time alarm flag does not generate an interrupt. + * - 1b : Time alarm flag does generate an interrupt. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetIerTaie(const RtcRegType *obj) +{ + return ((obj->IER & RTC_IER_TAIE_MASK) >> RTC_IER_TAIE_SHIFT); +} + +/*! \brief Sets the Time Alarm Interrupt Enable + * + * This function sets the Time Alarm Interrupt Enable. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Time Alarm Interrupt Enable + * - 0b : Time alarm flag does not generate an interrupt. + * - 1b : Time alarm flag does generate an interrupt. + */ +__attribute__((always_inline)) static inline void RtcReg_SetIerTaie(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IER; + + tmp &= ~RTC_IER_TAIE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_IER_TAIE_SHIFT)) & RTC_IER_TAIE_MASK); + obj->IER = tmp; +} + +/*! \brief Gets the Time Overflow Interrupt Enable + * + * This function gets the current Time Overflow Interrupt Enable. + * + * \param[in] obj : pointer to RTC register instance + * \return Time Overflow Interrupt Enable + * - 0b : Time overflow flag does not generate an interrupt. + * - 1b : Time overflow flag does generate an interrupt. + */ +__attribute__((always_inline)) static inline uint8_t RtcReg_GetIerTioe(const RtcRegType *obj) +{ + return ((obj->IER & RTC_IER_TIOE_MASK) >> RTC_IER_TIOE_SHIFT); +} + +/*! \brief Sets the Time Overflow Interrupt Enable + * + * This function sets the Time Overflow Interrupt Enable. + * + * \param[in] obj : pointer to RTC register instance + * \param[in] value : the value of Time Overflow Interrupt Enable + * - 0b : Time overflow flag does not generate an interrupt. + * - 1b : Time overflow flag does generate an interrupt. + */ +__attribute__((always_inline)) static inline void RtcReg_SetIerTioe(RtcRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->IER; + + tmp &= ~RTC_IER_TIOE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << RTC_IER_TIOE_SHIFT)) & RTC_IER_TIOE_MASK); + obj->IER = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _RTC_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/scg0_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/scg0_reg.h new file mode 100644 index 0000000..26dacc0 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/scg0_reg.h @@ -0,0 +1,638 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _SCG0_REG_H_ +#define _SCG0_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the SCG0 Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* TRIM Bit Fields */ +#define SCG0_TRIM_AUTO_GC_EN_MASK (0x100000u) +#define SCG0_TRIM_AUTO_GC_EN_SHIFT (20u) +#define SCG0_TRIM_AUTO_GC_EN_WIDTH (1u) + +/* OSC_CTRL Bit Fields */ +#define SCG0_OSC_CTRL_EN_EXT_CLK_MASK (0x10u) +#define SCG0_OSC_CTRL_EN_EXT_CLK_SHIFT (4u) +#define SCG0_OSC_CTRL_EN_EXT_CLK_WIDTH (1u) +#define SCG0_OSC_CTRL_RANGE_MASK (0x0Cu) +#define SCG0_OSC_CTRL_RANGE_SHIFT (2u) +#define SCG0_OSC_CTRL_RANGE_WIDTH (2u) +#define SCG0_OSC_CTRL_HGO_MASK (0x02u) +#define SCG0_OSC_CTRL_HGO_SHIFT (1u) +#define SCG0_OSC_CTRL_HGO_WIDTH (1u) +#define SCG0_OSC_CTRL_EN_SOSC_MASK (0x01u) +#define SCG0_OSC_CTRL_EN_SOSC_SHIFT (0u) +#define SCG0_OSC_CTRL_EN_SOSC_WIDTH (1u) + +/* PLL_CTRL0 Bit Fields */ +#define SCG0_PLL_CTRL0_PLL_VCO_DIV_MASK (0x200000u) +#define SCG0_PLL_CTRL0_PLL_VCO_DIV_SHIFT (21u) +#define SCG0_PLL_CTRL0_PLL_VCO_DIV_WIDTH (1u) +#define SCG0_PLL_CTRL0_PLL_POSDIV_MASK (0x3800u) +#define SCG0_PLL_CTRL0_PLL_POSDIV_SHIFT (11u) +#define SCG0_PLL_CTRL0_PLL_POSDIV_WIDTH (3u) +#define SCG0_PLL_CTRL0_PLL_FDKSEL_MASK (0x400u) +#define SCG0_PLL_CTRL0_PLL_FDKSEL_SHIFT (10u) +#define SCG0_PLL_CTRL0_PLL_FDKSEL_WIDTH (1u) +#define SCG0_PLL_CTRL0_PLL_PREDIV_MASK (0x300u) +#define SCG0_PLL_CTRL0_PLL_PREDIV_SHIFT (8u) +#define SCG0_PLL_CTRL0_PLL_PREDIV_WIDTH (2u) +#define SCG0_PLL_CTRL0_PLL_M_MASK (0xFEu) +#define SCG0_PLL_CTRL0_PLL_M_SHIFT (1u) +#define SCG0_PLL_CTRL0_PLL_M_WIDTH (7u) +#define SCG0_PLL_CTRL0_PLL_EN_MASK (0x01u) +#define SCG0_PLL_CTRL0_PLL_EN_SHIFT (0u) +#define SCG0_PLL_CTRL0_PLL_EN_WIDTH (1u) + +/* PLL_CTRL1 Bit Fields */ +#define SCG0_PLL_CTRL1_PLL_CLKIN_SEL_MASK (0x10u) +#define SCG0_PLL_CTRL1_PLL_CLKIN_SEL_SHIFT (4u) +#define SCG0_PLL_CTRL1_PLL_CLKIN_SEL_WIDTH (1u) + +/* STATUS Bit Fields */ +#define SCG0_STATUS_SCG0_LOCK_MASK (0x08u) +#define SCG0_STATUS_SCG0_LOCK_SHIFT (3u) +#define SCG0_STATUS_SCG0_LOCK_WIDTH (1u) +#define SCG0_STATUS_SOSC_RDY_MASK (0x04u) +#define SCG0_STATUS_SOSC_RDY_SHIFT (2u) +#define SCG0_STATUS_SOSC_RDY_WIDTH (1u) +#define SCG0_STATUS_SIRC_8M_RDY_MASK (0x02u) +#define SCG0_STATUS_SIRC_8M_RDY_SHIFT (1u) +#define SCG0_STATUS_SIRC_8M_RDY_WIDTH (1u) +#define SCG0_STATUS_PLL_LOCK_MASK (0x01u) +#define SCG0_STATUS_PLL_LOCK_SHIFT (0u) +#define SCG0_STATUS_PLL_LOCK_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of SCG0 registers + */ +typedef struct _Scg0RegType_ +{ + volatile uint32_t TRIM; /*!< Trimming code register, offset: 0x0 */ + uint32_t RESERVED0[2]; /*!< Reserverd block, offset: 0x4 */ + volatile uint32_t OSC_CTRL; /*!< oscillator control register, offset: 0xC */ + uint32_t RESERVED1[1]; /*!< Reserverd block, offset: 0x10 */ + volatile uint32_t PLL_CTRL0; /*!< phase lock loop control0 register, offset: 0x14 */ + volatile uint32_t PLL_CTRL1; /*!< MISC phase lock loop control1 register, offset: 0x18 */ + uint32_t RESERVED2[1]; /*!< Reserverd block, offset: 0x1C */ + volatile uint32_t STATUS; /*!< status register, offset: 0x20 */ + uint32_t RESERVED3[15]; /*!< Reserverd block, offset: 0x24 */ + volatile uint32_t KEY; /*!< key register, offset: 0x60 */ +} Scg0RegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the EEE auto garbage collection enable + * + * This function gets the current EEE auto garbage collection enable. + * + * \param[in] obj : pointer to SCG0 register instance + * \return EEE auto garbage collection enable + * - 1 : enable auto eee garbage collection; + * - 0 : disable auto eee garbage collection; + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetTrimAutoGcEn(const Scg0RegType *obj) +{ + return ((obj->TRIM & SCG0_TRIM_AUTO_GC_EN_MASK) >> SCG0_TRIM_AUTO_GC_EN_SHIFT); +} + +/*! \brief Sets the EEE auto garbage collection enable + * + * This function sets the EEE auto garbage collection enable. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of EEE auto garbage collection enable + * - 1 : enable auto eee garbage collection; + * - 0 : disable auto eee garbage collection; + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetTrimAutoGcEn(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->TRIM; + + tmp &= ~SCG0_TRIM_AUTO_GC_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_TRIM_AUTO_GC_EN_SHIFT)) & SCG0_TRIM_AUTO_GC_EN_MASK); + obj->TRIM = tmp; +} + +/*! \brief Gets the External clock input through XIN pin enable + * + * This function gets the current External clock input through XIN pin enable. + * Enable external clock input through XIN pin. When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \return External clock input through XIN pin enable + * - 0b : disable. + * - 1b : enable. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetOscCtrlEnExtClk(const Scg0RegType *obj) +{ + return ((obj->OSC_CTRL & SCG0_OSC_CTRL_EN_EXT_CLK_MASK) >> SCG0_OSC_CTRL_EN_EXT_CLK_SHIFT); +} + +/*! \brief Sets the External clock input through XIN pin enable + * + * This function sets the External clock input through XIN pin enable. + * Enable external clock input through XIN pin. When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of External clock input through XIN pin enable + * - 0b : disable. + * - 1b : enable. + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetOscCtrlEnExtClk(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OSC_CTRL; + + tmp &= ~SCG0_OSC_CTRL_EN_EXT_CLK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_OSC_CTRL_EN_EXT_CLK_SHIFT)) & SCG0_OSC_CTRL_EN_EXT_CLK_MASK); + obj->OSC_CTRL = tmp; +} + +/*! \brief Gets the SOSC frequency range + * + * This function gets the current SOSC frequency range. + * SOSC frequency range select, When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \return SOSC frequency range + * - 00b : Low frequency range selected for the crystal oscillator(4M); + * - 01b : Medium frequency range selected for the crytstal oscillator(4M~8M) + * - 10b : Medium frequency range selected for the crytstal oscillator(8M~24M) + * - 11b : High frequency range selected for the crystal oscillator(24M~40M) + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetOscCtrlRange(const Scg0RegType *obj) +{ + return ((obj->OSC_CTRL & SCG0_OSC_CTRL_RANGE_MASK) >> SCG0_OSC_CTRL_RANGE_SHIFT); +} + +/*! \brief Sets the SOSC frequency range + * + * This function sets the SOSC frequency range. + * SOSC frequency range select, When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of SOSC frequency range + * - 00b : Low frequency range selected for the crystal oscillator(4M); + * - 01b : Medium frequency range selected for the crytstal oscillator(4M~8M) + * - 10b : Medium frequency range selected for the crytstal oscillator(8M~24M) + * - 11b : High frequency range selected for the crystal oscillator(24M~40M) + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetOscCtrlRange(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OSC_CTRL; + + tmp &= ~SCG0_OSC_CTRL_RANGE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_OSC_CTRL_RANGE_SHIFT)) & SCG0_OSC_CTRL_RANGE_MASK); + obj->OSC_CTRL = tmp; +} + +/*! \brief Gets the High gain oscillator + * + * This function gets the current High gain oscillator. + * High gain oscillator control, When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \return High gain oscillator + * - 0b : Low power mode for SOSC(OSC output amplitude limited) + * - 1b : High gain mode for SOSC. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetOscCtrlHgo(const Scg0RegType *obj) +{ + return ((obj->OSC_CTRL & SCG0_OSC_CTRL_HGO_MASK) >> SCG0_OSC_CTRL_HGO_SHIFT); +} + +/*! \brief Sets the High gain oscillator + * + * This function sets the High gain oscillator. + * High gain oscillator control, When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of High gain oscillator + * - 0b : Low power mode for SOSC(OSC output amplitude limited) + * - 1b : High gain mode for SOSC. + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetOscCtrlHgo(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OSC_CTRL; + + tmp &= ~SCG0_OSC_CTRL_HGO_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_OSC_CTRL_HGO_SHIFT)) & SCG0_OSC_CTRL_HGO_MASK); + obj->OSC_CTRL = tmp; +} + +/*! \brief Gets the System oscillator (crystal osc) enable + * + * This function gets the current System oscillator (crystal osc) enable. + * System oscillator (crystal osc) enable control, When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \return System oscillator (crystal osc) enable + * - 0b : SOSC disable. + * - 1b : SOSC enable. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetOscCtrlEnSosc(const Scg0RegType *obj) +{ + return ((obj->OSC_CTRL & SCG0_OSC_CTRL_EN_SOSC_MASK) >> SCG0_OSC_CTRL_EN_SOSC_SHIFT); +} + +/*! \brief Sets the System oscillator (crystal osc) enable + * + * This function sets the System oscillator (crystal osc) enable. + * System oscillator (crystal osc) enable control, When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of System oscillator (crystal osc) enable + * - 0b : SOSC disable. + * - 1b : SOSC enable. + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetOscCtrlEnSosc(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->OSC_CTRL; + + tmp &= ~SCG0_OSC_CTRL_EN_SOSC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_OSC_CTRL_EN_SOSC_SHIFT)) & SCG0_OSC_CTRL_EN_SOSC_MASK); + obj->OSC_CTRL = tmp; +} + +/*! \brief Gets the PLL ICO DIV2 Setting + * + * This function gets the current PLL ICO DIV2 Setting. + * 1 stand for div2, When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \return PLL ICO DIV2 Setting + * - 0b : not divider. + * - 1b : divider 2. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetPllCtrl0PllVcoDiv(const Scg0RegType *obj) +{ + return ((obj->PLL_CTRL0 & SCG0_PLL_CTRL0_PLL_VCO_DIV_MASK) >> SCG0_PLL_CTRL0_PLL_VCO_DIV_SHIFT); +} + +/*! \brief Sets the PLL ICO DIV2 Setting + * + * This function sets the PLL ICO DIV2 Setting. + * 1 stand for div2, When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of PLL ICO DIV2 Setting + * - 0b : not divider. + * - 1b : divider 2. + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetPllCtrl0PllVcoDiv(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_CTRL0; + + tmp &= ~SCG0_PLL_CTRL0_PLL_VCO_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_PLL_CTRL0_PLL_VCO_DIV_SHIFT)) & SCG0_PLL_CTRL0_PLL_VCO_DIV_MASK); + obj->PLL_CTRL0 = tmp; +} + +/*! \brief Gets the PLL post-divide + * + * This function gets the current PLL post-divide. + * When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \return PLL post-divide + * - 000b : 8 + * - 001b : 1 + * - 010b : 2 + * - 011b : 3 + * . + * . + * . + * - 111b : 7 + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetPllCtrl0PllPosDiv(const Scg0RegType *obj) +{ + return ((obj->PLL_CTRL0 & SCG0_PLL_CTRL0_PLL_POSDIV_MASK) >> SCG0_PLL_CTRL0_PLL_POSDIV_SHIFT); +} + +/*! \brief Sets the PLL post-divide + * + * This function sets the PLL post-divide. + * When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of PLL post-divide + * - 000b : 8 + * - 001b : 1 + * - 010b : 2 + * - 011b : 3 + * . + * . + * . + * - 111b : 7 + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetPllCtrl0PllPosDiv(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_CTRL0; + + tmp &= ~SCG0_PLL_CTRL0_PLL_POSDIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_PLL_CTRL0_PLL_POSDIV_SHIFT)) & SCG0_PLL_CTRL0_PLL_POSDIV_MASK); + obj->PLL_CTRL0 = tmp; +} + +/*! \brief Gets the PLL Feedback clock divider pre-scaler + * + * This function gets the current PLL Feedback clock divider pre-scaler. + * When write-lock disabled, this register can be written. + * + * \param[in] obj : pointer to SCG0 register instance + * \return PLL Feedback clock divider pre-scaler + * - 0b : 1. + * - 1b : 2. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetPllCtrl0PllFdkSel(const Scg0RegType *obj) +{ + return ((obj->PLL_CTRL0 & SCG0_PLL_CTRL0_PLL_FDKSEL_MASK) >> SCG0_PLL_CTRL0_PLL_FDKSEL_SHIFT); +} + +/*! \brief Sets the PLL Feedback clock divider pre-scaler + * + * This function sets the PLL Feedback clock divider pre-scaler. + * When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of PLL Feedback clock divider pre-scaler + * - 0b : 1. + * - 1b : 2. + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetPllCtrl0PllFdkSel(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_CTRL0; + + tmp &= ~SCG0_PLL_CTRL0_PLL_FDKSEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_PLL_CTRL0_PLL_FDKSEL_SHIFT)) & SCG0_PLL_CTRL0_PLL_FDKSEL_MASK); + obj->PLL_CTRL0 = tmp; +} + +/*! \brief Gets the PLL pre-divider setting + * + * This function gets the current PLL pre-divider setting. + * When write-lock disabled, this register can be written. + * + * \param[in] obj : pointer to SCG0 register instance + * \return PLL pre-divider setting + * - 00b : 1. + * - 01b : 2. + * - 10b : 4. + * - 11b : 8. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetPllCtrl0PllPreDiv(const Scg0RegType *obj) +{ + return ((obj->PLL_CTRL0 & SCG0_PLL_CTRL0_PLL_PREDIV_MASK) >> SCG0_PLL_CTRL0_PLL_PREDIV_SHIFT); +} + +/*! \brief Sets the PLL pre-divider setting + * + * This function sets the PLL pre-divider setting. + * When write-lock disabled, this register can be written. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of PLL pre-divider setting + * - 00b : 1. + * - 01b : 2. + * - 10b : 4. + * - 11b : 8. + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetPllCtrl0PllPreDiv(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_CTRL0; + + tmp &= ~SCG0_PLL_CTRL0_PLL_PREDIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_PLL_CTRL0_PLL_PREDIV_SHIFT)) & SCG0_PLL_CTRL0_PLL_PREDIV_MASK); + obj->PLL_CTRL0 = tmp; +} + +/*! \brief Gets the PLL feedback divider setting + * + * This function gets the current PLL feedback divider setting. + * When write-lock disabled, this register can be written. + * + * \param[in] obj : pointer to SCG0 register instance + * \return PLL feedback divider setting + * - 0000001b : 1. + * - 0000010b : 2. + * . + * . + * . + * - 1111111b : 127. + * - 0000000b : 128. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetPllCtrl0PllM(const Scg0RegType *obj) +{ + return ((obj->PLL_CTRL0 & SCG0_PLL_CTRL0_PLL_M_MASK) >> SCG0_PLL_CTRL0_PLL_M_SHIFT); +} + +/*! \brief Sets the PLL feedback divider setting + * + * This function sets the PLL feedback divider setting. + * When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of PLL feedback divider setting + * - 0000001b : 1. + * - 0000010b : 2. + * . + * . + * . + * - 1111111b : 127. + * - 0000000b : 128. + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetPllCtrl0PllM(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_CTRL0; + + tmp &= ~SCG0_PLL_CTRL0_PLL_M_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_PLL_CTRL0_PLL_M_SHIFT)) & SCG0_PLL_CTRL0_PLL_M_MASK); + obj->PLL_CTRL0 = tmp; +} + +/*! \brief Gets the PLL enable + * + * This function gets the current PLL enable. + * When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \return PLL enable + * - 0 : disable. + * - 1 : enable. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetPllCtrl0PllEn(const Scg0RegType *obj) +{ + return ((obj->PLL_CTRL0 & SCG0_PLL_CTRL0_PLL_EN_MASK) >> SCG0_PLL_CTRL0_PLL_EN_SHIFT); +} + +/*! \brief Sets the PLL enable + * + * This function sets the PLL enable. + * When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of PLL enable + * - 0 : disable. + * - 1 : enable. + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetPllCtrl0PllEn(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_CTRL0; + + tmp &= ~SCG0_PLL_CTRL0_PLL_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_PLL_CTRL0_PLL_EN_SHIFT)) & SCG0_PLL_CTRL0_PLL_EN_MASK); + obj->PLL_CTRL0 = tmp; +} + +/*! \brief Gets the PLL input clock source select + * + * This function gets the current PLL input clock source select. + * When write-lock disabled, this register can be written.. + * + * \param[in] obj : pointer to SCG0 register instance + * \return PLL input clock source select + * - 0 : SIRC. + * - 1 : SOSC. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetPllCtrl1PllClkinSel(const Scg0RegType *obj) +{ + return ((obj->PLL_CTRL1 & SCG0_PLL_CTRL1_PLL_CLKIN_SEL_MASK) >> SCG0_PLL_CTRL1_PLL_CLKIN_SEL_SHIFT); +} + +/*! \brief Sets the PLL input clock source select + * + * This function sets the PLL input clock source select. + * When write-lock disabled, this register can be written. + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of PLL input clock source select + * - 0 : SIRC. + * - 1 : SOSC. + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetPllCtrl1PllClkinSel(Scg0RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_CTRL1; + + tmp &= ~SCG0_PLL_CTRL1_PLL_CLKIN_SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG0_PLL_CTRL1_PLL_CLKIN_SEL_SHIFT)) & SCG0_PLL_CTRL1_PLL_CLKIN_SEL_MASK); + obj->PLL_CTRL1 = tmp; +} + +/*! \brief Gets the scg0 lock enable status + * + * This function gets the current scg0 lock enable status. + * + * \param[in] obj : pointer to SCG0 register instance + * \return scg0 lock enable status + * - 0b : disalbe. + * - 1b : enable. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetStatusKeyLock(const Scg0RegType *obj) +{ + return ((obj->STATUS & SCG0_STATUS_SCG0_LOCK_MASK) >> SCG0_STATUS_SCG0_LOCK_SHIFT); +} + +/*! \brief Gets the Sytem oscillator clock ready flag + * + * This function gets the current Sytem oscillator clock ready flag. + * if use external, this flag is not used + * + * \param[in] obj : pointer to SCG0 register instance + * \return Sytem oscillator clock ready flag + * - 1b : SOSC ready. + * - 0b : SOSC not ready. + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetStatusSoscRdy(const Scg0RegType *obj) +{ + return ((obj->STATUS & SCG0_STATUS_SOSC_RDY_MASK) >> SCG0_STATUS_SOSC_RDY_SHIFT); +} + +/*! \brief Gets the SIRC clock ready flag + * + * This function gets the current SIRC clock ready flag. + * + * \param[in] obj : pointer to SCG0 register instance + * \return SIRC clock ready flag + * - 1b : ready; + * - 0b : not ready + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetStatusSircRdy(const Scg0RegType *obj) +{ + return ((obj->STATUS & SCG0_STATUS_SIRC_8M_RDY_MASK) >> SCG0_STATUS_SIRC_8M_RDY_SHIFT); +} + +/*! \brief Gets the PLL lock state + * + * This function gets the current PLL lock state. + * + * \param[in] obj : pointer to SCG0 register instance + * \return PLL lock state + * - 1b : Lock state; + * - 0b : Not lock state + */ +__attribute__((always_inline)) static inline uint8_t Scg0Reg_GetStatusPllLock(const Scg0RegType *obj) +{ + return ((obj->STATUS & SCG0_STATUS_PLL_LOCK_MASK) >> SCG0_STATUS_PLL_LOCK_SHIFT); +} + +/*! \brief Sets the SCG0 public write key register + * + * This function sets the SCG0 public write key register. + * SCG0 public write hit key, the initial confirm key is 0x1996_2020, + * when cpu write data is 0x19962020. SCG0 function lock is invalid, + * CPU can write the SCG0 function register. + * When cpu write data is not equal 0x1996_2020, SCG0 function lock is valid, + * CPU can not write the SCG0 function register + * + * \param[in] obj : pointer to SCG0 register instance + * \param[in] value : the value of SCG0 public write key register + */ +__attribute__((always_inline)) static inline void Scg0Reg_SetKey(Scg0RegType *obj, uint32_t value) +{ + obj->KEY = value; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _SCG0_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/scg1_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/scg1_reg.h new file mode 100644 index 0000000..7cc3e78 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/scg1_reg.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _SCG1_REG_H_ +#define _SCG1_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the SCG1 Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* CKSRC Bit Fields */ +#define SCG1_CKSRC_SYS_DIV_MASK (0x0Fu) +#define SCG1_CKSRC_SYS_DIV_SHIFT (0u) +#define SCG1_CKSRC_SYS_DIV_WIDTH (4u) + +/* CPU_MODE Bit Fields */ +#define SCG1_CPU_MODE_RET_MASK (0x01u) +#define SCG1_CPU_MODE_RET_SHIFT (0u) +#define SCG1_CPU_MODE_RET_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of SCG1 registers + */ +typedef struct _Scg1RegType_ +{ + volatile uint32_t CKSRC; /*!< clock source selection register, offset: 0x0 */ + volatile uint32_t CPU_MODE; /*!< CPU mode register, offset: 0x4 */ +} Scg1RegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the system clock divide control + * + * This function gets the current system clock divide control. + * rstn_apor domain + * + * \param[in] obj : pointer to SCG1 register instance + * \return system clock divide control + * - 0h : divide by 1 + * - 1h : divide by 2 + * - 2h : divide by 3 + * - 3h : divide by 4 + * . + * . + * . + * - Fh : divide by 16 + */ +__attribute__((always_inline)) static inline uint8_t Scg1Reg_GetCkSrcSysDiv(const Scg1RegType *obj) +{ + return ((obj->CKSRC & SCG1_CKSRC_SYS_DIV_MASK) >> SCG1_CKSRC_SYS_DIV_SHIFT); +} + +/*! \brief Sets the system clock divide control + * + * This function sets the system clock divide control. + * rstn_apor domain + * + * \param[in] obj : pointer to SCG1 register instance + * \param[in] value : the value of system clock divide control + * - 0h : divide by 1 + * - 1h : divide by 2 + * - 2h : divide by 3 + * - 3h : divide by 4 + * . + * . + * . + * - Fh : divide by 16 + */ +__attribute__((always_inline)) static inline void Scg1Reg_SetCkSrcSysDiv(Scg1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CKSRC; + + tmp &= ~SCG1_CKSRC_SYS_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG1_CKSRC_SYS_DIV_SHIFT)) & SCG1_CKSRC_SYS_DIV_MASK); + obj->CKSRC = tmp; +} + +/*! \brief Gets the cpu core work clock selection + * + * This function gets the current cpu core work clock selection. + * rstn_apor domain + * + * \param[in] obj : pointer to SCG1 register instance + * \return cpu core work clock selection + * - 0b : cpu core clock always on, delay cpu reset release; + * - 1b : cpu core clock gate enable, cpu reset early; + */ +__attribute__((always_inline)) static inline uint8_t Scg1Reg_GetCpuModeRet(const Scg1RegType *obj) +{ + return ((obj->CPU_MODE & SCG1_CPU_MODE_RET_MASK) >> SCG1_CPU_MODE_RET_SHIFT); +} + +/*! \brief Sets the cpu core work clock selection + * + * This function sets the cpu core work clock selection. + * rstn_apor domain + * + * \param[in] obj : pointer to SCG1 register instance + * \param[in] value : the value of cpu core work clock selection + * - 0b : cpu core clock always on, delay cpu reset release; + * - 1b : cpu core clock gate enable, cpu reset early; + */ +__attribute__((always_inline)) static inline void Scg1Reg_SetCpuModeRet(Scg1RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CPU_MODE; + + tmp &= ~SCG1_CPU_MODE_RET_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG1_CPU_MODE_RET_SHIFT)) & SCG1_CPU_MODE_RET_MASK); + obj->CPU_MODE = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _SCG1_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/scg2_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/scg2_reg.h new file mode 100644 index 0000000..121077c --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/scg2_reg.h @@ -0,0 +1,880 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _SCG2_REG_H_ +#define _SCG2_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the SCG2 Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* CSR Bit Fields */ +#define SCG2_CSR_SYS_ST_MASK (0x3000000u) +#define SCG2_CSR_SYS_ST_SHIFT (24u) +#define SCG2_CSR_SYS_ST_WIDTH (2u) +#define SCG2_CSR_SRC_SYS_MASK (0x30000u) +#define SCG2_CSR_SRC_SYS_SHIFT (16u) +#define SCG2_CSR_SRC_SYS_WIDTH (2u) +#define SCG2_CSR_DIV_AIPS_MASK (0xF00u) +#define SCG2_CSR_DIV_AIPS_SHIFT (8u) +#define SCG2_CSR_DIV_AIPS_WIDTH (4u) + +/* CLKOUT Bit Fields */ +#define SCG2_CLKOUT_SRC0_MASK (0x380000u) +#define SCG2_CLKOUT_SRC0_SHIFT (19u) +#define SCG2_CLKOUT_SRC0_WIDTH (3u) +#define SCG2_CLKOUT_SRC1_MASK (0x70000u) +#define SCG2_CLKOUT_SRC1_SHIFT (16u) +#define SCG2_CLKOUT_SRC1_WIDTH (3u) +#define SCG2_CLKOUT_DIV_MASK (0x700u) +#define SCG2_CLKOUT_DIV_SHIFT (8u) +#define SCG2_CLKOUT_DIV_WIDTH (3u) +#define SCG2_CLKOUT_EN_MASK (0x10u) +#define SCG2_CLKOUT_EN_SHIFT (4u) +#define SCG2_CLKOUT_EN_WIDTH (1u) + +/* SIRC_MFT Bit Fields */ +#define SCG2_SIRC_MFT_DIV_MASK (0x700u) +#define SCG2_SIRC_MFT_DIV_SHIFT (8u) +#define SCG2_SIRC_MFT_DIV_WIDTH (3u) +#define SCG2_SIRC_MFT_EN_MASK (0x10u) +#define SCG2_SIRC_MFT_EN_SHIFT (4u) +#define SCG2_SIRC_MFT_EN_WIDTH (1u) + +/* SIRC_CFG Bit Fields */ +#define SCG2_SIRC_CFG_DIV_MASK (0x700u) +#define SCG2_SIRC_CFG_DIV_SHIFT (8u) +#define SCG2_SIRC_CFG_DIV_WIDTH (3u) +#define SCG2_SIRC_CFG_EN_MASK (0x10u) +#define SCG2_SIRC_CFG_EN_SHIFT (4u) +#define SCG2_SIRC_CFG_EN_WIDTH (1u) + +/* SOSC_MFT Bit Fields */ +#define SCG2_SOSC_MFT_DIV_MASK (0x700u) +#define SCG2_SOSC_MFT_DIV_SHIFT (8u) +#define SCG2_SOSC_MFT_DIV_WIDTH (3u) +#define SCG2_SOSC_MFT_EN_MASK (0x10u) +#define SCG2_SOSC_MFT_EN_SHIFT (4u) +#define SCG2_SOSC_MFT_EN_WIDTH (1u) + +/* SOSC_CFG Bit Fields */ +#define SCG2_SOSC_CFG_DIV_MASK (0x700u) +#define SCG2_SOSC_CFG_DIV_SHIFT (8u) +#define SCG2_SOSC_CFG_DIV_WIDTH (3u) +#define SCG2_SOSC_CFG_EN_MASK (0x10u) +#define SCG2_SOSC_CFG_EN_SHIFT (4u) +#define SCG2_SOSC_CFG_EN_WIDTH (1u) + +/* PLL_MFT Bit Fields */ +#define SCG2_PLL_MFT_DIV_MASK (0x700u) +#define SCG2_PLL_MFT_DIV_SHIFT (8u) +#define SCG2_PLL_MFT_DIV_WIDTH (3u) +#define SCG2_PLL_MFT_EN_MASK (0x10u) +#define SCG2_PLL_MFT_EN_SHIFT (4u) +#define SCG2_PLL_MFT_EN_WIDTH (1u) + +/* PLL_CFG Bit Fields */ +#define SCG2_PLL_CFG_DIV_MASK (0x700u) +#define SCG2_PLL_CFG_DIV_SHIFT (8u) +#define SCG2_PLL_CFG_DIV_WIDTH (3u) +#define SCG2_PLL_CFG_EN_MASK (0x10u) +#define SCG2_PLL_CFG_EN_SHIFT (4u) +#define SCG2_PLL_CFG_EN_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of SCG2 registers + */ +typedef struct _Scg2RegType_ +{ + volatile uint32_t CSR; /*!< SYSTEM clock config register, offset: 0x0 */ + volatile uint32_t CLKOUT; /*!< system clock out control register, offset: 0x4 */ + uint32_t RESERVED0[2]; /*!< Reserved register, offset: 0x8 */ + volatile uint32_t SIRC_MFT; /*!< SIRC_MFT clock div configuration register, offset: 0x10 */ + volatile uint32_t SIRC_CFG; /*!< SIRC_DIV clock div configuration register, offset: 0x14 */ + volatile uint32_t SOSC_MFT; /*!< SOSC_MFT clock div configuration register, offset: 0x18 */ + volatile uint32_t SOSC_CFG; /*!< SOSC_DIV clock div configuration register, offset: 0x1C */ + volatile uint32_t PLL_MFT; /*!< PLL_MFT clock div configuration register, offset: 0x20 */ + volatile uint32_t PLL_CFG; /*!< PLL clock div configuration register, offset: 0x24 */ +} Scg2RegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the system clock(clk_sys) source status + * + * This function gets the current system clock(clk_sys) source status. + * + * \param[in] obj : pointer to SCG2 register instance + * \return system clock(clk_sys) source status + * - 0h : clk_sirc + * - 1h : clk_sosc + * - 2h : clk_pll + * - 3h : clk_sirc + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetCsrSysSt(const Scg2RegType *obj) +{ + return ((obj->CSR & SCG2_CSR_SYS_ST_MASK) >> SCG2_CSR_SYS_ST_SHIFT); +} + +/*! \brief Gets the System Clock(clk_sys) source select + * + * This function gets the current System Clock(clk_sys) source select. + * + * \param[in] obj : pointer to SCG2 register instance + * \return System Clock(clk_sys) source select + * - 0h : clk_sirc + * - 1h : clk_sosc + * - 2h : clk_pll + * - 3h : clk_sirc + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetCsrSrcSys(const Scg2RegType *obj) +{ + return ((obj->CSR & SCG2_CSR_SRC_SYS_MASK) >> SCG2_CSR_SRC_SYS_SHIFT); +} + +/*! \brief Sets the System Clock(clk_sys) source select + * + * This function sets the System Clock(clk_sys) source select. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of System Clock(clk_sys) source select + * - 0h : clk_sirc + * - 1h : clk_sosc + * - 2h : clk_pll + * - 3h : clk_sirc + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetCsrSrcSys(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CSR; + + tmp &= ~SCG2_CSR_SRC_SYS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_CSR_SRC_SYS_SHIFT)) & SCG2_CSR_SRC_SYS_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the clk_apb(APB bus Clock):Divide Ratio + * + * This function gets the current clk_apb(APB bus Clock):Divide Ratio. + * The source clock is clk_core. + * + * \param[in] obj : pointer to SCG2 register instance + * \return clk_apb(APB bus Clock):Divide Ratio + * - 0000 : Divide-by-1 + * - 0001 : Divide-by-2 + * - 0010 : Divide-by-3 + * - 0011 : Divide-by-4 + * - 0100 : Divide-by-5 + * - 0101 : Divide-by-6 + * - 0110 : Divide-by-7 + * - 0111 : Divide-by-8 + * - 1000 : Divide-by-9 + * - 1001 : Divide-by-10 + * - 1010 : Divide-by-11 + * - 1011 : Divide-by-12 + * - 1100 : Divide-by-13 + * - 1101 : Divide-by-14 + * - 1110 : Divide-by-15 + * - 1111 : Divide-by-16 + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetCsrDivAips(const Scg2RegType *obj) +{ + return ((obj->CSR & SCG2_CSR_DIV_AIPS_MASK) >> SCG2_CSR_DIV_AIPS_SHIFT); +} + +/*! \brief Sets the clk_apb(APB bus Clock):Divide Ratio + * + * This function sets the clk_apb(APB bus Clock):Divide Ratio. + * The source clock is clk_core. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of clk_apb(APB bus Clock):Divide Ratio + * - 0000 : Divide-by-1 + * - 0001 : Divide-by-2 + * - 0010 : Divide-by-3 + * - 0011 : Divide-by-4 + * - 0100 : Divide-by-5 + * - 0101 : Divide-by-6 + * - 0110 : Divide-by-7 + * - 0111 : Divide-by-8 + * - 1000 : Divide-by-9 + * - 1001 : Divide-by-10 + * - 1010 : Divide-by-11 + * - 1011 : Divide-by-12 + * - 1100 : Divide-by-13 + * - 1101 : Divide-by-14 + * - 1110 : Divide-by-15 + * - 1111 : Divide-by-16 + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetCsrDivAips(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CSR; + + tmp &= ~SCG2_CSR_DIV_AIPS_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_CSR_DIV_AIPS_SHIFT)) & SCG2_CSR_DIV_AIPS_MASK); + obj->CSR = tmp; +} + +/*! \brief Gets the scg clock out + * + * This function gets the current scg clock out. + * + * \param[in] obj : pointer to SCG2 register instance + * \return scg clock out + * - 0b : clk_cnt_fls + * - 1b : clk_sosc + * - 2h : clk_sirc + * - 3h : clk_pll + * - 4h : clk_core + * - 5h : clk_apb + * - 6h : clk_sosc_div + * - 7h : clk_sirc_div + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetClkOutSrc0(const Scg2RegType *obj) +{ + return ((obj->CLKOUT & SCG2_CLKOUT_SRC0_MASK) >> SCG2_CLKOUT_SRC0_SHIFT); +} + +/*! \brief Sets the scg clock out + * + * This function sets the scg clock out. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of scg clock out + * - 0b : clk_cnt_fls + * - 1b : clk_sosc + * - 2h : clk_sirc + * - 3h : clk_pll + * - 4h : clk_core + * - 5h : clk_apb + * - 6h : clk_sosc_div + * - 7h : clk_sirc_div + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetClkOutSrc0(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CLKOUT; + + tmp &= ~SCG2_CLKOUT_SRC0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_CLKOUT_SRC0_SHIFT)) & SCG2_CLKOUT_SRC0_MASK); + obj->CLKOUT = tmp; +} + +/*! \brief Gets the clock out(to PAD) source + * + * This function gets the current clock out(to PAD) source. + * + * \param[in] obj : pointer to SCG2 register instance + * \return clock out(to PAD) source + * - 0b : scg_out + * - 1h : clk_pll_div + * - 2h : clk_lpo128 + * - 3h : clk_lpo32 + * - 4h : clk_lpo1 + * - 5h : clk_rtc_cnt + * - 6h : clk_sirc + * - 7h : clk_sirc + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetClkOutSrc1(const Scg2RegType *obj) +{ + return ((obj->CLKOUT & SCG2_CLKOUT_SRC1_MASK) >> SCG2_CLKOUT_SRC1_SHIFT); +} + +/*! \brief Sets the clock out(to PAD) source + * + * This function sets the clock out(to PAD) source. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of clock out(to PAD) source + * - 0b : scg_out + * - 1h : clk_pll_div2 + * - 2h : clk_lpo128 + * - 3h : clk_lpo32 + * - 4h : clk_lpo1 + * - 5h : clk_rtc_cnt + * - 6h : clk_sirc + * - 7h : clk_sirc + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetClkOutSrc1(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CLKOUT; + + tmp &= ~SCG2_CLKOUT_SRC1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_CLKOUT_SRC1_SHIFT)) & SCG2_CLKOUT_SRC1_MASK); + obj->CLKOUT = tmp; +} + +/*! \brief Gets the clock out divide ratio + * + * This function gets the current clock out divide ratio. + * + * \note The max frequency is 24M, so this bit should be configured properly. + * + * \param[in] obj : pointer to SCG2 register instance + * \return clock out divide ratio + * - 0b : 1 + * - 1b : 2 + * - 2h : 3 + * - 3h : 4 + * - 4h : 5 + * - 5h : 6 + * - 6h : 7 + * - 7h : 8 + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetClkOutDiv(const Scg2RegType *obj) +{ + return ((obj->CLKOUT & SCG2_CLKOUT_DIV_MASK) >> SCG2_CLKOUT_DIV_SHIFT); +} + +/*! \brief Sets the clock out divide ratio + * + * This function sets the clock out divide ratio. + * + * \note The max frequency is 24M, so this bit should be configured properly. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of clock out divide ratio + * - 0b : 1 + * - 1b : 2 + * - 2h : 3 + * - 3h : 4 + * - 4h : 5 + * - 5h : 6 + * - 6h : 7 + * - 7h : 8 + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetClkOutDiv(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CLKOUT; + + tmp &= ~SCG2_CLKOUT_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_CLKOUT_DIV_SHIFT)) & SCG2_CLKOUT_DIV_MASK); + obj->CLKOUT = tmp; +} + +/*! \brief Gets the clock out enable + * + * This function gets the current clock out enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \return clock out enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetClkOutEn(const Scg2RegType *obj) +{ + return ((obj->CLKOUT & SCG2_CLKOUT_EN_MASK) >> SCG2_CLKOUT_EN_SHIFT); +} + +/*! \brief Sets the clock out enable + * + * This function sets the clock out enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of clock out enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetClkOutEn(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CLKOUT; + + tmp &= ~SCG2_CLKOUT_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_CLKOUT_EN_SHIFT)) & SCG2_CLKOUT_EN_MASK); + obj->CLKOUT = tmp; +} + +/*! \brief Gets the SIRC_DIV_MFT clock diviation + * + * This function gets the current SIRC_DIV_MFT clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \return SIRC_DIV_MFT clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : / + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetSircMftDiv(const Scg2RegType *obj) +{ + return ((obj->SIRC_MFT & SCG2_SIRC_MFT_DIV_MASK) >> SCG2_SIRC_MFT_DIV_SHIFT); +} + +/*! \brief Sets the SIRC_DIV_MFT clock diviation + * + * This function sets the SIRC_DIV_MFT clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of SIRC_DIV_MFT clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : / + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetSircMftDiv(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SIRC_MFT; + + tmp &= ~SCG2_SIRC_MFT_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_SIRC_MFT_DIV_SHIFT)) & SCG2_SIRC_MFT_DIV_MASK); + obj->SIRC_MFT = tmp; +} + +/*! \brief Gets the clk_sirc_div_mft clock enable + * + * This function gets the current clk_sirc_div_mft clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \return clk_sirc_div_mft clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetSircMftEn(const Scg2RegType *obj) +{ + return ((obj->SIRC_MFT & SCG2_SIRC_MFT_EN_MASK) >> SCG2_SIRC_MFT_EN_SHIFT); +} + +/*! \brief Sets the clk_sirc_div_mft clock enable + * + * This function sets the clk_sirc_div_mft clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of clk_sirc_div_mft clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetSircMftEn(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SIRC_MFT; + + tmp &= ~SCG2_SIRC_MFT_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_SIRC_MFT_EN_SHIFT)) & SCG2_SIRC_MFT_EN_MASK); + obj->SIRC_MFT = tmp; +} + +/*! \brief Gets the SIRC_DIV clock diviation + * + * This function gets the current SIRC_DIV clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \return SIRC_DIV clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : / + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetSircCfgDiv(const Scg2RegType *obj) +{ + return ((obj->SIRC_CFG & SCG2_SIRC_CFG_DIV_MASK) >> SCG2_SIRC_CFG_DIV_SHIFT); +} + +/*! \brief Sets the SIRC_DIV clock diviation + * + * This function sets the SIRC_DIV clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of SIRC_DIV clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : / + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetSircCfgDiv(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SIRC_CFG; + + tmp &= ~SCG2_SIRC_CFG_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_SIRC_CFG_DIV_SHIFT)) & SCG2_SIRC_CFG_DIV_MASK); + obj->SIRC_CFG = tmp; +} + +/*! \brief Gets the clk_sirc_div clock enable + * + * This function gets the current clk_sirc_div clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \return clk_sirc_div clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetSircCfgEn(const Scg2RegType *obj) +{ + return ((obj->SIRC_CFG & SCG2_SIRC_CFG_EN_MASK) >> SCG2_SIRC_CFG_EN_SHIFT); +} + +/*! \brief Sets the clk_sirc_div clock enable + * + * This function sets the clk_sirc_div clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of clk_sirc_div clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetSircCfgEn(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SIRC_CFG; + + tmp &= ~SCG2_SIRC_CFG_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_SIRC_CFG_EN_SHIFT)) & SCG2_SIRC_CFG_EN_MASK); + obj->SIRC_CFG = tmp; +} + +/*! \brief Gets the SOSC_DIV_MFT clock diviation + * + * This function gets the current SOSC_DIV_MFT clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \return SOSC_DIV_MFT clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : / + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetSoscMftDiv(const Scg2RegType *obj) +{ + return ((obj->SOSC_MFT & SCG2_SOSC_MFT_DIV_MASK) >> SCG2_SOSC_MFT_DIV_SHIFT); +} + +/*! \brief Sets the SOSC_DIV_MFT clock diviation + * + * This function sets the SOSC_DIV_MFT clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of SOSC_DIV_MFT clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : / + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetSoscMftDiv(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SOSC_MFT; + + tmp &= ~SCG2_SOSC_MFT_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_SOSC_MFT_DIV_SHIFT)) & SCG2_SOSC_MFT_DIV_MASK); + obj->SOSC_MFT = tmp; +} + +/*! \brief Gets the clk_sosc_div_mft clock enable + * + * This function gets the current clk_sosc_div_mft clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \return clk_sosc_div_mft clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetSoscMftEn(const Scg2RegType *obj) +{ + return ((obj->SOSC_MFT & SCG2_SOSC_MFT_EN_MASK) >> SCG2_SOSC_MFT_EN_SHIFT); +} + +/*! \brief Sets the clk_sosc_div_mft clock enable + * + * This function sets the clk_sosc_div_mft clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of clk_sosc_div_mft clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetSoscMftEn(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SOSC_MFT; + + tmp &= ~SCG2_SOSC_MFT_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_SOSC_MFT_EN_SHIFT)) & SCG2_SOSC_MFT_EN_MASK); + obj->SOSC_MFT = tmp; +} + +/*! \brief Gets the SOSC_DIV clock diviation + * + * This function gets the current SOSC_DIV clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \return SOSC_DIV clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : / + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetSoscCfgDiv(const Scg2RegType *obj) +{ + return ((obj->SOSC_CFG & SCG2_SOSC_CFG_DIV_MASK) >> SCG2_SOSC_CFG_DIV_SHIFT); +} + +/*! \brief Sets the SOSC_DIV clock diviation + * + * This function sets the SOSC_DIV clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of SOSC_DIV clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : / + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetSoscCfgDiv(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SOSC_CFG; + + tmp &= ~SCG2_SOSC_CFG_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_SOSC_CFG_DIV_SHIFT)) & SCG2_SOSC_CFG_DIV_MASK); + obj->SOSC_CFG = tmp; +} + +/*! \brief Gets the clk_sosc_div clock enable + * + * This function gets the current clk_sosc_div clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \return clk_sosc_div clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetSoscCfgEn(const Scg2RegType *obj) +{ + return ((obj->SOSC_CFG & SCG2_SOSC_CFG_EN_MASK) >> SCG2_SOSC_CFG_EN_SHIFT); +} + +/*! \brief Sets the clk_sosc_div clock enable + * + * This function sets the clk_sosc_div clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of clk_sosc_div clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetSoscCfgEn(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SOSC_CFG; + + tmp &= ~SCG2_SOSC_CFG_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_SOSC_CFG_EN_SHIFT)) & SCG2_SOSC_CFG_EN_MASK); + obj->SOSC_CFG = tmp; +} + +/*! \brief Gets the PLL_DIV_MFT clock diviation + * + * This function gets the current PLL_DIV_MFT clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \return PLL_DIV_MFT clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : /(128) + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetPllMftDiv(const Scg2RegType *obj) +{ + return ((obj->PLL_MFT & SCG2_PLL_MFT_DIV_MASK) >> SCG2_PLL_MFT_DIV_SHIFT); +} + +/*! \brief Sets the PLL_DIV_MFT clock diviation + * + * This function sets the PLL_DIV_MFT clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of PLL_DIV_MFT clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : /(128) + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetPllMftDiv(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_MFT; + + tmp &= ~SCG2_PLL_MFT_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_PLL_MFT_DIV_SHIFT)) & SCG2_PLL_MFT_DIV_MASK); + obj->PLL_MFT = tmp; +} + +/*! \brief Gets the clk_pll_div_mft clock enable + * + * This function gets the current clk_pll_div_mft clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \return clk_pll_div_mft clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetPllMftEn(const Scg2RegType *obj) +{ + return ((obj->PLL_MFT & SCG2_PLL_MFT_EN_MASK) >> SCG2_PLL_MFT_EN_SHIFT); +} + +/*! \brief Sets the clk_pll_div_mft clock enable + * + * This function sets the clk_pll_div_mft clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of clk_pll_div_mft clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetPllMftEn(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_MFT; + + tmp &= ~SCG2_PLL_MFT_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_PLL_MFT_EN_SHIFT)) & SCG2_PLL_MFT_EN_MASK); + obj->PLL_MFT = tmp; +} + +/*! \brief Gets the PLL_DIV clock diviation + * + * This function gets the current PLL_DIV clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \return PLL_DIV clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : /(128) + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetPllCfgDiv(const Scg2RegType *obj) +{ + return ((obj->PLL_CFG & SCG2_PLL_CFG_DIV_MASK) >> SCG2_PLL_CFG_DIV_SHIFT); +} + +/*! \brief Sets the PLL_DIV clock diviation + * + * This function sets the PLL_DIV clock diviation. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of PLL_DIV clock diviation + * - 0b : Divide by 1 + * - 1b : Divide by 2 + * - 2h : Divide by 4 + * - 3h : Divide by 8 + * - 4h : Divide by 16 + * - 5h : Divide by 32 + * - 6h : Divide by 64 + * - 7h : /(128) + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetPllCfgDiv(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_CFG; + + tmp &= ~SCG2_PLL_CFG_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_PLL_CFG_DIV_SHIFT)) & SCG2_PLL_CFG_DIV_MASK); + obj->PLL_CFG = tmp; +} + +/*! \brief Gets the clk_pll_div clock enable + * + * This function gets the current clk_pll_div clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \return clk_pll_div clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline uint8_t Scg2Reg_GetPllCfgEn(const Scg2RegType *obj) +{ + return ((obj->PLL_CFG & SCG2_PLL_CFG_EN_MASK) >> SCG2_PLL_CFG_EN_SHIFT); +} + +/*! \brief Sets the clk_pll_div clock enable + * + * This function sets the clk_pll_div clock enable. + * + * \param[in] obj : pointer to SCG2 register instance + * \param[in] value : the value of clk_pll_div clock enable + * - 0b : disable + * - 1b : enable + */ +__attribute__((always_inline)) static inline void Scg2Reg_SetPllCfgEn(Scg2RegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PLL_CFG; + + tmp &= ~SCG2_PLL_CFG_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SCG2_PLL_CFG_EN_SHIFT)) & SCG2_PLL_CFG_EN_MASK); + obj->PLL_CFG = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _SCG2_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/sim_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/sim_reg.h new file mode 100644 index 0000000..1e099ee --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/sim_reg.h @@ -0,0 +1,1410 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _SIM_REG_H_ +#define _SIM_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the SIM (System Integration Module) Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* CHIP Bit Fields */ +#define SIM_CHIP_SRAM_INIT_ST_MASK (0x20u) +#define SIM_CHIP_SRAM_INIT_ST_SHIFT (5u) +#define SIM_CHIP_SRAM_INIT_ST_WIDTH (1u) +#define SIM_CHIP_SRAM_INIT_MASK (0x08u) +#define SIM_CHIP_SRAM_INIT_SHIFT (3u) +#define SIM_CHIP_SRAM_INIT_WIDTH (1u) +#define SIM_CHIP_SRAM_RETEN_MASK (0x02u) +#define SIM_CHIP_SRAM_RETEN_SHIFT (1u) +#define SIM_CHIP_SRAM_RETEN_WIDTH (1u) + +/* PWM_CTRL0 Bit Fields */ +#define SIM_PWM_CTRL0_PWM_FUNC3_MASK (0xF000000u) +#define SIM_PWM_CTRL0_PWM_FUNC3_SHIFT (24u) +#define SIM_PWM_CTRL0_PWM_FUNC3_WIDTH (4u) +#define SIM_PWM_CTRL0_PWM_FUNC2_MASK (0xF0000u) +#define SIM_PWM_CTRL0_PWM_FUNC2_SHIFT (16u) +#define SIM_PWM_CTRL0_PWM_FUNC2_WIDTH (4u) +#define SIM_PWM_CTRL0_PWM_FUNC1_MASK (0xF00u) +#define SIM_PWM_CTRL0_PWM_FUNC1_SHIFT (8u) +#define SIM_PWM_CTRL0_PWM_FUNC1_WIDTH (4u) +#define SIM_PWM_CTRL0_PWM_FUNC0_MASK (0x0Fu) +#define SIM_PWM_CTRL0_PWM_FUNC0_SHIFT (0u) +#define SIM_PWM_CTRL0_PWM_FUNC0_WIDTH (4u) + +/* PWM_CTRL1 Bit Fields */ +#define SIM_PWM_CTRL1_PWM_FUNC5_MASK (0xF00u) +#define SIM_PWM_CTRL1_PWM_FUNC5_SHIFT (8u) +#define SIM_PWM_CTRL1_PWM_FUNC5_WIDTH (4u) +#define SIM_PWM_CTRL1_PWM_FUNC4_MASK (0x0Fu) +#define SIM_PWM_CTRL1_PWM_FUNC4_SHIFT (0u) +#define SIM_PWM_CTRL1_PWM_FUNC4_WIDTH (4u) + +/* ADC Bit Fields */ +#define SIM_ADC_TRG_SRC_MASK (0x20u) +#define SIM_ADC_TRG_SRC_SHIFT (5u) +#define SIM_ADC_TRG_SRC_WIDTH (1u) +#define SIM_ADC_PRETRG_SW_SRC_MASK (0x1Cu) +#define SIM_ADC_PRETRG_SW_SRC_SHIFT (2u) +#define SIM_ADC_PRETRG_SW_SRC_WIDTH (3u) +#define SIM_ADC_PRETRG_SRC_MASK (0x03u) +#define SIM_ADC_PRETRG_SRC_SHIFT (0u) +#define SIM_ADC_PRETRG_SRC_WIDTH (2u) + +/* I2S Bit Fields */ +#define SIM_I2S_SLV_DMA_IRQ_MASK (0x04u) +#define SIM_I2S_SLV_DMA_IRQ_SHIFT (2u) +#define SIM_I2S_SLV_DMA_IRQ_WIDTH (1u) +#define SIM_I2S_MST_DMA_IRQ_MASK (0x02u) +#define SIM_I2S_MST_DMA_IRQ_SHIFT (1u) +#define SIM_I2S_MST_DMA_IRQ_WIDTH (1u) +#define SIM_I2S_MODE_MASK (0x01u) +#define SIM_I2S_MODE_SHIFT (0u) +#define SIM_I2S_MODE_WIDTH (1u) + +/* MFT_CTRL0 Bit Fields */ +#define SIM_MFT_CTRL0_MFT1_FLT_SEL_MASK (0x700000u) +#define SIM_MFT_CTRL0_MFT1_FLT_SEL_SHIFT (20u) +#define SIM_MFT_CTRL0_MFT1_FLT_SEL_WIDTH (3u) +#define SIM_MFT_CTRL0_MFT0_FLT_SEL_MASK (0x70000u) +#define SIM_MFT_CTRL0_MFT0_FLT_SEL_SHIFT (16u) +#define SIM_MFT_CTRL0_MFT0_FLT_SEL_WIDTH (3u) +#define SIM_MFT_CTRL0_GLDOK_MASK (0x01u) +#define SIM_MFT_CTRL0_GLDOK_SHIFT (0u) +#define SIM_MFT_CTRL0_GLDOK_WIDTH (1u) + +/* MFT_CTRL1 Bit Fields */ +#define SIM_MFT_CTRL1_MFT1SYNCBIT_MASK (0x2000000u) +#define SIM_MFT_CTRL1_MFT1SYNCBIT_SHIFT (25u) +#define SIM_MFT_CTRL1_MFT1SYNCBIT_WIDTH (1u) +#define SIM_MFT_CTRL1_MFT0SYNCBIT_MASK (0x1000000u) +#define SIM_MFT_CTRL1_MFT0SYNCBIT_SHIFT (24u) +#define SIM_MFT_CTRL1_MFT0SYNCBIT_WIDTH (1u) +#define SIM_MFT_CTRL1_MFT1CH0SEL_MASK (0x80000u) +#define SIM_MFT_CTRL1_MFT1CH0SEL_SHIFT (19u) +#define SIM_MFT_CTRL1_MFT1CH0SEL_WIDTH (1u) +#define SIM_MFT_CTRL1_MFT0_OUTSEL_MASK (0xFF00u) +#define SIM_MFT_CTRL1_MFT0_OUTSEL_SHIFT (8u) +#define SIM_MFT_CTRL1_MFT0_OUTSEL_WIDTH (8u) + +/* FLASH Bit Fields */ +#define SIM_FLASH_EEERST_MASK (0x800u) +#define SIM_FLASH_EEERST_SHIFT (11u) +#define SIM_FLASH_EEERST_WIDTH (1u) +#define SIM_FLASH_EEEVLD_MASK (0x400u) +#define SIM_FLASH_EEEVLD_SHIFT (10u) +#define SIM_FLASH_EEEVLD_WIDTH (1u) +#define SIM_FLASH_LOAD_DONE_MASK (0x200u) +#define SIM_FLASH_LOAD_DONE_SHIFT (9u) +#define SIM_FLASH_LOAD_DONE_WIDTH (1u) +#define SIM_FLASH_VIRGIN_FLAG_MASK (0x100u) +#define SIM_FLASH_VIRGIN_FLAG_SHIFT (8u) +#define SIM_FLASH_VIRGIN_FLAG_WIDTH (1u) +#define SIM_FLASH_DFLS_FLUSH_EN_MASK (0x08u) +#define SIM_FLASH_DFLS_FLUSH_EN_SHIFT (3u) +#define SIM_FLASH_DFLS_FLUSH_EN_WIDTH (1u) +#define SIM_FLASH_PFLS_FLUSH_EN_MASK (0x04u) +#define SIM_FLASH_PFLS_FLUSH_EN_SHIFT (2u) +#define SIM_FLASH_PFLS_FLUSH_EN_WIDTH (1u) +#define SIM_FLASH_DFLS_PFB_EN_MASK (0x02u) +#define SIM_FLASH_DFLS_PFB_EN_SHIFT (1u) +#define SIM_FLASH_DFLS_PFB_EN_WIDTH (1u) +#define SIM_FLASH_PFLS_PFB_EN_MASK (0x01u) +#define SIM_FLASH_PFLS_PFB_EN_SHIFT (0u) +#define SIM_FLASH_PFLS_PFB_EN_WIDTH (1u) + +/* UDIDH Bit Fields */ +#define SIM_UDIDH_H_MASK (0xFFFFFFFFu) +#define SIM_UDIDH_H_SHIFT (0u) +#define SIM_UDIDH_H_WIDTH (32u) + +/* UDIDMH Bit Fields */ +#define SIM_UDIDMH_MH_MASK (0xFFFFFFFFu) +#define SIM_UDIDMH_MH_SHIFT (0u) +#define SIM_UDIDMH_MH_WIDTH (32u) + +/* UDIDML Bit Fields */ +#define SIM_UDIDML_ML_MASK (0xFFFFFFFFu) +#define SIM_UDIDML_ML_SHIFT (0u) +#define SIM_UDIDML_ML_WIDTH (32u) + +/* UDIDL Bit Fields */ +#define SIM_UDIDL_L_MASK (0xFFFFFFFFu) +#define SIM_UDIDL_L_SHIFT (0u) +#define SIM_UDIDL_L_WIDTH (32u) + +/* SDID Bit Fields */ +#define SIM_SDID_ID_MASK (0xFFFFFFFFu) +#define SIM_SDID_ID_SHIFT (0u) +#define SIM_SDID_ID_WIDTH (32u) + +/* SW_TRG Bit Fields */ +#define SIM_SW_TRG_SW_TRG_MASK (0x01u) +#define SIM_SW_TRG_SW_TRG_SHIFT (0u) +#define SIM_SW_TRG_SW_TRG_WIDTH (1u) + +/* CAN Bit Fields */ +#define SIM_CAN_WAK_INT_MASK (0x40000u) +#define SIM_CAN_WAK_INT_SHIFT (18u) +#define SIM_CAN_WAK_INT_WIDTH (1u) +#define SIM_CAN_SLF_WAK_MASK (0x20000u) +#define SIM_CAN_SLF_WAK_SHIFT (17u) +#define SIM_CAN_SLF_WAK_WIDTH (1u) +#define SIM_CAN_LPM_ACK_MASK (0x10000u) +#define SIM_CAN_LPM_ACK_SHIFT (16u) +#define SIM_CAN_LPM_ACK_WIDTH (1u) +#define SIM_CAN_IPG_STOP_MASK (0x08u) +#define SIM_CAN_IPG_STOP_SHIFT (3u) +#define SIM_CAN_IPG_STOP_WIDTH (1u) +#define SIM_CAN_SOFT_RESET_MASK (0x04u) +#define SIM_CAN_SOFT_RESET_SHIFT (2u) +#define SIM_CAN_SOFT_RESET_WIDTH (1u) +#define SIM_CAN_IPG_DOZE_MASK (0x02u) +#define SIM_CAN_IPG_DOZE_SHIFT (1u) +#define SIM_CAN_IPG_DOZE_WIDTH (1u) +#define SIM_CAN_WKUP_SRC_SEL_MASK (0x01u) +#define SIM_CAN_WKUP_SRC_SEL_SHIFT (0u) +#define SIM_CAN_WKUP_SRC_SEL_WIDTH (1u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of SIM registers + */ +typedef struct _SimRegType_ +{ + uint32_t RESERVED0[1]; /*!< Reserverd block, offset: 0x00 */ + volatile uint32_t CHIP; /*!< system chip register, offset: 0x04 */ + uint32_t RESERVED1[2]; /*!< Reserverd block, offset: 0x08 */ + volatile uint32_t PWM_CTRL0; /*!< system PWM register 0, offset: 0x10 */ + volatile uint32_t PWM_CTRL1; /*!< system PWM register 1, offset: 0x14 */ + volatile uint32_t ADC; /*!< system ADC register, offset: 0x18 */ + uint32_t RESERVED2[1]; /*!< Reserverd block, offset: 0x1C */ + volatile uint32_t I2S; /*!< system I2S register, offset: 0x20 */ + volatile uint32_t MFT_CTRL0; /*!< system MFT register 0, offset: 0x24 */ + volatile uint32_t MFT_CTRL1; /*!< system MFT register 1, offset: 0x28 */ + volatile uint32_t FLASH; /*!< system flash controller register, offset: 0x2C */ + const volatile uint32_t UDIDH; /*!< system UD ID high register, offset: 0x30 */ + const volatile uint32_t UDIDMH; /*!< system UD ID medium high register, offset: 0x34 */ + const volatile uint32_t UDIDML; /*!< system UD ID medium low register, offset: 0x38 */ + const volatile uint32_t UDIDL; /*!< system UD ID low register, offset: 0x3C */ + const volatile uint32_t SDID; /*!< system SDID high register, offset: 0x40 */ + volatile uint32_t SW_TRG; /*!< system software trigger register, offset: 0x44 */ + volatile uint32_t CAN; /*!< system CAN configure register, offset: 0x48 */ +} SimRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the SRAM initialization status + * + * This function gets the current SRAM initialization status. + * + * \param[in] obj : pointer to SIM register instance + * \return SRAM initialization status + * - 0b : SRAM initialization is in progress + * - 1b : SRAM initialization is done or not started + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetChipSRamInitSt(const SimRegType *obj) +{ + return ((obj->CHIP & SIM_CHIP_SRAM_INIT_ST_MASK) >> SIM_CHIP_SRAM_INIT_ST_SHIFT); +} + +/*! \brief Sets the SRAM initial command + * + * This function sets the SRAM initial command. + * SRAM initialization start trigger. Invalid when SRAM_RETEN is 0 + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of SRAM initial command + * - 0b : not start SRAM initialization + * - 1b : start SRAM initialization + */ +__attribute__((always_inline)) static inline void SimReg_SetChipSRamInit(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CHIP; + + tmp &= ~SIM_CHIP_SRAM_INIT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_CHIP_SRAM_INIT_SHIFT)) & SIM_CHIP_SRAM_INIT_MASK); + obj->CHIP = tmp; +} + +/*! \brief Gets the SRAM retention + * + * This function gets the current SRAM retention. + * It is reseted by power up and standby exit only. + * + * \note If this bit is set to 0 and system reset happens, program heap operation might malfunction. + * Use this bit with caution. + * + * \param[in] obj : pointer to SIM register instance + * \return SRAM retention + * - 0b : memory contents are retained across resets. + * - 1b : No memory contents retention. + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetChipSRamReten(const SimRegType *obj) +{ + return ((obj->CHIP & SIM_CHIP_SRAM_RETEN_MASK) >> SIM_CHIP_SRAM_RETEN_SHIFT); +} + +/*! \brief Sets the SRAM retention + * + * This function sets the SRAM retention. + * It is reseted by power up and standby exit only. + * + * \note If this bit is set to 0 and system reset happens, program heap operation might malfunction. + * Use this bit with caution. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of SRAM retention + * - 0b : memory contents are retained across resets. + * - 1b : No memory contents retention. + */ +__attribute__((always_inline)) static inline void SimReg_SetChipSRamReten(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CHIP; + + tmp &= ~SIM_CHIP_SRAM_RETEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_CHIP_SRAM_RETEN_SHIFT)) & SIM_CHIP_SRAM_RETEN_MASK); + obj->CHIP = tmp; +} + +/*! \brief Gets the PWM3 output channel select + * + * This function gets the current PWM3 output channel select. + * channel details are same with SIM_PWM_CTRL0[PWM_FUNC0] + * + * \param[in] obj : pointer to SIM register instance + * \return PWM3 output channel select + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetPwmCtrl0PwmFunc3(const SimRegType *obj) +{ + return ((obj->PWM_CTRL0 & SIM_PWM_CTRL0_PWM_FUNC3_MASK) >> SIM_PWM_CTRL0_PWM_FUNC3_SHIFT); +} + +/*! \brief Sets the PWM3 output channel select + * + * This function sets the PWM3 output channel select. + * channel details are same with SIM_PWM_CTRL0[PWM_FUNC0] + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of PWM3 output channel select + */ +__attribute__((always_inline)) static inline void SimReg_SetPwmCtrl0PwmFunc3(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWM_CTRL0; + + tmp &= ~SIM_PWM_CTRL0_PWM_FUNC3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_PWM_CTRL0_PWM_FUNC3_SHIFT)) & SIM_PWM_CTRL0_PWM_FUNC3_MASK); + obj->PWM_CTRL0 = tmp; +} + +/*! \brief Gets the PWM2 output channel select + * + * This function gets the current PWM2 output channel select. + * channel details are same with SIM_PWM_CTRL0[PWM_FUNC0 + * + * \param[in] obj : pointer to SIM register instance + * \return PWM2 output channel select + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetPwmCtrl0PwmFunc2(const SimRegType *obj) +{ + return ((obj->PWM_CTRL0 & SIM_PWM_CTRL0_PWM_FUNC2_MASK) >> SIM_PWM_CTRL0_PWM_FUNC2_SHIFT); +} + +/*! \brief Sets the PWM2 output channel select + * + * This function sets the PWM2 output channel select. + * channel details are same with SIM_PWM_CTRL0[PWM_FUNC0] + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of PWM2 output channel select + */ +__attribute__((always_inline)) static inline void SimReg_SetPwmCtrl0PwmFunc2(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWM_CTRL0; + + tmp &= ~SIM_PWM_CTRL0_PWM_FUNC2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_PWM_CTRL0_PWM_FUNC2_SHIFT)) & SIM_PWM_CTRL0_PWM_FUNC2_MASK); + obj->PWM_CTRL0 = tmp; +} + +/*! \brief Gets the PWM1 output channel select + * + * This function gets the current PWM1 output channel select. + * channel details are same with SIM_PWM_CTRL0[PWM_FUNC0] + * + * \param[in] obj : pointer to SIM register instance + * \return PWM1 output channel select + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetPwmCtrl0PwmFunc1(const SimRegType *obj) +{ + return ((obj->PWM_CTRL0 & SIM_PWM_CTRL0_PWM_FUNC1_MASK) >> SIM_PWM_CTRL0_PWM_FUNC1_SHIFT); +} + +/*! \brief Sets the PWM1 output channel select + * + * This function sets the PWM1 output channel select. + * channel details are same with SIM_PWM_CTRL0[PWM_FUNC0] + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of PWM1 output channel select + */ +__attribute__((always_inline)) static inline void SimReg_SetPwmCtrl0PwmFunc1(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWM_CTRL0; + + tmp &= ~SIM_PWM_CTRL0_PWM_FUNC1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_PWM_CTRL0_PWM_FUNC1_SHIFT)) & SIM_PWM_CTRL0_PWM_FUNC1_MASK); + obj->PWM_CTRL0 = tmp; +} + +/*! \brief Gets the PWM0 output channel select + * + * This function gets the current PWM0 output channel select. + * + * \param[in] obj : pointer to SIM register instance + * \return PWM0 output channel select + * - 0d : PWM0[0] + * - 1d : PWM0[1] + * - 2d : PWM0[2] + * - 3d : PWM0[3] + * - 4d : PWM0[4] + * - 5d : PWM0[5] + * - 6d : PWM1[0] + * - 7d : PWM1[1] + * - 8d : PWM1[2] + * - 9d : PWM1[3] + * - 10d : PWM1[4] + * - 11d : PWM1[5] + * - others : reserved + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetPwmCtrl0PwmFunc0(const SimRegType *obj) +{ + return ((obj->PWM_CTRL0 & SIM_PWM_CTRL0_PWM_FUNC0_MASK) >> SIM_PWM_CTRL0_PWM_FUNC0_SHIFT); +} + +/*! \brief Sets the PWM0 output channel select + * + * This function sets the PWM0 output channel select. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of PWM0 output channel select + * - 0d : PWM0[0] + * - 1d : PWM0[1] + * - 2d : PWM0[2] + * - 3d : PWM0[3] + * - 4d : PWM0[4] + * - 5d : PWM0[5] + * - 6d : PWM1[0] + * - 7d : PWM1[1] + * - 8d : PWM1[2] + * - 9d : PWM1[3] + * - 10d : PWM1[4] + * - 11d : PWM1[5] + * - others : reserved + */ +__attribute__((always_inline)) static inline void SimReg_SetPwmCtrl0PwmFunc0(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWM_CTRL0; + + tmp &= ~SIM_PWM_CTRL0_PWM_FUNC0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_PWM_CTRL0_PWM_FUNC0_SHIFT)) & SIM_PWM_CTRL0_PWM_FUNC0_MASK); + obj->PWM_CTRL0 = tmp; +} + +/*! \brief Gets the PWM5 output channel select + * + * This function gets the current PWM5 output channel select. + * channel details are same with SIM_PWM_CTRL0[PWM_FUNC0] + * + * \param[in] obj : pointer to SIM register instance + * \return PWM5 output channel select + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetPwmCtrl1PwmFunc5(const SimRegType *obj) +{ + return ((obj->PWM_CTRL1 & SIM_PWM_CTRL1_PWM_FUNC5_MASK) >> SIM_PWM_CTRL1_PWM_FUNC5_SHIFT); +} + +/*! \brief Sets the PWM5 output channel select + * + * This function sets the PWM5 output channel select. + * channel details are same with SIM_PWM_CTRL0[PWM_FUNC0] + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of PWM5 output channel select + */ +__attribute__((always_inline)) static inline void SimReg_SetPwmCtrl1PwmFunc5(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWM_CTRL1; + + tmp &= ~SIM_PWM_CTRL1_PWM_FUNC5_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_PWM_CTRL1_PWM_FUNC5_SHIFT)) & SIM_PWM_CTRL1_PWM_FUNC5_MASK); + obj->PWM_CTRL1 = tmp; +} + +/*! \brief Gets the PWM4 output channel select + * + * This function gets the current PWM4 output channel select. + * channel details are same with SIM_PWM_CTRL0[PWM_FUNC0] + * + * \param[in] obj : pointer to SIM register instance + * \return PWM4 output channel select + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetPwmCtrl1PwmFunc4(const SimRegType *obj) +{ + return ((obj->PWM_CTRL1 & SIM_PWM_CTRL1_PWM_FUNC4_MASK) >> SIM_PWM_CTRL1_PWM_FUNC4_SHIFT); +} + +/*! \brief Sets the PWM4 output channel select + * + * This function sets the PWM4 output channel select. + * channel details are same with SIM_PWM_CTRL0[PWM_FUNC0] + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of PWM4 output channel select + */ +__attribute__((always_inline)) static inline void SimReg_SetPwmCtrl1PwmFunc4(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PWM_CTRL1; + + tmp &= ~SIM_PWM_CTRL1_PWM_FUNC4_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_PWM_CTRL1_PWM_FUNC4_SHIFT)) & SIM_PWM_CTRL1_PWM_FUNC4_MASK); + obj->PWM_CTRL1 = tmp; +} + +/*! \brief Gets the ADC trigger source + * + * This function gets the current ADC trigger source. + * + * \param[in] obj : pointer to SIM register instance + * \return ADC trigger source + * - 0b : PDB trigger out + * - 1b : TRGMUX output + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetAdcTrgSrc(const SimRegType *obj) +{ + return ((obj->ADC & SIM_ADC_TRG_SRC_MASK) >> SIM_ADC_TRG_SRC_SHIFT); +} + +/*! \brief Sets the ADC trigger source + * + * This function sets the ADC trigger source. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of ADC trigger source + * - 0b : PDB trigger out + * - 1b : TRGMUX output + */ +__attribute__((always_inline)) static inline void SimReg_SetAdcTrgSrc(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~SIM_ADC_TRG_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_ADC_TRG_SRC_SHIFT)) & SIM_ADC_TRG_SRC_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the ADC software pre trigger source + * + * This function gets the current ADC software pre trigger source. + * + * \param[in] obj : pointer to SIM register instance + * \return ADC software pre trigger source + * - 100b : pretrigger 0 + * - 101b : pretrigger 1 + * - 110b : pretrigger 2 + * - 111b : pretrigger 3 + * - others : reserved + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetAdcPreTrgSwSrc(const SimRegType *obj) +{ + return ((obj->ADC & SIM_ADC_PRETRG_SW_SRC_MASK) >> SIM_ADC_PRETRG_SW_SRC_SHIFT); +} + +/*! \brief Sets the ADC software pre trigger source + * + * This function sets the ADC software pre trigger source. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of ADC software pre trigger source + * - 100b : pretrigger 0 + * - 101b : pretrigger 1 + * - 110b : pretrigger 2 + * - 111b : pretrigger 3 + * - others : reserved + */ +__attribute__((always_inline)) static inline void SimReg_SetAdcPreTrgSwSrc(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~SIM_ADC_PRETRG_SW_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_ADC_PRETRG_SW_SRC_SHIFT)) & SIM_ADC_PRETRG_SW_SRC_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the ADC pre trigger source + * + * This function gets the current ADC pre trigger source. + * + * \param[in] obj : pointer to SIM register instance + * \return ADC pre trigger source + * - 00b : PDB trigger out + * - 01b : TRGMUX output + * - 10b : software configure PRETRG1_SW_SRC + * - 11b : no hardware trigger + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetAdcPreTrgSrc(const SimRegType *obj) +{ + return ((obj->ADC & SIM_ADC_PRETRG_SRC_MASK) >> SIM_ADC_PRETRG_SRC_SHIFT); +} + +/*! \brief Sets the ADC pre trigger source + * + * This function sets the ADC pre trigger source. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of ADC pre trigger source + * - 00b : PDB trigger out + * - 01b : TRGMUX output + * - 10b : software configure PRETRG1_SW_SRC + * - 11b : no hardware trigger + */ +__attribute__((always_inline)) static inline void SimReg_SetAdcPreTrgSrc(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~SIM_ADC_PRETRG_SRC_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_ADC_PRETRG_SRC_SHIFT)) & SIM_ADC_PRETRG_SRC_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the I2S Slave dma or interrupt mode + * + * This function gets the current I2S Slave dma or interrupt mode. + * + * \param[in] obj : pointer to SIM register instance + * \return I2S Slave dma or interrupt mode + * - 0b : interrupt + * - 1b : dma + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetI2sSlvDmaIrq(const SimRegType *obj) +{ + return ((obj->I2S & SIM_I2S_SLV_DMA_IRQ_MASK) >> SIM_I2S_SLV_DMA_IRQ_SHIFT); +} + +/*! \brief Sets the I2S Slave dma or interrupt mode + * + * This function sets the I2S Slave dma or interrupt mode. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of I2S Slave dma or interrupt mode + * - 0b : interrupt + * - 1b : dma + */ +__attribute__((always_inline)) static inline void SimReg_SetI2sSlvDmaIrq(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2S; + + tmp &= ~SIM_I2S_SLV_DMA_IRQ_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_I2S_SLV_DMA_IRQ_SHIFT)) & SIM_I2S_SLV_DMA_IRQ_MASK); + obj->I2S = tmp; +} + +/*! \brief Gets the I2S Master dma or interrupt mode + * + * This function gets the current I2S Master dma or interrupt mode. + * + * \param[in] obj : pointer to SIM register instance + * \return I2S Master dma or interrupt mode + * - 0b : interrupt + * - 1b : dma + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetI2sMstDmaIrq(const SimRegType *obj) +{ + return ((obj->I2S & SIM_I2S_MST_DMA_IRQ_MASK) >> SIM_I2S_MST_DMA_IRQ_SHIFT); +} + +/*! \brief Sets the I2S Master dma or interrupt mode + * + * This function sets the I2S Master dma or interrupt mode. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of I2S Master dma or interrupt mode + * - 0b : interrupt + * - 1b : dma + */ +__attribute__((always_inline)) static inline void SimReg_SetI2sMstDmaIrq(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2S; + + tmp &= ~SIM_I2S_MST_DMA_IRQ_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_I2S_MST_DMA_IRQ_SHIFT)) & SIM_I2S_MST_DMA_IRQ_MASK); + obj->I2S = tmp; +} + +/*! \brief Gets the I2S mode + * + * This function gets the current I2S mode. + * + * \param[in] obj : pointer to SIM register instance + * \return I2S mode + * - 0b : slave + * - 1b : master + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetI2sMode(const SimRegType *obj) +{ + return ((obj->I2S & SIM_I2S_MODE_MASK) >> SIM_I2S_MODE_SHIFT); +} + +/*! \brief Sets the I2S mode + * + * This function sets the I2S mode. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of I2S mode + * - 0b : slave + * - 1b : master + */ +__attribute__((always_inline)) static inline void SimReg_SetI2sMode(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->I2S; + + tmp &= ~SIM_I2S_MODE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_I2S_MODE_SHIFT)) & SIM_I2S_MODE_MASK); + obj->I2S = tmp; +} + +/*! \brief Gets the MFT1 Fault X Select + * + * This function gets the current MFT1 Fault X Select. + * Selects the source of the MFT1 fault. + * Every bit means one fault input, respectively. + * If there is no pin assigned to the specific FAULT signal, logic zero is used as input source. + * + * \param[in] obj : pointer to SIM register instance + * \return MFT1 Fault X Select + * - 0b : MFT1_FLTx pin + * - 1b : TRGMUX_MFT1 out + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetMftCtrl0Mft1FltSel(const SimRegType *obj) +{ + return ((obj->MFT_CTRL0 & SIM_MFT_CTRL0_MFT1_FLT_SEL_MASK) >> SIM_MFT_CTRL0_MFT1_FLT_SEL_SHIFT); +} + +/*! \brief Sets the MFT1 Fault X Select + * + * This function sets the MFT1 Fault X Select. + * Selects the source of the MFT1 fault. + * Every bit means one fault input, respectively. + * If there is no pin assigned to the specific FAULT signal, logic zero is used as input source. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of MFT1 Fault X Select + * - 0b : MFT1_FLTx pin + * - 1b : TRGMUX_MFT1 out + */ +__attribute__((always_inline)) static inline void SimReg_SetMftCtrl0Mft1FltSel(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT_CTRL0; + + tmp &= ~SIM_MFT_CTRL0_MFT1_FLT_SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_MFT_CTRL0_MFT1_FLT_SEL_SHIFT)) & SIM_MFT_CTRL0_MFT1_FLT_SEL_MASK); + obj->MFT_CTRL0 = tmp; +} + +/*! \brief Gets the MFT0 Fault X Select + * + * This function gets the current MFT0 Fault X Select. + * Selects the source of the MFT0 fault. + * Every bit means one fault input, respectively. + * If there is no pin assigned to the specific FAULT signal, logic zero is used as input source. + * + * \param[in] obj : pointer to SIM register instance + * \return MFT0 Fault X Select + * - 0b : MFT0_FLTx pin + * - 1b : TRGMUX_MFT0 out + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetMftCtrl0Mft0FltSel(const SimRegType *obj) +{ + return ((obj->MFT_CTRL0 & SIM_MFT_CTRL0_MFT0_FLT_SEL_MASK) >> SIM_MFT_CTRL0_MFT0_FLT_SEL_SHIFT); +} + +/*! \brief Sets the MFT0 Fault X Select + * + * This function sets the MFT0 Fault X Select. + * Selects the source of the MFT0 fault. + * Every bit means one fault input, respectively. + * If there is no pin assigned to the specific FAULT signal, logic zero is used as input source. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of MFT0 Fault X Select + * - 0b : MFT0_FLTx pin + * - 1b : TRGMUX_MFT0 out + */ +__attribute__((always_inline)) static inline void SimReg_SetMftCtrl0Mft0FltSel(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT_CTRL0; + + tmp &= ~SIM_MFT_CTRL0_MFT0_FLT_SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_MFT_CTRL0_MFT0_FLT_SEL_SHIFT)) & SIM_MFT_CTRL0_MFT0_FLT_SEL_MASK); + obj->MFT_CTRL0 = tmp; +} + +/*! \brief Gets the MFT global load enable + * + * This function gets the current MFT global load enable. + * This bit is not self-clearing. + * For subsequent reload operations, it should be cleared and then set. + * + * \param[in] obj : pointer to SIM register instance + * \return MFT global load enable + * - 0b : MFT Global load mechanism disabled. + * - 1b : MFT Global load mechanism enabled + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetMftCtrl0GldOk(const SimRegType *obj) +{ + return ((obj->MFT_CTRL0 & SIM_MFT_CTRL0_GLDOK_MASK) >> SIM_MFT_CTRL0_GLDOK_SHIFT); +} + +/*! \brief Sets the MFT global load enable + * + * This function sets the MFT global load enable. + * This bit is not self-clearing. + * For subsequent reload operations, it should be cleared and then set. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of MFT global load enable + * - 0b : MFT Global load mechanism disabled. + * - 1b : MFT Global load mechanism enabled + */ +__attribute__((always_inline)) static inline void SimReg_SetMftCtrl0GldOk(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT_CTRL0; + + tmp &= ~SIM_MFT_CTRL0_GLDOK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_MFT_CTRL0_GLDOK_SHIFT)) & SIM_MFT_CTRL0_GLDOK_MASK); + obj->MFT_CTRL0 = tmp; +} + +/*! \brief Gets the MFT1 Sync Bit + * + * This function gets the current MFT1 Sync Bit. + * This is used as a synchronization trigger source for MFT + * + * \param[in] obj : pointer to SIM register instance + * \return MFT1 Sync Bit + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetMftCtrl1Mft1SyncBit(const SimRegType *obj) +{ + return ((obj->MFT_CTRL1 & SIM_MFT_CTRL1_MFT1SYNCBIT_MASK) >> SIM_MFT_CTRL1_MFT1SYNCBIT_SHIFT); +} + +/*! \brief Sets the MFT1 Sync Bit + * + * This function sets the MFT1 Sync Bit. + * This is used as a synchronization trigger source for MFT + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of MFT1 Sync Bit + */ +__attribute__((always_inline)) static inline void SimReg_SetMftCtrl1Mft1SyncBit(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT_CTRL1; + + tmp &= ~SIM_MFT_CTRL1_MFT1SYNCBIT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_MFT_CTRL1_MFT1SYNCBIT_SHIFT)) & SIM_MFT_CTRL1_MFT1SYNCBIT_MASK); + obj->MFT_CTRL1 = tmp; +} + +/*! \brief Gets the MFT0 Sync Bit + * + * This function gets the current MFT0 Sync Bit. + * This is used as a synchronization trigger source for MFT + * + * \param[in] obj : pointer to SIM register instance + * \return MFT0 Sync Bit + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetMftCtrl1Mft0SyncBit(const SimRegType *obj) +{ + return ((obj->MFT_CTRL1 & SIM_MFT_CTRL1_MFT0SYNCBIT_MASK) >> SIM_MFT_CTRL1_MFT0SYNCBIT_SHIFT); +} + +/*! \brief Sets the MFT0 Sync Bit + * + * This function sets the MFT0 Sync Bit. + * This is used as a synchronization trigger source for MFT + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of MFT0 Sync Bit + */ +__attribute__((always_inline)) static inline void SimReg_SetMftCtrl1Mft0SyncBit(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT_CTRL1; + + tmp &= ~SIM_MFT_CTRL1_MFT0SYNCBIT_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_MFT_CTRL1_MFT0SYNCBIT_SHIFT)) & SIM_MFT_CTRL1_MFT0SYNCBIT_MASK); + obj->MFT_CTRL1 = tmp; +} + +/*! \brief Gets the MFT1 CH0 Select + * + * This function gets the current MFT1 CH0 Select. + * Selects MFT1 Channel0's input + * + * \param[in] obj : pointer to SIM register instance + * \return MFT1 CH0 Select + * - 0b : MFT1_CH0 input from PAD + * - 1b : CMP0 output + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetMftCtrl1Mft1Ch0Sel(const SimRegType *obj) +{ + return ((obj->MFT_CTRL1 & SIM_MFT_CTRL1_MFT1CH0SEL_MASK) >> SIM_MFT_CTRL1_MFT1CH0SEL_SHIFT); +} + +/*! \brief Sets the MFT1 CH0 Select + * + * This function sets the MFT1 CH0 Select. + * Selects MFT1 Channel0's input + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of MFT1 CH0 Select + * - 0b : MFT1_CH0 input from PAD + * - 1b : CMP0 output + */ +__attribute__((always_inline)) static inline void SimReg_SetMftCtrl1Mft1Ch0Sel(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT_CTRL1; + + tmp &= ~SIM_MFT_CTRL1_MFT1CH0SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_MFT_CTRL1_MFT1CH0SEL_SHIFT)) & SIM_MFT_CTRL1_MFT1CH0SEL_MASK); + obj->MFT_CTRL1 = tmp; +} + +/*! \brief Gets the MFT0 channel modulation select with MFT1_CH1 + * + * This function gets the current MFT0 channel modulation select with MFT1_CH1. + * Bits 7 to 0 of this field are for channel 7 to 0, respectively. For each channel, + * + * \param[in] obj : pointer to SIM register instance + * \return MFT0 channel modulation select with MFT1_CH1 + * - 0b : No modulation with MFT1_CH1 + * - 1b : Modulation with MFT1_CH1 + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetMftCtrl1Mft0OutSel(const SimRegType *obj) +{ + return ((obj->MFT_CTRL1 & SIM_MFT_CTRL1_MFT0_OUTSEL_MASK) >> SIM_MFT_CTRL1_MFT0_OUTSEL_SHIFT); +} + +/*! \brief Sets the MFT0 channel modulation select with MFT1_CH1 + * + * This function sets the MFT0 channel modulation select with MFT1_CH1. + * Bits 7 to 0 of this field are for channel 7 to 0, respectively. For each channel, + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of MFT0 channel modulation select with MFT1_CH1 + * - 0b : No modulation with MFT1_CH1 + * - 1b : Modulation with MFT1_CH1 + */ +__attribute__((always_inline)) static inline void SimReg_SetMftCtrl1Mft0OutSel(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT_CTRL1; + + tmp &= ~SIM_MFT_CTRL1_MFT0_OUTSEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_MFT_CTRL1_MFT0_OUTSEL_SHIFT)) & SIM_MFT_CTRL1_MFT0_OUTSEL_MASK); + obj->MFT_CTRL1 = tmp; +} + +/*! \brief Gets the flash eee restore config status + * + * This function gets the current Flash eee restore config status. + * Indicates the restore settings of emulated eeprom + * + * \param[in] obj : pointer to SIM register instance + * \return flash eee restore config status. + * - 0b : emulated eeprom is configured as not restore after reset + * - 1b : emulated eeprom is configured as restore after reset + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetFlashEeeRst(const SimRegType *obj) +{ + return ((obj->FLASH & SIM_FLASH_EEERST_MASK) >> SIM_FLASH_EEERST_SHIFT); +} + +/*! \brief Gets the flash eee valid + * + * This function gets the current flash eee valid. + * emulated eeprom is valid + * + * \param[in] obj : pointer to SIM register instance + * \return Flash eee Valid + * - 0b : invalid + * - 1b : valid + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetFlashEeeVld(const SimRegType *obj) +{ + return ((obj->FLASH & SIM_FLASH_EEEVLD_MASK) >> SIM_FLASH_EEEVLD_SHIFT); +} + +/*! \brief Gets the flash load is done + * + * This function gets the current flash load is done. + * + * \param[in] obj : pointer to SIM register instance + * \return flash load is done + * - 0b : during load progress + * - 1b : load done + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetFlashLoadDone(const SimRegType *obj) +{ + return ((obj->FLASH & SIM_FLASH_LOAD_DONE_MASK) >> SIM_FLASH_LOAD_DONE_SHIFT); +} + +/*! \brief Gets the flash is blank + * + * This function gets the current flash is blank. + * + * \param[in] obj : pointer to SIM register instance + * \return flash is blank + * - 0b : flash is not blank + * - 1b : flash is blank + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetFlashVirginFlag(const SimRegType *obj) +{ + return ((obj->FLASH & SIM_FLASH_VIRGIN_FLAG_MASK) >> SIM_FLASH_VIRGIN_FLAG_SHIFT); +} + +/*! \brief Gets the dflash prefetch buffer flush + * + * This function gets the current dflash prefetch buffer flush. + * + * \param[in] obj : pointer to SIM register instance + * \return dflash prefetch buffer flush + * - 0b : do not flush dflash prefetch buffer; + * - 1b : flush dflash prefetch buffer; + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetFlashDFlsFlushEn(const SimRegType *obj) +{ + return ((obj->FLASH & SIM_FLASH_DFLS_FLUSH_EN_MASK) >> SIM_FLASH_DFLS_FLUSH_EN_SHIFT); +} + +/*! \brief Sets the dflash prefetch buffer flush + * + * This function sets the dflash prefetch buffer flush. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of dflash prefetch buffer flush + * - 0b : do not flush dflash prefetch buffer; + * - 1b : flush dflash prefetch buffer; + */ +__attribute__((always_inline)) static inline void SimReg_SetFlashDFlsFlushEn(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLASH; + + tmp &= ~SIM_FLASH_DFLS_FLUSH_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_FLASH_DFLS_FLUSH_EN_SHIFT)) & SIM_FLASH_DFLS_FLUSH_EN_MASK); + obj->FLASH = tmp; +} + +/*! \brief Gets the pflash prefetch buffer flush + * + * This function gets the current pflash prefetch buffer flush. + * + * \param[in] obj : pointer to SIM register instance + * \return pflash prefetch buffer flush + * - 0b : do not flush pflash prefetch buffer; + * - 1b : flush pflash prefetch buffer; + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetFlashPFlsFlushEn(const SimRegType *obj) +{ + return ((obj->FLASH & SIM_FLASH_PFLS_FLUSH_EN_MASK) >> SIM_FLASH_PFLS_FLUSH_EN_SHIFT); +} + +/*! \brief Sets the pflash prefetch buffer flush + * + * This function sets the pflash prefetch buffer flush. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of pflash prefetch buffer flush + * - 0b : do not flush pflash prefetch buffer; + * - 1b : flush pflash prefetch buffer; + */ +__attribute__((always_inline)) static inline void SimReg_SetFlashPFlsFlushEn(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLASH; + + tmp &= ~SIM_FLASH_PFLS_FLUSH_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_FLASH_PFLS_FLUSH_EN_SHIFT)) & SIM_FLASH_PFLS_FLUSH_EN_MASK); + obj->FLASH = tmp; +} + +/*! \brief Gets the dflash prefetch enable + * + * This function gets the current dflash prefetch enable. + * + * \param[in] obj : pointer to SIM register instance + * \return dflash prefetch enable + * - 0b : disable dflash prefetch; + * - 1b : enable dflash prefetch; + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetFlashDFlsPfbEn(const SimRegType *obj) +{ + return ((obj->FLASH & SIM_FLASH_DFLS_PFB_EN_MASK) >> SIM_FLASH_DFLS_PFB_EN_SHIFT); +} + +/*! \brief Sets the dflash prefetch enable + * + * This function sets the dflash prefetch enable. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of dflash prefetch enable + * - 0b : disable dflash prefetch; + * - 1b : enable dflash prefetch; + */ +__attribute__((always_inline)) static inline void SimReg_SetFlashDFlsPfbEn(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLASH; + + tmp &= ~SIM_FLASH_DFLS_PFB_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_FLASH_DFLS_PFB_EN_SHIFT)) & SIM_FLASH_DFLS_PFB_EN_MASK); + obj->FLASH = tmp; +} + +/*! \brief Gets the pflash prefetch enable + * + * This function gets the current pflash prefetch enable. + * + * \param[in] obj : pointer to SIM register instance + * \return pflash prefetch enable + * - 0b : disable pflash prefetch; + * - 1b : enable pflash prefetch; + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetFlashPFlsPfbEn(const SimRegType *obj) +{ + return ((obj->FLASH & SIM_FLASH_PFLS_PFB_EN_MASK) >> SIM_FLASH_PFLS_PFB_EN_SHIFT); +} + +/*! \brief Sets the pflash prefetch enable + * + * This function sets the pflash prefetch enable. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of pflash prefetch enable + * - 0b : disable pflash prefetch; + * - 1b : enable pflash prefetch; + */ +__attribute__((always_inline)) static inline void SimReg_SetFlashPFlsPfbEn(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->FLASH; + + tmp &= ~SIM_FLASH_PFLS_PFB_EN_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_FLASH_PFLS_PFB_EN_SHIFT)) & SIM_FLASH_PFLS_PFB_EN_MASK); + obj->FLASH = tmp; +} + +/*! \brief Gets the Unique Identification[127:96] + * + * This function gets the current Unique Identification[127:96]. + * + * \param[in] obj : pointer to SIM register instance + * \return Unique Identification[127:96] + */ +__attribute__((always_inline)) static inline uint32_t SimReg_GetUdidH(const SimRegType *obj) +{ + return ((obj->UDIDH & SIM_UDIDH_H_MASK) >> SIM_UDIDH_H_SHIFT); +} + +/*! \brief Gets the Unique Identification[95:64] + * + * This function gets the current Unique Identification[95:64]. + * + * \param[in] obj : pointer to SIM register instance + * \return Unique Identification[95:64] + */ +__attribute__((always_inline)) static inline uint32_t SimReg_GetUdidMH(const SimRegType *obj) +{ + return ((obj->UDIDMH & SIM_UDIDMH_MH_MASK) >> SIM_UDIDMH_MH_SHIFT); +} + +/*! \brief Gets the Unique Identification[63:32] + * + * This function gets the current Unique Identification[63:32]. + * + * \param[in] obj : pointer to SIM register instance + * \return Unique Identification[63:32] + */ +__attribute__((always_inline)) static inline uint32_t SimReg_GetUdidML(const SimRegType *obj) +{ + return ((obj->UDIDML & SIM_UDIDML_ML_MASK) >> SIM_UDIDML_ML_SHIFT); +} + +/*! \brief Gets the Unique Identification[31:0] + * + * This function gets the current Unique Identification[31:0]. + * + * \param[in] obj : pointer to SIM register instance + * \return Unique Identification[31:0] + */ +__attribute__((always_inline)) static inline uint32_t SimReg_GetUdidL(const SimRegType *obj) +{ + return ((obj->UDIDL & SIM_UDIDL_L_MASK) >> SIM_UDIDL_L_SHIFT); +} + +/*! \brief Gets the System Device Identification + * + * This function gets the current System Device Identification. + * + * \param[in] obj : pointer to SIM register instance + * \return System Device Identification + */ +__attribute__((always_inline)) static inline uint32_t SimReg_GetSdId(const SimRegType *obj) +{ + return ((obj->SDID & SIM_SDID_ID_MASK) >> SIM_SDID_ID_SHIFT); +} + +/*! \brief Gets the Software trigger to TRGMUX + * + * This function gets the current Software trigger to TRGMUX. + * Writing to this bit generates software trigger to peripheral + * + * \param[in] obj : pointer to SIM register instance + * \return Software trigger to TRGMUX + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetSwTrg(const SimRegType *obj) +{ + return ((obj->SW_TRG & SIM_SW_TRG_SW_TRG_MASK) >> SIM_SW_TRG_SW_TRG_SHIFT); +} + +/*! \brief Sets the Software trigger to TRGMUX + * + * This function sets the Software trigger to TRGMUX. + * Writing to this bit generates software trigger to peripheral + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of Software trigger to TRGMUX + */ +__attribute__((always_inline)) static inline void SimReg_SetSwTrg(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->SW_TRG; + + tmp &= ~SIM_SW_TRG_SW_TRG_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_SW_TRG_SW_TRG_SHIFT)) & SIM_SW_TRG_SW_TRG_MASK); + obj->SW_TRG = tmp; +} + +/*! \brief Gets the unmasked wake up interrupt flag + * + * This function gets the current unmasked wake up interrupt flag. + * + * \param[in] obj : pointer to SIM register instance + * \return unmasked wake up interrupt flag + * - 0b : there haven't wake up interrupt. + * - 1b : wake up interrrupt. + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetCanWakInt(const SimRegType *obj) +{ + return ((obj->CAN & SIM_CAN_WAK_INT_MASK) >> SIM_CAN_WAK_INT_SHIFT); +} + +/*! \brief Gets the FlexCAN self wakeup enable + * + * This function gets the current FlexCAN self wakeup enable. + * Indicates that the FlexCAN self wake up mechanism is enabled. + * + * \param[in] obj : pointer to SIM register instance + * \return FlexCAN self wakeup enable + * - 0b : the self wake up mechanism is not enabled. + * - 1b : the self wake up mechanism enabled. + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetCanSlfWak(const SimRegType *obj) +{ + return ((obj->CAN & SIM_CAN_SLF_WAK_MASK) >> SIM_CAN_SLF_WAK_SHIFT); +} + +/*! \brief Gets the FlexCAN low power mode flag + * + * This function gets the current FlexCAN low power mode flag. + * Indicates that the FlexCAN is in either Doze mode or stop mode. + * + * \param[in] obj : pointer to SIM register instance + * \return FlexCAN low power mode flag + * - 0b : the state is normal work mode. + * - 1b : the state is in low power mode. + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetCanLpmAck(const SimRegType *obj) +{ + return ((obj->CAN & SIM_CAN_LPM_ACK_MASK) >> SIM_CAN_LPM_ACK_SHIFT); +} + +/*! \brief Gets the CAN stop mode request + * + * This function gets the current CAN stop mode request. + * high active. + * + * \param[in] obj : pointer to SIM register instance + * \return CAN stop mode request + * - 0b : not request. + * - 1b : stop mode request. + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetCanIpgStop(const SimRegType *obj) +{ + return ((obj->CAN & SIM_CAN_IPG_STOP_MASK) >> SIM_CAN_IPG_STOP_SHIFT); +} + +/*! \brief Sets the CAN stop mode request + * + * This function sets the CAN stop mode request. + * high active. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of CAN stop mode request + * - 0b : not request. + * - 1b : stop mode request. + */ +__attribute__((always_inline)) static inline void SimReg_SetCanIpgStop(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CAN; + + tmp &= ~SIM_CAN_IPG_STOP_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_CAN_IPG_STOP_SHIFT)) & SIM_CAN_IPG_STOP_MASK); + obj->CAN = tmp; +} + +/*! \brief Gets the CAN soft reset + * + * This function gets the current CAN soft reset. + * high active. + * + * \param[in] obj : pointer to SIM register instance + * \return CAN soft reset + * - 0b : not reset. + * - 1b : reset. + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetCanSoftReset(const SimRegType *obj) +{ + return ((obj->CAN & SIM_CAN_SOFT_RESET_MASK) >> SIM_CAN_SOFT_RESET_SHIFT); +} + +/*! \brief Sets the CAN soft reset + * + * This function sets the CAN soft reset. + * high active. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of CAN soft reset + * - 0b : not reset. + * - 1b : reset. + */ +__attribute__((always_inline)) static inline void SimReg_SetCanSoftReset(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CAN; + + tmp &= ~SIM_CAN_SOFT_RESET_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_CAN_SOFT_RESET_SHIFT)) & SIM_CAN_SOFT_RESET_MASK); + obj->CAN = tmp; +} + +/*! \brief Gets the CAN doze mode request + * + * This function gets the current CAN doze mode request. + * high active. + * + * \param[in] obj : pointer to SIM register instance + * \return CAN doze mode request + * - 0b : not request. + * - 1b : doze request. + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetCanIpgDoze(const SimRegType *obj) +{ + return ((obj->CAN & SIM_CAN_IPG_DOZE_MASK) >> SIM_CAN_IPG_DOZE_SHIFT); +} + +/*! \brief Sets the CAN doze mode request + * + * This function sets the CAN doze mode request. + * high active. + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of CAN doze mode request + * - 0b : not request. + * - 1b : doze request. + */ +__attribute__((always_inline)) static inline void SimReg_SetCanIpgDoze(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CAN; + + tmp &= ~SIM_CAN_IPG_DOZE_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_CAN_IPG_DOZE_SHIFT)) & SIM_CAN_IPG_DOZE_MASK); + obj->CAN = tmp; +} + +/*! \brief Gets the CAN wake up function select signal + * + * This function gets the current CAN wake up function select signal . + * + * \param[in] obj : pointer to SIM register instance + * \return CAN wake up function select signal + * - 1b : support stop and doze mode. + * - 0b : select not support stop and doze mode. + */ +__attribute__((always_inline)) static inline uint8_t SimReg_GetCanWkupSrcSel(const SimRegType *obj) +{ + return ((obj->CAN & SIM_CAN_WKUP_SRC_SEL_MASK) >> SIM_CAN_WKUP_SRC_SEL_SHIFT); +} + +/*! \brief Sets the CAN wake up function select signal + * + * This function sets the CAN wake up function select signal . + * + * \param[in] obj : pointer to SIM register instance + * \param[in] value : the value of CAN wake up function select signal + * - 1b : support stop and doze mode. + * - 0b : select not support stop and doze mode. + */ +__attribute__((always_inline)) static inline void SimReg_SetCanWkupSrcSel(SimRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CAN; + + tmp &= ~SIM_CAN_WKUP_SRC_SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << SIM_CAN_WKUP_SRC_SEL_SHIFT)) & SIM_CAN_WKUP_SRC_SEL_MASK); + obj->CAN = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _SIM_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/spi_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/spi_reg.h new file mode 100644 index 0000000..e864bde --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/spi_reg.h @@ -0,0 +1,1708 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _SPI_REG_H_ +#define _SPI_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of SPI module + */ + +/****************************************************************************** + * the includes + *****************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * the defines + *****************************************************************************/ + +/* PARAM Bit fields */ +#define SPI_PARAM_TX_FIFO_DEPTH_MASK (0x000000FFul) +#define SPI_PARAM_TX_FIFO_DEPTH_SHIFT (0u) +#define SPI_PARAM_TX_FIFO_DEPTH_WIDTH (8u) + +#define SPI_PARAM_RX_FIFO_DEPTH_MASK (0x0000FF00ul) +#define SPI_PARAM_RX_FIFO_DEPTH_SHIFT (8u) +#define SPI_PARAM_RX_FIFO_DEPTH_WIDTH (8u) + +/* CR Bit fields */ +#define SPI_CR_EN_MASK (0x00000001ul) +#define SPI_CR_EN_SHIFT (0u) +#define SPI_CR_EN_WIDTH (1u) + +#define SPI_CR_RESET_MASK (0x00000002ul) +#define SPI_CR_RESET_SHIFT (1u) +#define SPI_CR_RESET_WIDTH (1u) + +#define SPI_CR_DOZE_EN_MASK (0x00000004ul) +#define SPI_CR_DOZE_EN_SHIFT (2u) +#define SPI_CR_DOZE_EN_WIDTH (1u) + +#define SPI_CR_DBG_EN_MASK (0x00000008ul) +#define SPI_CR_DBG_EN_SHIFT (3u) +#define SPI_CR_DBG_EN_WIDTH (1u) + +#define SPI_CR_RESET_TXFIFO_MASK (0x00000100ul) +#define SPI_CR_RESET_TXFIFO_SHIFT (8u) +#define SPI_CR_RESET_TXFIFO_WIDTH (1u) + +#define SPI_CR_RESET_RXFIFO_MASK (0x00000200ul) +#define SPI_CR_RESET_RXFIFO_SHIFT (9u) +#define SPI_CR_RESET_RXFIFO_WIDTH (1u) + +/* SR Bit fields */ +#define SPI_SR_TX_DATA_FLAG_MASK (0x00000001ul) +#define SPI_SR_TX_DATA_FLAG_SHIFT (0u) +#define SPI_SR_TX_DATA_FLAG_WIDTH (1u) + +#define SPI_SR_RX_DATA_FLAG_MASK (0x00000002ul) +#define SPI_SR_RX_DATA_FLAG_SHIFT (1u) +#define SPI_SR_RX_DATA_FLAG_WIDTH (1u) + +#define SPI_SR_RX_WORD_DONE_FLAG_MASK (0x00000100ul) +#define SPI_SR_RX_WORD_DONE_FLAG_SHIFT (8u) +#define SPI_SR_RX_WORD_DONE_FLAG_WIDTH (1u) + +#define SPI_SR_FRAME_DONE_FLAG_MASK (0x00000200ul) +#define SPI_SR_FRAME_DONE_FLAG_SHIFT (9u) +#define SPI_SR_FRAME_DONE_FLAG_WIDTH (1u) + +#define SPI_SR_XFR_DONE_FLAG_MASK (0x00000400ul) +#define SPI_SR_XFR_DONE_FLAG_SHIFT (10u) +#define SPI_SR_XFR_DONE_FLAG_WIDTH (1u) + +#define SPI_SR_TX_UF_FLAG_MASK (0x00000800ul) +#define SPI_SR_TX_UF_FLAG_SHIFT (11u) +#define SPI_SR_TX_UF_FLAG_WIDTH (1u) + +#define SPI_SR_RX_OF_FLAG_MASK (0x00001000ul) +#define SPI_SR_RX_OF_FLAG_SHIFT (12u) +#define SPI_SR_RX_OF_FLAG_WIDTH (1u) + +#define SPI_SR_BUSY_FLAG_MASK (0x01000000ul) +#define SPI_SR_BUSY_FLAG_SHIFT (24u) +#define SPI_SR_BUSY_FLAG_WIDTH (1u) + +/* IER Bit fields */ +#define SPI_IER_TX_DATA_IE_MASK (0x00000001ul) +#define SPI_IER_TX_DATA_IE_SHIFT (0u) +#define SPI_IER_TX_DATA_IE_WIDTH (1u) + +#define SPI_IER_RX_DATA_IE_MASK (0x00000002ul) +#define SPI_IER_RX_DATA_IE_SHIFT (1u) +#define SPI_IER_RX_DATA_IE_WIDTH (1u) + +#define SPI_IER_RX_WORD_DONE_IE_MASK (0x00000100ul) +#define SPI_IER_RX_WORD_DONE_IE_SHIFT (8u) +#define SPI_IER_RX_WORD_DONE_IE_WIDTH (1u) + +#define SPI_IER_FRAME_DONE_IE_MASK (0x00000200ul) +#define SPI_IER_FRAME_DONE_IE_SHIFT (9u) +#define SPI_IER_FRAME_DONE_IE_WIDTH (1u) + +#define SPI_IER_MST_TRANSFER_DONE_IE_MASK (0x00000400ul) +#define SPI_IER_MST_TRANSFER_DONE_IE_SHIFT (10u) +#define SPI_IER_MST_TRANSFER_DONE_IE_WIDTH (1u) + +#define SPI_IER_TX_UF_IE_MASK (0x00000800ul) +#define SPI_IER_TX_UF_IE_SHIFT (11u) +#define SPI_IER_TX_UF_IE_WIDTH (1u) + +#define SPI_IER_RX_OF_IE_MASK (0x00001000ul) +#define SPI_IER_RX_OF_IE_SHIFT (12u) +#define SPI_IER_RX_OF_IE_WIDTH (1u) + +#define SPI_IER_ALL_ISR_IE_MASK (0x00001FFFul) +#define SPI_IER_ALL_ISR_IE_SHIFT (0u) +#define SPI_IER_ALL_ISR_IE_WIDTH (13u) + +/* DER Bit fields */ +#define SPI_DER_DMA_TX_EN_MASK (0x00000001ul) +#define SPI_DER_DMA_TX_EN_SHIFT (0u) +#define SPI_DER_DMA_TX_EN_WIDTH (1u) + +#define SPI_DER_DMA_RX_EN_MASK (0x00000002ul) +#define SPI_DER_DMA_RX_EN_SHIFT (1u) +#define SPI_DER_DMA_RX_EN_WIDTH (1u) + +/* CFGR0 Bit fields */ +#define SPI_CFGR0_CIRCULAR_FIFO_EN_MASK (0x00000100ul) +#define SPI_CFGR0_CIRCULAR_FIFO_EN_SHIFT (8u) +#define SPI_CFGR0_CIRCULAR_FIFO_EN_WIDTH (1u) + +/* CFGR1 Bit fields */ +#define SPI_CFGR1_MASTER_EN_MASK (0x00000001ul) +#define SPI_CFGR1_MASTER_EN_SHIFT (0u) +#define SPI_CFGR1_MASTER_EN_WIDTH (1u) + +#define SPI_CFGR1_AUTO_PCS_MASK (0x00000004ul) +#define SPI_CFGR1_AUTO_PCS_SHIFT (2u) +#define SPI_CFGR1_AUTO_PCS_WIDTH (1u) + +#define SPI_CFGR1_NO_STALL_MASK (0x00000008ul) +#define SPI_CFGR1_NO_STALL_SHIFT (3u) +#define SPI_CFGR1_NO_STALL_WIDTH (1u) + +#define SPI_CFGR1_MST_SCK_DLY_MASK (0x00000070ul) +#define SPI_CFGR1_MST_SCK_DLY_SHIFT (4u) +#define SPI_CFGR1_MST_SCK_DLY_WIDTH (3u) + +#define SPI_CFGR1_PCS_POL_MASK (0x00000F00ul) +#define SPI_CFGR1_PCS_POL_SHIFT (8u) +#define SPI_CFGR1_PCS_POL_WIDTH (4u) + +#define SPI_CFGR1_PIN_CFG_MASK (0x03000000ul) +#define SPI_CFGR1_PIN_CFG_SHIFT (24u) +#define SPI_CFGR1_PIN_CFG_WIDTH (2u) + +#define SPI_CFGR1_OUT_CFG_MASK (0x04000000ul) +#define SPI_CFGR1_OUT_CFG_SHIFT (26u) +#define SPI_CFGR1_OUT_CFG_WIDTH (1u) + +/* CCR Bit fields */ +#define SPI_CCR_SCK_DIV_MASK (0x000000FFul) +#define SPI_CCR_SCK_DIV_SHIFT (0u) +#define SPI_CCR_SCK_DIV_WIDTH (8u) + +#define SPI_CCR_DBT_MASK (0x0000FF00ul) +#define SPI_CCR_DBT_SHIFT (8u) +#define SPI_CCR_DBT_WIDTH (8u) + +#define SPI_CCR_PCS_SCK_MASK (0x00FF0000ul) +#define SPI_CCR_PCS_SCK_SHIFT (16u) +#define SPI_CCR_PCS_SCK_WIDTH (8u) + +#define SPI_CCR_SCK_PCS_MASK (0xFF000000ul) +#define SPI_CCR_SCK_PCS_SHIFT (24u) +#define SPI_CCR_SCK_PCS_WIDTH (8u) + +/* FCR Bit fields */ +#define SPI_FCR_TX_FIFO_WATER_MASK (0x0000001Ful) +#define SPI_FCR_TX_FIFO_WATER_SHIFT (0u) +#define SPI_FCR_TX_FIFO_WATER_WIDTH (5u) + +#define SPI_FCR_RX_FIFO_WATER_MASK (0x001F0000ul) +#define SPI_FCR_RX_FIFO_WATER_SHIFT (16u) +#define SPI_FCR_RX_FIFO_WATER_WIDTH (5u) + +/* FSR Bit fields */ +#define SPI_FSR_TX_FIFO_CNT_MASK (0x0000001Ful) +#define SPI_FSR_TX_FIFO_CNT_SHIFT (0u) +#define SPI_FSR_TX_FIFO_CNT_WIDTH (5u) + +#define SPI_FSR_RX_FIFO_CNT_MASK (0x001F0000ul) +#define SPI_FSR_RX_FIFO_CNT_SHIFT (16u) +#define SPI_FSR_RX_FIFO_CNT_WIDTH (5u) + +/* TCR Bit fields */ +#define SPI_TCR_FRAME_SIZE_MASK (0x00000FFFul) +#define SPI_TCR_FRAME_SIZE_SHIFT (0u) +#define SPI_TCR_FRAME_SIZE_WIDTH (12u) + +#define SPI_TCR_TRANSFER_WIDTH_MASK (0x00030000ul) +#define SPI_TCR_TRANSFER_WIDTH_SHIFT (16u) +#define SPI_TCR_TRANSFER_WIDTH_WIDTH (2u) + +#define SPI_TCR_TX_MASK_MASK (0x00040000ul) +#define SPI_TCR_TX_MASK_SHIFT (18u) +#define SPI_TCR_TX_MASK_WIDTH (1u) + +#define SPI_TCR_RX_MASK_MASK (0x00080000ul) +#define SPI_TCR_RX_MASK_SHIFT (19u) +#define SPI_TCR_RX_MASK_WIDTH (1u) + +#define SPI_TCR_CONTINUE_CMD_MASK (0x00100000ul) +#define SPI_TCR_CONTINUE_CMD_SHIFT (20u) +#define SPI_TCR_CONTINUE_CMD_WIDTH (1u) + +#define SPI_TCR_CONTINUE_TRANSFER_MASK (0x00200000ul) +#define SPI_TCR_CONTINUE_TRANSFER_SHIFT (21u) +#define SPI_TCR_CONTINUE_TRANSFER_WIDTH (1u) + +#define SPI_TCR_BYTE_SWAP_MASK (0x00400000ul) +#define SPI_TCR_BYTE_SWAP_SHIFT (22u) +#define SPI_TCR_BYTE_SWAP_WIDTH (1u) + +#define SPI_TCR_LSB_FIRST_MASK (0x00800000ul) +#define SPI_TCR_LSB_FIRST_SHIFT (23u) +#define SPI_TCR_LSB_FIRST_WIDTH (1u) + +#define SPI_TCR_PCS_SEL_MASK (0x03000000ul) +#define SPI_TCR_PCS_SEL_SHIFT (24u) +#define SPI_TCR_PCS_SEL_WIDTH (2u) + +#define SPI_TCR_PRESCALER_MASK (0x38000000ul) +#define SPI_TCR_PRESCALER_SHIFT (27u) +#define SPI_TCR_PRESCALER_WIDTH (3u) + +#define SPI_TCR_CPHA_MASK (0x40000000ul) +#define SPI_TCR_CPHA_SHIFT (30u) +#define SPI_TCR_CPHA_WIDTH (1u) + +#define SPI_TCR_CPOL_MASK (0x80000000ul) +#define SPI_TCR_CPOL_SHIFT (31u) +#define SPI_TCR_CPOL_WIDTH (1u) + +/* TDR Bit fields */ +#define SPI_TDR_DATA_MASK (0xFFFFFFFFul) +#define SPI_TDR_DATA_SHIFT (0u) +#define SPI_TDR_DATA_WIDTH (32u) + +/* RSR Bit fields */ +#define SPI_RSR_SOF_MASK (0x00000001ul) +#define SPI_RSR_SOF_SHIFT (0u) +#define SPI_RSR_SOF_WIDTH (1u) + +#define SPI_RSR_RX_FIFO_EMPTY_MASK (0x00000002ul) +#define SPI_RSR_RX_FIFO_EMPTY_SHIFT (1u) +#define SPI_RSR_RX_FIFO_EMPTY_WIDTH (1u) + +/* RDR Bit fields */ +#define SPI_RDR_DATA_MASK (0xFFFFFFFFul) +#define SPI_RDR_DATA_SHIFT (0u) +#define SPI_RDR_DATA_WIDTH (32u) + +/****************************************************************************** + * the typedefs + *****************************************************************************/ + +/*! \brief the definition of spi register */ +typedef struct _SpiRegType_ +{ + volatile uint32_t VERID; /*!< SPI Version ID Register, offset: 0x00 */ + volatile uint32_t PARAM; /*!< SPI Parameters Register, offset: 0x04 */ + uint32_t RES1[2]; /*!< SPI Res, offset: 0x08 */ + volatile uint32_t CR; /*!< SPI Control Register, offset: 0x10 */ + volatile uint32_t SR; /*!< SPI Status Register, offset: 0x14 */ + volatile uint32_t IER; /*!< SPI Interrupt Enable Register, offset: 0x18 */ + volatile uint32_t DER; /*!< SPI DMA control Register, offset: 0x1C */ + volatile uint32_t CFGR0; /*!< SPI Configuration 0 Register, offset: 0x20 */ + volatile uint32_t CFGR1; /*!< SPI Configuration 1 Register, offset: 0x24 */ + uint32_t RES2[6]; /*!< SPI Res, offset: 0x28 */ + volatile uint32_t CCR; /*!< SPI Clock Configuration Register, offset: 0x40 */ + uint32_t RES3[5]; /*!< SPI Res Register, offset: 0x44 */ + volatile uint32_t FCR; /*!< SPI FIFO Control Register, offset: 0x58 */ + volatile uint32_t FSR; /*!< SPI FIFO Status Register, offset: 0x5C */ + volatile uint32_t TCR; /*!< SPI Transmit Control Register, offset: 0x60 */ + volatile uint32_t TDR; /*!< SPI Transmit Data Register, offset: 0x64 */ + uint32_t RES4[2]; /*!< SPI Res Register, offset: 0x68 */ + volatile uint32_t RSR; /*!< SPI Receive Status Register, offset: 0x70 */ + volatile uint32_t RDR; /*!< SPI Receive Data Register, offset: 0x74 */ +} SpiRegType; + +/****************************************************************************** + * the globals + *****************************************************************************/ + +/****************************************************************************** + * the function prototypes + *****************************************************************************/ + +/*! \brief Get the tx fifo depth size that the hardware supports + * + * this function get the tx fifo depth how many the hardware supported + * + * \param[in] obj : base address for the SPI instance + * \return: uint8_t : Real depth = 2^(TX_FIFO_DEPTH) + * 0h:1 + * 1h:2 + * 2h:4 + * 3h:8 + * 4h:16 + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetTxFifoDepth(SpiRegType *obj) +{ + uint8_t tRtn = 0; + uint8_t tFifoDepth[5] = {1, 2, 4, 8, 16}; + + tRtn = (((obj->PARAM & SPI_PARAM_TX_FIFO_DEPTH_MASK) >> SPI_PARAM_TX_FIFO_DEPTH_SHIFT) & 0xFF); + tRtn = tRtn < 4 ? tRtn : 4; + + return tFifoDepth[tRtn]; +} + +/*! \brief Get the rx fifo depth size that the hardware supports + * + * this function get the rx fifo depth how many the hardware supported + * + * \param[in] obj : base address for the SPI instance + * \return: uint8_t : Real depth = 2^(RX_FIFO_DEPTH) + * 0h:1 + * 1h:2 + * 2h:4 + * 3h:8 + * 4h:16 + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetRxFifoDepth(const SpiRegType *obj) +{ + uint8_t tRtn = 0; + uint8_t tFifoDepth[5] = {1, 2, 4, 8, 16}; + + tRtn = (((obj->PARAM & SPI_PARAM_RX_FIFO_DEPTH_MASK) >> SPI_PARAM_RX_FIFO_DEPTH_SHIFT) & 0xFF); + tRtn = tRtn < 4 ? tRtn : 4; + + return tFifoDepth[tRtn]; +} + +/*! \brief spi module enable + * + * this function enable the module + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable : enable or disable module + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_EnableModule(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->CR; + + if(enable == true) + { + obj->CR = ((1ul << SPI_CR_EN_SHIFT) | ((~SPI_CR_EN_MASK) & tRegValue)); + } + else + { + obj->CR = ((0ul << SPI_CR_EN_SHIFT) | ((~SPI_CR_EN_MASK) & tRegValue)); + } +} + +/*! \brief module software reset + * + * Reset all internal logic and registers, except the Control Register. + * RST remains set until cleared by software. + * + * \param[in] obj: base address for the SPI instance + * \param[in] reset: enable or disable reset module + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_ResetModule(SpiRegType *obj, bool reset) +{ + uint32_t tRegValue = obj->CR; + + if(reset == true) + { + obj->CR = ((1ul << SPI_CR_RESET_SHIFT) | ((~SPI_CR_RESET_MASK) & tRegValue)); + } + else + { + obj->CR = ((0ul << SPI_CR_RESET_SHIFT) | ((~SPI_CR_RESET_MASK) & tRegValue)); + } +} + +/*! \brief STOP/DEBUG Mode Enable + * + * Enables or disables the SPI module in STOP and DEBUG mode. + * This bit should be updated only when the SPI module is disabled. + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: enable or disable doze mode + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_EnableDozeMode(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->CR; + + if(enable == true) + { + obj->CR = ((1ul << SPI_CR_DOZE_EN_SHIFT) | ((~SPI_CR_DOZE_EN_MASK) & tRegValue)); + } + else + { + obj->CR = ((0ul << SPI_CR_DOZE_EN_SHIFT) | ((~SPI_CR_DOZE_EN_MASK) & tRegValue)); + } +} + +/*! \brief Debug Enable + * + * Enables or disables the SPI module in debug mode. + * Debug Enable bit should be updated only when the SPI module is disabled. + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: enable or disable debug mode + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_EnableDebugMode(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->CR; + + if(enable == true) + { + obj->CR = ((1ul << SPI_CR_DBG_EN_SHIFT) | ((~SPI_CR_DBG_EN_MASK) & tRegValue)); + } + else + { + obj->CR = ((0ul << SPI_CR_DBG_EN_SHIFT) | ((~SPI_CR_DBG_EN_MASK) & tRegValue)); + } +} + +/*! \brief Reset Transmit FIFO + * + * the bit is WO + * + * \param[in] obj: base address for the SPI instance + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_ResetTxFIFO(SpiRegType *obj) +{ + uint32_t tRegValue = obj->CR; + + obj->CR = ((1ul << SPI_CR_RESET_TXFIFO_SHIFT) | ((~SPI_CR_RESET_TXFIFO_MASK) & tRegValue)); +} + +/*! \brief Reset Receive FIFO + * + * the bit is WO + * + * \param[in] obj: base address for the SPI instance + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_ResetRxFIFO(SpiRegType *obj) +{ + uint32_t tRegValue = obj->CR; + + obj->CR = ((1ul << SPI_CR_RESET_RXFIFO_SHIFT) | ((~SPI_CR_RESET_RXFIFO_MASK) & tRegValue)); +} + +/*! \brief Transmit Data Flag + * + * The Transmit Data Flag is set whenever the number of words in the transmit FIFO is equal or less than FCR[TXWATER] + * (FIFO Control Register) + * + * \param[in] obj: base address for the SPI instance + * \return: uint8_t + * 0b - Transmit data not requested + * 1b - Transmit data is requested + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetTxDataFlag(const SpiRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = ((obj->SR & SPI_SR_TX_DATA_FLAG_MASK) >> SPI_SR_TX_DATA_FLAG_SHIFT) & 0xFF; + + return tRtn; +} + +/*! \brief Receive Data Flag + * + * The Receive Data Flag is set whenever the number of words in the receive FIFO is greater than + * FCR[RXWATER] (FIFO Control Register) + * + * \param[in] obj: base address for the SPI instance + * \return: uint8_t + * 0b - Receive Data is not ready + * 1b - Receive data is ready + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetRxDataFlag(const SpiRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->SR & SPI_SR_RX_DATA_FLAG_MASK) >> SPI_SR_RX_DATA_FLAG_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Get Receive Word Complete Flag + * + * The Word Complete Flag will set when the last bit of a received word is sampled. + * + * \param[in] obj: base address for the SPI instance + * \return: uint8_t + * 0b : Transfer of a received word has not yet completed + * 1b : Transfer of a received word has completed + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetRxWordDoneFlag(const SpiRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->SR & SPI_SR_RX_WORD_DONE_FLAG_MASK) >> SPI_SR_RX_WORD_DONE_FLAG_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Clear Receive Word Complete Flag + * + * this flag is clear by write one to the referenced bit + * + * \param[in] obj: base address for the SPI instance + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_ClearRxWordDoneFlag(SpiRegType *obj) +{ + obj->SR |= SPI_SR_RX_WORD_DONE_FLAG_MASK; +} + +/*! \brief Get Frame Complete Flag + * + * The Frame Complete Flag will set at the end of each frame transfer. + * + * \param[in] obj: base address for the SPI instance + * \return: uint8_t + * 0b : Frame transfer has not completed + * 1b : Frame transfer has completed + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetFrameDoneFlag(const SpiRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->SR & SPI_SR_FRAME_DONE_FLAG_MASK) >> SPI_SR_FRAME_DONE_FLAG_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Clear Frame Complete Flag + * + * this flag is clear by write one to the referenced bit + * + * \param[in] obj: base address for the SPI instance + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_ClearFrameDoneFlag(SpiRegType *obj) +{ + obj->SR |= SPI_SR_FRAME_DONE_FLAG_MASK; +} + +/*! \brief Get Master Transfer Complete Flag + * + * In master mode when the SPI returns to idle state,when the PCS negates, + the Transfer Complete Flag will set. + * + * \param[in] obj: base address for the SPI instance + * \return: uint8_t + * 0b : All transfers have not completed + * 1b : All transfers have completed + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetMasterTransferDoneFlag(const SpiRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->SR & SPI_SR_XFR_DONE_FLAG_MASK) >> SPI_SR_XFR_DONE_FLAG_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Clear Master Transfer Complete Flag + * + * this flag is clear by write one to the referenced bit + * + * \param[in] obj: base address for the SPI instance + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_ClearMasterTransferDoneFlag(SpiRegType *obj) +{ + obj->SR |= SPI_SR_XFR_DONE_FLAG_MASK; +} + +/*! \brief Get Transmit FIFO underflow Flag + * + * The Transmit Error Flag will set when the Transmit FIFO under runs + * + * \param[in] obj: base address for the SPI instance + * \return: uint8_t + * 0b : Transmit FIFO underrun has not occurred + * 1b : Transmit FIFO underrun has occurred + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetTxUnderFlowFlag(const SpiRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->SR & SPI_SR_TX_UF_FLAG_MASK) >> SPI_SR_TX_UF_FLAG_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Clear Transmit FIFO underflow Flag + * + * this flag is clear by write one to the referenced bit + * + * \param[in] obj: base address for the SPI instance + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_ClearTxUnderFlowFlag(SpiRegType *obj) +{ + obj->SR |= SPI_SR_TX_UF_FLAG_MASK; +} + +/*! \brief Get RX FIFO overflow flag + * + * The Receive Error Flag will set when the Receiver FIFO overflows. When the Receive Error Flag is set + * + * \param[in] obj: base address for the SPI instance + * \return: uint8_t + * 0b : Receive FIFO has not overflowed + * 1b : Receive FIFO has overflowed + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetRxOverFlowFlag(const SpiRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->SR & SPI_SR_RX_OF_FLAG_MASK) >> SPI_SR_RX_OF_FLAG_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Clear RX FIFO overflow flag + * + * this flag is clear by write one to the referenced bit + * + * \param[in] obj: base address for the SPI instance + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_ClearRxOverFlowFlag(SpiRegType *obj) +{ + obj->SR |= SPI_SR_RX_OF_FLAG_MASK; +} + +/*! \brief Module Busy Flag + * + * this function get the current status about the module + * + * \param[in] obj: base address for the SPI instance + * \return: uint8_t + * 0b : SPI is idle + * 1b : SPI is busy + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetBusyFlag(const SpiRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->SR & SPI_SR_BUSY_FLAG_MASK) >> SPI_SR_BUSY_FLAG_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief RX FIFO overflow interrupt enable or disable + * + * this function enable the rx overflow interrupt request if the condition is matched + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: RX FIFO overflow interrupt enable + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetRxOverflowIsr(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->IER; + + if(enable == true) + { + obj->IER = ((1ul << SPI_IER_RX_OF_IE_SHIFT) | ((~SPI_IER_RX_OF_IE_MASK) & tRegValue)); + } + else + { + obj->IER = ((0ul << SPI_IER_RX_OF_IE_SHIFT) | ((~SPI_IER_RX_OF_IE_MASK) & tRegValue)); + } +} + +/*! \brief Transmit FIFO underflow interrupt enable or disable + * + * this function enable the tx underflow interrupt request if the condition is matched + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: Transmit FIFO underflow interrupt enable + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetTxUnderflowIsr(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->IER; + + if(enable == true) + { + obj->IER = ((1ul << SPI_IER_TX_UF_IE_SHIFT) | ((~SPI_IER_TX_UF_IE_MASK) & tRegValue)); + } + else + { + obj->IER = ((0ul << SPI_IER_TX_UF_IE_SHIFT) | ((~SPI_IER_TX_UF_IE_MASK) & tRegValue)); + } +} + +/*! \brief Master Transfer Complete interrupt enable or disable + * + * this function enable the tx transfer done interrupt request if the condition is matched + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: Master Transfer Complete interrupt enable + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetTxTransferDoneIsr(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->IER; + + if(enable == true) + { + obj->IER = ((1ul << SPI_IER_MST_TRANSFER_DONE_IE_SHIFT) | ((~SPI_IER_MST_TRANSFER_DONE_IE_MASK) & tRegValue)); + } + else + { + obj->IER = ((0ul << SPI_IER_MST_TRANSFER_DONE_IE_SHIFT) | ((~SPI_IER_MST_TRANSFER_DONE_IE_MASK) & tRegValue)); + } +} + +/*! \brief Master Transfer Complete interrupt enable or disable + * + * this function enable the frame done interrupt request if the condition is matched + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: Frame Complete interrupt enable + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetFrameDoneIsr(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->IER; + + if(enable == true) + { + obj->IER = ((1ul << SPI_IER_FRAME_DONE_IE_SHIFT) | ((~SPI_IER_FRAME_DONE_IE_MASK) & tRegValue)); + } + else + { + obj->IER = ((0ul << SPI_IER_FRAME_DONE_IE_SHIFT) | ((~SPI_IER_FRAME_DONE_IE_MASK) & tRegValue)); + } +} + +/*! \brief Receive Word Complete interrupt enable or disable + * + * this function enable the rx word done interrupt request if the condition is matched + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: Receive Word Complete interrupt enable + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetRxWordDoneIsr(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->IER; + + if(enable == true) + { + obj->IER = ((1ul << SPI_IER_RX_WORD_DONE_IE_SHIFT) | ((~SPI_IER_RX_WORD_DONE_IE_MASK) & tRegValue)); + } + else + { + obj->IER = ((0ul << SPI_IER_RX_WORD_DONE_IE_SHIFT) | ((~SPI_IER_RX_WORD_DONE_IE_MASK) & tRegValue)); + } +} + +/*! \brief Receive Data interrupt enable + * + * this function enable the rx data interrupt request if the condition is matched + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: Receive Data interrupt enable + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetRxDataIsr(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->IER; + + if(enable == true) + { + obj->IER = ((1ul << SPI_IER_RX_DATA_IE_SHIFT) | ((~SPI_IER_RX_DATA_IE_MASK) & tRegValue)); + } + else + { + obj->IER = ((0ul << SPI_IER_RX_DATA_IE_SHIFT) | ((~SPI_IER_RX_DATA_IE_MASK) & tRegValue)); + } +} + +/*! \brief Transmit Data interrupt enable or disable + * + * this function enable the tx data interrupt request if the condition is matched + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: Transmit Data interrupt enable + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetTxDataIsr(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->IER; + + if(enable == true) + { + obj->IER = ((1ul << SPI_IER_TX_DATA_IE_SHIFT) | ((~SPI_IER_TX_DATA_IE_MASK) & tRegValue)); + } + else + { + obj->IER = ((0ul << SPI_IER_TX_DATA_IE_SHIFT) | ((~SPI_IER_TX_DATA_IE_MASK) & tRegValue)); + } +} + +/*! \brief Enable the interrupt request with combination + * + * this function enable the interrupt request with the intMask + * + * \param[in] obj :: base address for the SPI instance + * \param[in] intMask : which interrupt request to be operated + * example : SPI_IER_RX_DATA_IE_MASK | SPI_IER_TX_DATA_IE_MASK + * \param[in] enable : enable or disable + * \return void + */ +__attribute__((always_inline)) static inline void SpiReg_EnableIntReq(SpiRegType *obj, uint32_t intMask, bool enable) +{ + uint32_t tRegValue = obj->IER; + + if(enable == true) + { + obj->IER = (intMask | ((~intMask) & tRegValue)); + } + else + { + obj->IER = ((~intMask) & tRegValue); + } +} + +/*! \brief Get the interrupt request is enabled or not + * + * this function enable the interrupt request with the intMask + * + * \param[in] obj :: base address for the SPI instance + * \param[in] intMask : which interrupt request to be operated + * \return bool + * true: the interrupt is enabled + * false: the interrupt is disabled + */ +__attribute__((always_inline)) static inline bool SpiReg_GetIntReqEnableState(const SpiRegType *obj, uint32_t intMask) +{ + bool tRtn = false; + + if((obj->IER & intMask) == intMask) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief receive dma enable or disable + * + * this function enable the rx with dma method + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: receive dma enable + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetRxDMA(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->DER; + + if(enable == true) + { + obj->DER = ((1ul << SPI_DER_DMA_RX_EN_SHIFT) | ((~SPI_DER_DMA_RX_EN_MASK) & tRegValue)); + } + else + { + obj->DER = ((0ul << SPI_DER_DMA_RX_EN_SHIFT) | ((~SPI_DER_DMA_RX_EN_MASK) & tRegValue)); + } +} + +/*! \brief transmit dma enable or disable + * + * this function enable the tx with dma method + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: transmit dma enable + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetTxDMA(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->DER; + + if(enable == true) + { + obj->DER = ((1ul << SPI_DER_DMA_TX_EN_SHIFT) | ((~SPI_DER_DMA_TX_EN_MASK) & tRegValue)); + } + else + { + obj->DER = ((0ul << SPI_DER_DMA_TX_EN_SHIFT) | ((~SPI_DER_DMA_TX_EN_MASK) & tRegValue)); + } +} + +/*! \brief Set Clock Polarity + * + * The Clock Polarity field is only updated when PCS negated. + * + * \param[in] obj : base address for the SPI instance + * \param[in] clockPolarity : + * 0b : The inactive state value of SCK is low + * 1b : The inactive state value of SCK is high + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetClockPolarity(SpiRegType *obj, uint8_t clockPolarity) +{ + uint32_t tmp = obj->TCR; + + tmp &= ~SPI_TCR_CPOL_MASK; + tmp |= (((uint32_t)(((uint32_t)(clockPolarity)) << SPI_TCR_CPOL_SHIFT)) & SPI_TCR_CPOL_MASK); + obj->TCR = tmp; +} + +/*! \brief Set Clock Phase + * + * The Clock Phase field is only updated when PCS negated. + * + * \param[in] obj : base address for the SPI instance + * \param[in] clockPhase : + * 0b : Data is captured on the leading edge of SCK and changed on the following edge of SCK + * 1b : Data is changed on the leading edge of SCK and captured on the following edge of SCK + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetClockPhase(SpiRegType *obj, uint8_t clockPhase) +{ + uint32_t tmp = obj->TCR; + + tmp &= ~SPI_TCR_CPHA_MASK; + tmp |= (((uint32_t)(((uint32_t)(clockPhase)) << SPI_TCR_CPHA_SHIFT)) & SPI_TCR_CPHA_MASK); + obj->TCR = tmp; +} + +/*! \brief Set Prescaler Value + * + * For all SPI bus transfers, the Prescaler value applied to the clock configuration register. The Prescaler Value field is only updated when PCS negated. + * + * \param[in] obj : base address for the SPI instance + * \param[in] prescaler : + * 000b : Divide by 1 + * 001b : Divide by 2 + * 010b : Divide by 4 + * 011b : Divide by 8 + * 100b : Divide by 16 + * 101b : Divide by 32 + * 110b : Divide by 64 + * 111b : Divide by 128 + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetPrescaler(SpiRegType *obj, uint8_t prescaler) +{ + uint32_t tmp = obj->TCR; + + tmp &= ~SPI_TCR_PRESCALER_MASK; + tmp |= (((uint32_t)(((uint32_t)(prescaler)) << SPI_TCR_PRESCALER_SHIFT)) & SPI_TCR_PRESCALER_MASK); + obj->TCR = tmp; +} + +/*! \brief Select Peripheral Chip + * + * Configures the peripheral chip select used for the transfer. The Peripheral Chip Select field is only updated when PCS negated. + * + * \param[in] obj : base address for the SPI instance + * \param[in] pcsSelection : + * 00b : Transfer using SPI_PCS[0] + * 01b : Transfer using SPI_PCS[1] + * 10b : Transfer using SPI_PCS[2] + * 11b : Transfer using SPI_PCS[3] + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetPcsSelection(SpiRegType *obj, uint8_t pcsSelection) +{ + uint32_t tmp = obj->TCR; + + tmp &= ~SPI_TCR_PCS_SEL_MASK; + tmp |= (((uint32_t)(((uint32_t)(pcsSelection)) << SPI_TCR_PCS_SEL_SHIFT)) & SPI_TCR_PCS_SEL_MASK); + obj->TCR = tmp; +} + +/*! \brief Set data transfer bit direction + * + * Note: + * + * \param[in] obj : base address for the SPI instance + * \param[in] lsbFirst : + * 0b:Data is transferred MSB first + * 1b:Data is transferred LSB first + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetLowBitFirstTransfer(SpiRegType *obj, uint8_t lsbFirst) +{ + uint32_t tmp = obj->TCR; + + tmp &= ~SPI_TCR_LSB_FIRST_MASK; + tmp |= (((uint32_t)(((uint32_t)(lsbFirst)) << SPI_TCR_LSB_FIRST_SHIFT)) & SPI_TCR_LSB_FIRST_MASK); + obj->TCR = tmp; +} + +/*! \brief Get data transfer bit direction + * + * + * + * \param[in] obj: base address for the SPI instance + * \return: transfer bit direction + * 0b:Data is transferred MSB first + * 1b:Data is transferred LSB first + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetTransferDataBitLsbState(const SpiRegType *obj) +{ + uint8_t tRtn = 0; + + if((obj->TCR & SPI_TCR_LSB_FIRST_MASK) != 0u) + { + tRtn = 1; + } + + return tRtn; +} + +/*! \brief Set Byte Swap + * + * Byte swap will swap the contents of [31:24] with [7:0] and [23:16] with [15:8] for each transmit data word read from + * the FIFO and for each received data word stored to the FIFO + * + * \param[in] obj : base address for the SPI instance + * \param[in] enable : + * 0b:Byte swap is disabled + * 1b:Byte swap is enabled + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetByteSwap(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->TCR; + + if(enable == true) + { + obj->TCR = ((1ul << SPI_TCR_BYTE_SWAP_SHIFT) | ((~SPI_TCR_BYTE_SWAP_MASK) & tRegValue)); + } + else + { + obj->TCR = ((0ul << SPI_TCR_BYTE_SWAP_SHIFT) | ((~SPI_TCR_BYTE_SWAP_MASK) & tRegValue)); + } +} + +/*! \brief Set Continuous Transfer + * + * In master mode, continuous transfer will keep the PCS asserted at the end of the frame size, + * until a command word is received that starts a new frame. + * In slave mode, when continuous transfer is enabled, the SPI will only transmit the first FRAMESZ bits; + * after which the SPI will transmit received data (assuming a 32-bit shift register) until the next PCS negation. + * + * \param[in] obj : base address for the SPI instance + * \param[in] enable : + * 0b:Continuous transfer is disabled + * 1b:Continuous transfer is enabled + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetContinuousTransfer(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->TCR; + + if(enable == true) + { + obj->TCR = ((1ul << SPI_TCR_CONTINUE_TRANSFER_SHIFT) | ((~SPI_TCR_CONTINUE_TRANSFER_MASK) & tRegValue)); + } + else + { + obj->TCR = ((0ul << SPI_TCR_CONTINUE_TRANSFER_SHIFT) | ((~SPI_TCR_CONTINUE_TRANSFER_MASK) & tRegValue)); + } +} + +/*! \brief Set Continuing Command + * + * In master mode, the Continuing Command bit allows the command word to be changed within a transfer. + * 1. in continuous transfer + * The initial command word must enable continuous transfer (CONT=1), + * the continuing command must set this bit (CONTC=1), + * the continuing command word must be loaded on a frame size boundary. + * 2. in non-continuous transfer + * the continuing command must set this bit (CONTC=1), + * the continuing command word must be loaded on a frame size boundary. + * + * \param[in] obj : base address for the SPI instance + * \param[in] cmd : + * 0b:Command word for start of new transfer + * 1b:Command word for continuing transfer + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetContinuousCmd(SpiRegType *obj, uint8_t cmd) +{ + uint32_t tmp = obj->TCR; + + tmp &= ~SPI_TCR_CONTINUE_CMD_MASK; + tmp |= (((uint32_t)(((uint32_t)(cmd)) << SPI_TCR_CONTINUE_CMD_SHIFT)) & SPI_TCR_CONTINUE_CMD_MASK); + obj->TCR = tmp; +} + +/*! \brief Set Receive Data Mask + * + * When set, receive data is masked (receive data is not stored in receive FIFO). + * + * \param[in] obj : base address for the SPI instance + * \param[in] enableMask : + * 0b:Normal transfer + * 1b:Receive data is masked + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetRxDataMask(SpiRegType *obj, bool enableMask) +{ + uint32_t tRegValue = obj->TCR; + + if(enableMask == true) + { + obj->TCR = ((1ul << SPI_TCR_RX_MASK_SHIFT) | ((~SPI_TCR_RX_MASK_MASK) & tRegValue)); + } + else + { + obj->TCR = ((0ul << SPI_TCR_RX_MASK_SHIFT) | ((~SPI_TCR_RX_MASK_MASK) & tRegValue)); + } +} + +/*! \brief Set Transmit Data Mask + * + * When set, transmit data is masked (no data is loaded from transmit FIFO and output pin is tristated). + * In master mode, the Transmit Data Mask bit will initiate a new transfer + * which cannot be aborted by another command word; TXMSK bit will be cleared by hardware at the end of the transfer. + * + * \param[in] obj : base address for the SPI instance + * \param[in] enableMask : + * 0b:Normal transfer + * 1b:Mask transmit data + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetTxDataMask(SpiRegType *obj, bool enableMask) +{ + uint32_t tRegValue = obj->TCR; + + if(enableMask == true) + { + obj->TCR = ((1ul << SPI_TCR_TX_MASK_SHIFT) | ((~SPI_TCR_TX_MASK_MASK) & tRegValue)); + } + else + { + obj->TCR = ((0ul << SPI_TCR_TX_MASK_SHIFT) | ((~SPI_TCR_TX_MASK_MASK) & tRegValue)); + } +} + +/*! \brief Set Transfer data Width + * + * Configures between serial (1-bit) or parallel transfers. For half-duplex parallel transfers, either Receive Data Mask (RXMSK) or Transmit Data Mask (TXMSK) must be set. + * + * \param[in] obj : base address for the SPI instance + * \param[in] transferWidth : + * 00b:1 bit transfer + * 01b:2 bit transfer + * 10b:Reserved + * 11b:Reserved + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetTransferWidth(SpiRegType *obj, uint8_t transferWidth) +{ + uint32_t tmp = obj->TCR; + + tmp &= ~SPI_TCR_TRANSFER_WIDTH_MASK; + tmp |= (((uint32_t)(((uint32_t)(transferWidth)) << SPI_TCR_TRANSFER_WIDTH_SHIFT)) & SPI_TCR_TRANSFER_WIDTH_MASK); + obj->TCR = tmp; +} + +/*! \brief Set Frame Size + * + * The minimum frame size is 8 bits, The minimum word size is 2 bits; a frame size of 33 bits (or similar) is not supported. + * If the frame size is larger than 32 bits, then the frame is divided into multiple words of 32-bits; + * each word is loaded from the transmit FIFO and stored in the receive FIFO separately. + * If the size of the frame is not divisible by 32, then the last load of the transmit FIFO and store of the receive FIFO will contain the remainder bits. + * For example, a 72-bit transfer will consist of 3 words: the 1st and 2nd words are 32 bits, and the 3rd word is 8 bits. + * + * \param[in] obj : base address for the SPI instance + * \param[in] frameSize :Configures the frame size in number of bits equal to (FRAMESZ + 1) + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetFrameSize(SpiRegType *obj, uint16_t frameSize) +{ + uint32_t tmp = obj->TCR; + + tmp &= ~SPI_TCR_FRAME_SIZE_MASK; + tmp |= (((uint32_t)(((uint32_t)(frameSize)) << SPI_TCR_FRAME_SIZE_SHIFT)) & SPI_TCR_FRAME_SIZE_MASK); + obj->TCR = tmp; +} + +/*! \brief Get Frame Size + * + * \param[in] obj : base address for the SPI instance + * \return : Return the frame size in number of bits equal to (FRAMESZ + 1) + */ +__attribute__((always_inline)) static inline uint16_t SpiReg_GetFrameSize(const SpiRegType *obj) +{ + uint16_t tRtn = 0; + + tRtn = ((obj->TCR & SPI_TCR_FRAME_SIZE_MASK) >> SPI_TCR_FRAME_SIZE_SHIFT); + return tRtn; +} + +/*! \brief Transmit Command config + * + * this function config the clock polarity, clock phase prescaler value and transfer mode .... + * + * \param[in] obj: base address for the SPI instance + * \param[in] tcr: Transmit Command + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetTcr(SpiRegType *obj, uint32_t tcr) +{ + obj->TCR = tcr; +} + +/*! \brief Get Transmit Command config + * + * this function config get the clock polarity, clock phase prescaler value and transfer mode .... + * + * \param[in] obj: base address for the SPI instance + * \return: Transmit Command + */ +__attribute__((always_inline)) static inline uint32_t SpiReg_GetTcr(const SpiRegType *obj) +{ + return obj->TCR; +} + +/*! \brief Circular FIFO Enable or disable + * + * this function enable the tx circular fifo mode + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: + * 0b : disabled + * 1b : enabled + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetCircularFIFO(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->CFGR0; + + if(enable == true) + { + obj->CFGR0 = ((1ul << SPI_CFGR0_CIRCULAR_FIFO_EN_SHIFT) | ((~SPI_CFGR0_CIRCULAR_FIFO_EN_MASK) & tRegValue)); + } + else + { + obj->CFGR0 = ((0ul << SPI_CFGR0_CIRCULAR_FIFO_EN_SHIFT) | ((~SPI_CFGR0_CIRCULAR_FIFO_EN_MASK) & tRegValue)); + } +} + +/*! \brief Output Configuration + * + * Configures if the output data is tristate between accesses (SPI_PCS is negated). If performing half- + * duplex transfers, this bit must be set. + * + * \param[in] obj: base address for the SPI instance + * \param[in] enableTristate + * false : Output data retains last value when PCS is negated + * true : Output data is tristate when PCS is negated + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetOutCfg(SpiRegType *obj, bool enableTristate) +{ + uint32_t tRegValue = obj->CFGR1; + + if(enableTristate == true) + { + obj->CFGR1 = ((1ul << SPI_CFGR1_OUT_CFG_SHIFT) | ((~SPI_CFGR1_OUT_CFG_MASK) & tRegValue)); + } + else + { + obj->CFGR1 = ((0ul << SPI_CFGR1_OUT_CFG_SHIFT) | ((~SPI_CFGR1_OUT_CFG_MASK) & tRegValue)); + } +} + +/*! \brief Pin Configuration + * + * Configures which pins are used for input and output data during serial transfers. + * + * \param[in] obj: base address for the SPI instance + * \param[in] pin_cfg + * 00b : SIN is used for input data and SOUT is used for output data + * 01b : SIN is used for both input and output data, only half-duplex serial transfers are supported + * 10b : SOUT is used for both input and output data, only half-duplex serial transfers are supported + * 11b : SOUT is used for input data and SIN is used for output data + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetPinCfg(SpiRegType *obj, uint8_t pin_cfg) +{ + uint32_t tmp = obj->CFGR1; + + tmp &= ~SPI_CFGR1_PIN_CFG_MASK; + tmp |= (((uint32_t)(((uint32_t)(pin_cfg)) << SPI_CFGR1_PIN_CFG_SHIFT)) & SPI_CFGR1_PIN_CFG_MASK); + obj->CFGR1 = tmp; +} + +/*! \brief Peripheral Chip Select Polarity + * + * Configures the polarity of each Peripheral Chip Select pin. Each PCS_POL bit position corresponds to a PCS[n] pin. + * + * \param[in] obj: base address for the SPI instance + * \param[in] polarity + * 0b: the PCS[n] pin is active low. + * 1b: the PCS[n] pin is active high. + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetPcsPolarity(SpiRegType *obj, uint8_t polarity) +{ + uint32_t tmp = obj->CFGR1; + + tmp &= ~SPI_CFGR1_PCS_POL_MASK; + tmp |= (((uint32_t)(((uint32_t)(polarity)) << SPI_CFGR1_PCS_POL_SHIFT)) & SPI_CFGR1_PCS_POL_MASK); + obj->CFGR1 = tmp; +} + +/*! \brief Set master sck delay + * + * this function set the sck delay ticks + * + * \param[in] obj: base address for the SPI instance + * \param[in] delaytick: delay tick + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetMstSckDelay(SpiRegType *obj, uint8_t delaytick) +{ + uint32_t tmp = obj->CFGR1; + + tmp &= ~SPI_CFGR1_MST_SCK_DLY_MASK; + tmp |= (((uint32_t)(((uint32_t)(delaytick)) << SPI_CFGR1_MST_SCK_DLY_SHIFT)) & SPI_CFGR1_MST_SCK_DLY_MASK); + obj->CFGR1 = tmp; +} + +/*! \brief Master mode No Stall enable or disable + * + * In master mode, the SPI will stall transfers when the transmit FIFO is empty, + * ensuring that no transmit FIFO underrun can occur. Setting the No Stall bit will disable this functionality. + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable + * 0b : Transfers will stall when the transmit FIFO is empty + * 1b : Transfers will not stall, allowing transmit FIFO underruns to occur + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetNoStallMode(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->CFGR1; + + if(enable == true) + { + obj->CFGR1 = ((1ul << SPI_CFGR1_NO_STALL_SHIFT) | ((~SPI_CFGR1_NO_STALL_MASK) & tRegValue)); + } + else + { + obj->CFGR1 = ((0ul << SPI_CFGR1_NO_STALL_SHIFT) | ((~SPI_CFGR1_NO_STALL_MASK) & tRegValue)); + } +} + +/*! \brief Automatic PCS enable or disable in slave mode + * + * The module normally requires the PCS to negate between frames. Setting this bit will cause the module to generate an internal PCS signal + * at the end of each transfer word when the Clock Phase bit TCR[CPHA] = 1. + * + * \param[in] obj: base address for the SPI instance + * \param[in] enable: Automatic PCS in slave mode + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetAutoCS(SpiRegType *obj, bool enable) +{ + uint32_t tRegValue = obj->CFGR1; + + if(enable == true) + { + obj->CFGR1 = ((1ul << SPI_CFGR1_AUTO_PCS_SHIFT) | ((~SPI_CFGR1_AUTO_PCS_MASK) & tRegValue)); + } + else + { + obj->CFGR1 = ((0ul << SPI_CFGR1_AUTO_PCS_SHIFT) | ((~SPI_CFGR1_AUTO_PCS_MASK) & tRegValue)); + } +} + +/*! \brief Configures the module in master or slave mode + * + * this function set the node word mode in master or slave + * + * \param[in] obj: base address for the SPI instance + * \param[in] ismaster: + * false:as slave + * true: as master + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetNodeMode(SpiRegType *obj, bool ismaster) +{ + uint32_t tRegValue = obj->CFGR1; + + if(ismaster == true) + { + obj->CFGR1 = ((1ul << SPI_CFGR1_MASTER_EN_SHIFT) | ((~SPI_CFGR1_MASTER_EN_MASK) & tRegValue)); + } + else + { + obj->CFGR1 = ((0ul << SPI_CFGR1_MASTER_EN_SHIFT) | ((~SPI_CFGR1_MASTER_EN_MASK) & tRegValue)); + } +} + +/*! \brief Get the module in master or slave mode + * + * + * + * \param[in] obj : base address for the SPI instance + * \return bool + * false: is slave node + * true: is master node + */ +__attribute__((always_inline)) static inline bool SpiReg_GetNodeMasterState(const SpiRegType *obj) +{ + bool tRtn = false; + + if((obj->CFGR1 & SPI_CFGR1_MASTER_EN_MASK) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief configures the delay from the last SCK edge to the PCS negation + * + * The delay is equal to (SCKPCS + 1) cycles of the SPI functional clock divided by the Prescaler Value TCR[PRESCALE] configuration. + * The minimum delay is 1 cycle. + * + * \param[in] obj: base address for the SPI instance + * \param[in] delaytick: SCK-to-PCS Delay + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetDelaySckToPcs(SpiRegType *obj, uint8_t delaytick) +{ + uint32_t tmp = obj->CCR; + + tmp &= ~SPI_CCR_SCK_PCS_MASK; + tmp |= (((uint32_t)(((uint32_t)(delaytick)) << SPI_CCR_SCK_PCS_SHIFT)) & SPI_CCR_SCK_PCS_MASK); + obj->CCR = tmp; +} + +/*! \brief configures the delay from the PCS assertion to the first SCK edge. + * + * The delay is equal to (PCSSCK + 1) cycles of the SPI functional clock divided by the Prescaler Value TCR[PRESCALE] configuration + * The minimum delay is 1 cycle. + * + * \param[in] obj: base address for the SPI instance + * \param[in] delaytick: PCS-to-SCK Delay + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetDelayPcsToSck(SpiRegType *obj, uint8_t delaytick) +{ + uint32_t tmp = obj->CCR; + + tmp &= ~SPI_CCR_PCS_SCK_MASK; + tmp |= (((uint32_t)(((uint32_t)(delaytick)) << SPI_CCR_PCS_SCK_SHIFT)) & SPI_CCR_PCS_SCK_MASK); + obj->CCR = tmp; +} + +/*! \brief Configures the delay from the PCS negation to the next PCS assertion. + * + * The delay is equal to (DBT + 2) cycles of the SPI functional clock divided by the Prescaler. + * The minimum delay is 2 cycles. + * + * \param[in] obj: base address for the SPI instance + * \param[in] delaytick: Delay Between Transfers + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetDelayDBT(SpiRegType *obj, uint8_t delaytick) +{ + uint32_t tmp = obj->CCR; + + tmp &= ~SPI_CCR_DBT_MASK; + tmp |= (((uint32_t)(((uint32_t)(delaytick)) << SPI_CCR_DBT_SHIFT)) & SPI_CCR_DBT_MASK); + obj->CCR = tmp; +} + +/*! \brief the SCK Divider configures the divide ratio of the SCK pin + * + * The SCK period is equal to (SCKDIV+2) cycles of the SPI functional clock divided by the Prescaler Value TCR[PRESCALE] configuration. + * The minimum SCK period is 2 cycles. + * + * \param[in] obj: base address for the SPI instance + * \param[in] sckdiv: SCK Divider + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetSckDiv(SpiRegType *obj, uint8_t sckdiv) +{ + uint32_t tmp = obj->CCR; + + tmp &= ~SPI_CCR_SCK_DIV_MASK; + tmp |= (((uint32_t)(((uint32_t)(sckdiv)) << SPI_CCR_SCK_DIV_SHIFT)) & SPI_CCR_SCK_DIV_MASK); + obj->CCR = tmp; +} + +/*! \brief Transmit FIFO water mark + * + * The Transmit Data Flag is set whenever the number of words in the transmit FIFO is equal or less than TX_WATER + * + * \param[in] obj: base address for the SPI instance + * \param[in] txWaterMark: Transmit FIFO water mark + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetTxFifoWaterMark(SpiRegType *obj, uint8_t txWaterMark) +{ + uint32_t tmp = obj->FCR; + + tmp &= ~SPI_FCR_TX_FIFO_WATER_MASK; + tmp |= (((uint32_t)(((uint32_t)(txWaterMark)) << SPI_FCR_TX_FIFO_WATER_SHIFT)) & SPI_FCR_TX_FIFO_WATER_MASK); + obj->FCR = tmp; +} + +/*! \brief Get Tx FIFO water mark + * + * this function get the tx fifo water mark + * + * \param[in] obj: base address for the SPI instance + * \return: return tx fifo water mark value + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetTxFifoWaterMark(const SpiRegType *obj) +{ + uint8_t tTxWaterMark = 0; + + tTxWaterMark = ((obj->FCR & SPI_FCR_TX_FIFO_WATER_MASK) >> SPI_FCR_TX_FIFO_WATER_SHIFT); + + return tTxWaterMark; +} + +/*! \brief Receive FIFO Watermark + * + * The Receive Data Flag is set whenever the number of words in the receive FIFO is greater than RX_WATER + * + * \param[in] obj: base address for the SPI instance + * \param[in] rxWaterMark: Receive FIFO Watermark + * \return: void + */ +__attribute__((always_inline)) static inline void SpiReg_SetRxFifoWaterMark(SpiRegType *obj, uint8_t rxWaterMark) +{ + uint32_t tmp = obj->FCR; + + tmp &= ~SPI_FCR_RX_FIFO_WATER_MASK; + tmp |= (((uint32_t)(((uint32_t)(rxWaterMark)) << SPI_FCR_RX_FIFO_WATER_SHIFT)) & SPI_FCR_RX_FIFO_WATER_MASK); + obj->FCR = tmp; +} + +/*! \brief Get Rx FIFO water mark + * + * this function get the rx fifo water mark + * + * \param[in] obj: base address for the SPI instance + * \return: return rx fifo water mark value + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetRxFifoWaterMark(const SpiRegType *obj) +{ + uint8_t tRxWaterMark = 0; + + tRxWaterMark = ((obj->FCR & SPI_FCR_RX_FIFO_WATER_MASK) >> SPI_FCR_RX_FIFO_WATER_SHIFT); + + return tRxWaterMark; +} + +/*! \brief Transmit FIFO Count + * + * Returns the number of words currently stored in the transmit FIFO. + * + * \param[in] obj: base address for the SPI instance + * \return: uint8_t: return tx fifo counter value + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetTxFifoCounter(const SpiRegType *obj) +{ + uint8_t tTxFifoCnt = 0; + + tTxFifoCnt = ((obj->FSR & SPI_FSR_TX_FIFO_CNT_MASK) >> SPI_FSR_TX_FIFO_CNT_SHIFT); + + return tTxFifoCnt; +} + +/*! \brief Receive FIFO Count + * + * Returns the number of words currently stored in the receive FIFO. + * + * \param[in] obj: base address for the SPI instance + * \return: return received rx fifo counter value + */ +__attribute__((always_inline)) static inline uint8_t SpiReg_GetRxFifoCounter(const SpiRegType *obj) +{ + uint8_t tRxFifoCnt = 0; + + tRxFifoCnt = ((obj->FSR & SPI_FSR_RX_FIFO_CNT_MASK) >> SPI_FSR_RX_FIFO_CNT_SHIFT); + + return tRxFifoCnt; +} + +/*! \brief Set TX FIFO data + * + * this function is write data to hardware fifo + * + * \param[in] obj: base address for the SPI instance + * \param[in] dat: TX FIFO data + */ +__attribute__((always_inline)) static inline void SpiReg_SetTxFifoData(SpiRegType *obj, uint32_t dat) +{ + obj->TDR = dat; +} + +/*! \brief Get RX FIFO data + * + * this function read out the received data from hardware fifo + * + * \param[in] obj: base address for the SPI instance + * \return: RX FIFO data + */ +__attribute__((always_inline)) static inline uint32_t SpiReg_GetRxFiFoData(const SpiRegType *obj) +{ + return obj->RDR; +} + +/*! \brief RX FIFO Empty status + * + * this function get the current rx fifo status + * + * \param[in] obj: base address for the SPI instance + * \return: RX FIFO Empty status + * false:RX FIFO is not empty + * true:RX FIFO is empty + */ +__attribute__((always_inline)) static inline bool SpiReg_GetRxFifoEmptyState(const SpiRegType *obj) +{ + bool tRtn = false; + + if(((obj->RSR & SPI_RSR_RX_FIFO_EMPTY_MASK) >> SPI_RSR_RX_FIFO_EMPTY_SHIFT) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief Indicates that this is the first data word received after PCS assertion. + * + * this function get the current received data that is the first time to received + * + * \param[in] obj: base address for the SPI instance + * \return: the first data word received + * false:The first word after PCS assertion is read by software or has no data after PCS assertion. + * true:receive the first word after PCS assertion + */ +__attribute__((always_inline)) static inline bool SpiReg_GetStartOfFrameIndicate(const SpiRegType *obj) +{ + bool tRtn = false; + + if(((obj->RSR & SPI_RSR_SOF_MASK) >> SPI_RSR_SOF_SHIFT) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _SPI_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/trgmux_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/trgmux_reg.h new file mode 100644 index 0000000..129749b --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/trgmux_reg.h @@ -0,0 +1,1351 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _TRGMUX_REG_H_ +#define _TRGMUX_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the TRGMUX Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* DMAMUX0 Bit Fields */ +#define TRGMUX_DMAMUX0_LK_MASK (0x80000000u) +#define TRGMUX_DMAMUX0_LK_SHIFT (31u) +#define TRGMUX_DMAMUX0_LK_WIDTH (1u) +#define TRGMUX_DMAMUX0_SEL3_MASK (0x7F000000u) +#define TRGMUX_DMAMUX0_SEL3_SHIFT (24u) +#define TRGMUX_DMAMUX0_SEL3_WIDTH (7u) +#define TRGMUX_DMAMUX0_SEL2_MASK (0x7F0000u) +#define TRGMUX_DMAMUX0_SEL2_SHIFT (16u) +#define TRGMUX_DMAMUX0_SEL2_WIDTH (7u) +#define TRGMUX_DMAMUX0_SEL1_MASK (0x7F00u) +#define TRGMUX_DMAMUX0_SEL1_SHIFT (8u) +#define TRGMUX_DMAMUX0_SEL1_WIDTH (7u) +#define TRGMUX_DMAMUX0_SEL0_MASK (0x7Fu) +#define TRGMUX_DMAMUX0_SEL0_SHIFT (0u) +#define TRGMUX_DMAMUX0_SEL0_WIDTH (7u) + +/* EXTOUT0 Bit Fields */ +#define TRGMUX_EXTOUT0_LK_MASK (0x80000000u) +#define TRGMUX_EXTOUT0_LK_SHIFT (31u) +#define TRGMUX_EXTOUT0_LK_WIDTH (1u) +#define TRGMUX_EXTOUT0_SEL3_MASK (0x7F000000u) +#define TRGMUX_EXTOUT0_SEL3_SHIFT (24u) +#define TRGMUX_EXTOUT0_SEL3_WIDTH (7u) +#define TRGMUX_EXTOUT0_SEL2_MASK (0x7F0000u) +#define TRGMUX_EXTOUT0_SEL2_SHIFT (16u) +#define TRGMUX_EXTOUT0_SEL2_WIDTH (7u) +#define TRGMUX_EXTOUT0_SEL1_MASK (0x7F00u) +#define TRGMUX_EXTOUT0_SEL1_SHIFT (8u) +#define TRGMUX_EXTOUT0_SEL1_WIDTH (7u) +#define TRGMUX_EXTOUT0_SEL0_MASK (0x7Fu) +#define TRGMUX_EXTOUT0_SEL0_SHIFT (0u) +#define TRGMUX_EXTOUT0_SEL0_WIDTH (7u) + +/* ADC Bit Fields */ +#define TRGMUX_ADC_LK_MASK (0x80000000u) +#define TRGMUX_ADC_LK_SHIFT (31u) +#define TRGMUX_ADC_LK_WIDTH (1u) +#define TRGMUX_ADC_SEL3_MASK (0x7F000000u) +#define TRGMUX_ADC_SEL3_SHIFT (24u) +#define TRGMUX_ADC_SEL3_WIDTH (7u) +#define TRGMUX_ADC_SEL2_MASK (0x7F0000u) +#define TRGMUX_ADC_SEL2_SHIFT (16u) +#define TRGMUX_ADC_SEL2_WIDTH (7u) +#define TRGMUX_ADC_SEL1_MASK (0x7F00u) +#define TRGMUX_ADC_SEL1_SHIFT (8u) +#define TRGMUX_ADC_SEL1_WIDTH (7u) +#define TRGMUX_ADC_SEL0_MASK (0x7Fu) +#define TRGMUX_ADC_SEL0_SHIFT (0u) +#define TRGMUX_ADC_SEL0_WIDTH (7u) + +/* CMP Bit Fields */ +#define TRGMUX_CMP_LK_MASK (0x80000000u) +#define TRGMUX_CMP_LK_SHIFT (31u) +#define TRGMUX_CMP_LK_WIDTH (1u) +#define TRGMUX_CMP_SEL0_MASK (0x7Fu) +#define TRGMUX_CMP_SEL0_SHIFT (0u) +#define TRGMUX_CMP_SEL0_WIDTH (7u) + +/* MFT0 Bit Fields */ +#define TRGMUX_MFT0_LK_MASK (0x80000000u) +#define TRGMUX_MFT0_LK_SHIFT (31u) +#define TRGMUX_MFT0_LK_WIDTH (1u) +#define TRGMUX_MFT0_SEL3_MASK (0x7F000000u) +#define TRGMUX_MFT0_SEL3_SHIFT (24u) +#define TRGMUX_MFT0_SEL3_WIDTH (7u) +#define TRGMUX_MFT0_SEL2_MASK (0x7F0000u) +#define TRGMUX_MFT0_SEL2_SHIFT (16u) +#define TRGMUX_MFT0_SEL2_WIDTH (7u) +#define TRGMUX_MFT0_SEL1_MASK (0x7F00u) +#define TRGMUX_MFT0_SEL1_SHIFT (8u) +#define TRGMUX_MFT0_SEL1_WIDTH (7u) +#define TRGMUX_MFT0_SEL0_MASK (0x7Fu) +#define TRGMUX_MFT0_SEL0_SHIFT (0u) +#define TRGMUX_MFT0_SEL0_WIDTH (7u) + +/* MFT1 Bit Fields */ +#define TRGMUX_MFT1_LK_MASK (0x80000000u) +#define TRGMUX_MFT1_LK_SHIFT (31u) +#define TRGMUX_MFT1_LK_WIDTH (1u) +#define TRGMUX_MFT1_SEL3_MASK (0x7F000000u) +#define TRGMUX_MFT1_SEL3_SHIFT (24u) +#define TRGMUX_MFT1_SEL3_WIDTH (7u) +#define TRGMUX_MFT1_SEL2_MASK (0x7F0000u) +#define TRGMUX_MFT1_SEL2_SHIFT (16u) +#define TRGMUX_MFT1_SEL2_WIDTH (7u) +#define TRGMUX_MFT1_SEL1_MASK (0x7F00u) +#define TRGMUX_MFT1_SEL1_SHIFT (8u) +#define TRGMUX_MFT1_SEL1_WIDTH (7u) +#define TRGMUX_MFT1_SEL0_MASK (0x7Fu) +#define TRGMUX_MFT1_SEL0_SHIFT (0u) +#define TRGMUX_MFT1_SEL0_WIDTH (7u) + +/* PDB Bit Fields */ +#define TRGMUX_PDB_LK_MASK (0x80000000u) +#define TRGMUX_PDB_LK_SHIFT (31u) +#define TRGMUX_PDB_LK_WIDTH (1u) +#define TRGMUX_PDB_SEL0_MASK (0x7Fu) +#define TRGMUX_PDB_SEL0_SHIFT (0u) +#define TRGMUX_PDB_SEL0_WIDTH (7u) + +/* LPIT Bit Fields */ +#define TRGMUX_LPIT_LK_MASK (0x80000000u) +#define TRGMUX_LPIT_LK_SHIFT (31u) +#define TRGMUX_LPIT_LK_WIDTH (1u) +#define TRGMUX_LPIT_SEL3_MASK (0x7F000000u) +#define TRGMUX_LPIT_SEL3_SHIFT (24u) +#define TRGMUX_LPIT_SEL3_WIDTH (7u) +#define TRGMUX_LPIT_SEL2_MASK (0x7F0000u) +#define TRGMUX_LPIT_SEL2_SHIFT (16u) +#define TRGMUX_LPIT_SEL2_WIDTH (7u) +#define TRGMUX_LPIT_SEL1_MASK (0x7F00u) +#define TRGMUX_LPIT_SEL1_SHIFT (8u) +#define TRGMUX_LPIT_SEL1_WIDTH (7u) +#define TRGMUX_LPIT_SEL0_MASK (0x7Fu) +#define TRGMUX_LPIT_SEL0_SHIFT (0u) +#define TRGMUX_LPIT_SEL0_WIDTH (7u) + +/* LPTMR Bit Fields */ +#define TRGMUX_LPTMR_LK_MASK (0x80000000u) +#define TRGMUX_LPTMR_LK_SHIFT (31u) +#define TRGMUX_LPTMR_LK_WIDTH (1u) +#define TRGMUX_LPTMR_SEL0_MASK (0x7Fu) +#define TRGMUX_LPTMR_SEL0_SHIFT (0u) +#define TRGMUX_LPTMR_SEL0_WIDTH (7u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of TRGMUX registers + */ +typedef struct _TrgMuxRegType_ +{ + volatile uint32_t DMAMUX0; /*!< TRGMUX DMAMUX0 register, offset: 0x0 */ + volatile uint32_t EXTOUT0; /*!< TRGMUX EXTOUT0 register, offset: 0x4 */ + uint32_t RESERVED0[1]; /*!< Reserverd block, offset: 0x08 */ + volatile uint32_t ADC; /*!< TRGMUX ADC register, offset: 0x0C */ + uint32_t RESERVED1[1]; /*!< Reserverd block, offset: 0x10 */ + volatile uint32_t CMP; /*!< TRGMUX CMP register, offset: 0x014 */ + volatile uint32_t MFT0; /*!< TRGMUX MFT0 register, offset: 0x18 */ + volatile uint32_t MFT1; /*!< TRGMUX MFT1 register, offset: 0x1C */ + uint32_t RESERVED2[2]; /*!< Reserverd block, offset: 0x20 */ + volatile uint32_t PDB; /*!< TRGMUX PDB register, offset: 0x28 */ + uint32_t RESERVED3[1]; /*!< Reserverd block, offset: 0x2C */ + volatile uint32_t LPIT; /*!< TRGMUX LPIT register, offset: 0x30 */ + volatile uint32_t LPTMR; /*!< TRGMUX LPTMR register, offset: 0x34 */ +} TrgMuxRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the TRGMUX DMAMUX0 register lock + * + * This function gets the current TRGMUX DMAMUX0 register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \return TRGMUX DMAMUX0 register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetDmaMux0Lk(const TrgMuxRegType *obj) +{ + return ((obj->DMAMUX0 & TRGMUX_DMAMUX0_LK_MASK) >> TRGMUX_DMAMUX0_LK_SHIFT); +} + +/*! \brief Sets the TRGMUX DMAMUX0 register lock + * + * This function sets the TRGMUX DMAMUX0 register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of TRGMUX DMAMUX0 register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetDmaMux0Lk(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DMAMUX0; + + tmp &= ~TRGMUX_DMAMUX0_LK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_DMAMUX0_LK_SHIFT)) & TRGMUX_DMAMUX0_LK_MASK); + obj->DMAMUX0 = tmp; +} + +/*! \brief Gets the Selected source for output 3 of this module + * + * This function gets the current Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetDmaMux0Sel3(const TrgMuxRegType *obj) +{ + return ((obj->DMAMUX0 & TRGMUX_DMAMUX0_SEL3_MASK) >> TRGMUX_DMAMUX0_SEL3_SHIFT); +} + +/*! \brief Sets the Selected source for output 3 of this module + * + * This function sets the Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetDmaMux0Sel3(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DMAMUX0; + + tmp &= ~TRGMUX_DMAMUX0_SEL3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_DMAMUX0_SEL3_SHIFT)) & TRGMUX_DMAMUX0_SEL3_MASK); + obj->DMAMUX0 = tmp; +} + +/*! \brief Gets the Selected source for output 2 of this module + * + * This function gets the current Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetDmaMux0Sel2(const TrgMuxRegType *obj) +{ + return ((obj->DMAMUX0 & TRGMUX_DMAMUX0_SEL2_MASK) >> TRGMUX_DMAMUX0_SEL2_SHIFT); +} + +/*! \brief Sets the Selected source for output 2 of this module + * + * This function sets the Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetDmaMux0Sel2(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DMAMUX0; + + tmp &= ~TRGMUX_DMAMUX0_SEL2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_DMAMUX0_SEL2_SHIFT)) & TRGMUX_DMAMUX0_SEL2_MASK); + obj->DMAMUX0 = tmp; +} + +/*! \brief Gets the Selected source for output 1 of this module + * + * This function gets the current Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetDmaMux0Sel1(const TrgMuxRegType *obj) +{ + return ((obj->DMAMUX0 & TRGMUX_DMAMUX0_SEL1_MASK) >> TRGMUX_DMAMUX0_SEL1_SHIFT); +} + +/*! \brief Sets the Selected source for output 1 of this module + * + * This function sets the Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetDmaMux0Sel1(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DMAMUX0; + + tmp &= ~TRGMUX_DMAMUX0_SEL1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_DMAMUX0_SEL1_SHIFT)) & TRGMUX_DMAMUX0_SEL1_MASK); + obj->DMAMUX0 = tmp; +} + +/*! \brief Gets the Selected source for output 0 of this module + * + * This function gets the current Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetDmaMux0Sel0(const TrgMuxRegType *obj) +{ + return ((obj->DMAMUX0 & TRGMUX_DMAMUX0_SEL0_MASK) >> TRGMUX_DMAMUX0_SEL0_SHIFT); +} + +/*! \brief Sets the Selected source for output 0 of this module + * + * This function sets the Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetDmaMux0Sel0(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->DMAMUX0; + + tmp &= ~TRGMUX_DMAMUX0_SEL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_DMAMUX0_SEL0_SHIFT)) & TRGMUX_DMAMUX0_SEL0_MASK); + obj->DMAMUX0 = tmp; +} + +/*! \brief Gets the TRGMUX EXTOUT0 register lock + * + * This function gets the current TRGMUX EXTOUT0 register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \return TRGMUX EXTOUT0 register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetExtOut0Lk(const TrgMuxRegType *obj) +{ + return ((obj->EXTOUT0 & TRGMUX_EXTOUT0_LK_MASK) >> TRGMUX_EXTOUT0_LK_SHIFT); +} + +/*! \brief Sets the TRGMUX EXTOUT0 register lock + * + * This function sets the TRGMUX EXTOUT0 register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of TRGMUX EXTOUT0 register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetExtOut0Lk(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTOUT0; + + tmp &= ~TRGMUX_EXTOUT0_LK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_EXTOUT0_LK_SHIFT)) & TRGMUX_EXTOUT0_LK_MASK); + obj->EXTOUT0 = tmp; +} + +/*! \brief Gets the Selected source for output 3 of this module + * + * This function gets the current Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetExtOut0Sel3(const TrgMuxRegType *obj) +{ + return ((obj->EXTOUT0 & TRGMUX_EXTOUT0_SEL3_MASK) >> TRGMUX_EXTOUT0_SEL3_SHIFT); +} + +/*! \brief Sets the Selected source for output 3 of this module + * + * This function sets the Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetExtOut0Sel3(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTOUT0; + + tmp &= ~TRGMUX_EXTOUT0_SEL3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_EXTOUT0_SEL3_SHIFT)) & TRGMUX_EXTOUT0_SEL3_MASK); + obj->EXTOUT0 = tmp; +} + +/*! \brief Gets the Selected source for output 2 of this module + * + * This function gets the current Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetExtOut0Sel2(const TrgMuxRegType *obj) +{ + return ((obj->EXTOUT0 & TRGMUX_EXTOUT0_SEL2_MASK) >> TRGMUX_EXTOUT0_SEL2_SHIFT); +} + +/*! \brief Sets the Selected source for output 2 of this module + * + * This function sets the Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetExtOut0Sel2(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTOUT0; + + tmp &= ~TRGMUX_EXTOUT0_SEL2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_EXTOUT0_SEL2_SHIFT)) & TRGMUX_EXTOUT0_SEL2_MASK); + obj->EXTOUT0 = tmp; +} + +/*! \brief Gets the Selected source for output 1 of this module + * + * This function gets the current Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetExtOut0Sel1(const TrgMuxRegType *obj) +{ + return ((obj->EXTOUT0 & TRGMUX_EXTOUT0_SEL1_MASK) >> TRGMUX_EXTOUT0_SEL1_SHIFT); +} + +/*! \brief Sets the Selected source for output 1 of this module + * + * This function sets the Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetExtOut0Sel1(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTOUT0; + + tmp &= ~TRGMUX_EXTOUT0_SEL1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_EXTOUT0_SEL1_SHIFT)) & TRGMUX_EXTOUT0_SEL1_MASK); + obj->EXTOUT0 = tmp; +} + +/*! \brief Gets the Selected source for output 0 of this module + * + * This function gets the current Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetExtOut0Sel0(const TrgMuxRegType *obj) +{ + return ((obj->EXTOUT0 & TRGMUX_EXTOUT0_SEL0_MASK) >> TRGMUX_EXTOUT0_SEL0_SHIFT); +} + +/*! \brief Sets the Selected source for output 0 of this module + * + * This function sets the Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetExtOut0Sel0(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->EXTOUT0; + + tmp &= ~TRGMUX_EXTOUT0_SEL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_EXTOUT0_SEL0_SHIFT)) & TRGMUX_EXTOUT0_SEL0_MASK); + obj->EXTOUT0 = tmp; +} + +/*! \brief Gets the TRGMUX ADC register lock + * + * This function gets the current TRGMUX ADC register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \return TRGMUX ADC register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetAdcLk(const TrgMuxRegType *obj) +{ + return ((obj->ADC & TRGMUX_ADC_LK_MASK) >> TRGMUX_ADC_LK_SHIFT); +} + +/*! \brief Sets the TRGMUX ADC register lock + * + * This function sets the TRGMUX ADC register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of TRGMUX ADC register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetAdcLk(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~TRGMUX_ADC_LK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_ADC_LK_SHIFT)) & TRGMUX_ADC_LK_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the Selected source for output 3 of this module + * + * This function gets the current Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetAdcSel3(const TrgMuxRegType *obj) +{ + return ((obj->ADC & TRGMUX_ADC_SEL3_MASK) >> TRGMUX_ADC_SEL3_SHIFT); +} + +/*! \brief Sets the Selected source for output 3 of this module + * + * This function sets the Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetAdcSel3(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~TRGMUX_ADC_SEL3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_ADC_SEL3_SHIFT)) & TRGMUX_ADC_SEL3_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the Selected source for output 2 of this module + * + * This function gets the current Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetAdcSel2(const TrgMuxRegType *obj) +{ + return ((obj->ADC & TRGMUX_ADC_SEL2_MASK) >> TRGMUX_ADC_SEL2_SHIFT); +} + +/*! \brief Sets the Selected source for output 2 of this module + * + * This function sets the Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetAdcSel2(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~TRGMUX_ADC_SEL2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_ADC_SEL2_SHIFT)) & TRGMUX_ADC_SEL2_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the Selected source for output 1 of this module + * + * This function gets the current Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetAdcSel1(const TrgMuxRegType *obj) +{ + return ((obj->ADC & TRGMUX_ADC_SEL1_MASK) >> TRGMUX_ADC_SEL1_SHIFT); +} + +/*! \brief Sets the Selected source for output 1 of this module + * + * This function sets the Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetAdcSel1(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~TRGMUX_ADC_SEL1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_ADC_SEL1_SHIFT)) & TRGMUX_ADC_SEL1_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the Selected source for output 0 of this module + * + * This function gets the current Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetAdcSel0(const TrgMuxRegType *obj) +{ + return ((obj->ADC & TRGMUX_ADC_SEL0_MASK) >> TRGMUX_ADC_SEL0_SHIFT); +} + +/*! \brief Sets the Selected source for output 0 of this module + * + * This function sets the Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetAdcSel0(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->ADC; + + tmp &= ~TRGMUX_ADC_SEL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_ADC_SEL0_SHIFT)) & TRGMUX_ADC_SEL0_MASK); + obj->ADC = tmp; +} + +/*! \brief Gets the TRGMUX CMP register lock + * + * This function gets the current TRGMUX CMP register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \return TRGMUX CMP register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetCmpLk(const TrgMuxRegType *obj) +{ + return ((obj->CMP & TRGMUX_CMP_LK_MASK) >> TRGMUX_CMP_LK_SHIFT); +} + +/*! \brief Sets the TRGMUX CMP register lock + * + * This function sets the TRGMUX CMP register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of TRGMUX CMP register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetCmpLk(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CMP; + + tmp &= ~TRGMUX_CMP_LK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_CMP_LK_SHIFT)) & TRGMUX_CMP_LK_MASK); + obj->CMP = tmp; +} + +/*! \brief Gets the Selected source for output 0 of this module + * + * This function gets the current Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetCmpSel0(const TrgMuxRegType *obj) +{ + return ((obj->CMP & TRGMUX_CMP_SEL0_MASK) >> TRGMUX_CMP_SEL0_SHIFT); +} + +/*! \brief Sets the Selected source for output 0 of this module + * + * This function sets the Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetCmpSel0(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->CMP; + + tmp &= ~TRGMUX_CMP_SEL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_CMP_SEL0_SHIFT)) & TRGMUX_CMP_SEL0_MASK); + obj->CMP = tmp; +} + +/*! \brief Gets the TRGMUX MFT0 register lock + * + * This function gets the current TRGMUX MFT0 register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \return TRGMUX MFT0 register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetMft0Lk(const TrgMuxRegType *obj) +{ + return ((obj->MFT0 & TRGMUX_MFT0_LK_MASK) >> TRGMUX_MFT0_LK_SHIFT); +} + +/*! \brief Sets the TRGMUX MFT0 register lock + * + * This function sets the TRGMUX MFT0 register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of TRGMUX MFT0 register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetMft0Lk(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT0; + + tmp &= ~TRGMUX_MFT0_LK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_MFT0_LK_SHIFT)) & TRGMUX_MFT0_LK_MASK); + obj->MFT0 = tmp; +} + +/*! \brief Gets the Selected source for output 3 of this module + * + * This function gets the current Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetMft0Sel3(const TrgMuxRegType *obj) +{ + return ((obj->MFT0 & TRGMUX_MFT0_SEL3_MASK) >> TRGMUX_MFT0_SEL3_SHIFT); +} + +/*! \brief Sets the Selected source for output 3 of this module + * + * This function sets the Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetMft0Sel3(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT0; + + tmp &= ~TRGMUX_MFT0_SEL3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_MFT0_SEL3_SHIFT)) & TRGMUX_MFT0_SEL3_MASK); + obj->MFT0 = tmp; +} + +/*! \brief Gets the Selected source for output 2 of this module + * + * This function gets the current Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetMft0Sel2(const TrgMuxRegType *obj) +{ + return ((obj->MFT0 & TRGMUX_MFT0_SEL2_MASK) >> TRGMUX_MFT0_SEL2_SHIFT); +} + +/*! \brief Sets the Selected source for output 2 of this module + * + * This function sets the Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetMft0Sel2(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT0; + + tmp &= ~TRGMUX_MFT0_SEL2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_MFT0_SEL2_SHIFT)) & TRGMUX_MFT0_SEL2_MASK); + obj->MFT0 = tmp; +} + +/*! \brief Gets the Selected source for output 1 of this module + * + * This function gets the current Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetMft0Sel1(const TrgMuxRegType *obj) +{ + return ((obj->MFT0 & TRGMUX_MFT0_SEL1_MASK) >> TRGMUX_MFT0_SEL1_SHIFT); +} + +/*! \brief Sets the Selected source for output 1 of this module + * + * This function sets the Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetMft0Sel1(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT0; + + tmp &= ~TRGMUX_MFT0_SEL1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_MFT0_SEL1_SHIFT)) & TRGMUX_MFT0_SEL1_MASK); + obj->MFT0 = tmp; +} + +/*! \brief Gets the Selected source for output 0 of this module + * + * This function gets the current Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetMft0Sel0(const TrgMuxRegType *obj) +{ + return ((obj->MFT0 & TRGMUX_MFT0_SEL0_MASK) >> TRGMUX_MFT0_SEL0_SHIFT); +} + +/*! \brief Sets the Selected source for output 0 of this module + * + * This function sets the Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetMft0Sel0(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT0; + + tmp &= ~TRGMUX_MFT0_SEL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_MFT0_SEL0_SHIFT)) & TRGMUX_MFT0_SEL0_MASK); + obj->MFT0 = tmp; +} + +/*! \brief Gets the TRGMUX MFT1 register lock + * + * This function gets the current TRGMUX MFT1 register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \return TRGMUX MFT1 register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetMft1Lk(const TrgMuxRegType *obj) +{ + return ((obj->MFT1 & TRGMUX_MFT1_LK_MASK) >> TRGMUX_MFT1_LK_SHIFT); +} + +/*! \brief Sets the TRGMUX MFT1 register lock + * + * This function sets the TRGMUX MFT1 register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of TRGMUX MFT1 register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetMft1Lk(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT1; + + tmp &= ~TRGMUX_MFT1_LK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_MFT1_LK_SHIFT)) & TRGMUX_MFT1_LK_MASK); + obj->MFT1 = tmp; +} + +/*! \brief Gets the Selected source for output 3 of this module + * + * This function gets the current Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetMft1Sel3(const TrgMuxRegType *obj) +{ + return ((obj->MFT1 & TRGMUX_MFT1_SEL3_MASK) >> TRGMUX_MFT1_SEL3_SHIFT); +} + +/*! \brief Sets the Selected source for output 3 of this module + * + * This function sets the Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetMft1Sel3(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT1; + + tmp &= ~TRGMUX_MFT1_SEL3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_MFT1_SEL3_SHIFT)) & TRGMUX_MFT1_SEL3_MASK); + obj->MFT1 = tmp; +} + +/*! \brief Gets the Selected source for output 2 of this module + * + * This function gets the current Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetMft1Sel2(const TrgMuxRegType *obj) +{ + return ((obj->MFT1 & TRGMUX_MFT1_SEL2_MASK) >> TRGMUX_MFT1_SEL2_SHIFT); +} + +/*! \brief Sets the Selected source for output 2 of this module + * + * This function sets the Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetMft1Sel2(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT1; + + tmp &= ~TRGMUX_MFT1_SEL2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_MFT1_SEL2_SHIFT)) & TRGMUX_MFT1_SEL2_MASK); + obj->MFT1 = tmp; +} + +/*! \brief Gets the Selected source for output 1 of this module + * + * This function gets the current Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetMft1Sel1(const TrgMuxRegType *obj) +{ + return ((obj->MFT1 & TRGMUX_MFT1_SEL1_MASK) >> TRGMUX_MFT1_SEL1_SHIFT); +} + +/*! \brief Sets the Selected source for output 1 of this module + * + * This function sets the Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetMft1Sel1(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT1; + + tmp &= ~TRGMUX_MFT1_SEL1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_MFT1_SEL1_SHIFT)) & TRGMUX_MFT1_SEL1_MASK); + obj->MFT1 = tmp; +} + +/*! \brief Gets the Selected source for output 0 of this module + * + * This function gets the current Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetMft1Sel0(const TrgMuxRegType *obj) +{ + return ((obj->MFT1 & TRGMUX_MFT1_SEL0_MASK) >> TRGMUX_MFT1_SEL0_SHIFT); +} + +/*! \brief Sets the Selected source for output 0 of this module + * + * This function sets the Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetMft1Sel0(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->MFT1; + + tmp &= ~TRGMUX_MFT1_SEL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_MFT1_SEL0_SHIFT)) & TRGMUX_MFT1_SEL0_MASK); + obj->MFT1 = tmp; +} + +/*! \brief Gets the TRGMUX PDB register lock + * + * This function gets the current TRGMUX PDB register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \return TRGMUX PDB register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetPdbLk(const TrgMuxRegType *obj) +{ + return ((obj->PDB & TRGMUX_PDB_LK_MASK) >> TRGMUX_PDB_LK_SHIFT); +} + +/*! \brief Sets the TRGMUX PDB register lock + * + * This function sets the TRGMUX PDB register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of TRGMUX PDB register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetPdbLk(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PDB; + + tmp &= ~TRGMUX_PDB_LK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_PDB_LK_SHIFT)) & TRGMUX_PDB_LK_MASK); + obj->PDB = tmp; +} + +/*! \brief Gets the Selected source for output 0 of this module + * + * This function gets the current Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetPdbSel0(const TrgMuxRegType *obj) +{ + return ((obj->PDB & TRGMUX_PDB_SEL0_MASK) >> TRGMUX_PDB_SEL0_SHIFT); +} + +/*! \brief Sets the Selected source for output 0 of this module + * + * This function sets the Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetPdbSel0(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->PDB; + + tmp &= ~TRGMUX_PDB_SEL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_PDB_SEL0_SHIFT)) & TRGMUX_PDB_SEL0_MASK); + obj->PDB = tmp; +} + +/*! \brief Gets the TRGMUX LPIT register lock + * + * This function gets the current TRGMUX LPIT register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \return TRGMUX LPIT register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetLpitLk(const TrgMuxRegType *obj) +{ + return ((obj->LPIT & TRGMUX_LPIT_LK_MASK) >> TRGMUX_LPIT_LK_SHIFT); +} + +/*! \brief Sets the TRGMUX LPIT register lock + * + * This function sets the TRGMUX LPIT register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of TRGMUX LPIT register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetLpitLk(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPIT; + + tmp &= ~TRGMUX_LPIT_LK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_LPIT_LK_SHIFT)) & TRGMUX_LPIT_LK_MASK); + obj->LPIT = tmp; +} + +/*! \brief Gets the Selected source for output 3 of this module + * + * This function gets the current Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetLpitSel3(const TrgMuxRegType *obj) +{ + return ((obj->LPIT & TRGMUX_LPIT_SEL3_MASK) >> TRGMUX_LPIT_SEL3_SHIFT); +} + +/*! \brief Sets the Selected source for output 3 of this module + * + * This function sets the Selected source for output 3 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 3 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetLpitSel3(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPIT; + + tmp &= ~TRGMUX_LPIT_SEL3_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_LPIT_SEL3_SHIFT)) & TRGMUX_LPIT_SEL3_MASK); + obj->LPIT = tmp; +} + +/*! \brief Gets the Selected source for output 2 of this module + * + * This function gets the current Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetLpitSel2(const TrgMuxRegType *obj) +{ + return ((obj->LPIT & TRGMUX_LPIT_SEL2_MASK) >> TRGMUX_LPIT_SEL2_SHIFT); +} + +/*! \brief Sets the Selected source for output 2 of this module + * + * This function sets the Selected source for output 2 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 2 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetLpitSel2(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPIT; + + tmp &= ~TRGMUX_LPIT_SEL2_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_LPIT_SEL2_SHIFT)) & TRGMUX_LPIT_SEL2_MASK); + obj->LPIT = tmp; +} + +/*! \brief Gets the Selected source for output 1 of this module + * + * This function gets the current Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetLpitSel1(const TrgMuxRegType *obj) +{ + return ((obj->LPIT & TRGMUX_LPIT_SEL1_MASK) >> TRGMUX_LPIT_SEL1_SHIFT); +} + +/*! \brief Sets the Selected source for output 1 of this module + * + * This function sets the Selected source for output 1 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 1 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetLpitSel1(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPIT; + + tmp &= ~TRGMUX_LPIT_SEL1_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_LPIT_SEL1_SHIFT)) & TRGMUX_LPIT_SEL1_MASK); + obj->LPIT = tmp; +} + +/*! \brief Gets the Selected source for output 0 of this module + * + * This function gets the current Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetLpitSel0(const TrgMuxRegType *obj) +{ + return ((obj->LPIT & TRGMUX_LPIT_SEL0_MASK) >> TRGMUX_LPIT_SEL0_SHIFT); +} + +/*! \brief Sets the Selected source for output 0 of this module + * + * This function sets the Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetLpitSel0(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPIT; + + tmp &= ~TRGMUX_LPIT_SEL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_LPIT_SEL0_SHIFT)) & TRGMUX_LPIT_SEL0_MASK); + obj->LPIT = tmp; +} + +/*! \brief Gets the TRGMUX LPTMR register lock + * + * This function gets the current TRGMUX LPTMR register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \return TRGMUX LPTMR register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetLptmrLk(const TrgMuxRegType *obj) +{ + return ((obj->LPTMR & TRGMUX_LPTMR_LK_MASK) >> TRGMUX_LPTMR_LK_SHIFT); +} + +/*! \brief Sets the TRGMUX LPTMR register lock + * + * This function sets the TRGMUX LPTMR register lock. + * This bit shows whether the register can be written or not. + * The LK bit can only be written once after any system reset. + * Once LK is set, the SELx bits in this TRGMUX register cannot be changed until the next system reset clears LK. + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of TRGMUX LPTMR register lock + * - 0b : Register can be written. + * - 1b : Register cannot be written until the next system Reset. + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetLptmrLk(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPTMR; + + tmp &= ~TRGMUX_LPTMR_LK_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_LPTMR_LK_SHIFT)) & TRGMUX_LPTMR_LK_MASK); + obj->LPTMR = tmp; +} + +/*! \brief Gets the Selected source for output 0 of this module + * + * This function gets the current Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \return Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline uint8_t TrgMuxReg_GetLptmrSel0(const TrgMuxRegType *obj) +{ + return ((obj->LPTMR & TRGMUX_LPTMR_SEL0_MASK) >> TRGMUX_LPTMR_SEL0_SHIFT); +} + +/*! \brief Sets the Selected source for output 0 of this module + * + * This function sets the Selected source for output 0 of this module. + * Refer to user manual for signal encoding details + * + * \param[in] obj : pointer to TRGMUX register instance + * \param[in] value : the value of Selected source for output 0 of this module + */ +__attribute__((always_inline)) static inline void TrgMuxReg_SetLptmrSel0(TrgMuxRegType *obj, uint8_t value) +{ + uint32_t tmp = obj->LPTMR; + + tmp &= ~TRGMUX_LPTMR_SEL0_MASK; + tmp |= (((uint32_t)(((uint32_t)(value)) << TRGMUX_LPTMR_SEL0_SHIFT)) & TRGMUX_LPTMR_SEL0_MASK); + obj->LPTMR = tmp; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _TRGMUX_REG_H_ */ diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/uart_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/uart_reg.h new file mode 100644 index 0000000..b6e46a8 --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/uart_reg.h @@ -0,0 +1,2398 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UART_REG_H_ +#define _UART_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of UART module + */ + +/****************************************************************************** + * the includes + *****************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * the defines + *****************************************************************************/ + +/* CR1 Bit fields */ +#define UART_CR1_UE_MASK (0x00000001ul) +#define UART_CR1_UE_SHIFT (0u) +#define UART_CR1_UE_WIDTH (1u) + +#define UART_CR1_RE_MASK (0x00000004ul) +#define UART_CR1_RE_SHIFT (2u) +#define UART_CR1_RE_WIDTH (1u) + +#define UART_CR1_TE_MASK (0x00000008ul) +#define UART_CR1_TE_SHIFT (3u) +#define UART_CR1_TE_WIDTH (1u) + +#define UART_CR1_IDLEIE_MASK (0x00000010ul) +#define UART_CR1_IDLEIE_SHIFT (4u) +#define UART_CR1_IDLEIE_WIDTH (1u) + +#define UART_CR1_RDRFIE_MASK (0x00000020ul) +#define UART_CR1_RDRFIE_SHIFT (5u) +#define UART_CR1_RDRFIE_WIDTH (1u) + +#define UART_CR1_TCIE_MASK (0x00000040ul) +#define UART_CR1_TCIE_SHIFT (6u) +#define UART_CR1_TCIE_WIDTH (1u) + +#define UART_CR1_TDREIE_MASK (0x00000080ul) +#define UART_CR1_TDREIE_SHIFT (7u) +#define UART_CR1_TDREIE_WIDTH (1u) + +#define UART_CR1_PEIE_MASK (0x00000100ul) +#define UART_CR1_PEIE_SHIFT (8u) +#define UART_CR1_PEIE_WIDTH (1u) + +#define UART_CR1_PS_MASK (0x00000200ul) +#define UART_CR1_PS_SHIFT (9u) +#define UART_CR1_PS_WIDTH (1u) + +#define UART_CR1_PCE_MASK (0x00000400ul) +#define UART_CR1_PCE_SHIFT (10u) +#define UART_CR1_PCE_WIDTH (1u) + +#define UART_CR1_WAKE_MASK (0x00000800ul) +#define UART_CR1_WAKE_IDLE_LINE (0x00000000ul) +#define UART_CR1_WAKE_ADDR_MARK (0x00000800ul) +#define UART_CR1_WAKE_SHIFT (11u) +#define UART_CR1_WAKE_WIDTH (1u) + +#define UART_CR1_M_MASK (0x00001000ul) +#define UART_CR1_M_8BITS (0x00000000ul) +#define UART_CR1_M_9BITS (0x00001000ul) +#define UART_CR1_M_SHIFT (12u) +#define UART_CR1_M_WIDTH (1u) + +#define UART_CR1_MME_MASK (0x00002000ul) +#define UART_CR1_MME_SHIFT (13u) +#define UART_CR1_MME_WIDTH (1u) + +#define UART_CR1_SBRKDIE_MASK (0x00004000ul) +#define UART_CR1_SBRKDIE_SHIFT (14u) +#define UART_CR1_SBRKDIE_WIDTH (1u) + +#define UART_CR1_OVER8_MASK (0x00008000ul) +#define UART_CR1_OVER8_SHIFT (15u) +#define UART_CR1_OVER8_WIDTH (1u) + +#define UART_CR1_DEDT_MASK (0x001F0000ul) +#define UART_CR1_DEDT_SHIFT (16u) +#define UART_CR1_DEDT_WIDTH (5u) + +#define UART_CR1_DEAT_MASK (0x01F00000ul) +#define UART_CR1_DEAT_SHIFT (21u) +#define UART_CR1_DEAT_WIDTH (5u) + +#define UART_CR1_RTOIE_MASK (0x04000000ul) +#define UART_CR1_RTOIE_SHIFT (26u) +#define UART_CR1_RTOIE_WIDTH (1u) + +/* CR2 Bit fields */ +#define UART_CR2_SBRK_LEN_MASK (0x00000003ul) +#define UART_CR2_SBRK_LEN_13BITS (0x00000000ul) +#define UART_CR2_SBRK_LEN_14BITS (0x00000001ul) +#define UART_CR2_SBRK_LEN_15BITS (0x00000002ul) +#define UART_CR2_SBRK_LEN_SHIFT (0u) +#define UART_CR2_SBRK_LEN_WIDTH (2u) + +#define UART_CR2_SDEL_LEN_MASK (0x00000004ul) +#define UART_CR2_SDEL_LEN_1BITS (0x00000000ul) +#define UART_CR2_SDEL_LEN_2BITS (0x00000004ul) +#define UART_CR2_SDEL_LEN_SHIFT (2u) +#define UART_CR2_SDEL_LEN_WIDTH (1u) + +#define UART_CR2_ADDM_MASK (0x00000010ul) +#define UART_CR2_ADDM_4BITS (0x00000000ul) +#define UART_CR2_ADDM_7BITS (0x00000010ul) +#define UART_CR2_ADDM_SHIFT (4u) +#define UART_CR2_ADDM_WIDTH (1u) + +#define UART_CR2_LBDL_MASK (0x00000060ul) +#define UART_CR2_LBDL_11BITS (0x00000000ul) +#define UART_CR2_LBDL_12BITS (0x00000020ul) +#define UART_CR2_LBDL_13BITS (0x00000040ul) +#define UART_CR2_LBDL_SHIFT (5u) +#define UART_CR2_LBDL_WIDTH (2u) + +#define UART_CR2_LBDTIE_MASK (0x00000080ul) +#define UART_CR2_LBDTIE_SHIFT (7u) +#define UART_CR2_LBDTIE_WIDTH (1u) + +#define UART_CR2_IDLECFG_MASK (0x00000700ul) +#define UART_CR2_IDLECFG_1DILE_CHAR (0x00000000ul) +#define UART_CR2_IDLECFG_2DILE_CHAR (0x00000100ul) +#define UART_CR2_IDLECFG_4DILE_CHAR (0x00000200ul) +#define UART_CR2_IDLECFG_8DILE_CHAR (0x00000300ul) +#define UART_CR2_IDLECFG_16DILE_CHAR (0x00000400ul) +#define UART_CR2_IDLECFG_32DILE_CHAR (0x00000500ul) +#define UART_CR2_IDLECFG_64DILE_CHAR (0x00000600ul) +#define UART_CR2_IDLECFG_128DILE_CHAR (0x00000700ul) +#define UART_CR2_IDLECFG_SHIFT (8u) +#define UART_CR2_IDLECFG_WIDTH (3u) + +#define UART_CR2_STOP_MASK (0x00002000ul) +#define UART_CR2_STOP_SHIFT (13u) +#define UART_CR2_STOP_WIDTH (1u) + +#define UART_CR2_LINEN_MASK (0x00004000ul) +#define UART_CR2_LINEN_SHIFT (14u) +#define UART_CR2_LINEN_WIDTH (1u) + +#define UART_CR2_RXINV_MASK (0x00010000ul) +#define UART_CR2_RXINV_SHIFT (16u) +#define UART_CR2_RXINV_WIDTH (1u) + +#define UART_CR2_TXINV_MASK (0x00020000ul) +#define UART_CR2_TXINV_SHIFT (17u) +#define UART_CR2_TXINV_WIDTH (1u) + +#define UART_CR2_DATAINV_MASK (0x00040000ul) +#define UART_CR2_DATAINV_SHIFT (18u) +#define UART_CR2_DATAINV_WIDTH (1u) + +#define UART_CR2_MSBFIRST_MASK (0x00080000ul) +#define UART_CR2_MSBFIRST_SHIFT (19u) +#define UART_CR2_MSBFIRST_WIDTH (1u) + +#define UART_CR2_ABREN_MASK (0x00100000ul) +#define UART_CR2_ABREN_SHIFT (20u) +#define UART_CR2_ABREN_WIDTH (1u) + +#define UART_CR2_ABRMOD_MASK (0x00600000ul) +#define UART_CR2_ABRMOD_SHIFT (21u) +#define UART_CR2_ABRMOD_WIDTH (2u) + +#define UART_CR2_RTOEN_MASK (0x00800000ul) +#define UART_CR2_RTOEN_SHIFT (23u) +#define UART_CR2_RTOEN_WIDTH (1u) + +#define UART_CR2_ADD_MASK (0xFF000000ul) +#define UART_CR2_ADD_SHIFT (24u) +#define UART_CR2_ADD_WIDTH (8u) + +/* CR3 Bit fields */ +#define UART_CR3_EIE_MASK (0x00000001uL) +#define UART_CR3_EIE_SHIFT (0u) +#define UART_CR3_EIE_WIDTH (1u) + +#define UART_CR3_LOOPS_MASK (0x00000004uL) +#define UART_CR3_LOOPS_SHIFT (2u) +#define UART_CR3_LOOPS_WIDTH (1u) + +#define UART_CR3_HDSEL_MASK (0x00000008uL) +#define UART_CR3_HDSEL_SHIFT (3u) +#define UART_CR3_HDSEL_WIDTH (1u) + +#define UART_CR3_DMAR_MASK (0x00000040ul) +#define UART_CR3_DMAR_SHIFT (6u) +#define UART_CR3_DMAR_WIDTH (1u) + +#define UART_CR3_DMAT_MASK (0x00000080ul) +#define UART_CR3_DMAT_SHIFT (7u) +#define UART_CR3_DMAT_WIDTH (1u) + +#define UART_CR3_RTSE_MASK (0x00000100ul) +#define UART_CR3_RTSE_SHIFT (8u) +#define UART_CR3_RTSE_WIDTH (1u) + +#define UART_CR3_CTSE_MASK (0x00000200ul) +#define UART_CR3_CTSE_SHIFT (9u) +#define UART_CR3_CTSE_WIDTH (1u) + +#define UART_CR3_CTSIE_MASK (0x00000400ul) +#define UART_CR3_CTSIE_SHIFT (10u) +#define UART_CR3_CTSIE_WIDTH (1u) + +#define UART_CR3_ONEBIT_MASK (0x00000800ul) +#define UART_CR3_ONEBIT_SHIFT (11u) +#define UART_CR3_ONEBIT_WIDTH (1u) + +#define UART_CR3_DEM_MASK (0x00004000ul) +#define UART_CR3_DEM_SHIFT (14u) +#define UART_CR3_DEM_WIDTH (1u) + +#define UART_CR3_DEP_MASK (0x00008000ul) +#define UART_CR3_DEP_SHIFT (15u) +#define UART_CR3_DEP_WIDTH (1u) + +/* BRR Bit fields */ +#define UART_BRR_BRR_MASK (0x00FFFFFFul) +#define UART_BRR_BRR_SHIFT (0u) +#define UART_BRR_BRR_WIDTH (24u) + +/* RTOR Bit fields */ +#define UART_RTOR_RTO_MASK (0x00FFFFFFul) +#define UART_RTOR_RTO_SHIFT (0u) +#define UART_RTOR_RTO_WIDTH (24u) + +/* RQR Bit fields */ +#define UART_RQR_ABRRQ_MASK (0x00000001ul) +#define UART_RQR_ABRRQ_SHIFT (0u) +#define UART_RQR_ABRRQ_WIDTH (1u) + +#define UART_RQR_SBRKRQ_MASK (0x00000002ul) +#define UART_RQR_SBRKRQ_SHIFT (1u) +#define UART_RQR_SBRKRQ_WIDTH (1u) + +#define UART_RQR_MMRQ_MASK (0x00000004ul) +#define UART_RQR_MMRQ_SHIFT (2u) +#define UART_RQR_MMRQ_WIDTH (1u) + +/* ISR Bit fields */ +#define UART_ISR_PE_MASK (0x00000001ul) +#define UART_ISR_PE_SHIFT (0u) +#define UART_ISR_PE_WIDTH (1u) + +#define UART_ISR_FE_MASK (0x00000002ul) +#define UART_ISR_FE_SHIFT (1u) +#define UART_ISR_FE_WIDTH (1u) + +#define UART_ISR_NF_MASK (0x00000004ul) +#define UART_ISR_NF_SHIFT (2u) +#define UART_ISR_NF_WIDTH (1u) + +#define UART_ISR_ORE_MASK (0x00000008ul) +#define UART_ISR_ORE_SHIFT (3u) +#define UART_ISR_ORE_WIDTH (1u) + +#define UART_ISR_IDLE_MASK (0x00000010ul) +#define UART_ISR_IDLE_SHIFT (4u) +#define UART_ISR_IDLE_WIDTH (1u) + +#define UART_ISR_RDRF_MASK (0x00000020ul) +#define UART_ISR_RDRF_SHIFT (5u) +#define UART_ISR_RDRF_WIDTH (1u) + +#define UART_ISR_TC_MASK (0x00000040ul) +#define UART_ISR_TC_SHIFT (6u) +#define UART_ISR_TC_WIDTH (1u) + +#define UART_ISR_TDRE_MASK (0x00000080ul) +#define UART_ISR_TDRE_SHIFT (7u) +#define UART_ISR_TDRE_WIDTH (1u) + +#define UART_ISR_LBDT_DONE_MASK (0x00000100ul) +#define UART_ISR_LBDT_DONE_SHIFT (8u) +#define UART_ISR_LBDT_DONE_WIDTH (1u) + +#define UART_ISR_CTSIF_MASK (0x00000200ul) +#define UART_ISR_CTSIF_SHIFT (9u) +#define UART_ISR_CTSIF_WIDTH (1u) + +#define UART_ISR_CTS_MASK (0x00000400ul) +#define UART_ISR_CTS_SHIFT (10u) +#define UART_ISR_CTS_WIDTH (1u) + +#define UART_ISR_RTOF_MASK (0x00000800ul) +#define UART_ISR_RTOF_SHIFT (11u) +#define UART_ISR_RTOF_WIDTH (1u) + +#define UART_ISR_ABRE_MASK (0x00004000ul) +#define UART_ISR_ABRE_SHIFT (14u) +#define UART_ISR_ABRE_WIDTH (1u) + +#define UART_ISR_ABRF_MASK (0x00008000ul) +#define UART_ISR_ABRF_SHIFT (15u) +#define UART_ISR_ABRF_WIDTH (1u) + +#define UART_ISR_BUSY_MASK (0x00010000ul) +#define UART_ISR_BUSY_SHIFT (16u) +#define UART_ISR_BUSY_WIDTH (1u) + +#define UART_ISR_LBDT_FAIL_MASK (0x00020000ul) +#define UART_ISR_LBDT_FAIL_SHIFT (17u) +#define UART_ISR_LBDT_FAIL_WIDTH (1u) + +#define UART_ISR_SBRKD_MASK (0x00040000ul) +#define UART_ISR_SBRKD_SHIFT (18u) +#define UART_ISR_SBRKD_WIDTH (1u) + +#define UART_ISR_RWU_MASK (0x00080000ul) +#define UART_ISR_RWU_SHIFT (19u) +#define UART_ISR_RWU_WIDTH (1u) + +/* ICR Bit fields */ +#define UART_ICR_PECF_MASK (0x00000001ul) +#define UART_ICR_PECF_SHIFT (0u) +#define UART_ICR_PECF_WIDTH (1u) + +#define UART_ICR_FECF_MASK (0x00000002ul) +#define UART_ICR_FECF_SHIFT (1u) +#define UART_ICR_FECF_WIDTH (1u) + +#define UART_ICR_NCF_MASK (0x00000004ul) +#define UART_ICR_NCF_SHIFT (2u) +#define UART_ICR_NCF_WIDTH (1u) + +#define UART_ICR_ORECF_MASK (0x00000008ul) +#define UART_ICR_ORECF_SHIFT (3u) +#define UART_ICR_ORECF_WIDTH (1u) + +#define UART_ICR_IDLECF_MASK (0x00000010ul) +#define UART_ICR_IDLECF_SHIFT (4u) +#define UART_ICR_IDLECF_WIDTH (1u) + +#define UART_ICR_TCCF_MASK (0x00000040ul) +#define UART_ICR_TCCF_SHIFT (6u) +#define UART_ICR_TCCF_WIDTH (1u) + +#define UART_ICR_LBDTCF_MASK (0x00000100ul) +#define UART_ICR_LBDTCF_SHIFT (8u) +#define UART_ICR_LBDTCF_WIDTH (1u) + +#define UART_ICR_CTSCF_MASK (0x00000200ul) +#define UART_ICR_CTSCF_SHIFT (9u) +#define UART_ICR_CTSCF_WIDTH (1u) + +#define UART_ICR_RTOCF_MASK (0x00000800ul) +#define UART_ICR_RTOCF_SHIFT (11u) +#define UART_ICR_RTOCF_WIDTH (1u) + +#define UART_ICR_SBRKDCF_MASK (0x00040000ul) +#define UART_ICR_SBRKDCF_SHIFT (18u) +#define UART_ICR_SBRKDCF_WIDTH (1u) + +/* RDR Bit fields */ +#define UART_RDR_RDR_MASK (0x000001FFul) +#define UART_RDR_RDR_SHIFT (0u) +#define UART_RDR_RDR_WIDTH (9u) + +#define UART_RDR_FE_MASK (0x00002000ul) +#define UART_RDR_FE_SHIFT (13u) +#define UART_RDR_FE_WIDTH (1u) + +#define UART_RDR_PE_MASK (0x00004000ul) +#define UART_RDR_PE_SHIFT (14u) +#define UART_RDR_PE_WIDTH (1u) + +#define UART_RDR_NF_MASK (0x00008000ul) +#define UART_RDR_NF_SHIFT (15u) +#define UART_RDR_NF_WIDTH (1u) + +#define UART_RDR_ERR_MASK (0x0000E000ul) +#define UART_RDR_ERR_SHIFT (13u) +#define UART_RDR_ERR_WIDTH (3u) + +/* TDR Bit fields */ +#define UART_TDR_TDR_MASK (0x000001FFul) +#define UART_TDR_TDR_SHIFT (0u) +#define UART_TDR_TDR_WIDTH (9u) + +/* FIFO Bit fields */ +#define UART_FIFO_RXUFE_MASK (0x00000100ul) +#define UART_FIFO_RXUFE_SHIFT (8u) +#define UART_FIFO_RXUFE_WIDTH (1u) + +#define UART_FIFO_TXOFE_MASK (0x00000200ul) +#define UART_FIFO_TXOFE_SHIFT (9u) +#define UART_FIFO_TXOFE_WIDTH (1u) + +#define UART_FIFO_RXFLUSH_MASK (0x00004000ul) +#define UART_FIFO_RXFLUSH_SHIFT (14u) +#define UART_FIFO_RXFLUSH_WIDTH (1u) + +#define UART_FIFO_TXFLUSH_MASK (0x00008000ul) +#define UART_FIFO_TXFLUSH_SHIFT (15u) +#define UART_FIFO_TXFLUSH_WIDTH (1u) + +#define UART_FIFO_RXUF_MASK (0x00010000ul) +#define UART_FIFO_RXUF_SHIFT (16u) +#define UART_FIFO_RXUF_WIDTH (1u) + +#define UART_FIFO_TXOF_MASK (0x00020000ul) +#define UART_FIFO_TXOF_SHIFT (17u) +#define UART_FIFO_TXOF_WIDTH (1u) + +#define UART_FIFO_RXEMPT_MASK (0x00400000ul) +#define UART_FIFO_RXEMPT_SHIFT (22u) +#define UART_FIFO_RXEMPT_WIDTH (1u) + +#define UART_FIFO_TXEMPT_MASK (0x00800000ul) +#define UART_FIFO_TXEMPT_SHIFT (23u) +#define UART_FIFO_TXEMPT_WIDTH (1u) + +/* WATER Bit fields */ +#define UART_WATER_TXWATER_MASK (0x00000003ul) +#define UART_WATER_TXWATER_SHIFT (0u) +#define UART_WATER_TXWATER_WIDTH (2u) + +#define UART_WATER_TXCOUNT_MASK (0x00000700ul) +#define UART_WATER_TXCOUNT_SHIFT (8u) +#define UART_WATER_TXCOUNT_WIDTH (3u) +#define UART_WATER_RXWATER_MASK (0x00030000ul) +#define UART_WATER_RXWATER_SHIFT (16u) +#define UART_WATER_RXWATER_WIDTH (2u) + +#define UART_WATER_RXCOUNT_MASK (0x07000000ul) +#define UART_WATER_RXCOUNT_SHIFT (24u) +#define UART_WATER_RXCOUNT_WIDTH (3u) + +/****************************************************************************** + * the typedefs + *****************************************************************************/ + +/*! \brief The definition of UART registers */ +typedef struct _UartRegType_ +{ + volatile uint32_t CR1; /*!< UART Control Register 1, offset: 0x0 */ + volatile uint32_t CR2; /*!< UART Control Register 2, offset: 0x4 */ + volatile uint32_t CR3; /*!< UART Control Register 3, offset: 0x8 */ + volatile uint32_t BRR; /*!< UART Baud Rate Register, offset: 0xC */ + uint32_t RES; + volatile uint32_t RTOR; /*!< UART Receiver timeout Value Register, offset: 0x14 */ + volatile uint32_t RQR; /*!< UART Request Register, offset: 0x18 */ + volatile const uint32_t ISR; /*!< UART Status Register, offset: 0x1C */ + volatile uint32_t ICR; /*!< UART Interrupt Clear Register, offset: 0x20 */ + volatile uint32_t RDR; /*!< UART Receive data Register, offset: 0x24 */ + volatile uint32_t TDR; /*!< UART Transmit data Register, offset: 0x28 */ + volatile uint32_t FIFO; /*!< UART FIFO Register, offset: 0x2C */ + volatile uint32_t WATER; /*!< UART Watermark Register, offset: 0x30 */ +} UartRegType; + +/****************************************************************************** + * the globals + ******************************************************************************/ + +/****************************************************************************** + * the function prototypes + ******************************************************************************/ + +/*! \brief Receiver timeout interrupt enable or disable + * + * this function enable the rx timeout interrupt features + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable : + * 0: Interrupt is inhibited + * 1: An UART interrupt is generated when the RTOF bit is set in the ISR register. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetRxTimeoutIsr(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR1; + + if(enable == true) + { + obj->CR1 = ((1ul << UART_CR1_RTOIE_SHIFT) | ((~UART_CR1_RTOIE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_RTOIE_SHIFT) | ((~UART_CR1_RTOIE_MASK) & tmp)); + } +} + +/*! \brief Get the RxTimeoutIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetRxTimeoutIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->CR1 & UART_CR1_RTOIE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief Driver Enable assertion time + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] deat :This 5-bit value defines the time between the activation of the DE (Driver Enable) signal and the beginning of the start bit + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetDEAT(UartRegType *obj, uint8_t deat) +{ + uint32_t tmp = obj->CR1; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR1_DEAT_MASK; + tmp |= (((uint32_t)(((uint32_t)(deat)) << UART_CR1_DEAT_SHIFT)) & UART_CR1_DEAT_MASK); + obj->CR1 = tmp; +} + +/*! \brief Driver Enable de-assertion time + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] dedt: This 5-bit value defines the time between the end of the last stop bit, + * in a transmitted message, and the de-activation of the DE (Driver Enable) signal + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetDEDT(UartRegType *obj, uint8_t dedt) +{ + uint32_t tmp = obj->CR1; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR1_DEDT_MASK; + tmp |= (((uint32_t)(((uint32_t)(dedt)) << UART_CR1_DEDT_SHIFT)) & UART_CR1_DEDT_MASK); + obj->CR1 = tmp; +} + +/*! \brief Oversampling mode + * + * This bit can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] samplingBy8BitModeEn: + * 0: Oversampling by 16 + * 1: Oversampling by 8 + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetOverSamplingMode(UartRegType *obj, bool samplingBy8BitModeEn) +{ + uint32_t tmp = obj->CR1; + + if(samplingBy8BitModeEn == true) + { + obj->CR1 = ((1ul << UART_CR1_OVER8_SHIFT) | ((~UART_CR1_OVER8_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_OVER8_SHIFT) | ((~UART_CR1_OVER8_MASK) & tmp)); + } +} + +/*! \brief SBRKD interrupt enable + * + * this function enable the break tx completed interrupt request if finished tx break signal + * + * \param[in] obj : pointer to UART driver instance + * \param[in] txBreakOkIsr: + * 0: Interrupt is inhibited + * 1: A UART interrupt is generated whenever SBRKD=1 in the ISR register + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetBreakTxCompletedIsr(UartRegType *obj, bool txBreakOkIsr) +{ + uint32_t tmp = obj->CR1; + + if(txBreakOkIsr == true) + { + obj->CR1 = ((1ul << UART_CR1_SBRKDIE_SHIFT) | ((~UART_CR1_SBRKDIE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_SBRKDIE_SHIFT) | ((~UART_CR1_SBRKDIE_MASK) & tmp)); + } +} + +/*! \brief Get the BreakTxCompletedIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetBreakTxCompletedIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->CR1 & UART_CR1_SBRKDIE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief Mute mode enable + * + * This bit activates the mute mode function of the UART. when set, the UART can switch between the active and mute modes, + * as defined by the WAKE bit. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] muteEn: + * 0: Receiver in active mode permanently + * 1: Receiver can switch between mute mode and active mode. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetMuteMode(UartRegType *obj, bool muteEn) +{ + uint32_t tmp = obj->CR1; + + if(muteEn == true) + { + obj->CR1 = ((1ul << UART_CR1_MME_SHIFT) | ((~UART_CR1_MME_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_MME_SHIFT) | ((~UART_CR1_MME_MASK) & tmp)); + } +} + +/*! \brief Get the mute + * + * this function get the mute mode is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * 0: Receiver in active mode permanently + * 1: Receiver can switch between mute mode and active mode. + */ +__attribute__((always_inline)) static inline bool UartReg_GetMuteIsActive(const UartRegType *obj) +{ + bool tRtn = false; + + if((obj->CR1 & UART_CR1_MME_MASK) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief Set Word length + * + * this function set the frame bits formate + * + * \param[in] obj : pointer to UART driver instance + * \param[in] wordLen: + * 0: 1 Start bit, 8 data bits, n stop bits + * 1: 1 Start bit, 9 data bits, n stop bits + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetWordLength(UartRegType *obj, uint8_t wordLen) +{ + uint32_t tmp = obj->CR1; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR1_M_MASK; + tmp |= (((uint32_t)(((uint32_t)(wordLen)) << UART_CR1_M_SHIFT)) & UART_CR1_M_MASK); + obj->CR1 = tmp; +} + +/*! \brief Set Receiver wakeup method + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] wkpMethod: + * 0: Idle line + * 1: Address mark + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetWakeupMethod(UartRegType *obj, uint8_t wkpMethod) +{ + uint32_t tmp = obj->CR1; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR1_WAKE_MASK; + tmp |= (((uint32_t)(((uint32_t)(wkpMethod)) << UART_CR1_WAKE_SHIFT)) & UART_CR1_WAKE_MASK); + obj->CR1 = tmp; +} + +/*! \brief Get wake up source + * + * this function get the address to wakeup + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * 0: Idle line + * 1: Address mark + */ +__attribute__((always_inline)) static inline bool UartReg_GetWakeUpByAddress(const UartRegType *obj) +{ + bool tRtn = false; + + if((obj->CR1 & UART_CR1_WAKE_MASK) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief selects the hardware parity control + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] parityCtrlEn: enable or disable + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetParityControlEnable(UartRegType *obj, bool parityCtrlEn) +{ + uint32_t tmp = obj->CR1; + + if(parityCtrlEn == true) + { + obj->CR1 = ((1ul << UART_CR1_PCE_SHIFT) | ((~UART_CR1_PCE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_PCE_SHIFT) | ((~UART_CR1_PCE_MASK) & tmp)); + } +} + +/*! \brief This bit selects the odd or even parity when the parity generation/detection is enabled (PCE bit set). + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] paritySelection: + * 0: Even parity + * 1: Odd parity + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SelectParity(UartRegType *obj, uint8_t paritySelection) +{ + uint32_t tmp = obj->CR1; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR1_PS_MASK; + tmp |= (((uint32_t)(((uint32_t)(paritySelection)) << UART_CR1_PS_SHIFT)) & UART_CR1_PS_MASK); + obj->CR1 = tmp; +} + +/*! \brief Set Parity error interrupt enable or disable + * + * this function set the Parity error interrupt enable or disable + * + * \param[in] obj : pointer to UART driver instance + * \param[in] parityErrIsrEn: + * 0: Interrupt is inhibited + * 1: A UART interrupt is generated whenever PE=1 in the ISR register + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetParityErrIsr(UartRegType *obj, bool parityErrIsrEn) +{ + uint32_t tmp = obj->CR1; + + if(parityErrIsrEn == true) + { + obj->CR1 = ((1ul << UART_CR1_PEIE_SHIFT) | ((~UART_CR1_PEIE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_PEIE_SHIFT) | ((~UART_CR1_PEIE_MASK) & tmp)); + } +} + +/*! \brief Get the ParityErrIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetParityErrIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->CR1 & UART_CR1_PEIE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief Set tx buffer empty interrupt enable or disable + * + * this function set the tx buffer empty interrupt request when condition is matched + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Interrupt is inhibited + * 1: A UART interrupt is generated whenever TDRE=1 in the ISR register + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetTxBufferEmptyIsr(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR1; + + if(enable == true) + { + obj->CR1 = ((1ul << UART_CR1_TDREIE_SHIFT) | ((~UART_CR1_TDREIE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_TDREIE_SHIFT) | ((~UART_CR1_TDREIE_MASK) & tmp)); + } +} + +/*! \brief Get the TxBufferEmptyIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetTxBufferEmptyIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->CR1 & UART_CR1_TDREIE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief Set Transmission complete interrupt enable or disable + * + * This bit is set and cleared by software. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Interrupt is inhibited + * 1: A UART interrupt is generated whenever TC=1 in the ISR register + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetTxCompletedIsr(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR1; + + if(enable == true) + { + obj->CR1 = ((1ul << UART_CR1_TCIE_SHIFT) | ((~UART_CR1_TCIE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_TCIE_SHIFT) | ((~UART_CR1_TCIE_MASK) & tmp)); + } +} + +/*! \brief Get the TxCompletedIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetTxCompletedIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->CR1 & UART_CR1_TCIE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief Set rx buffer full interrupt enable or disable + * + * this function set the rx buffer full interrupt request when condition is matched + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Interrupt is inhibited + * 1: A UART interrupt is generated when RDRF=1 in the ISR register + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetRxBufferFullIsr(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR1; + + if(enable == true) + { + obj->CR1 = ((1ul << UART_CR1_RDRFIE_SHIFT) | ((~UART_CR1_RDRFIE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_RDRFIE_SHIFT) | ((~UART_CR1_RDRFIE_MASK) & tmp)); + } +} + +/*! \brief Get the RxBufferFullIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetRxBufferFullIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->CR1 & UART_CR1_RDRFIE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief Set IDLE interrupt enable or disable + * + * this function set the idle interrupt request when condition is matched + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Interrupt is inhibited + * 1: A UART interrupt is generated whenever IDLE=1 in the ISR register + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetIdleIsr(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR1; + + if(enable == true) + { + obj->CR1 = ((1ul << UART_CR1_IDLEIE_SHIFT) | ((~UART_CR1_IDLEIE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_IDLEIE_SHIFT) | ((~UART_CR1_IDLEIE_MASK) & tmp)); + } +} + +/*! \brief Get the IdleIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetIdleIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->CR1 & UART_CR1_IDLEIE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief Set Transmitter enable or disable + * + * this function enable the transmitter feature + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Transmitter is disabled + * 1: Transmitter is enabled + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetTransmitterEnable(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR1; + + if(enable == true) + { + obj->CR1 = ((1ul << UART_CR1_TE_SHIFT) | ((~UART_CR1_TE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_TE_SHIFT) | ((~UART_CR1_TE_MASK) & tmp)); + } +} + +/*! \brief Set Receiver enable or disable + * + * this function enable the receive feature + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Receiver is disabled + * 1: Receiver is enabled and begins searching for a start bit + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetReceiverEnable(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR1; + + if(enable == true) + { + obj->CR1 = ((1ul << UART_CR1_RE_SHIFT) | ((~UART_CR1_RE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_RE_SHIFT) | ((~UART_CR1_RE_MASK) & tmp)); + } +} + +/*! \brief UART module enable + * + * In order to go into low-power mode without generating errors on the line, the TE bit must be reset before and + * the software must wait for the TC bit in the ISR to be set before resetting the UE bit. + * The DMA requests are also reset when UE = 0 so the DMA channel must be disabled before resetting the UE bit. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: UART prescaler and outputs disabled, low-power mode + * 1: UART enabled + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableModule(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR1; + + if(enable == true) + { + obj->CR1 = ((1ul << UART_CR1_UE_SHIFT) | ((~UART_CR1_UE_MASK) & tmp)); + } + else + { + obj->CR1 = ((0ul << UART_CR1_UE_SHIFT) | ((~UART_CR1_UE_MASK) & tmp)); + } +} + +/*! \brief Get UART module enable state + * + * This function get the enable state of LPTMR. + * When UE is clear, the UART is disabled. + * When UE is set, the UART is enabled. + * + * \param[in] obj : pointer to UART driver instance + * \return the state of the UART + * - 0 : UART is disabled. + * - 1 : UART is enabled. + */ +__attribute__((always_inline)) static inline uint8_t UartReg_GetEnable(const UartRegType *obj) +{ + return ((obj->CR1 & UART_CR1_UE_MASK) >> UART_CR1_UE_SHIFT); +} + +/*! \brief Set Address of the UART node + * + * This bit field can only be written when reception is disabled (RE = 0) or the UART is disabled (UE=0) + * + * \param[in] obj : pointer to UART driver instance + * \param[in] address: This bit-field gives the address of the UART node or a character code to be recognized. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetNodeAddress(UartRegType *obj, uint8_t address) +{ + uint32_t tmp = obj->CR2; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR2_ADD_MASK; + tmp |= (((uint32_t)(((uint32_t)(address)) << UART_CR2_ADD_SHIFT)) & UART_CR2_ADD_MASK); + obj->CR2 = tmp; +} + +/*! \brief Receiver timeout enable + * + * When this feature is enabled, the RTOF flag in the ISR register is set if the RX line is idle (no reception) + * for the duration programmed in the RTOR (receiver timeout register). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Receiver timeout feature disabled. + * 1: Receiver timeout feature enabled. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableRxTimeoutFeature(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR2; + + if(enable == true) + { + obj->CR2 = ((1ul << UART_CR2_RTOEN_SHIFT) | ((~UART_CR2_RTOEN_MASK) & tmp)); + } + else + { + obj->CR2 = ((0ul << UART_CR2_RTOEN_SHIFT) | ((~UART_CR2_RTOEN_MASK) & tmp)); + } +} + +/*! \brief Get RxTimeout feature enable or disable + * + * this function get the config of rx timeout feature tha is enable or disable + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * 0: Receiver timeout feature disabled. + * 1: Receiver timeout feature enabled. + */ +__attribute__((always_inline)) static inline bool UartReg_GetRxTimeoutFeatureEnable(const UartRegType *obj) +{ + bool tRtn = false; + + if((obj->CR2 & UART_CR2_RTOEN_MASK) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief Auto baud rate mode + * + * This bit field can only be written when ABREN = 0 or the UART is disabled (UE=0). + * If DATAINV=1 and/or MSBFIRST=1 the patterns must be the same on the line, for example 0xAA for MSBFIRST) + * + * \param[in] obj : pointer to UART driver instance + * \param[in] autoMode: + * 00: Measurement of the start bit is used to detect the baud rate. + * 01: Falling edge to falling edge measurement. (the received frame must start with a single bit = 1 -> Frame = Start10xxxxxx) + * 10: 0x7F frame detection. + * 11: 0x55 frame detection + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetAutoBaudrateMode(UartRegType *obj, uint8_t autoMode) +{ + uint32_t tmp = obj->CR2; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR2_ABRMOD_MASK; + tmp |= (((uint32_t)(((uint32_t)(autoMode)) << UART_CR2_ABRMOD_SHIFT)) & UART_CR2_ABRMOD_MASK); + obj->CR2 = tmp; +} + +/*! \brief Auto baud rate mode + * + * This bit field can only be written when ABREN = 0 or the UART is disabled (UE=0). + * If DATAINV=1 and/or MSBFIRST=1 the patterns must be the same on the line, for example 0xAA for MSBFIRST) + * + * \param[in] obj : pointer to UART driver instance + * \return: uint8_t + * 00: Measurement of the start bit is used to detect the baud rate. + * 01: Falling edge to falling edge measurement. (the received frame must start with a single bit = 1 -> Frame = Start10xxxxxx) + * 10: 0x7F frame detection. + * 11: 0x55 frame detection + */ +__attribute__((always_inline)) static inline uint8_t UartReg_GetAutoBaudrateMode(const UartRegType *obj) +{ + uint8_t tRtn = 0; + uint32_t tmp = obj->CR2; + + tRtn = ((tmp & UART_CR2_ABRMOD_MASK) >> UART_CR2_ABRMOD_SHIFT) & 0xFF; + + return tRtn; +} + +/*! \brief Set Auto baud rate enable or disable + * + * this function enable auto baudrate features + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Auto baud rate detection is disabled. + * 1: Auto baud rate detection is enabled. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableAutoBaudrateFeature(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR2; + + if(enable == true) + { + obj->CR2 = ((1ul << UART_CR2_ABREN_SHIFT) | ((~UART_CR2_ABREN_MASK) & tmp)); + } + else + { + obj->CR2 = ((0ul << UART_CR2_ABREN_SHIFT) | ((~UART_CR2_ABREN_MASK) & tmp)); + } +} + +/*! \brief Most significant bit first + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] mbsFirst: + * 0: data is transmitted/received with data bit 0 first, following the start bit. + * 1: data is transmitted/received with the MSB (bit 7/8/9) first, following the start bit. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetFirstBitShift(UartRegType *obj, uint8_t mbsFirst) +{ + uint32_t tmp = obj->CR2; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR2_MSBFIRST_MASK; + tmp |= (((uint32_t)(((uint32_t)(mbsFirst)) << UART_CR2_MSBFIRST_SHIFT)) & UART_CR2_MSBFIRST_MASK); + obj->CR2 = tmp; +} + +/*! \brief Binary data inversion + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Logical data from the data register are send/received in positive/direct logic. (1=H, 0=L) + * 1: Logical data from the data register are send/received in negative/inverse logic. (1=L, 0=H). The parity bit is also inverted. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableDataInverteFeature(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR2; + + if(enable == true) + { + obj->CR2 = ((1ul << UART_CR2_DATAINV_SHIFT) | ((~UART_CR2_DATAINV_MASK) & tmp)); + } + else + { + obj->CR2 = ((0ul << UART_CR2_DATAINV_SHIFT) | ((~UART_CR2_DATAINV_MASK) & tmp)); + } +} + +/*! \brief TX pin active level inversion + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: TX pin signal works using the standard logic levels (VDD =1/idle, Gnd=0/mark) + * 1: TX pin signal values are inverted. (VDD =0/mark, Gnd=1/idle). This allows the use of an external inverter on the TX line. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableTxInverteFeature(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR2; + + if(enable == true) + { + obj->CR2 = ((1ul << UART_CR2_TXINV_SHIFT) | ((~UART_CR2_TXINV_MASK) & tmp)); + } + else + { + obj->CR2 = ((0ul << UART_CR2_TXINV_SHIFT) | ((~UART_CR2_TXINV_MASK) & tmp)); + } +} + +/*! \brief RX pin active level inversion + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: RX pin signal works using the standard logic levels (VDD =1/idle, Gnd=0/mark) + * 1: RX pin signal values are inverted. (VDD =0/mark, Gnd=1/idle). This allows the use of an external inverter on the RX line. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableRxInverteFeature(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR2; + + if(enable == true) + { + obj->CR2 = ((1ul << UART_CR2_RXINV_SHIFT) | ((~UART_CR2_RXINV_MASK) & tmp)); + } + else + { + obj->CR2 = ((0ul << UART_CR2_RXINV_SHIFT) | ((~UART_CR2_RXINV_MASK) & tmp)); + } +} + +/*! \brief LIN feature enable or disable + * + * this function is used only in lin mode + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: LIN break detect disabled + * 1: LIN break detect enabled + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableLineBreakDetectFeature(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR2; + + if(enable == true) + { + obj->CR2 = ((1ul << UART_CR2_LINEN_SHIFT) | ((~UART_CR2_LINEN_MASK) & tmp)); + } + else + { + obj->CR2 = ((0ul << UART_CR2_LINEN_SHIFT) | ((~UART_CR2_LINEN_MASK) & tmp)); + } +} + +/*! \brief Get break synect detected enable status + * + * this function get the lin break detected features tha is enable or disbale + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * 0: LIN break detect disabled + * 1: LIN break detect enabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetLinBreakDetecteEnable(const UartRegType *obj) +{ + bool tRtn = false; + + if((obj->CR2 & UART_CR2_LINEN_MASK) != 0u) + { + tRtn = true; + } + + return tRtn; +} + +/*! \brief These bits are used for programming the stop bits. + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] stopBitsNum: + * 0: 1 stop bit + * 1: 2 stop bits + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetStopBitNums(UartRegType *obj, uint8_t stopBitsNum) +{ + uint32_t tmp = obj->CR2; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR2_STOP_MASK; + tmp |= (((uint32_t)(((uint32_t)(stopBitsNum)) << UART_CR2_STOP_SHIFT)) & UART_CR2_STOP_MASK); + obj->CR2 = tmp; +} + +/*! \brief Configures the number of idle characters that must be received before the IDLE flag is set. + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] idleCfg: + * 000b : 1 idle character + * 001b : 2 idle characters + * 010b : 4 idle characters + * 011b : 8 idle characters + * 100b : 16 idle characters + * 101b : 32 idle characters + * 110b : 64 idle characters + * 111b : 128 idle characters + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetIdleConfig(UartRegType *obj, uint8_t idleCfg) +{ + uint32_t tmp = obj->CR2; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR2_IDLECFG_MASK; + tmp |= (((uint32_t)(((uint32_t)(idleCfg)) << UART_CR2_IDLECFG_SHIFT)) & UART_CR2_IDLECFG_MASK); + obj->CR2 = tmp; +} + +/*! \brief LIN break detection done interrupt enable + * + * this function set lin break signal detected to trigger one interrupt request + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Interrupt is inhibited + * 1: An interrupt is generated whenever LBDT_DONE=1 in the ISR register + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetLinBreakDetectedIsr(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR2; + + if(enable == true) + { + obj->CR2 = ((1ul << UART_CR2_LBDTIE_SHIFT) | ((~UART_CR2_LBDTIE_MASK) & tmp)); + } + else + { + obj->CR2 = ((0ul << UART_CR2_LBDTIE_SHIFT) | ((~UART_CR2_LBDTIE_MASK) & tmp)); + } +} + +/*! \brief Get the LinBreakDetectedIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetLinBreakDetectedIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->CR2 & UART_CR2_LBDTIE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief LIN synch break detect length + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] breakLen: + * 00: 11bit + * 01: 12bit + * 10: 13bit + * 11: 11bit + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetLinSyncBreakDetectLen(UartRegType *obj, uint8_t breakLen) +{ + uint32_t tmp = obj->CR2; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR2_LBDL_MASK; + tmp |= (((uint32_t)(((uint32_t)(breakLen)) << UART_CR2_LBDL_SHIFT)) & UART_CR2_LBDL_MASK); + obj->CR2 = tmp; +} + +/*! \brief This bit is for selection between 4-bit address detection or 7-bit address detection. + * + * This bit can only be written when the UART is disabled (UE=0) + * + * \param[in] obj : pointer to UART driver instance + * \param[in] addressSelection: + * 0: 4-bit address detection + * 1: 7-bit address detection (in 8-bit data mode) + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetAddreDetectMode(UartRegType *obj, uint8_t addressSelection) +{ + uint32_t tmp = obj->CR2; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR2_ADDM_MASK; + tmp |= (((uint32_t)(((uint32_t)(addressSelection)) << UART_CR2_ADDM_SHIFT)) & UART_CR2_ADDM_MASK); + obj->CR2 = tmp; +} + +/*! \brief Config Transmiting LIN Delimitor Width + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] delimitorWidth: + * 0 : 1 bit + * 1 : 2 bits + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetLinDelimitorWidth(UartRegType *obj, uint8_t delimitorWidth) +{ + uint32_t tmp = obj->CR2; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR2_SDEL_LEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(delimitorWidth)) << UART_CR2_SDEL_LEN_SHIFT)) & UART_CR2_SDEL_LEN_MASK); + obj->CR2 = tmp; +} + +/*! \brief Config Transmiting synch break Width + * + * This bit field can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] syncBreakLen: + * 00b : 13 bits + * 01b : 14 bits + * 10b : 15 bits + * 11b : 13 bits + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetTxLinSyncBreakWidth(UartRegType *obj, uint8_t syncBreakLen) +{ + uint32_t tmp = obj->CR2; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR2_SBRK_LEN_MASK; + tmp |= (((uint32_t)(((uint32_t)(syncBreakLen)) << UART_CR2_SBRK_LEN_SHIFT)) & UART_CR2_SBRK_LEN_MASK); + obj->CR2 = tmp; +} + +/*! \brief Driver enable polarity selection + * + * This bit can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] deInActiveIsLowEn: + * 0: DE signal is active high. + * 1: DE signal is active low. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetDriverPolarity(UartRegType *obj, bool deInActiveIsLowEn) +{ + uint32_t tmp = obj->CR3; + + if(deInActiveIsLowEn == true) + { + obj->CR3 = ((1ul << UART_CR3_DEP_SHIFT) | ((~UART_CR3_DEP_MASK) & tmp)); + } + else + { + obj->CR3 = ((0ul << UART_CR3_DEP_SHIFT) | ((~UART_CR3_DEP_MASK) & tmp)); + } +} + +/*! \brief This bit allows the user to activate the external transceiver control, through the DE signal + * + * This bit can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: DE function is disabled. + * 1: DE function is enabled. The DE signal is output on the RTS pin. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetDriverEnableMode(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR3; + + if(enable == true) + { + obj->CR3 = ((1ul << UART_CR3_DEM_SHIFT) | ((~UART_CR3_DEM_MASK) & tmp)); + } + else + { + obj->CR3 = ((0ul << UART_CR3_DEM_SHIFT) | ((~UART_CR3_DEM_MASK) & tmp)); + } +} + +/*! \brief This bit allows the user to select the sample method + * + * This bit can only be written when the UART is disabled (UE=0). ONEBIT feature applies only to data bits, It does not apply to Start bit. + * When the one sample bit method is selected the noise detection flag (NF) is disabled. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] sampleBitMethod: + * 0: Three sample bit method + * 1: One sample bit method + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetSampleBitMethod(UartRegType *obj, uint8_t sampleBitMethod) +{ + uint32_t tmp = obj->CR3; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_CR3_ONEBIT_MASK; + tmp |= (((uint32_t)(((uint32_t)(sampleBitMethod)) << UART_CR3_ONEBIT_SHIFT)) & UART_CR3_ONEBIT_MASK); + obj->CR3 = tmp; +} + +/*! \brief CTS interrupt enable + * + * this function set the cts interrupt request, but only in rs232 mode + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Interrupt is inhibited + * 1: An interrupt is generated whenever CTSIF=1 in the ISR register + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetCtsIsr(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR3; + + if(enable == true) + { + obj->CR3 = ((1ul << UART_CR3_CTSIE_SHIFT) | ((~UART_CR3_CTSIE_MASK) & tmp)); + } + else + { + obj->CR3 = ((0ul << UART_CR3_CTSIE_SHIFT) | ((~UART_CR3_CTSIE_MASK) & tmp)); + } +} + +/*! \brief Get the CtsIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetCtsIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->CR3 & UART_CR3_CTSIE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief CTS enable + * + * This bit can only be written when the UART is disabled (UE=0) + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: CTS hardware flow control disabled + * 1: CTS mode enabled, data is only transmitted when the CTS input + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableCts(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR3; + + if(enable == true) + { + obj->CR3 = ((1ul << UART_CR3_CTSE_SHIFT) | ((~UART_CR3_CTSE_MASK) & tmp)); + } + else + { + obj->CR3 = ((0ul << UART_CR3_CTSE_SHIFT) | ((~UART_CR3_CTSE_MASK) & tmp)); + } +} + +/*! \brief RTS enable or disable + * + * This bit can only be written when the UART is disabled (UE=0). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: RTS hardware flow control disabled + * 1: RTS output enabled, data is only requested when there is space in the receive buffer + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableRts(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR3; + + if(enable == true) + { + obj->CR3 = ((1ul << UART_CR3_RTSE_SHIFT) | ((~UART_CR3_RTSE_MASK) & tmp)); + } + else + { + obj->CR3 = ((0ul << UART_CR3_RTSE_SHIFT) | ((~UART_CR3_RTSE_MASK) & tmp)); + } +} + +/*! \brief DMA enable transmitter + * + * this function set the tx data used DMA mode + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: DMA mode is disabled for transmission + * 1: DMA mode is enabled for transmission + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableTxDMA(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR3; + + if(enable == true) + { + obj->CR3 = ((1ul << UART_CR3_DMAT_SHIFT) | ((~UART_CR3_DMAT_MASK) & tmp)); + } + else + { + obj->CR3 = ((0ul << UART_CR3_DMAT_SHIFT) | ((~UART_CR3_DMAT_MASK) & tmp)); + } +} + +/*! \brief DMA enable receiver + * + * This function set the received data used DMA + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: DMA mode is disabled for reception + * 1: DMA mode is enabled for reception + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_EnableRxDMA(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR3; + + if(enable == true) + { + obj->CR3 = ((1ul << UART_CR3_DMAR_SHIFT) | ((~UART_CR3_DMAR_MASK) & tmp)); + } + else + { + obj->CR3 = ((0ul << UART_CR3_DMAR_SHIFT) | ((~UART_CR3_DMAR_MASK) & tmp)); + } +} + +/*! \brief Half-duplex selection + * + * This bit can only be written when the UART is disabled (UE=0). If LOOPS and HDSEL are both 1, HDSEL is invalid. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Half duplex mode is not selected + * 1: Half duplex mode is selected + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetHalfDuplex(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR3; + + if(enable == true) + { + obj->CR3 = ((1ul << UART_CR3_HDSEL_SHIFT) | ((~UART_CR3_HDSEL_MASK) & tmp)); + } + else + { + obj->CR3 = ((0ul << UART_CR3_HDSEL_SHIFT) | ((~UART_CR3_HDSEL_MASK) & tmp)); + } +} + +/*! \brief Loop Mode Selec + * + * This bit can only be written when the UART is disabled (UE=0). If LOOPS and HDSEL are both 1, HDSEL is invalid. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Normal operation - RXD and TXD use separate pins. + * 1: Loop mode mode where transmitter outputs are internally connected to receiver input. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetLoopsMode(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR3; + + if(enable == true) + { + obj->CR3 = ((1ul << UART_CR3_LOOPS_SHIFT) | ((~UART_CR3_LOOPS_MASK) & tmp)); + } + else + { + obj->CR3 = ((0ul << UART_CR3_LOOPS_SHIFT) | ((~UART_CR3_LOOPS_MASK) & tmp)); + } +} + +/*! \brief Error Interrupt Enable + * + * Error Interrupt Enable bit is required to enable interrupt generation in case of a framing error, + * overrun error or noise flag (FE=1 or ORE=1 or NF=1 in the ISR register). + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0: Interrupt is inhibited + * 1: An interrupt is generated when FE=1 or ORE=1 or NF=1 in the ISR register. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetErrIsr(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->CR3; + + if(enable == true) + { + obj->CR3 = ((1ul << UART_CR3_EIE_SHIFT) | ((~UART_CR3_EIE_MASK) & tmp)); + } + else + { + obj->CR3 = ((0ul << UART_CR3_EIE_SHIFT) | ((~UART_CR3_EIE_MASK) & tmp)); + } +} + +/*! \brief Get the Error Interrupt enable status + * + * Readout the current Error Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetErrIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->CR3 & UART_CR3_EIE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief Send break done clear flag + * + * Writing 1 to this bit clears the SBRKD flag in the ISR register. + * + * \param[in] obj : pointer to UART driver instance + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_ClearTxBreakDoneFlag(UartRegType *obj) +{ + obj->ICR |= UART_ICR_SBRKDCF_MASK; + /* Read back to avoid problem */ + (void)obj->ICR; +} + +/*! \brief Receiver timeout clear flag + * + * Writing 1 to this bit clears the RTOF flag in the ISR register. + * + * \param[in] obj : pointer to UART driver instance + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_ClearRxTimeoutFlag(UartRegType *obj) +{ + obj->ICR |= UART_ICR_RTOCF_MASK; + /* Read back to avoid problem */ + (void)obj->ICR; +} + +/*! \brief CTS clear flag + * + * Writing 1 to this bit clears the CTSIF flag in the ISR register. + * + * \param[in] obj : pointer to UART driver instance + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_ClearCtsFlag(UartRegType *obj) +{ + obj->ICR |= UART_ICR_CTSCF_MASK; + /* Read back to avoid problem */ + (void)obj->ICR; +} + +/*! \brief LIN break detection result (LBDT_DONE and LBDT_FAIL) clear flag + * + * Writing 1 to this bit clears the LBDT_DONE and LBDT_FAIL flag in the ISR register. + * + * \param[in] obj : pointer to UART driver instance + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_ClearLinBreakDetectedResultFlag(UartRegType *obj) +{ + obj->ICR |= UART_ICR_LBDTCF_MASK; + /* Read back to avoid problem */ + (void)obj->ICR; +} + +/*! \brief Transmission complete clear flag + * + * Writing 1 to this bit clears the TC flag in the ISR register. + * + * \param[in] obj : pointer to UART driver instance + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_ClearTxCompletedFlag(UartRegType *obj) +{ + obj->ICR |= UART_ICR_TCCF_MASK; + /* Read back to avoid problem */ + (void)obj->ICR; +} + +/*! \brief Idle line detected clear flag + * + * Writing 1 to this bit clears the IDLE flag in the ISR register. + * + * \param[in] obj : pointer to UART driver instance + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_ClearIdlelineDetectedFlag(UartRegType *obj) +{ + obj->ICR |= UART_ICR_IDLECF_MASK; + /* Read back to avoid problem */ + (void)obj->ICR; +} + +/*! \brief Overrun error clear flag + * + * Writing 1 to this bit clears the ORE flag in the ISR register. + * + * \param[in] obj : pointer to UART driver instance + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_ClearOverRunnErrFlag(UartRegType *obj) +{ + obj->ICR |= UART_ICR_ORECF_MASK; + /* Read back to avoid problem */ + (void)obj->ICR; +} + +/*! \brief Noise detected clear flag + * + * Writing 1 to this bit clears the NE flag in the ISR register. + * + * \param[in] obj : pointer to UART driver instance + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_ClearNoiseDetectedFlag(UartRegType *obj) +{ + obj->ICR |= UART_ICR_NCF_MASK; + /* Read back to avoid problem */ + (void)obj->ICR; +} + +/*! \brief Framing error clear flag + * + * Writing 1 to this bit clears the FE flag in the ISR register. + * + * \param[in] obj : pointer to UART driver instance + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_ClearFrameErrFlag(UartRegType *obj) +{ + obj->ICR |= UART_ICR_FECF_MASK; + /* Read back to avoid problem */ + (void)obj->ICR; +} + +/*! \brief Parity error clear flag + * + * Writing 1 to this bit clears the PE flag in the ISR register. + * + * \param[in] obj : pointer to UART driver instance + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_ClearParityErrFlag(UartRegType *obj) +{ + obj->ICR |= UART_ICR_PECF_MASK; + /* Read back to avoid problem */ + (void)obj->ICR; +} + +/*! \brief Baud Rate Regiter + * + * This register can only be written when the UART is disabled (UE=0), + * It may be automatically updated by hardware in auto baud rate detection mode. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] brr: + * BRR[15:4] = UARTDIV[15:4] + * When OVER8 = 0, BRR[3:0] = UARTDIV[3:0]. + * When OVER8 = 1: BRR[2:0] = UARTDIV[3:0] shifted 1 bit to the right. BRR[3] must be kept cleared. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetBaudRate(UartRegType *obj, uint16_t brr) +{ + uint32_t tmp = obj->BRR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_BRR_BRR_MASK; + tmp |= (((uint32_t)(((uint32_t)(brr)) << UART_BRR_BRR_SHIFT)) & UART_BRR_BRR_MASK); + obj->BRR = tmp; +} + +/*! \brief This bit-field gives the Receiver timeout value in terms of number of bit duration. + * + * This value must only be programmed once per received character. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] timeout: Receiver timeout value + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetRxTimeout(UartRegType *obj, uint32_t timeout) +{ + uint32_t tmp = obj->RTOR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_RTOR_RTO_MASK; + tmp |= (((uint32_t)(((uint32_t)(timeout)) << UART_RTOR_RTO_SHIFT)) & UART_RTOR_RTO_MASK); + obj->RTOR = tmp; +} + +/*! \brief Mute mode request + * + * Writing 1 to this bit puts the UART in mute mode and sets the RWU flag. + * + * \param[in] obj : pointer to UART driver instance + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_ReqMuteMode(UartRegType *obj) +{ + uint32_t tmp = obj->RQR; + + obj->RQR = ((1ul << UART_RQR_MMRQ_SHIFT) | ((~UART_RQR_MMRQ_MASK) & tmp)); +} + +/*! \brief Send break request + * + * In the case the application needs to send the break character following all previously inserted data, + * including the ones not yet transmitted, the software should wait for the TXEMPT flag assertion before setting the SBRKRQ bit. + * + * \param[in] obj : pointer to UART driver instance + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_ReqTxBreak(UartRegType *obj) +{ + uint32_t tmp = obj->RQR; + + obj->RQR = ((1ul << UART_RQR_SBRKRQ_SHIFT) | ((~UART_RQR_SBRKRQ_MASK) & tmp)); +} + +/*! \brief Auto baud rate request + * + * Writing 1 to this bit resets the ABRF flag in the ISR and request an automatic baud rate measurement on the next received data frame. + * + * \param[in] obj : pointer to UART driver instance + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_ReqAutoBaudRate(UartRegType *obj) +{ + uint32_t tmp = obj->RQR; + + obj->RQR = ((1ul << UART_RQR_ABRRQ_SHIFT) | ((~UART_RQR_ABRRQ_MASK) & tmp)); +} + +/*! \brief Transmit data + * + * Note: Contains the data character to be transmitted. When transmitting with the parity enabled (PCE bit set to 1 in the CR1 register), + * the value written in the MSB (bit 7 or bit 8 depending on the data length) has no effect because it is replaced by the parity + * + * \param[in] obj : pointer to UART driver instance + * \param[in] txData : the tx data value + * \return void + */ +__attribute__((always_inline)) static inline void UartReg_TxData(UartRegType *obj, uint16_t txData) +{ + uint32_t tmp = obj->TDR; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_TDR_TDR_MASK; + tmp |= (((uint32_t)(((uint32_t)(txData)) << UART_TDR_TDR_SHIFT)) & UART_TDR_TDR_MASK); + obj->TDR = tmp; +} + +/*! \brief Transmit Buffer/FIFO Empty + * + * this function get the current tx buffer is empty or not + * + * \param[in] obj : pointer to UART driver instance + * \return: uint8_t + * 0b : Transmit buffer is not empty. + * 1b : Transmit buffer is empty. + */ +__attribute__((always_inline)) static inline uint8_t UartReg_GetTxBufferIsEmpty(const UartRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->FIFO & UART_FIFO_TXEMPT_MASK) >> UART_FIFO_TXEMPT_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Receive Buffer/FIFO Empty + * + * this function get the current rx buffer is empty or not + * + * \param[in] obj : pointer to UART driver instance + * \return: uint8_t + * 0b : Receive buffer is not empty. + * 1b : Receive buffer is empty. + */ +__attribute__((always_inline)) static inline uint8_t UartReg_GetRxBufferIsEmpty(const UartRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->FIFO & UART_FIFO_RXEMPT_MASK) >> UART_FIFO_RXEMPT_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Get Transmitter Buffer Overflow Flag + * + * Indicates that more data has been written to the transmit buffer than it can hold. This field asserts regardless of the value of TXOFE. However, + * an interrupt is issued to the host only if TXOFE is set. + * + * \param[in] obj : pointer to UART driver instance + * \return: uint8_t + * 0b : No transmit buffer overflow has occurred since the last time the flag was cleared. + * 1b : At least one transmit buffer overflow has occurred since the last time the flag was cleared. + */ +__attribute__((always_inline)) static inline uint8_t UartReg_GetTxOverflowFlag(const UartRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->FIFO & UART_FIFO_TXOF_MASK) >> UART_FIFO_TXOF_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Clear Transmitter Buffer Overflow Flag + * + * This flag is cleared by writing a 1. + * + * \param[in] obj : pointer to UART driver instance + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_ClearTxOverflowFlag(UartRegType *obj) +{ + obj->FIFO |= UART_FIFO_TXOF_MASK; + /* Read back to avoid problem */ + (void)obj->FIFO; +} + +/*! \brief Get Receiver Buffer Underflow Flag + * + * This flag is cleared by writing a 1. + * + * \param[in] obj : pointer to UART driver instance + * \return: uint8_t + * 0b : No receive buffer underflow has occurred since the last time the flag was cleared. + * 1b : At least one receive buffer underflow has occurred since the last time the flag was cleared. + */ +__attribute__((always_inline)) static inline uint8_t UartReg_GetRxUnderflowFlag(const UartRegType *obj) +{ + uint8_t tRtn = 0; + + tRtn = (((obj->FIFO & UART_FIFO_RXUF_MASK) >> UART_FIFO_RXUF_SHIFT) & 0xFF); + + return tRtn; +} + +/*! \brief Clear Receiver Buffer Underflow Flag + * + * Indicates that more data has been read from the receive buffer than was present. This field asserts regardless of the value of RXUFE. However, + * an interrupt is issued to the host only if RXUFE is setThis flag is cleared by writing a 1. + * + * \param[in] obj : pointer to UART driver instance + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_ClearRxUnderflowFlag(UartRegType *obj) +{ + obj->FIFO |= UART_FIFO_RXUF_MASK; + /* Read back to avoid problem */ + (void)obj->FIFO; +} + +/*! \brief Transmit FIFO/Buffer Flush + * + * Set and cleared by software. When using this bit, it is recommended this bit is high for at least three clock cycles. + * + * \param[in] obj : pointer to UART driver instance + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_FlushTxFifo(UartRegType *obj) +{ + uint32_t tmp = obj->FIFO; + + obj->FIFO = ((1ul << UART_FIFO_TXFLUSH_SHIFT) | ((~UART_FIFO_TXFLUSH_MASK) & tmp)); + + __asm volatile("nop"); + __asm volatile("nop"); + __asm volatile("nop"); + __asm volatile("nop"); + + obj->FIFO = ((0ul << UART_FIFO_TXFLUSH_SHIFT) | ((~UART_FIFO_TXFLUSH_MASK) & tmp)); +} + +/*! \brief Receiver FIFO/Buffer Flush + * + * Set and cleared by software. When using this bit, it is recommended this bit is high for at least three clock cycles. + * + * \param[in] obj : pointer to UART driver instance + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_FlushRxFifo(UartRegType *obj) +{ + uint32_t tmp = obj->FIFO; + + obj->FIFO = ((1ul << UART_FIFO_RXFLUSH_SHIFT) | ((~UART_FIFO_RXFLUSH_MASK) & tmp)); + + __asm volatile("nop"); + __asm volatile("nop"); + __asm volatile("nop"); + __asm volatile("nop"); + + obj->FIFO = ((0ul << UART_FIFO_RXFLUSH_SHIFT) | ((~UART_FIFO_RXFLUSH_MASK) & tmp)); +} + +/*! \brief Transmit FIFO Overflow Interrupt Enable + * + * When this field is set, the TXOF flag generates an interrupt to the host. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0b : TXOF flag does not generate an interrupt to the host. + * 1b : TXOF flag generates an interrupt to the host. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetTxOverflowIsr(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->FIFO; + + if(enable == true) + { + obj->FIFO = ((1ul << UART_FIFO_TXOFE_SHIFT) | ((~UART_FIFO_TXOFE_MASK) & tmp)); + } + else + { + obj->FIFO = ((0ul << UART_FIFO_TXOFE_SHIFT) | ((~UART_FIFO_TXOFE_MASK) & tmp)); + } +} + +/*! \brief Get the TxOverflowIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetTxOverflowIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->FIFO & UART_FIFO_TXOFE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief Receive FIFO Underflow Interrupt Enable + * + * When this field is set, the RXUF flag generates an interrupt to the host. + * + * \param[in] obj : pointer to UART driver instance + * \param[in] enable: + * 0b : No receive buffer underflow has occurred since the last time the flag was cleared. + * 1b : At least one receive buffer underflow has occurred since the last time the flag was cleared. + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetRxUnderflowIsr(UartRegType *obj, bool enable) +{ + uint32_t tmp = obj->FIFO; + + if(enable == true) + { + obj->FIFO = ((1ul << UART_FIFO_RXUFE_SHIFT) | ((~UART_FIFO_RXUFE_MASK) & tmp)); + } + else + { + obj->FIFO = ((0ul << UART_FIFO_RXUFE_SHIFT) | ((~UART_FIFO_RXUFE_MASK) & tmp)); + } +} + +/*! \brief Get the RxUnderflowIsr enable status + * + * Readout the current Interrupt enable is active or not + * + * \param[in] obj : pointer to UART driver instance + * \return: bool + * true: Enabled + * false: Disabled + */ +__attribute__((always_inline)) static inline bool UartReg_GetRxUnderflowIsrIsEnabled(const UartRegType *obj) +{ + bool isEnabled = false; + + if((obj->FIFO & UART_FIFO_RXUFE_MASK) != 0u) + { + isEnabled = true; + } + + return isEnabled; +} + +/*! \brief The value in this register indicates the number of datawords that are in the receive FIFO/buffer + * + * If a dataword is being received, that is, in the receive shift register, it is not included in the count. + * This value may be used to calculate how much room is left in the receive FIFO/buffer. + * + * \param[in] obj : pointer to UART driver instance + * \return: Receive Counter + */ +__attribute__((always_inline)) static inline uint8_t UartReg_GetRxCounter(const UartRegType *obj) +{ + uint8_t tRxCnt = 0; + + tRxCnt = (((obj->WATER & UART_WATER_RXCOUNT_MASK) >> UART_WATER_RXCOUNT_SHIFT) & 0xFF); + + return tRxCnt; +} + +/*! \brief When the number of datawords in the receive FIFO/buffer is greater than the value in this register field, + * an interrupt or a DMA request is generated. + * + * These 2 bits can only be written when the UART is disabled (UE=0) + * + * \param[in] obj : pointer to UART driver instance + * \param[in] rxWater: Receive Watermark + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetRxWater(UartRegType *obj, uint8_t rxWater) +{ + uint32_t tmp = obj->WATER; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_WATER_RXWATER_MASK; + tmp |= (((uint32_t)(((uint32_t)(rxWater)) << UART_WATER_RXWATER_SHIFT)) & UART_WATER_RXWATER_MASK); + obj->WATER = tmp; +} + +/*! \brief The value in this register indicates the number of datawords that are in the receive FIFO/buffer + * + * If a dataword is being transmitted, that is, in the transmit shift register, it is not included in the count. + * This value may be used to calculate how much room is left in the transmit FIFO/buffer. + * + * \param[in] obj : pointer to UART driver instance + * \return: Transmit Counter + */ +__attribute__((always_inline)) static inline uint8_t UartReg_GetTxCounter(const UartRegType *obj) +{ + uint8_t tTxCnt = 0; + + tTxCnt = (((obj->WATER & UART_WATER_TXCOUNT_MASK) >> UART_WATER_TXCOUNT_SHIFT) & 0xFF); + + return tTxCnt; +} + +/*! \brief When the number of datawords in the transmit FIFO/buffer is equal to or less than the value in this register field, + * an interrupt or a DMA request is generated. + * + * These 2 bits can only be written when the UART is disabled (UE=0) + * + * \param[in] obj : pointer to UART driver instance + * \param[in] txWater: Transmit Watermark + * \return: void + */ +__attribute__((always_inline)) static inline void UartReg_SetTxWater(UartRegType *obj, uint8_t txWater) +{ + uint32_t tmp = obj->WATER; + /* Clear the affected bit-field and write '0' to the w1c bits to avoid side-effects */ + tmp &= ~UART_WATER_TXWATER_MASK; + tmp |= (((uint32_t)(((uint32_t)(txWater)) << UART_WATER_TXWATER_SHIFT)) & UART_WATER_TXWATER_MASK); + obj->WATER = tmp; +} + +/*! \brief Get Tx water mark + * + * This function get the theshold value to compared with tx counter + * + * \param[in] obj : pointer to UART driver instance + * \return: Transmit Watermark + */ +__attribute__((always_inline)) static inline uint8_t UartReg_GetTxWaterMark(const UartRegType *obj) +{ + uint8_t tTxWaterMark = 0; + + tTxWaterMark = (((obj->WATER & UART_WATER_TXWATER_MASK) >> UART_WATER_TXWATER_SHIFT) & 0xFF); + + return tTxWaterMark; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UART_REG_H_ */ \ No newline at end of file diff --git a/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/wdg_reg.h b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/wdg_reg.h new file mode 100644 index 0000000..94894da --- /dev/null +++ b/cva_bootloader_m0118/SDK/platform/devices/CVM011x/reg/wdg_reg.h @@ -0,0 +1,687 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _WDG_REG_H_ +#define _WDG_REG_H_ + +/*! \brief Contains public interface to various functions related + * to the WDG (Watch Dog) Registers + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* CS Bit Fields */ +#define WDG_CS_CLK_MASK (0x70000u) +#define WDG_CS_CLK_SHIFT (16u) +#define WDG_CS_CLK_WIDTH (3u) +#define WDG_CS_WIN_MASK (0x8000u) +#define WDG_CS_WIN_SHIFT (15u) +#define WDG_CS_WIN_WIDTH (1u) +#define WDG_CS_FLG_MASK (0x4000u) +#define WDG_CS_FLG_SHIFT (14u) +#define WDG_CS_FLG_WIDTH (1u) +#define WDG_CS_PRES_MASK (0x1000u) +#define WDG_CS_PRES_SHIFT (12u) +#define WDG_CS_PRES_WIDTH (1u) +#define WDG_CS_ULK_MASK (0x800u) +#define WDG_CS_ULK_SHIFT (11u) +#define WDG_CS_ULK_WIDTH (1u) +#define WDG_CS_RCS_MASK (0x400u) +#define WDG_CS_RCS_SHIFT (10u) +#define WDG_CS_RCS_WIDTH (1u) +#define WDG_CS_CSD_MASK (0x200u) +#define WDG_CS_CSD_SHIFT (9) +#define WDG_CS_CSD_WIDTH (1) +#define WDG_CS_EN_MASK (0x80u) +#define WDG_CS_EN_SHIFT (7u) +#define WDG_CS_EN_WIDTH (1u) +#define WDG_CS_INTR_MASK (0x40u) +#define WDG_CS_INTR_SHIFT (6u) +#define WDG_CS_INTR_WIDTH (1u) +#define WDG_CS_UPDATE_MASK (0x20u) +#define WDG_CS_UPDATE_SHIFT (5u) +#define WDG_CS_UPDATE_WIDTH (1u) +#define WDG_CS_TST_MASK (0x18u) +#define WDG_CS_TST_SHIFT (3u) +#define WDG_CS_TST_WIDTH (2u) +#define WDG_CS_DEBUG_MASK (0x02u) +#define WDG_CS_DEBUG_SHIFT (1u) +#define WDG_CS_DEBUG_WIDTH (1u) +#define WDG_CS_STOP_MASK (0x01u) +#define WDG_CS_STOP_SHIFT (0u) +#define WDG_CS_STOP_WIDTH (1u) + +/* CNT Bit Fields */ +#define WDG_CNT_HIGH_MASK (0xFF00u) +#define WDG_CNT_HIGH_SHIFT (8u) +#define WDG_CNT_HIGH_WIDTH (8u) +#define WDG_CNT_LOW_MASK (0xFFu) +#define WDG_CNT_LOW_SHIFT (0u) +#define WDG_CNT_LOW_WIDTH (8u) + +/* TOVAL Bit Fields */ +#define WDG_TOVAL_HIGH_MASK (0xFF00u) +#define WDG_TOVAL_HIGH_SHIFT (8u) +#define WDG_TOVAL_HIGH_WIDTH (8u) +#define WDG_TOVAL_LOW_MASK (0xFFu) +#define WDG_TOVAL_LOW_SHIFT (0u) +#define WDG_TOVAL_LOW_WIDTH (8u) + +/* WIN Bit Fields */ +#define WDG_WIN_HIGH_MASK (0xFF00u) +#define WDG_WIN_HIGH_SHIFT (8u) +#define WDG_WIN_HIGH_WIDTH (8u) +#define WDG_WIN_LOW_MASK (0xFFu) +#define WDG_WIN_LOW_SHIFT (0u) +#define WDG_WIN_LOW_WIDTH (8u) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The definition of WDG registers + */ +typedef struct _WdgRegType_ +{ + volatile uint32_t CS; /*!< control register, offset: 0x00 */ + volatile uint32_t CNT; /*!< counter set register, offset: 0x04 */ + volatile uint32_t TOVAL; /*!< timeout value register, offset: 0x08 */ + volatile uint32_t WIN; /*!< window value register, offset: 0x0C */ +} WdgRegType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Gets the WDG CS value. + * + * the function gets the WDG CS value. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to CS current value + * + */ +__attribute__((always_inline)) static inline uint32_t WdgReg_GetCsVal(const WdgRegType *obj) +{ + return obj->CS; +} + +/*! \brief Sets the WDG CS unlock key + * + * The WDG CS registers is locked by default. + * Before writing registers, write unlock key to this register or refresh this register. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : pointer to the value + */ +__attribute__((always_inline)) static inline void WdgReg_SetCsVal(WdgRegType *obj, uint32_t value) +{ + obj->CS = value; +} + +/*! \brief Gets the WDG input clock source + * + * This function gets the WDG input clock source + * + * \param[in] obj : pointer to WDG register instance + * \return indicate the clock source that feeds the watchdog counter + * - 000b : BUS clock as source; + * - 001b : LPO_CLK_128 clock as source; + * - 010b : SOSC clock as source; + * - 011b : SIRC clock as source; + * - 100b : LPO_CLK_32 clock as source; + * - 101b : LPO_CLK_1 clock as source; + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_GetClockSource(const WdgRegType *obj) +{ + return ((obj->CS & WDG_CS_CLK_MASK) >> WDG_CS_CLK_SHIFT); +} + +/*! \brief Sets the WDG input clock source + * + * This function sets the WDG input clock source + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : the value of WDG input clock source + * - 000b : BUS clock as source; + * - 001b : LPO_CLK_128 clock as source; + * - 010b : SOSC clock as source; + * - 011b : SIRC clock as source; + * - 100b : LPO_CLK_32 clock as source; + * - 101b : LPO_CLK_1 clock as source; + */ +__attribute__((always_inline)) static inline void WdgReg_SetClockSource(WdgRegType *obj, uint8_t value) +{ + uint32_t csTmp = obj->CS; + + csTmp &= ~(WDG_CS_CLK_MASK); + csTmp |= (((uint32_t)(((uint32_t)(value)) << WDG_CS_CLK_SHIFT)) & WDG_CS_CLK_MASK); + obj->CS = csTmp; +} + +/*! \brief Verifies if the WDG windouw mode is enabled. + * + * This function verifies if the WDG windouw mode is enabled. + * + * \param[in] obj : pointer to WDG register instance + * \return Verifies if the WDG windouw mode is enabled + * - 000b : window mode is disabled; + * - 001b : window mode is enabled; + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_IsEnabledWinMode(const WdgRegType *obj) +{ + return ((obj->CS & WDG_CS_WIN_MASK) >> WDG_CS_WIN_SHIFT); +} + +/*! \brief Enable/disable the WDG windouw mode. + * + * This function enable/disable the WDG windouw mode. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : Enable/disable + * - 000b : disable; + * - 001b : enable; + */ +__attribute__((always_inline)) static inline void WdgReg_EnableWinMode(WdgRegType *obj, uint8_t value) +{ + uint32_t csTmp = obj->CS; + + csTmp &= ~(WDG_CS_WIN_MASK); + csTmp |= (((uint32_t)(((uint32_t)(value)) << WDG_CS_WIN_SHIFT)) & WDG_CS_WIN_MASK); + obj->CS = csTmp; +} + +/*! \brief Gets the WDG interrupt flag. + * + * This function gets the WDG interript flag. + * + * \param[in] obj : pointer to WDG register instance + * \return the WDG interrupt flag + * - 000b : disable; + * - 001b : enable; + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_GetInterruptFlag(WdgRegType *obj) +{ + return ((obj->CS & WDG_CS_FLG_MASK) >> WDG_CS_FLG_SHIFT); +} + +/*! \brief Sets the WDG interrupt flag. + * + * This bit is an interrupt indicator when INT is set in control and status register 1. Write 1 to clear it. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : pointer to clear value + * - 000b: No occurred. + * - 001b: clear interrupt flag + */ +__attribute__((always_inline)) static inline void WdgReg_ClearInterruptFlag(WdgRegType *obj, uint16_t value) +{ + uint32_t csTmp = obj->CS; + + csTmp &= ~(WDG_CS_FLG_MASK); + csTmp |= (((uint32_t)(((uint32_t)(value)) << WDG_CS_FLG_SHIFT)) & WDG_CS_FLG_MASK); + obj->CS = csTmp; +} + +/*! \brief Verifies if the WDG prescaler is enabled. + * + * This bit is an interrupt indicator when INT is set in control and status register 1. Write 1 to clear it. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to prescaler status + * - 000b: No occurred. + * - 001b: clear interrupt flag + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_IsEnabledPrescaler(const WdgRegType *obj) +{ + return ((obj->CS & WDG_CS_PRES_MASK) >> WDG_CS_PRES_SHIFT); +} + +/*! \brief Enable/disable the WDG prescaler. + * + * This function enable/disable the WDG prescaler. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : Enable/disable + * - 000b : disable; + * - 001b : enable; + */ +__attribute__((always_inline)) static inline void WdgReg_EnablePrescaler(WdgRegType *obj, uint8_t value) +{ + uint32_t csTmp = obj->CS; + + csTmp &= ~(WDG_CS_PRES_MASK); + csTmp |= (((uint32_t)(((uint32_t)(value)) << WDG_CS_PRES_SHIFT)) & WDG_CS_PRES_MASK); + obj->CS = csTmp; +} + +/*! \brief Verifies if the WDG prescaler is unlocked. + * + * this read-only bit indicates whether WDOG is unlocked or not. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to unlock status + * - 000b: WDG is locked. + * - 001b: WDG is unlocked. + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_IsUnlocked(WdgRegType *obj) +{ + return ((uint8_t)((obj->CS & WDG_CS_ULK_MASK) >> WDG_CS_ULK_SHIFT)); +} + +/*! \brief Verifies if the WDG configuration is successful. + * + * this read-only bit indicates whether the configuration is successful or not. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to configuration status + * - 000b: configuring WDG. + * - 001b: configuration is successful. + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_IsSuccessConfig(WdgRegType *obj) +{ + return ((uint8_t)((obj->CS & WDG_CS_RCS_MASK) >> WDG_CS_RCS_SHIFT)); +} + +/*! \brief Verifies if the synchronization of the WDG new configuration is done + * + * this flag indicate the synchronization of new configuration is done, next unlock seq is allowed if required + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to configuration status + * - 000b: synchronization is ongoing, next unlock seq is not allowed. + * - 001b: synchronization is done, next unlock seq is allowed if required. + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_IsDoneConfigSync(WdgRegType *obj) +{ + return ((uint8_t)((obj->CS & WDG_CS_CSD_MASK) >> WDG_CS_CSD_SHIFT)); +} + +/*! \brief Verifies if the WDG is enabled. + * + * Verifies if the WDG is enabled. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to enable status + * - 000b: watchdog disabled. + * - 001b: watchdog enabled. + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_IsEnabled(const WdgRegType *obj) +{ + return ((obj->CS & WDG_CS_EN_MASK) >> WDG_CS_EN_SHIFT); +} + +/*! \brief Enable/Disable the WDG . + * + * the function enable/disable the WDG . + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : pointer to WDG enable value + * - 000b: watchdog disable. + * - 001b: watchdog enable. + */ +__attribute__((always_inline)) static inline void WdgReg_Enable(WdgRegType *obj, uint8_t value) +{ + uint32_t csTmp = obj->CS; + + csTmp &= ~(WDG_CS_EN_MASK); + csTmp |= (((uint32_t)(((uint32_t)(value)) << WDG_CS_EN_SHIFT)) & WDG_CS_EN_MASK); + obj->CS = csTmp; +} + +/*! \brief Verifies if the WDG interrupt is enabled.. + * + * the function verifies if the WDG interrupt is enabled . + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to enable status + * - 000b: disabled. + * - 001b: enabled. + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_IsEnabledInterrupt(const WdgRegType *obj) +{ + return ((obj->CS & WDG_CS_INTR_MASK) >> WDG_CS_INTR_SHIFT); +} + +/*! \brief Enable/Disable the WDG interrupt. + * + * the function enable/disable the WDG interrupt. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : pointer to WDG enable value + * - 000b: disable. + * - 001b: enable. + */ +__attribute__((always_inline)) static inline void WdgReg_EnableInterrupt(WdgRegType *obj, uint8_t value) +{ + uint32_t csTmp = obj->CS; + + csTmp &= ~(WDG_CS_INTR_MASK); + csTmp |= (((uint32_t)(((uint32_t)(value)) << WDG_CS_INTR_SHIFT)) & WDG_CS_INTR_MASK); + obj->CS = csTmp; +} + +/*! \brief Verifies if allow update register. + * + * the function verifies if allow update register. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to allow status + * - 000b: updates not allowed. + * - 001b: update allowed. + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_IsEnabledUpdate(const WdgRegType *obj) +{ + return ((obj->CS & WDG_CS_UPDATE_MASK) >> WDG_CS_UPDATE_SHIFT); +} + +/*! \brief Enable/Disable the WDG update register. + * + * the function enable/disable the WDG update register. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : pointer to WDG enable value + * - 000b: disable. + * - 001b: enable. + */ +__attribute__((always_inline)) static inline void WdgReg_EnableUpdate(WdgRegType *obj, uint8_t value) +{ + uint32_t csTmp = obj->CS; + + csTmp &= ~(WDG_CS_UPDATE_MASK); + csTmp |= (((uint32_t)(((uint32_t)(value)) << WDG_CS_UPDATE_SHIFT)) & WDG_CS_UPDATE_MASK); + obj->CS = csTmp; +} + +/*! \brief Verifies if test mode is enabled. + * + * the function TST is cleared (0:0) on POR only. + * Any other reset does not affect the value of this field. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to status + * - 000b: watchdog test mode disable + * - 001b: watchdog user mode enable. (watchdog test mode disabled) + * - 010b: watchdog test mode enabled, only the low byte is used. + * - 011b: watchdog test mode enabled, only the high byte is used. + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_GetTestModeStatus(const WdgRegType *obj) +{ + return ((obj->CS & WDG_CS_TST_MASK) >> WDG_CS_TST_SHIFT); +} + +/*! \brief Enable/Disable the WDG test mode. + * + * the function enable/disable the WDG test mode. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : pointer to WDG enable value + * - 000b: watchdog test mode disable + * - 001b: watchdog user mode enable. (watchdog test mode disabled) + * - 010b: watchdog test mode enabled, only the low byte is used. + * - 011b: watchdog test mode enabled, only the high byte is used. + */ +__attribute__((always_inline)) static inline void WdgReg_SetTestMode(WdgRegType *obj, uint8_t value) +{ + uint32_t csTmp = obj->CS; + + csTmp &= ~(WDG_CS_TST_MASK); + csTmp |= (((uint32_t)(((uint32_t)(value)) << WDG_CS_TST_SHIFT)) & WDG_CS_TST_MASK); + obj->CS = csTmp; +} + +/*! \brief Verifies if enable debug mode. + * + * the function verifies if enable the WDG in debug mode. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to allow status + * - 000b: watchdog disable in chip stop mode. + * - 001b: watchdog enabled in chip stop mode + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_IsEnabledDebugMode(const WdgRegType *obj) +{ + return ((obj->CS & WDG_CS_DEBUG_MASK) >> WDG_CS_DEBUG_SHIFT); +} + +/*! \brief Enable/Disable the WDG in debug mode. + * + * the function enable/disable the WDG in debug mode. + * the reg is write-once bit. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : pointer to WDG enable value + * - 000b: watchdog disable in chip stop mode. + * - 001b: watchdog enabled in chip stop mode. + */ +__attribute__((always_inline)) static inline void WdgReg_EnableDebugMode(WdgRegType *obj, uint8_t value) +{ + uint32_t csTmp = obj->CS; + + csTmp &= ~(WDG_CS_DEBUG_MASK); + csTmp |= (((uint32_t)(((uint32_t)(value)) << WDG_CS_DEBUG_SHIFT)) & WDG_CS_DEBUG_MASK); + obj->CS = csTmp; +} + +/*! \brief Verifies if the WDG stop mode. + * + * the function verifies if the watchdog is eabled to operate in stop mode. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to status + * - 000b: disabled. + * - 001b: enabled. + */ +__attribute__((always_inline)) static inline uint8_t WdgReg_IsEnabledStopMode(WdgRegType *obj) +{ + return ((obj->CS & WDG_CS_STOP_MASK) >> WDG_CS_STOP_SHIFT); +} + +/*! \brief Enable/Disable the WDG stop mode. + * + * the function enable/disable the WDG stop mode. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : pointer to WDG enable value + * - 000b: disable. + * - 001b: enable. + */ +__attribute__((always_inline)) static inline void WdgReg_EnableStopMode(WdgRegType *obj, uint8_t value) +{ + uint32_t csTmp = obj->CS; + + csTmp &= ~(WDG_CS_STOP_MASK); + csTmp |= (((uint32_t)(((uint32_t)(value)) << WDG_CS_STOP_SHIFT)) & WDG_CS_STOP_MASK); + obj->CS = csTmp; +} + +/*! \brief Gets the WDG CNT value. + * + * the function gets the WDG CNT value. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to CNT current value + * + */ +__attribute__((always_inline)) static inline uint32_t WdgReg_GetCntVal(const WdgRegType *obj) +{ + return obj->CNT; +} + +/*! \brief Sets the WDG CNT unlock key + * + * The WDG CNT registers is locked by default. + * Before writing registers, write unlock key to this register or refresh this register. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : CNT value + */ +__attribute__((always_inline)) static inline void WdgReg_SetCntVal(WdgRegType *obj, uint32_t value) +{ + obj->CNT = value; +} + +/*! \brief Gets the WDG CNT high 8 bits value . + * + * the function gets he WDG CNT high 8 bits value. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to CNT current high 8 bits value + * + */ +__attribute__((always_inline)) static inline uint32_t WdgReg_GetCntValHighBits(WdgRegType *obj) +{ + return ((obj->CNT & WDG_CNT_HIGH_MASK) >> WDG_CNT_HIGH_SHIFT); +} + +/*! \brief Gets the WDG CNT low 8 bits value . + * + * the function gets he WDG CNT low 8 bits value. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to CNT current low 8 bits value + * + */ +__attribute__((always_inline)) static inline uint32_t WdgReg_GetCntValLowBits(WdgRegType *obj) +{ + return ((obj->CNT & WDG_CNT_LOW_MASK) >> WDG_CNT_LOW_SHIFT); +} + +/*! \brief Gets the WDG Timeout configuration value. + * + * the function gets the WDG Timeout configuration value. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to TOVAL current value + * + */ +__attribute__((always_inline)) static inline uint32_t WdgReg_GetToval(const WdgRegType *obj) +{ + return obj->TOVAL; +} + +/*! \brief Sets the WDG Timeout Configuration value + * + * The WDG TOVAL registers is locked by default. + * Before writing registers, write unlock key to CNT register. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : pointer to configuration value + */ +__attribute__((always_inline)) static inline void WdgReg_SetToval(WdgRegType *obj, uint32_t value) +{ + obj->TOVAL = value; +} + +/*! \brief Gets the WDG Timeout high 8 bits value . + * + * the function gets he WDG Timeout high8 bits value. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to current Timeout high 8 bits value + * + */ +__attribute__((always_inline)) static inline uint32_t WdgReg_GetTovalHighBits(WdgRegType *obj) +{ + return ((obj->TOVAL & WDG_TOVAL_HIGH_MASK) >> WDG_TOVAL_HIGH_SHIFT); +} + +/*! \brief Gets the WDG Timeout low 8 bits value . + * + * the function gets he WDG Timeout low 8 bits value. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to Timeout current low 8 bits value + * + */ +__attribute__((always_inline)) static inline uint32_t WdgReg_GetTovalLowBits(WdgRegType *obj) +{ + return ((obj->TOVAL & WDG_TOVAL_LOW_MASK) >> WDG_TOVAL_LOW_SHIFT); +} + +/*! \brief Gets the WDG window configuration value. + * + * the function gets the WDG window configuration value. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to TOVAL current value + * + */ +__attribute__((always_inline)) static inline uint32_t WdgReg_GetWinVal(const WdgRegType *obj) +{ + return obj->WIN; +} + +/*! \brief Sets the WDG window Configuration value + * + * The WDG WIN registers is locked by default. + * Before writing registers, write unlock key to CNT register. + * + * \param[in] obj : pointer to WDG register instance + * \param[in] value : pointer to configuration value + */ +__attribute__((always_inline)) static inline void WdgReg_SetWinVal(WdgRegType *obj, uint32_t value) +{ + obj->WIN = value; +} + +/*! \brief Gets the WDG window high 8 bits value . + * + * the function gets he WDG window high8 bits value. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to current window high 8 bits value + * + */ +__attribute__((always_inline)) static inline uint32_t WdgReg_GetWinValHighBits(WdgRegType *obj) +{ + return ((obj->WIN & WDG_WIN_HIGH_MASK) >> WDG_WIN_HIGH_SHIFT); +} + +/*! \brief Gets the WDG window low 8 bits value . + * + * the function gets he WDG window low 8 bits value. + * + * \param[in] obj : pointer to WDG register instance + * \return : pointer to window current low 8 bits value + * + */ +__attribute__((always_inline)) static inline uint32_t WdgReg_GetWinValLowBits(WdgRegType *obj) +{ + return ((obj->WIN & WDG_WIN_LOW_MASK) >> WDG_WIN_LOW_SHIFT); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _WDG_REG_H_ */ diff --git a/cva_bootloader_m0118/bat_complier_object/InfoWindow2.dll b/cva_bootloader_m0118/bat_complier_object/InfoWindow2.dll new file mode 100644 index 0000000..5683215 Binary files /dev/null and b/cva_bootloader_m0118/bat_complier_object/InfoWindow2.dll differ diff --git a/cva_bootloader_m0118/bat_complier_object/convert_hex.bat b/cva_bootloader_m0118/bat_complier_object/convert_hex.bat new file mode 100644 index 0000000..0bcd857 --- /dev/null +++ b/cva_bootloader_m0118/bat_complier_object/convert_hex.bat @@ -0,0 +1,6 @@ +@echo off +set curdir=%~dp0 +cd /d %curdir% +convert_hex ..\Debug_FLASH\Exe\cva_bootloader_m0118.srec /CR:0x00000000,0x10000 /XS:32 -o cva_m0118_FlashDrv_iar.srec +convert_hex cva_m0118_FlashDrv_iar.srec /FA /FR:0x20005BF0-0x200063EB /FP:FF /CS9:@0x200063EC /XS:32 -o cva_m0118_FlashDrv_iar.srec +convert_hex cva_m0118_FlashDrv_iar.srec /XI:32 -o cva_m0118_FlashDrv_iar.hex \ No newline at end of file diff --git a/cva_bootloader_m0118/bat_complier_object/convert_hex.exe b/cva_bootloader_m0118/bat_complier_object/convert_hex.exe new file mode 100644 index 0000000..f59e15d Binary files /dev/null and b/cva_bootloader_m0118/bat_complier_object/convert_hex.exe differ diff --git a/cva_bootloader_m0118/bat_complier_object/cva_m0118_FlashDrv_iar.hex b/cva_bootloader_m0118/bat_complier_object/cva_m0118_FlashDrv_iar.hex new file mode 100644 index 0000000..cce644a --- /dev/null +++ b/cva_bootloader_m0118/bat_complier_object/cva_m0118_FlashDrv_iar.hex @@ -0,0 +1,66 @@ +:020000042000DA +:205BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:205C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:205C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:205C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:205C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:205C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +:205CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +:205CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +:205CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +:205D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +:205D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +:205D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:205D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:205D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:205DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:205DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:205DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +:205E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:205E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:205E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:205E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:205E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:205EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:205ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:205EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:205F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:205F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:205F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:205F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:205F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +:205FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:205FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:205FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:20601000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:20603000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:20605000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:20607000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:20609000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:2060B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:2060D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:2060F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:20611000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +:20613000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +:20615000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +:20617000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +:20619000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +:2061B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +:2061D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +:2061F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +:20621000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +:20623000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:20625000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +:20627000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:20629000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +:2062B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +:2062D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +:2062F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +:20631000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:20633000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:20635000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:20637000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:20639000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:2063B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:2063D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60169A5267 +:00000001FF diff --git a/cva_bootloader_m0118/bat_complier_object/cva_m0118_FlashDrv_iar.srec b/cva_bootloader_m0118/bat_complier_object/cva_m0118_FlashDrv_iar.srec new file mode 100644 index 0000000..b078492 --- /dev/null +++ b/cva_bootloader_m0118/bat_complier_object/cva_m0118_FlashDrv_iar.srec @@ -0,0 +1,65 @@ +S32520005BF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +S32520005C10FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +S32520005C30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +S32520005C50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +S32520005C70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +S32520005C90FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +S32520005CB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +S32520005CD0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +S32520005CF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +S32520005D10FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +S32520005D30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +S32520005D50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +S32520005D70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +S32520005D90FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +S32520005DB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +S32520005DD0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +S32520005DF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +S32520005E10FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +S32520005E30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +S32520005E50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +S32520005E70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +S32520005E90FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +S32520005EB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +S32520005ED0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +S32520005EF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +S32520005F10FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +S32520005F30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +S32520005F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +S32520005F70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +S32520005F90FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +S32520005FB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +S32520005FD0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +S32520005FF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +S32520006010FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +S32520006030FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +S32520006050FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +S32520006070FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +S32520006090FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +S325200060B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +S325200060D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +S325200060F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +S32520006110FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +S32520006130FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +S32520006150FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +S32520006170FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +S32520006190FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +S325200061B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +S325200061D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +S325200061F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +S32520006210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +S32520006230FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +S32520006250FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +S32520006270FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +S32520006290FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +S325200062B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +S325200062D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +S325200062F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +S32520006310FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +S32520006330FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +S32520006350FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +S32520006370FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +S32520006390FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +S325200063B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +S325200063D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60169A5241 +S70500000000FA diff --git a/cva_bootloader_m0118/bat_complier_object/expdatproc.dll b/cva_bootloader_m0118/bat_complier_object/expdatproc.dll new file mode 100644 index 0000000..7a51585 Binary files /dev/null and b/cva_bootloader_m0118/bat_complier_object/expdatproc.dll differ diff --git a/cva_bootloader_m0118/bat_complier_object/gl_inst.dll b/cva_bootloader_m0118/bat_complier_object/gl_inst.dll new file mode 100644 index 0000000..babfa00 Binary files /dev/null and b/cva_bootloader_m0118/bat_complier_object/gl_inst.dll differ diff --git a/cva_bootloader_m0118/bat_complier_object/license.liz b/cva_bootloader_m0118/bat_complier_object/license.liz new file mode 100644 index 0000000..ab9c12c Binary files /dev/null and b/cva_bootloader_m0118/bat_complier_object/license.liz differ diff --git a/cva_bootloader_m0118/cva_bootloader_m0118.ewd b/cva_bootloader_m0118/cva_bootloader_m0118.ewd new file mode 100644 index 0000000..31ecfc6 --- /dev/null +++ b/cva_bootloader_m0118/cva_bootloader_m0118.ewd @@ -0,0 +1,3226 @@ + + + 4 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 33 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + E2_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9a.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 33 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + E2_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9a.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/cva_bootloader_m0118/cva_bootloader_m0118.ewp b/cva_bootloader_m0118/cva_bootloader_m0118.ewp new file mode 100644 index 0000000..71ddaa7 --- /dev/null +++ b/cva_bootloader_m0118/cva_bootloader_m0118.ewp @@ -0,0 +1,3087 @@ + + + 4 + + Debug + + ARM + + 1 + + General + 3 + + 36 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 38 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 12 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 1 + inputOutputBased + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BUILDACTION + 2 + + + + + Release + + ARM + + 0 + + General + 3 + + 36 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 38 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 12 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + ILINK + 0 + + 27 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + BUILDACTION + 2 + + + + $PROJ_DIR$\bat_complier_object\convert_hex.bat && echo > "$BUILD_FILES_DIR$/.postbuild" + $PROJ_DIR$ + postLink + + + $BUILD_FILES_DIR$/.postbuild + + + + + + + + + src + + bootloader + + $PROJ_DIR$\src\bootloader\bootloader.c + + + $PROJ_DIR$\src\bootloader\bootloader.h + + + $PROJ_DIR$\src\bootloader\bootloader_cfg.h + + + + drivers + + adc + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\adc\adc_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\adc\adc_drv.h + + + + clock + + Debug + Release + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\clock\clock_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\clock\clock_drv.h + + + + cmp + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cmp\cmp_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cmp\cmp_drv.h + + + + cmu + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cmu\cmu_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cmu\cmu_drv.h + + + + cpu + + cmsis + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\arm_common_tables.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\arm_const_structs.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\arm_math.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_armcc.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_armclang.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_compiler.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_gcc.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_iccarm.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_version.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\core_cm0plus.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\mpu_armv7.h + + + + startup + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\startup\startup.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\startup\startup.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\startup\startup_M011x.S + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\startup\system_M011x.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\startup\system_M011x.h + + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cpu_drv.h + + + + crc + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\crc\crc_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\crc\crc_drv.h + + + + dma + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\edma\edma_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\edma\edma_drv.h + + + + eim + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\eim\eim_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\eim\eim_drv.h + + + + erm + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\erm\erm_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\erm\erm_drv.h + + + + flash + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\flash\flash_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\flash\flash_drv.h + + + + flexcan + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\flexcan\flexcan_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\flexcan\flexcan_drv.h + + + + i2c + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2c\i2c_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2c\i2c_drv.h + + + + i2sm + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2sm\i2sm_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2sm\i2sm_drv.h + + + + i2ss + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2ss\i2ss_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2ss\i2ss_drv.h + + + + irq + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\irq\irq_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\irq\irq_drv.h + + + + lpit + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\lpit\lpit_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\lpit\lpit_drv.h + + + + lptmr + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\lptmr\lptmr_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\lptmr\lptmr_drv.h + + + + mft + + mft_cap + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_cap\mft_cap_ch.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_cap\mft_cap_ch.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_cap\mft_cap_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_cap\mft_cap_drv.h + + + + mft_oc + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_oc\mft_oc_ch.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_oc\mft_oc_ch.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_oc\mft_oc_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_oc\mft_oc_drv.h + + + + mft_pwm + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_pwm\mft_pwm_ch.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_pwm\mft_pwm_ch.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_pwm\mft_pwm_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_pwm\mft_pwm_drv.h + + + + mft_qd + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_qd\mft_qd_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_qd\mft_qd_drv.h + + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_drv.h + + + + mpu + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mpu\mpu_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mpu\mpu_drv.h + + + + pdb + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pdb\pdb_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pdb\pdb_drv.h + + + + pins + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pins\pins_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pins\pins_drv.h + + + + power + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\power\power_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\power\power_drv.h + + + + pwmlite + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pwmlite\pwmlite_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pwmlite\pwmlite_drv.h + + + + reset + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\reset\reset_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\reset\reset_drv.h + + + + rtc + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\rtc\rtc_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\rtc\rtc_drv.h + + + + spi + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\spi\spi_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\spi\spi_drv.h + + + + trgmux + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\trgmux\trgmux_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\trgmux\trgmux_drv.h + + + + uart + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\uart\uart_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\uart\uart_drv.h + + + + wdg + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\wdg\wdg_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\wdg\wdg_drv.h + + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\CVM011x_features.h + + Debug + Release + + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\mcu.c + + Debug + Release + + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\mcu.h + + Debug + Release + + + + + fls + + $PROJ_DIR$\src\fls\fls.c + + + $PROJ_DIR$\src\fls\fls.h + + + + lib + + $PROJ_DIR$\SDK\lib\shared\common\stimer\stimer.h + + + + linker + + $PROJ_DIR$\linker\bootloader_m0118_flash.icf + + + + middleware + + isotp + + Debug + Release + + + $PROJ_DIR$\SDK\middleware\isotp\isotp.c + + + $PROJ_DIR$\SDK\middleware\isotp\isotp.h + + + + uds + + stack + + Debug + Release + + + $PROJ_DIR$\SDK\middleware\uds\stack\uds.c + + + $PROJ_DIR$\SDK\middleware\uds\stack\uds.h + + + + user + + $PROJ_DIR$\SDK\middleware\uds\user\uds_dtc.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_dtc.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service10.c + + Debug + Release + + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service10.h + + Debug + Release + + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service11.c + + Debug + Release + + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service11.h + + Debug + Release + + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service14.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service14.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service19.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service19.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service22.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service22.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service27.c + + Debug + Release + + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service27.h + + Debug + Release + + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service28.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service28.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service2E.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service2E.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service2F.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service2F.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service31.c + + Debug + Release + + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service31.h + + Debug + Release + + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service34.c + + Debug + Release + + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service34.h + + Debug + Release + + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service36.c + + Debug + Release + + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service36.h + + Debug + Release + + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service37.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service37.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service3E.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service3E.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service85.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service85.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_user.c + + Debug + Release + + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_user.h + + Debug + Release + + + + + + + private_driver + + drivers + + clock + + $PROJ_DIR$\src\private_driver\drivers\clock\clock_drv.c + + + $PROJ_DIR$\src\private_driver\drivers\clock\clock_drv.h + + + + + isotp + + $PROJ_DIR$\src\private_driver\isotp\isotp.c + + + $PROJ_DIR$\src\private_driver\isotp\isotp.h + + + + uds + + stack + + $PROJ_DIR$\src\private_driver\uds\stack\uds.c + + + $PROJ_DIR$\src\private_driver\uds\stack\uds.h + + + + user + + $PROJ_DIR$\src\private_driver\uds\user\uds_service10.c + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service10.h + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service11.c + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service11.h + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service27.c + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service27.h + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service31.c + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service31.h + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service34.c + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service34.h + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service36.c + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service36.h + + + $PROJ_DIR$\src\private_driver\uds\user\uds_user.c + + + $PROJ_DIR$\src\private_driver\uds\user\uds_user.h + + + + + $PROJ_DIR$\src\private_driver\CVM011x_features.h + + + $PROJ_DIR$\src\private_driver\mcu.c + + + $PROJ_DIR$\src\private_driver\mcu.h + + + + reg + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\adc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\axbs_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\cmp_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\cmu_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\crc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\dmamux_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\edma_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\eim_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\erm_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\fhu_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\flexcan_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\ftfc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\gpio_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\i2c_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\i2sm_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\i2ss_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\lpit_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\lptmr_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\mft_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\mpu_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\mscm_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\pcc0_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\pcc1_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\pdb_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\pmc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\port_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\pwmlite_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\rcm_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\rtc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\scg0_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\scg1_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\scg2_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\sim_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\spi_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\trgmux_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\uart_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\wdg_reg.h + + + + RTT + + $PROJ_DIR$\src\RTT\SEGGER_RTT.c + + + $PROJ_DIR$\src\RTT\SEGGER_RTT.h + + + $PROJ_DIR$\src\RTT\SEGGER_RTT_ASM_ARMv7M.S + + + $PROJ_DIR$\src\RTT\SEGGER_RTT_Conf.h + + + $PROJ_DIR$\src\RTT\SEGGER_RTT_printf.c + + + $PROJ_DIR$\src\RTT\SEGGER_RTT_Syscalls_GCC.c + + + + TLE9461 + + $PROJ_DIR$\src\TLE9461\SBC_TLE94x1.h + + + $PROJ_DIR$\src\TLE9461\TLE94x1.c + + + $PROJ_DIR$\src\TLE9461\TLE94x1.h + + + $PROJ_DIR$\src\TLE9461\TLE94x1_DEFINES.h + + + $PROJ_DIR$\src\TLE9461\TLE94x1_ISR.h + + + $PROJ_DIR$\src\TLE9461\TLE94x1_SPI.c + + + $PROJ_DIR$\src\TLE9461\TLE94x1_SPI.h + + + + $PROJ_DIR$\src\main.c + + + diff --git a/cva_bootloader_m0118/cva_bootloader_m0118.ewt b/cva_bootloader_m0118/cva_bootloader_m0118.ewt new file mode 100644 index 0000000..5e33b2f --- /dev/null +++ b/cva_bootloader_m0118/cva_bootloader_m0118.ewt @@ -0,0 +1,3649 @@ + + + 4 + + Debug + + ARM + + 1 + + C-STAT + 517 + + 517 + + 0 + + 1 + 600 + 0 + 10 + 0 + 1 + 100 + Debug/C-STAT + + + 2.5.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RuntimeChecking + 0 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + Release + + ARM + + 0 + + C-STAT + 517 + + 517 + + 0 + + 1 + 600 + 0 + 10 + 0 + 1 + 100 + Release/C-STAT + + + 2.5.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RuntimeChecking + 0 + + 2 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + src + + bootloader + + $PROJ_DIR$\src\bootloader\bootloader.c + + + $PROJ_DIR$\src\bootloader\bootloader.h + + + $PROJ_DIR$\src\bootloader\bootloader_cfg.h + + + + drivers + + adc + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\adc\adc_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\adc\adc_drv.h + + + + clock + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\clock\clock_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\clock\clock_drv.h + + + + cmp + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cmp\cmp_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cmp\cmp_drv.h + + + + cmu + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cmu\cmu_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cmu\cmu_drv.h + + + + cpu + + cmsis + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\arm_common_tables.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\arm_const_structs.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\arm_math.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_armcc.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_armclang.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_compiler.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_gcc.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_iccarm.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\cmsis_version.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\core_cm0plus.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cmsis\mpu_armv7.h + + + + startup + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\startup\startup.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\startup\startup.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\startup\startup_M011x.S + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\startup\system_M011x.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\startup\system_M011x.h + + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\cpu_drv.h + + + + crc + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\crc\crc_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\crc\crc_drv.h + + + + dma + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\edma\edma_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\edma\edma_drv.h + + + + eim + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\eim\eim_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\eim\eim_drv.h + + + + erm + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\erm\erm_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\erm\erm_drv.h + + + + flash + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\flash\flash_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\flash\flash_drv.h + + + + flexcan + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\flexcan\flexcan_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\flexcan\flexcan_drv.h + + + + i2c + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2c\i2c_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2c\i2c_drv.h + + + + i2sm + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2sm\i2sm_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2sm\i2sm_drv.h + + + + i2ss + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2ss\i2ss_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\i2ss\i2ss_drv.h + + + + irq + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\irq\irq_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\cpu\irq\irq_drv.h + + + + lpit + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\lpit\lpit_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\lpit\lpit_drv.h + + + + lptmr + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\lptmr\lptmr_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\lptmr\lptmr_drv.h + + + + mft + + mft_cap + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_cap\mft_cap_ch.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_cap\mft_cap_ch.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_cap\mft_cap_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_cap\mft_cap_drv.h + + + + mft_oc + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_oc\mft_oc_ch.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_oc\mft_oc_ch.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_oc\mft_oc_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_oc\mft_oc_drv.h + + + + mft_pwm + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_pwm\mft_pwm_ch.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_pwm\mft_pwm_ch.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_pwm\mft_pwm_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_pwm\mft_pwm_drv.h + + + + mft_qd + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_qd\mft_qd_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_qd\mft_qd_drv.h + + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mft\mft_drv.h + + + + mpu + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mpu\mpu_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\mpu\mpu_drv.h + + + + pdb + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pdb\pdb_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pdb\pdb_drv.h + + + + pins + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pins\pins_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pins\pins_drv.h + + + + power + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\power\power_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\power\power_drv.h + + + + pwmlite + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pwmlite\pwmlite_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\pwmlite\pwmlite_drv.h + + + + reset + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\reset\reset_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\reset\reset_drv.h + + + + rtc + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\rtc\rtc_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\rtc\rtc_drv.h + + + + spi + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\spi\spi_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\spi\spi_drv.h + + + + trgmux + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\trgmux\trgmux_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\trgmux\trgmux_drv.h + + + + uart + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\uart\uart_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\uart\uart_drv.h + + + + wdg + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\wdg\wdg_drv.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\drivers\wdg\wdg_drv.h + + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\CVM011x_features.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\mcu.c + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\mcu.h + + + + fls + + $PROJ_DIR$\src\fls\fls.c + + + $PROJ_DIR$\src\fls\fls.h + + + + lib + + $PROJ_DIR$\SDK\lib\shared\common\stimer\stimer.h + + + + linker + + $PROJ_DIR$\linker\bootloader_m0118_flash.icf + + + + middleware + + isotp + + $PROJ_DIR$\SDK\middleware\isotp\isotp.c + + + $PROJ_DIR$\SDK\middleware\isotp\isotp.h + + + + uds + + stack + + $PROJ_DIR$\SDK\middleware\uds\stack\uds.c + + + $PROJ_DIR$\SDK\middleware\uds\stack\uds.h + + + + user + + $PROJ_DIR$\SDK\middleware\uds\user\uds_dtc.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_dtc.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service10.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service10.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service11.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service11.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service14.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service14.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service19.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service19.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service22.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service22.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service27.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service27.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service28.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service28.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service2E.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service2E.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service2F.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service2F.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service31.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service31.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service34.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service34.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service36.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service36.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service37.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service37.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service3E.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service3E.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service85.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_service85.h + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_user.c + + + $PROJ_DIR$\SDK\middleware\uds\user\uds_user.h + + + + + + private_driver + + drivers + + clock + + $PROJ_DIR$\src\private_driver\drivers\clock\clock_drv.c + + + $PROJ_DIR$\src\private_driver\drivers\clock\clock_drv.h + + + + + isotp + + $PROJ_DIR$\src\private_driver\isotp\isotp.c + + + $PROJ_DIR$\src\private_driver\isotp\isotp.h + + + + uds + + stack + + $PROJ_DIR$\src\private_driver\uds\stack\uds.c + + + $PROJ_DIR$\src\private_driver\uds\stack\uds.h + + + + user + + $PROJ_DIR$\src\private_driver\uds\user\uds_service10.c + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service10.h + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service11.c + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service11.h + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service27.c + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service27.h + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service31.c + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service31.h + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service34.c + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service34.h + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service36.c + + + $PROJ_DIR$\src\private_driver\uds\user\uds_service36.h + + + $PROJ_DIR$\src\private_driver\uds\user\uds_user.c + + + $PROJ_DIR$\src\private_driver\uds\user\uds_user.h + + + + + $PROJ_DIR$\src\private_driver\CVM011x_features.h + + + $PROJ_DIR$\src\private_driver\mcu.c + + + $PROJ_DIR$\src\private_driver\mcu.h + + + + reg + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\adc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\axbs_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\cmp_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\cmu_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\crc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\dmamux_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\edma_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\eim_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\erm_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\fhu_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\flexcan_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\ftfc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\gpio_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\i2c_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\i2sm_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\i2ss_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\lpit_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\lptmr_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\mft_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\mpu_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\mscm_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\pcc0_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\pcc1_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\pdb_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\pmc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\port_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\pwmlite_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\rcm_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\rtc_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\scg0_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\scg1_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\scg2_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\sim_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\spi_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\trgmux_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\uart_reg.h + + + $PROJ_DIR$\SDK\platform\devices\CVM011x\reg\wdg_reg.h + + + + RTT + + $PROJ_DIR$\src\RTT\SEGGER_RTT.c + + + $PROJ_DIR$\src\RTT\SEGGER_RTT.h + + + $PROJ_DIR$\src\RTT\SEGGER_RTT_ASM_ARMv7M.S + + + $PROJ_DIR$\src\RTT\SEGGER_RTT_Conf.h + + + $PROJ_DIR$\src\RTT\SEGGER_RTT_printf.c + + + $PROJ_DIR$\src\RTT\SEGGER_RTT_Syscalls_GCC.c + + + + TLE9461 + + $PROJ_DIR$\src\TLE9461\SBC_TLE94x1.h + + + $PROJ_DIR$\src\TLE9461\TLE94x1.c + + + $PROJ_DIR$\src\TLE9461\TLE94x1.h + + + $PROJ_DIR$\src\TLE9461\TLE94x1_DEFINES.h + + + $PROJ_DIR$\src\TLE9461\TLE94x1_ISR.h + + + $PROJ_DIR$\src\TLE9461\TLE94x1_SPI.c + + + $PROJ_DIR$\src\TLE9461\TLE94x1_SPI.h + + + + $PROJ_DIR$\src\main.c + + + diff --git a/cva_bootloader_m0118/cva_bootloader_m0118.eww b/cva_bootloader_m0118/cva_bootloader_m0118.eww new file mode 100644 index 0000000..dd2be9a --- /dev/null +++ b/cva_bootloader_m0118/cva_bootloader_m0118.eww @@ -0,0 +1,7 @@ + + + + $WS_DIR$\cva_bootloader_m0118.ewp + + + diff --git a/cva_bootloader_m0118/linker/bootloader_m0118_flash.icf b/cva_bootloader_m0118/linker/bootloader_m0118_flash.icf new file mode 100644 index 0000000..8c2bbbd --- /dev/null +++ b/cva_bootloader_m0118/linker/bootloader_m0118_flash.icf @@ -0,0 +1,145 @@ +/* +** ################################################################### +** Processor: CVM0118 +** Compiler: IAR ANSI C/C++ Compiler for ARM +** +** Abstract: +** Linker file for the IAR ANSI C/C++ Compiler for ARM +** +** Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD +** All rights reserved. +** +** Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use +** exclusively with CVA's microcontroller products. This file can be freely +** distributed within development tools that are supporting such microcontroller +** products. +** +** THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED +** OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. +** CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, +** OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +** +** http: www.cvachip.com +** +** ################################################################### +*/ + +/* If symbol __flash_vector_table__=1 is defined at link time + * the interrupt vector will not be copied to RAM. + * Warning: Using the interrupt vector from FLASH will not allow + * INT_SYS_InstallHandler because the section is Read Only. + */ + +define symbol __flash_vector_table__ = 0x00000001; + +define symbol __ram_vector_table_size__ = isdefinedsymbol(__flash_vector_table__) ? 0 : 0x000000c0; +define symbol __ram_vector_table_offset__ = isdefinedsymbol(__flash_vector_table__) ? 0 : 0x000000BF; + +/* Flash */ +define symbol m_interrupts_start = 0x00000000; +define symbol m_interrupts_end = 0x000000BF; + +define symbol m_bootinformation_start = 0x000000C0; +define symbol m_bootinformation_end = 0x000003FF; + +define symbol m_flash_config_start = 0x00000400; +define symbol m_flash_config_end = 0x0000041F; + +define symbol m_text_start = 0x00000420; +define symbol m_text_end = 0x0000FFFF; + +/* .data space */ +define symbol m_interrupts_ram_start = 0x20000000; +define symbol m_interrupts_ram_end = 0x20000000 + __ram_vector_table_offset__; + +define symbol m_data_start = m_interrupts_ram_start + __ram_vector_table_size__; +define symbol m_data_end = m_data_start + 0x00001FFF; + +/* .bss stack ... */ +define symbol m_data_2_start = m_data_end + 0x00000001; +define symbol m_data_2_end = m_data_2_start + 0x00003BF0 - 0x00000001; + +/* Flash driver space: 2K Bytes */ +define symbol m_ram_flash_driver_map_start = m_data_2_end + 0x00000001; +define symbol m_ram_flash_driver_map_end = m_ram_flash_driver_map_start + 0x0000000F; + +define symbol m_ram_flash_driver_start = m_ram_flash_driver_map_end + 0x00000001; +define symbol m_ram_flash_driver_end = 0x200063EF; + +/* No initial Ram space: 16 Bytes */ +define symbol m_data_noinit_start = m_ram_flash_driver_end + 0x00000001; +define symbol m_data_noinit_end = 0x200063FF; + +/* Stack space: 512 Bytes */ +/* Stack & Heap Sizes */ +if (isdefinedsymbol(__stack_size__)) { + define symbol __size_cstack__ = __stack_size__; +} else { + define symbol __size_cstack__ = 0x00000200; +} + +if (isdefinedsymbol(__heap_size__)) { + define symbol __size_heap__ = __heap_size__; +} else { + define symbol __size_heap__ = 0x00000200; +} + +define exported symbol __VECTOR_TABLE = m_interrupts_start; +define exported symbol __VECTOR_RAM = isdefinedsymbol(__flash_vector_table__) ? m_interrupts_start : m_interrupts_ram_start; +define exported symbol __RAM_VECTOR_TABLE_SIZE = __ram_vector_table_size__; + +define exported symbol __RAM_START = m_interrupts_ram_start; +define exported symbol __RAM_END = m_data_2_end; + +define memory mem with size = 4G; +define region m_flash_config_region = mem:[from m_flash_config_start to m_flash_config_end]; +define region BootInfo_region = mem:[from m_bootinformation_start to m_bootinformation_end]; + +define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end] + | mem:[from m_text_start to m_text_end]; + +define region DATA_region = mem:[from m_data_start to m_data_end]; + +define region DATA_flash_driver_map_region = mem:[from m_ram_flash_driver_map_start to m_ram_flash_driver_map_end]; + +define region DATA_flash_driver_region = mem:[from m_ram_flash_driver_start to m_ram_flash_driver_end]; + +define region DATA_noinit_region = mem:[from m_data_noinit_start to m_data_noinit_end]; + +define region DATA_region_2 = mem:[from m_data_2_start to m_data_2_end]; +define region CSTACK_region = mem:[from m_data_2_end + 1 - __size_cstack__ to m_data_2_end]; +define region m_interrupts_ram_region = mem:[from m_interrupts_ram_start to m_interrupts_ram_end]; + + +define block CSTACK with alignment = 8, size = __size_cstack__ { }; +define block HEAP with alignment = 8, size = __size_heap__ { }; +define block RW { readwrite }; +define block ZI { zi }; + + +define block __CODE_ROM { section .textrw_init }; +define block __CODE_RAM { section .textrw }; + +initialize manually { section .textrw }; +initialize manually { section .bss}; +initialize manually { section .data, section .code_ram }; +initialize manually { section __DLIB_PERTHREAD }; + +do not initialize { section .no_init, section .bss, section .data, section __DLIB_PERTHREAD}; + +place at address mem: m_interrupts_start { readonly section .intvec }; +place in m_flash_config_region { section FlashConfig }; +place in TEXT_region { readonly }; +place in TEXT_region { block __CODE_ROM }; +place in DATA_region { block RW }; +place in DATA_region { block __CODE_RAM }; +place in DATA_region_2 { block ZI }; +place in DATA_region_2 { last block HEAP }; +place in CSTACK_region { block CSTACK }; +place in m_interrupts_ram_region { section m_interrupts_ram }; +place in DATA_noinit_region { readwrite section .no_init }; +place in DATA_flash_driver_map_region { readwrite section .ram_flash_driver_map}; +place in DATA_flash_driver_region { readonly section .ram_flash_driver}; +place in BootInfo_region { readonly section .bootloaderInfo}; + diff --git a/cva_bootloader_m0118/settings/cva_bootloader_m0118.Debug.cspy.bat b/cva_bootloader_m0118/settings/cva_bootloader_m0118.Debug.cspy.bat new file mode 100644 index 0000000..73d1b93 --- /dev/null +++ b/cva_bootloader_m0118/settings/cva_bootloader_m0118.Debug.cspy.bat @@ -0,0 +1,40 @@ +@REM This batch file has been generated by the IAR Embedded Workbench +@REM C-SPY Debugger, as an aid to preparing a command line for running +@REM the cspybat command line utility using the appropriate settings. +@REM +@REM Note that this file is generated every time a new debug session +@REM is initialized, so you may want to move or rename the file before +@REM making changes. +@REM +@REM You can launch cspybat by typing the name of this batch file followed +@REM by the name of the debug file (usually an ELF/DWARF or UBROF file). +@REM +@REM Read about available command line parameters in the C-SPY Debugging +@REM Guide. Hints about additional command line parameters that may be +@REM useful in specific cases: +@REM --download_only Downloads a code image without starting a debug +@REM session afterwards. +@REM --silent Omits the sign-on message. +@REM --timeout Limits the maximum allowed execution time. +@REM + + +@echo off + +if not "%~1" == "" goto debugFile + +@echo on + +"D:\software\IAR\common\bin\cspybat" -f "E:\work\wk\K86\CVM0118BOOT\cva_bootloader_m0118\settings\cva_bootloader_m0118.Debug.general.xcl" --backend -f "E:\work\wk\K86\CVM0118BOOT\cva_bootloader_m0118\settings\cva_bootloader_m0118.Debug.driver.xcl" + +@echo off +goto end + +:debugFile + +@echo on + +"D:\software\IAR\common\bin\cspybat" -f "E:\work\wk\K86\CVM0118BOOT\cva_bootloader_m0118\settings\cva_bootloader_m0118.Debug.general.xcl" "--debug_file=%~1" --backend -f "E:\work\wk\K86\CVM0118BOOT\cva_bootloader_m0118\settings\cva_bootloader_m0118.Debug.driver.xcl" + +@echo off +:end \ No newline at end of file diff --git a/cva_bootloader_m0118/settings/cva_bootloader_m0118.Debug.cspy.ps1 b/cva_bootloader_m0118/settings/cva_bootloader_m0118.Debug.cspy.ps1 new file mode 100644 index 0000000..563673c --- /dev/null +++ b/cva_bootloader_m0118/settings/cva_bootloader_m0118.Debug.cspy.ps1 @@ -0,0 +1,31 @@ +param([String]$debugfile = ""); + +# This powershell file has been generated by the IAR Embedded Workbench +# C - SPY Debugger, as an aid to preparing a command line for running +# the cspybat command line utility using the appropriate settings. +# +# Note that this file is generated every time a new debug session +# is initialized, so you may want to move or rename the file before +# making changes. +# +# You can launch cspybat by typing Powershell.exe -File followed by the name of this batch file, followed +# by the name of the debug file (usually an ELF / DWARF or UBROF file). +# +# Read about available command line parameters in the C - SPY Debugging +# Guide. Hints about additional command line parameters that may be +# useful in specific cases : +# --download_only Downloads a code image without starting a debug +# session afterwards. +# --silent Omits the sign - on message. +# --timeout Limits the maximum allowed execution time. +# + + +if ($debugfile -eq "") +{ +& "D:\software\IAR\common\bin\cspybat" -f "E:\work\wk\K86\CVM0118BOOT\cva_bootloader_m0118\settings\cva_bootloader_m0118.Debug.general.xcl" --backend -f "E:\work\wk\K86\CVM0118BOOT\cva_bootloader_m0118\settings\cva_bootloader_m0118.Debug.driver.xcl" +} +else +{ +& "D:\software\IAR\common\bin\cspybat" -f "E:\work\wk\K86\CVM0118BOOT\cva_bootloader_m0118\settings\cva_bootloader_m0118.Debug.general.xcl" --debug_file=$debugfile --backend -f "E:\work\wk\K86\CVM0118BOOT\cva_bootloader_m0118\settings\cva_bootloader_m0118.Debug.driver.xcl" +} diff --git a/cva_bootloader_m0118/settings/cva_bootloader_m0118.Debug.driver.xcl b/cva_bootloader_m0118/settings/cva_bootloader_m0118.Debug.driver.xcl new file mode 100644 index 0000000..8a274d0 --- /dev/null +++ b/cva_bootloader_m0118/settings/cva_bootloader_m0118.Debug.driver.xcl @@ -0,0 +1,31 @@ +"--endian=little" + +"--cpu=Cortex-M0+" + +"--fpu=None" + +"-p" + +"D:\software\IAR\arm\config\debugger\CVAChip\CVM0118.ddf" + +"--semihosting" + +"--device=CVM0118" + +"--drv_communication=USB0" + +"--drv_interface_speed=auto" + +"--jlink_initial_speed=1000" + +"--jlink_reset_strategy=0,0" + +"--drv_interface=SWD" + +"--drv_catch_exceptions=0x000" + +"--drv_swo_clock_setup=112000000,0,2000000" + + + + diff --git a/cva_bootloader_m0118/settings/cva_bootloader_m0118.Debug.general.xcl b/cva_bootloader_m0118/settings/cva_bootloader_m0118.Debug.general.xcl new file mode 100644 index 0000000..b904051 --- /dev/null +++ b/cva_bootloader_m0118/settings/cva_bootloader_m0118.Debug.general.xcl @@ -0,0 +1,11 @@ +"D:\software\IAR\arm\bin\armPROC.dll" + +"D:\software\IAR\arm\bin\armJLINK.dll" + +"E:\work\wk\K86\CVM0118BOOT\cva_bootloader_m0118\Debug_FLASH\Exe\bootloader_m118.out" + +--plugin="D:\software\IAR\arm\bin\armbat.dll" + + + + diff --git a/cva_bootloader_m0118/settings/cva_bootloader_m0118.crun b/cva_bootloader_m0118/settings/cva_bootloader_m0118.crun new file mode 100644 index 0000000..d71ea55 --- /dev/null +++ b/cva_bootloader_m0118/settings/cva_bootloader_m0118.crun @@ -0,0 +1,13 @@ + + + 1 + + + * + * + * + 0 + 1 + + + diff --git a/cva_bootloader_m0118/settings/cva_bootloader_m0118.dbgdt b/cva_bootloader_m0118/settings/cva_bootloader_m0118.dbgdt new file mode 100644 index 0000000..f37c31e --- /dev/null +++ b/cva_bootloader_m0118/settings/cva_bootloader_m0118.dbgdt @@ -0,0 +1,1017 @@ + + + + + 34048 + 34049 + 34050 + 34051 + 34052 + 34053 + 34054 + 34055 + 34056 + 34057 + 34058 + 34059 + 34060 + 34061 + 34062 + 34063 + 34064 + 34065 + 34066 + 34067 + 34068 + 34069 + 34070 + 34071 + 34072 + 34073 + 34074 + 34075 + 34076 + 34077 + 34078 + 34079 + 34080 + 34081 + 34082 + 34083 + 34084 + 34085 + 34086 + 34087 + 34088 + 34089 + 34090 + 34091 + 34092 + 34093 + 34094 + 34095 + 34096 + 34097 + 34098 + 34099 + 34100 + 34101 + 34102 + 34103 + 34104 + 34105 + + + + + 34001 + 0 + + + + + 34390 + 34323 + 34398 + 34400 + 34397 + 34320 + 34321 + 34324 + 0 + + + + + 37459 + 37460 + + + + + 57600 + 57601 + 57603 + 33024 + 0 + 57607 + 0 + 57635 + 57634 + 57637 + 0 + 57643 + 57644 + 0 + 33090 + 33057 + 57636 + 57640 + 57641 + 33026 + 33065 + 33063 + 33064 + 33053 + 33054 + 0 + 33035 + 33036 + 34399 + 0 + 33055 + 33056 + 33094 + 0 + + + + + + Disassembly + _I0 + + + 500 + 20 + + 1 + 1 + + + 14 + 32 + + + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 830000000E001386000001000000488100000100000010860000090000005F8600000200000020810000010000000C81000013000000568600005C00000055840000180000005E860000010000000E810000050000000B81000001000000118600000500000046810000040000000D81000001000000 + + + 0F000D8400000F84000008840000FFFFFFFF54840000328100001C810000098400005384000000DC000001DC000002DC000003DC000004DC00001C970000 + 3600139700005B020000048400004D0000001097000056020000048100001B0000001581000024000000318400005400000007E100003F000000208100002A0000000F81000022000000009000005800000004E100003D00000007970000960200000C8100001F00000001E100003A0000000D80000018000000159700005A020000098100001D000000068400004F0000001297000055020000038400004C00000017810000260000000F970000540200001481000023000000449200000C0000000081000019000000308400009C0100000E8400009A0100001F810000290000000E810000210000001F9200000900000003E100003C000000179700005F0200002D9200000B00000000E10000390000000B81000067010000149700005D020000D184000008000000058400004E00000041E10000460000001197000059020000028400004B000000058100001C00000016810000250000000E970000530200001084000052000000328400005500000005E100003E00000051840000570000000A8400005000000035E100004500000002E100003B0000000D8100006901000016970000600200002C9200000A000000 + + + 0 + 0A0000000A0000006E0000006E000000 + 000000001A030000000600002B030000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 4294967295 + 00000000CB010000000600007C020000 + 00000000B40100000006000065020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34052 + 00000000170000000601000078010000 + 560400004A000000FC05000000030000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34072 + 00000000170000000601000078010000 + 560400004A000000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34095 + 00000000170000000601000078010000 + 560400004A000000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34101 + 00000000170000000601000078010000 + 5204000046000000000600001A030000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + + sBootloader_Cb + + + + Expression + Location + Type + Value + + + 100 + 150 + 100 + 100 + + 0 + + + 34102 + 00000000170000000601000078010000 + 560400004A000000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34103 + 00000000170000000601000078010000 + 560400004A000000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34104 + 00000000170000000601000078010000 + 560400004A000000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34053 + 000000001700000022010000C8000000 + 0400000081020000FC05000000030000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34079 + 000000001700000022010000C8000000 + 0400000081020000FC05000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34054 + 000000001700000022010000C8000000 + 04000000810200004A04000000030000 + 32768 + 0 + 0 + 32767 + 0 + + + 1 + + + 34062 + 000000001700000022010000C8000000 + 04000000810200004A04000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34066 + 000000001700000022010000C8000000 + 04000000810200004A04000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34067 + 000000001700000022010000C8000000 + 04000000810200004A04000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34068 + 000000001700000022010000C8000000 + 04000000810200004A04000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34087 + 000000001700000022010000C8000000 + 04000000810200004A04000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34090 + 000000001700000022010000C8000000 + 04000000810200004A04000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34100 + 000000001700000022010000C8000000 + 04000000810200004A04000000030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34055 + 000000001700000080020000A8000000 + 00000000000000008002000091000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34056 + 00000000170000000601000078010000 + 0400000030000000020100004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34092 + 00000000170000000601000078010000 + 0400000030000000020100004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34093 + 00000000170000000601000078010000 + 0400000030000000020100004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34057 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34058 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34059 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34060 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34061 + 00000000170000000601000078010000 + FE04000030000000FC0500004B020000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34073 + 00000000170000000601000078010000 + FE04000030000000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34063 + 00000000170000000601000078010000 + A4020000320000004E04000065020000 + 16384 + 0 + 0 + 32767 + 0 + + + 1 + + + 34064 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34065 + 000000001700000022010000C8000000 + 04000000CC010000FC0500004B020000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34070 + 000000001700000022010000C8000000 + 04000000CC010000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34088 + 000000001700000022010000C8000000 + 04000000CC010000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34089 + 000000001700000022010000C8000000 + 04000000CC010000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34069 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34071 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34074 + 00000000170000000601000078010000 + FE04000030000000FC0500004B020000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34082 + 00000000170000000601000078010000 + FE04000030000000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34083 + 00000000170000000601000078010000 + FE04000030000000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34084 + 00000000170000000601000078010000 + FE04000030000000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34085 + 00000000170000000601000078010000 + FE04000030000000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34075 + 000000001700000022010000C8000000 + 04000000CC010000FC0500004B020000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34076 + 000000001700000022010000C8000000 + 04000000CC010000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34077 + 000000001700000022010000C8000000 + 04000000CC010000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34078 + 000000001700000022010000C8000000 + 04000000CC010000FC0500004B020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34080 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34081 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34086 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34091 + 000000001700000080020000A8000000 + 00000000000000008002000091000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34094 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34096 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34097 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34098 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34099 + 0000000017000000AE010000D8000000 + 0000000000000000AE010000C1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34105 + 00000000170000000601000078010000 + 00000000320000000601000065020000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 0000000036000000000000000010000001000000FFFFFFFFFFFFFFFF06010000320000000A01000065020000010000000200001004000000010000000000000000000000398500000000000000000000000000000000000001000000398500000100000039850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000338500000000000000000000000000000000000001000000338500000100000033850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000328500000000000000000000000000000000000001000000328500000100000032850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000318500000000000000000000000000000000000001000000318500000100000031850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000308500000000000000000000000000000000000001000000308500000100000030850000000000000040000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000000040000000100000000000000000000002E85000000000000000000000000000000000000010000002E850000010000002E850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000002B85000000000000000000000000000000000000010000002B850000010000002B850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000268500000000000000000000000000000000000001000000268500000100000026850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000218500000000000000000000000000000000000001000000218500000100000021850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000208500000000000000000000000000000000000001000000208500000100000020850000000000000080000000000000FFFFFFFFFFFFFFFF00000000B001000000060000B4010000000000000100000004000000010000000000000000000000FFFFFFFF040000001B8500001C8500001D8500001E850000FFFF02000B004354616262656450616E65008000000000000000000000CB010000000600007C02000000000000B40100000006000065020000000000004080004604000000FFFEFF084D0065006D006F007200790020003100000000001B85000001000000FFFFFFFFFFFFFFFFFFFEFF084D0065006D006F007200790020003200000000001C85000001000000FFFFFFFFFFFFFFFFFFFEFF084D0065006D006F007200790020003300000000001D85000001000000FFFFFFFFFFFFFFFFFFFEFF084D0065006D006F007200790020003400000000001E85000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFF1B85000001000000FFFFFFFF1B850000000000000040000000000000FFFFFFFFFFFFFFFFF604000018000000FA04000065020000000000000200000004000000010000000000000000000000FFFFFFFF050000001A8500002285000023850000248500002585000001800040000000000000FA0400002F000000000600007C020000FA040000180000000006000065020000000000004040004605000000FFFEFF124D006100630072006F00200052006500670069007300740072006100740069006F006E00000000001A85000001000000FFFFFFFFFFFFFFFFFFFEFF0B52006500670069007300740065007200730020003100000000002285000001000000FFFFFFFFFFFFFFFFFFFEFF0B52006500670069007300740065007200730020003200000000002385000001000000FFFFFFFFFFFFFFFFFFFEFF0B52006500670069007300740065007200730020003300000000002485000001000000FFFFFFFFFFFFFFFFFFFEFF0B52006500670069007300740065007200730020003400000000002585000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFF1A85000001000000FFFFFFFF1A850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000178500000000000000000000000000000000000001000000178500000100000017850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000158500000000000000000000000000000000000001000000158500000100000015850000000000000080000000000000FFFFFFFFFFFFFFFF00000000B001000000060000B4010000000000000100000004000000010000000000000000000000FFFFFFFF04000000118500001685000028850000298500000180008000000000000000000000CB010000000600007C02000000000000B40100000006000065020000000000004080004604000000FFFEFF09530057004F00200054007200610063006500000000001185000001000000FFFFFFFFFFFFFFFFFFFEFF11460069006E006400200049006E002000530057004F00200054007200610063006500000000001685000001000000FFFFFFFFFFFFFFFFFFFEFF12450054004D002000460075006E006300740069006F006E00200054007200610063006500000000002885000001000000FFFFFFFFFFFFFFFFFFFEFF09450054004D00200054007200610063006500000000002985000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFF1185000001000000FFFFFFFF11850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000108500000000000000000000000000000000000001000000108500000100000010850000000000000040000001000000FFFFFFFFFFFFFFFFA002000032000000A4020000650200000100000002000010040000000100000019FCFFFFB50000000F85000000000000000000000000000000000000010000000F850000010000000F850000000000000040000000000000FFFFFFFFFFFFFFFFF604000018000000FA04000065020000000000000200000004000000010000000000000000000000FFFFFFFF020000000D8500001985000001800040000000000000FA0400002F000000000600007C020000FA040000180000000006000065020000000000004040004602000000FFFEFF0F4400650062007500670067006500720020004D006100630072006F007300000000000D85000001000000FFFFFFFFFFFFFFFFFFFEFF114D006100630072006F00200051007500690063006B006C00610075006E0063006800000000001985000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFF0D85000001000000FFFFFFFF0D850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000C85000000000000000000000000000000000000010000000C850000010000000C850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000B85000000000000000000000000000000000000010000000B850000010000000B850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000A85000000000000000000000000000000000000010000000A850000010000000A850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000098500000000000000000000000000000000000001000000098500000100000009850000000000000010000000000000FFFFFFFFFFFFFFFF06010000180000000A01000065020000000000000200000004000000010000000000000000000000FFFFFFFF03000000088500002C8500002D85000001800010000000000000000000002F000000060100007C02000000000000180000000601000065020000000000004010004603000000FFFEFF0A430061006C006C00200053007400610063006B00000000000885000001000000FFFFFFFFFFFFFFFFFFFEFF0753007400610063006B0020003100000000002C85000001000000FFFFFFFFFFFFFFFFFFFEFF0753007400610063006B0020003200000000002D85000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFF0885000001000000FFFFFFFF08850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000078500000000000000000000000000000000000001000000078500000100000007850000000000000080000001000000FFFFFFFFFFFFFFFF00000000650200004E04000069020000010000000100001004000000010000000000000000000000FFFFFFFF08000000068500000E850000128500001385000014850000278500002A850000348500000180008000000100000000000000800200004E0400003103000000000000690200004E0400001A030000000000004080005608000000FFFEFF054200750069006C006400010000000685000001000000FFFFFFFFFFFFFFFFFFFEFF094400650062007500670020004C006F006700010000000E85000001000000FFFFFFFFFFFFFFFFFFFEFF0C4400650063006C00610072006100740069006F006E007300000000001285000001000000FFFFFFFFFFFFFFFFFFFEFF0A5200650066006500720065006E00630065007300000000001385000001000000FFFFFFFFFFFFFFFFFFFEFF0D460069006E006400200069006E002000460069006C0065007300000000001485000001000000FFFFFFFFFFFFFFFFFFFEFF1541006D0062006900670075006F0075007300200044006500660069006E006900740069006F006E007300000000002785000001000000FFFFFFFFFFFFFFFFFFFEFF1153006F0075007200630065002000420072006F0077007300650020004C006F006700000000002A85000001000000FFFFFFFFFFFFFFFFFFFEFF0B54006F006F006C0020004F0075007400700075007400000000003485000001000000FFFFFFFFFFFFFFFF01000000000000000000000000000000000000000000000001000000FFFFFFFF0685000001000000FFFFFFFF06850000000000000080000000000000FFFFFFFFFFFFFFFF00000000650200000006000069020000000000000100000004000000010000000000000000000000FFFFFFFF02000000058500001F85000001800080000000000000000000008002000000060000310300000000000069020000000600001A030000000000004080004602000000FFFEFF0B42007200650061006B0070006F0069006E0074007300000000000585000001000000FFFFFFFFFFFFFFFFFFFEFF1042007200650061006B0070006F0069006E007400200055007300610067006500000000001F85000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFF0585000001000000FFFFFFFF05850000000000000040000001000000FFFFFFFFFFFFFFFF4E04000032000000520400001A0300000100000002000010040000000100000019FCFFFFB5000000FFFFFFFF0700000004850000188500002F8500003585000036850000378500003885000001800040000001000000520400004900000000060000310300005204000032000000000600001A030000000000004040005607000000FFFEFF044100750074006F00000000000485000001000000FFFFFFFFFFFFFFFFFFFEFF064C006F00630061006C007300000000001885000001000000FFFFFFFFFFFFFFFFFFFEFF0A4C00690076006500200057006100740063006800000000002F85000001000000FFFFFFFFFFFFFFFFFFFEFF075700610074006300680020003100010000003585000001000000FFFFFFFFFFFFFFFFFFFEFF075700610074006300680020003200000000003685000001000000FFFFFFFFFFFFFFFFFFFEFF075700610074006300680020003300000000003785000001000000FFFFFFFFFFFFFFFFFFFEFF075700610074006300680020003400000000003885000001000000FFFFFFFFFFFFFFFF03000000000000000000000000000000000000000000000001000000FFFFFFFF0485000001000000FFFFFFFF04850000000000000000000000000000 + + + CMSIS-Pack + 00200000010000000100FFFF01001100434D4643546F6F6C426172427574746F6ED18400000200000021040000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF0A43004D005300490053002D005000610063006B0018000000 + + + 34048 + 0A0000000A0000006E0000006E000000 + 6704000000000000950400001A000000 + 8192 + 0 + 0 + 24 + 0 + + + 1 + + + Debug + 00200000010000000800FFFF01001100434D4643546F6F6C426172427574746F6E56860000020004003C040000FFFEFF0000000000000000000000000001000000010000000180138600000200040038040000FFFEFF00000000000000000000000000010000000100000001805E860000020004003E040000FFFEFF0000000000000000000000000001000000010000000180608600000200040040040000FFFEFF00000000000000000000000000010000000100000001805D860000020004003D040000FFFEFF0000000000000000000000000001000000010000000180108600000200040036040000FFFEFF0000000000000000000000000001000000010000000180118600000200000037040000FFFEFF000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E148600000200040039040000FFFEFF205200650073006500740020007400680065002000640065006200750067006700650064002000700072006F006700720061006D000A00520065007300650074000000000000000000000000000100000001000000000000000000000001000000060009802B87000000000000FFFFFFFFFFFEFF13440069007300610062006C0065006400200028004E006F0020007200650073006500740029000100000000000000000000000100000001000000000000000000000001000000000009802C87000000000000FFFFFFFFFFFEFF0853006F006600740077006100720065000100000000000000000000000100000001000000000000000000000001000000000009802D87000000000000FFFFFFFFFFFEFF144800610072006400770061007200650020002800520065007300650074002000700069006E0029000100000000000000000000000100000001000000000000000000000001000000000009802F87000000000000FFFFFFFFFFFEFF064E006F0072006D0061006C000100000000000000000000000100000001000000000000000000000001000000000009800000000000000400FFFFFFFFFFFEFF000000000000000000000000000100000001000000000000000000000001000000000009801986000000000000FFFFFFFFFFFEFF000100000000000000000000000100000001000000000000000000000001000000000000000000FFFEFF0544006500620075006700C6000000 + + + 34049 + 0A0000000A0000006E0000006E000000 + 51030000000000002D0400001A000000 + 8192 + 0 + 0 + 198 + 0 + + + 1 + + + Trace + 00200000010000000200FFFF01001100434D4643546F6F6C426172427574746F6E5392000000000000A3040000FFFEFF03450054004D00000000000000000000000000010000000100000001805492000000000400A4040000FFFEFF03530057004F00000000000000000000000000010000000100000000000000FFFEFF05540072006100630065002F000000 + + + 34050 + 0A0000000A0000006E0000006E000000 + 2D04000000000000670400001A000000 + 8192 + 0 + 0 + 47 + 0 + + + 1 + + + Main + 00200000010000002100FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000083040000FFFEFF000000000000000000000000000100000001000000018001E100000000000084040000FFFEFF000000000000000000000000000100000001000000018003E100000000000086040000FFFEFF0000000000000000000000000001000000010000000180008100000000000063040000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018007E100000000000089040000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018023E10000000004008B040000FFFEFF000000000000000000000000000100000001000000018022E10000000004008A040000FFFEFF000000000000000000000000000100000001000000018025E10000000000008C040000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001802BE10000000004008D040000FFFEFF00000000000000000000000000010000000100000001802CE10000000004008E040000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000FFFF01000D005061737465436F6D626F426F784281000000000000FFFFFFFFFFFEFF000100000000000000010000000000000001000000B400000002002050FFFFFFFFFFFEFF00960000000000000000000180218100000000040075040000FFFEFF000000000000000000000000000100000001000000018024E10000000000007E040000FFFEFF000000000000000000000000000100000001000000018028E10000000004007D040000FFFEFF000000000000000000000000000100000001000000018029E10000000000007F040000FFFEFF0000000000000000000000000001000000010000000180028100000000000064040000FFFEFF0000000000000000000000000001000000010000000180298100000000000079040000FFFEFF0000000000000000000000000001000000010000000180278100000000000077040000FFFEFF0000000000000000000000000001000000010000000180288100000000000078040000FFFEFF00000000000000000000000000010000000100000001801D8100000000000071040000FFFEFF00000000000000000000000000010000000100000001801E8100000000040072040000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800B8100000200000068040000FFFEFF00000000000000000000000000010000000100000001800C8100000200000069040000FFFEFF00000000000000000000000000010000000100000001805F860000020000007C040000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001801F8100000200000073040000FFFEFF0000000000000000000000000001000000010000000180208100000200000074040000FFFEFF000000000000000000000000000100000001000000018046810000020002007A040000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF044D00610069006E003B030000 + + + 34051 + 0A0000000A0000006E0000006E000000 + 0000000000000000510300001A000000 + 8192 + 0 + 0 + 827 + 0 + + + 1 + + + + diff --git a/cva_bootloader_m0118/settings/cva_bootloader_m0118.dnx b/cva_bootloader_m0118/settings/cva_bootloader_m0118.dnx new file mode 100644 index 0000000..c96e006 --- /dev/null +++ b/cva_bootloader_m0118/settings/cva_bootloader_m0118.dnx @@ -0,0 +1,83 @@ + + + + 0 + 1 + 90 + 1 + 1 + 1 + main + 0 + 50 + + + 0 + D:\software\IAR\arm\config\debugger\CVAChip\CVM0118.ddf + + + 1 + 0 + + + 519825789 + + + 1 + 0 + + + 0 + 1 + + + 1 + 10 + $PROJ_DIR$\TermIOInput.txt + 1 + 0 + 2 + 2 + + + _ 0 + _ 0 + + + 0 + + + 12 + 0 + 0x10000 + 0x0 + 0x0 + _ 0 + _ 0 + + + 0 + 0 + + + 0 + 1 + 0 + 0 + + + _ 0 + _ "" + + + 0 + + + _ 0 "EMUL_CODE" "{$PROJ_DIR$\src\bootloader\bootloader.c}.869.25" 0 0 1 "" 0 "" 0 + 1 + + + 0 + 0 + + diff --git a/cva_bootloader_m0118/settings/cva_bootloader_m0118.wsdt b/cva_bootloader_m0118/settings/cva_bootloader_m0118.wsdt new file mode 100644 index 0000000..22b293a --- /dev/null +++ b/cva_bootloader_m0118/settings/cva_bootloader_m0118.wsdt @@ -0,0 +1,504 @@ + + + + + cva_bootloader_m0118/Debug + + + + + 34048 + 34049 + 34050 + 34051 + 34052 + 34053 + 34054 + 34055 + 34056 + 34057 + 34058 + 34059 + 34060 + 34061 + 34062 + 34063 + + + + + 34001 + 0 + + + + + 57600 + 57601 + 57603 + 33024 + 0 + 57607 + 0 + 57635 + 57634 + 57637 + 0 + 57643 + 57644 + 0 + 33090 + 33057 + 57636 + 57640 + 57641 + 33026 + 33065 + 33063 + 33064 + 33053 + 33054 + 0 + 33035 + 33036 + 34399 + 0 + 33038 + 33039 + 33877 + 0 + + + + + Log + _I0 + + + 1052 + 20 + + 2 + $PROJ_DIR$\DebugLog.log + 0 + 0 + + + + cva_bootloader_m0118 + cva_bootloader_m0118/src + + + + 14 + 27 + + + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 8E0000000E0013860000010000001086000001000000488100000100000020810000010000005F860000020000000C8100005B000000568600000100000055840000190000000E810000140000005E860000010000000B81000002000000118600000100000046810000010000000D81000001000000 + + + 3E000D8400000F84000008840000FFFFFFFF54840000328100001C81000009840000538400002DDE00001FDE000020DE000021DE000026DE000028DE000023DE000022DE000024DE000027DE000025DE000020920000289200002992000037920000389200003492000033920000259200001E9200001D9200002CDE00000C84000033840000788400001184000008800000098000000A8000000B8000000C800000158000000A81000001E80000778400000784000086840000808C000044D500003C8400003D840000408400004C8400003E8400004B8400004D8400003F8400003A8400003B8400005A8400005B8400004881000001000000 + 360004840000EA040000139700005B02000015810000240000000481000063000000109700005602000007E100003F000000318400005400000004E100003D00000000900000580000000F81000022000000208100002A0000000D8000001800000001E100003A0000000C8100001F000000079700009602000006840000EC0400000981000065000000159700005A0200001781000026000000038400004C000000129700005502000014810000230000000F970000540200000E84000099000000308400009B0000000081000019000000449200000C00000003E100003C0000001F920000090000000E810000210000001F810000290000000B8100006600000000E10000390000002D9200000B000000179700005F02000041E1000046000000058400004E000000D184000008000000149700005D02000016810000250000000581000064000000028400004B0000001197000059020000328400005500000010840000520000000E97000053020000518400005700000005E100003E0000000D8100006800000002E100008300000035E100008D0000000A840000500000002C9200000A0000001697000060020000 + + + 0 + 0A0000000A0000006E0000006E000000 + 00000000A7020000F0040000B8020000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34050 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 4294967295 + D80000005903000083070000C2040000 + 000000003E010000F0040000A7020000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34051 + 000000001700000022010000C8000000 + 0400000056010000EC0400008D020000 + 32768 + 0 + 0 + 32767 + 0 + + + 1 + + + + File + Line + Messages + _I0 + + + 363 + 40 + 810 + 20 + + 2 + $WS_DIR$\BuildLog.log + 0 + 0 + + + 34055 + 000000001700000022010000C8000000 + 0400000056010000EC0400008D020000 + 32768 + 0 + 0 + 32767 + 0 + + + 1 + + + 34056 + 000000001700000022010000C8000000 + 0400000056010000A70600008D020000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 532 + 76 + 912 + 2 + + 0 + -1 + + + 34057 + 000000001700000022010000C8000000 + 0400000056010000A70600008D020000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 532 + 76 + 912 + 2 + + 0 + -1 + + + 34058 + 000000001700000022010000C8000000 + 0400000056010000A70600008D020000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34059 + 000000001700000022010000C8000000 + 0400000056010000A70600008D020000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 532 + 76 + 912 + 2 + + 0 + -1 + + + 34060 + 000000001700000022010000C8000000 + 0400000056010000A70600008D020000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 2 + $WS_DIR/SourceBrowseLog.log + 0 + -1 + + + 34062 + 000000001700000022010000C8000000 + 0400000056010000A70600008D020000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 2 + + 0 + -1 + + + 34052 + 000000001700000080020000A8000000 + 00000000000000008002000091000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 2 + + + + + + + + + <Right-click on a symbol in the editor to show a call graph> + + + + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + File + Function + Line + + + 200 + 700 + 100 + + + + 34053 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34054 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + + Check + File + Line + Message + Severity + + + 200 + 200 + 100 + 500 + 100 + + + + 34061 + 000000001700000080020000A8000000 + 00000000000000008002000091000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 2 + + + 0 + + + F:\FCB_project\RP-77\CVM0118BOOT\cva_bootloader_m0118\Debug\BrowseInfo\cva_bootloader_m0118.pbw + + + File + Name + Scope + Symbol type + + + 300 + 300 + 300 + 300 + + + + 34063 + 00000000170000000601000078010000 + 0000000032000000B00100003A010000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 000000000E000000000000000010000001000000FFFFFFFFFFFFFFFFB001000032000000B40100003A0100000100000002000010040000000100000091FFFFFFF10400000F85000000000000000000000000000000000000010000000F850000010000000F850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000D85000000000000000000000000000000000000010000000D850000010000000D850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000068500000000000000000000000000000000000001000000068500000100000006850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000058500000000000000000000000000000000000001000000058500000100000005850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000048500000000000000000000000000000000000001000000048500000100000004850000000000000080000001000000FFFFFFFFFFFFFFFF000000003A010000F00400003E01000001000000010000100400000001000000D2FDFFFF6F000000FFFFFFFF08000000038500000785000008850000098500000A8500000B8500000C8500000E850000FFFF02000B004354616262656450616E650080000001000000D80000005903000083070000C2040000000000003E010000F0040000A7020000000000004080005608000000FFFEFF054200750069006C006400010000000385000001000000FFFFFFFFFFFFFFFFFFFEFF094400650062007500670020004C006F006700010000000785000001000000FFFFFFFFFFFFFFFFFFFEFF0C4400650063006C00610072006100740069006F006E007300000000000885000001000000FFFFFFFFFFFFFFFFFFFEFF0A5200650066006500720065006E00630065007300000000000985000001000000FFFFFFFFFFFFFFFFFFFEFF0D460069006E006400200069006E002000460069006C0065007300000000000A85000001000000FFFFFFFFFFFFFFFFFFFEFF1541006D0062006900670075006F0075007300200044006500660069006E006900740069006F006E007300000000000B85000001000000FFFFFFFFFFFFFFFFFFFEFF1153006F0075007200630065002000420072006F0077007300650020004C006F006700000000000C85000001000000FFFFFFFFFFFFFFFFFFFEFF0B54006F006F006C0020004F0075007400700075007400000000000E85000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFF0385000001000000FFFFFFFF03850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000028500000000000000000000000000000000000001000000028500000100000002850000000000000000000000000000 + + + CMSIS-Pack + 00200000010000000100FFFF01001100434D4643546F6F6C426172427574746F6ED18400000200000008000000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF0A43004D005300490053002D005000610063006B0018000000 + + + 34048 + 0A0000000A0000006E0000006E000000 + CB03000000000000F90300001A000000 + 8192 + 0 + 0 + 24 + 0 + + + 1 + + + Main + 00200000010000002100FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000039000000FFFEFF000000000000000000000000000100000001000000018001E10000000000003A000000FFFEFF000000000000000000000000000100000001000000018003E10000000000003C000000FFFEFF0000000000000000000000000001000000010000000180008100000000000019000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018007E10000000000003F000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018023E100000000040041000000FFFEFF000000000000000000000000000100000001000000018022E100000000040040000000FFFEFF000000000000000000000000000100000001000000018025E100000000000042000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001802BE100000000040043000000FFFEFF00000000000000000000000000010000000100000001802CE100000000040044000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000FFFF01000D005061737465436F6D626F426F784281000000000000FFFFFFFFFFFEFF000100000000000000010000000000000001000000B400000002002050FFFFFFFFFFFEFF0096000000000000000000018021810000000004002B000000FFFEFF000000000000000000000000000100000001000000018024E100000000000034000000FFFEFF000000000000000000000000000100000001000000018028E100000000040033000000FFFEFF000000000000000000000000000100000001000000018029E100000000000035000000FFFEFF000000000000000000000000000100000001000000018002810000000000001A000000FFFEFF000000000000000000000000000100000001000000018029810000000000002F000000FFFEFF000000000000000000000000000100000001000000018027810000000000002D000000FFFEFF000000000000000000000000000100000001000000018028810000000000002E000000FFFEFF00000000000000000000000000010000000100000001801D8100000000040027000000FFFEFF00000000000000000000000000010000000100000001801E8100000000040028000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800B810000020000001E000000FFFEFF00000000000000000000000000010000000100000001800C810000020000001F000000FFFEFF00000000000000000000000000010000000100000001805F8600000200000032000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800E8100000200000021000000FFFEFF00000000000000000000000000010000000100000001800F8100000200000022000000FFFEFF00000000000000000000000000010000000100000001805584000002000000FFFFFFFFFFFEFF1B44006F0077006E006C006F0061006400200061006300740069007600650020006100700070006C00690063006100740069006F006E00010000000000000001000000000000000100000000000000FFFEFF044D00610069006E00E4010000 + + + 34049 + 0A0000000A0000006E0000006E000000 + 0000000000000000CB0300001A000000 + 8192 + 0 + 0 + 484 + 0 + + + 1 + + + + + 010000000300000001000000000000000000000001000000010000000200000000000000010000000100000000000000280000002800000001000000090000000000000001000000FFFEFF132400570053005F0044004900520024005C007300720063005C006D00610069006E002E00630001000000FFFF010017004966436F6E74656E7453746F726167654D6663496D706CFFFEFF00FFFEFFFF28013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E003100310037003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0035003800380037003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0035003800380037003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF066D00610069006E002E00630000000000FFFFFFFFFFFFFFFFFFFEFF162400570053005F0044004900520024005C007300720063005C0066006C0073005C0066006C0073002E006800010000000180FFFEFF00FFFEFFFF24013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E0030003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E003800330031003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E003800330031003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF0566006C0073002E00680000000000FFFFFFFFFFFFFFFFFFFEFF2B2400570053005F0044004900520024005C007300720063005C0070007200690076006100740065005F006400720069007600650072005C007500640073005C0073007400610063006B005C007500640073002E006800010000000180FFFEFF00FFFEFFFF28013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E003100380039003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0037003400370032003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0037003400370032003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF057500640073002E00680000000000FFFFFFFFFFFFFFFFFFFEFF242400570053005F0044004900520024005C007300720063005C0062006F006F0074006C006F0061006400650072005C0062006F006F0074006C006F0061006400650072002E006300010000000180FFFEFF00FFFEFFFF22013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E003900350037003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0030003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0030003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF0C62006F006F0074006C006F0061006400650072002E00630000000000FFFFFFFFFFFFFFFFFFFEFF1D2400570053005F0044004900520024005C007300720063005C005200540054005C005300450047004700450052005F005200540054002E006300010000000180FFFEFF00FFFEFFFF22013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E003100380036003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0030003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0030003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF0C5300450047004700450052005F005200540054002E00630000000000FFFFFFFFFFFFFFFFFFFEFF342400570053005F0044004900520024005C007300720063005C0070007200690076006100740065005F006400720069007600650072005C007500640073005C0075007300650072005C007500640073005F007300650072007600690063006500330036002E006300010000000180FFFEFF00FFFEFFFF22013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E003100300037003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0030003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0030003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF0F7500640073005F007300650072007600690063006500330036002E00630000000000FFFFFFFFFFFFFFFFFFFEFF492400570053005F0044004900520024005C00530044004B005C0070006C006100740066006F0072006D005C0064006500760069006300650073005C00430056004D0030003100310078005C0064007200690076006500720073005C006300700075005C0073007400610072007400750070005C0073007400610072007400750070005F004D0030003100310078002E005300010000000180FFFEFF00FFFEFFFF28013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E003100300032003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0035003600330037003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0035003600330037003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF0F73007400610072007400750070005F004D0030003100310078002E00530000000000FFFFFFFFFFFFFFFFFFFEFF2E2400570053005F0044004900520024005C007300720063005C0070007200690076006100740065005F006400720069007600650072005C007500640073005C0073007400610063006B005C007300740069006D00650072002E006800010000000180FFFEFF00FFFEFFFF27013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E00370031003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0033003000320032003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0033003000320032003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF087300740069006D00650072002E00680000000000FFFFFFFFFFFFFFFFFFFEFF242400570053005F0044004900520024005C007300720063005C0062006F006F0074006C006F0061006400650072005C0062006F006F0074006C006F0061006400650072002E006800010000000180FFFEFF00FFFEFFFF27013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E00330033003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0031003900370033003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0031003900370033003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF0C62006F006F0074006C006F0061006400650072002E00680000000000FFFFFFFFFFFFFFFF0000000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD5000100000001000000020000008C02000021010000C805000029020000 + + + + diff --git a/cva_bootloader_m0118/settings/cva_bootloader_m0118_Debug.jlink b/cva_bootloader_m0118/settings/cva_bootloader_m0118_Debug.jlink new file mode 100644 index 0000000..e830972 --- /dev/null +++ b/cva_bootloader_m0118/settings/cva_bootloader_m0118_Debug.jlink @@ -0,0 +1,47 @@ +[BREAKPOINTS] +ForceImpTypeAny = 0 +ShowInfoWin = 1 +EnableFlashBP = 2 +BPDuringExecution = 0 +[CFI] +CFISize = 0x00 +CFIAddr = 0x00 +[CPU] +MonModeVTableAddr = 0xFFFFFFFF +MonModeDebug = 0 +MaxNumAPs = 0 +LowPowerHandlingMode = 0 +OverrideMemMap = 0 +AllowSimulation = 1 +ScriptFile="" +[FLASH] +RMWThreshold = 0x00 +Loaders="" +EraseType = 0x00 +CacheExcludeSize = 0x00 +CacheExcludeAddr = 0x00 +MinNumBytesFlashDL = 0 +SkipProgOnCRCMatch = 1 +VerifyDownload = 1 +AllowCaching = 1 +EnableFlashDL = 2 +Override = 0 +Device="ARM7" +[GENERAL] +WorkRAMSize = 0x6400 +WorkRAMAddr = 0x20000000 +RAMUsageLimit = 0x00 +[SWO] +SWOLogFile="" +[MEM] +RdOverrideOrMask = 0x00 +RdOverrideAndMask = 0xFFFFFFFF +RdOverrideAddr = 0xFFFFFFFF +WrOverrideOrMask = 0x00 +WrOverrideAndMask = 0xFFFFFFFF +WrOverrideAddr = 0xFFFFFFFF +[RAM] +VerifyDownload = 0x00 +[MEM_MAP] +[DYN_MEM_MAP] +NumUserRegion = 0x00 diff --git a/cva_bootloader_m0118/settings/cva_bootloader_m0118_EditorBookmarks.xml b/cva_bootloader_m0118/settings/cva_bootloader_m0118_EditorBookmarks.xml new file mode 100644 index 0000000..38c3485 --- /dev/null +++ b/cva_bootloader_m0118/settings/cva_bootloader_m0118_EditorBookmarks.xml @@ -0,0 +1,2 @@ + + diff --git a/cva_bootloader_m0118/src/RTT/README.txt b/cva_bootloader_m0118/src/RTT/README.txt new file mode 100644 index 0000000..6ca82ce --- /dev/null +++ b/cva_bootloader_m0118/src/RTT/README.txt @@ -0,0 +1,23 @@ +README.txt for the SEGGER RTT Implementation Pack. + +MDK-ARM specifics: +https://wiki.segger.com/Keil_MDK-ARM#RTT_in_uVision + +Included files: +=============== +Root Directory + - Examples + - Main_RTT_InputEchoApp.c - Sample application which echoes input on Channel 0. + - Main_RTT_MenuApp.c - Sample application to demonstrate RTT bi-directional functionality. + - Main_RTT_PrintfTest.c - Sample application to test RTT small printf implementation. + - Main_RTT_SpeedTestApp.c - Sample application for measuring RTT performance. embOS needed. + - RTT + - SEGGER_RTT.c - The RTT implementation. + - SEGGER_RTT.h - Header for RTT implementation. + - SEGGER_RTT_Conf.h - Pre-processor configuration for the RTT implementation. + - SEGGER_RTT_Printf.c - Simple implementation of printf to write formatted strings via RTT. + - Syscalls + - RTT_Syscalls_GCC.c - Low-level syscalls to retarget printf() to RTT with GCC / Newlib. + - RTT_Syscalls_IAR.c - Low-level syscalls to retarget printf() to RTT with IAR compiler. + - RTT_Syscalls_KEIL.c - Low-level syscalls to retarget printf() to RTT with KEIL/uVision compiler. + - RTT_Syscalls_SES.c - Low-level syscalls to retarget printf() to RTT with SEGGER Embedded Studio. diff --git a/cva_bootloader_m0118/src/RTT/SEGGER_RTT.c b/cva_bootloader_m0118/src/RTT/SEGGER_RTT.c new file mode 100644 index 0000000..baa496f --- /dev/null +++ b/cva_bootloader_m0118/src/RTT/SEGGER_RTT.c @@ -0,0 +1,2078 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2021 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* condition is met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this condition and the following disclaimer. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 7.22b * +* * +********************************************************************** + +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT.c +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support + debugger memory accesses while the CPU is running. +Revision: $Rev: 22333 $ + +Additional information: + Type "int" is assumed to be 32-bits in size + H->T Host to target communication + T->H Target to host communication + + RTT channel 0 is always present and reserved for Terminal usage. + Name is fixed to "Terminal" + + Effective buffer size: SizeOfBuffer - 1 + + WrOff == RdOff: Buffer is empty + WrOff == (RdOff - 1): Buffer is full + WrOff > RdOff: Free space includes wrap-around + WrOff < RdOff: Used space includes wrap-around + (WrOff == (SizeOfBuffer - 1)) && (RdOff == 0): + Buffer full and wrap-around after next byte + + +---------------------------------------------------------------------- +*/ + +#include "SEGGER_RTT.h" + +#include // for memcpy + +/********************************************************************* +* +* Configuration, default values +* +********************************************************************** +*/ + +#if SEGGER_RTT_CPU_CACHE_LINE_SIZE + #ifdef SEGGER_RTT_CB_ALIGN + #error "Custom SEGGER_RTT_CB_ALIGN() is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" + #endif + #ifdef SEGGER_RTT_BUFFER_ALIGN + #error "Custom SEGGER_RTT_BUFFER_ALIGN() is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" + #endif + #ifdef SEGGER_RTT_PUT_CB_SECTION + #error "Custom SEGGER_RTT_PUT_CB_SECTION() is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" + #endif + #ifdef SEGGER_RTT_PUT_BUFFER_SECTION + #error "Custom SEGGER_RTT_PUT_BUFFER_SECTION() is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" + #endif + #ifdef SEGGER_RTT_BUFFER_ALIGNMENT + #error "Custom SEGGER_RTT_BUFFER_ALIGNMENT is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" + #endif + #ifdef SEGGER_RTT_ALIGNMENT + #error "Custom SEGGER_RTT_ALIGNMENT is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" + #endif +#endif + +#ifndef BUFFER_SIZE_UP + #define BUFFER_SIZE_UP 1024 // Size of the buffer for terminal output of target, up to host +#endif + +#ifndef BUFFER_SIZE_DOWN + #define BUFFER_SIZE_DOWN 16 // Size of the buffer for terminal input to target from host (Usually keyboard input) +#endif + +#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS + #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 // Number of up-buffers (T->H) available on this target +#endif + +#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS + #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 // Number of down-buffers (H->T) available on this target +#endif + +#ifndef SEGGER_RTT_BUFFER_SECTION + #if defined(SEGGER_RTT_SECTION) + #define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION + #endif +#endif + +#ifndef SEGGER_RTT_ALIGNMENT + #define SEGGER_RTT_ALIGNMENT SEGGER_RTT_CPU_CACHE_LINE_SIZE +#endif + +#ifndef SEGGER_RTT_BUFFER_ALIGNMENT + #define SEGGER_RTT_BUFFER_ALIGNMENT SEGGER_RTT_CPU_CACHE_LINE_SIZE +#endif + +#ifndef SEGGER_RTT_MODE_DEFAULT + #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP +#endif + +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK() +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK() +#endif + +#ifndef STRLEN + #define STRLEN(a) strlen((a)) +#endif + +#ifndef STRCPY + #define STRCPY(pDest, pSrc) strcpy((pDest), (pSrc)) +#endif + +#ifndef SEGGER_RTT_MEMCPY_USE_BYTELOOP + #define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 +#endif + +#ifndef SEGGER_RTT_MEMCPY + #ifdef MEMCPY + #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) MEMCPY((pDest), (pSrc), (NumBytes)) + #else + #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes)) + #endif +#endif + +#ifndef MIN + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX + #define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif +// +// For some environments, NULL may not be defined until certain headers are included +// +#ifndef NULL + #define NULL 0 +#endif + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ +#if (defined __ICCARM__) || (defined __ICCRX__) + #define RTT_PRAGMA(P) _Pragma(#P) +#endif + +#if SEGGER_RTT_ALIGNMENT || SEGGER_RTT_BUFFER_ALIGNMENT + #if (defined __GNUC__) + #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) + #elif (defined __ICCARM__) || (defined __ICCRX__) + #define PRAGMA(A) _Pragma(#A) +#define SEGGER_RTT_ALIGN(Var, Alignment) RTT_PRAGMA(data_alignment=Alignment) \ + Var + #elif (defined __CC_ARM) + #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) + #else + #error "Alignment not supported for this compiler." + #endif +#else + #define SEGGER_RTT_ALIGN(Var, Alignment) Var +#endif + +#if defined(SEGGER_RTT_SECTION) || defined (SEGGER_RTT_BUFFER_SECTION) + #if (defined __GNUC__) + #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section))) Var + #elif (defined __ICCARM__) || (defined __ICCRX__) +#define SEGGER_RTT_PUT_SECTION(Var, Section) RTT_PRAGMA(location=Section) \ + Var + #elif (defined __CC_ARM) + #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section), zero_init)) Var + #else + #error "Section placement not supported for this compiler." + #endif +#else + #define SEGGER_RTT_PUT_SECTION(Var, Section) Var +#endif + +#if SEGGER_RTT_ALIGNMENT + #define SEGGER_RTT_CB_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_ALIGNMENT) +#else + #define SEGGER_RTT_CB_ALIGN(Var) Var +#endif + +#if SEGGER_RTT_BUFFER_ALIGNMENT + #define SEGGER_RTT_BUFFER_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_BUFFER_ALIGNMENT) +#else + #define SEGGER_RTT_BUFFER_ALIGN(Var) Var +#endif + + +#if defined(SEGGER_RTT_SECTION) + #define SEGGER_RTT_PUT_CB_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_SECTION) +#else + #define SEGGER_RTT_PUT_CB_SECTION(Var) Var +#endif + +#if defined(SEGGER_RTT_BUFFER_SECTION) + #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_BUFFER_SECTION) +#else + #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) Var +#endif + +/********************************************************************* +* +* Static const data +* +********************************************************************** +*/ + +static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + +/********************************************************************* +* +* Static data +* +********************************************************************** +*/ + +// +// RTT Control Block and allocate buffers for channel 0 +// +SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT)); +SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acUpBuffer [SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_UP)])); +SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acDownBuffer[SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_DOWN)])); + +static unsigned char _ActiveTerminal; + +/********************************************************************* +* +* Static functions +* +********************************************************************** +*/ + +/********************************************************************* +* +* _DoInit() +* +* Function description +* Initializes the control block an buffers. +* May only be called via INIT() to avoid overriding settings. +* +*/ +#define INIT() { \ + volatile SEGGER_RTT_CB* pRTTCBInit; \ + pRTTCBInit = (volatile SEGGER_RTT_CB*)((char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); \ + do { \ + if (pRTTCBInit->acID[0] == '\0') { \ + _DoInit(); \ + } \ + } while (0); \ + } + +static void _DoInit(void) { + volatile SEGGER_RTT_CB* p; // Volatile to make sure that compiler cannot change the order of accesses to the control block + // + // Initialize control block + // + p = (volatile SEGGER_RTT_CB*)((char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access control block uncached so that nothing in the cache ever becomes dirty and all changes are visible in HW directly + p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS; + p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS; + // + // Initialize up buffer 0 + // + p->aUp[0].sName = "Terminal"; + p->aUp[0].pBuffer = _acUpBuffer; + p->aUp[0].SizeOfBuffer = BUFFER_SIZE_UP; + p->aUp[0].RdOff = 0u; + p->aUp[0].WrOff = 0u; + p->aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT; + // + // Initialize down buffer 0 + // + p->aDown[0].sName = "Terminal"; + p->aDown[0].pBuffer = _acDownBuffer; + p->aDown[0].SizeOfBuffer = BUFFER_SIZE_DOWN; + p->aDown[0].RdOff = 0u; + p->aDown[0].WrOff = 0u; + p->aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT; + // + // Finish initialization of the control block. + // Copy Id string in three steps to make sure "SEGGER RTT" is not found + // in initializer memory (usually flash) by J-Link + // + STRCPY((char*)&p->acID[7], "RTT"); + RTT__DMB(); // Force order of memory accessed inside core for cores that allow to change the order + STRCPY((char*)&p->acID[0], "SEGGER"); + RTT__DMB(); // Force order of memory accessed inside core for cores that allow to change the order + p->acID[6] = ' '; + RTT__DMB(); // Force order of memory accessed inside core for cores that allow to change the order +} + +/********************************************************************* +* +* _WriteBlocking() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* The caller is responsible for managing the write chunk sizes as +* _WriteBlocking() will block until all data has been posted successfully. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* >= 0 - Number of bytes written into buffer. +*/ +static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer, unsigned NumBytes) { + unsigned NumBytesToWrite; + unsigned NumBytesWritten; + unsigned RdOff; + unsigned WrOff; + volatile char* pDst; + // + // Write data to buffer and handle wrap-around if necessary + // + NumBytesWritten = 0u; + WrOff = pRing->WrOff; + do { + RdOff = pRing->RdOff; // May be changed by host (debug probe) in the meantime + if (RdOff > WrOff) { + NumBytesToWrite = RdOff - WrOff - 1u; + } else { + NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u); + } + NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around + NumBytesToWrite = MIN(NumBytesToWrite, NumBytes); + pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + NumBytesWritten += NumBytesToWrite; + NumBytes -= NumBytesToWrite; + WrOff += NumBytesToWrite; + while (NumBytesToWrite--) { + *pDst++ = *pBuffer++; + }; +#else + SEGGER_RTT_MEMCPY((void*)pDst, pBuffer, NumBytesToWrite); + NumBytesWritten += NumBytesToWrite; + pBuffer += NumBytesToWrite; + NumBytes -= NumBytesToWrite; + WrOff += NumBytesToWrite; +#endif + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0u; + } + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = WrOff; + } while (NumBytes); + return NumBytesWritten; +} + +/********************************************************************* +* +* _WriteNoCheck() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* It is callers responsibility to make sure data actually fits in buffer. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Notes +* (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking +*/ +static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsigned NumBytes) { + unsigned NumBytesAtOnce; + unsigned WrOff; + unsigned Rem; + volatile char* pDst; + + WrOff = pRing->WrOff; + Rem = pRing->SizeOfBuffer - WrOff; + if (Rem > NumBytes) { + // + // All data fits before wrap around + // + pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + WrOff += NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = WrOff; +#else + SEGGER_RTT_MEMCPY((void*)pDst, pData, NumBytes); + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = WrOff + NumBytes; +#endif + } else { + // + // We reach the end of the buffer, so need to wrap around + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF; + NumBytesAtOnce = Rem; + while (NumBytesAtOnce--) { + *pDst++ = *pData++; + }; + pDst = pRing->pBuffer + SEGGER_RTT_UNCACHED_OFF; + NumBytesAtOnce = NumBytes - Rem; + while (NumBytesAtOnce--) { + *pDst++ = *pData++; + }; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = NumBytes - Rem; +#else + NumBytesAtOnce = Rem; + pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF; + SEGGER_RTT_MEMCPY((void*)pDst, pData, NumBytesAtOnce); + NumBytesAtOnce = NumBytes - Rem; + pDst = pRing->pBuffer + SEGGER_RTT_UNCACHED_OFF; + SEGGER_RTT_MEMCPY((void*)pDst, pData + Rem, NumBytesAtOnce); + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = NumBytesAtOnce; +#endif + } +} + +/********************************************************************* +* +* _PostTerminalSwitch() +* +* Function description +* Switch terminal to the given terminal ID. It is the caller's +* responsibility to ensure the terminal ID is correct and there is +* enough space in the buffer for this to complete successfully. +* +* Parameters +* pRing Ring buffer to post to. +* TerminalId Terminal ID to switch to. +*/ +static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) { + unsigned char ac[2]; + + ac[0] = 0xFFu; + ac[1] = _aTerminalId[TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit + _WriteBlocking(pRing, (const char*)ac, 2u); +} + +/********************************************************************* +* +* _GetAvailWriteSpace() +* +* Function description +* Returns the number of bytes that can be written to the ring +* buffer without blocking. +* +* Parameters +* pRing Ring buffer to check. +* +* Return value +* Number of bytes that are free in the buffer. +*/ +static unsigned _GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP* pRing) { + unsigned RdOff; + unsigned WrOff; + unsigned r; + // + // Avoid warnings regarding volatile access order. It's not a problem + // in this case, but dampen compiler enthusiasm. + // + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + if (RdOff <= WrOff) { + r = pRing->SizeOfBuffer - 1u - WrOff + RdOff; + } else { + r = RdOff - WrOff - 1u; + } + return r; +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ + +/********************************************************************* +* +* SEGGER_RTT_ReadUpBufferNoLock() +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the application. +* Do not lock against interrupts and multiple access. +* Used to do the same operation that J-Link does, to transfer +* RTT data via other channels, such as TCP/IP or UART. +* +* Parameters +* BufferIndex Index of Up-buffer to be used. +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-up-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +* +* Additional information +* This function must not be called when J-Link might also do RTT. +*/ +unsigned SEGGER_RTT_ReadUpBufferNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) { + unsigned NumBytesRem; + unsigned NumBytesRead; + unsigned RdOff; + unsigned WrOff; + unsigned char* pBuffer; + SEGGER_RTT_BUFFER_UP* pRing; + volatile char* pSrc; + + INIT(); + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + pBuffer = (unsigned char*)pData; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + NumBytesRead = 0u; + // + // Read from current read position to wrap-around of buffer, first + // + if (RdOff > WrOff) { + NumBytesRem = pRing->SizeOfBuffer - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + pSrc = (pRing->pBuffer + RdOff) + SEGGER_RTT_UNCACHED_OFF; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + NumBytesRead += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + while (NumBytesRem--) { + *pBuffer++ = *pSrc++; + }; +#else + SEGGER_RTT_MEMCPY(pBuffer, (void*)pSrc, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; +#endif + // + // Handle wrap-around of buffer + // + if (RdOff == pRing->SizeOfBuffer) { + RdOff = 0u; + } + } + // + // Read remaining items of buffer + // + NumBytesRem = WrOff - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + if (NumBytesRem > 0u) { + pSrc = (pRing->pBuffer + RdOff) + SEGGER_RTT_UNCACHED_OFF; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + NumBytesRead += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + while (NumBytesRem--) { + *pBuffer++ = *pSrc++; + }; +#else + SEGGER_RTT_MEMCPY(pBuffer, (void*)pSrc, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; +#endif + } + // + // Update read offset of buffer + // + if (NumBytesRead) { + pRing->RdOff = RdOff; + } + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_ReadNoLock() +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* Do not lock against interrupts and multiple access. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) { + unsigned NumBytesRem; + unsigned NumBytesRead; + unsigned RdOff; + unsigned WrOff; + unsigned char* pBuffer; + SEGGER_RTT_BUFFER_DOWN* pRing; + volatile char* pSrc; + // + INIT(); + pRing = (SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + pBuffer = (unsigned char*)pData; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + NumBytesRead = 0u; + // + // Read from current read position to wrap-around of buffer, first + // + if (RdOff > WrOff) { + NumBytesRem = pRing->SizeOfBuffer - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + pSrc = (pRing->pBuffer + RdOff) + SEGGER_RTT_UNCACHED_OFF; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + NumBytesRead += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + while (NumBytesRem--) { + *pBuffer++ = *pSrc++; + }; +#else + SEGGER_RTT_MEMCPY(pBuffer, (void*)pSrc, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; +#endif + // + // Handle wrap-around of buffer + // + if (RdOff == pRing->SizeOfBuffer) { + RdOff = 0u; + } + } + // + // Read remaining items of buffer + // + NumBytesRem = WrOff - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + if (NumBytesRem > 0u) { + pSrc = (pRing->pBuffer + RdOff) + SEGGER_RTT_UNCACHED_OFF; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + NumBytesRead += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + while (NumBytesRem--) { + *pBuffer++ = *pSrc++; + }; +#else + SEGGER_RTT_MEMCPY(pBuffer, (void*)pSrc, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; +#endif + } + if (NumBytesRead) { + pRing->RdOff = RdOff; + } + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_ReadUpBuffer +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the application. +* Used to do the same operation that J-Link does, to transfer +* RTT data via other channels, such as TCP/IP or UART. +* +* Parameters +* BufferIndex Index of Up-buffer to be used. +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-up-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +* +* Additional information +* This function must not be called when J-Link might also do RTT. +* This function locks against all other RTT operations. I.e. during +* the read operation, writing is also locked. +* If only one consumer reads from the up buffer, +* call sEGGER_RTT_ReadUpBufferNoLock() instead. +*/ +unsigned SEGGER_RTT_ReadUpBuffer(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) { + unsigned NumBytesRead; + + SEGGER_RTT_LOCK(); + // + // Call the non-locking read function + // + NumBytesRead = SEGGER_RTT_ReadUpBufferNoLock(BufferIndex, pBuffer, BufferSize); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_Read +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) { + unsigned NumBytesRead; + + SEGGER_RTT_LOCK(); + // + // Call the non-locking read function + // + NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteWithOverwriteNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block. +* SEGGER_RTT_WriteWithOverwriteNoLock does not lock the application +* and overwrites data if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, data is overwritten. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +* (3) Do not use SEGGER_RTT_WriteWithOverwriteNoLock if a J-Link +* connection reads RTT data. +*/ +void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + volatile char* pDst; + // + // Get "to-host" ring buffer and copy some elements into local variables. + // + pData = (const char *)pBuffer; + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + // + // Check if we will overwrite data and need to adjust the RdOff. + // + if (pRing->WrOff == pRing->RdOff) { + Avail = pRing->SizeOfBuffer - 1u; + } else if ( pRing->WrOff < pRing->RdOff) { + Avail = pRing->RdOff - pRing->WrOff - 1u; + } else { + Avail = pRing->RdOff - pRing->WrOff - 1u + pRing->SizeOfBuffer; + } + if (NumBytes > Avail) { + pRing->RdOff += (NumBytes - Avail); + while (pRing->RdOff >= pRing->SizeOfBuffer) { + pRing->RdOff -= pRing->SizeOfBuffer; + } + } + // + // Write all data, no need to check the RdOff, but possibly handle multiple wrap-arounds + // + Avail = pRing->SizeOfBuffer - pRing->WrOff; + do { + if (Avail > NumBytes) { + // + // Last round + // + pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + Avail = NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff += Avail; +#else + SEGGER_RTT_MEMCPY((void*)pDst, pData, NumBytes); + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff += NumBytes; +#endif + break; + } else { + // + // Wrap-around necessary, write until wrap-around and reset WrOff + // + pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + NumBytes -= Avail; + while (Avail--) { + *pDst++ = *pData++; + }; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = 0; +#else + SEGGER_RTT_MEMCPY((void*)pDst, pData, Avail); + pData += Avail; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = 0; + NumBytes -= Avail; +#endif + Avail = (pRing->SizeOfBuffer - 1); + } + } while (NumBytes); +} + +/********************************************************************* +* +* SEGGER_RTT_WriteSkipNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteSkipNoLock does not lock the application and +* skips all data, if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* MUST be > 0!!! +* This is done for performance reasons, so no initial check has do be done. +* +* Return value +* 1: Data has been copied +* 0: No space, data has not been copied +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, all data is dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +#if (RTT_USE_ASM == 0) +unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + unsigned RdOff; + unsigned WrOff; + unsigned Rem; + volatile char* pDst; + // + // Cases: + // 1) RdOff <= WrOff => Space until wrap-around is sufficient + // 2) RdOff <= WrOff => Space after wrap-around needed (copy in 2 chunks) + // 3) RdOff < WrOff => No space in buf + // 4) RdOff > WrOff => Space is sufficient + // 5) RdOff > WrOff => No space in buf + // + // 1) is the most common case for large buffers and assuming that J-Link reads the data fast enough + // + pData = (const char *)pBuffer; + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + if (RdOff <= WrOff) { // Case 1), 2) or 3) + Avail = pRing->SizeOfBuffer - WrOff - 1u; // Space until wrap-around (assume 1 byte not usable for case that RdOff == 0) + if (Avail >= NumBytes) { // Case 1)? +CopyStraight: + pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF; + memcpy((void*)pDst, pData, NumBytes); + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = WrOff + NumBytes; + return 1; + } + Avail += RdOff; // Space incl. wrap-around + if (Avail >= NumBytes) { // Case 2? => If not, we have case 3) (does not fit) + Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer + pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF; + memcpy((void*)pDst, pData, Rem); // Copy 1st chunk + NumBytes -= Rem; + // + // Special case: First check that assumed RdOff == 0 calculated that last element before wrap-around could not be used + // But 2nd check (considering space until wrap-around and until RdOff) revealed that RdOff is not 0, so we can use the last element + // In this case, we may use a copy straight until buffer end anyway without needing to copy 2 chunks + // Therefore, check if 2nd memcpy is necessary at all + // + if (NumBytes) { + pDst = pRing->pBuffer + SEGGER_RTT_UNCACHED_OFF; + memcpy((void*)pDst, pData + Rem, NumBytes); + } + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = NumBytes; + return 1; + } + } else { // Potential case 4) + Avail = RdOff - WrOff - 1u; + if (Avail >= NumBytes) { // Case 4)? => If not, we have case 5) (does not fit) + goto CopyStraight; + } + } + return 0; // No space in buffer +} +#endif + +/********************************************************************* +* +* SEGGER_RTT_WriteDownBufferNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block inside a buffer. +* SEGGER_RTT_WriteDownBufferNoLock does not lock the application. +* Used to do the same operation that J-Link does, to transfer +* RTT data from other channels, such as TCP/IP or UART. +* +* Parameters +* BufferIndex Index of "Down"-buffer to be used. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Down"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +* +* Additional information +* This function must not be called when J-Link might also do RTT. +*/ +unsigned SEGGER_RTT_WriteDownBufferNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + unsigned Avail; + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + // + // Get "to-target" ring buffer. + // It is save to cast that to a "to-host" buffer. Up and Down buffer differ in volatility of offsets that might be modified by J-Link. + // + pData = (const char *)pBuffer; + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aDown[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + // + // How we output depends upon the mode... + // + switch (pRing->Flags) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother. + // + Avail = _GetAvailWriteSpace(pRing); + if (Avail < NumBytes) { + Status = 0u; + } else { + Status = NumBytes; + _WriteNoCheck(pRing, pData, NumBytes); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode, trim to what we can output without blocking. + // + Avail = _GetAvailWriteSpace(pRing); + Status = Avail < NumBytes ? Avail : NumBytes; + _WriteNoCheck(pRing, pData, Status); + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + Status = _WriteBlocking(pRing, pData, NumBytes); + break; + default: + Status = 0u; + break; + } + // + // Finish up. + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteNoLock does not lock the application. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + unsigned Avail; + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + // + // Get "to-host" ring buffer. + // + pData = (const char *)pBuffer; + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + // + // How we output depends upon the mode... + // + switch (pRing->Flags) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother. + // + Avail = _GetAvailWriteSpace(pRing); + if (Avail < NumBytes) { + Status = 0u; + } else { + Status = NumBytes; + _WriteNoCheck(pRing, pData, NumBytes); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode, trim to what we can output without blocking. + // + Avail = _GetAvailWriteSpace(pRing); + Status = Avail < NumBytes ? Avail : NumBytes; + _WriteNoCheck(pRing, pData, Status); + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + Status = _WriteBlocking(pRing, pData, NumBytes); + break; + default: + Status = 0u; + break; + } + // + // Finish up. + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteDownBuffer +* +* Function description +* Stores a specified number of characters in SEGGER RTT control block in a buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Down"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +* +* Additional information +* This function must not be called when J-Link might also do RTT. +* This function locks against all other RTT operations. I.e. during +* the write operation, writing from the application is also locked. +* If only one consumer writes to the down buffer, +* call SEGGER_RTT_WriteDownBufferNoLock() instead. +*/ +unsigned SEGGER_RTT_WriteDownBuffer(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + + INIT(); + SEGGER_RTT_LOCK(); + Status = SEGGER_RTT_WriteDownBufferNoLock(BufferIndex, pBuffer, NumBytes); // Call the non-locking write function + SEGGER_RTT_UNLOCK(); + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_Write +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +*/ +unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + + INIT(); + SEGGER_RTT_LOCK(); + Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes); // Call the non-locking write function + SEGGER_RTT_UNLOCK(); + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteString +* +* Function description +* Stores string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* s Pointer to string. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +* (2) String passed to this function has to be \0 terminated +* (3) \0 termination character is *not* stored in RTT buffer +*/ +unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) { + unsigned Len; + + Len = STRLEN(s); + return SEGGER_RTT_Write(BufferIndex, s, Len); +} + +/********************************************************************* +* +* SEGGER_RTT_PutCharSkipNoLock +* +* Function description +* Stores a single character/byte in SEGGER RTT buffer. +* SEGGER_RTT_PutCharSkipNoLock does not lock the application and +* skips the byte, if it does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* c Byte to be stored. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, the character is dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ + +unsigned SEGGER_RTT_PutCharSkipNoLock(unsigned BufferIndex, char c) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned WrOff; + unsigned Status; + volatile char* pDst; + // + // Get "to-host" ring buffer. + // + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + // + // Get write position and handle wrap-around if necessary + // + WrOff = pRing->WrOff + 1; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0; + } + // + // Output byte if free space is available + // + if (WrOff != pRing->RdOff) { + pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF; + *pDst = c; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = WrOff; + Status = 1; + } else { + Status = 0; + } + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_PutCharSkip +* +* Function description +* Stores a single character/byte in SEGGER RTT buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* c Byte to be stored. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, the character is dropped. +*/ + +unsigned SEGGER_RTT_PutCharSkip(unsigned BufferIndex, char c) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned WrOff; + unsigned Status; + volatile char* pDst; + // + // Prepare + // + INIT(); + SEGGER_RTT_LOCK(); + // + // Get "to-host" ring buffer. + // + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + // + // Get write position and handle wrap-around if necessary + // + WrOff = pRing->WrOff + 1; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0; + } + // + // Output byte if free space is available + // + if (WrOff != pRing->RdOff) { + pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF; + *pDst = c; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = WrOff; + Status = 1; + } else { + Status = 0; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return Status; +} + + /********************************************************************* +* +* SEGGER_RTT_PutChar +* +* Function description +* Stores a single character/byte in SEGGER RTT buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* c Byte to be stored. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +*/ + +unsigned SEGGER_RTT_PutChar(unsigned BufferIndex, char c) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned WrOff; + unsigned Status; + volatile char* pDst; + // + // Prepare + // + INIT(); + SEGGER_RTT_LOCK(); + // + // Get "to-host" ring buffer. + // + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + // + // Get write position and handle wrap-around if necessary + // + WrOff = pRing->WrOff + 1; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0; + } + // + // Wait for free space if mode is set to blocking + // + if (pRing->Flags == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { + while (WrOff == pRing->RdOff) { + ; + } + } + // + // Output byte if free space is available + // + if (WrOff != pRing->RdOff) { + pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF; + *pDst = c; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = WrOff; + Status = 1; + } else { + Status = 0; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_GetKey +* +* Function description +* Reads one character from the SEGGER RTT buffer. +* Host has previously stored data there. +* +* Return value +* < 0 - No character available (buffer empty). +* >= 0 - Character which has been read. (Possible values: 0 - 255) +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0. +*/ +int SEGGER_RTT_GetKey(void) { + char c; + int r; + + r = (int)SEGGER_RTT_Read(0u, &c, 1u); + if (r == 1) { + r = (int)(unsigned char)c; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_WaitKey +* +* Function description +* Waits until at least one character is avaible in the SEGGER RTT buffer. +* Once a character is available, it is read and this function returns. +* +* Return value +* >=0 - Character which has been read. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +* (2) This function is blocking if no character is present in RTT buffer +*/ +int SEGGER_RTT_WaitKey(void) { + int r; + + do { + r = SEGGER_RTT_GetKey(); + } while (r < 0); + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasKey +* +* Function description +* Checks if at least one character for reading is available in the SEGGER RTT buffer. +* +* Return value +* == 0 - No characters are available to read. +* == 1 - At least one character is available. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +*/ +int SEGGER_RTT_HasKey(void) { + SEGGER_RTT_BUFFER_DOWN* pRing; + unsigned RdOff; + int r; + + INIT(); + pRing = (SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[0] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + RdOff = pRing->RdOff; + if (RdOff != pRing->WrOff) { + r = 1; + } else { + r = 0; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasData +* +* Function description +* Check if there is data from the host in the given buffer. +* +* Return value: +* ==0: No data +* !=0: Data in buffer +* +*/ +unsigned SEGGER_RTT_HasData(unsigned BufferIndex) { + SEGGER_RTT_BUFFER_DOWN* pRing; + unsigned v; + + pRing = (SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + v = pRing->WrOff; + return v - pRing->RdOff; +} + +/********************************************************************* +* +* SEGGER_RTT_HasDataUp +* +* Function description +* Check if there is data remaining to be sent in the given buffer. +* +* Return value: +* ==0: No data +* !=0: Data in buffer +* +*/ +unsigned SEGGER_RTT_HasDataUp(unsigned BufferIndex) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned v; + + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + v = pRing->RdOff; + return pRing->WrOff - v; +} + +/********************************************************************* +* +* SEGGER_RTT_AllocDownBuffer +* +* Function description +* Run-time configuration of the next down-buffer (H->T). +* The next buffer, which is not used yet is configured. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. Buffer Index +* < 0 - Error +*/ +int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int BufferIndex; + volatile SEGGER_RTT_CB* pRTTCB; + + INIT(); + SEGGER_RTT_LOCK(); + pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + BufferIndex = 0; + do { + if (pRTTCB->aDown[BufferIndex].pBuffer == NULL) { + break; + } + BufferIndex++; + } while (BufferIndex < pRTTCB->MaxNumDownBuffers); + if (BufferIndex < pRTTCB->MaxNumDownBuffers) { + pRTTCB->aDown[BufferIndex].sName = sName; + pRTTCB->aDown[BufferIndex].pBuffer = (char*)pBuffer; + pRTTCB->aDown[BufferIndex].SizeOfBuffer = BufferSize; + pRTTCB->aDown[BufferIndex].RdOff = 0u; + pRTTCB->aDown[BufferIndex].WrOff = 0u; + pRTTCB->aDown[BufferIndex].Flags = Flags; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + } else { + BufferIndex = -1; + } + SEGGER_RTT_UNLOCK(); + return BufferIndex; +} + +/********************************************************************* +* +* SEGGER_RTT_AllocUpBuffer +* +* Function description +* Run-time configuration of the next up-buffer (T->H). +* The next buffer, which is not used yet is configured. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. Buffer Index +* < 0 - Error +*/ +int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int BufferIndex; + volatile SEGGER_RTT_CB* pRTTCB; + + INIT(); + SEGGER_RTT_LOCK(); + pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + BufferIndex = 0; + do { + if (pRTTCB->aUp[BufferIndex].pBuffer == NULL) { + break; + } + BufferIndex++; + } while (BufferIndex < pRTTCB->MaxNumUpBuffers); + if (BufferIndex < pRTTCB->MaxNumUpBuffers) { + pRTTCB->aUp[BufferIndex].sName = sName; + pRTTCB->aUp[BufferIndex].pBuffer = (char*)pBuffer; + pRTTCB->aUp[BufferIndex].SizeOfBuffer = BufferSize; + pRTTCB->aUp[BufferIndex].RdOff = 0u; + pRTTCB->aUp[BufferIndex].WrOff = 0u; + pRTTCB->aUp[BufferIndex].Flags = Flags; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + } else { + BufferIndex = -1; + } + SEGGER_RTT_UNLOCK(); + return BufferIndex; +} + +/********************************************************************* +* +* SEGGER_RTT_ConfigUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer (T->H). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. +* < 0 - Error +* +* Additional information +* Buffer 0 is configured on compile-time. +* May only be called once per buffer. +* Buffer name and flags can be reconfigured using the appropriate functions. +*/ +int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + volatile SEGGER_RTT_CB* pRTTCB; + volatile SEGGER_RTT_BUFFER_UP* pUp; + + INIT(); + pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + if (BufferIndex < SEGGER_RTT_MAX_NUM_UP_BUFFERS) { + SEGGER_RTT_LOCK(); + pUp = &pRTTCB->aUp[BufferIndex]; + if (BufferIndex) { + pUp->sName = sName; + pUp->pBuffer = (char*)pBuffer; + pUp->SizeOfBuffer = BufferSize; + pUp->RdOff = 0u; + pUp->WrOff = 0u; + } + pUp->Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_ConfigDownBuffer +* +* Function description +* Run-time configuration of a specific down-buffer (H->T). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 O.K. +* < 0 Error +* +* Additional information +* Buffer 0 is configured on compile-time. +* May only be called once per buffer. +* Buffer name and flags can be reconfigured using the appropriate functions. +*/ +int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + volatile SEGGER_RTT_CB* pRTTCB; + volatile SEGGER_RTT_BUFFER_DOWN* pDown; + + INIT(); + pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + if (BufferIndex < SEGGER_RTT_MAX_NUM_DOWN_BUFFERS) { + SEGGER_RTT_LOCK(); + pDown = &pRTTCB->aDown[BufferIndex]; + if (BufferIndex) { + pDown->sName = sName; + pDown->pBuffer = (char*)pBuffer; + pDown->SizeOfBuffer = BufferSize; + pDown->RdOff = 0u; + pDown->WrOff = 0u; + } + pDown->Flags = Flags; + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) { + int r; + volatile SEGGER_RTT_CB* pRTTCB; + volatile SEGGER_RTT_BUFFER_UP* pUp; + + INIT(); + pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + if (BufferIndex < SEGGER_RTT_MAX_NUM_UP_BUFFERS) { + SEGGER_RTT_LOCK(); + pUp = &pRTTCB->aUp[BufferIndex]; + pUp->sName = sName; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameDownBuffer +* +* Function description +* Run-time configuration of a specific Down-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) { + int r; + volatile SEGGER_RTT_CB* pRTTCB; + volatile SEGGER_RTT_BUFFER_DOWN* pDown; + + INIT(); + pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + if (BufferIndex < SEGGER_RTT_MAX_NUM_DOWN_BUFFERS) { + SEGGER_RTT_LOCK(); + pDown = &pRTTCB->aDown[BufferIndex]; + pDown->sName = sName; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetFlagsUpBuffer +* +* Function description +* Run-time configuration of specific up-buffer flags (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer. +* Flags Flags to set for the buffer. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags) { + int r; + volatile SEGGER_RTT_CB* pRTTCB; + volatile SEGGER_RTT_BUFFER_UP* pUp; + + INIT(); + pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + if (BufferIndex < SEGGER_RTT_MAX_NUM_UP_BUFFERS) { + SEGGER_RTT_LOCK(); + pUp = &pRTTCB->aUp[BufferIndex]; + pUp->Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetFlagsDownBuffer +* +* Function description +* Run-time configuration of specific Down-buffer flags (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* Flags Flags to set for the buffer. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags) { + int r; + volatile SEGGER_RTT_CB* pRTTCB; + volatile SEGGER_RTT_BUFFER_DOWN* pDown; + + INIT(); + pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + if (BufferIndex < SEGGER_RTT_MAX_NUM_DOWN_BUFFERS) { + SEGGER_RTT_LOCK(); + pDown = &pRTTCB->aDown[BufferIndex]; + pDown->Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_Init +* +* Function description +* Initializes the RTT Control Block. +* Should be used in RAM targets, at start of the application. +* +*/ +void SEGGER_RTT_Init (void) { + _DoInit(); +} + +/********************************************************************* +* +* SEGGER_RTT_SetTerminal +* +* Function description +* Sets the terminal to be used for output on channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* +* Return value +* >= 0 O.K. +* < 0 Error (e.g. if RTT is configured for non-blocking mode and there was no space in the buffer to set the new terminal Id) +* +* Notes +* (1) Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed +*/ +int SEGGER_RTT_SetTerminal (unsigned char TerminalId) { + unsigned char ac[2]; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + int r; + + INIT(); + r = 0; + ac[0] = 0xFFu; + if (TerminalId < sizeof(_aTerminalId)) { // We only support a certain number of channels + ac[1] = _aTerminalId[TerminalId]; + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[0] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + SEGGER_RTT_LOCK(); // Lock to make sure that no other task is writing into buffer, while we are and number of free bytes in buffer does not change downwards after checking and before writing + if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { + _ActiveTerminal = TerminalId; + _WriteBlocking(pRing, (const char*)ac, 2u); + } else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes + Avail = _GetAvailWriteSpace(pRing); + if (Avail >= 2) { + _ActiveTerminal = TerminalId; // Only change active terminal in case of success + _WriteNoCheck(pRing, (const char*)ac, 2u); + } else { + r = -1; + } + } + SEGGER_RTT_UNLOCK(); + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_TerminalOut +* +* Function description +* Writes a string to the given terminal +* without changing the terminal for channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* s String to be printed on the terminal. +* +* Return value +* >= 0 - Number of bytes written. +* < 0 - Error. +* +*/ +int SEGGER_RTT_TerminalOut (unsigned char TerminalId, const char* s) { + int Status; + unsigned FragLen; + unsigned Avail; + SEGGER_RTT_BUFFER_UP* pRing; + // + INIT(); + // + // Validate terminal ID. + // + if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels + // + // Get "to-host" ring buffer. + // + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[0] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + // + // Need to be able to change terminal, write data, change back. + // Compute the fixed and variable sizes. + // + FragLen = STRLEN(s); + // + // How we output depends upon the mode... + // + SEGGER_RTT_LOCK(); + Avail = _GetAvailWriteSpace(pRing); + switch (pRing->Flags & SEGGER_RTT_MODE_MASK) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother switching terminals at all. + // + if (Avail < (FragLen + 4u)) { + Status = 0; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode and there is not enough space for everything, + // trim the output but always include the terminal switch. If no room + // for terminal switch, skip that totally. + // + if (Avail < 4u) { + Status = -1; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u)); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + break; + default: + Status = -1; + break; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + } else { + Status = -1; + } + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_GetAvailWriteSpace +* +* Function description +* Returns the number of bytes available in the ring buffer. +* +* Parameters +* BufferIndex Index of the up buffer. +* +* Return value +* Number of bytes that are free in the selected up buffer. +*/ +unsigned SEGGER_RTT_GetAvailWriteSpace (unsigned BufferIndex) { + SEGGER_RTT_BUFFER_UP* pRing; + + pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + return _GetAvailWriteSpace(pRing); +} + + +/********************************************************************* +* +* SEGGER_RTT_GetBytesInBuffer() +* +* Function description +* Returns the number of bytes currently used in the up buffer. +* +* Parameters +* BufferIndex Index of the up buffer. +* +* Return value +* Number of bytes that are used in the buffer. +*/ +unsigned SEGGER_RTT_GetBytesInBuffer(unsigned BufferIndex) { + unsigned RdOff; + unsigned WrOff; + unsigned r; + volatile SEGGER_RTT_CB* pRTTCB; + // + // Avoid warnings regarding volatile access order. It's not a problem + // in this case, but dampen compiler enthusiasm. + // + pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + RdOff = pRTTCB->aUp[BufferIndex].RdOff; + WrOff = pRTTCB->aUp[BufferIndex].WrOff; + if (RdOff <= WrOff) { + r = WrOff - RdOff; + } else { + r = pRTTCB->aUp[BufferIndex].SizeOfBuffer - (WrOff - RdOff); + } + return r; +} + +/*************************** End of file ****************************/ diff --git a/cva_bootloader_m0118/src/RTT/SEGGER_RTT.h b/cva_bootloader_m0118/src/RTT/SEGGER_RTT.h new file mode 100644 index 0000000..f0eaa42 --- /dev/null +++ b/cva_bootloader_m0118/src/RTT/SEGGER_RTT.h @@ -0,0 +1,419 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2021 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* condition is met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this condition and the following disclaimer. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 7.22b * +* * +********************************************************************** + +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT.h +Purpose : Implementation of SEGGER real-time transfer which allows + real-time communication on targets which support debugger + memory accesses while the CPU is running. +Revision: $Rev: 20869 $ +---------------------------------------------------------------------- +*/ + +#ifndef SEGGER_RTT_H +#define SEGGER_RTT_H + +#include "SEGGER_RTT_Conf.h" + +/********************************************************************* +* +* Defines, defaults +* +********************************************************************** +*/ +#ifndef RTT_USE_ASM + #if (defined __SES_ARM) // SEGGER Embedded Studio + #define _CC_HAS_RTT_ASM_SUPPORT 1 + #elif (defined __CROSSWORKS_ARM) // Rowley Crossworks + #define _CC_HAS_RTT_ASM_SUPPORT 1 + #elif (defined __ARMCC_VERSION) // ARM compiler + #if (__ARMCC_VERSION >= 6000000) // ARM compiler V6.0 and later is clang based + #define _CC_HAS_RTT_ASM_SUPPORT 1 + #else + #define _CC_HAS_RTT_ASM_SUPPORT 0 + #endif + #elif (defined __GNUC__) // GCC + #define _CC_HAS_RTT_ASM_SUPPORT 1 + #elif (defined __clang__) // Clang compiler + #define _CC_HAS_RTT_ASM_SUPPORT 1 + #elif ((defined __IASMARM__) || (defined __ICCARM__)) // IAR assembler/compiler + #define _CC_HAS_RTT_ASM_SUPPORT 1 + #else + #define _CC_HAS_RTT_ASM_SUPPORT 0 + #endif + #if ((defined __IASMARM__) || (defined __ICCARM__)) // IAR assembler/compiler + // + // IAR assembler / compiler + // + #if (__VER__ < 6300000) + #define VOLATILE + #else + #define VOLATILE volatile + #endif + #if (defined __ARM7M__) // Needed for old versions that do not know the define yet + #if (__CORE__ == __ARM7M__) // Cortex-M3 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #endif + #endif + #if (defined __ARM7EM__) // Needed for old versions that do not know the define yet + #if (__CORE__ == __ARM7EM__) // Cortex-M4/M7 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() asm VOLATILE ("DMB"); + #endif + #endif + #if (defined __ARM8M_BASELINE__) // Needed for old versions that do not know the define yet + #if (__CORE__ == __ARM8M_BASELINE__) // Cortex-M23 + #define _CORE_HAS_RTT_ASM_SUPPORT 0 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() asm VOLATILE ("DMB"); + #endif + #endif + #if (defined __ARM8M_MAINLINE__) // Needed for old versions that do not know the define yet + #if (__CORE__ == __ARM8M_MAINLINE__) // Cortex-M33 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() asm VOLATILE ("DMB"); + #endif + #endif + #else + // + // GCC / Clang + // + #if (defined __ARM_ARCH_7M__) // Cortex-M3 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #elif (defined __ARM_ARCH_7EM__) // Cortex-M4/M7 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() __asm volatile ("dmb\n" : : :); + #elif (defined __ARM_ARCH_8M_BASE__) // Cortex-M23 + #define _CORE_HAS_RTT_ASM_SUPPORT 0 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() __asm volatile ("dmb\n" : : :); + #elif (defined __ARM_ARCH_8M_MAIN__) // Cortex-M33 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() __asm volatile ("dmb\n" : : :); + #else + #define _CORE_HAS_RTT_ASM_SUPPORT 0 + #endif + #endif + // + // If IDE and core support the ASM version, enable ASM version by default + // + #ifndef _CORE_HAS_RTT_ASM_SUPPORT + #define _CORE_HAS_RTT_ASM_SUPPORT 0 // Default for unknown cores + #endif + #if (_CC_HAS_RTT_ASM_SUPPORT && _CORE_HAS_RTT_ASM_SUPPORT) + #define RTT_USE_ASM (1) + #else + #define RTT_USE_ASM (0) + #endif +#endif + +// +// We need to know if a DMB is needed to make sure that on Cortex-M7 etc. +// the order of accesses to the ring buffers is guaranteed +// Needed for: Cortex-M7, Cortex-M23, Cortex-M33 +// +#ifndef _CORE_NEEDS_DMB + #define _CORE_NEEDS_DMB 0 +#endif + +#ifndef RTT__DMB + #if _CORE_NEEDS_DMB + #error "Don't know how to place inline assembly for DMB" + #else + #define RTT__DMB() + #endif +#endif + +#ifndef SEGGER_RTT_CPU_CACHE_LINE_SIZE + #define SEGGER_RTT_CPU_CACHE_LINE_SIZE (0) // On most target systems where RTT is used, we do not have a CPU cache, therefore 0 is a good default here +#endif + +#ifndef SEGGER_RTT_UNCACHED_OFF + #if SEGGER_RTT_CPU_CACHE_LINE_SIZE + #error "SEGGER_RTT_UNCACHED_OFF must be defined when setting SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" + #else + #define SEGGER_RTT_UNCACHED_OFF (0) + #endif +#endif +#if RTT_USE_ASM + #if SEGGER_RTT_CPU_CACHE_LINE_SIZE + #error "RTT_USE_ASM is not available if SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" + #endif +#endif + +#ifndef SEGGER_RTT_ASM // defined when SEGGER_RTT.h is included from assembly file +#include +#include + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ + +// +// Determine how much we must pad the control block to make it a multiple of a cache line in size +// Assuming: U8 = 1B +// U16 = 2B +// U32 = 4B +// U8/U16/U32* = 4B +// +#if SEGGER_RTT_CPU_CACHE_LINE_SIZE // Avoid division by zero in case we do not have any cache + #define SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(NumBytes) (((NumBytes + SEGGER_RTT_CPU_CACHE_LINE_SIZE - 1) / SEGGER_RTT_CPU_CACHE_LINE_SIZE) * SEGGER_RTT_CPU_CACHE_LINE_SIZE) +#else + #define SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(NumBytes) (NumBytes) +#endif +#define SEGGER_RTT__CB_SIZE (16 + 4 + 4 + (SEGGER_RTT_MAX_NUM_UP_BUFFERS * 24) + (SEGGER_RTT_MAX_NUM_DOWN_BUFFERS * 24)) +#define SEGGER_RTT__CB_PADDING (SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(SEGGER_RTT__CB_SIZE) - SEGGER_RTT__CB_SIZE) + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +// +// Description for a circular buffer (also called "ring buffer") +// which is used as up-buffer (T->H) +// +typedef struct { + const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" + char* pBuffer; // Pointer to start of buffer + unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. + unsigned WrOff; // Position of next item to be written by either target. + volatile unsigned RdOff; // Position of next item to be read by host. Must be volatile since it may be modified by host. + unsigned Flags; // Contains configuration flags +} SEGGER_RTT_BUFFER_UP; + +// +// Description for a circular buffer (also called "ring buffer") +// which is used as down-buffer (H->T) +// +typedef struct { + const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" + char* pBuffer; // Pointer to start of buffer + unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. + volatile unsigned WrOff; // Position of next item to be written by host. Must be volatile since it may be modified by host. + unsigned RdOff; // Position of next item to be read by target (down-buffer). + unsigned Flags; // Contains configuration flags +} SEGGER_RTT_BUFFER_DOWN; + +// +// RTT control block which describes the number of buffers available +// as well as the configuration for each buffer +// +// +typedef struct { + char acID[16]; // Initialized to "SEGGER RTT" + int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2) + int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2) + SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host + SEGGER_RTT_BUFFER_DOWN aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target +#if SEGGER_RTT__CB_PADDING + unsigned char aDummy[SEGGER_RTT__CB_PADDING]; +#endif +} SEGGER_RTT_CB; + +/********************************************************************* +* +* Global data +* +********************************************************************** +*/ +extern SEGGER_RTT_CB _SEGGER_RTT; + +/********************************************************************* +* +* RTT API functions +* +********************************************************************** +*/ +#ifdef __cplusplus + extern "C" { +#endif +int SEGGER_RTT_AllocDownBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_AllocUpBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_GetKey (void); +unsigned SEGGER_RTT_HasData (unsigned BufferIndex); +int SEGGER_RTT_HasKey (void); +unsigned SEGGER_RTT_HasDataUp (unsigned BufferIndex); +void SEGGER_RTT_Init (void); +unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize); +unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize); +int SEGGER_RTT_SetNameDownBuffer (unsigned BufferIndex, const char* sName); +int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName); +int SEGGER_RTT_SetFlagsDownBuffer (unsigned BufferIndex, unsigned Flags); +int SEGGER_RTT_SetFlagsUpBuffer (unsigned BufferIndex, unsigned Flags); +int SEGGER_RTT_WaitKey (void); +unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_ASM_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s); +void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_PutChar (unsigned BufferIndex, char c); +unsigned SEGGER_RTT_PutCharSkip (unsigned BufferIndex, char c); +unsigned SEGGER_RTT_PutCharSkipNoLock (unsigned BufferIndex, char c); +unsigned SEGGER_RTT_GetAvailWriteSpace (unsigned BufferIndex); +unsigned SEGGER_RTT_GetBytesInBuffer (unsigned BufferIndex); +// +// Function macro for performance optimization +// +#define SEGGER_RTT_HASDATA(n) (((SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[n] + SEGGER_RTT_UNCACHED_OFF))->WrOff - ((SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[n] + SEGGER_RTT_UNCACHED_OFF))->RdOff) + +#if RTT_USE_ASM + #define SEGGER_RTT_WriteSkipNoLock SEGGER_RTT_ASM_WriteSkipNoLock +#endif + +/********************************************************************* +* +* RTT transfer functions to send RTT data via other channels. +* +********************************************************************** +*/ +unsigned SEGGER_RTT_ReadUpBuffer (unsigned BufferIndex, void* pBuffer, unsigned BufferSize); +unsigned SEGGER_RTT_ReadUpBufferNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize); +unsigned SEGGER_RTT_WriteDownBuffer (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteDownBufferNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); + +#define SEGGER_RTT_HASDATA_UP(n) (((SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[n] + SEGGER_RTT_UNCACHED_OFF))->WrOff - ((SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[n] + SEGGER_RTT_UNCACHED_OFF))->RdOff) // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly + +/********************************************************************* +* +* RTT "Terminal" API functions +* +********************************************************************** +*/ +int SEGGER_RTT_SetTerminal (unsigned char TerminalId); +int SEGGER_RTT_TerminalOut (unsigned char TerminalId, const char* s); + +/********************************************************************* +* +* RTT printf functions (require SEGGER_RTT_printf.c) +* +********************************************************************** +*/ +int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...); +int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList); + +#ifdef __cplusplus + } +#endif + +#endif // ifndef(SEGGER_RTT_ASM) + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ + +// +// Operating modes. Define behavior if buffer is full (not enough space for entire message) +// +#define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0) // Skip. Do not block, output nothing. (Default) +#define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1) // Trim: Do not block, output as much as fits. +#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2) // Block: Wait until there is space in the buffer. +#define SEGGER_RTT_MODE_MASK (3) + +// +// Control sequences, based on ANSI. +// Can be used to control color, and clear the screen +// +#define RTT_CTRL_RESET "\x1B[0m" // Reset to default colors +#define RTT_CTRL_CLEAR "\x1B[2J" // Clear screen, reposition cursor to top left + +#define RTT_CTRL_TEXT_BLACK "\x1B[2;30m" +#define RTT_CTRL_TEXT_RED "\x1B[2;31m" +#define RTT_CTRL_TEXT_GREEN "\x1B[2;32m" +#define RTT_CTRL_TEXT_YELLOW "\x1B[2;33m" +#define RTT_CTRL_TEXT_BLUE "\x1B[2;34m" +#define RTT_CTRL_TEXT_MAGENTA "\x1B[2;35m" +#define RTT_CTRL_TEXT_CYAN "\x1B[2;36m" +#define RTT_CTRL_TEXT_WHITE "\x1B[2;37m" + +#define RTT_CTRL_TEXT_BRIGHT_BLACK "\x1B[1;30m" +#define RTT_CTRL_TEXT_BRIGHT_RED "\x1B[1;31m" +#define RTT_CTRL_TEXT_BRIGHT_GREEN "\x1B[1;32m" +#define RTT_CTRL_TEXT_BRIGHT_YELLOW "\x1B[1;33m" +#define RTT_CTRL_TEXT_BRIGHT_BLUE "\x1B[1;34m" +#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "\x1B[1;35m" +#define RTT_CTRL_TEXT_BRIGHT_CYAN "\x1B[1;36m" +#define RTT_CTRL_TEXT_BRIGHT_WHITE "\x1B[1;37m" + +#define RTT_CTRL_BG_BLACK "\x1B[24;40m" +#define RTT_CTRL_BG_RED "\x1B[24;41m" +#define RTT_CTRL_BG_GREEN "\x1B[24;42m" +#define RTT_CTRL_BG_YELLOW "\x1B[24;43m" +#define RTT_CTRL_BG_BLUE "\x1B[24;44m" +#define RTT_CTRL_BG_MAGENTA "\x1B[24;45m" +#define RTT_CTRL_BG_CYAN "\x1B[24;46m" +#define RTT_CTRL_BG_WHITE "\x1B[24;47m" + +#define RTT_CTRL_BG_BRIGHT_BLACK "\x1B[4;40m" +#define RTT_CTRL_BG_BRIGHT_RED "\x1B[4;41m" +#define RTT_CTRL_BG_BRIGHT_GREEN "\x1B[4;42m" +#define RTT_CTRL_BG_BRIGHT_YELLOW "\x1B[4;43m" +#define RTT_CTRL_BG_BRIGHT_BLUE "\x1B[4;44m" +#define RTT_CTRL_BG_BRIGHT_MAGENTA "\x1B[4;45m" +#define RTT_CTRL_BG_BRIGHT_CYAN "\x1B[4;46m" +#define RTT_CTRL_BG_BRIGHT_WHITE "\x1B[4;47m" + + +#endif + +/*************************** End of file ****************************/ diff --git a/cva_bootloader_m0118/src/RTT/SEGGER_RTT_ASM_ARMv7M.S b/cva_bootloader_m0118/src/RTT/SEGGER_RTT_ASM_ARMv7M.S new file mode 100644 index 0000000..cbbc52f --- /dev/null +++ b/cva_bootloader_m0118/src/RTT/SEGGER_RTT_ASM_ARMv7M.S @@ -0,0 +1,242 @@ +/********************************************************************* +* (c) SEGGER Microcontroller GmbH * +* The Embedded Experts * +* www.segger.com * +********************************************************************** + +-------------------------- END-OF-HEADER ----------------------------- + +File : SEGGER_RTT_ASM_ARMv7M.S +Purpose : Assembler implementation of RTT functions for ARMv7M + +Additional information: + This module is written to be assembler-independent and works with + GCC and clang (Embedded Studio) and IAR. +*/ + +#define SEGGER_RTT_ASM // Used to control processed input from header file +#include "SEGGER_RTT.h" + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ + +#define _CCIAR 0 +#define _CCCLANG 1 + +#if (defined __SES_ARM) || (defined __GNUC__) || (defined __clang__) + #define _CC_TYPE _CCCLANG + #define _PUB_SYM .global + #define _EXT_SYM .extern + #define _END .end + #define _WEAK .weak + #define _THUMB_FUNC .thumb_func + #define _THUMB_CODE .code 16 + #define _WORD .word + #define _SECTION(Sect, Type, AlignExp) .section Sect ##, "ax" + #define _ALIGN(Exp) .align Exp + #define _PLACE_LITS .ltorg + #define _DATA_SECT_START + #define _C_STARTUP _start + #define _STACK_END __stack_end__ + #define _RAMFUNC + // + // .text => Link to flash + // .fast => Link to RAM + // OtherSect => Usually link to RAM + // Alignment is 2^x + // +#elif defined (__IASMARM__) + #define _CC_TYPE _CCIAR + #define _PUB_SYM PUBLIC + #define _EXT_SYM EXTERN + #define _END END + #define _WEAK _WEAK + #define _THUMB_FUNC + #define _THUMB_CODE THUMB + #define _WORD DCD + #define _SECTION(Sect, Type, AlignExp) SECTION Sect ## : ## Type ## :REORDER:NOROOT ## (AlignExp) + #define _ALIGN(Exp) alignrom Exp + #define _PLACE_LITS + #define _DATA_SECT_START DATA + #define _C_STARTUP __iar_program_start + #define _STACK_END sfe(CSTACK) + #define _RAMFUNC SECTION_TYPE SHT_PROGBITS, SHF_WRITE | SHF_EXECINSTR + // + // .text => Link to flash + // .textrw => Link to RAM + // OtherSect => Usually link to RAM + // NOROOT => Allows linker to throw away the function, if not referenced + // Alignment is 2^x + // +#endif + +#if (_CC_TYPE == _CCIAR) + NAME SEGGER_RTT_ASM_ARMv7M +#else + .syntax unified +#endif + +#if defined (RTT_USE_ASM) && (RTT_USE_ASM == 1) + #define SHT_PROGBITS 0x1 + +/********************************************************************* +* +* Public / external symbols +* +********************************************************************** +*/ + + _EXT_SYM __aeabi_memcpy + _EXT_SYM __aeabi_memcpy4 + _EXT_SYM _SEGGER_RTT + + _PUB_SYM SEGGER_RTT_ASM_WriteSkipNoLock + +/********************************************************************* +* +* SEGGER_RTT_WriteSkipNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteSkipNoLock does not lock the application and +* skips all data, if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* MUST be > 0!!! +* This is done for performance reasons, so no initial check has do be done. +* +* Return value +* 1: Data has been copied +* 0: No space, data has not been copied +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, all data is dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ + _SECTION(.text, CODE, 2) + _ALIGN(2) + _THUMB_FUNC +SEGGER_RTT_ASM_WriteSkipNoLock: // unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pData, unsigned NumBytes) { + // + // Cases: + // 1) RdOff <= WrOff => Space until wrap-around is sufficient + // 2) RdOff <= WrOff => Space after wrap-around needed (copy in 2 chunks) + // 3) RdOff < WrOff => No space in buf + // 4) RdOff > WrOff => Space is sufficient + // 5) RdOff > WrOff => No space in buf + // + // 1) is the most common case for large buffers and assuming that J-Link reads the data fast enough + // + // Register usage: + // R0 Temporary needed as RdOff, register later on + // R1 pData + // R2 + // R3 register. Hold free for subroutine calls + // R4 + // R5 pRing->pBuffer + // R6 pRing (Points to active struct SEGGER_RTT_BUFFER_DOWN) + // R7 WrOff + // + PUSH {R4-R7} + ADD R3,R0,R0, LSL #+1 + LDR.W R0,=_SEGGER_RTT // pRing = &_SEGGER_RTT.aUp[BufferIndex]; + ADD R0,R0,R3, LSL #+3 + ADD R6,R0,#+24 + LDR R0,[R6, #+16] // RdOff = pRing->RdOff; + LDR R7,[R6, #+12] // WrOff = pRing->WrOff; + LDR R5,[R6, #+4] // pRing->pBuffer + CMP R7,R0 + BCC.N _CheckCase4 // if (RdOff <= WrOff) { => Case 1), 2) or 3) + // + // Handling for case 1, later on identical to case 4 + // + LDR R3,[R6, #+8] // Avail = pRing->SizeOfBuffer - WrOff - 1u; => Space until wrap-around (assume 1 byte not usable for case that RdOff == 0) + SUBS R4,R3,R7 // (Used in case we jump into case 2 afterwards) + SUBS R3,R4,#+1 // + CMP R3,R2 + BCC.N _CheckCase2 // if (Avail >= NumBytes) { => Case 1)? +_Case4: + ADDS R5,R7,R5 // pBuffer += WrOff + ADDS R0,R2,R7 // v = WrOff + NumBytes + // + // 2x unrolling for the copy loop that is used most of the time + // This is a special optimization for small SystemView packets and makes them even faster + // + _ALIGN(2) +_LoopCopyStraight: // memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + LDRB R3,[R1], #+1 + STRB R3,[R5], #+1 // *pDest++ = *pSrc++ + SUBS R2,R2,#+1 + BEQ _CSDone + LDRB R3,[R1], #+1 + STRB R3,[R5], #+1 // *pDest++ = *pSrc++ + SUBS R2,R2,#+1 + BNE _LoopCopyStraight +_CSDone: +#if _CORE_NEEDS_DMB // Do not slow down cores that do not need a DMB instruction here + DMB // Cortex-M7 may delay memory writes and also change the order in which the writes happen. Therefore, make sure that all buffer writes are finished, before updating the in the struct +#endif + STR R0,[R6, #+12] // pRing->WrOff = WrOff + NumBytes; + MOVS R0,#+1 + POP {R4-R7} + BX LR // Return 1 +_CheckCase2: + ADDS R0,R0,R3 // Avail += RdOff; => Space incl. wrap-around + CMP R0,R2 + BCC.N _Case3 // if (Avail >= NumBytes) { => Case 2? => If not, we have case 3) (does not fit) + // + // Handling for case 2 + // + ADDS R0,R7,R5 // v = pRing->pBuffer + WrOff => Do not change pRing->pBuffer here because 2nd chunk needs org. value + SUBS R2,R2,R4 // NumBytes -= Rem; (Rem = pRing->SizeOfBuffer - WrOff; => Space until end of buffer) +_LoopCopyBeforeWrapAround: // memcpy(pRing->pBuffer + WrOff, pData, Rem); => Copy 1st chunk + LDRB R3,[R1], #+1 + STRB R3,[R0], #+1 // *pDest++ = *pSrc++ + SUBS R4,R4,#+1 + BNE _LoopCopyBeforeWrapAround + // + // Special case: First check that assumed RdOff == 0 calculated that last element before wrap-around could not be used + // But 2nd check (considering space until wrap-around and until RdOff) revealed that RdOff is not 0, so we can use the last element + // In this case, we may use a copy straight until buffer end anyway without needing to copy 2 chunks + // Therefore, check if 2nd memcpy is necessary at all + // + ADDS R4,R2,#+0 // Save (needed as counter in loop but must be written to after the loop). Also use this inst to update the flags to skip 2nd loop if possible + BEQ.N _No2ChunkNeeded // if (NumBytes) { +_LoopCopyAfterWrapAround: // memcpy(pRing->pBuffer, pData + Rem, NumBytes); + LDRB R3,[R1], #+1 // pData already points to the next src byte due to copy loop increment before this loop + STRB R3,[R5], #+1 // *pDest++ = *pSrc++ + SUBS R2,R2,#+1 + BNE _LoopCopyAfterWrapAround +_No2ChunkNeeded: +#if _CORE_NEEDS_DMB // Do not slow down cores that do not need a DMB instruction here + DMB // Cortex-M7 may delay memory writes and also change the order in which the writes happen. Therefore, make sure that all buffer writes are finished, before updating the in the struct +#endif + STR R4,[R6, #+12] // pRing->WrOff = NumBytes; => Must be written after copying data because J-Link may read control block asynchronously while writing into buffer + MOVS R0,#+1 + POP {R4-R7} + BX LR // Return 1 +_CheckCase4: + SUBS R0,R0,R7 + SUBS R0,R0,#+1 // Avail = RdOff - WrOff - 1u; + CMP R0,R2 + BCS.N _Case4 // if (Avail >= NumBytes) { => Case 4) == 1) ? => If not, we have case 5) == 3) (does not fit) +_Case3: + MOVS R0,#+0 + POP {R4-R7} + BX LR // Return 0 + _PLACE_LITS + +#endif // defined (RTT_USE_ASM) && (RTT_USE_ASM == 1) + _END + +/*************************** End of file ****************************/ diff --git a/cva_bootloader_m0118/src/RTT/SEGGER_RTT_Conf.h b/cva_bootloader_m0118/src/RTT/SEGGER_RTT_Conf.h new file mode 100644 index 0000000..f71e227 --- /dev/null +++ b/cva_bootloader_m0118/src/RTT/SEGGER_RTT_Conf.h @@ -0,0 +1,429 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2021 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* condition is met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this condition and the following disclaimer. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 7.22b * +* * +********************************************************************** + +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_Conf.h +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support + debugger memory accesses while the CPU is running. +Revision: $Rev: 21386 $ + +*/ + +#ifndef SEGGER_RTT_CONF_H +#define SEGGER_RTT_CONF_H + +#ifdef __IAR_SYSTEMS_ICC__ + #include +#endif + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ + +// +// Take in and set to correct values for Cortex-A systems with CPU cache +// +//#define SEGGER_RTT_CPU_CACHE_LINE_SIZE (32) // Largest cache line size (in bytes) in the current system +//#define SEGGER_RTT_UNCACHED_OFF (0xFB000000) // Address alias where RTT CB and buffers can be accessed uncached +// +// Most common case: +// Up-channel 0: RTT +// Up-channel 1: SystemView +// +#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS + #define SEGGER_RTT_MAX_NUM_UP_BUFFERS (3) // Max. number of up-buffers (T->H) available on this target (Default: 3) +#endif +// +// Most common case: +// Down-channel 0: RTT +// Down-channel 1: SystemView +// +#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS + #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (3) // Max. number of down-buffers (H->T) available on this target (Default: 3) +#endif + +#ifndef BUFFER_SIZE_UP + #define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k) +#endif + +#ifndef BUFFER_SIZE_DOWN + #define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16) +#endif + +#ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE + #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64) +#endif + +#ifndef SEGGER_RTT_MODE_DEFAULT + #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0) +#endif + +/********************************************************************* +* +* RTT memcpy configuration +* +* memcpy() is good for large amounts of data, +* but the overhead is big for small amounts, which are usually stored via RTT. +* With SEGGER_RTT_MEMCPY_USE_BYTELOOP a simple byte loop can be used instead. +* +* SEGGER_RTT_MEMCPY() can be used to replace standard memcpy() in RTT functions. +* This is may be required with memory access restrictions, +* such as on Cortex-A devices with MMU. +*/ +#ifndef SEGGER_RTT_MEMCPY_USE_BYTELOOP + #define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 // 0: Use memcpy/SEGGER_RTT_MEMCPY, 1: Use a simple byte-loop +#endif +// +// Example definition of SEGGER_RTT_MEMCPY to external memcpy with GCC toolchains and Cortex-A targets +// +//#if ((defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)) && (defined (__ARM_ARCH_7A__)) +// #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) SEGGER_memcpy((pDest), (pSrc), (NumBytes)) +//#endif + +// +// Target is not allowed to perform other RTT operations while string still has not been stored completely. +// Otherwise we would probably end up with a mixed string in the buffer. +// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here. +// +// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4. +// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches. +// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly. +// (Higher priority = lower priority number) +// Default value for embOS: 128u +// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) +// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC +// or define SEGGER_RTT_LOCK() to completely disable interrupts. +// +#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20) +#endif + +/********************************************************************* +* +* RTT lock configuration for SEGGER Embedded Studio, +* Rowley CrossStudio and GCC +*/ +#if ((defined(__SES_ARM) || defined(__SES_RISCV) || defined(__CROSSWORKS_ARM) || defined(__GNUC__) || defined(__clang__)) && !defined (__CC_ARM) && !defined(WIN32)) + #if (defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_8M_BASE__)) + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + __asm volatile ("mrs %0, primask \n\t" \ + "movs r1, #1 \n\t" \ + "msr primask, r1 \n\t" \ + : "=r" (_SEGGER_RTT__LockState) \ + : \ + : "r1", "cc" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \ + : \ + : "r" (_SEGGER_RTT__LockState) \ + : \ + ); \ + } + #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + __asm volatile ("mrs %0, basepri \n\t" \ + "mov r1, %1 \n\t" \ + "msr basepri, r1 \n\t" \ + : "=r" (_SEGGER_RTT__LockState) \ + : "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \ + : "r1", "cc" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \ + : \ + : "r" (_SEGGER_RTT__LockState) \ + : \ + ); \ + } + + #elif defined(__ARM_ARCH_7A__) + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + __asm volatile ("mrs r1, CPSR \n\t" \ + "mov %0, r1 \n\t" \ + "orr r1, r1, #0xC0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : "=r" (_SEGGER_RTT__LockState) \ + : \ + : "r1", "cc" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \ + "mrs r1, CPSR \n\t" \ + "bic r1, r1, #0xC0 \n\t" \ + "and r0, r0, #0xC0 \n\t" \ + "orr r1, r1, r0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : \ + : "r" (_SEGGER_RTT__LockState) \ + : "r0", "r1", "cc" \ + ); \ + } + #elif defined(__riscv) || defined(__riscv_xlen) + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + __asm volatile ("csrr %0, mstatus \n\t" \ + "csrci mstatus, 8 \n\t" \ + "andi %0, %0, 8 \n\t" \ + : "=r" (_SEGGER_RTT__LockState) \ + : \ + : \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("csrr a1, mstatus \n\t" \ + "or %0, %0, a1 \n\t" \ + "csrs mstatus, %0 \n\t" \ + : \ + : "r" (_SEGGER_RTT__LockState) \ + : "a1" \ + ); \ + } + #else + #define SEGGER_RTT_LOCK() + #define SEGGER_RTT_UNLOCK() + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR EWARM +*/ +#ifdef __ICCARM__ + #if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) || \ + (defined (__ARM8M_BASELINE__) && (__CORE__ == __ARM8M_BASELINE__)) + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + _SEGGER_RTT__LockState = __get_PRIMASK(); \ + __set_PRIMASK(1); + + #define SEGGER_RTT_UNLOCK() __set_PRIMASK(_SEGGER_RTT__LockState); \ + } + #elif (defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || \ + (defined (__ARM7M__) && (__CORE__ == __ARM7M__)) || \ + (defined (__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__)) || \ + (defined (__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + _SEGGER_RTT__LockState = __get_BASEPRI(); \ + __set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); + + #define SEGGER_RTT_UNLOCK() __set_BASEPRI(_SEGGER_RTT__LockState); \ + } + #elif (defined (__ARM7A__) && (__CORE__ == __ARM7A__)) || \ + (defined (__ARM7R__) && (__CORE__ == __ARM7R__)) + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + __asm volatile ("mrs r1, CPSR \n\t" \ + "mov %0, r1 \n\t" \ + "orr r1, r1, #0xC0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : "=r" (_SEGGER_RTT__LockState) \ + : \ + : "r1", "cc" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \ + "mrs r1, CPSR \n\t" \ + "bic r1, r1, #0xC0 \n\t" \ + "and r0, r0, #0xC0 \n\t" \ + "orr r1, r1, r0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : \ + : "r" (_SEGGER_RTT__LockState) \ + : "r0", "r1", "cc" \ + ); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR RX +*/ +#ifdef __ICCRX__ + #define SEGGER_RTT_LOCK() { \ + unsigned long _SEGGER_RTT__LockState; \ + _SEGGER_RTT__LockState = __get_interrupt_state(); \ + __disable_interrupt(); + + #define SEGGER_RTT_UNLOCK() __set_interrupt_state(_SEGGER_RTT__LockState); \ + } +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR RL78 +*/ +#ifdef __ICCRL78__ + #define SEGGER_RTT_LOCK() { \ + __istate_t _SEGGER_RTT__LockState; \ + _SEGGER_RTT__LockState = __get_interrupt_state(); \ + __disable_interrupt(); + + #define SEGGER_RTT_UNLOCK() __set_interrupt_state(_SEGGER_RTT__LockState); \ + } +#endif + +/********************************************************************* +* +* RTT lock configuration for KEIL ARM +*/ +#ifdef __CC_ARM + #if (defined __TARGET_ARCH_6S_M) + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + register unsigned char _SEGGER_RTT__PRIMASK __asm( "primask"); \ + _SEGGER_RTT__LockState = _SEGGER_RTT__PRIMASK; \ + _SEGGER_RTT__PRIMASK = 1u; \ + __schedule_barrier(); + + #define SEGGER_RTT_UNLOCK() _SEGGER_RTT__PRIMASK = _SEGGER_RTT__LockState; \ + __schedule_barrier(); \ + } + #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + register unsigned char BASEPRI __asm( "basepri"); \ + _SEGGER_RTT__LockState = BASEPRI; \ + BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \ + __schedule_barrier(); + + #define SEGGER_RTT_UNLOCK() BASEPRI = _SEGGER_RTT__LockState; \ + __schedule_barrier(); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for TI ARM +*/ +#ifdef __TI_ARM__ + #if defined (__TI_ARM_V6M0__) + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + _SEGGER_RTT__LockState = __get_PRIMASK(); \ + __set_PRIMASK(1); + + #define SEGGER_RTT_UNLOCK() __set_PRIMASK(_SEGGER_RTT__LockState); \ + } + #elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int _SEGGER_RTT__LockState; \ + _SEGGER_RTT__LockState = _set_interrupt_priority(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); + + #define SEGGER_RTT_UNLOCK() _set_interrupt_priority(_SEGGER_RTT__LockState); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for CCRX +*/ +#ifdef __RX + #include + #define SEGGER_RTT_LOCK() { \ + unsigned long _SEGGER_RTT__LockState; \ + _SEGGER_RTT__LockState = get_psw() & 0x010000; \ + clrpsw_i(); + + #define SEGGER_RTT_UNLOCK() set_psw(get_psw() | _SEGGER_RTT__LockState); \ + } +#endif + +/********************************************************************* +* +* RTT lock configuration for embOS Simulation on Windows +* (Can also be used for generic RTT locking with embOS) +*/ +#if defined(WIN32) || defined(SEGGER_RTT_LOCK_EMBOS) + +void OS_SIM_EnterCriticalSection(void); +void OS_SIM_LeaveCriticalSection(void); + +#define SEGGER_RTT_LOCK() { \ + OS_SIM_EnterCriticalSection(); + +#define SEGGER_RTT_UNLOCK() OS_SIM_LeaveCriticalSection(); \ + } +#endif + +/********************************************************************* +* +* RTT lock configuration fallback +*/ +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK() // Lock RTT (nestable) (i.e. disable interrupts) +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state) +#endif + +#endif +/*************************** End of file ****************************/ diff --git a/cva_bootloader_m0118/src/RTT/SEGGER_RTT_Syscalls_GCC.c b/cva_bootloader_m0118/src/RTT/SEGGER_RTT_Syscalls_GCC.c new file mode 100644 index 0000000..f0688f7 --- /dev/null +++ b/cva_bootloader_m0118/src/RTT/SEGGER_RTT_Syscalls_GCC.c @@ -0,0 +1,125 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2021 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* condition is met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this condition and the following disclaimer. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 7.22b * +* * +********************************************************************** + +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_Syscalls_GCC.c +Purpose : Low-level functions for using printf() via RTT in GCC. + To use RTT for printf output, include this file in your + application. +Revision: $Rev: 20755 $ +---------------------------------------------------------------------- +*/ +#if (defined __GNUC__) && !(defined __SES_ARM) && !(defined __CROSSWORKS_ARM) && !(defined __ARMCC_VERSION) && !(defined __CC_ARM) + +#include // required for _write_r +#include "SEGGER_RTT.h" + + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +// +// If necessary define the _reent struct +// to match the one passed by the used standard library. +// +struct _reent; + +/********************************************************************* +* +* Function prototypes +* +********************************************************************** +*/ +_ssize_t _write (int file, const void *ptr, size_t len); +_ssize_t _write_r(struct _reent *r, int file, const void *ptr, size_t len); + +/********************************************************************* +* +* Global functions +* +********************************************************************** +*/ + +/********************************************************************* +* +* _write() +* +* Function description +* Low-level write function. +* libc subroutines will use this system routine for output to all files, +* including stdout. +* Write data via RTT. +*/ +_ssize_t _write(int file, const void *ptr, size_t len) { + (void) file; /* Not used, avoid warning */ + SEGGER_RTT_Write(0, ptr, len); + return len; +} + +/********************************************************************* +* +* _write_r() +* +* Function description +* Low-level reentrant write function. +* libc subroutines will use this system routine for output to all files, +* including stdout. +* Write data via RTT. +*/ +_ssize_t _write_r(struct _reent *r, int file, const void *ptr, size_t len) { + (void) file; /* Not used, avoid warning */ + (void) r; /* Not used, avoid warning */ + SEGGER_RTT_Write(0, ptr, len); + return len; +} + +#endif +/****** End Of File *************************************************/ diff --git a/cva_bootloader_m0118/src/RTT/SEGGER_RTT_printf.c b/cva_bootloader_m0118/src/RTT/SEGGER_RTT_printf.c new file mode 100644 index 0000000..fba41db --- /dev/null +++ b/cva_bootloader_m0118/src/RTT/SEGGER_RTT_printf.c @@ -0,0 +1,505 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2021 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* condition is met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this condition and the following disclaimer. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 7.22b * +* * +********************************************************************** + +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_printf.c +Purpose : Replacement for printf to write formatted data via RTT +Revision: $Rev: 17697 $ +---------------------------------------------------------------------- +*/ +#include "SEGGER_RTT.h" +#include "SEGGER_RTT_Conf.h" + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ + +#ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE + #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64) +#endif + +#include +#include + + +#define FORMAT_FLAG_LEFT_JUSTIFY (1u << 0) +#define FORMAT_FLAG_PAD_ZERO (1u << 1) +#define FORMAT_FLAG_PRINT_SIGN (1u << 2) +#define FORMAT_FLAG_ALTERNATE (1u << 3) + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +typedef struct { + char* pBuffer; + unsigned BufferSize; + unsigned Cnt; + + int ReturnValue; + + unsigned RTTBufferIndex; +} SEGGER_RTT_PRINTF_DESC; + +/********************************************************************* +* +* Function prototypes +* +********************************************************************** +*/ + +/********************************************************************* +* +* Static code +* +********************************************************************** +*/ +/********************************************************************* +* +* _StoreChar +*/ +static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p, char c) { + unsigned Cnt; + + Cnt = p->Cnt; + if ((Cnt + 1u) <= p->BufferSize) { + *(p->pBuffer + Cnt) = c; + p->Cnt = Cnt + 1u; + p->ReturnValue++; + } + // + // Write part of string, when the buffer is full + // + if (p->Cnt == p->BufferSize) { + if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) { + p->ReturnValue = -1; + } else { + p->Cnt = 0u; + } + } +} + +/********************************************************************* +* +* _PrintUnsigned +*/ +static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc, unsigned v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) { + static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + unsigned Div; + unsigned Digit; + unsigned Number; + unsigned Width; + char c; + + Number = v; + Digit = 1u; + // + // Get actual field width + // + Width = 1u; + while (Number >= Base) { + Number = (Number / Base); + Width++; + } + if (NumDigits > Width) { + Width = NumDigits; + } + // + // Print leading chars if necessary + // + if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) { + if (FieldWidth != 0u) { + if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) { + c = '0'; + } else { + c = ' '; + } + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, c); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Compute Digit. + // Loop until Digit has the value of the highest digit required. + // Example: If the output is 345 (Base 10), loop 2 times until Digit is 100. + // + while (1) { + if (NumDigits > 1u) { // User specified a min number of digits to print? => Make sure we loop at least that often, before checking anything else (> 1 check avoids problems with NumDigits being signed / unsigned) + NumDigits--; + } else { + Div = v / Digit; + if (Div < Base) { // Is our divider big enough to extract the highest digit from value? => Done + break; + } + } + Digit *= Base; + } + // + // Output digits + // + do { + Div = v / Digit; + v -= Div * Digit; + _StoreChar(pBufferDesc, _aV2C[Div]); + if (pBufferDesc->ReturnValue < 0) { + break; + } + Digit /= Base; + } while (Digit); + // + // Print trailing spaces if necessary + // + if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, ' '); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + } +} + +/********************************************************************* +* +* _PrintInt +*/ +static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc, int v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) { + unsigned Width; + int Number; + + Number = (v < 0) ? -v : v; + + // + // Get actual field width + // + Width = 1u; + while (Number >= (int)Base) { + Number = (Number / (int)Base); + Width++; + } + if (NumDigits > Width) { + Width = NumDigits; + } + if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) { + FieldWidth--; + } + + // + // Print leading spaces if necessary + // + if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, ' '); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + // + // Print sign if necessary + // + if (pBufferDesc->ReturnValue >= 0) { + if (v < 0) { + v = -v; + _StoreChar(pBufferDesc, '-'); + } else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) { + _StoreChar(pBufferDesc, '+'); + } else { + + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Print leading zeros if necessary + // + if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, '0'); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Print number without sign + // + _PrintUnsigned(pBufferDesc, (unsigned)v, Base, NumDigits, FieldWidth, FormatFlags); + } + } + } +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* SEGGER_RTT_vprintf +* +* Function description +* Stores a formatted string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal") +* sFormat Pointer to format string +* pParamList Pointer to the list of arguments for the format string +* +* Return values +* >= 0: Number of bytes which have been stored in the "Up"-buffer. +* < 0: Error +*/ +int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) { + char c; + SEGGER_RTT_PRINTF_DESC BufferDesc; + int v; + unsigned NumDigits; + unsigned FormatFlags; + unsigned FieldWidth; + char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE]; + + BufferDesc.pBuffer = acBuffer; + BufferDesc.BufferSize = SEGGER_RTT_PRINTF_BUFFER_SIZE; + BufferDesc.Cnt = 0u; + BufferDesc.RTTBufferIndex = BufferIndex; + BufferDesc.ReturnValue = 0; + + do { + c = *sFormat; + sFormat++; + if (c == 0u) { + break; + } + if (c == '%') { + // + // Filter out flags + // + FormatFlags = 0u; + v = 1; + do { + c = *sFormat; + switch (c) { + case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break; + case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++; break; + case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++; break; + case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++; break; + default: v = 0; break; + } + } while (v); + // + // filter out field with + // + FieldWidth = 0u; + do { + c = *sFormat; + if ((c < '0') || (c > '9')) { + break; + } + sFormat++; + FieldWidth = (FieldWidth * 10u) + ((unsigned)c - '0'); + } while (1); + + // + // Filter out precision (number of digits to display) + // + NumDigits = 0u; + c = *sFormat; + if (c == '.') { + sFormat++; + do { + c = *sFormat; + if ((c < '0') || (c > '9')) { + break; + } + sFormat++; + NumDigits = NumDigits * 10u + ((unsigned)c - '0'); + } while (1); + } + // + // Filter out length modifier + // + c = *sFormat; + do { + if ((c == 'l') || (c == 'h')) { + sFormat++; + c = *sFormat; + } else { + break; + } + } while (1); + // + // Handle specifiers + // + switch (c) { + case 'c': { + char c0; + v = va_arg(*pParamList, int); + c0 = (char)v; + _StoreChar(&BufferDesc, c0); + break; + } + case 'd': + v = va_arg(*pParamList, int); + _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags); + break; + case 'u': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 10u, NumDigits, FieldWidth, FormatFlags); + break; + case 'x': + case 'X': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, NumDigits, FieldWidth, FormatFlags); + break; + case 's': + { + const char * s = va_arg(*pParamList, const char *); + do { + c = *s; + s++; + if (c == '\0') { + break; + } + _StoreChar(&BufferDesc, c); + } while (BufferDesc.ReturnValue >= 0); + } + break; + case 'p': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, 8u, 8u, 0u); + break; + case '%': + _StoreChar(&BufferDesc, '%'); + break; + default: + break; + } + sFormat++; + } else { + _StoreChar(&BufferDesc, c); + } + } while (BufferDesc.ReturnValue >= 0); + + if (BufferDesc.ReturnValue > 0) { + // + // Write remaining data, if any + // + if (BufferDesc.Cnt != 0u) { + SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt); + } + BufferDesc.ReturnValue += (int)BufferDesc.Cnt; + } + return BufferDesc.ReturnValue; +} + +/********************************************************************* +* +* SEGGER_RTT_printf +* +* Function description +* Stores a formatted string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal") +* sFormat Pointer to format string, followed by the arguments for conversion +* +* Return values +* >= 0: Number of bytes which have been stored in the "Up"-buffer. +* < 0: Error +* +* Notes +* (1) Conversion specifications have following syntax: +* %[flags][FieldWidth][.Precision]ConversionSpecifier +* (2) Supported flags: +* -: Left justify within the field width +* +: Always print sign extension for signed conversions +* 0: Pad with 0 instead of spaces. Ignored when using '-'-flag or precision +* Supported conversion specifiers: +* c: Print the argument as one char +* d: Print the argument as a signed integer +* u: Print the argument as an unsigned integer +* x: Print the argument as an hexadecimal integer +* s: Print the string pointed to by the argument +* p: Print the argument as an 8-digit hexadecimal integer. (Argument shall be a pointer to void.) +*/ +int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...) { + int r; + va_list ParamList; + + va_start(ParamList, sFormat); + r = SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList); + va_end(ParamList); + return r; +} +/*************************** End of file ****************************/ diff --git a/cva_bootloader_m0118/src/TLE9461/SBC_TLE94x1.h b/cva_bootloader_m0118/src/TLE9461/SBC_TLE94x1.h new file mode 100644 index 0000000..146c2cc --- /dev/null +++ b/cva_bootloader_m0118/src/TLE9461/SBC_TLE94x1.h @@ -0,0 +1,101 @@ +/** + * @cond + *********************************************************************************************************************** + * + * Copyright (c) 2018, Infineon Technologies AG + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the + * following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * + * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************************************************************/ +#ifndef SBC_TLE94X1_H +#define SBC_TLE94X1_H + +/* XML Version 0.0.6 */ +#define SBC_XML_VERSION (00006) + +#define CTRL_BUS_CTRL_0 (0x3) /*decimal 3*/ + +#define CTRL_BUS_CTRL_3 (0x0) /*decimal 0*/ + +#define CTRL_GPIO_CTRL (0x4) /*decimal 4*/ + +#define CTRL_HW_CTRL_0 (0x40) /*decimal 64*/ + +#define CTRL_HW_CTRL_1 (0x0) /*decimal 0*/ + +#define CTRL_HW_CTRL_2 (0x40) /*decimal 64*/ + +#define CTRL_HW_CTRL_3 (0x1) /*decimal 1*/ + +#define CTRL_M_S_CTRL (0x13) /*decimal 19*/ + +#define CTRL_PWM_CTRL (0x0) /*decimal 0*/ + +#define CTRL_PWM_FREQ_CTRL (0x0) /*decimal 0*/ + +#define CTRL_SWK_BTL0_CTRL (0x50) /*decimal 80*/ + +#define CTRL_SWK_CAN_FD_CTRL (0x0) /*decimal 0*/ + +#define CTRL_SWK_CDR_CTRL2 (0x1) /*decimal 1*/ + +#define CTRL_SWK_CDR_LIMIT_HIGH_CTRL (0x54) /*decimal 84*/ + +#define CTRL_SWK_CDR_LIMIT_LOW_CTRL (0x4C) /*decimal 76*/ + +#define CTRL_SWK_DATA_H_CTRL 0x00000000 + +#define CTRL_SWK_DATA_L_CTRL 0x00000000 + +#define CTRL_SWK_DLC_CTRL (0x0) /*decimal 0*/ + +#define CTRL_SWK_ID0_CTRL (0x0) /*decimal 0*/ + +#define CTRL_SWK_IDx_CTRL 0x00000000 + +#define CTRL_SWK_MASK_IDx_CTRL 0x00000000 + +#define CTRL_TIMER_CTRL (0x0) /*decimal 0*/ + +#define CTRL_WD_CTRL (0x15) /*decimal 21*/ + +#define CTRL_WK_CTRL_0 (0x0) /*decimal 0*/ + +#define CTRL_WK_CTRL_1 (0x0) /*decimal 0*/ + +#define CTRL_WK_PUPD_CTRL (0x0) /*decimal 0*/ + +#define LED_Math_extendedID (0x1) /*decimal 1*/ + +#define LED_Math_extendedIDMsk (0x1) /*decimal 1*/ + +#define MATH_Baudrate (0x2) /*decimal 2*/ + +#define MATH_CDR_FrequencyMHz (0x28) /*decimal 40*/ + +#define MATH_DoubleCDRFreq (0x0) /*decimal 0*/ + +#define MATH_EN_PN (0x1) /*decimal 1*/ + +#define MATH_PWM_DC (0.0) + +#endif /* SBC_TLE94X1_H */ diff --git a/cva_bootloader_m0118/src/TLE9461/TLE9461.icwp b/cva_bootloader_m0118/src/TLE9461/TLE9461.icwp new file mode 100644 index 0000000..5a043c4 --- /dev/null +++ b/cva_bootloader_m0118/src/TLE9461/TLE9461.icwp @@ -0,0 +1,233 @@ + + + 9e8e9087eecb39921ec31dfccce96b2a2efec664bafe2827aea4ddb51cb86761 + TLE94x1_Lib.xml + V0.0.6 + + + CTRL.HW_CTRL_2[4] + 0 + 0 + + + CTRL.HW_CTRL_1[4] + 0 + 0 + + + CTRL.WK_PUPD_CTRL[7:6] + 0 + 0 + + + CTRL.PWM_FREQ_CTRL[1:0] + 0 + 0 + + + MATH.PWM_DC + 0 + 0.0 + + + CTRL.WK_CTRL_1[7] + 0 + 0 + + + CTRL.HW_CTRL_0[0] + 0 + 0 + + + CTRL.HW_CTRL_0[5] + 0 + 0 + + + CTRL.BUS_CTRL_3[4] + 0 + 0 + + + CTRL.WK_PUPD_CTRL[1:0] + 0 + 0 + + + CTRL.WK_CTRL_0[6] + 0 + 0 + + + CTRL.TIMER_CTRL[3:0] + 0 + 0 + + + CTRL.TIMER_CTRL[6:4] + 0 + 0 + + + CTRL.HW_CTRL_1[5] + 0 + 0 + + + CTRL.HW_CTRL_3[2] + 0 + 0 + + + CTRL.WD_CTRL[5] + 0 + 0 + + + CTRL.HW_CTRL_0[2] + 0 + 0 + + + CTRL.HW_CTRL_2[7:5] + 2 + 2 + + + CTRL.HW_CTRL_2[3:2] + 0 + 0 + + + CTRL.SWK_CAN_FD_CTRL[3:1] + 2 + 0 + + + MATH.Baudrate + 2 + 2 + + + CTRL.SWK_ID0_CTRL[0] + 0 + 0 + + + CTRL.SWK_MASK_IDx_CTRL + 0x00000000 + 0 + + + CTRL.SWK_DLC_CTRL[3:0] + 0 + 0 + + + CTRL.SWK_DATA_H_CTRL + 0x00000000 + 0x00000000 + + + CTRL.SWK_DATA_L_CTRL + 0x00000000 + 0x00000000 + + + CTRL.HW_CTRL_1[3] + 0 + 0 + + + CTRL.HW_CTRL_2[0] + 0 + 0 + + + CTRL.M_S_CTRL[4:3] + 2 + 2 + + + MATH.EN_PN + 1 + 1 + + + CTRL.HW_CTRL_3[1:0] + 1 + 1 + + + CTRL.HW_CTRL_0[6] + 1 + 1 + + + CTRL.SWK_CAN_FD_CTRL[0] + 0 + 0 + + + MATH.DoubleCDRFreq + 0 + 0 + + + CTRL.SWK_IDx_CTRL + 0x00000000 + 0 + + + CTRL.GPIO_CTRL[2:0] + 4 + 4 + + + CTRL.WK_CTRL_1[0] + 0 + 0 + + + CTRL.WK_CTRL_1[5] + 0 + 0 + + + CTRL.WK_CTRL_0[2];CTRL.WD_CTRL[6] + 1 + 1 + + + CTRL.WD_CTRL[4] + 1 + 1 + + + CTRL.WD_CTRL[2:0] + 5 + 5 + + + CTRL.M_S_CTRL[1:0] + 3 + 3 + + + CTRL.HW_CTRL_1[7] + 0 + 0 + + + CTRL.M_S_CTRL[2] + 0 + 0 + + + CTRL.BUS_CTRL_0[2:0] + 3 + 3 + + + \ No newline at end of file diff --git a/cva_bootloader_m0118/src/TLE9461/TLE94x1.c b/cva_bootloader_m0118/src/TLE9461/TLE94x1.c new file mode 100644 index 0000000..73428d2 --- /dev/null +++ b/cva_bootloader_m0118/src/TLE9461/TLE94x1.c @@ -0,0 +1,591 @@ +/********************************************************************************************************************* + * Copyright (c) 2019, Infineon Technologies AG + * + * + * Distributed under the Boost Software License, Version 1.0. + * + * + * Boost Software License - Version 1.0 - August 17th, 2003 + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *********************************************************************************************************************/ + + +/****************************************************************************************************//** + * @file TLE94x1.c + * + * @brief Implementation of main library functions + * + * @version V1.0.1 + * @date 05. October 2020 + * @author Markus Noll / markus.noll@infineon.com + * @author Yannek Micha Rixen / Yannek.Rixen@infineon.com + ********************************************************************************************************/ + + + +/* ================================================================================ */ +/* ============================ HEADER FILES ================================ */ +/* ================================================================================ */ + +#include "TLE94x1.h" +#include "SBC_TLE94x1.h" +#include + + +/* ================================================================================ */ +/* ============================== Variables ================================= */ +/* ================================================================================ */ + + +/* -------------------------------- ISR Handling --------------------------------- */ + +static SBC_Func_Callback SBC_ISR_Callbacks[30]; +static uint32_t SBC_ISR_Vectors[30]; +static uint8_t SBC_ISR_ReadOutRegs[30]; +static uint8_t SBC_ISR_ReadOutVals[30]; +static uint8_t SBC_RegisteredCallbacks = 0; +static uint8_t SBC_RegisteredRedoutRegs = 0; + + + +/* ================================================================================ */ +/* =========================== Library Functions ============================ */ +/* ================================================================================ */ + + +/* -------------------------------- Main Functions ------------------------------- */ + + +SBC_ErrorCode SBC_WD_Trigger(void) { + /* Read WD config out of SBC and write back to trigger WD */ + uint8_t WD_Data = (uint8_t)SBC_Read_Command(SBC_WD_CTRL); + return SBC_Write_Reg(SBC_WD_CTRL, WD_Data, NULL); +} + + +uint16_t SBC_Read_Command(uint8_t SBC_Reg) { + /* Read and return data - Bit[15:8] = Status Information Field - Bit [7:0] Register data */ + return SBC_SPI_TRANSFER16(SBC_Read_Mask & SBC_Reg, 0x00U); +} + + +uint8_t SBC_Read_RegField(uint8_t SBC_Reg, uint8_t SBC_FieldMsk, uint8_t SBC_FieldPos) { + uint8_t data = ((uint8_t)SBC_Read_Command(SBC_Reg)) & 0xFFU; + return (data & SBC_FieldMsk) >> SBC_FieldPos; +} + + +SBC_ErrorCode SBC_Write_Reg(uint8_t SBC_Reg, uint8_t SBC_Val, uint16_t * returnval) { + SBC_ErrorCode errCode; + uint16_t returndata = SBC_SPI_TRANSFER16(SBC_Write_Bit | SBC_Reg, SBC_Val); + if(returnval != NULL) { + *returnval = returndata; + } + + errCode.SBC_Register = SBC_Reg; + errCode.flippedBitsMask = ((uint8_t)SBC_Read_Command(SBC_Reg)) ^ SBC_Val; + errCode.expectedValue = SBC_Val; + return errCode; +} + + +SBC_ErrorCode SBC_Write_RegField(uint8_t SBC_Reg, uint8_t SBC_FieldMsk, uint8_t SBC_FieldPos, uint8_t SBC_FieldVal, uint16_t * returnval) { + SBC_ErrorCode errCode; + + /* Read data out of register to be manipulated */ + uint16_t returndata = SBC_Read_Command(SBC_Reg); + if(returnval != NULL) { + *returnval = returndata; + } + uint8_t data = (uint8_t)returndata; + + /* Set the used bit field to all 0 */ + data &= ~(SBC_FieldMsk); + + /* Configure new data to bit field */ + data |= (SBC_FieldVal << SBC_FieldPos); + + (void)SBC_SPI_TRANSFER16(SBC_Write_Bit | SBC_Reg, data); + + errCode.SBC_Register = SBC_Reg; + errCode.expectedValue = (SBC_FieldVal << SBC_FieldPos); + uint8_t actualValue = ((uint8_t)SBC_Read_Command(SBC_Reg)) & SBC_FieldMsk; + errCode.flippedBitsMask = errCode.expectedValue ^ actualValue; + return errCode; +} + + +SBC_ErrorCode SBC_Init(void) { + SBC_ErrorCode errCode; + uint8_t WD_Checksum = CTRL_WD_CTRL; + uint8_t WD_CTRL = CTRL_WD_CTRL; + uint8_t SWK_ID3_CTRL, SWK_ID2_CTRL, SWK_ID1_CTRL, SWK_ID0_CTRL; + uint8_t SWK_MASK_ID3_CTRL, SWK_MASK_ID2_CTRL, SWK_MASK_ID1_CTRL, SWK_MASK_ID0_CTRL; + uint8_t SWK_CAN_FD_CTRL = CTRL_SWK_CAN_FD_CTRL; + + /* Calculate checksum */ + WD_Checksum = WD_Checksum ^ WD_Checksum >> 4; + WD_Checksum = WD_Checksum ^ WD_Checksum >> 2; + WD_Checksum = WD_Checksum ^ WD_Checksum >> 1; + + if((WD_Checksum & 1) > 0) { + /* Set parity bit */ + WD_CTRL = CTRL_WD_CTRL | 0x80U; + } + + /* Check if ID is configured to be extended */ + if((CTRL_SWK_ID0_CTRL & SBC_SWK_ID0_CTRL_IDE_Msk) == SBC_IDE_EXTENDED) { + /* extended ID */ + uint32_t SWK_ID_CTRL = CTRL_SWK_IDx_CTRL << 3; + uint32_t SWK_MASK_ID_CTRL = CTRL_SWK_MASK_IDx_CTRL << 3; + + SWK_ID3_CTRL = (uint8_t)(SWK_ID_CTRL >> 24); + SWK_ID2_CTRL = (uint8_t)(SWK_ID_CTRL >> 16); + SWK_ID1_CTRL = (uint8_t)(SWK_ID_CTRL >> 8); + SWK_ID0_CTRL = (((uint8_t)(SWK_ID_CTRL >> 1)) & SBC_SWK_ID0_CTRL_ID4_0_Msk) | SBC_IDE_EXTENDED; + SWK_MASK_ID3_CTRL = (uint8_t)(SWK_MASK_ID_CTRL >> 24); + SWK_MASK_ID2_CTRL = (uint8_t)(SWK_MASK_ID_CTRL >> 16); + SWK_MASK_ID1_CTRL = (uint8_t)(SWK_MASK_ID_CTRL >> 8); + SWK_MASK_ID0_CTRL = (((uint8_t)(SWK_MASK_ID_CTRL >> 1)) & SBC_SWK_MASK_ID0_CTRL_MASK_ID4_0_Msk); + } else { + /* Standard length ID */ + uint16_t SWK_ID_CTRL = CTRL_SWK_IDx_CTRL; + uint32_t SWK_MASK_ID_CTRL = CTRL_SWK_MASK_IDx_CTRL; + + SWK_ID3_CTRL = (uint8_t)(SWK_ID_CTRL >> 3); + SWK_ID2_CTRL = (uint8_t)(SWK_ID_CTRL << 5); + SWK_ID1_CTRL = 0x00U; + SWK_ID0_CTRL = 0x00U; + SWK_MASK_ID3_CTRL = (uint8_t)(SWK_MASK_ID_CTRL >> 3); + SWK_MASK_ID2_CTRL = (uint8_t)(SWK_MASK_ID_CTRL << 5); + SWK_MASK_ID1_CTRL = 0x00U; + SWK_MASK_ID0_CTRL = 0x00U; + } + + /* DIS_ERR_CNT is set only when FD Tolerance is set. */ + if((CTRL_SWK_CAN_FD_CTRL & SBC_SWK_CAN_FD_CTRL_CAN_FD_EN_Msk) == SBC_CAN_FD_EN_ENABLED) { + SWK_CAN_FD_CTRL &= SBC_DIS_ERR_CNT_DISABLED << SBC_SWK_CAN_FD_CTRL_DIS_ERR_CNT_Pos; + } + + /* Describes initialization sequence */ + uint8_t initSequence[39][2] = { + {SBC_WD_CTRL, WD_CTRL}, + {SBC_M_S_CTRL, CTRL_M_S_CTRL}, + {SBC_HW_CTRL_0, CTRL_HW_CTRL_0}, + {SBC_HW_CTRL_3, CTRL_HW_CTRL_3}, + {SBC_BUS_CTRL_3, CTRL_BUS_CTRL_3}, + {SBC_WK_CTRL_0, CTRL_WK_CTRL_0}, + {SBC_WK_CTRL_1, CTRL_WK_CTRL_1}, + {SBC_WK_PUPD_CTRL, CTRL_WK_PUPD_CTRL}, + {SBC_TIMER_CTRL, CTRL_TIMER_CTRL}, + {SBC_PWM_FREQ_CTRL, CTRL_PWM_FREQ_CTRL}, /* The desired duty cycle should be set first before GPIO is enabled as PWM HS or PWM LS. */ + {SBC_PWM_CTRL, CTRL_PWM_CTRL}, + {SBC_GPIO_CTRL, CTRL_GPIO_CTRL}, + {SBC_HW_CTRL_1, CTRL_HW_CTRL_1}, /* May lock configuration (CFG_LOCK_0) */ + {SBC_HW_CTRL_2, CTRL_HW_CTRL_2}, /* May lock configuration (CFG_LOCK_1) */ + {SBC_BUS_CTRL_0, CTRL_BUS_CTRL_0}, + + /* -------------------------- SELECTIVE WAKE REGISTERS --------------------------- */ + + /* Configuring CDR */ + {SBC_SWK_CDR_CTRL2, CTRL_SWK_CDR_CTRL2}, + {SBC_SWK_BTL0_CTRL, CTRL_SWK_BTL0_CTRL}, + {SBC_SWK_CDR_LIMIT_HIGH_CTRL, CTRL_SWK_CDR_LIMIT_HIGH_CTRL}, + {SBC_SWK_CDR_LIMIT_LOW_CTRL, CTRL_SWK_CDR_LIMIT_LOW_CTRL}, + {SBC_SWK_CDR_CTRL1, (SBC_SEL_FILT_TC16 << SBC_SWK_CDR_CTRL1_SEL_FILT_Pos) | (SBC_CDR_EN_ENABLED << SBC_SWK_CDR_CTRL1_CDR_EN_Pos)}, + + + /* Set ID */ + {SBC_SWK_ID3_CTRL, SWK_ID3_CTRL}, + {SBC_SWK_ID2_CTRL, SWK_ID2_CTRL}, + {SBC_SWK_ID1_CTRL, SWK_ID1_CTRL}, + {SBC_SWK_ID0_CTRL, SWK_ID0_CTRL}, + + /* Set Mask */ + {SBC_SWK_MASK_ID3_CTRL, SWK_MASK_ID3_CTRL}, + {SBC_SWK_MASK_ID2_CTRL, SWK_MASK_ID2_CTRL}, + {SBC_SWK_MASK_ID1_CTRL, SWK_MASK_ID1_CTRL}, + {SBC_SWK_MASK_ID0_CTRL, SWK_MASK_ID0_CTRL}, + + /* Set Data */ + {SBC_SWK_DATA7_CTRL, (uint8_t)(CTRL_SWK_DATA_H_CTRL >> 24)}, + {SBC_SWK_DATA6_CTRL, (uint8_t)(CTRL_SWK_DATA_H_CTRL >> 16)}, + {SBC_SWK_DATA5_CTRL, (uint8_t)(CTRL_SWK_DATA_H_CTRL >> 8)}, + {SBC_SWK_DATA4_CTRL, (uint8_t)(CTRL_SWK_DATA_H_CTRL >> 0)}, + {SBC_SWK_DATA3_CTRL, (uint8_t)(CTRL_SWK_DATA_L_CTRL >> 24)}, + {SBC_SWK_DATA2_CTRL, (uint8_t)(CTRL_SWK_DATA_L_CTRL >> 16)}, + {SBC_SWK_DATA1_CTRL, (uint8_t)(CTRL_SWK_DATA_L_CTRL >> 8)}, + {SBC_SWK_DATA0_CTRL, (uint8_t)(CTRL_SWK_DATA_L_CTRL >> 0)}, + + /* Set DLC */ + {SBC_SWK_DLC_CTRL, CTRL_SWK_DLC_CTRL}, + + {SBC_SWK_CAN_FD_CTRL, SWK_CAN_FD_CTRL}, + + /* End Configuration */ + {0x00U, 0x00U} + }; + + /* Call SPI Init */ + if(SBC_SPI_INIT() != 0) { + errCode.SBC_Register = 0x00; + errCode.flippedBitsMask = 0xFF; + errCode.expectedValue = 0x00; + return errCode; + }; + + uint8_t i = 0; + + /* Write all initialization items to Lite SBC */ + while(initSequence[i][0] != 0x00U || initSequence[i][1] != 0x00U) { + errCode = SBC_Write_Reg(initSequence[i][0], initSequence[i][1], NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + i++; + } + + errCode.SBC_Register = 0x00; + errCode.flippedBitsMask = 0x00; + errCode.expectedValue = 0x00; + return errCode; +} + + + +/* -------------------------------- ISR Functions -------------------------------- */ + + +void SBC_Register_Callback(uint32_t ISR_Vector, void (*Callback_Handler)(uint8_t callbackHandler)) { + /* Save callback */ + SBC_ISR_Callbacks[SBC_RegisteredCallbacks] = Callback_Handler; + + /* Save callback vector */ + SBC_ISR_Vectors[SBC_RegisteredCallbacks] = ISR_Vector; + + /* Check if the register will be readout already to avoid double-readout later */ + uint8_t RegFound = 0; + for (uint8_t i = 0; i < SBC_RegisteredRedoutRegs; i++) { + if (SBC_ISR_ReadOutRegs[i] == (ISR_Vector >> 24)) { + RegFound = 1; + } + } + + /* If readout status-reg was not found, register in the readout list */ + if (RegFound == 0) { + SBC_ISR_ReadOutRegs[SBC_RegisteredRedoutRegs] = (uint8_t)(ISR_Vector >> 24); + SBC_RegisteredRedoutRegs++; + } + + SBC_RegisteredCallbacks++; +} + + +SBC_ErrorCode SBC_ISR(void) { + SBC_ErrorCode errCode; + + /* Readout all registered status-registers */ + for (uint8_t i = 0; i < SBC_RegisteredRedoutRegs; i++) { + SBC_ISR_ReadOutVals[i] = (uint8_t) SBC_Read_Command(SBC_ISR_ReadOutRegs[i]); + } + + /* Handle all interrupts */ + for (uint8_t i = 0; i < SBC_RegisteredCallbacks; i++) { + /* Decode ISR Vector */ + uint8_t Compare = (uint8_t)SBC_ISR_Vectors[i]; + uint8_t FieldPos = (uint8_t)(SBC_ISR_Vectors[i] >> 8); + uint8_t FieldMsk = (uint8_t)(SBC_ISR_Vectors[i] >> 16); + uint8_t RegAddr = (uint8_t)(SBC_ISR_Vectors[i] >> 24); + + /* Readback of associated status-bit */ + uint8_t ReadBack = 0; + for (uint8_t j = 0; j < SBC_RegisteredRedoutRegs; j++) { + if (SBC_ISR_ReadOutRegs[j] == RegAddr) { + ReadBack = SBC_ISR_ReadOutVals[j]; + break; + } + } + + /* If compare-values matched -> proceed callback and clear field */ + if (((ReadBack & FieldMsk) >> FieldPos) == Compare) { + SBC_ISR_Callbacks[i](ReadBack); + } + } + + /* Clear all ISR related registers */ + for (uint8_t i = 0; i < SBC_RegisteredRedoutRegs; i++) { + errCode = SBC_Write_Reg(SBC_ISR_ReadOutRegs[i], 0x00U, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + } + + errCode.SBC_Register = 0x00U; + errCode.flippedBitsMask = 0x00U; + errCode.expectedValue = 0x00U; + return errCode; +} + + + +/* -------------------------------- API Calls ----------------------------------- */ + +SBC_ErrorCode SBC_Mode_Normal(void) { + return SBC_Write_RegField(SBC_M_S_CTRL, SBC_M_S_CTRL_MODE_Msk, SBC_M_S_CTRL_MODE_Pos, SBC_MODE_NORMAL, NULL); +} + + +SBC_ErrorCode SBC_Mode_Stop(void) { + return SBC_Write_RegField(SBC_M_S_CTRL, SBC_M_S_CTRL_MODE_Msk, SBC_M_S_CTRL_MODE_Pos, SBC_MODE_STOP, NULL); +} + + +SBC_ErrorCode SBC_Mode_Sleep(void) { + uint8_t registerReadOut; + + SBC_ErrorCode errCode; + + /* If CAN PN is configured */ + if(MATH_EN_PN != 0) { + + /* Reading value of SWK_STAT. */ + registerReadOut = (uint8_t)SBC_Read_Command(SBC_SWK_STAT); + + /* CAN Protocol Handler in sync? The selective wake routine should be aborted if sync is not set. Note: for SYNC to be set the transceiver must have been in Normal Mode and a valid CAN communication must have been sent on the bus by any node. */ + if((registerReadOut & SBC_SWK_STAT_SYNC_Msk) >> SBC_SWK_STAT_SYNC_Pos != SBC_SYNC_VALID_FRAME_RECEIVED) { + errCode.SBC_Register = SBC_SWK_STAT; + errCode.flippedBitsMask = SBC_SWK_STAT_SYNC_Msk; + errCode.expectedValue = SBC_SYNC_VALID_FRAME_RECEIVED << SBC_SWK_STAT_SYNC_Pos; + return errCode; + } + + /* Set SWK Configuration valid */ + errCode = SBC_Write_RegField(SBC_SWK_CTRL, SBC_SWK_CTRL_CFG_VAL_Msk, SBC_SWK_CTRL_CFG_VAL_Pos, SBC_CFG_VAL_VALID, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + + + /* Clear SYSERR bit */ + errCode = SBC_Write_RegField(SBC_BUS_STAT, SBC_BUS_STAT_SYSERR_Msk, SBC_BUS_STAT_SYSERR_Pos, 0x00, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + + /* Set CAN Mode to off and once again to desired configuration */ + errCode = SBC_Write_Reg(SBC_BUS_CTRL_0, 0x03, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + + errCode = SBC_Write_Reg(SBC_BUS_CTRL_0, CTRL_BUS_CTRL_0, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + + /* Check SWK_STAT for SYNC == 1 && SWK_SET == 1 && WUF == 0 && WUP == 0. Ignore CANSIL */ + registerReadOut = (uint8_t)SBC_Read_Command(SBC_SWK_STAT); + if( ((SBC_SWK_STAT_SYNC_Msk & registerReadOut) == SBC_SWK_STAT_SYNC_Msk) + && ((SBC_SWK_STAT_SWK_SET_Msk & registerReadOut) == SBC_SWK_STAT_SWK_SET_Msk) + && ((SBC_SWK_STAT_WUP_Msk & registerReadOut) != SBC_SWK_STAT_WUP_Msk) + && ((SBC_SWK_STAT_WUF_Msk & registerReadOut) != SBC_SWK_STAT_WUF_Msk)) { + /* Empty */ + } else { + errCode.SBC_Register = SBC_SWK_STAT; + errCode.expectedValue = 0b01000100U; + errCode.flippedBitsMask = errCode.expectedValue ^ registerReadOut; + return errCode; + } + + + + } + + + + /* Clear Wake Status Registers, so that SBC can sleep. */ + errCode = SBC_Write_Reg(SBC_WK_STAT_0, 0x00, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + errCode = SBC_Write_Reg(SBC_WK_STAT_1, 0x00, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + + /* Select sleep mode */ + (void)SBC_Write_RegField(SBC_M_S_CTRL, SBC_M_S_CTRL_MODE_Msk, SBC_M_S_CTRL_MODE_Pos, SBC_MODE_SLEEP, NULL); + registerReadOut = (uint8_t)SBC_Read_Command(SBC_M_S_CTRL); + + /* This piece of code is ideally never reached as the microcontroller should be already turned off then */ + if(registerReadOut != 0) { + errCode.SBC_Register = SBC_M_S_CTRL; + errCode.flippedBitsMask = registerReadOut; + errCode.expectedValue = 0x00U; + return errCode; + } + + errCode.SBC_Register = 0x00U; + errCode.flippedBitsMask = 0x00U; + errCode.expectedValue = 0x00U; + return errCode; +} + + +SBC_ErrorCode SBC_Set_DutyCycle_PWM (uint8_t PWM_DC) { + return SBC_Write_Reg(SBC_PWM_CTRL, PWM_DC, NULL); +} + + +SBC_ErrorCode SBC_Set_Timer_On (uint8_t OnTime) { + return SBC_Write_RegField(SBC_TIMER_CTRL, SBC_TIMER_CTRL_TIMER_ON_Msk, SBC_TIMER_CTRL_TIMER_ON_Pos, OnTime, NULL); +} + + +SBC_ErrorCode SBC_Set_Timer_Period (uint8_t Period) { + return SBC_Write_RegField(SBC_TIMER_CTRL, SBC_TIMER_CTRL_TIMER_PER_Msk, SBC_TIMER_CTRL_TIMER_PER_Pos, Period, NULL); +} + + +SBC_ErrorCode SBC_FO_Test_On(void) { + return SBC_Write_RegField(SBC_HW_CTRL_0, SBC_HW_CTRL_0_FO_ON_Msk, SBC_HW_CTRL_0_FO_ON_Pos, SBC_FO_ON_ACTIVE, NULL); +} + + +SBC_ErrorCode SBC_FO_Test_Off(void) { + return SBC_Write_RegField(SBC_HW_CTRL_0, SBC_HW_CTRL_0_FO_ON_Msk, SBC_HW_CTRL_0_FO_ON_Pos, SBC_FO_ON_NOT_ACTIVE, NULL); +} + + +SBC_ErrorCode SBC_CP_On(void) { + return SBC_Write_RegField(SBC_HW_CTRL_0, SBC_HW_CTRL_0_CP_EN_Msk, SBC_HW_CTRL_0_CP_EN_Pos, SBC_CP_EN_ON, NULL); +} + + +SBC_ErrorCode SBC_CP_Off(void) { + return SBC_Write_RegField(SBC_HW_CTRL_0, SBC_HW_CTRL_0_CP_EN_Msk, SBC_HW_CTRL_0_CP_EN_Pos, SBC_CP_EN_OFF, NULL); +} + + +SBC_ErrorCode SBC_WK_MEAS_On(void) { + return SBC_Write_RegField(SBC_WK_CTRL_1, SBC_WK_CTRL_1_WK_MEAS_Msk, SBC_WK_CTRL_1_WK_MEAS_Pos, SBC_WK_MEAS_WK_AS_VOLTAGESENSING, NULL); +} + + +SBC_ErrorCode SBC_WK_MEAS_Off(void) { + return SBC_Write_RegField(SBC_WK_CTRL_1, SBC_WK_CTRL_1_WK_MEAS_Msk, SBC_WK_CTRL_1_WK_MEAS_Pos, SBC_WK_MEAS_WK_AS_WAKEUP, NULL); +} + + +SBC_ErrorCode SBC_TIMER_WK_EN_On(void) { + return SBC_Write_RegField(SBC_WK_CTRL_0, SBC_WK_CTRL_0_TIMER_WK_EN_Msk, SBC_WK_CTRL_0_TIMER_WK_EN_Pos, WK_CTRL_0_TIMER_WK_EN_WAKESOURCE, NULL); +} + + +SBC_ErrorCode SBC_TIMER_WK_EN_Off(void) { + return SBC_Write_RegField(SBC_WK_CTRL_0, SBC_WK_CTRL_0_TIMER_WK_EN_Msk, SBC_WK_CTRL_0_TIMER_WK_EN_Pos, WK_CTRL_0_TIMER_WK_EN_WAKEUP_DISABLED, NULL); +} + + +uint16_t SBC_SYS_STAT_Read(void) { + uint16_t systemStatus = 0; + uint16_t returndata = SBC_Read_Command(SBC_SYS_STATUS_CTRL_0); + systemStatus = returndata & 0x00FFU; + systemStatus |= SBC_Read_Command(SBC_SYS_STATUS_CTRL_1) << 8; + return systemStatus; +} + + +SBC_ErrorCode SBC_SYS_STAT_Write(uint16_t SystemStatus) { + SBC_ErrorCode errCode; + + /* Write lower bits */ + errCode = SBC_Write_Reg(SBC_SYS_STATUS_CTRL_0, (uint8_t)SystemStatus, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + + /* Write higher bits */ + return SBC_Write_Reg(SBC_SYS_STATUS_CTRL_1, (uint8_t)(SystemStatus >> 8), NULL); +} + + +SBC_ErrorCode SBC_Lock_Configuration(void) { + SBC_ErrorCode errCode; + + /* Lock CP_EN and GPIO cannot be modified */ + errCode = SBC_Write_RegField(SBC_HW_CTRL_1, SBC_HW_CTRL_1_CFG_LOCK_0_Msk, SBC_HW_CTRL_1_CFG_LOCK_0_Pos, SBC_CFG_LOCK_0_LOCKED, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + + /* Lock Bits with bit type ‘rwl’ (except CP_EN and GPIO) until next device power-up. */ + errCode = SBC_Write_RegField(SBC_HW_CTRL_2, SBC_HW_CTRL_2_CFG_LOCK_1_Msk, SBC_HW_CTRL_2_CFG_LOCK_1_Pos, SBC_CFG_LOCK_1_LOCKED, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + + errCode.SBC_Register = 0x00; + errCode.flippedBitsMask = 0x00; + errCode.expectedValue = 0x00; + return errCode; +} + + +SBC_ErrorCode SBC_Unlock_Configuration(void) { + SBC_ErrorCode errCode; + + /* Unlock CP_EN and GPIO configuration. */ + errCode = SBC_Write_RegField(SBC_HW_CTRL_1, SBC_HW_CTRL_1_CFG_LOCK_0_Msk, SBC_HW_CTRL_1_CFG_LOCK_0_Pos, SBC_CFG_LOCK_0_NOTLOCKED, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + + /* Unlock Bits with bit type ‘rwl’ (except CP_EN and GPIO). */ + errCode = SBC_Write_RegField(SBC_HW_CTRL_2, SBC_HW_CTRL_2_CFG_LOCK_1_Msk, SBC_HW_CTRL_2_CFG_LOCK_1_Pos, SBC_CFG_LOCK_1_NOTLOCKED, NULL); + if(errCode.flippedBitsMask > 0) { + return errCode; + } + + errCode.SBC_Register = 0x00; + errCode.flippedBitsMask = 0x00; + errCode.expectedValue = 0x00; + return errCode; +} + +SBC_ErrorCode SBC_Clear_Wake_Status(void) { + SBC_ErrorCode errCode = SBC_Write_Reg(SBC_WK_STAT_0, 0x00, NULL); + if(errCode.flippedBitsMask != 0) { + return errCode; + } + errCode = SBC_Write_Reg(SBC_WK_STAT_1, 0x00, NULL); + if(errCode.flippedBitsMask != 0) { + return errCode; + } + errCode.SBC_Register = 0x00; + errCode.flippedBitsMask = 0x00; + errCode.expectedValue = 0x00; + return errCode; +} diff --git a/cva_bootloader_m0118/src/TLE9461/TLE94x1.h b/cva_bootloader_m0118/src/TLE9461/TLE94x1.h new file mode 100644 index 0000000..a434389 --- /dev/null +++ b/cva_bootloader_m0118/src/TLE9461/TLE94x1.h @@ -0,0 +1,393 @@ +/********************************************************************************************************************* + * Copyright (c) 2019, Infineon Technologies AG + * + * + * Distributed under the Boost Software License, Version 1.0. + * + * + * Boost Software License - Version 1.0 - August 17th, 2003 + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *********************************************************************************************************************/ + + +/****************************************************************************************************//** + * @file TLE94x1.h + * + * @brief Main header declaration file for TLE94x1 SBC family device + * + * @version V1.0.0 + * @date 15. April 2019 + * @author Markus Noll / markus.noll@infineon.com + * @author Yannek Micha Rixen / Yannek.Rixen@infineon.com + *******************************************************************************************************/ + + + + +#ifndef TLE94x1_H +#define TLE94x1_H + + + + + + +/* ================================================================================ */ +/* ============================ HEADER FILES ================================ */ +/* ================================================================================ */ + + + +#include "TLE94x1_DEFINES.h" +#include "TLE94x1_ISR.h" +#include "TLE94x1_SPI.h" +#include + + + + +/* ================================================================================ */ +/* ================================ MACROS ================================== */ +/* ================================================================================ */ + + +/** + * @def SBC_Write_Bit + * + * @brief This bit has to be set in order to write to a register. + */ +#define SBC_Write_Bit (0x80U) + +/** + * @def SBC_Read_Mask + * + * @brief A mask to prevent the user from accidentally writing to a register. + */ +#define SBC_Read_Mask (0x7FU) + + + + +/* ================================================================================ */ +/* =========================== Library Functions ============================ */ +/* ================================================================================ */ + +struct __SBC_ErrorCode; + +/** + * @brief A structure for simple error readout. + * + * flippedBitsMask is greater than 0 if the value read from the register at SBC_Register differs from expectedValue. + */ +typedef struct __SBC_ErrorCode { + uint8_t SBC_Register; //!< The register where an error occurred. + uint8_t flippedBitsMask; //!< Masks the bits that differ from the expected value. Is 0 if readout is as expected. + uint8_t expectedValue; //!< Expected readout of the register. +} SBC_ErrorCode; + +/** + * @brief Typedef for interrupt callbacks. + */ +typedef void (*SBC_Func_Callback)(uint8_t callbackHandler); + + + + + + +/* -------------------------------- Main Functions ------------------------------- */ + + +/** + * @brief This method will trigger the watchdog. + * + * The function must be called periodically according to the configured watchdog-time. + */ +SBC_ErrorCode SBC_WD_Trigger(void); + + +/** + * @brief This method will proceed a readout of a register. + * + * @param SBC_Reg Address of the register to be read out. See TLE94x1_DEFINES.h for definitions + * @retval A 16 bit value will be returned. + * Bit[15:8] is the Status-Information-Field, Bit [7:0] is the read register-value. + * For furhter information of the Status-Information-Field see chapter 13.3 in the datasheet. + */ +uint16_t SBC_Read_Command(uint8_t SBC_Reg); + + +/** + * @brief This method will proceed a readout of a dedicated bitfield within a register + * + * @param SBC_Reg Address of the register to be readout. See TLE94x1_DEFINES.h for definitions + * @param SBC_FieldMsk Bit mask of the field to be readout. See TLE94x1_DEFINES.h for definitions + * @param SBC_FieldPos Bit position of the field to be readout. See TLE94x1_DEFINES.h for definitions + * + * + * @retval A 8 bit value will be returned and includes the data of the bitfield to be read out * + */ +uint8_t SBC_Read_RegField(uint8_t SBC_Reg, uint8_t SBC_FieldMsk, uint8_t SBC_FieldPos); + + + +/** + * @brief Writes a whole byte to a register and verifies it. + * + * @param SBC_Reg Address of the register to be manipulated. See TLE94x1_DEFINES.h for definitions + * @param SBC_Val Byte to write to SBC_Reg + * @param *returnval A 16 bit value will be returned. + * Bit[15:8] is the Status-Information-Field, Bit [7:0] is the value of the manipulated register before write + * For furhter information of the Status-Information-Field see chapter 13.3 in the datasheet. + * + * @retval See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Write_Reg(uint8_t SBC_Reg, uint8_t SBC_Val, uint16_t * returnval); + + +/** + * @brief This method can be used for manipulating a single bit-field in a control-register. + * + * It will readout the old value of the registers, manipulate the desired bit-field and keep + * the other bit-configuration as it was. + * For usage examples have a look at the implementations of different API calls below. + * + * @param SBC_Reg Address of the register to be manipulated. See TLE94x1_DEFINES.h for definitions + * @param SBC_FieldMsk Bit mask of the field to manipulate. See TLE94x1_DEFINES.h for definitions + * @param SBC_FieldPos Bit position of the field to manipulate. See TLE94x1_DEFINES.h for definitions + * @param SBC_FieldVal New value which will be written to the bit-field. See TLE94x1_DEFINES.h for enumerations + * @param *returnval A 16 bit value will be returned. + * Bit[15:8] is the Status-Information-Field, Bit [7:0] is the value of the manipulated register before write + * For furhter information of the Status-Information-Field see chapter 13.3 in the datasheet. + * + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + * + */ +SBC_ErrorCode SBC_Write_RegField(uint8_t SBC_Reg, uint8_t SBC_FieldMsk, uint8_t SBC_FieldPos, uint8_t SBC_FieldVal, uint16_t * returnval); + + +/** + * @brief This method must be called one time at startup of the microcontroller. + * + * This method will initialize all registers of the SBC with the configuration-data of SBC_TLE94x1.h. + * After this, the SBC can be used as normal. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Init(void); + +/* -------------------------------- ISR Functions -------------------------------- */ + + +/** + * @brief This function can register a self-defined function to a specific interrupt-event of the SBC. + * + * Everytime the SBC_ISR() method is called and the associated status-bit is set, it will consider to + * proceed a callback to this function later. + * See all the possible ISR_Vectors in the TLE94x1_ISR.h + * + * + * @param ISR_Vector Definition of the interrupt event. See all possible events in TLE94x1_ISR.h + * + * @param *Callback_Handler Pointer to the function which will be called back. + * The function must accept a uint8_t as first argument. + */ +void SBC_Register_Callback(uint32_t ISR_Vector, void (*Callback_Handler)(uint8_t callbackHandler)); + + +/** + * @brief Interrupt Service Routine for handling interrupts. + * + * This method must be called automatically everytime a rising-edge on the INTN pin is recognized. + * In case, the INTN pin is not connected, this method can also be called periodically by the user during runtime. + * The ISR will proceed a readout of all registered interrupts. If a status-bit of a registered interrupt is set, + * it will initiate a callback to the registered function and give the registered function the status-register value + * as a parameter. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_ISR(void); + + + +/* -------------------------------- API Calls ----------------------------------- */ + +/** + * @brief Enters SBC normal mode + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Mode_Normal(void); + + +/** + * @brief Enters SBC stop mode + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Mode_Stop(void); + + +/** + * @brief Clears all wake status registers and enter SBC sleep mode. Depending on configuration also the selective-wake feature will be initialized + * before entering sleep mode. In case, the SWK option is enabled and the internal CAN protocol handler is not in sync when calling this function, + * the sleep mode will be not entered. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Mode_Sleep(void); + + +/** + * @brief Sets the duty-cycle of the internal PWM generator + * + * @param PWM_DC Set the duty-cycle with values of 0-255 for 0% to 100% + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Set_DutyCycle_PWM(uint8_t PWM_DC); + + +/** + * @brief Sets the OnTime of the internal timer. + * + * @param OnTime On time which will be configured to the timer. See TLE94x1_DEFINES.h for enumerations. + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Set_Timer_On(uint8_t OnTime); + +/** + * @brief Sets the Period time of the internal timer + * + * @param Period Period time which will be configured to the timer. See TLE94x1_DEFINES.h for enumerations. + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Set_Timer_Period(uint8_t Period); + + +/** + * @brief FO output activated by software for testing. Only working if FO/GPIO is configured as FO + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_FO_Test_On(void); + + +/** + * @brief FO output deactivated by software for testing. Only working if FO/GPIO is configured as FO + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_FO_Test_Off(void); + + +/** + * @brief Charge-Pump (VCP-Pin) is enabled. See chapter 5.3 in datasheet. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_CP_On(void); + + +/** + * @brief Charge-Pump (VCP-Pin) is disabled. See chapter 5.3 in datasheet. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_CP_Off(void); + + +/** + * @brief Enable Voltage Sensing. No wake-up events are generated. See chapter 9.2.4 in datasheet. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_WK_MEAS_On(void); + + +/** + * @brief Disable Voltage Sensing and enable wake-up functionality. See chapter 9.2.4 in datasheet. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_WK_MEAS_Off(void); + + +/** + * @brief WK is enabled as wake source. See chapter 5.2. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_TIMER_WK_EN_On(void); + + +/** + * @brief WK wake-up disabled. See chapter 5.2. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_TIMER_WK_EN_Off(void); + + +/** + * @brief Reads System Status Control, both lower and higher bits. See page 138 in datasheet. + * + * @retval Upper 8 bit are read from register SBC_SYS_STATUS_CTRL_1 and the lower 8 bit from SBC_SYS_STATUS_CTRL_0 + */ +uint16_t SBC_SYS_STAT_Read(void); + + +/** + * @brief Writes System Status Control, both lower and higher bits. See page 138 in datasheet. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_SYS_STAT_Write(uint16_t SystemStatus); + + +/** + * @brief Locks CP_EN, GPIO configuration and 'rwl'-bits. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Lock_Configuration(void); + + +/** + * @brief Unlocks CP_EN, GPIO configuration and 'rwl'-bits. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Unlock_Configuration(void); + + +/** + * @brief Clears both Wake Status registers. + * + * @retval SBC_ErrorCode See description of SBC_ErrorCode. + */ +SBC_ErrorCode SBC_Clear_Wake_Status(void); + +#endif /*TLE94x1_H*/ diff --git a/cva_bootloader_m0118/src/TLE9461/TLE94x1_DEFINES.h b/cva_bootloader_m0118/src/TLE9461/TLE94x1_DEFINES.h new file mode 100644 index 0000000..57d8ab2 --- /dev/null +++ b/cva_bootloader_m0118/src/TLE9461/TLE94x1_DEFINES.h @@ -0,0 +1,3248 @@ +/********************************************************************************************************************* + * Copyright (c) 2019, Infineon Technologies AG + * + * + * Distributed under the Boost Software License, Version 1.0. + * + * + * Boost Software License - Version 1.0 - August 17th, 2003 + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *********************************************************************************************************************/ + + +/****************************************************************************************************//** + * @file TLE94x1_DEFINES.h + * + * @brief Main header declaration file for TLE94x1 SBC family device + * + * @version V1.0.0 + * @date 15. April 2019 + * @author Markus Noll / markus.noll@infineon.com + * @author Yannek Micha Rixen / Yannek.Rixen@infineon.com + *******************************************************************************************************/ + + + +#ifndef TLE94x1_DEFINES_H +#define TLE94x1_DEFINES_H + + + + + + +/* ================================================================================ */ +/* ================ General Control Registers ================ */ +/* ================================================================================ */ + + + +/** + * @def SBC_M_S_CTRL + * + * @brief Control register address. + */ +#define SBC_M_S_CTRL (0b00000001U) + +/** + * @def SBC_HW_CTRL_0 + * + * @brief Control register address. + */ +#define SBC_HW_CTRL_0 (0b00000010U) + +/** + * @def SBC_WD_CTRL + * + * @brief Control register address. + */ +#define SBC_WD_CTRL (0b00000011U) + +/** + * @def SBC_BUS_CTRL_0 + * + * @brief Control register address. + */ +#define SBC_BUS_CTRL_0 (0b00000100U) + +/** + * @def SBC_WK_CTRL_0 + * + * @brief Control register address. + */ +#define SBC_WK_CTRL_0 (0b00000110U) + +/** + * @def SBC_WK_CTRL_1 + * + * @brief Control register address. + */ +#define SBC_WK_CTRL_1 (0b00000111U) + +/** + * @def SBC_WK_PUPD_CTRL + * + * @brief Control register address. + */ +#define SBC_WK_PUPD_CTRL (0b00001000U) + +/** + * @def SBC_BUS_CTRL_3 + * + * @brief Control register address. + */ +#define SBC_BUS_CTRL_3 (0b00001011U) + +/** + * @def SBC_TIMER_CTRL + * + * @brief Control register address. + */ +#define SBC_TIMER_CTRL (0b00001100U) + +/** + * @def SBC_HW_CTRL_1 + * + * @brief Control register address. + */ +#define SBC_HW_CTRL_1 (0b00001110U) + +/** + * @def SBC_HW_CTRL_2 + * + * @brief Control register address. + */ +#define SBC_HW_CTRL_2 (0b00001111U) + +/** + * @def SBC_GPIO_CTRL + * + * @brief Control register address. + */ +#define SBC_GPIO_CTRL (0b00010111U) + +/** + * @def SBC_PWM_CTRL + * + * @brief Control register address. + */ +#define SBC_PWM_CTRL (0b00011000U) + +/** + * @def SBC_PWM_FREQ_CTRL + * + * @brief Control register address. + */ +#define SBC_PWM_FREQ_CTRL (0b00011100U) + +/** + * @def SBC_HW_CTRL_3 + * + * @brief Control register address. + */ +#define SBC_HW_CTRL_3 (0b00011101U) + +/** + * @def SBC_SYS_STATUS_CTRL_0 + * + * @brief Control register address. + */ +#define SBC_SYS_STATUS_CTRL_0 (0b00011110U) + +/** + * @def SBC_SYS_STATUS_CTRL_1 + * + * @brief Control register address. + */ +#define SBC_SYS_STATUS_CTRL_1 (0b00011111U) + + + + + + +/* ================================================================================ */ +/* ================ Selective Wake Control Registers ================ */ +/* ================================================================================ */ + + + +/** + * @def SBC_SWK_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_CTRL (0b00100000U) + +/** + * @def SBC_SWK_BTL0_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_BTL0_CTRL (0b00100001U) + +/** + * @def SBC_SWK_BTL1_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_BTL1_CTRL (0b00100010U) + +/** + * @def SBC_SWK_ID3_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_ID3_CTRL (0b00100011U) + +/** + * @def SBC_SWK_ID2_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_ID2_CTRL (0b00100100U) + +/** + * @def SBC_SWK_ID1_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_ID1_CTRL (0b00100101U) + +/** + * @def SBC_SWK_ID0_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_ID0_CTRL (0b00100110U) + +/** + * @def SBC_SWK_MASK_ID3_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_MASK_ID3_CTRL (0b00100111U) + +/** + * @def SBC_SWK_MASK_ID2_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_MASK_ID2_CTRL (0b00101000U) + +/** + * @def SBC_SWK_MASK_ID1_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_MASK_ID1_CTRL (0b00101001U) + +/** + * @def SBC_SWK_MASK_ID0_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_MASK_ID0_CTRL (0b00101010U) + +/** + * @def SBC_SWK_DLC_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_DLC_CTRL (0b00101011U) + +/** + * @def SBC_SWK_DATA7_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_DATA7_CTRL (0b00101100U) + +/** + * @def SBC_SWK_DATA6_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_DATA6_CTRL (0b00101101U) + +/** + * @def SBC_SWK_DATA5_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_DATA5_CTRL (0b00101110U) + +/** + * @def SBC_SWK_DATA4_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_DATA4_CTRL (0b00101111U) + +/** + * @def SBC_SWK_DATA3_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_DATA3_CTRL (0b00110000U) + +/** + * @def SBC_SWK_DATA2_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_DATA2_CTRL (0b00110001U) + +/** + * @def SBC_SWK_DATA1_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_DATA1_CTRL (0b00110010U) + +/** + * @def SBC_SWK_DATA0_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_DATA0_CTRL (0b00110011U) + +/** + * @def SBC_SWK_CAN_FD_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_CAN_FD_CTRL (0b00110100U) + +/** + * @def SBC_SWK_OSC_TRIM_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_OSC_TRIM_CTRL (0b00111000U) + +/** + * @def SBC_SWK_OPT_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_OPT_CTRL (0b00111001U) + +/** + * @def SBC_SWK_OSC_CAL_H_STAT + * + * @brief Selective wake register address. + */ +#define SBC_SWK_OSC_CAL_H_STAT (0b00111010U) + +/** + * @def SBC_SWK_OSC_CAL_L_STAT + * + * @brief Selective wake register address. + */ +#define SBC_SWK_OSC_CAL_L_STAT (0b00111011U) + +/** + * @def SBC_SWK_CDR_CTRL1 + * + * @brief Selective wake register address. + */ +#define SBC_SWK_CDR_CTRL1 (0b00111100U) + +/** + * @def SBC_SWK_CDR_CTRL2 + * + * @brief Selective wake register address. + */ +#define SBC_SWK_CDR_CTRL2 (0b00111101U) + +/** + * @def SBC_SWK_CDR_LIMIT_HIGH_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_CDR_LIMIT_HIGH_CTRL (0b00111110U) + +/** + * @def SBC_SWK_CDR_LIMIT_LOW_CTRL + * + * @brief Selective wake register address. + */ +#define SBC_SWK_CDR_LIMIT_LOW_CTRL (0b00111111U) + + + + + + +/* ================================================================================ */ +/* ================ General Status Registers ================ */ +/* ================================================================================ */ + + + + +/** + * @def SBC_SUP_STAT_1 + * + * @brief Status register address. + */ +#define SBC_SUP_STAT_1 (0b01000000U) + +/** + * @def SBC_SUP_STAT_0 + * + * @brief Status register address. + */ +#define SBC_SUP_STAT_0 (0b01000001U) + +/** + * @def SBC_THERM_STAT + * + * @brief Status register address. + */ +#define SBC_THERM_STAT (0b01000010U) + +/** + * @def SBC_DEV_STAT + * + * @brief Status register address. + */ +#define SBC_DEV_STAT (0b01000011U) + +/** + * @def SBC_BUS_STAT + * + * @brief Status register address. + */ +#define SBC_BUS_STAT (0b01000100U) + +/** + * @def SBC_WK_STAT_0 + * + * @brief Status register address. + */ +#define SBC_WK_STAT_0 (0b01000110U) + +/** + * @def SBC_WK_STAT_1 + * + * @brief Status register address. + */ +#define SBC_WK_STAT_1 (0b01000111U) + +/** + * @def SBC_WK_LVL_STAT + * + * @brief Status register address. + */ +#define SBC_WK_LVL_STAT (0b01001000U) + +/** + * @def SBC_GPIO_OC_STAT + * + * @brief Status register address. + */ +#define SBC_GPIO_OC_STAT (0b01010100U) + +/** + * @def SBC_GPIO_OL_STAT + * + * @brief Status register address. + */ +#define SBC_GPIO_OL_STAT (0b01010101U) + + + + + + +/* ================================================================================ */ +/* ================ Selective Wake Status Registers ================ */ +/* ================================================================================ */ + + + + +/** + * @def SBC_SWK_STAT + * + * @brief Selective wake status register address. + */ +#define SBC_SWK_STAT (0b01110000U) + +/** + * @def SBC_SWK_ECNT_STAT + * + * @brief Selective wake status register address. + */ +#define SBC_SWK_ECNT_STAT (0b01110001U) + +/** + * @def SBC_SWK_CDR_STAT1 + * + * @brief Selective wake status register address. + */ +#define SBC_SWK_CDR_STAT1 (0b01110010U) + +/** + * @def SBC_SWK_CDR_STAT2 + * + * @brief Selective wake status register address. + */ +#define SBC_SWK_CDR_STAT2 (0b01110011U) + +/** + * @def SBC_FAM_PROD_STAT + * + * @brief Selective wake status register address. + */ +#define SBC_FAM_PROD_STAT (0b01111110U) + + + + + + +/* ================================================================================ */ +/* ============ General Control Registers Position & Mask ================ */ +/* ================================================================================ */ + + + +/* -------------------------------- M_S_CTRL ------------------------------------ */ + +/** + * @def SBC_M_S_CTRL_MODE_Pos + * + * @brief Control register bit position. + */ +#define SBC_M_S_CTRL_MODE_Pos (6U) +/** + * @def SBC_M_S_CTRL_MODE_Msk + * + * @brief Control register bit mask. + */ +#define SBC_M_S_CTRL_MODE_Msk (0b11000000U) +/** + * @def SBC_M_S_CTRL_VCC2_ON_Pos + * + * @brief Control register bit position. + */ +#define SBC_M_S_CTRL_VCC2_ON_Pos (3U) +/** + * @def SBC_M_S_CTRL_VCC2_ON_Msk + * + * @brief Control register bit mask. + */ +#define SBC_M_S_CTRL_VCC2_ON_Msk (0b00011000U) +/** + * @def SBC_M_S_CTRL_VCC1_OV_RST_Pos + * + * @brief Control register bit position. + */ +#define SBC_M_S_CTRL_VCC1_OV_RST_Pos (2U) +/** + * @def SBC_M_S_CTRL_VCC1_OV_RST_Msk + * + * @brief Control register bit mask. + */ +#define SBC_M_S_CTRL_VCC1_OV_RST_Msk (0b00000100U) +/** + * @def SBC_M_S_CTRL_VCC1_RT_Pos + * + * @brief Control register bit position. + */ +#define SBC_M_S_CTRL_VCC1_RT_Pos (0U) +/** + * @def SBC_M_S_CTRL_VCC1_RT_Msk + * + * @brief Control register bit mask. + */ +#define SBC_M_S_CTRL_VCC1_RT_Msk (0b00000011U) + + +/* -------------------------------- HW_CTRL_0 ----------------------------------- */ + + +/** + * @def SBC_HW_CTRL_0_SOFT_RESET_RST_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_0_SOFT_RESET_RST_Pos (6U) + +/** + * @def SBC_HW_CTRL_0_SOFT_RESET_RST_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_0_SOFT_RESET_RST_Msk (0b01000000U) + +/** + * @def SBC_HW_CTRL_0_FO_ON_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_0_FO_ON_Pos (5U) + +/** + * @def SBC_HW_CTRL_0_FO_ON_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_0_FO_ON_Msk (0b00100000U) + +/** + * @def SBC_HW_CTRL_0_CP_EN_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_0_CP_EN_Pos (2U) + +/** + * @def SBC_HW_CTRL_0_CP_EN_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_0_CP_EN_Msk (0b00000100U) + +/** + * @def SBC_HW_CTRL_0_CFG1_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_0_CFG1_Pos (0U) + +/** + * @def SBC_HW_CTRL_0_CFG1_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_0_CFG1_Msk (0b00000001U) + + +/* -------------------------------- WD_CTRL ----------------------------------- */ + + +/** + * @def SBC_WD_CTRL_CHECKSUM_Pos + * + * @brief Control register bit position. + */ +#define SBC_WD_CTRL_CHECKSUM_Pos (7U) + +/** + * @def SBC_WD_CTRL_CHECKSUM_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WD_CTRL_CHECKSUM_Msk (0b10000000U) + +/** + * @def SBC_WD_CTRL_WD_STM_EN_0_Pos + * + * @brief Control register bit position. + */ +#define SBC_WD_CTRL_WD_STM_EN_0_Pos (6U) + +/** + * @def SBC_WD_CTRL_WD_STM_EN_0_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WD_CTRL_WD_STM_EN_0_Msk (0b01000000U) + +/** + * @def SBC_WD_CTRL_WD_WIN_Pos + * + * @brief Control register bit position. + */ +#define SBC_WD_CTRL_WD_WIN_Pos (5U) + +/** + * @def SBC_WD_CTRL_WD_WIN_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WD_CTRL_WD_WIN_Msk (0b00100000U) + +/** + * @def SBC_WD_CTRL_WD_EN_WK_BUS_Pos + * + * @brief Control register bit position. + */ +#define SBC_WD_CTRL_WD_EN_WK_BUS_Pos (4U) + +/** + * @def SBC_WD_CTRL_WD_EN_WK_BUS_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WD_CTRL_WD_EN_WK_BUS_Msk (0b00010000U) + +/** + * @def SBC_WD_CTRL_WD_TIMER_Pos + * + * @brief Control register bit position. + */ +#define SBC_WD_CTRL_WD_TIMER_Pos (0U) + +/** + * @def SBC_WD_CTRL_WD_TIMER_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WD_CTRL_WD_TIMER_Msk (0b00000111U) + + +/* -------------------------------- BUS_CTRL_0 ---------------------------------- */ + +/** + * @def SBC_BUS_CTRL_0_CAN_Pos + * + * @brief Control register bit position. + */ +#define SBC_BUS_CTRL_0_CAN_Pos (0U) + +/** + * @def SBC_BUS_CTRL_0_CAN_Msk + * + * @brief Control register bit mask. + */ +#define SBC_BUS_CTRL_0_CAN_Msk (0b00000111U) + + +/* -------------------------------- WK_CTRL_0 ----------------------------------- */ + +/** + * @def SBC_WK_CTRL_0_TIMER_WK_EN_Pos + * + * @brief Control register bit position. + */ +#define SBC_WK_CTRL_0_TIMER_WK_EN_Pos (6U) + +/** + * @def SBC_WK_CTRL_0_TIMER_WK_EN_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WK_CTRL_0_TIMER_WK_EN_Msk (0b01000000U) + +/** + * @def SBC_WK_CTRL_0_WD_STM_EN_1_Pos + * + * @brief Control register bit position. + */ +#define SBC_WK_CTRL_0_WD_STM_EN_1_Pos (2U) + +/** + * @def SBC_WK_CTRL_0_WD_STM_EN_1_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WK_CTRL_0_WD_STM_EN_1_Msk (0b00000100U) + + +/* -------------------------------- WK_CTRL_1 ----------------------------------- */ + + +/** + * @def SBC_WK_CTRL_1_INT_GLOBAL_Pos + * + * @brief Control register bit position. + */ +#define SBC_WK_CTRL_1_INT_GLOBAL_Pos (7U) + +/** + * @def SBC_WK_CTRL_1_INT_GLOBAL_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WK_CTRL_1_INT_GLOBAL_Msk (0b10000000U) + +/** + * @def SBC_WK_CTRL_1_WK_MEAS_Pos + * + * @brief Control register bit position. + */ +#define SBC_WK_CTRL_1_WK_MEAS_Pos (5U) + +/** + * @def SBC_WK_CTRL_1_WK_MEAS_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WK_CTRL_1_WK_MEAS_Msk (0b00100000U) + +/** + * @def SBC_WK_CTRL_1_WK_EN_Pos + * + * @brief Control register bit position. + */ +#define SBC_WK_CTRL_1_WK_EN_Pos (0U) + +/** + * @def SBC_WK_CTRL_1_WK_EN_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WK_CTRL_1_WK_EN_Msk (0b00000001U) + + +/* -------------------------------- WK_PUPD_CTRL -------------------------------- */ + + +/** + * @def SBC_WK_PUPD_CTRL_GPIO_WK_PUPD_Pos + * + * @brief Control register bit position. + */ +#define SBC_WK_PUPD_CTRL_GPIO_WK_PUPD_Pos (6U) + +/** + * @def SBC_WK_PUPD_CTRL_GPIO_WK_PUPD_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WK_PUPD_CTRL_GPIO_WK_PUPD_Msk (0b11000000U) + +/** + * @def SBC_WK_PUPD_CTRL_WK_PUPD_Pos + * + * @brief Control register bit position. + */ +#define SBC_WK_PUPD_CTRL_WK_PUPD_Pos (0U) + +/** + * @def SBC_WK_PUPD_CTRL_WK_PUPD_Msk + * + * @brief Control register bit mask. + */ +#define SBC_WK_PUPD_CTRL_WK_PUPD_Msk (0b00000011U) + + +/* ------------------------------- BUS_CTRL_3 ---------------------------------- */ + +/** + * @def SBC_BUS_CTRL_3_CAN_FLASH_Pos + * + * @brief Control register bit position. + */ +#define SBC_BUS_CTRL_3_CAN_FLASH_Pos (4U) + +/** + * @def SBC_BUS_CTRL_3_CAN_FLASH_Msk + * + * @brief Control register bit mask. + */ +#define SBC_BUS_CTRL_3_CAN_FLASH_Msk (0b00010000U) + + +/* ------------------------------- TIMER_CTRL ---------------------------------- */ + + +/** + * @def SBC_TIMER_CTRL_TIMER_ON_Pos + * + * @brief Control register bit position. + */ +#define SBC_TIMER_CTRL_TIMER_ON_Pos (4U) + +/** + * @def SBC_TIMER_CTRL_TIMER_ON_Msk + * + * @brief Control register bit mask. + */ +#define SBC_TIMER_CTRL_TIMER_ON_Msk (0b01110000U) + +/** + * @def SBC_TIMER_CTRL_TIMER_PER_Pos + * + * @brief Control register bit position. + */ +#define SBC_TIMER_CTRL_TIMER_PER_Pos (0U) + +/** + * @def SBC_TIMER_CTRL_TIMER_PER_Msk + * + * @brief Control register bit mask. + */ +#define SBC_TIMER_CTRL_TIMER_PER_Msk (0b00001111U) + + +/* -------------------------------- HW_CTRL_1 ----------------------------------- */ + + +/** + * @def SBC_HW_CTRL_1_RSTN_HYS_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_1_RSTN_HYS_Pos (7U) + +/** + * @def SBC_HW_CTRL_1_RSTN_HYS_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_1_RSTN_HYS_Msk (0b10000000U) + +/** + * @def SBC_HW_CTRL_1_TSD2_DEL_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_1_TSD2_DEL_Pos (5U) + +/** + * @def SBC_HW_CTRL_1_TSD2_DEL_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_1_TSD2_DEL_Msk (0b00100000U) + +/** + * @def SBC_HW_CTRL_1_RSTN_DEL_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_1_RSTN_DEL_Pos (4U) + +/** + * @def SBC_HW_CTRL_1_RSTN_DEL_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_1_RSTN_DEL_Msk (0b00010000U) + +/** + * @def SBC_HW_CTRL_1_CFG_LOCK_0_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_1_CFG_LOCK_0_Pos (3U) + +/** + * @def SBC_HW_CTRL_1_CFG_LOCK_0_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_1_CFG_LOCK_0_Msk (0b00001000U) + + +/* -------------------------------- HW_CTRL_2 ----------------------------------- */ + + +/** + * @def SBC_HW_CTRL_2_2MHZ_FREQ_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_2_2MHZ_FREQ_Pos (5U) + +/** + * @def SBC_HW_CTRL_2_2MHZ_FREQ_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_2_2MHZ_FREQ_Msk (0b11100000U) + +/** + * @def SBC_HW_CTRL_2_I_PEAK_TH_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_2_I_PEAK_TH_Pos (4U) + +/** + * @def SBC_HW_CTRL_2_I_PEAK_TH_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_2_I_PEAK_TH_Msk (0b00010000U) + +/** + * @def SBC_HW_CTRL_2_SS_MOD_FR_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_2_SS_MOD_FR_Pos (2U) + +/** + * @def SBC_HW_CTRL_2_SS_MOD_FR_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_2_SS_MOD_FR_Msk (0b00001100U) + +/** + * @def SBC_HW_CTRL_2_CFG_LOCK_1_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_2_CFG_LOCK_1_Pos (0U) + +/** + * @def SBC_HW_CTRL_2_CFG_LOCK_1_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_2_CFG_LOCK_1_Msk (0b00000001U) + + +/* -------------------------------- GPIO_CTRL ----------------------------------- */ + +/** + * @def SBC_GPIO_CTRL_GPIO_Pos + * + * @brief Control register bit position. + */ +#define SBC_GPIO_CTRL_GPIO_Pos (0U) + +/** + * @def SBC_GPIO_CTRL_GPIO_Msk + * + * @brief Control register bit mask. + */ +#define SBC_GPIO_CTRL_GPIO_Msk (0b00000111U) + + +/* -------------------------------- PWM_CTRL -------------------------------------- */ + +/** + * @def SBC_PWM_DC_PWM_DC_Pos + * + * @brief Control register bit position. + */ +#define SBC_PWM_CTRL_PWM_DC_Pos (0U) + +/** + * @def SBC_PWM_DC_PWM_DC_Msk + * + * @brief Control register bit mask. + */ +#define SBC_PWM_CTRL_PWM_DC_Msk (0b11111111U) + + +/* -------------------------------- PWM_FREQ_CTRL -------------------------------------- */ + +/** + * @def SBC_PWM_FREQ_CTRL_PWM_FREQ_Pos + * + * @brief Control register bit position. + */ +#define SBC_PWM_FREQ_CTRL_PWM_FREQ_Pos (0U) + + +/** + * @def SBC_PWM_FREQ_CTRL_PWM_FREQ_Msk + * + * @brief Control register bit mask. + */ +#define SBC_PWM_FREQ_CTRL_PWM_FREQ_Msk (0b00000011U) + + +/* -------------------------------- HW_CTRL_3 ----------------------------------- */ + + +/** + * @def SBC_HW_CTRL_3_TSD_THR_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_3_TSD_THR_Pos (2U) + +/** + * @def SBC_HW_CTRL_3_TSD_THR_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_3_TSD_THR_Msk (0b00000100U) + +/** + * @def SBC_HW_CTRL_3_ICC1_LIM_ADJ_Pos + * + * @brief Control register bit position. + */ +#define SBC_HW_CTRL_3_ICC1_LIM_ADJ_Pos (0U) + +/** + * @def SBC_HW_CTRL_3_ICC1_LIM_ADJ_Msk + * + * @brief Control register bit mask. + */ +#define SBC_HW_CTRL_3_ICC1_LIM_ADJ_Msk (0b00000011U) + + +/* -------------------------------- SYS_STATUS_CTRL_0 --------------------------- */ + +/** + * @def SBC_SYS_STATUS_CTRL_0_SYS_STAT_L_Pos + * + * @brief Control register bit position. + */ +#define SBC_SYS_STATUS_CTRL_0_SYS_STAT_L_Pos (0U) + +/** + * @def SBC_SYS_STATUS_CTRL_0_SYS_STAT_L_Msk + * + * @brief Control register bit mask. + */ +#define SBC_SYS_STATUS_CTRL_0_SYS_STAT_L_Msk (0b11111111U) + + +/* -------------------------------- SYS_STATUS_CTRL_1 --------------------------- */ + + +/** + * @def SBC_SYS_STATUS_CTRL_0_SYS_STAT_H_Pos + * + * @brief Control register bit position. + */ +#define SBC_SYS_STATUS_CTRL_0_SYS_STAT_H_Pos (0U) + +/** + * @def SBC_SYS_STATUS_CTRL_0_SYS_STAT_H_Msk + * + * @brief Control register bit mask. + */ +#define SBC_SYS_STATUS_CTRL_0_SYS_STAT_H_Msk (0b11111111U) + + + + + + +/* ================================================================================ */ +/* ======== Selective Wake Control Registers Position & Mask ============= */ +/* ================================================================================ */ + + + +/* -------------------------------- SWK_CTRL ------------------------------------ */ + + +/** + * @def SBC_SWK_CTRL_OSC_CAL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CTRL_OSC_CAL_Pos (7U) + +/** + * @def SBC_SWK_CTRL_OSC_CAL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CTRL_OSC_CAL_Msk (0b10000000U) + +/** + * @def SBC_SWK_CTRL_TRIM_EN_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CTRL_TRIM_EN_Pos (5U) + +/** + * @def SBC_SWK_CTRL_TRIM_EN_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CTRL_TRIM_EN_Msk (0b01100000U) + +/** + * @def SBC_SWK_CTRL_CANTO_MASK_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CTRL_CANTO_MASK_Pos (4U) + +/** + * @def SBC_SWK_CTRL_CANTO_MASK_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CTRL_CANTO_MASK_Msk (0b00010000U) + +/** + * @def SBC_SWK_CTRL_CFG_VAL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CTRL_CFG_VAL_Pos (0U) + +/** + * @def SBC_SWK_CTRL_CFG_VAL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CTRL_CFG_VAL_Msk (0b00000001U) + + +/* -------------------------------- SWK_BTL0_CTRL ------------------------------- */ + + +/** + * @def SBC_SWK_BTL0_CTRL_TBIT_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_BTL0_CTRL_TBIT_Pos (0U) + +/** + * @def SBC_SWK_BTL0_CTRL_TBIT_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_BTL0_CTRL_TBIT_Msk (0b11111111U) + + +/* -------------------------------- SWK_BTL1_CTRL ------------------------------- */ + + +/** + * @def SBC_SWK_BTL1_CTRL_SP_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_BTL1_CTRL_SP_Pos (0U) + +/** + * @def SBC_SWK_BTL1_CTRL_SP_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_BTL1_CTRL_SP_Msk (0b00111111U) + + +/* -------------------------------- SWK_ID3_CTRL -------------------------------- */ + + +/** + * @def SBC_SWK_ID3_CTRL_ID28_21_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_ID3_CTRL_ID28_21_Pos (0U) + +/** + * @def SBC_SWK_ID3_CTRL_ID28_21_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_ID3_CTRL_ID28_21_Msk (0b11111111U) + + +/* -------------------------------- SWK_ID2_CTRL -------------------------------- */ + + +/** + * @def SBC_SWK_ID2_CTRL_ID20_13_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_ID2_CTRL_ID20_13_Pos (0U) + +/** + * @def SBC_SWK_ID2_CTRL_ID20_13_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_ID2_CTRL_ID20_13_Msk (0b11111111U) + + +/* -------------------------------- SWK_ID1_CTRL -------------------------------- */ + + +/** + * @def SBC_SWK_ID1_CTRL_ID12_5_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_ID1_CTRL_ID12_5_Pos (0U) + +/** + * @def SBC_SWK_ID1_CTRL_ID12_5_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_ID1_CTRL_ID12_5_Msk (0b11111111U) + + +/* -------------------------------- SWK_ID0_CTRL -------------------------------- */ + + +/** + * @def SBC_SWK_ID0_CTRL_ID4_0_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_ID0_CTRL_ID4_0_Pos (2U) + +/** + * @def SBC_SWK_ID0_CTRL_ID4_0_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_ID0_CTRL_ID4_0_Msk (0b01111100U) + +/** + * @def SBC_SWK_ID0_CTRL_RTR_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_ID0_CTRL_RTR_Pos (1U) + +/** + * @def SBC_SWK_ID0_CTRL_RTR_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_ID0_CTRL_RTR_Msk (0b00000010U) + +/** + * @def SBC_SWK_ID0_CTRL_IDE_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_ID0_CTRL_IDE_Pos (0U) + +/** + * @def SBC_SWK_ID0_CTRL_IDE_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_ID0_CTRL_IDE_Msk (0b00000001U) + + +/* -------------------------------- SWK_MASK_ID3_CTRL --------------------------- */ + + +/** + * @def SBC_SWK_MASK_ID3_CTRL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_MASK_ID3_CTRL_Pos (0U) + +/** + * @def SBC_SWK_MASK_ID3_CTRL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_MASK_ID3_CTRL_Msk (0b11111111U) + + +/* -------------------------------- SWK_MASK_ID2_CTRL --------------------------- */ + + +/** + * @def SBC_SWK_MASK_ID2_CTRL_MASK_ID20_13_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_MASK_ID2_CTRL_MASK_ID20_13_Pos (0U) + +/** + * @def SBC_SWK_MASK_ID2_CTRL_MASK_ID20_13_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_MASK_ID2_CTRL_MASK_ID20_13_Msk (0b11111111U) + + +/* -------------------------------- SWK_MASK_ID1_CTRL --------------------------- */ + + +/** + * @def SBC_SWK_MASK_ID1_CTRL_MASK_ID12_5_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_MASK_ID1_CTRL_MASK_ID12_5_Pos (0U) + +/** + * @def SBC_SWK_MASK_ID1_CTRL_MASK_ID12_5_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_MASK_ID1_CTRL_MASK_ID12_5_Msk (0b11111111U) + + +/* -------------------------------- SWK_MASK_ID0_CTRL --------------------------- */ + + +/** + * @def SBC_SWK_MASK_ID0_CTRL_MASK_ID4_0_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_MASK_ID0_CTRL_MASK_ID4_0_Pos (2U) + +/** + * @def SBC_SWK_MASK_ID0_CTRL_MASK_ID4_0_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_MASK_ID0_CTRL_MASK_ID4_0_Msk (0b01111100U) + + +/* -------------------------------- SWK_DLC_CTRL -------------------------------- */ + + +/** + * @def SBC_SWK_DLC_CTRL_DLC_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_DLC_CTRL_DLC_Pos (0U) + +/** + * @def SBC_SWK_DLC_CTRL_DLC_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_DLC_CTRL_DLC_Msk (0b00001111U) + + +/* -------------------------------- SWK_DATA7_CTRL ------------------------------ */ + + +/** + * @def SBC_SWK_DATA7_CTRL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_DATA7_CTRL_Pos (0U) + +/** + * @def SBC_SWK_DATA7_CTRL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_DATA7_CTRL_Msk (0b11111111U) + + +/* -------------------------------- SWK_DATA6_CTRL ------------------------------ */ + + +/** + * @def SBC_SWK_DATA6_CTRL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_DATA6_CTRL_Pos (0U) + +/** + * @def SBC_SWK_DATA6_CTRL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_DATA6_CTRL_Msk (0b11111111U) + + +/* -------------------------------- SWK_DATA5_CTRL ------------------------------ */ + + +/** + * @def SBC_SWK_DATA5_CTRL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_DATA5_CTRL_Pos (0U) + +/** + * @def SBC_SWK_DATA5_CTRL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_DATA5_CTRL_Msk (0b11111111U) + + +/* -------------------------------- SWK_DATA4_CTRL ------------------------------ */ + + +/** + * @def SBC_SWK_DATA4_CTRL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_DATA4_CTRL_Pos (0U) + +/** + * @def SBC_SWK_DATA4_CTRL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_DATA4_CTRL_Msk (0b11111111U) + + +/* -------------------------------- SWK_DATA3_CTRL ------------------------------ */ + + +/** + * @def SBC_SWK_DATA3_CTRL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_DATA3_CTRL_Pos (0U) + +/** + * @def SBC_SWK_DATA3_CTRL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_DATA3_CTRL_Msk (0b11111111U) + + +/* -------------------------------- SWK_DATA2_CTRL ------------------------------ */ + + +/** + * @def SBC_SWK_DATA2_CTRL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_DATA2_CTRL_Pos (0U) + +/** + * @def SBC_SWK_DATA2_CTRL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_DATA2_CTRL_Msk (0b11111111U) + + +/* -------------------------------- SWK_DATA1_CTRL ------------------------------ */ + + +/** + * @def SBC_SWK_DATA1_CTRL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_DATA1_CTRL_Pos (0U) + +/** + * @def SBC_SWK_DATA1_CTRL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_DATA1_CTRL_Msk (0b11111111U) + + +/* -------------------------------- SWK_DATA0_CTRL ------------------------------ */ + + +/** + * @def SBC_SWK_DATA0_CTRL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_DATA0_CTRL_Pos (0U) + +/** + * @def SBC_SWK_DATA0_CTRL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_DATA0_CTRL_Msk (0b11111111U) + + +/* -------------------------------- SWK_CAN_FD_CTRL ----------------------------- */ + + +/** + * @def SBC_SWK_CAN_FD_CTRL_DIS_ERR_CNT_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CAN_FD_CTRL_DIS_ERR_CNT_Pos (5U) + +/** + * @def SBC_SWK_CAN_FD_CTRL_DIS_ERR_CNT_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CAN_FD_CTRL_DIS_ERR_CNT_Msk (0b00100000U) + +/** + * @def SBC_SWK_CAN_FD_CTRL_RX_FILT_BYP_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CAN_FD_CTRL_RX_FILT_BYP_Pos (4U) + +/** + * @def SBC_SWK_CAN_FD_CTRL_RX_FILT_BYP_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CAN_FD_CTRL_RX_FILT_BYP_Msk (0b00010000U) + +/** + * @def SBC_SWK_CAN_FD_CTRL_FD_FILTER_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CAN_FD_CTRL_FD_FILTER_Pos (1U) + +/** + * @def SBC_SWK_CAN_FD_CTRL_FD_FILTER_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CAN_FD_CTRL_FD_FILTER_Msk (0b00001110U) + +/** + * @def SBC_SWK_CAN_FD_CTRL_CAN_FD_EN_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CAN_FD_CTRL_CAN_FD_EN_Pos (0U) + +/** + * @def SBC_SWK_CAN_FD_CTRL_CAN_FD_EN_Msk + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CAN_FD_CTRL_CAN_FD_EN_Msk (0b00000001U) + + +/* -------------------------------- SWK_OSC_TRIM_CTRL --------------------------- */ + + +/** + * @def SBC_SWK_OSC_TRIM_CTRL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_OSC_TRIM_CTRL_Pos (0U) + +/** + * @def SBC_SWK_OSC_TRIM_CTRL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_OSC_TRIM_CTRL_Msk (0b01111111U) + + +/* -------------------------------- SWK_OPT_CTRL -------------------------------- */ + + +/** + * @def SBC_SWK_OPT_CTRL_RX_WK_SEL_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_OPT_CTRL_RX_WK_SEL_Pos (7U) + +/** + * @def SBC_SWK_OPT_CTRL_RX_WK_SEL_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_OPT_CTRL_RX_WK_SEL_Msk (0b10000000U) + + +/* -------------------------------- SWK_OSC_CAL_H_STAT -------------------------- */ + + +/** + * @def SBC_SWK_OSC_CAL_H_STAT_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_OSC_CAL_H_STAT_Pos (0U) + +/** + * @def SBC_SWK_OSC_CAL_H_STAT_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_OSC_CAL_H_STAT_Msk (0b11111111U) + + +/* -------------------------------- SWK_OPT_CAL_L_STAT -------------------------- */ + + +/** + * @def SBC_SWK_OPT_CAL_L_STAT_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_OPT_CAL_L_STAT_Pos (0U) + +/** + * @def SBC_SWK_OPT_CAL_L_STAT_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_OPT_CAL_L_STAT_Msk (0b11111111U) + + +/* -------------------------------- SWK_CDR_CTRL1 ------------------------------- */ + + +/** + * @def SBC_SWK_CDR_CTRL1_SEL_FILT_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CDR_CTRL1_SEL_FILT_Pos (2U) + +/** + * @def SBC_SWK_CDR_CTRL1_SEL_FILT_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CDR_CTRL1_SEL_FILT_Msk (0b00001100U) + +/** + * @def SBC_SWK_CDR_CTRL1_CDR_EN_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CDR_CTRL1_CDR_EN_Pos (0U) + +/** + * @def SBC_SWK_CDR_CTRL1_CDR_EN_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CDR_CTRL1_CDR_EN_Msk (0b00000001U) + + +/* -------------------------------- SWK_CDR_CTRL2 ------------------------------- */ + + +/** + * @def SBC_SWK_CDR_CTRL2_SEL_OSC_CLK_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CDR_CTRL2_SEL_OSC_CLK_Pos (0U) + +/** + * @def SBC_SWK_CDR_CTRL2_SEL_OSC_CLK_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CDR_CTRL2_SEL_OSC_CLK_Msk (0b00000011U) + + +/* -------------------------------- SWK_CDR_LIMIT_HIGH_CTRL --------------------- */ + + +/** + * @def SBC_SWK_CDR_LIMIT_HIGH_CTRL_CDR_LIM_H_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CDR_LIMIT_HIGH_CTRL_CDR_LIM_H_Pos (0U) + +/** + * @def SBC_SWK_CDR_LIMIT_HIGH_CTRL_CDR_LIM_H_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CDR_LIMIT_HIGH_CTRL_CDR_LIM_H_Msk (0b11111111U) + + +/* -------------------------------- SWK_CDR_LIMIT_LOW_CTRL ---------------------- */ + + +/** + * @def SBC_SWK_CDR_LIMIT_LOW_CTRL_CDR_LIM_L_Pos + * + * @brief Selective wake register bit position. + */ +#define SBC_SWK_CDR_LIMIT_LOW_CTRL_CDR_LIM_L_Pos (0U) + +/** + * @def SBC_SWK_CDR_LIMIT_LOW_CTRL_CDR_LIM_L_Msk + * + * @brief Selective wake register bit mask. + */ +#define SBC_SWK_CDR_LIMIT_LOW_CTRL_CDR_LIM_L_Msk (0b11111111U) + + + + + + +/* ================================================================================ */ +/* ============= General Status Registers Position & Mask ================ */ +/* ================================================================================ */ + + + +/* -------------------------------- SUP_STAT_1 ---------------------------------- */ + + +/** + * @def SBC_SUP_STAT_1_VS_UV_Pos + * + * @brief General status register bit position. + */ +#define SBC_SUP_STAT_1_VS_UV_Pos (6U) + +/** + * @def SBC_SUP_STAT_1_VS_UV_Msk + * + * @brief General status register bit mask. + */ +#define SBC_SUP_STAT_1_VS_UV_Msk (0b01000000U) + +/** + * @def SBC_SUP_STAT_1_VS_OV_Pos + * + * @brief General status register bit position. + */ +#define SBC_SUP_STAT_1_VS_OV_Pos (5U) + +/** + * @def SBC_SUP_STAT_1_VS_OV_Msk + * + * @brief General status register bit mask. + */ +#define SBC_SUP_STAT_1_VS_OV_Msk (0b00100000U) + +/** + * @def SBC_SUP_STAT_1_VCC1_OV_Pos + * + * @brief General status register bit position. + */ +#define SBC_SUP_STAT_1_VCC1_OV_Pos (1U) + +/** + * @def SBC_SUP_STAT_1_VCC1_OV_Msk + * + * @brief General status register bit mask. + */ +#define SBC_SUP_STAT_1_VCC1_OV_Msk (0b00000010U) + +/** + * @def SBC_SUP_STAT_1_VCC1_WARN_Pos + * + * @brief General status register bit position. + */ +#define SBC_SUP_STAT_1_VCC1_WARN_Pos (0U) + +/** + * @def SBC_SUP_STAT_1_VCC1_WARN_Msk + * + * @brief General status register bit mask. + */ +#define SBC_SUP_STAT_1_VCC1_WARN_Msk (0b00000001U) + + +/* -------------------------------- SUP_STAT_0 ---------------------------------- */ + + +/** + * @def SBC_SUP_STAT_0_POR_Pos + * + * @brief General status register bit position. + */ +#define SBC_SUP_STAT_0_POR_Pos (7U) + +/** + * @def SBC_SUP_STAT_0_POR_Msk + * + * @brief General status register bit mask. + */ +#define SBC_SUP_STAT_0_POR_Msk (0b10000000U) + +/** + * @def SBC_SUP_STAT_0_VCC2_OT_Pos + * + * @brief General status register bit position. + */ +#define SBC_SUP_STAT_0_VCC2_OT_Pos (4U) + +/** + * @def SBC_SUP_STAT_0_VCC2_OT_Msk + * + * @brief General status register bit mask. + */ +#define SBC_SUP_STAT_0_VCC2_OT_Msk (0b00010000U) + +/** + * @def SBC_SUP_STAT_0_VCC2_UV_Pos + * + * @brief General status register bit position. + */ +#define SBC_SUP_STAT_0_VCC2_UV_Pos (3U) + +/** + * @def SBC_SUP_STAT_0_VCC2_UV_Msk + * + * @brief General status register bit mask. + */ +#define SBC_SUP_STAT_0_VCC2_UV_Msk (0b00001000U) + +/** + * @def SBC_SUP_STAT_0_VCC1_SC_Pos + * + * @brief General status register bit position. + */ +#define SBC_SUP_STAT_0_VCC1_SC_Pos (2U) + +/** + * @def SBC_SUP_STAT_0_VCC1_SC_Msk + * + * @brief General status register bit mask. + */ +#define SBC_SUP_STAT_0_VCC1_SC_Msk (0b00000100U) + +/** + * @def SBC_SUP_STAT_0_VCC1_UV_Pos + * + * @brief General status register bit position. + */ +#define SBC_SUP_STAT_0_VCC1_UV_Pos (0U) + +/** + * @def SBC_SUP_STAT_0_VCC1_UV_Msk + * + * @brief General status register bit mask. + */ +#define SBC_SUP_STAT_0_VCC1_UV_Msk (0b00000001U) + + +/* -------------------------------- THERM_STAT ---------------------------------- */ + + +/** + * @def SBC_THERM_STAT_TSD2_SAFE_Pos + * + * @brief General status register bit position. + */ +#define SBC_THERM_STAT_TSD2_SAFE_Pos (3U) + +/** + * @def SBC_THERM_STAT_TSD2_SAFE_Msk + * + * @brief General status register bit mask. + */ +#define SBC_THERM_STAT_TSD2_SAFE_Msk (0b00001000U) + +/** + * @def SBC_THERM_STAT_TSD2_Pos + * + * @brief General status register bit position. + */ +#define SBC_THERM_STAT_TSD2_Pos (2U) + +/** + * @def SBC_THERM_STAT_TSD2_Msk + * + * @brief General status register bit mask. + */ +#define SBC_THERM_STAT_TSD2_Msk (0b00000100U) + +/** + * @def SBC_THERM_STAT_TSD1_Pos + * + * @brief General status register bit position. + */ +#define SBC_THERM_STAT_TSD1_Pos (1U) + +/** + * @def SBC_THERM_STAT_TSD1_Msk + * + * @brief General status register bit mask. + */ +#define SBC_THERM_STAT_TSD1_Msk (0b00000010U) + +/** + * @def SBC_THERM_STAT_TPW_Pos + * + * @brief General status register bit position. + */ +#define SBC_THERM_STAT_TPW_Pos (0U) + +/** + * @def SBC_THERM_STAT_TPW_Msk + * + * @brief General status register bit mask. + */ +#define SBC_THERM_STAT_TPW_Msk (0b00000001U) + + +/* -------------------------------- DEV_STAT ------------------------------------ */ + + +/** + * @def SBC_DEV_STAT_DEV_STAT_Pos + * + * @brief General status register bit position. + */ +#define SBC_DEV_STAT_DEV_STAT_Pos (6U) + +/** + * @def SBC_DEV_STAT_DEV_STAT_Msk + * + * @brief General status register bit mask. + */ +#define SBC_DEV_STAT_DEV_STAT_Msk (0b11000000U) + +/** + * @def SBC_DEV_STAT_WD_FAIL_Pos + * + * @brief General status register bit position. + */ +#define SBC_DEV_STAT_WD_FAIL_Pos (2U) + +/** + * @def SBC_DEV_STAT_WD_FAIL_Msk + * + * @brief General status register bit mask. + */ +#define SBC_DEV_STAT_WD_FAIL_Msk (0b00001100U) + +/** + * @def SBC_DEV_STAT_SPI_FAIL_Pos + * + * @brief General status register bit position. + */ +#define SBC_DEV_STAT_SPI_FAIL_Pos (1U) + +/** + * @def SBC_DEV_STAT_SPI_FAIL_Msk + * + * @brief General status register bit mask. + */ +#define SBC_DEV_STAT_SPI_FAIL_Msk (0b00000010U) + +/** + * @def SBC_DEV_STAT_FAILURE_Pos + * + * @brief General status register bit position. + */ +#define SBC_DEV_STAT_FAILURE_Pos (0U) + +/** + * @def SBC_DEV_STAT_FAILURE_Msk + * + * @brief General status register bit mask. + */ +#define SBC_DEV_STAT_FAILURE_Msk (0b00000001U) + + +/* -------------------------------- BUS_STAT ------------------------------------ */ + + +/** + * @def SBC_BUS_STAT_CANTO_Pos + * + * @brief General status register bit position. + */ +#define SBC_BUS_STAT_CANTO_Pos (4U) + +/** + * @def SBC_BUS_STAT_CANTO_Msk + * + * @brief General status register bit mask. + */ +#define SBC_BUS_STAT_CANTO_Msk (0b00010000U) + +/** + * @def SBC_BUS_STAT_SYSERR_Pos + * + * @brief General status register bit position. + */ +#define SBC_BUS_STAT_SYSERR_Pos (3U) + +/** + * @def SBC_BUS_STAT_SYSERR_Msk + * + * @brief General status register bit mask. + */ +#define SBC_BUS_STAT_SYSERR_Msk (0b00001000U) + +/** + * @def SBC_BUS_STAT_CAN_FAIL_Pos + * + * @brief General status register bit position. + */ +#define SBC_BUS_STAT_CAN_FAIL_Pos (1U) + +/** + * @def SBC_BUS_STAT_CAN_FAIL_Msk + * + * @brief General status register bit mask. + */ +#define SBC_BUS_STAT_CAN_FAIL_Msk (0b00000110U) + +/** + * @def SBC_BUS_STAT_VCAN_UV_Pos + * + * @brief General status register bit position. + */ +#define SBC_BUS_STAT_VCAN_UV_Pos (0U) + +/** + * @def SBC_BUS_STAT_VCAN_UV_Msk + * + * @brief General status register bit mask. + */ +#define SBC_BUS_STAT_VCAN_UV_Msk (0b00000001U) + + +/* -------------------------------- WK_STAT_0 ----------------------------------- */ + + +/** + * @def SBC_WK_STAT_0_CAN_WU_Pos + * + * @brief General status register bit position. + */ +#define SBC_WK_STAT_0_CAN_WU_Pos (5U) + +/** + * @def SBC_WK_STAT_0_CAN_WU_Msk + * + * @brief General status register bit mask. + */ +#define SBC_WK_STAT_0_CAN_WU_Msk (0b00100000U) + +/** + * @def SBC_WK_STAT_0_TIMER_WU_Pos + * + * @brief General status register bit position. + */ +#define SBC_WK_STAT_0_TIMER_WU_Pos (4U) + +/** + * @def SBC_WK_STAT_0_TIMER_WU_Msk + * + * @brief General status register bit mask. + */ +#define SBC_WK_STAT_0_TIMER_WU_Msk (0b00010000U) + +/** + * @def SBC_WK_STAT_0_WK_WU_Pos + * + * @brief General status register bit position. + */ +#define SBC_WK_STAT_0_WK_WU_Pos (0U) + +/** + * @def SBC_WK_STAT_0_WK_WU_Msk + * + * @brief General status register bit mask. + */ +#define SBC_WK_STAT_0_WK_WU_Msk (0b00000001U) + + +/* -------------------------------- WK_STAT_1 ----------------------------------- */ + + +/** + * @def SBC_WK_STAT_1_GPIO_WK_WU_Pos + * + * @brief General status register bit position. + */ +#define SBC_WK_STAT_1_GPIO_WK_WU_Pos (4U) + +/** + * @def SBC_WK_STAT_1_GPIO_WK_WU_Msk + * + * @brief General status register bit mask. + */ +#define SBC_WK_STAT_1_GPIO_WK_WU_Msk (0b00010000U) + + +/* -------------------------------- WK_LVL_STAT --------------------------------- */ + + +/** + * @def SBC_WK_LVL_STAT_SBC_DEV_LVL_Pos + * + * @brief General status register bit position. + */ +#define SBC_WK_LVL_STAT_SBC_DEV_LVL_Pos (7U) + +/** + * @def SBC_WK_LVL_STAT_SBC_DEV_LVL_Msk + * + * @brief General status register bit mask. + */ +#define SBC_WK_LVL_STAT_SBC_DEV_LVL_Msk (0b10000000U) + +/** + * @def SBC_WK_LVL_STAT_CFG0_STATE_Pos + * + * @brief General status register bit position. + */ +#define SBC_WK_LVL_STAT_CFG0_STATE_Pos (6U) + +/** + * @def SBC_WK_LVL_STAT_CFG0_STATE_Msk + * + * @brief General status register bit mask. + */ +#define SBC_WK_LVL_STAT_CFG0_STATE_Msk (0b01000000U) + +/** + * @def SBC_WK_LVL_STAT_GPIO_LVL_Pos + * + * @brief General status register bit position. + */ +#define SBC_WK_LVL_STAT_GPIO_LVL_Pos (4U) + +/** + * @def SBC_WK_LVL_STAT_GPIO_LVL_Msk + * + * @brief General status register bit mask. + */ +#define SBC_WK_LVL_STAT_GPIO_LVL_Msk (0b00010000U) + +/** + * @def SBC_WK_LVL_STAT_WK_LVL_Pos + * + * @brief General status register bit position. + */ +#define SBC_WK_LVL_STAT_WK_LVL_Pos (0U) + +/** + * @def SBC_WK_LVL_STAT_WK_LVL_Msk + * + * @brief General status register bit mask. + */ +#define SBC_WK_LVL_STAT_WK_LVL_Msk (0b00000001U) + + +/* -------------------------------- GPIO_OC_STAT -------------------------------- */ + + +/** + * @def SBC_GPIO_OC_STAT_GPIO_OC_Pos + * + * @brief General status register bit position. + */ +#define SBC_GPIO_OC_STAT_GPIO_OC_Pos (6U) + +/** + * @def SBC_GPIO_OC_STAT_GPIO_OC_Msk + * + * @brief General status register bit mask. + */ +#define SBC_GPIO_OC_STAT_GPIO_OC_Msk (0b01000000U) + + +/* -------------------------------- GPIO_OL_STAT -------------------------------- */ + + +/** + * @def SBC_GPIO_OL_STAT_GPIO_OL_Pos + * + * @brief General status register bit position. + */ +#define SBC_GPIO_OL_STAT_GPIO_OL_Pos (6U) + +/** + * @def SBC_GPIO_OL_STAT_GPIO_OL_Msk + * + * @brief General status register bit mask. + */ +#define SBC_GPIO_OL_STAT_GPIO_OL_Msk (0b01000000U) + + + + + + + +/* ================================================================================ */ +/* ========= Selective Wake Status Registers Position & Mask ============= */ +/* ================================================================================ */ + + + + +/* -------------------------------- SWK_STAT ------------------------------------ */ + + +/** + * @def SBC_SWK_STAT_SYNC_Pos + * + * @brief Selective wake status register bit position. + */ +#define SBC_SWK_STAT_SYNC_Pos (6U) + +/** + * @def SBC_SWK_STAT_SYNC_Msk + * + * @brief Selective wake status register bit mask. + */ +#define SBC_SWK_STAT_SYNC_Msk (0b01000000U) + +/** + * @def SBC_SWK_STAT_CANSIL_Pos + * + * @brief Selective wake status register bit position. + */ +#define SBC_SWK_STAT_CANSIL_Pos (3U) + +/** + * @def SBC_SWK_STAT_CANSIL_Msk + * + * @brief Selective wake status register bit mask. + */ +#define SBC_SWK_STAT_CANSIL_Msk (0b00001000U) + +/** + * @def SBC_SWK_STAT_SWK_SET_Pos + * + * @brief Selective wake status register bit position. + */ +#define SBC_SWK_STAT_SWK_SET_Pos (2U) + +/** + * @def SBC_SWK_STAT_SWK_SET_Msk + * + * @brief Selective wake status register bit mask. + */ +#define SBC_SWK_STAT_SWK_SET_Msk (0b00000100U) + +/** + * @def SBC_SWK_STAT_WUP_Pos + * + * @brief Selective wake status register bit position. + */ +#define SBC_SWK_STAT_WUP_Pos (1U) + +/** + * @def SBC_SWK_STAT_WUP_Msk + * + * @brief Selective wake status register bit mask. + */ +#define SBC_SWK_STAT_WUP_Msk (0b00000010U) + +/** + * @def SBC_SWK_STAT_WUF_Pos + * + * @brief Selective wake status register bit position. + */ +#define SBC_SWK_STAT_WUF_Pos (0U) + +/** + * @def SBC_SWK_STAT_WUF_Msk + * + * @brief Selective wake status register bit mask. + */ +#define SBC_SWK_STAT_WUF_Msk (0b00000001U) + + + + + +/* -------------------------------- SWK_ECNT_STAT -------------------------------- */ + + +/** + * @def SBC_SWK_ECNT_STAT_ECNT_Pos + * + * @brief Selective wake status register bit position. + */ +#define SBC_SWK_ECNT_STAT_ECNT_Pos (0U) + +/** + * @def SBC_SWK_ECNT_STAT_ECNT_Msk + * + * @brief Selective wake status register bit mask. + */ +#define SBC_SWK_ECNT_STAT_ECNT_Msk (0b00111111U) + + +/* -------------------------------- SWK_CDR_STAT1 -------------------------------- */ + + +/** + * @def SBC_SWK_CDR_STAT1_NAVG_SAT_Pos + * + * @brief Selective wake status register bit position. + */ +#define SBC_SWK_CDR_STAT1_NAVG_SAT_Pos (0U) + +/** + * @def SBC_SWK_CDR_STAT1_NAVG_SAT_Msk + * + * @brief Selective wake status register bit mask. + */ +#define SBC_SWK_CDR_STAT1_NAVG_SAT_Msk (0b11111111U) + + +/* -------------------------------- SWK_CDR_STAT2 -------------------------------- */ + + +/** + * @def SBC_SWK_CDR_STAT2_NAVG_SAT_Pos + * + * @brief Selective wake status register bit position. + */ +#define SBC_SWK_CDR_STAT2_NAVG_SAT_Pos (4U) + +/** + * @def SBC_SWK_CDR_STAT2_NAVG_SAT_Msk + * + * @brief Selective wake status register bit mask. + */ +#define SBC_SWK_CDR_STAT2_NAVG_SAT_Msk (0b11110000U) + + + + + + +/* ================================================================================ */ +/* ====== Family and Product Information Register Position & Mask ======== */ +/* ================================================================================ */ + + + +/* -------------------------------- FAM_PROD_STAT -------------------------------- */ + + +/** + * @def SBC_FAM_PROD_STAT_FAM_Pos + * + * @brief Family and product register bit position. + */ +#define SBC_FAM_PROD_STAT_FAM_Pos (4U) + +/** + * @def SBC_FAM_PROD_STAT_FAM_Msk + * + * @brief Family and product register bit mask. + */ +#define SBC_FAM_PROD_STAT_FAM_Msk (0b11110000U) + +/** + * @def SBC_FAM_PROD_STAT_PROD_Pos + * + * @brief Family and product register bit position. + */ +#define SBC_FAM_PROD_STAT_PROD_Pos (0U) + +/** + * @def SBC_FAM_PROD_STAT_PROD_Msk + * + * @brief Family and product register bit mask. + */ +#define SBC_FAM_PROD_STAT_PROD_Msk (0b00001111U) + + + + + + +/* ================================================================================ */ +/* =============== General Control Registers Enumerations ================ */ +/* ================================================================================ */ + + + +/* -------------------------------- M_S_CTRL ------------------------------------ */ + +typedef enum +{ + SBC_MODE_NORMAL = 0x00U, + SBC_MODE_SLEEP, + SBC_MODE_STOP, + SBC_MODE_RESET +}; + +typedef enum +{ + SBC_VCC2_OFF = 0x00U, + SBC_VCC2_ON_NORMAL, + SBC_VCC2_ON_NORMAL_STOP, + SBC_VCC2_ON_ALWAYS +}; + +typedef enum +{ + SBC_VCC1_OV_RST_NOACTION = 0x00U, + SBC_VCC1_OV_RST_RESTART_FAILSAFE +}; + +typedef enum +{ + SBC_VCC1_RT_VRT1 = 0x00U, + SBC_VCC1_RT_VRT2, + SBC_VCC1_RT_VRT3, + SBC_VCC1_RT_VRT4 +}; + + +/* -------------------------------- HW_CTRL_0 ----------------------------------- */ + +typedef enum +{ + SBC_SOFT_RESET_RST_TRIGGER_SOFTRST = 0x00U, + SBC_SOFT_RESET_RST_NOTRIGGER_SOFTRST +}; + +typedef enum +{ + SBC_FO_ON_NOT_ACTIVE = 0x00U, + SBC_FO_ON_ACTIVE +}; + +typedef enum +{ + SBC_CP_EN_OFF = 0x00U, + SBC_CP_EN_ON +}; + +typedef enum +{ + SBC_CFG1_RESTART_FAILSAFE_2WDFAIL = 0x00U, + SBC_CFG1_RESTART_FAILSAFE_1WDFAIL +}; + + +/* -------------------------------- WD_CTRL ------------------------------------- */ + +typedef enum +{ + SBC_CHECKSUM_0 = 0x00U, + SBC_CHECKSUM_1 +}; + +typedef enum +{ + SBC_WD_STM_EN_0_ACTIVE_STOPMODE = 0x00U, + SBC_WD_STM_EN_0_NOTACTIVE_STOPMODE +}; + +typedef enum +{ + SBC_WD_WIN_TIMEOUT_WD = 0x00U, + SBC_WD_WIN_WINDOW_WD +}; + +typedef enum +{ + SBC_WD_EN_WK_BUS_NOSTART_AFTER_CANWAKE = 0x00U, + SBC_WD_EN_WK_BUS_START_LONGOPENWINDOW_CANWAKE +}; + +typedef enum +{ + SBC_WD_TIMER_10MS = 0x00U, + SBC_WD_TIMER_20MS, + SBC_WD_TIMER_50MS, + SBC_WD_TIMER_100MS, + SBC_WD_TIMER_200MS, + SBC_WD_TIMER_500MS, + SBC_WD_TIMER_1000MS, + SBC_WD_TIMER_10000MS +}; + + +/* -------------------------------- BUS_CTRL_0 ---------------------------------- */ + +typedef enum +{ + SBC_BUS_CTRL_0_CAN_WAKECAPABLE_NOSWK = 0x01U, + SBC_BUS_CTRL_0_CAN_RECEIVEONLY_NOSWK, + SBC_BUS_CTRL_0_CAN_NORMAL_NOSWK, + SBC_BUS_CTRL_0_CAN_OFF, + SBC_BUS_CTRL_0_CAN_WAKECAPABLE_SWK, + SBC_BUS_CTRL_0_CAN_RECEIVEONLY_SWK, + SBC_BUS_CTRL_0_CAN_NORMAL_SWK +}; + + +/* -------------------------------- WK_CTRL_0 ----------------------------------- */ + +typedef enum +{ + WK_CTRL_0_TIMER_WK_EN_WAKEUP_DISABLED = 0x00U, + WK_CTRL_0_TIMER_WK_EN_WAKESOURCE +}; + +typedef enum +{ + SBC_WD_STM_EN_1_WATCHDOG_STOPMPDE = 0x00U, + SBC_WD_STM_EN_1_NOWATCHDOG_STOPMODE +}; + + +/* -------------------------------- WK_CTRL_1 ----------------------------------- */ + +typedef enum +{ + SBC_INT_GLOBAL_WAKESOURCES_ONLY = 0x00U, + SBC_INT_GLOBAL_ALLINFORMATIONBITS +}; + +typedef enum +{ + SBC_WK_MEAS_WK_AS_WAKEUP = 0x00U, + SBC_WK_MEAS_WK_AS_VOLTAGESENSING +}; + +typedef enum +{ + SBC_WK_EN_WAKEUP_DISABLED = 0x00U, + SBC_WK_EN_WAKEUP_ENABLED +}; + + +/* -------------------------------- WK_PUPD_CTRL -------------------------------- */ + +typedef enum +{ + SBC_GPIO_WK_PUPD_NOPULLING = 0x00U, + SBC_GPIO_WK_PUPD_PULLDOWN, + SBC_GPIO_WK_PUPD_PULLUP, + SBC_GPIO_WK_PUPD_AUTOMATIC_PULLING +}; + +typedef enum +{ + SBC_WK_PUPD_NOPULLING = 0x00U, + SBC_WK_PUPD_PULLDOWN, + SBC_WK_PUPD_PULLUP, + SBC_WK_PUPD_AUTOMATIC_PULLING +}; + + +/* -------------------------------- BUS_CTRL_3 ---------------------------------- */ + +typedef enum +{ + SBC_CAN_FLASH_DISABLED = 0x00U, + SBC_CAN_FLASH_ENABLED +}; + + +/* -------------------------------- TIMER_CTRL ---------------------------------- */ + +typedef enum +{ + SBC_TIMER_ON_TIMEROFF_HSX_LOW = 0x00U, + SBC_TIMER_ON_100US, + SBC_TIMER_ON_300US, + SBC_TIMER_ON_1MS, + SBC_TIMER_ON_10MS, + SBC_TIMER_ON_20MS, + SBC_TIMER_ON_TIMEROFF_HSX_HIGH +}; + +typedef enum +{ + SBC_TIMER_PER_10MS = 0x00U, + SBC_TIMER_PER_20MS, + SBC_TIMER_PER_50MS, + SBC_TIMER_PER_100MS, + SBC_TIMER_PER_200MS, + SBC_TIMER_PER_500MS, + SBC_TIMER_PER_1S, + SBC_TIMER_PER_2S, + SBC_TIMER_PER_5S, + SBC_TIMER_PER_10S, + SBC_TIMER_PER_20S, + SBC_TIMER_PER_50S, + SBC_TIMER_PER_100S, + SBC_TIMER_PER_200S, + SBC_TIMER_PER_500S, + SBC_TIMER_PER_1000S +}; + + +/* -------------------------------- HW_CTRL_1 ----------------------------------- */ + +typedef enum +{ + SBC_RSTN_HYS_DEFAULT = 0x00U, + SBC_RSTN_HYS_HIGHEST_VRT +}; + +typedef enum +{ + SBC_TSD2_DEL_NO_WAIT_RELEASE_EXTENSION = 0x00U, + SBC_TSD2_DEL_64S_AFTER_16_TSD2_EVENTS +}; + +typedef enum +{ + SBC_RSTN_DEL_TRD1 = 0x00U, + SBC_RSTN_DEL_TRD2 +}; + +typedef enum +{ + SBC_CFG_LOCK_0_NOTLOCKED = 0x00U, + SBC_CFG_LOCK_0_LOCKED +}; + + +/* -------------------------------- HW_CTRL_2 ----------------------------------- */ + +typedef enum +{ + SBC_2MHZ_FREQ_1_8_MHZ = 0x00U, + SBC_2MHZ_FREQ_2_0_MHZ, + SBC_2MHZ_FREQ_2_2_MHZ, + SBC_2MHZ_FREQ_2_4_MHZ +}; + +typedef enum +{ + SBC_I_PEAK_TH_LOW = 0x00U, + SBC_I_PEAK_TH_HIGH +}; + +typedef enum +{ + SBC_SS_MOD_FR_DISABLED = 0x00U, + SBC_SS_MOD_FR_15_6KHZ, + SBC_SS_MOD_FR_31_2KHZ, + SBC_SS_MOD_FR_62_5KHZ +}; + +typedef enum +{ + SBC_CFG_LOCK_1_NOTLOCKED = 0x00U, + SBC_CFG_LOCK_1_LOCKED +}; + + +/* -------------------------------- GPIO_CTRL ----------------------------------- */ + +typedef enum +{ + SBC_GPIO_FO = 0x00U, + SBC_GPIO_HSS_TIMER = 0x03U, + SBC_GPIO_OFF, + SBC_GPIO_WAKE_INPUT, + SBC_GPIO_LSS_PWM, + SBC_GPIO_HSS_PWM +}; + + +/* -------------------------------- PWM_CTRL ------------------------------------ */ + +typedef enum +{ + SBC_PWM_DC_0 = 0x00U, + SBC_PWM_DC_10 = 0x19U, + SBC_PWM_DC_20 = 0x51U, + SBC_PWM_DC_30 = 0x4DU, + SBC_PWM_DC_40 = 0x66U, + SBC_PWM_DC_50 = 0x80U, + SBC_PWM_DC_60 = 0x99U, + SBC_PWM_DC_70 = 0xB3U, + SBC_PWM_DC_80 = 0xCCU, + SBC_PWM_DC_90 = 0xE6U, + SBC_PWM_DC_100 = 0xFFU +}; + + +/* -------------------------------- PWM_FREQ_CTRL ------------------------------- */ + +typedef enum +{ + SBC_PWM_FREQ_100HZ = 0x00U, + SBC_PWM_FREQ_200HZ, + SBC_PWM_FREQ_325HZ, + SBC_PWM_FREQ_400HZ +}; + + +/* -------------------------------- HW_CTRL_3 ----------------------------------- */ + +typedef enum +{ + SBC_TSD_THR_DEFAULT = 0x00U, + SBC_TSD_THR_HIGHER +}; + +typedef enum +{ + SBC_ICC1_LIM_ADJ_750MA = 0x00U, + SBC_ICC1_LIM_ADJ_1000MA, + SBC_ICC1_LIM_ADJ_1200MA, + SBC_ICC1_LIM_ADJ_1500MA +}; + + + + + + +/* ================================================================================ */ +/* ========== Selective Wake Control Registers Enumerations ============== */ +/* ================================================================================ */ + + + +/* -------------------------------- SWK_CTRL ------------------------------------ */ + +typedef enum +{ + SBC_OSC_CAL_DISABLED = 0x00U, + SBC_OSC_CAL_ENABLED +}; + +typedef enum +{ + SBC_TRIM_EN_LOCKED = 0x00U, + SBC_TRIM_EN_UNLOCKED = 0x03U +}; + +typedef enum +{ + SBC_CANTO_MASK_NOINT = 0x00U, + SBC_CANTO_MASK_INT_ON_TO +}; + +typedef enum +{ + SBC_CFG_VAL_NOTVALID = 0x00U, + SBC_CFG_VAL_VALID +}; + + +/* -------------------------------- SWK_ID0_CTRL --------------------------------- */ + +typedef enum +{ + SBC_RTR_NORMAL_DATA_FRAME = 0x00U, + SBC_RTR_REMOTE_TRANSMIT_REQUEST +}; + +typedef enum +{ + SBC_IDE_STANDARD = 0x00U, + SBC_IDE_EXTENDED +}; + + +/* -------------------------------- SWK_DLC_CTRL --------------------------------- */ + +typedef enum +{ + SBC_DLC_0BYTES = 0x00U, + SBC_DLC_1BYTES, + SBC_DLC_2BYTES, + SBC_DLC_3BYTES, + SBC_DLC_4BYTES, + SBC_DLC_5BYTES, + SBC_DLC_6BYTES, + SBC_DLC_7BYTES, + SBC_DLC_8BYTES +}; + + +/* -------------------------------- SWK_CAN_FD_CTRL ------------------------------ */ + +typedef enum +{ + SBC_DIS_ERR_CNT_ENABLED = 0x00U, + SBC_DIS_ERR_CNT_DISABLED +}; + +typedef enum +{ + SBC_RX_FILT_BYP_NOTBYPASSED = 0x00U, + SBC_RX_FILT_BYP_BYPASSED +}; + +typedef enum +{ + SBC_FD_FILTER_50NS = 0x00U, + SBC_FD_FILTER_100NS, + SBC_FD_FILTER_150NS, + SBC_FD_FILTER_200NS, + SBC_FD_FILTER_250NS, + SBC_FD_FILTER_300NS, + SBC_FD_FILTER_350NS, + SBC_FD_FILTER_700NS +}; + +typedef enum +{ + SBC_CAN_FD_EN_DISABLED = 0x00U, + SBC_CAN_FD_EN_ENABLED +}; + + +/* -------------------------------- SWK_OPT_CTRL --------------------------------- */ + +typedef enum +{ + SBC_RX_WK_SEL_LOWPOWER = 0x00U, + SBC_RX_WK_SEL_STANDARD +}; + + +/* -------------------------------- SWK_CDR_CTRL1 -------------------------------- */ + +typedef enum +{ + SBC_SEL_FILT_TC8 = 0x00U, + SBC_SEL_FILT_TC16, + SBC_SEL_FILT_TC32, + SBC_SEL_FILT_ADAPT +}; + +typedef enum +{ + SBC_CDR_EN_DISABLED = 0x00U, + SBC_CDR_EN_ENABLED +}; + + +/* -------------------------------- SWK_CDR_CTRL2 -------------------------------- */ + +typedef enum +{ + SBC_SEL_OSC_CLK_80MHZ = 0x00U, + SBC_SEL_OSC_CLK_40MHZ, + SBC_SEL_OSC_CLK_20MHZ, + SBC_SEL_OSC_CLK_10MHZ +}; + + + + + + +/* ================================================================================ */ +/* ========== General Status Information Registers Enumerations ========== */ +/* ================================================================================ */ + + + +/* -------------------------------- SUP_STAT_1 ---------------------------------- */ + +typedef enum +{ + SBC_VS_UV_NOEVENT = 0x00U, + SBC_VS_UV_EVENT +}; + +typedef enum +{ + SBC_VS_OV_NOEVENT = 0x00U, + SBC_VS_OV_EVENT +}; + +typedef enum +{ + SBC_VCC1_OV_NOEVENT = 0x00U, + SBC_VCC1_OV_EVENT +}; + +typedef enum +{ + SBC_VCC1_UV_PREWARN_NOEVENT = 0x00U, + SBC_VCC1_UV_PREWARN_EVENT +}; + + +/* -------------------------------- SUP_STAT_0 ----------------------------------- */ + +typedef enum +{ + SBC_POR_NOEVENT = 0x00U, + SBC_POR_EVENT +}; + +typedef enum +{ + SBC_VCC2_OT_NOEVENT = 0x00U, + SBC_VCC2_OT_EVENT +}; + +typedef enum +{ + SBC_VCC2_UV_NOEVENT = 0x00U, + SBC_VCC2_UV_EVENT +}; + +typedef enum +{ + SBC_VCC1_SC_NOEVENT = 0x00U, + SBC_VCC1_SC_TO_GND_EVENT +}; + +typedef enum +{ + SBC_VCC1_UV_NOEVENT = 0x00U, + SBC_VCC1_UV_EVENT +}; + + +/* -------------------------------- THERM_STAT ----------------------------------- */ + +typedef enum +{ + SBC_TSD2_SAFE_NOSAFESTATE = 0x00U, + SBC_TSD2_SAFE_SAFESTATE_DETECTED +}; + +typedef enum +{ + SBC_TSD2_NOEVENT = 0x00U, + SBC_TSD2_EVENT +}; + +typedef enum +{ + SBC_TSD1_NOEVENT = 0x00U, + SBC_TSD1_EVENT +}; + +typedef enum +{ + SBC_TPW_NOEVENT = 0x00U, + SBC_TPW_EVENT +}; + + +/* -------------------------------- DEV_STAT ------------------------------------- */ + +typedef enum +{ + SBC_DEV_STAT_CLEARED = 0x00U, + SBC_DEV_STAT_RESTART_AFTER_FAIL, + SBC_DEV_STAT_SLEEP_MODE +}; + +typedef enum +{ + SBC_WD_FAIL_NOFAIL = 0x00U, + SBC_WD_FAIL_1FAIL, + SBC_WD_FAIL_2FAIL +}; + +typedef enum +{ + SBC_SPI_FAIL_NOEVENT = 0x00U, + SBC_SPI_FAIL_EVENT +}; + +typedef enum +{ + SBC_FAILURE_NOEVENT = 0x00U, + SBC_FAILURE_EVENT +}; + + +/* -------------------------------- BUS_STAT ------------------------------------- */ + +typedef enum +{ + SBC_CANTO_NORMAL = 0x00U, + SBC_CANTO_TIMEOUT +}; + +typedef enum +{ + SBC_SYSERR_NOEVENT = 0x00U, + SBC_SYSERR_DETECTED +}; + +typedef enum +{ + SBC_CAN_FAIL_NO_FAIL = 0x00U, + SBC_CAN_FAIL_TSD, + SBC_CAN_FAIL_TXD_DOM_TO, + SBC_CAN_FAIL_BUS_DOM_TO +}; + +typedef enum +{ + SBC_VCAN_UV_NOEVENT = 0x00U, + SBC_VCAN_UV_EVENT +}; + + +/* -------------------------------- WK_STAT_0 ------------------------------------ */ + +typedef enum +{ + SBC_CAN_WU_NOEVENT = 0x00U, + SBC_CAN_WU_EVENT +}; + +typedef enum +{ + SBC_TIMER_WU_NOEVENT = 0x00U, + SBC_TIMER_WU_EVENT +}; + +typedef enum +{ + SBC_WK_WU_NOEVENT = 0x00U, + SBC_WK_WU_EVENT +}; + + +/* -------------------------------- WK_STAT_1 ------------------------------------ */ + +typedef enum +{ + SBC_GPIO_WK_WU_NOEVENT = 0x00U, + SBC_GPIO_WK_WU_EVENT +}; + + +/* -------------------------------- WK_LVL_STAT ---------------------------------- */ + +typedef enum +{ + SBC_DEV_LVL_NORMAL = 0x00U, + SBC_DEV_LVL_DEVELOPMENT_MODE +}; + +typedef enum +{ + SBC_CFG0_STATE_CONFIG_2_4 = 0x00U, + SBC_CFG0_STATE_CONFIG_1_3 +}; + +typedef enum +{ + SBC_GPIO_LVL_LOW = 0x00U, + SBC_GPIO_LVL_HIGH +}; + +typedef enum +{ + SBC_WK_LVL_LOW = 0x00U, + SBC_WK_LVL_HIGH +}; + + +/* -------------------------------- GPIO_OC_STAT --------------------------------- */ + +typedef enum +{ + SBC_GPIO_OC_NOEVENT = 0x00U, + SBC_GPIO_OC_EVENT +}; + + +/* -------------------------------- GPIO_OL_STAT --------------------------------- */ + +typedef enum +{ + SBC_GPIO_OL_NOEVENT = 0x00U, + SBC_GPIO_OL_EVENT +}; + + + + + + +/* ================================================================================ */ +/* ============= Selective Wake Status Registers Enumerations ============ */ +/* ================================================================================ */ + + + +/* -------------------------------- SWK_STAT ------------------------------------ */ + +typedef enum +{ + SBC_SYNC_NOT_SYNCHRONOUS = 0x00U, + SBC_SYNC_VALID_FRAME_RECEIVED +}; + +typedef enum +{ + SBC_CANSIL_NOT_EXCEEDED = 0x00U, + SBC_CANSIL_EXCEEDED +}; + +typedef enum +{ + SBC_SWK_SET_SWK_NOT_ACTIVE = 0x00U, + SBC_SWK_SET_SWK_ACTIVE +}; + +typedef enum +{ + SBC_WUP_NO_WUP = 0x00U, + SBC_WUP_DETECTED +}; + +typedef enum +{ + SBC_WUF_NO_WUF = 0x00U, + SBC_WUF_DETECTED +}; + + +/* -------------------------------- SWK_ECNT_STAT ------------------------------ */ + +typedef enum +{ + SBC_ECNT_NOEVENT = 0x00U, + SBC_ECNT_31_FRAME_ERRORS = 0x1FU, + SBC_ECNT_ERROR_OVERFLOW = 0x20U +}; + + +/* ================================================================================ */ +/* ======== Family and Product Information Registers Enumerations ======== */ +/* ================================================================================ */ + + + +/* -------------------------------- FAM_PROD_STAT ------------------------------- */ + +typedef enum +{ + SBC_FAM_DRIVER = 0x01U, + SBC_FAM_DCDC, + SBC_FAM_MIDRANGE, + SBC_FAM_MULTICAN, + SBC_FAM_LITE, + SBC_FAM_MIDRANGEPLUS = 0x07U +}; + +typedef enum +{ + SBC_PROD_TLE9461 = 0x06U, + SBC_PROD_TLE9461V33, + SBC_PROD_TLE9471 = 0x0EU, + SBC_PROD_TLE9471V33 +}; + + +#endif /* TLE94x1_DEFINES_H */ diff --git a/cva_bootloader_m0118/src/TLE9461/TLE94x1_ISR.h b/cva_bootloader_m0118/src/TLE9461/TLE94x1_ISR.h new file mode 100644 index 0000000..b40bbbe --- /dev/null +++ b/cva_bootloader_m0118/src/TLE9461/TLE94x1_ISR.h @@ -0,0 +1,127 @@ +/********************************************************************************************************************* + * Copyright (c) 2019, Infineon Technologies AG + * + * + * Distributed under the Boost Software License, Version 1.0. + * + * + * Boost Software License - Version 1.0 - August 17th, 2003 + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *********************************************************************************************************************/ + + +/****************************************************************************************************//** + * @file TLE94x1_ISR.h + * + * @brief Declaration file for ISR-Vectors and ISR related functions + * + * @version V1.0.0 + * @date 15. April 2019 + * @author Markus Noll / markus.noll@infineon.com + * @author Yannek Micha Rixen / Yannek.Rixen@infineon.com + *******************************************************************************************************/ + + + + +#ifndef TLE94x1_ISR_H +#define TLE94x1_ISR_H + + + + + + + +/* ================================================================================ */ +/* ============================ HEADER FILES ================================== */ +/* ================================================================================ */ + +#include "TLE94x1_DEFINES.h" + + + + + + + + +/* ================================================================================ */ +/* ================================ MACROS ==================================== */ +/* ================================================================================ */ + + +/** + * @def SBC_ISR_VECTOR + * + * @brief Vector defining the handling of interrupts. + * + * Vectors of this type have to be registered by the SBC_Register_Callback method. + */ +#define SBC_ISR_VECTOR(REG,MASK,POS,COMPARE) ((((uint32_t)REG) << 24) | (((uint32_t)MASK) << 16) | (((uint32_t)POS) << 8) | ((uint32_t)COMPARE)) + + + + + + +/* ================================================================================ */ +/* ======================= General Interrupt Defines ========================== */ +/* ================================================================================ */ + + + +/* Interrupts based on WK_STAT_0 and WK_STAT_1 register are always available */ +#define SBC_ISR_CAN_WU SBC_ISR_VECTOR(SBC_WK_STAT_0, SBC_WK_STAT_0_CAN_WU_Msk, SBC_WK_STAT_0_CAN_WU_Pos, SBC_CAN_WU_EVENT) +#define SBC_ISR_TIMER_WU SBC_ISR_VECTOR(SBC_WK_STAT_0, SBC_WK_STAT_0_TIMER_WU_Msk, SBC_WK_STAT_0_TIMER_WU_Pos, SBC_TIMER_WU_EVENT) +#define SBC_ISR_WK_WU SBC_ISR_VECTOR(SBC_WK_STAT_0, SBC_WK_STAT_0_WK_WU_Msk, SBC_WK_STAT_0_WK_WU_Pos, SBC_WK_WU_EVENT) +#define SBC_ISR_GPIO_WK_WU SBC_ISR_VECTOR(SBC_WK_STAT_1, SBC_WK_STAT_1_GPIO_WK_WU_Msk, SBC_WK_STAT_1_GPIO_WK_WU_Pos, SBC_GPIO_WK_WU_EVENT) + + +/* Following interrupts only usable if INT_GLOBAL bit is set to '1' */ +#define SBC_ISR_VS_UV SBC_ISR_VECTOR(SBC_SUP_STAT_1, SBC_SUP_STAT_1_VS_UV_Msk, SBC_SUP_STAT_1_VS_UV_Pos, SBC_VS_UV_EVENT) +#define SBC_ISR_VS_OV SBC_ISR_VECTOR(SBC_SUP_STAT_1, SBC_SUP_STAT_1_VS_OV_Msk, SBC_SUP_STAT_1_VS_OV_Pos, SBC_VS_OV_EVENT) +#define SBC_ISR_VCC1_OV SBC_ISR_VECTOR(SBC_SUP_STAT_1, SBC_SUP_STAT_1_VCC1_OV_Msk, SBC_SUP_STAT_1_VCC1_OV_Pos, SBC_VCC1_OV_EVENT) +#define SBC_ISR_VCC1_UV_PREWARN SBC_ISR_VECTOR(SBC_SUP_STAT_1, SBC_SUP_STAT_1_VCC1_WARN_Msk, SBC_SUP_STAT_1_VCC1_WARN_Pos, SBC_VCC1_UV_PREWARN_EVENT) +#define SBC_ISR_VCC2_OT SBC_ISR_VECTOR(SBC_SUP_STAT_0, SBC_SUP_STAT_0_VCC2_OT_Msk, SBC_SUP_STAT_0_VCC2_OT_Pos, SBC_VCC2_OT_EVENT) +#define SBC_ISR_VCC2_UV SBC_ISR_VECTOR(SBC_SUP_STAT_0, SBC_SUP_STAT_0_VCC2_UV_Msk, SBC_SUP_STAT_0_VCC2_UV_Pos, SBC_VCC2_UV_EVENT) +#define SBC_ISR_VCC1_UV SBC_ISR_VECTOR(SBC_SUP_STAT_0, SBC_SUP_STAT_0_VCC1_UV_Msk, SBC_SUP_STAT_0_VCC1_UV_Pos, SBC_VCC1_UV_EVENT) +#define SBC_ISR_TSD2_SAFESTATE SBC_ISR_VECTOR(SBC_THERM_STAT, SBC_THERM_STAT_TSD2_SAFE_Msk, SBC_THERM_STAT_TSD2_SAFE_Pos, SBC_TSD2_SAFE_SAFESTATE_DETECTED) +#define SBC_ISR_TSD1 SBC_ISR_VECTOR(SBC_THERM_STAT, SBC_THERM_STAT_TSD1_Msk, SBC_THERM_STAT_TSD1_Pos, SBC_TSD1_EVENT) +#define SBC_ISR_TPW SBC_ISR_VECTOR(SBC_THERM_STAT, SBC_THERM_STAT_TPW_Msk, SBC_THERM_STAT_TPW_Pos, SBC_TPW_EVENT) +#define SBC_ISR_RESTART_AFTER_FAIL SBC_ISR_VECTOR(SBC_DEV_STAT, SBC_DEV_STAT_DEV_STAT_Msk, SBC_DEV_STAT_DEV_STAT_Pos, SBC_DEV_STAT_RESTART_AFTER_FAIL) +#define SBC_ISR_FROM_SLEEPMODE SBC_ISR_VECTOR(SBC_DEV_STAT, SBC_DEV_STAT_DEV_STAT_Msk, SBC_DEV_STAT_DEV_STAT_Pos, SBC_DEV_STAT_SLEEP_MODE) +#define SBC_ISR_WD_FAIL_1 SBC_ISR_VECTOR(SBC_DEV_STAT, SBC_DEV_STAT_WD_FAIL_Msk, SBC_DEV_STAT_WD_FAIL_Pos, SBC_WD_FAIL_1FAIL) +#define SBC_ISR_WD_FAIL_2 SBC_ISR_VECTOR(SBC_DEV_STAT, SBC_DEV_STAT_WD_FAIL_Msk, SBC_DEV_STAT_WD_FAIL_Pos, SBC_WD_FAIL_2FAIL) +#define SBC_ISR_FAILURE SBC_ISR_VECTOR(SBC_DEV_STAT, SBC_DEV_STAT_FAILURE_Msk, SBC_DEV_STAT_FAILURE_Pos, SBC_FAILURE_EVENT) +#define SBC_ISR_CAN_TSD SBC_ISR_VECTOR(SBC_BUS_STAT, SBC_BUS_STAT_CAN_FAIL_Msk, SBC_BUS_STAT_CAN_FAIL_Pos, SBC_CAN_FAIL_TSD) +#define SBC_ISR_CAN_TXD_DOM_TO SBC_ISR_VECTOR(SBC_BUS_STAT, SBC_BUS_STAT_CAN_FAIL_Msk, SBC_BUS_STAT_CAN_FAIL_Pos, SBC_CAN_FAIL_TXD_DOM_TO) +#define SBC_ISR_CAN_BUS_DOM_TO SBC_ISR_VECTOR(SBC_BUS_STAT, SBC_BUS_STAT_CAN_FAIL_Msk, SBC_BUS_STAT_CAN_FAIL_Pos, SBC_CAN_FAIL_BUS_DOM_TO) +#define SBC_ISR_VCAN_UV SBC_ISR_VECTOR(SBC_BUS_STAT, SBC_BUS_STAT_VCAN_UV_Msk, SBC_BUS_STAT_VCAN_UV_Pos, SBC_VCAN_UV_EVENT) +#define SBC_ISR_GPIO_OC SBC_ISR_VECTOR(SBC_GPIO_OC_STAT, SBC_GPIO_OC_STAT_GPIO_OC_Msk, SBC_GPIO_OC_STAT_GPIO_OC_Pos, SBC_GPIO_OC_EVENT) +#define SBC_ISR_GPIO_OL SBC_ISR_VECTOR(SBC_GPIO_OL_STAT, SBC_GPIO_OL_STAT_GPIO_OL_Msk, SBC_GPIO_OL_STAT_GPIO_OL_Pos, SBC_GPIO_OL_EVENT) + + +#endif /*TLE94x1_ISR_H*/ diff --git a/cva_bootloader_m0118/src/TLE9461/TLE94x1_SPI.c b/cva_bootloader_m0118/src/TLE9461/TLE94x1_SPI.c new file mode 100644 index 0000000..b90577c --- /dev/null +++ b/cva_bootloader_m0118/src/TLE9461/TLE94x1_SPI.c @@ -0,0 +1,156 @@ +/********************************************************************************************************************* + * Copyright (c) 2019, Infineon Technologies AG + * + * + * Distributed under the Boost Software License, Version 1.0. + * + * + * Boost Software License - Version 1.0 - August 17th, 2003 + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *********************************************************************************************************************/ + + +/****************************************************************************************************//** + * @file TLE94x1_SPI.c + * + * @brief Implementation of all SPI related functions + * + * @version V1.0.0 + * @date 15. April 2019 + * @author Markus Noll / markus.noll@infineon.com + * @author Yannek Micha Rixen / Yannek.Rixen@infineon.com + *******************************************************************************************************/ + + + + +/* ================================================================================ */ +/* ============================ HEADER FILES ================================ */ +/* ================================================================================ */ + +#include "TLE94x1_SPI.h" +#include "mcu.h" + +void SPI_PortInit(void); + + + + +/* ================================================================================ */ +/* ======================= SPI communication functions ====================== */ +/* ================================================================================ */ + + +uint8_t spitxbuf[10],spirxbuf[10]; +extern McuType mcu; +uint8_t SBC_SPI_INIT(void) { + SpiDrv_InitCfgType masterCfg; + + SPI_PortInit(); + + SpiDrv_GetDefaultConfig(&masterCfg); + masterCfg.basicParameters.isMasterNode = true; + masterCfg.basicParameters.baudRate = 1000000ul; + masterCfg.basicParameters.pcsSelection = 1; + //masterCfg.basicParameters.clockPolarity = SPIDRV_CLK_POLARITY_IDLE_IN_HIGH; + masterCfg.basicParameters.clockPhase = SPIDRV_CLK_PHASE_DATA_SAMPLE_ON_TRAILING_EDGE; + + while(ClockDrv_GetFreq(&mcu.clockDrv, CLOCKDRV_SPI0, &masterCfg.basicParameters.busClockFreq) == false) + { + ; + } + SpiDrv_SetConfig(&mcu.spiDrv0, &masterCfg); + + SpiDrv_SetRxFifoWaterMask(&mcu.spiDrv0, 0); + //SpiDrv_SetIsrConfig(&mcu.spiDrv0, SPIDRV_ISR_SRC_RX_DATA, true); + + /* Enable the SPI interrupts */ + return 0; +} + + + +uint16_t SBC_SPI_TRANSFER16(uint8_t Upper, uint8_t Lower) { + uint16_t ret; + //LPSPI_DRV_SetPcs(LPSPICOM1,LPSPI_PCS0,LPSPI_ACTIVE_LOW); + spitxbuf[0] = Upper; + spitxbuf[1] = Lower; + + SpiDrv_MasterSyncTransfer(&mcu.spiDrv0,SPIDRV_FRAME_SIZE_BIT_TYPE_BYTE,2,spitxbuf,spirxbuf); + //LPSPI_DRV_MasterTransferBlocking(LPSPICOM1,spitxbuf,spirxbuf,2,10); + ret = spirxbuf[0]; + ret <<= 8; + ret |= spirxbuf[1]; + //LPSPI_DRV_SetPcs(LPSPICOM1,LPSPI_PCS0,LPSPI_ACTIVE_HIGH); + return ret; +} + + +/********************CVA SPI DRV**********************/ + +void SPI0_Handler(void) +{ + if(SpiDrv_GetStatus(&mcu.spiDrv0, SPIDRV_STATUS_RX_DATA) == true && SpiDrv_GetIsrConfig(&mcu.spiDrv0, SPIDRV_ISR_SRC_RX_DATA) == true) + { + //spi0IrqCnt++; + //uint8_t len = SpiDrv_AsyncReceive(&mcu.spiDrv0, (void *)masterRxBuff, true); + } +} + +void SPI_PortInit(void) +{ + /* SPI CS */ + PinsDrv_SetMuxModeSel(&mcu.ptb, 5, PINSDRV_MUX_ALT3); + /* Strength driver */ + PortReg_SetPcrDrvStr(mcu.ptb.port, 5, 1); + /* fast slew rate */ + PortReg_SetPcrSr(mcu.ptb.port, 5, 1); + + /* SPI CLK */ + PinsDrv_SetMuxModeSel(&mcu.ptb, 2, PINSDRV_MUX_ALT3); + /* Strength driver */ + PortReg_SetPcrDrvStr(mcu.ptb.port, 2, 1); + /* fast slew rate */ + PortReg_SetPcrSr(mcu.ptb.port, 2, 1); + + /* SPI SIN */ + PinsDrv_SetMuxModeSel(&mcu.ptb, 4, PINSDRV_MUX_ALT3); + /* Strength driver */ + PortReg_SetPcrDrvStr(mcu.ptb.port, 4, 1); + /* fast slew rate */ + PortReg_SetPcrSr(mcu.ptb.port, 4, 1); + + /* SPI SOUT */ + PinsDrv_SetMuxModeSel(&mcu.ptb, 3, PINSDRV_MUX_ALT3); + /* Strength driver */ + PortReg_SetPcrDrvStr(mcu.ptb.port, 3, 1); + /* fast slew rate */ + PortReg_SetPcrSr(mcu.ptb.port, 3, 1); +} + +void SPI_TEST_TASK(void) +{ + +} \ No newline at end of file diff --git a/cva_bootloader_m0118/src/TLE9461/TLE94x1_SPI.h b/cva_bootloader_m0118/src/TLE9461/TLE94x1_SPI.h new file mode 100644 index 0000000..abf88cc --- /dev/null +++ b/cva_bootloader_m0118/src/TLE9461/TLE94x1_SPI.h @@ -0,0 +1,95 @@ +/********************************************************************************************************************* + * Copyright (c) 2019, Infineon Technologies AG + * + * + * Distributed under the Boost Software License, Version 1.0. + * + * + * Boost Software License - Version 1.0 - August 17th, 2003 + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *********************************************************************************************************************/ + + +/****************************************************************************************************//** + * @file TLE94x1_SPI.h + * + * @brief Declaration file for TLE94x1 SBC family device SPI functions + * + * @version V1.0.0 + * @date 15. April 2019 + * @author Markus Noll / markus.noll@infineon.com + * @author Yannek Micha Rixen / Yannek.Rixen@infineon.com + *******************************************************************************************************/ + + + + +#ifndef TLE94x1_SPI_H +#define TLE94x1_SPI_H + + + + + + +/* ================================================================================ */ +/* ============================ HEADER FILES ================================ */ +/* ================================================================================ */ + +#include + + + +/* ================================================================================ */ +/* ============================= SPI Functions ============================== */ +/* ================================================================================ */ + +/** + * @brief IMPORTANT! THIS METHOD HAS TO BE DEFINED BY THE USER + * + * The function has to initialze the SPI of the uC and will be called once during SBC_Init(). + * In case, the SPI hardware is already initialized by some other code before, it can be left blank. + * + * @retval Method has to return 0 if initialization was successful. + */ +uint8_t SBC_SPI_INIT(void); + +/** + * @brief IMPORTANT! THIS METHOD HAS TO BE DEFINED BY THE USER + * + * The function will be called by the library everytime when a SPI communication is needed. + * The function proceeds a bidirectional 16-bit transfer to/from the SBC . + * As some UCs only supports 8-Bit transfers, the input arguments are split in two 8-bit arguments. + * For further implementation details have a look at datasheet chapter 13.1 or at the Arduino-examples. + * + * @param Upper The first 8 bit to transmit to the SBC. + * @param Lower The second 8 bit to transmit to the SBC. + * @retval The function will return all 16 bits received from the SBC. + * Bit[15:8] are the first 8 bits received (Status-Information-Field). + * Bit[7:0] is the data-field transmitted of the SBC. + */ +uint16_t SBC_SPI_TRANSFER16(uint8_t Upper, uint8_t Lower); + +#endif /* TLE94x1_SPI_H */ diff --git a/cva_bootloader_m0118/src/bootloader/bootloader.c b/cva_bootloader_m0118/src/bootloader/bootloader.c new file mode 100644 index 0000000..fafa7c0 --- /dev/null +++ b/cva_bootloader_m0118/src/bootloader/bootloader.c @@ -0,0 +1,1294 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ +#include +#include +#include "bootloader_cfg.h" +#include "fls.h" +#include "bootloader.h" +#include "uds.h" +#include "uds_user.h" +#include "mcu.h" +#include "TLE94x1.h" +#include "SEGGER_RTT.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ +static bool Bootloader_GetBootReq(void); +static uint32_t Bootloader_CalculateCheckSum(uint32_t initCrcValue, const uint8_t *dataBuffer, uint32_t bytesNum, bool inverted); +static void Bootloader_JumpToApp(void); +static void Bootloader_Reset(void); +static void Bootloader_InitState(void); +static void Bootloader_EraseState(void); +static void Bootloader_PgmState(void); +static void Bootloader_CheckState(void); +static void Bootloader_ExitState(void); +static void Bootloader_ErrorState(void); + +extern McuType mcu; + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +typedef void (*pBootloader_StateFun)(void); + +/******************************************************************************* + * the globals + ******************************************************************************/ + +#pragma location = ".no_init" +static uint32_t sBootloader_Req; + +#pragma location = ".bootloaderInfo" +__root const Bootloade_CfgInfoType sBootloader_Version = { + .HWVersion = "HW01", + .BLVersion = "BL0101", + .bootBuildDate = __DATE__, + .bootBuildTime = __TIME__, + .ECUName = "RP-77B", +}; + +static Bootloader_CbType sBootloader_Cb; + +pBootloader_StateFun sBootloader_StateFuncTbl[BOOTLOADER_STATE_NUM] = { + Bootloader_InitState, + Bootloader_EraseState, + Bootloader_PgmState, + Bootloader_ErrorState, + Bootloader_CheckState, + Bootloader_ExitState}; + +static const unsigned int crc32_table[] = { + 0x00000000uL, + 0x77073096uL, + 0xEE0E612CuL, + 0x990951BAuL, + 0x076DC419uL, + 0x706AF48FuL, + 0xE963A535uL, + 0x9E6495A3uL, + 0x0EDB8832uL, + 0x79DCB8A4uL, + 0xE0D5E91EuL, + 0x97D2D988uL, + 0x09B64C2BuL, + 0x7EB17CBDuL, + 0xE7B82D07uL, + 0x90BF1D91uL, + 0x1DB71064uL, + 0x6AB020F2uL, + 0xF3B97148uL, + 0x84BE41DEuL, + 0x1ADAD47DuL, + 0x6DDDE4EBuL, + 0xF4D4B551uL, + 0x83D385C7uL, + 0x136C9856uL, + 0x646BA8C0uL, + 0xFD62F97AuL, + 0x8A65C9ECuL, + 0x14015C4FuL, + 0x63066CD9uL, + 0xFA0F3D63uL, + 0x8D080DF5uL, + 0x3B6E20C8uL, + 0x4C69105EuL, + 0xD56041E4uL, + 0xA2677172uL, + 0x3C03E4D1uL, + 0x4B04D447uL, + 0xD20D85FDuL, + 0xA50AB56BuL, + 0x35B5A8FAuL, + 0x42B2986CuL, + 0xDBBBC9D6uL, + 0xACBCF940uL, + 0x32D86CE3uL, + 0x45DF5C75uL, + 0xDCD60DCFuL, + 0xABD13D59uL, + 0x26D930ACuL, + 0x51DE003AuL, + 0xC8D75180uL, + 0xBFD06116uL, + 0x21B4F4B5uL, + 0x56B3C423uL, + 0xCFBA9599uL, + 0xB8BDA50FuL, + 0x2802B89EuL, + 0x5F058808uL, + 0xC60CD9B2uL, + 0xB10BE924uL, + 0x2F6F7C87uL, + 0x58684C11uL, + 0xC1611DABuL, + 0xB6662D3DuL, + 0x76DC4190uL, + 0x01DB7106uL, + 0x98D220BCuL, + 0xEFD5102AuL, + 0x71B18589uL, + 0x06B6B51FuL, + 0x9FBFE4A5uL, + 0xE8B8D433uL, + 0x7807C9A2uL, + 0x0F00F934uL, + 0x9609A88EuL, + 0xE10E9818uL, + 0x7F6A0DBBuL, + 0x086D3D2DuL, + 0x91646C97uL, + 0xE6635C01uL, + 0x6B6B51F4uL, + 0x1C6C6162uL, + 0x856530D8uL, + 0xF262004EuL, + 0x6C0695EDuL, + 0x1B01A57BuL, + 0x8208F4C1uL, + 0xF50FC457uL, + 0x65B0D9C6uL, + 0x12B7E950uL, + 0x8BBEB8EAuL, + 0xFCB9887CuL, + 0x62DD1DDFuL, + 0x15DA2D49uL, + 0x8CD37CF3uL, + 0xFBD44C65uL, + 0x4DB26158uL, + 0x3AB551CEuL, + 0xA3BC0074uL, + 0xD4BB30E2uL, + 0x4ADFA541uL, + 0x3DD895D7uL, + 0xA4D1C46DuL, + 0xD3D6F4FBuL, + 0x4369E96AuL, + 0x346ED9FCuL, + 0xAD678846uL, + 0xDA60B8D0uL, + 0x44042D73uL, + 0x33031DE5uL, + 0xAA0A4C5FuL, + 0xDD0D7CC9uL, + 0x5005713CuL, + 0x270241AAuL, + 0xBE0B1010uL, + 0xC90C2086uL, + 0x5768B525uL, + 0x206F85B3uL, + 0xB966D409uL, + 0xCE61E49FuL, + 0x5EDEF90EuL, + 0x29D9C998uL, + 0xB0D09822uL, + 0xC7D7A8B4uL, + 0x59B33D17uL, + 0x2EB40D81uL, + 0xB7BD5C3BuL, + 0xC0BA6CADuL, + 0xEDB88320uL, + 0x9ABFB3B6uL, + 0x03B6E20CuL, + 0x74B1D29AuL, + 0xEAD54739uL, + 0x9DD277AFuL, + 0x04DB2615uL, + 0x73DC1683uL, + 0xE3630B12uL, + 0x94643B84uL, + 0x0D6D6A3EuL, + 0x7A6A5AA8uL, + 0xE40ECF0BuL, + 0x9309FF9DuL, + 0x0A00AE27uL, + 0x7D079EB1uL, + 0xF00F9344uL, + 0x8708A3D2uL, + 0x1E01F268uL, + 0x6906C2FEuL, + 0xF762575DuL, + 0x806567CBuL, + 0x196C3671uL, + 0x6E6B06E7uL, + 0xFED41B76uL, + 0x89D32BE0uL, + 0x10DA7A5AuL, + 0x67DD4ACCuL, + 0xF9B9DF6FuL, + 0x8EBEEFF9uL, + 0x17B7BE43uL, + 0x60B08ED5uL, + 0xD6D6A3E8uL, + 0xA1D1937EuL, + 0x38D8C2C4uL, + 0x4FDFF252uL, + 0xD1BB67F1uL, + 0xA6BC5767uL, + 0x3FB506DDuL, + 0x48B2364BuL, + 0xD80D2BDAuL, + 0xAF0A1B4CuL, + 0x36034AF6uL, + 0x41047A60uL, + 0xDF60EFC3uL, + 0xA867DF55uL, + 0x316E8EEFuL, + 0x4669BE79uL, + 0xCB61B38CuL, + 0xBC66831AuL, + 0x256FD2A0uL, + 0x5268E236uL, + 0xCC0C7795uL, + 0xBB0B4703uL, + 0x220216B9uL, + 0x5505262FuL, + 0xC5BA3BBEuL, + 0xB2BD0B28uL, + 0x2BB45A92uL, + 0x5CB36A04uL, + 0xC2D7FFA7uL, + 0xB5D0CF31uL, + 0x2CD99E8BuL, + 0x5BDEAE1DuL, + 0x9B64C2B0uL, + 0xEC63F226uL, + 0x756AA39CuL, + 0x026D930AuL, + 0x9C0906A9uL, + 0xEB0E363FuL, + 0x72076785uL, + 0x05005713uL, + 0x95BF4A82uL, + 0xE2B87A14uL, + 0x7BB12BAEuL, + 0x0CB61B38uL, + 0x92D28E9BuL, + 0xE5D5BE0DuL, + 0x7CDCEFB7uL, + 0x0BDBDF21uL, + 0x86D3D2D4uL, + 0xF1D4E242uL, + 0x68DDB3F8uL, + 0x1FDA836EuL, + 0x81BE16CDuL, + 0xF6B9265BuL, + 0x6FB077E1uL, + 0x18B74777uL, + 0x88085AE6uL, + 0xFF0F6A70uL, + 0x66063BCAuL, + 0x11010B5CuL, + 0x8F659EFFuL, + 0xF862AE69uL, + 0x616BFFD3uL, + 0x166CCF45uL, + 0xA00AE278uL, + 0xD70DD2EEuL, + 0x4E048354uL, + 0x3903B3C2uL, + 0xA7672661uL, + 0xD06016F7uL, + 0x4969474DuL, + 0x3E6E77DBuL, + 0xAED16A4AuL, + 0xD9D65ADCuL, + 0x40DF0B66uL, + 0x37D83BF0uL, + 0xA9BCAE53uL, + 0xDEBB9EC5uL, + 0x47B2CF7FuL, + 0x30B5FFE9uL, + 0xBDBDF21CuL, + 0xCABAC28AuL, + 0x53B39330uL, + 0x24B4A3A6uL, + 0xBAD03605uL, + 0xCDD70693uL, + 0x54DE5729uL, + 0x23D967BFuL, + 0xB3667A2EuL, + 0xC4614AB8uL, + 0x5D681B02uL, + 0x2A6F2B94uL, + 0xB40BBE37uL, + 0xC30C8EA1uL, + 0x5A05DF1BuL, + 0x2D02EF8DuL}; + +/******************************************************************************* + * the functions + ******************************************************************************/ + +/*! \brief Get boot request flag from app + * + * This function get the boot request event that is from app + * + * \param[in] void + * + * \return void + */ +static bool Bootloader_GetBootReq(void) +{ + bool ret = true; + + /* Make sure the read action for no-init ram zone is in system reset happen */ + if(ResetDrv_IsResetCaused(&mcu.resetDrv, RESETDRV_SOURCE_POR) == false) + { + if(ResetDrv_IsResetCaused(&mcu.resetDrv, RESETDRV_SOURCE_SYS) == true) + { + if(sBootloader_Req != BOOTLOADER_CFG_REQ_ACTIVE) + { + ret = false; + } + else + { + sBootloader_Req = 0; + } + } + else + { + ret = false; + } + } + else + { + ret = false; + } + + return ret; +} + +/*! \brief Get boot block size bytes + * + * This function get the pgm block byte size + * + * \param[in] void + * + * \return void + */ +uint32_t Bootloader_GetPgmBlockSize(void) +{ + return BOOTLOADER_CFG_PGM_BYTES_SIZE; +} + +/*! \brief Calculate the app crc + * + * This function get the boot request event that is from app + * + * \param[in] initCrcValue : the old crc value + * \param[in] dataBuffer : the start addresss to take in calculating crc + * \param[in] bytesNum : how many bytes to be take in + * + * \return the calculate the crc value + */ +static uint32_t Bootloader_CalculateCheckSum(uint32_t initCrcValue, const uint8_t *dataBuffer, uint32_t bytesNum, bool inverted) +{ + uint32_t tCrc = initCrcValue; + uint32_t i = 0; + + for(i = 0; i < bytesNum; i++) + { + tCrc = crc32_table[(tCrc ^ dataBuffer[i]) & 0xff] ^ (tCrc >> 8); + } + + if(inverted == true) + { + tCrc = 0xFFFFFFFF - tCrc; + } + + return tCrc; +} + +/*! \brief Jump to app + * + * This function jump to app from boot + * + * \param[in] void + * + * \return void + */ +static void Bootloader_JumpToApp(void) +{ + uint32_t appEntry = 0, appStack = 0; + static uint32_t statckPointer = 0; + static void (*pJumpToApp)(void); + + IrqDrv_DisableGlobalInterrupt(); + FlexCanDrv_SoftReset(&mcu.flexCanDrv); + memset(&sBootloader_Cb, 0, sizeof(sBootloader_Cb)); + /* MSP */ + appStack = *(uint32_t *)BOOTLOADER_CFG_APP_START_ADDR; + /* PC */ + appEntry = *(uint32_t *)(BOOTLOADER_CFG_APP_START_ADDR + 4); + + pJumpToApp = (void (*)(void))appEntry; + statckPointer = appStack; + /* Set the MSP */ + __set_PSP(statckPointer); + __set_MSP(statckPointer); + + SCB->VTOR = (uint32_t)BOOTLOADER_CFG_APP_START_ADDR; + /* Jump action */ + pJumpToApp(); +} + +/*! \brief Reset the cpu + * + * This function reset the cpu if get reset request + * + * \param[in] void + * + * \return void + */ +static void Bootloader_Reset(void) +{ + /* TODO */ + memset(&sBootloader_Cb, 0, sizeof(sBootloader_Cb)); + IrqDrv_DisableGlobalInterrupt();//关闭中断,不加会导致无法复位 + ResetDrv_SoftwareResetModule(&mcu.resetDrv, RESETDRV_SWRESET_SYS); +} + +/*! \brief Reset the cpu + * + * This function reset the cpu if get reset request + * + * \param[in] void + * + * \return void + */ +static void Bootloader_HardReset(void) +{ + /* TODO */ + SBC_Write_RegField(SBC_M_S_CTRL, SBC_M_S_CTRL_MODE_Msk, SBC_M_S_CTRL_MODE_Pos, SBC_MODE_RESET, NULL); +} + +/*! \brief pgm positive respose to eol + * + * This function response to EOL when finished the current block data pgm + * + * \param[in] void + * + * \return void + */ +static void Bootloader_PositiveResp(void) +{ + uint8_t rspBuffer[8]; + + rspBuffer[0] = 0x76; + rspBuffer[1] = sBootloader_Cb.pgmInfo.pgmBlockSn; + + sBootloader_Cb.positiveRespFunction(sBootloader_Cb.udsObj, rspBuffer, 2); +} + +/*! \brief pgm negative respose to eol + * + * This function response to EOL when finished the current block data pgm + * + * \param[in] sid : service id + * \param[in] nrc : negative response code + * + * \return void + */ +static void Bootloader_NegativeResp(uint8_t sid, uint8_t nrc) +{ + sBootloader_Cb.negativeRespFunction(sBootloader_Cb.udsObj, sid, nrc); +} + +/*! \brief Update the flash driver if the flash driver is from outside + * + * This function update the flash driver interface address and init the flash module + * + * \param[in] void + * + * \return void + */ +void Bootloader_FlsDrvUpdate(void) +{ +#if BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 0u + uint32_t localCrc = 0; + uint8_t i = 0; + sBootloader_Cb.flsDrvInfo.flashDriverDownloaded = false; + /* Read out the flash driver first 4words data */ + sBootloader_Cb.flsDrvInfo.startFlsInitAddr = *((uint32_t *)(BOOTLOADER_CFG_FLS_DRV_RAM_START_ADDR + 4)); + sBootloader_Cb.flsDrvInfo.startFlsEraseAddr = *((uint32_t *)(BOOTLOADER_CFG_FLS_DRV_RAM_START_ADDR + 8)); + sBootloader_Cb.flsDrvInfo.startFlsPgmAddr = *((uint32_t *)(BOOTLOADER_CFG_FLS_DRV_RAM_START_ADDR + 12)); + + /* Check the current download data is for flash driver */ + if((sBootloader_Cb.pgmInfo.pgmStartAddress == BOOTLOADER_CFG_FLS_DRV_RAM_START_ADDR) && (sBootloader_Cb.pgmInfo.pgmMemSize == (BOOTLOADER_CFG_FLS_DRV_RAM_CODE_SIZE + BOOTLOADER_CFG_FLS_DRV_RAM_CRC_SIZE))) + { + sBootloader_Cb.pgmInfo.pgmCrc = Bootloader_CalculateCheckSum(BOOTLOADER_CFG_INIT_CRC_VALUE, + (const uint8_t *)sBootloader_Cb.pgmInfo.pgmStartAddress, + sBootloader_Cb.pgmInfo.pgmMemSize - BOOTLOADER_CFG_FLS_DRV_RAM_CRC_SIZE, + true); + } + /* + for(i = 0; i< 4; i++) + { + localCrc <<= 8; + localCrc += (*((uint8_t *)(BOOTLOADER_CFG_FLS_DRV_RAM_CRC_ADDR + i))); + } + */ + localCrc = (*((uint8_t *)BOOTLOADER_CFG_FLS_DRV_RAM_CRC_ADDR)); + + if(sBootloader_Cb.pgmInfo.pgmCrc == localCrc) + { + sBootloader_Cb.flsDrvInfo.pFls_InitFunction = (pFls_InitFunctionPtr)sBootloader_Cb.flsDrvInfo.startFlsInitAddr; + sBootloader_Cb.flsDrvInfo.pFls_EraseFunction = (pFls_EraseFunctionPtr)sBootloader_Cb.flsDrvInfo.startFlsEraseAddr; + sBootloader_Cb.flsDrvInfo.pFls_WriteFunction = (pFls_WriteFunctionPtr)sBootloader_Cb.flsDrvInfo.startFlsPgmAddr; + + sBootloader_Cb.flsDrvInfo.pFls_InitFunction(sBootloader_Cb.flashDrvObj); + sBootloader_Cb.flsDrvInfo.flashDriverDownloaded = true; + } + +#endif +} + +/*! \brief Bootloader init state process + * + * This function check the boot request is existed or not + * + * \param[in] void + * + * \return void + */ +static void Bootloader_InitState(void) +{ + if(sBootloader_Cb.bootSubState == BOOTLOADER_SUB_STATE_NONE) + { + if((sBootloader_Cb.emergeBootReqEn == true) || (sBootloader_Cb.bootActive == true)) + { + /* Emerge boot request */ + sBootloader_Cb.stayInBootTimeoutCnt = 0; +#if BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 0u + sBootloader_Cb.flsDrvInfo.flashDriverDownloaded = false; +#endif + sBootloader_Cb.bootActive = true; + sBootloader_Cb.bootSubState = BOOTLOADER_SUB_STATE_END; + sBootloader_Cb.udsObj->session = UDS_SESSION_PROGRAMMING; + } + else + { + Bootloader_SetBootState(BOOTLOADER_STATE_CHECK); + } + } +} + +/*! \brief Bootloader erase state process + * + * This function excute the action if bootloader is in erase flash state + * + * \param[in] void + * + * \return void + */ +static void Bootloader_EraseState(void) +{ + if((sBootloader_Cb.bootSubState == BOOTLOADER_SUB_STATE_NONE) || (sBootloader_Cb.bootSubState == BOOTLOADER_SUB_STATE_DOING)) + { + if(sBootloader_Cb.eraseInfo.eraseSectionNums > 0u) + { + if(sBootloader_Cb.eraseInfo.eraseSectionCnt < sBootloader_Cb.eraseInfo.eraseSectionNums) + { + Fls_StdRtnType ret = FLS_STD_RETURN_OK; + uint32_t eraseStartAddress = sBootloader_Cb.eraseInfo.eraseStartAddress; + + if(sBootloader_Cb.downloadObj != BOOLOADER_OBJECT_FLASH_DRIVER) + { + /* Make sure no interrupt during erasing action, so disable global */ + IrqDrv_DisableGlobalInterrupt(); +#if BOOTLOADER_CFG_ERASE_SECTOR_NUM == BOOTLOADER_CFG_ERASE_ALL + + /* First erase App Head then erased other sectors */ +#if BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u + ret = Fls_Erase(sBootloader_Cb.eraseInfo.eraseStartAddress, 1); +#else + /* Check flash driver has been download into ram */ + if(sBootloader_Cb.flsDrvInfo.flashDriverDownloaded == true) + { + ret = sBootloader_Cb.flsDrvInfo.pFls_EraseFunction(sBootloader_Cb.eraseInfo.eraseStartAddress, 1); + } + else + { + ret = FLS_STD_RETURN_FLASH_DRIVER_INVALID; + } +#endif + + if(ret == FLS_STD_RETURN_OK) + { + /* Erase other sectors */ +#if BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u + ret = Fls_Erase(eraseStartAddress + FLS_ERASE_SECTION_SIZE, + sBootloader_Cb.eraseInfo.eraseSectionNums - 1u); +#else + ret = sBootloader_Cb.flsDrvInfo.pFls_EraseFunction(eraseStartAddress + FLS_ERASE_SECTION_SIZE, + sBootloader_Cb.eraseInfo.eraseSectionNums - 1u); +#endif + } +#else + uint32_t eraseSectorNums = 0; + eraseStartAddress = sBootloader_Cb.eraseInfo.eraseStartAddress + (sBootloader_Cb.eraseInfo.eraseSectionCnt * FLS_ERASE_SECTION_SIZE); + + /* Check out the rest sector nums is more than the once-erased nums, if not, erased the rest sector nums */ + eraseSectorNums = sBootloader_Cb.eraseInfo.eraseSectionNums - sBootloader_Cb.eraseInfo.eraseSectionCnt; + if(eraseSectorNums > BOOTLOADER_CFG_ERASE_SECTOR_NUM) + { + eraseSectorNums = BOOTLOADER_CFG_ERASE_SECTOR_NUM; + } + +#if BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u + ret = Fls_Erase(eraseStartAddress, + eraseSectorNums); +#else + /* Check flash driver has been download into ram */ + if(sBootloader_Cb.flsDrvInfo.flashDriverDownloaded == true) + { + ret = sBootloader_Cb.flsDrvInfo.pFls_EraseFunction(eraseStartAddress, + eraseSectorNums); + } + else + { + ret = FLS_STD_RETURN_FLASH_DRIVER_INVALID; + } +#endif + +#endif + /* After erased, restored the global interrupt */ + IrqDrv_EnableGlobalInterrupt(); + } + else + { +#if BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 0u + /* Clear flash driver in ram */ + memset((uint8_t *)BOOTLOADER_CFG_FLS_DRV_RAM_START_ADDR, 0, BOOTLOADER_CFG_FLS_DRV_RAM_CODE_SIZE + BOOTLOADER_CFG_FLS_DRV_RAM_CRC_SIZE); +#endif + } + + if(ret == FLS_STD_RETURN_OK) + { +#if BOOTLOADER_CFG_ERASE_SECTOR_NUM == BOOTLOADER_CFG_ERASE_ALL + /* Erased action has been finished */ + sBootloader_Cb.bootSubState = BOOTLOADER_SUB_STATE_END; + sBootloader_Cb.eraseInfo.eraseSectionNums = 0; + sBootloader_Cb.eraseInfo.eraseLength = 0; + sBootloader_Cb.eraseInfo.eraseSectionCnt = 0; +#else + sBootloader_Cb.eraseInfo.eraseSectionCnt += BOOTLOADER_CFG_ERASE_SECTOR_NUM; + if(sBootloader_Cb.eraseInfo.eraseSectionCnt >= sBootloader_Cb.eraseInfo.eraseSectionNums) + { + /* Erased action has been finished */ + sBootloader_Cb.bootSubState = BOOTLOADER_SUB_STATE_END; + sBootloader_Cb.eraseInfo.eraseSectionNums = 0; + sBootloader_Cb.eraseInfo.eraseLength = 0; + sBootloader_Cb.eraseInfo.eraseSectionCnt = 0; + } + else + { + sBootloader_Cb.bootSubState = BOOTLOADER_SUB_STATE_DOING; + } +#endif + } + else + { + sBootloader_Cb.eraseInfo.eraseSectionNums = 0; + sBootloader_Cb.eraseInfo.eraseLength = 0; + sBootloader_Cb.eraseInfo.eraseSectionCnt = 0; + Bootloader_SetBootState(BOOTLOADER_STATE_ERR); + } + } + } + } + else + { + /* Nothing to do , just wait for the next event */ + } +} + +/*! \brief Bootloader program flash state process + * + * This function excute the action if bootloader is in programming flash state + * + * \param[in] void + * + * \return void + */ +static void Bootloader_PgmState(void) +{ + if(((sBootloader_Cb.pgmInfo.pgmReadyEn == true) && ((sBootloader_Cb.bootSubState == BOOTLOADER_SUB_STATE_NONE) || (sBootloader_Cb.bootSubState == BOOTLOADER_SUB_STATE_DOING)))) + { + /* if received one frame datas to be need to download to mcu */ + if(sBootloader_Cb.pgmInfo.pgmStartTriggerEn == true) + { + if(sBootloader_Cb.pgmInfo.pgmMemCnt < sBootloader_Cb.pgmInfo.pgmMemSize) + { + Fls_StdRtnType ret = FLS_STD_RETURN_OK; + + if(sBootloader_Cb.downloadObj != BOOLOADER_OBJECT_FLASH_DRIVER) + { + uint8_t pgmPackageCnt = 0, i = 0; + + pgmPackageCnt = (BOOTLOADER_CFG_PGM_BYTES_SIZE + FLS_PGM_SECTION_SIZE - 1u) / FLS_PGM_SECTION_SIZE; + IrqDrv_DisableGlobalInterrupt(); + +#if BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u + for (i = 0; i< pgmPackageCnt;i++) + { + ret = Fls_Write(sBootloader_Cb.pgmInfo.pgmStartAddress + sBootloader_Cb.pgmInfo.pgmMemCnt + i * FLS_PGM_SECTION_SIZE, + (const uint8_t *)&sBootloader_Cb.pgmInfo.pgmData[i * FLS_PGM_SECTION_SIZE], + FLS_PGM_SECTION_SIZE); + + if (ret != FLS_STD_RETURN_OK) + { + break; + } + } +#else + /* Check flash driver has been download into ram */ + if(sBootloader_Cb.flsDrvInfo.flashDriverDownloaded == true) + { + for(i = 0; i < pgmPackageCnt; i++) + { + ret = sBootloader_Cb.flsDrvInfo.pFls_WriteFunction(sBootloader_Cb.pgmInfo.pgmStartAddress + sBootloader_Cb.pgmInfo.pgmMemCnt + i * FLS_PGM_SECTION_SIZE, + (const uint8_t *)&sBootloader_Cb.pgmInfo.pgmData[i * FLS_PGM_SECTION_SIZE], + FLS_PGM_SECTION_SIZE); + + if(ret != FLS_STD_RETURN_OK) + { + break; + } + } + } + else + { + ret = FLS_STD_RETURN_FLASH_DRIVER_INVALID; + } +#endif + IrqDrv_EnableGlobalInterrupt(); + } + else + { +#if BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u + /* Nothing to do, no need to copy flash driver from outer side */ +#else + /* Copy flash driver into ram */ + memcpy((uint8_t *)(sBootloader_Cb.pgmInfo.pgmStartAddress + sBootloader_Cb.pgmInfo.pgmMemCnt), + (const uint8_t *)sBootloader_Cb.pgmInfo.pgmData, + BOOTLOADER_CFG_PGM_BYTES_SIZE); +#endif + } + + if(ret == FLS_STD_RETURN_OK) + { + sBootloader_Cb.pgmInfo.pgmMemCnt += BOOTLOADER_CFG_PGM_BYTES_SIZE; + + if(sBootloader_Cb.pgmInfo.pgmMemCnt >= sBootloader_Cb.pgmInfo.pgmMemSize) + { + sBootloader_Cb.pgmInfo.pgmReadyEn = false; + sBootloader_Cb.bootSubState = BOOTLOADER_SUB_STATE_END; + } + else + { + sBootloader_Cb.bootSubState = BOOTLOADER_SUB_STATE_DOING; + } + + /* Indicate the EOL thant it can transfer the next block data to be written */ + Bootloader_PositiveResp(); + } + else + { + sBootloader_Cb.pgmInfo.pgmReadyEn = false; + sBootloader_Cb.pgmInfo.pgmMemSize = 0; + sBootloader_Cb.pgmInfo.pgmMemCnt = 0; + Bootloader_SetBootState(BOOTLOADER_STATE_ERR); + } + + /* Clear the download trigger event, wait for the next download data if need */ + sBootloader_Cb.pgmInfo.pgmStartTriggerEn = false; + sBootloader_Cb.pgmInfo.pgmBlockByteCnt = 0; + } + } + } + else + { + /* Nothing to do , just wait for the next event */ + } +} + +/*! \brief Bootloader check state process + * + * This function excute the action if bootloader is in check state + * + * \param[in] void + * + * \return void + */ +static void Bootloader_CheckState(void) +{ + if((sBootloader_Cb.bootSubState == BOOTLOADER_SUB_STATE_NONE) || (sBootloader_Cb.bootSubState == BOOTLOADER_SUB_STATE_DOING)) + { + sBootloader_Cb.bootSubState = BOOTLOADER_SUB_STATE_DOING; + if((sBootloader_Cb.downloadObj == BOOLOADER_OBJECT_APP_CODE) || (sBootloader_Cb.downloadObj == BOOLOADER_OBJECT_NONE)) + { + if((Fls_CheckWriteState(BOOTLOADER_CFG_APP_HEAD_ADDR) == FLS_STD_RETURN_OK) && (Fls_CheckWriteState(BOOTLOADER_CFG_APP_CRC_ADDR - 4u) == FLS_STD_RETURN_OK)) + { + /* Check App Head */ + if((*((uint32_t *)BOOTLOADER_CFG_APP_HEAD_ADDR)) != BOOTLOADER_CFG_HEAD_MASK) + { + /* Active mcu enter into boot */ + sBootloader_Cb.bootActive = true; + sBootloader_Cb.bootSubState = BOOTLOADER_SUB_STATE_END; + sBootloader_Cb.pgmInfo.crcResult = false; + } + else + { + uint32_t localCrc = (*((uint32_t *)BOOTLOADER_CFG_APP_CRC_ADDR)); + uint32_t app_size = (*((uint32_t *)(BOOTLOADER_CFG_APP_CRC_ADDR-4))) - BOOTLOADER_CFG_APP_START_ADDR; + + if (app_size < 0x28000 && app_size > 0x4000) + { + sBootloader_Cb.pgmInfo.pgmCrc = Bootloader_CalculateCheckSum(BOOTLOADER_CFG_INIT_CRC_VALUE, + (const uint8_t *)BOOTLOADER_CFG_APP_START_ADDR, + app_size, + true); + } + else + { + sBootloader_Cb.pgmInfo.pgmCrc = 0; + } + + + if(localCrc != sBootloader_Cb.pgmInfo.pgmCrc) + { + /* Active mcu enter into boot */ + sBootloader_Cb.bootActive = true; + sBootloader_Cb.bootSubState = BOOTLOADER_SUB_STATE_END; + sBootloader_Cb.pgmInfo.crcResult = false; + } + else + { + sBootloader_Cb.pgmInfo.crcResult = true; + /* If the current app is ok and no bootloader process action, then enter into exit state */ + if(sBootloader_Cb.bootActive == false) + { + Bootloader_SetBootState(BOOTLOADER_STATE_EXIT); + } + else + { + /* Stay in check state, wait for next command */ + sBootloader_Cb.bootActive = true; + sBootloader_Cb.bootSubState = BOOTLOADER_SUB_STATE_END; + } + } + } + } + else + { + /* Active mcu enter into boot */ + sBootloader_Cb.bootActive = true; + sBootloader_Cb.bootSubState = BOOTLOADER_SUB_STATE_END; + sBootloader_Cb.pgmInfo.crcResult = false; + } + } + else if(sBootloader_Cb.downloadObj == BOOLOADER_OBJECT_CALIBRATION_DATA) + { + } +#if BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 0u + else if(sBootloader_Cb.downloadObj == BOOLOADER_OBJECT_FLASH_DRIVER) + { + Bootloader_FlsDrvUpdate(); + if(sBootloader_Cb.flsDrvInfo.flashDriverDownloaded == true) + { + sBootloader_Cb.pgmInfo.crcResult = true; + sBootloader_Cb.bootSubState = BOOTLOADER_SUB_STATE_END; + } + else + { + sBootloader_Cb.pgmInfo.crcResult = false; + sBootloader_Cb.bootSubState = BOOTLOADER_SUB_STATE_END; + } + } +#else + else if(sBootloader_Cb.downloadObj == BOOLOADER_OBJECT_FLASH_DRIVER) + { + sBootloader_Cb.pgmInfo.crcResult = true; + sBootloader_Cb.bootSubState = BOOTLOADER_SUB_STATE_END; + } +#endif + } + else + { + /* Nothing to do , just wait for the next event */ + } +} + +/*! \brief Bootloader exit state process + * + * This function excute the action if bootloader is in exist state + * + * \param[in] void + * + * \return void + */ +static void Bootloader_ExitState(void) +{ + if((sBootloader_Cb.bootSubState == BOOTLOADER_SUB_STATE_NONE) || (sBootloader_Cb.bootSubState == BOOTLOADER_SUB_STATE_DOING)) + { + if((sBootloader_Cb.stayInBootTimeoutCnt >= BOOTLOADER_CFG_BOOT_DURATION_MS) && (sBootloader_Cb.bootActive == false)) + { + SEGGER_RTT_printf(0,"-----JumpToApp-----\n"); + /* Disable wdg */ + + /* Disable global interrupt */ + IrqDrv_DisableGlobalInterrupt(); + + /* Jump to App */ + Bootloader_JumpToApp(); + } + else + { + sBootloader_Cb.bootSubState = BOOTLOADER_SUB_STATE_DOING; + } + } + else + { + /* Nothing to do , just wait for the next event */ + } +} + +/*! \brief Bootloader error state process + * + * This function excute the action if bootloader is in errored state + * + * \param[in] void + * + * \return void + */ +static void Bootloader_ErrorState(void) +{ + /* TODO: */ + if((sBootloader_Cb.bootSubState == BOOTLOADER_SUB_STATE_NONE) || (sBootloader_Cb.bootSubState == BOOTLOADER_SUB_STATE_DOING)) + { + /* TODO: */ + } + else + { + /* Nothing to do , just wait for the next event */ + } +} + +/*! \brief Initialize bootloader control block information + * + * This function Initialize bootloader control block information + * + * \param[in] obj : flashdriver instance + * \param[in] udsObj : uds instance + * \param[in] positiveRespFunction : uds positve response interface + * \param[in] negativeRespFunction : uds negative response interface + * + * \return void + */ +void Bootloader_Init(FlashDrvType *obj, UdsType *udsObj, pUds_PositiveResponsePtr positiveRespFunction, pUds_NegativeResponsePtr negativeRespFunction) +{ + memset(&sBootloader_Cb, 0, sizeof(sBootloader_Cb)); + +#if BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 0u + /* Clear flash driver in ram */ + memset((uint8_t *)BOOTLOADER_CFG_FLS_DRV_RAM_START_ADDR, 0, BOOTLOADER_CFG_FLS_DRV_RAM_CODE_SIZE + BOOTLOADER_CFG_FLS_DRV_RAM_CRC_SIZE); +#endif + + sBootloader_Cb.flashDrvObj = obj; + sBootloader_Cb.udsObj = udsObj; + sBootloader_Cb.positiveRespFunction = positiveRespFunction; + sBootloader_Cb.negativeRespFunction = negativeRespFunction; + sBootloader_Cb.pgmInfo.pgmCrc = 0; + +#if BOOTLOADER_CFG_FLS_COPY_AUTO_EN != 0u + Fls_Init(obj); +#else + /* Update the flash instance */ + *((uint32_t *)BOOTLOADER_CFG_FLS_DRV_RAM_START_ADDR) = (uint32_t)obj; +#endif + + if(Bootloader_GetBootReq() == true) + { + /* Emerge boot request */ + sBootloader_Cb.stayInBootTimeoutCnt = 0; + sBootloader_Cb.bootActive = true; + sBootloader_Cb.udsObj->session = UDS_SESSION_PROGRAMMING; + } +} + +/*! \brief Set the bootloader into the target state + * + * This function Set the bootloader into the target state + * + * \param[in] state : the target state to be switch to + * + * \return void + */ +void Bootloader_SetBootState(Bootloader_StateType state) +{ + sBootloader_Cb.bootSubState = BOOTLOADER_SUB_STATE_NONE; + sBootloader_Cb.bootState = state; + sBootloader_Cb.stayInBootTimeoutCnt = 0; +} + +/*! \brief Get the bootloader current state + * + * This function Get the bootloader current state + * + * \param[in] void + * + * \return : return the current state + */ +Bootloader_StateType Bootloader_GetBootState(void) +{ + return sBootloader_Cb.bootState; +} + +/*! \brief Get the bootloader current sub state + * + * This function Get the bootloader current sub state + * + * \param[in] void + * + * \return : return the current sub state + */ +Bootloader_SubStateType Bootloader_GetBootSubState(void) +{ + return sBootloader_Cb.bootSubState; +} + +/*! \brief Get the bootloader current crc result + * + * This function Get the bootloader current crc result + * + * \param[in] void + * + * \return : return the current crc result + */ +bool Bootloader_GetCrcResult(void) +{ + return sBootloader_Cb.pgmInfo.crcResult; +} + +/*! \brief Set emerge boot request + * + * This function Set emerge boot request + * + * \param[in] void + * + * \return void + */ +void Bootloader_EventEmergeBootRequest(bool requestEn) +{ + if(sBootloader_Cb.bootActive == false) + { + sBootloader_Cb.emergeBootReqEn = requestEn; + sBootloader_Cb.stayInBootTimeoutCnt = 0; + sBootloader_Cb.bootActive = true; +#if BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 0u + sBootloader_Cb.flsDrvInfo.flashDriverDownloaded = false; +#endif + } + + /* Set the current state into end sub state */ + sBootloader_Cb.bootSubState = BOOTLOADER_SUB_STATE_END; +} + +/*! \brief Set the reset cup request + * + * This function Set the reset cup request + * + * \param[in] void + * + * \return void + */ +void Bootloader_EventResetRequest(bool requestEn,uint8_t resetMode) +{ + sBootloader_Cb.resetReqEn = requestEn; + sBootloader_Cb.resetReqMode = resetMode; +#if BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 0u + sBootloader_Cb.flsDrvInfo.flashDriverDownloaded = false; +#endif +} + +/*! \brief Set the erase information + * + * This function set the erase information about where to be start to be erased and how many bytes to be erased + * + * \param[in] startAddress : where to be start to be erased + * \param[in] bytesNum : how many bytes to be erased + * + * \return void + */ +void Bootloader_EventEraseRequest(uint32_t startAddress, uint32_t bytesNum) +{ + sBootloader_Cb.eraseInfo.eraseLength = bytesNum; + sBootloader_Cb.eraseInfo.eraseStartAddress = startAddress; + sBootloader_Cb.pgmInfo.pgmStartTriggerEn = false; + sBootloader_Cb.pgmInfo.pgmReadyEn = false; + + /* Update the dowmloader object */ + if((startAddress == BOOTLOADER_CFG_APP_START_ADDR) && (bytesNum == (BOOTLOADER_CFG_APP_SIZE + BOOTLOADER_CFG_APP_CRC_SIZE))) + { + sBootloader_Cb.downloadObj = BOOLOADER_OBJECT_APP_CODE; + sBootloader_Cb.eraseInfo.eraseSectionNums = (sBootloader_Cb.eraseInfo.eraseLength + FLS_ERASE_SECTION_ADDR_ALIGNED_MASK) / FLS_ERASE_SECTION_SIZE; + } + else if((startAddress == BOOTLOADER_CFG_CALIBRATION_DATA_START_ADDR) && (bytesNum == (BOOTLOADER_CFG_CALIBRATION_DATA_SIZE + BOOTLOADER_CFG_CALIBRATION_DATA_CRC_SIZE))) + { + sBootloader_Cb.downloadObj = BOOLOADER_OBJECT_CALIBRATION_DATA; + sBootloader_Cb.eraseInfo.eraseSectionNums = (sBootloader_Cb.eraseInfo.eraseLength + FLS_ERASE_SECTION_ADDR_ALIGNED_MASK) / FLS_ERASE_SECTION_SIZE; + } +#if BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 0u + else if((startAddress == BOOTLOADER_CFG_FLS_DRV_RAM_START_ADDR) && (bytesNum <= (BOOTLOADER_CFG_FLS_DRV_RAM_CODE_SIZE + BOOTLOADER_CFG_FLS_DRV_RAM_CRC_SIZE))) + { + sBootloader_Cb.downloadObj = BOOLOADER_OBJECT_FLASH_DRIVER; + sBootloader_Cb.flsDrvInfo.flashDriverDownloaded = false; + sBootloader_Cb.eraseInfo.eraseSectionNums = ((BOOTLOADER_CFG_FLS_DRV_RAM_CODE_SIZE + BOOTLOADER_CFG_FLS_DRV_RAM_CRC_SIZE) + FLS_ERASE_SECTION_ADDR_ALIGNED_MASK) / FLS_ERASE_SECTION_SIZE; + } +#else + else if((startAddress == BOOTLOADER_CFG_FLS_DRV_RAM_START_ADDR) && (bytesNum <= (BOOTLOADER_CFG_FLS_DRV_RAM_CODE_SIZE + BOOTLOADER_CFG_FLS_DRV_RAM_CRC_SIZE))) + { + sBootloader_Cb.downloadObj = BOOLOADER_OBJECT_FLASH_DRIVER; + sBootloader_Cb.eraseInfo.eraseSectionNums = ((BOOTLOADER_CFG_FLS_DRV_RAM_CODE_SIZE + BOOTLOADER_CFG_FLS_DRV_RAM_CRC_SIZE) + FLS_ERASE_SECTION_ADDR_ALIGNED_MASK) / FLS_ERASE_SECTION_SIZE; + } +#endif + + Bootloader_SetBootState(BOOTLOADER_STATE_ERASE); +} + +/*! \brief Set program information + * + * This function Set program information about where to be start to be write and how many bytes to be write + * + * \param[in] startAddress : where to be start to be write + * \param[in] bytesNum : how many bytes to be write + * + * \return void + */ +void Bootloader_EventPgmReady(uint32_t startAddress, uint32_t bytesNum) +{ + sBootloader_Cb.pgmInfo.pgmReadyEn = true; + sBootloader_Cb.pgmInfo.pgmStartTriggerEn = false; + sBootloader_Cb.pgmInfo.pgmStartAddress = startAddress; + sBootloader_Cb.pgmInfo.pgmMemSize = bytesNum; + sBootloader_Cb.pgmInfo.pgmMemCnt = 0; + + Bootloader_SetBootState(BOOTLOADER_STATE_PGM); +} + +/*! \brief Trigger the pgm start + * + * This function indication that can be write datas into flash + * + * \param[in] pDatabuffer : stored the datas to be written into flash + * \param[in] bytesNum : how many bytes to be write into local buffer + * \param[in] blockSn : current block sn number + * + * \return true: ecu start to pgm, false: ecu don't start to pgm + */ +bool Bootloader_EventPgmData(const uint8_t *pDatabuffer, uint16_t bytesNum, uint8_t blockSn) +{ + uint32_t i = 0; + bool ret = false; + + /* Copy data into local */ + for(i = 0; i < bytesNum; i++) + { + sBootloader_Cb.pgmInfo.pgmData[sBootloader_Cb.pgmInfo.pgmBlockByteCnt + i] = pDatabuffer[i]; + } + + sBootloader_Cb.pgmInfo.pgmBlockByteCnt += bytesNum; + sBootloader_Cb.pgmInfo.pgmBlockSn = blockSn; + if(sBootloader_Cb.pgmInfo.pgmBlockByteCnt >= BOOTLOADER_CFG_PGM_BYTES_SIZE) + { + sBootloader_Cb.pgmInfo.pgmStartTriggerEn = true; + ret = true; + } + + return ret; +} + +/*! \brief data check request + * + * This function indication that data check request + * + * \param[in] void + * + * \return void + */ +void Bootloader_EventDataCheckRequest(void) +{ + sBootloader_Cb.bootSubState = BOOTLOADER_SUB_STATE_NONE; + sBootloader_Cb.bootState = BOOTLOADER_STATE_CHECK; + sBootloader_Cb.pgmInfo.crcResult = false; + sBootloader_Cb.pgmInfo.pgmCrc = 0; +} + +/*! \brief Bootloader main state process + * + * This function process the bootloader variant state + * + * \param[in] void + * + * \return void + */ +void Bootloader_StateProc(void) +{ + if(sBootloader_Cb.bootState < BOOTLOADER_STATE_NUM) + { + if(sBootloader_StateFuncTbl[sBootloader_Cb.bootState] != 0u) + { + sBootloader_StateFuncTbl[sBootloader_Cb.bootState](); + } + } +} + +/*! \brief Calculate the stay in boot duration + * + * This function calculate the timeout when before jump to app if app is ok + * + * \param[in] periodms : add in every period + * + * \return void + */ +void Bootloader_TimingProcess(uint8_t periodms) +{ + if((sBootloader_Cb.bootState == BOOTLOADER_STATE_INIT) || (sBootloader_Cb.bootState == BOOTLOADER_STATE_EXIT)) + { + sBootloader_Cb.stayInBootTimeoutCnt += periodms; + } + + if(sBootloader_Cb.resetReqEn == true) + { + sBootloader_Cb.resetReqEn = false; + if (sBootloader_Cb.resetReqMode == 1) + { + Bootloader_HardReset(); + Bootloader_Reset(); + } + else + { + Bootloader_Reset(); + } + + } +} diff --git a/cva_bootloader_m0118/src/bootloader/bootloader.h b/cva_bootloader_m0118/src/bootloader/bootloader.h new file mode 100644 index 0000000..a37013e --- /dev/null +++ b/cva_bootloader_m0118/src/bootloader/bootloader.h @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _BOOTLOADER_H_ +#define _BOOTLOADER_H_ + +/*! \brief Contains public interface to various functions related + * to the _BOOTLOADER module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ +#include +#include +#include "bootloader_cfg.h" +#include "fls.h" +#include "uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +typedef void (*pFls_InitFunctionPtr)(FlashDrvType *flashDrvPtr); +typedef Fls_StdRtnType (*pFls_EraseFunctionPtr)(uint32_t targetAddress, uint32_t sectorNum); +typedef Fls_StdRtnType (*pFls_WriteFunctionPtr)(uint32_t targetAddress, const uint8_t *sourceAddressPtr, uint32_t bytesNum); + +typedef void (*pUds_PositiveResponsePtr)(UdsType *udsObj, const uint8_t *data, uint16_t len); +typedef void (*pUds_NegativeResponsePtr)(UdsType *udsObj, uint8_t sid, uint8_t rsp_nrc); + +typedef enum +{ + BOOTLOADER_STATE_INIT = 0u, + BOOTLOADER_STATE_ERASE, + BOOTLOADER_STATE_PGM, + BOOTLOADER_STATE_ERR, + BOOTLOADER_STATE_CHECK, + BOOTLOADER_STATE_EXIT, + + BOOTLOADER_STATE_NUM +} Bootloader_StateType; + +typedef enum +{ + BOOLOADER_OBJECT_NONE = 0u, + BOOLOADER_OBJECT_APP_CODE, + BOOLOADER_OBJECT_CALIBRATION_DATA, + BOOLOADER_OBJECT_FLASH_DRIVER, + + BOOLOADER_OBJECT_NUM +} Bootloader_ObjectType; + +typedef enum +{ + BOOTLOADER_FLS_DRV_INIT = 0u, + BOOTLOADER_FLS_DRV_ERASE, + BOOTLOADER_FLS_DRV_WRITE, + BOOTLOADER_FLS_DRV_NUM +} Bootloader_FlsDriverType; + +typedef enum +{ + BOOTLOADER_SUB_STATE_NONE = 0u, + BOOTLOADER_SUB_STATE_DOING, + BOOTLOADER_SUB_STATE_END +} Bootloader_SubStateType; + +typedef enum +{ + BOOTLOADER_EVENT_NONE = 0u, + BOOTLOADER_EVENT_EMERGENCY_BOOT, + BOOTLOADER_EVENT_RESET, + BOOTLOADER_EVENT_ERASE, + BOOTLOADER_EVENT_PGM_READY, + BOOTLOADER_EVENT_PGM_START, + BOOTLOADER_EVENT_PGM_EXIT, + BOOTLOADER_EVENT_CHECK, + + BOOTLOADER_EVENT_NUM +} Bootloader_EventType; + +typedef struct +{ + uint32_t eraseStartAddress; + uint32_t eraseLength; + uint32_t eraseSectionNums; + uint32_t eraseSectionCnt; +} Bootloader_EraseInfoType; + +typedef struct +{ + uint32_t pgmStartAddress; + uint32_t pgmMemSize; + uint32_t pgmMemCnt; + uint32_t pgmBlockByteCnt; + uint8_t pgmBlockSn; + uint8_t pgmData[BOOTLOADER_CFG_PGM_BYTES_SIZE]; + uint32_t pgmCrc; + bool crcResult; + bool pgmReadyEn; + bool pgmStartTriggerEn; +} Bootloader_PgmInfoType; + +typedef struct +{ + uint32_t flashInstanceAddr; + uint32_t startFlsInitAddr; + uint32_t startFlsClearCommandStateAddr; + uint32_t startFlsCommandSequenceAddr; + uint32_t startFlsEraseAddr; + uint32_t startFlsPgmAddr; + pFls_InitFunctionPtr pFls_InitFunction; + pFls_EraseFunctionPtr pFls_EraseFunction; + pFls_WriteFunctionPtr pFls_WriteFunction; + bool flashDriverDownloaded; +} Bootloader_FlsDrvInfoType; + +typedef struct +{ + FlashDrvType *flashDrvObj; + UdsType *udsObj; + pUds_PositiveResponsePtr positiveRespFunction; + pUds_NegativeResponsePtr negativeRespFunction; + Bootloader_StateType bootState; + Bootloader_SubStateType bootSubState; + Bootloader_EraseInfoType eraseInfo; + Bootloader_PgmInfoType pgmInfo; + bool emergeBootReqEn; + bool resetReqEn; + uint8_t resetReqMode; + bool bootActive; + Bootloader_ObjectType downloadObj; + uint32_t stayInBootTimeoutCnt; +#if(BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 0u) + Bootloader_FlsDrvInfoType flsDrvInfo; +#endif + + Bootloader_EventType eventReq; +} Bootloader_CbType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ +/*! \brief Initialize bootloader control block information + * + * This function Initialize bootloader control block information + * + * \param[in] obj : flashdriver instance + * \param[in] udsInstance : uds instance + * \param[in] positiveRespFunction : uds positve response interface + * \param[in] negativeRespFunction : uds negative response interface + * + * \return void + */ +extern void Bootloader_Init(FlashDrvType *obj, UdsType *udsInstance, + pUds_PositiveResponsePtr positiveRespFunction, + pUds_NegativeResponsePtr negativeRespFunction); + +/*! \brief Get boot block size bytes + * + * This function get the pgm block byte size + * + * \param[in] void + * + * \return void + */ +extern uint32_t Bootloader_GetPgmBlockSize(void); + +/*! \brief Calculate the stay in boot duration + * + * This function calculate the timeout when before jump to app if app is ok + * + * \param[in] periodms : add in every period + * + * \return void + */ +extern void Bootloader_TimingProcess(uint8_t periodms); + +/*! \brief Set the bootloader into the target state + * + * This function Set the bootloader into the target state + * + * \param[in] state ��the target state to be switch to + * + * \return void + */ +extern void Bootloader_SetBootState(Bootloader_StateType state); + +/*! \brief Get the bootloader current state + * + * This function Get the bootloader current state + * + * \param[in] void + * + * \return : return the current state + */ +extern Bootloader_StateType Bootloader_GetBootState(void); + +/*! \brief Get the bootloader current sub state + * + * This function Get the bootloader current sub state + * + * \param[in] void + * + * \return : return the current sub state + */ +extern Bootloader_SubStateType Bootloader_GetBootSubState(void); + +/*! \brief Get the bootloader current crc result + * + * This function Get the bootloader current crc result + * + * \param[in] void + * + * \return : return the current crc result + */ +extern bool Bootloader_GetCrcResult(void); + +/*! \brief Set emerge boot request + * + * This function Set emerge boot request + * + * \param[in] void + * + * \return void + */ +extern void Bootloader_EventEmergeBootRequest(bool requestEn); + +/*! \brief Set the reset cup request + * + * This function Set the reset cup request + * + * \param[in] void + * + * \return void + */ +extern void Bootloader_EventResetRequest(bool requestEn,uint8_t resetMode); + +/*! \brief Set the erase information + * + * This function set the erase information about where to be start to be erased and how many bytes to be erased + * + * \param[in] startAddress : where to be start to be erased + * \param[in] bytesNum : how many bytes to be erased + * + * \return void + */ +extern void Bootloader_EventEraseRequest(uint32_t startAddress, uint32_t bytesNum); + +/*! \brief Set program information + * + * This function Set program information about where to be start to be write and how many bytes to be write + * + * \param[in] startAddress : where to be start to be write + * \param[in] bytesNum : how many bytes to be write + * + * \return void + */ +extern void Bootloader_EventPgmReady(uint32_t startAddress, uint32_t bytesNum); + +/*! \brief Trigger the pgm start + * + * This function indication that can be write datas into flash + * + * \param[in] pDatabuffer : stored the datas to be written into flash + * \param[in] bytesNum : how many bytes to be write into local buffer + * \param[in] blockSn : current block sn number + * + * \return true: ecu start to pgm, false: ecu don't start to pgm + */ +extern bool Bootloader_EventPgmData(const uint8_t *pDatabuffer, uint16_t bytesNum, uint8_t blockSn); + +/*! \brief data check request + * + * This function indication that data check request + * + * \param[in] void + * + * \return void + */ +extern void Bootloader_EventDataCheckRequest(void); + +/*! \brief Bootloader main state process + * + * This function process the bootloader variant state + * + * \param[in] void + * + * \return void + */ +extern void Bootloader_StateProc(void); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _BOOTLOADER_H_ */ diff --git a/cva_bootloader_m0118/src/bootloader/bootloader_cfg.h b/cva_bootloader_m0118/src/bootloader/bootloader_cfg.h new file mode 100644 index 0000000..19f66a1 --- /dev/null +++ b/cva_bootloader_m0118/src/bootloader/bootloader_cfg.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _BOOTLOADER_CFG_H_ +#define _BOOTLOADER_CFG_H_ + +/*! \brief Contains public interface to various functions related + * to the _BOOTLOADER_CFG module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +/* If want to Generate flash driver code in ram, enable the configuration; if not, disable the configuration */ +#define BOOTLOADER_CFG_FLS_CODE_GENERATE_EN (1u) +/* Copy flash driver from flash to ram to run if don't get flash driver from out side, only just for debug the flash driver */ +#define BOOTLOADER_CFG_FLS_COPY_AUTO_EN (1u) + +/* Indication value with boot loader request from asw */ +#define BOOTLOADER_CFG_REQ_ACTIVE (0x55AAAA55ul) +/* Asw code head id to show asw is not empty */ +#define BOOTLOADER_CFG_HEAD_MASK (0xAABBCCDDul) + +/* Once pgm block size bytes num to be written to flash */ +#define BOOTLOADER_CFG_PGM_BYTES_SIZE (2048) +/* The App flash start address, that stored the vector table for app */ +#define BOOTLOADER_CFG_APP_START_ADDR (0x00010000ul) +/* The App flash header id stored at this address */ +#define BOOTLOADER_CFG_APP_HEAD_ADDR (0x000100C0ul) +/* The App flash code stored to be end at this address */ +#define BOOTLOADER_CFG_APP_CODE_END_ADDR (0x00037FFBul) +/* The App flash crc stored at this address */ +#define BOOTLOADER_CFG_APP_CRC_ADDR (0x00037FFCul) +/* Crc bytes num: 4bytes */ +#define BOOTLOADER_CFG_APP_CRC_SIZE (4u) +/* The total app code size exclude the crc-self */ +#define BOOTLOADER_CFG_APP_SIZE (BOOTLOADER_CFG_APP_CODE_END_ADDR - BOOTLOADER_CFG_APP_START_ADDR + 1u) +/* All the app memory last byte address */ +#define BOOTLOADER_CFG_APP_END_ADDR (BOOTLOADER_CFG_APP_CRC_ADDR + BOOTLOADER_CFG_APP_CRC_SIZE - 1) + +/* Calibration data information */ +#define BOOTLOADER_CFG_CALIBRATION_DATA_START_ADDR (0) +#define BOOTLOADER_CFG_CALIBRATION_DATA_CRC_ADDR (0) +#define BOOTLOADER_CFG_CALIBRATION_DATA_CRC_SIZE (4u) +#define BOOTLOADER_CFG_CALIBRATION_DATA_SIZE (BOOTLOADER_CFG_CALIBRATION_DATA_CRC_ADDR + BOOTLOADER_CFG_CALIBRATION_DATA_CRC_SIZE - BOOTLOADER_CFG_CALIBRATION_DATA_START_ADDR) + +/* The start address of Flash driver copied into ram, the fisrt 16bytes is used to store the function address */ +#define BOOTLOADER_CFG_FLS_DRV_RAM_START_ADDR (0x20005BF0) +#define BOOTLOADER_CFG_FLS_DRV_RAM_CRC_ADDR (0x200063EC) +#define BOOTLOADER_CFG_FLS_DRV_RAM_CRC_SIZE (4u) +#define BOOTLOADER_CFG_FLS_DRV_RAM_CODE_SIZE (BOOTLOADER_CFG_FLS_DRV_RAM_CRC_ADDR - BOOTLOADER_CFG_FLS_DRV_RAM_START_ADDR) + +/* The max time stay in boot before can jump to App, unit: ms */ +#define BOOTLOADER_CFG_BOOT_DURATION_MS (10u) + +/* Erased all sector */ +#define BOOTLOADER_CFG_ERASE_ALL (0xFFFFFFFF) +/* How many sector to be earsed once, recommand at least 2 sectors */ +#define BOOTLOADER_CFG_ERASE_SECTOR_NUM (BOOTLOADER_CFG_ERASE_ALL) + +/* Define the intial value by calculate crc */ +#define BOOTLOADER_CFG_INIT_CRC_VALUE (0xFFFFFFFF) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +typedef struct +{ + uint32_t memStartAddr; + uint32_t memSize; + uint32_t crcStartAddr; + uint32_t crcSize; +} Bootloadder_CfgType; + +typedef struct +{ + uint8_t HWVersion[4]; + uint8_t BLVersion[8]; + uint8_t bootBuildTime[12]; + uint8_t bootBuildDate[16]; + uint8_t ECUName[8]; + uint8_t Reverse[16]; +} Bootloade_CfgInfoType;//64 byte + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _BOOTLOADER_CFG_H_ */ diff --git a/cva_bootloader_m0118/src/fls/fls.c b/cva_bootloader_m0118/src/fls/fls.c new file mode 100644 index 0000000..8302748 --- /dev/null +++ b/cva_bootloader_m0118/src/fls/fls.c @@ -0,0 +1,557 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ +#include +#include "fls.h" +#include "mcu.h" +#include "bootloader_cfg.h" + +#if(BOOTLOADER_CFG_FLS_CODE_GENERATE_EN != 0u) + +/******************************************************************************* + * the defines + ******************************************************************************/ +#if(BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u) +#pragma location = ".textrw" +#else +#pragma location = ".ram_flash_driver" +#endif +static void + Fls_ClearCommandState(FlashDrvType *obj); + +#if(BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u) +#pragma location = ".textrw" +#else +#pragma location = ".ram_flash_driver" +#endif +static Fls_StdRtnType + Fls_CommandSequence(FlashDrvType *obj); + +#if(BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u) +#pragma location = ".textrw" +#else +#pragma location = ".ram_flash_driver" +#endif +static Fls_StdRtnType + Fls_CommandSequence(FlashDrvType *obj); + +#if(BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u) +#pragma location = ".textrw" +#else +#pragma location = ".ram_flash_driver" +#endif +void Fls_Init(FlashDrvType *obj); + +#if(BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u) +#pragma location = ".textrw" +#else +#pragma location = ".ram_flash_driver" +#endif +Fls_StdRtnType + Fls_Erase(uint32_t targetAddress, uint32_t sectorNum); + +#if(BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u) +#pragma location = ".textrw" +#else +#pragma location = ".ram_flash_driver" +#endif +Fls_StdRtnType + Fls_Write(uint32_t targetAddress, const uint8_t* sourceAddressPtr, uint32_t bytesNum); + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +#if(BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 0u) +#pragma location = ".ram_flash_driver_map" +__root uint32_t fls_DrvMapTbl[] = { + 0, /* Store flash instance address */ + (uint32_t)(&Fls_Init), + (uint32_t)(&Fls_Erase), + (uint32_t)(&Fls_Write)}; + +#endif + +/******************************************************************************* + * the functions + ******************************************************************************/ +#if(BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u) +#pragma location = ".textrw" +#else +#pragma location = ".ram_flash_driver" +#endif +static void + Fls_ClearCommandState(FlashDrvType *obj) +{ + FtfcReg_SetFstatRspErrF(obj->reg, 1); + FtfcReg_SetFstatProtViolF(obj->reg, 1); + FtfcReg_SetFstatAccErrF(obj->reg, 1); + FtfcReg_SetFstatRdColF(obj->reg, 1); + FtfcReg_SetFstatSecF(obj->reg, 1); + FtfcReg_SetFstatDedF(obj->reg, 1); +} + +#if(BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u) +#pragma location = ".textrw" +#else +#pragma location = ".ram_flash_driver" +#endif +static Fls_StdRtnType + Fls_CommandSequence(FlashDrvType *obj) +{ + Fls_StdRtnType ret = FLS_STD_RETURN_OK; + + FtfcReg_SetFstatCcif(obj->reg, 1); + + while(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + } + + if(FtfcReg_GetFstatAccErrF(obj->reg) || FtfcReg_GetFstatProtViolF(obj->reg) || FtfcReg_GetFstatMgStat(obj->reg)) + { + ret = FLS_STD_RETURN_ERASE_NG; + } + + return ret; +} + +#if(BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u) +#pragma location = ".textrw" +#else +#pragma location = ".ram_flash_driver" +#endif +static Fls_StdRtnType + Fls_SetFlexRam(FlashDrvType *obj, bool eeramEn) +{ + Fls_StdRtnType ret = FLS_STD_RETURN_OK; + + bool gctrg = false; + + if(FtfcReg_GetFstatEeeRamRdy(obj->reg) == 0 && eeramEn == true && Scg0Reg_GetTrimAutoGcEn(obj->scg0Reg) == 1) + { + gctrg = true; + } + + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLS_STD_RETURN_BUSY; + } + else + { + Fls_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_SETFRAM); + FtfcReg_SetFccob(obj->reg, 1, eeramEn ? 1 : 0); + ret = Fls_CommandSequence(obj); + + if(eeramEn && (FtfcReg_GetFstatEeeRamRdy(obj->reg) == 0)) + { + ret = FLS_STD_RETURN_PGM_NG; + } + + if((!eeramEn) && (FtfcReg_GetFstatRamRdy(obj->reg) == 0u)) + { + ret = FLS_STD_RETURN_PGM_NG; + } + + if((ret == FLS_STD_RETURN_OK) && (gctrg == true)) + { + FtfcReg_SetFstatEeeTlov(obj->reg, 1); + } + } + + return ret; +} + +/*! \brief Initializes the Flash driver module + * + * This function initializes Flash driver by setting the register + * instance to it. + * + * \param[in] flashDrvPtr : pointer to Flash driver instance + * \return void + */ +#if(BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u) +#pragma location = ".textrw" +#else +#pragma location = ".ram_flash_driver" +#endif +void Fls_Init(FlashDrvType * obj) +{ + /* Update the flash instance */ + *((uint32_t *)BOOTLOADER_CFG_FLS_DRV_RAM_START_ADDR) = (uint32_t)obj; + + Fls_ClearCommandState(obj); + obj->callback = NULL; +} + +/*! \brief Erased the pflash + * + * This function erase the length located in the pflash + * + * \param[in] targetAddress : pointer to pFlash address + * \param[in] sectorNum : how many sector to be erased + * \return Fls_StdRtnType + */ +#if(BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u) +#pragma location = ".textrw" +#else +#pragma location = ".ram_flash_driver" +#endif +Fls_StdRtnType + Fls_Erase(uint32_t targetAddress, uint32_t sectorNum) +{ + Fls_StdRtnType ret = FLS_STD_RETURN_OK; + FlashDrvType *flashRegPtr; + + flashRegPtr = (FlashDrvType *)((*(uint32_t *)BOOTLOADER_CFG_FLS_DRV_RAM_START_ADDR)); + /* Check the current requested address is aligned with 1024byte or not */ + if((targetAddress & FLS_ERASE_SECTION_ADDR_ALIGNED_MASK) != 0u) + { + ret = FLS_STD_RETURN_ADDR_INVALID; + } + else + { + uint32_t i = 0; + + /* Check how many sections to be erased */ + for(i = 0; i < sectorNum; i++) + { + if(FtfcReg_GetFstatCcif(flashRegPtr->reg) == 0u) + { + ret = FLS_STD_RETURN_BUSY; + break; + } + else + { + Fls_ClearCommandState(flashRegPtr); + + FtfcReg_SetFccob(flashRegPtr->reg, 0, FLASHDRV_OPCMD_SCTERS); + FtfcReg_SetFccob(flashRegPtr->reg, 1, FCCOBADDRLOW((targetAddress + (i * FLS_ERASE_SECTION_SIZE)))); + FtfcReg_SetFccob(flashRegPtr->reg, 2, FCCOBADDRMDLOW((targetAddress + (i * FLS_ERASE_SECTION_SIZE)))); + FtfcReg_SetFccob(flashRegPtr->reg, 3, FCCOBADDRMDHIG((targetAddress + (i * FLS_ERASE_SECTION_SIZE)))); + FtfcReg_SetFccob(flashRegPtr->reg, 4, FCCOBADDRHIG((targetAddress + (i * FLS_ERASE_SECTION_SIZE)))); + FtfcReg_SetFccob(flashRegPtr->reg, 5, FLASHDRV_SCTERS_RETRY); + + ret = Fls_CommandSequence(flashRegPtr); + } + + if(ret != FLS_STD_RETURN_OK) + { + break; + } + } + } + + return ret; +} + +/*! \brief Write datas to pflash + * + * This function wrtie the length bytes to pflash + * + * \param[in] targetAddress : the target address to begin to write in pflash + * \param[in] sourceAddressPtr : pointer to write data buffer + * \param[in] bytesNum : how many bytes to be written to pflash + * \return Fls_StdRtnType + */ +#if(BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u) +#pragma location = ".textrw" +#else +#pragma location = ".ram_flash_driver" +#endif +Fls_StdRtnType + Fls_Write(uint32_t targetAddress, const uint8_t* sourceAddressPtr, uint32_t bytesNum) +{ + Fls_StdRtnType ret = FLS_STD_RETURN_OK; + FlashDrvType *flashRegPtr; + + flashRegPtr = (FlashDrvType *)((*(uint32_t *)BOOTLOADER_CFG_FLS_DRV_RAM_START_ADDR)); + + /* Check the current requested address is aligned with 8byte or not */ + if((targetAddress & FLS_PGM_SECTION_ADDR_ALIGNED_MASK) != 0u) + { + ret = FLS_STD_RETURN_ADDR_INVALID; + } + else if((bytesNum & FLS_PGM_SECTION_ADDR_ALIGNED_MASK) != 0u) + { + ret = FLS_STD_RETURN_LEN_INVALID; + } + else + { + bool eeramrdy = false; + uint32_t i = 0, offset = 0; + uint8_t* pfastram; + + if(FtfcReg_GetFstatEeeRamRdy(flashRegPtr->reg) == 1) + { + eeramrdy = true; + } + + if(eeramrdy) + { + Fls_SetFlexRam(flashRegPtr, false); + } + + offset = (targetAddress & (FLS_PGM_SECTION_SIZE - 1u)); + pfastram = (uint8_t*)(FLS_FASTRAM_ADDR + offset); + for(i = 0; i < bytesNum; i++) + { + *pfastram = sourceAddressPtr[i]; + pfastram++; + } + + if(0U == FtfcReg_GetFstatCcif(flashRegPtr->reg)) + { + ret = FLS_STD_RETURN_BUSY; + } + else + { + Fls_ClearCommandState(flashRegPtr); + + FtfcReg_SetFccob(flashRegPtr->reg, 0, FLASHDRV_OPCMD_SCTPGM); + FtfcReg_SetFccob(flashRegPtr->reg, 1, FCCOBADDRLOW(targetAddress)); + FtfcReg_SetFccob(flashRegPtr->reg, 2, FCCOBADDRMDLOW(targetAddress)); + FtfcReg_SetFccob(flashRegPtr->reg, 3, FCCOBADDRMDHIG(targetAddress)); + FtfcReg_SetFccob(flashRegPtr->reg, 4, FCCOBADDRHIG(targetAddress)); + FtfcReg_SetFccob(flashRegPtr->reg, 5, (uint8_t)((bytesNum / FLS_PGM_PHRASE_BYTE_SIZE) - 1)); + + ret = Fls_CommandSequence(flashRegPtr); + } + + if(eeramrdy) + { + Fls_SetFlexRam(flashRegPtr, true); + } + } + + return ret; +} + +/*! \brief Read out data from pflash + * + * This function read out the length bytes data from pflash + * + * \param[in] readAddress : the target address to begin to read in pflash + * \param[in] readBufferPtr : pointer to store read out datas + * \param[in] bytesNum : how many bytes to be readout from pflash + * \return Fls_StdRtnType + */ +Fls_StdRtnType Fls_Read(uint32_t readAddress, uint8_t *readBufferPtr, uint32_t bytesNum) +{ + Fls_StdRtnType ret = FLS_STD_RETURN_OK; + uint32_t i = 0; + uint8_t *targetReadAddrPtr; + + targetReadAddrPtr = (uint8_t *)readAddress; + + for(i = 0; i < bytesNum; i++) + { + readBufferPtr[i] = targetReadAddrPtr[i]; + } + + return ret; +} + +/*! \brief Check the flash is write or not been write + * + * This function Check the flash is write or not been write + * + * \param[in] memAddress : the target address to begin to read in pflash + * \return Fls_StdRtnType + */ +Fls_StdRtnType Fls_CheckWriteState(uint32_t memAddress) +{ + Fls_StdRtnType ret = FLS_STD_RETURN_OK; + FlashDrvType *obj; + + if((memAddress & FLS_PGM_SECTION_ADDR_ALIGNED_MASK) != 0u) + { + ret = FLS_STD_RETURN_ADDR_INVALID; + } + else + { + obj = (FlashDrvType *)((*(uint32_t *)BOOTLOADER_CFG_FLS_DRV_RAM_START_ADDR)); + + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLS_STD_RETURN_BUSY; + } + else + { + Fls_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_SCTRD1S); + FtfcReg_SetFccob(obj->reg, 1, FCCOBADDRLOW(memAddress)); + FtfcReg_SetFccob(obj->reg, 2, FCCOBADDRMDLOW(memAddress)); + FtfcReg_SetFccob(obj->reg, 3, FCCOBADDRMDHIG(memAddress)); + FtfcReg_SetFccob(obj->reg, 4, FCCOBADDRHIG(memAddress)); + FtfcReg_SetFccob(obj->reg, 5, (8u / FLASHDRV_PHRASE_SIZE) - 1); + + ret = Fls_CommandSequence(obj); + /* Return success: means the flash is virgin, or the flash is write */ + if(ret == FLS_STD_RETURN_OK) + { + ret = FLS_STD_RETURN_VIRGIN; + } + else + { + ret = FLS_STD_RETURN_OK; + } + } + } + + return ret; +} + +#else + +static void Fls_ClearCommandState(FlashDrvType *obj) +{ + FtfcReg_SetFstatRspErrF(obj->reg, 1); + FtfcReg_SetFstatProtViolF(obj->reg, 1); + FtfcReg_SetFstatAccErrF(obj->reg, 1); + FtfcReg_SetFstatRdColF(obj->reg, 1); + FtfcReg_SetFstatSecF(obj->reg, 1); + FtfcReg_SetFstatDedF(obj->reg, 1); +} + +static Fls_StdRtnType Fls_CommandSequence(FlashDrvType *obj) +{ + Fls_StdRtnType ret = FLS_STD_RETURN_OK; + + FtfcReg_SetFstatCcif(obj->reg, 1); + + while(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + } + + if(FtfcReg_GetFstatAccErrF(obj->reg) || FtfcReg_GetFstatProtViolF(obj->reg) || FtfcReg_GetFstatMgStat(obj->reg)) + { + ret = FLS_STD_RETURN_ERASE_NG; + } + + return ret; +} + + +/*! \brief Check the flash is write or not been write + * + * This function Check the flash is write or not been write + * + * \param[in] memAddress : the target address to begin to read in pflash + * \return Fls_StdRtnType + */ +Fls_StdRtnType Fls_CheckWriteState(uint32_t memAddress) +{ + Fls_StdRtnType ret = FLS_STD_RETURN_OK; + FlashDrvType *obj; + + if((memAddress & FLS_PGM_SECTION_ADDR_ALIGNED_MASK) != 0u) + { + ret = FLS_STD_RETURN_ADDR_INVALID; + } + else + { + obj = (FlashDrvType *)((*(uint32_t *)BOOTLOADER_CFG_FLS_DRV_RAM_START_ADDR)); + + if(0U == FtfcReg_GetFstatCcif(obj->reg)) + { + ret = FLS_STD_RETURN_BUSY; + } + else + { + Fls_ClearCommandState(obj); + FtfcReg_SetFccob(obj->reg, 0, FLASHDRV_OPCMD_SCTRD1S); + FtfcReg_SetFccob(obj->reg, 1, FCCOBADDRLOW(memAddress)); + FtfcReg_SetFccob(obj->reg, 2, FCCOBADDRMDLOW(memAddress)); + FtfcReg_SetFccob(obj->reg, 3, FCCOBADDRMDHIG(memAddress)); + FtfcReg_SetFccob(obj->reg, 4, FCCOBADDRHIG(memAddress)); + FtfcReg_SetFccob(obj->reg, 5, (8u / FLASHDRV_PHRASE_SIZE) - 1); + + ret = Fls_CommandSequence(obj); + /* Return success: means the flash is virgin, or the flash is write */ + if(ret == FLS_STD_RETURN_OK) + { + ret = FLS_STD_RETURN_VIRGIN; + } + else + { + ret = FLS_STD_RETURN_OK; + } + } + } + + return ret; +} + +/*! \brief Read out data from pflash + * + * This function read out the length bytes data from pflash + * + * \param[in] readAddress : the target address to begin to read in pflash + * \param[in] readBufferPtr : pointer to store read out datas + * \param[in] bytesNum : how many bytes to be readout from pflash + * \return Fls_StdRtnType + */ +Fls_StdRtnType Fls_Read(uint32_t readAddress, uint8_t* readBufferPtr, uint32_t bytesNum) +{ + Fls_StdRtnType ret = FLS_STD_RETURN_OK; + uint32_t i = 0; + uint8_t* targetReadAddrPtr; + + targetReadAddrPtr = (uint8_t*)readAddress; + + for(i = 0; i < bytesNum; i++) + { + readBufferPtr[i] = targetReadAddrPtr[i]; + } + + return ret; +} + +/*! \brief Compare written datas in pflash + * + * This function compare the written length datas + * + * \param[in] sourceAddressPtr : pointer to stored in localed buffer + * \param[in] targetAddressPtr : pointer to stored in pflash + * \param[in] bytesNum : how many bytes to be compared from pflash + * \return Fls_StdRtnType + */ +Fls_StdRtnType Fls_Compare(const uint8_t* sourceAddressPtr, const uint8_t* targetAddressPtr, uint32_t bytesNum) +{ + Fls_StdRtnType ret = FLS_STD_RETURN_OK; + uint32_t i = 0; + + for(i = 0; i < bytesNum; i++) + { + if((*(sourceAddressPtr + i)) != (*(targetAddressPtr + i))) + { + ret = FLS_STD_RETURN_DATA_INVALID; + break; + } + } + + return ret; +} + +#endif diff --git a/cva_bootloader_m0118/src/fls/fls.h b/cva_bootloader_m0118/src/fls/fls.h new file mode 100644 index 0000000..2dd7e32 --- /dev/null +++ b/cva_bootloader_m0118/src/fls/fls.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _FLS_H_ +#define _FLS_H_ + +/*! \brief Contains public interface to various functions related + * to the FLS module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ +#include +#include +#include "mcu.h" +#include "bootloader_cfg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ +/* One erase section bytes size is 1024 */ +#define FLS_ERASE_SECTION_ADDR_ALIGNED_MASK (0x3FFu) +#define FLS_PGM_SECTION_ADDR_ALIGNED_MASK (0x07u) +#define FLS_PGM_PHRASE_BYTE_SIZE (0x08u) +#define FLS_ERASE_SECTION_SIZE (FLS_ERASE_SECTION_ADDR_ALIGNED_MASK + 1u) +#define FLS_PGM_SECTION_SIZE (FLS_ERASE_SECTION_SIZE) +#define FLS_FASTRAM_ADDR (0x14000000UL) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +typedef enum +{ + FLS_STD_RETURN_OK = 0u, + FLS_STD_RETURN_ADDR_INVALID, + FLS_STD_RETURN_DATA_INVALID, + FLS_STD_RETURN_LEN_INVALID, + FLS_STD_RETURN_FLASH_DRIVER_INVALID, + FLS_STD_RETURN_PGM_NG, + FLS_STD_RETURN_CHECK_PHASE_NG, + FLS_STD_RETURN_ERASE_NG, + FLS_STD_RETURN_PENDING, + FLS_STD_RETURN_BUSY, + FLS_STD_RETURN_TIMEOUT, + FLS_STD_RETURN_VIRGIN, + +} Fls_StdRtnType; + +#if(BOOTLOADER_CFG_FLS_CODE_GENERATE_EN != 0u) + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the Flash driver module + * + * This function initializes Flash driver by setting the register + * instance to it. + * + * \param[in] flashDrvPtr : pointer to Flash driver instance + * \return void + */ +extern +#if(BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u) + __attribute__((section(".code_ram"))) +#else + __attribute__((section(".ram_flash_driver"))) +#endif + void + Fls_Init(FlashDrvType *obj); + +/*! \brief Erased the pflash + * + * This function erase the length located in the pflash + * + * \param[in] targetAddress : pointer to pFlash address + * \param[in] sectorNum : how many sector to be erased + * \return Fls_StdRtnType + */ +extern +#if(BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u) + __attribute__((section(".code_ram"))) +#else + __attribute__((section(".ram_flash_driver"))) +#endif + Fls_StdRtnType + Fls_Erase(uint32_t targetAddress, uint32_t sectorNum); + +/*! \brief Write datas to pflash + * + * This function wrtie the length bytes to pflash + * + * \param[in] targetAddress : the target address to begin to write in pflash + * \param[in] sourceAddressPtr : pointer to write data buffer + * \param[in] bytesNum : how many bytes to be written to pflash + * \return Fls_StdRtnType + */ +extern +#if(BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u) + __attribute__((section(".code_ram"))) +#else + __attribute__((section(".ram_flash_driver"))) +#endif + Fls_StdRtnType + Fls_Write(uint32_t targetAddress, const uint8_t* sourceAddressPtr, uint32_t bytesNum); + +/*! \brief Read out data from pflash + * + * This function read out the length bytes data from pflash + * + * \param[in] readAddress : the target address to begin to read in pflash + * \param[in] readBufferPtr : pointer to store read out datas + * \param[in] bytesNum : how many bytes to be readout from pflash + * \return Fls_StdRtnType + */ +extern Fls_StdRtnType Fls_Read(uint32_t readAddress, uint8_t *readBufferPtr, uint32_t bytesNum); + +/*! \brief Compare written datas in pflash + * + * This function compare the written length datas + * + * \param[in] sourceAddressPtr : pointer to stored in localed buffer + * \param[in] targetAddressPtr : pointer to stored in pflash + * \param[in] bytesNum : how many bytes to be compared from pflash + * \return Fls_StdRtnType + */ +extern Fls_StdRtnType Fls_Compare(const uint8_t *sourceAddressPtr, const uint8_t *targetAddressPtr, uint32_t bytesNum); + +/*! \brief Check the flash is write or not been write + * + * This function Check the flash is write or not been write + * + * \param[in] memAddress : the target address to begin to read in pflash + * \return Fls_StdRtnType + */ +extern Fls_StdRtnType Fls_CheckWriteState(uint32_t memAddress); + +#else + +/*! \brief Read out data from pflash + * + * This function read out the length bytes data from pflash + * + * \param[in] readAddress : the target address to begin to read in pflash + * \param[in] readBufferPtr : pointer to store read out datas + * \param[in] bytesNum : how many bytes to be readout from pflash + * \return Fls_StdRtnType + */ +extern Fls_StdRtnType Fls_Read(uint32_t readAddress, uint8_t* readBufferPtr, uint32_t bytesNum); + +/*! \brief Compare written datas in pflash + * + * This function compare the written length datas + * + * \param[in] sourceAddressPtr : pointer to stored in localed buffer + * \param[in] targetAddressPtr : pointer to stored in pflash + * \param[in] bytesNum : how many bytes to be compared from pflash + * \return Fls_StdRtnType + */ +extern Fls_StdRtnType Fls_Compare(const uint8_t* sourceAddressPtr, const uint8_t* targetAddressPtr, uint32_t bytesNum); + +/*! \brief Check the flash is write or not been write + * + * This function Check the flash is write or not been write + * + * \param[in] memAddress : the target address to begin to read in pflash + * \return Fls_StdRtnType + */ +extern Fls_StdRtnType Fls_CheckWriteState(uint32_t memAddress); + +#endif + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif diff --git a/cva_bootloader_m0118/src/main.c b/cva_bootloader_m0118/src/main.c new file mode 100644 index 0000000..63c8fd0 --- /dev/null +++ b/cva_bootloader_m0118/src/main.c @@ -0,0 +1,441 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/*! \brief bootloader demo project + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "private_driver/mcu.h" +#include "bootloader.h" +#include "fls.h" +#include "uds_user.h" +#include "SEGGER_RTT.h" +#include "TLE94x1.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ +#define UDS_PHYS_RECV_MSG_ID (0x731) +#define UDS_FUNC_RECV_MSG_ID (0x7DF) +#define UDS_PHYS_RESP_MSG_ID (0x7B1) +#define UDS_TEXT_TX_MSG_ID (0x234) + +#define UDS_RECV_BUF (2080) +#define UDS_SEND_BUF (512) +#define CAN_BUFF_MAX_NUM (32) + +#define CAN_DATA_BUFFER_SIZE (64u) +#define CAN_BUFFER_FIFO_SIZE (32u) + +int64_t Get_Cur_Time_Stamp(void); +static int8_t FlexCanBoot_TxMessage(uint32_t msgId, const uint8_t *pData, uint8_t size); +void DebugOutput(const char *message, ...); +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +typedef enum +{ + UDS_MSG_IDX_STD_RX_PHYS, + UDS_MSG_IDX_STD_RX_FUNC, + UDS_MSG_IDX_STD_TX, + UDS_MSG_IDX_STD_TEST_TX, + UDS_MSG_IDX_NUM +} Uds_MsgIdIdxType; + +typedef struct +{ + uint32_t id; + uint8_t data[CAN_DATA_BUFFER_SIZE]; + uint8_t len; + uint16_t timeStamp; + uint32_t hrTimeStamp; +} FlexCan_FrameStructureType; + +typedef struct +{ + FlexCan_FrameStructureType rxMsg[CAN_BUFFER_FIFO_SIZE]; + FlexCan_FrameStructureType txMsg[CAN_BUFFER_FIFO_SIZE]; + uint8_t wrIdx; + uint8_t rdIdx; +} FlexCan_DataInfoType; + +/******************************************************************************* + * the globals + ******************************************************************************/ +McuType mcu; +volatile uint32_t gSystick1msEvent = 0, gSystick1msCnt = 0, gTestIoEn = 0; +uint32_t gCpuClockFrequency = 0; +int64_t timer_1ms = 0; +uint8_t udsSendBuf[UDS_SEND_BUF] = {0}; +uint8_t udsRecvBuf[UDS_RECV_BUF] = {0}; +UdsType udsObj; +FlexCan_DataInfoType flexCan_DataInfo; +FlexCanDrv_ControllerCfgType flexCanCfg; +FlexCanDrvType *flexCanDrv_DemoObj; +uint8_t flexCanBoot_EnhanceRxFFCnt = 0; + +Uds_ParamsType udsParam = { + .isotpParams.framePadding = true, + .isotpParams.blockSize = 0, + .isotpParams.recvPhysId = UDS_PHYS_RECV_MSG_ID, + .isotpParams.recvFuncId = UDS_FUNC_RECV_MSG_ID, + .isotpParams.sendid = UDS_PHYS_RESP_MSG_ID, + .isotpParams.sendBuf = udsSendBuf, + .isotpParams.sendBufSize = UDS_SEND_BUF, + .isotpParams.recvBuf = udsRecvBuf, + .isotpParams.recvBufSize = UDS_RECV_BUF, + .isotpParams.debug = NULL, + .isotpParams.sendCanMsg = FlexCanBoot_TxMessage, + .isotpParams.getTimeMs = Get_Cur_Time_Stamp, + .p2Server_ms = 50, + .p2xServer_10ms = 500, + .s3Server_ms = 5000, +}; + +const FlexCanDrv_MsgCfgType msgCfgObj[UDS_MSG_IDX_NUM] = { + {UDS_MSG_IDX_STD_RX_PHYS, 1, UDS_PHYS_RECV_MSG_ID, false, FLEXCANDRV_MSGTYPE_RX, DLC_BYTE_8, false, true, 0xFFFFFFFF}, /* CAN_MSGOBJ_STD_RX_PHYS */ + {UDS_MSG_IDX_STD_RX_FUNC, 1, UDS_FUNC_RECV_MSG_ID, false, FLEXCANDRV_MSGTYPE_RX, DLC_BYTE_8, false, true, 0xFFFFFFFF}, /* CAN_MSGOBJ_STD_RX_FUNC */ + {UDS_MSG_IDX_STD_TX, 1, UDS_PHYS_RESP_MSG_ID, false, FLEXCANDRV_MSGTYPE_TX, DLC_BYTE_8, false, false, 0xFFFFFFFF}, /* CAN_MSGOBJ_STD_TX */ + {UDS_MSG_IDX_STD_TEST_TX, 1, UDS_TEXT_TX_MSG_ID, false, FLEXCANDRV_MSGTYPE_TX, DLC_BYTE_8, false, false, 0xFFFFFFFF}, /* CAN_MSGOBJ_STD_TX */ +}; + +/******************************************************************************* + * the functions + ******************************************************************************/ + +int64_t Get_Cur_Time_Stamp(void) +{ + return timer_1ms; +} + +void SysTick_Handler(void) +{ + gSystick1msEvent++; + timer_1ms++; + Uds_Tick(&udsObj); +} + +void CAN_ORed_0_31_MB_Handler(void) +{ + uint8_t i = 0; + FlexCanDrv_MsgObjType msgObj; + + for(i = 0; i < flexCanCfg.msgNum; i++) + { + msgObj.msgBufId = i; + + if(FlexCanDrv_GetMsgObjFlag(flexCanDrv_DemoObj, &msgObj)) + { + if(flexCanCfg.msgCfg[i].msgType == FLEXCANDRV_MSGTYPE_RX) + { + /* clear message buffer interrupt flag */ + FlexCanDrv_ClearMsgObjFlag(flexCanDrv_DemoObj, &msgObj); + + /* get the new message data */ + FlexCanDrv_GetRxMsg(flexCanDrv_DemoObj, &msgObj); + + memcpy(flexCan_DataInfo.rxMsg[flexCan_DataInfo.wrIdx].data, msgObj.data, msgObj.dlc); + flexCan_DataInfo.rxMsg[flexCan_DataInfo.wrIdx].id = msgObj.msgId; + flexCan_DataInfo.rxMsg[flexCan_DataInfo.wrIdx].len = msgObj.dlc; + flexCan_DataInfo.wrIdx++; + if(flexCan_DataInfo.wrIdx >= CAN_BUFFER_FIFO_SIZE) + { + flexCan_DataInfo.wrIdx = 0; + } + } + else + { + /* clear message buffer interrupt flag */ + FlexCanDrv_ClearMsgObjFlag(flexCanDrv_DemoObj, &msgObj); + } + } + } +} + +bool FlexCanBoot_ReadoutMsg(FlexCan_FrameStructureType *pRxMsgObj) +{ + bool ret = false; + + if(flexCan_DataInfo.wrIdx != flexCan_DataInfo.rdIdx) + { + memcpy(pRxMsgObj, &flexCan_DataInfo.rxMsg[flexCan_DataInfo.rdIdx], sizeof(FlexCan_FrameStructureType)); + flexCan_DataInfo.rdIdx++; + if(flexCan_DataInfo.rdIdx >= CAN_BUFFER_FIFO_SIZE) + { + flexCan_DataInfo.rdIdx = 0; + } + + ret = true; + } + + return ret; +} + +static int8_t FlexCanBoot_TxMessage(uint32_t msgId, const uint8_t *pData, uint8_t size) +{ + FlexCanDrv_MsgObjType txMsgObj; + uint8_t msgIdx = 0, i = 0; + for(i = 0; i < flexCanCfg.msgNum; i++) + { + if(msgId == flexCanCfg.msgCfg[i].msgId) + { + msgIdx = i; + break; + } + } + + txMsgObj.msgBufId = flexCanCfg.msgCfg[msgIdx].msgBufId; + txMsgObj.dlc = size; + txMsgObj.msgId = flexCanCfg.msgCfg[msgIdx].msgId; + memcpy(&txMsgObj.data[0], pData, size); + + FlexCanDrv_SetTxMsg(flexCanDrv_DemoObj, &txMsgObj); + /* transmit standard CAN Tx message */ + FlexCanDrv_TransmitMsg(flexCanDrv_DemoObj, &txMsgObj); + + return 0; +} + +void FlexCanBoot_Init(void) +{ + uint32_t busClockFreq = 0; + + flexCanDrv_DemoObj = &mcu.flexCanDrv; + + + + /* set PTE4 as MUX 5 - CAN0.RX */ + PinsDrv_SetMuxModeSel(&mcu.ptb, 0, PINSDRV_MUX_ALT5); + + /* set PTE5 as MUX 5 - CAN0.TX */ + PinsDrv_SetMuxModeSel(&mcu.ptb, 1, PINSDRV_MUX_ALT5); + + /* get CAN controller default configuration */ + FlexCanDrv_GetDefaultCfg(&flexCanCfg); + flexCanCfg.msgNum = sizeof(msgCfgObj) / sizeof(FlexCanDrv_MsgCfgType); + flexCanCfg.msgCfg = msgCfgObj; + + flexCanCfg.clkSrc = FLEXCANDRV_CLKSRC_CHICLK; + flexCanCfg.fdEnable = false; + flexCanCfg.fdISOEnable = false; + flexCanCfg.fifoEnable = false;//TODO false? + flexCanCfg.msgBufDataLenSel = FLEXCANDRV_MB_SIZE_BYTE_8; + flexCanCfg.individualMaskEnable = true; + + if(flexCanCfg.clkSrc == FLEXCANDRV_CLKSRC_CHICLK) + { + ClockDrv_GetFreq(&mcu.clockDrv, CLOCKDRV_APB, &busClockFreq); + } + else + { + ClockDrv_GetFreq(&mcu.clockDrv, CLOCKDRV_SOSC_DIV, &busClockFreq); + } + + if(flexCanCfg.fdEnable == true) + { + FlexCanDrv_BitTimingCalc(&flexCanCfg.fdBitTiming, + busClockFreq, /* module clock source: 16M */ + 2000000, /* baudrate: 2M */ + 7500, /* sample point: 75% */ + 2000, /* SJW: 20% */ + 1); /* FD bit timing */ + } + + FlexCanDrv_BitTimingCalc(&flexCanCfg.bitTiming, + busClockFreq, /* module clock source: 16M */ + 500000, /* baudrate: 500K */ + 7500, /* sample point: 75% */ + 2500, /* SJW: 20% */ + 0); /* classic CAN bit timing */ + + /* initialize CAN module */ + FlexCanDrv_Configure(flexCanDrv_DemoObj, &flexCanCfg); + + /* enable rx interrupt */ + IrqDrv_EnableIrq(CAN_ORed_0_31_MB_IRQn); +} + +static uint8_t testdata[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; +void TxTestMsg (uint8_t * data) +{ + for (uint8_t i = 0; i < 8; i++) + { + testdata[i] = data[i]; + } + FlexCanBoot_TxMessage(UDS_TEXT_TX_MSG_ID,testdata,8); +} + +void DebugOutput(const char *message, ...) +{ + va_list ParamList; + + va_start(ParamList, message); + SEGGER_RTT_printf(0, message, &ParamList); + va_end(ParamList); +} +uint8_t BootReqDelay = 0; +uint8_t BootReqFlag = 0; +void BootReqInit(void) +{ + /* Setup the clock */ + ClockDrv_ModuleClkConfigType clockConfig; + + /* Setup the Pll div2 clock */ + clockConfig.gating = true; + clockConfig.source = CLOCKDRV_PLL; + clockConfig.div = 1; + ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PLL_DIV, &clockConfig); + + clockConfig.gating = true; + clockConfig.source = CLOCKDRV_PLL; + clockConfig.div = 2; + ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PLL_DIV, &clockConfig); + + /* Setup the SPI clock */ + clockConfig.gating = true; + clockConfig.source = CLOCKDRV_PLL_DIV; + ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_SPI0, &clockConfig); + + uint32_t tTcr = SpiReg_GetTcr((const SpiRegType *)&mcu.spiDrv0.reg); + SpiDrv_SetPrescaler(&tTcr,0x02); + + SBC_SPI_INIT(); + + + SBC_Init(); + +} +uint32_t rollingcounter; +int main(void) +{ + FlexCan_FrameStructureType rxMsg; + /* Setup the clock */ + ClockDrv_ModuleClkConfigType clockConfig; + + SEGGER_RTT_Init(); + SEGGER_RTT_printf(0,"-----INTO BOOT-----\n"); + + IrqDrv_DisableGlobalInterrupt(); + + /* Initialize all MCU drivers: flash drv included */ + Mcu_Init(&mcu); + + WdgDrv_Disable(&mcu.wdgDrv); + + /* CAN init */ + memset(&flexCan_DataInfo, 0, sizeof(flexCan_DataInfo)); + memset(&flexCanCfg, 0, sizeof(flexCanCfg)); + + + + + + /* Enable the clock for all port peripheral */ + clockConfig.gating = true; + clockConfig.div = 1; + ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PORTA, &clockConfig); + ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PORTB, &clockConfig); + ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PORTC, &clockConfig); + ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PORTD, &clockConfig); + ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PORTE, &clockConfig); + + /* set PTC1 MUX as GPIO */ + PinsDrv_SetMuxModeSel(&mcu.ptd, 1, PINSDRV_MUX_AS_GPIO); + /* set PTC1 as GPIO output */ + PinsDrv_SetPinDirection(&mcu.ptd, 1, 0); + PinsDrv_SetPullSel(&mcu.ptd,1,PINSDRV_INTERNAL_PULL_UP); + + + /* get CAN controller default configuration */ + FlexCanBoot_Init(); + + + /* UDS init */ + Uds_UserInit(&udsObj, &udsParam); + + Bootloader_Init(&mcu.flashDrv, &udsObj, &Uds_PositiveResponse, &Uds_NegativeResponse); + + /* Set system tick clock, 1ms event */ + ClockDrv_GetFreq(&mcu.clockDrv, CLOCKDRV_SYS, &gCpuClockFrequency); + SysTick_Config(gCpuClockFrequency / 1000u); + + IrqDrv_EnableIrq(SysTick_IRQn); +#if BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u + Fls_Init(&mcu.flashDrv); + #endif + IrqDrv_EnableGlobalInterrupt(); + + while(1) + { + if(gSystick1msEvent > 0u) + { + gSystick1msEvent = 0; + gSystick1msCnt++; + + if (gSystick1msCnt % 10 == 0) + { + //SEGGER_RTT_printf(0,"-----SBC_WD_Trigger-----\n"); + if (BootReqFlag == 1) + { + SBC_WD_Trigger(); + } + + + } + + if(gSystick1msCnt >= 1000) + { + gSystick1msCnt = 0; + //TxTestMsg(testdata); + + //SEGGER_RTT_printf(0,"-boot running-\n"); + uint8_t ret = SBC_Read_Command(SBC_M_S_CTRL); + SEGGER_RTT_printf(0,"%04d : M_S_CTRL = 0x%x\n",rollingcounter++,ret); + } + if (BootReqFlag == 0) + { + BootReqDelay++; + if (BootReqDelay > 10) + { + BootReqFlag = 1; + BootReqInit(); + } + + } + + + + Bootloader_TimingProcess(1); + Uds_Run(&udsObj); + Bootloader_StateProc(); + } + /* Handler user routine */ + if(FlexCanBoot_ReadoutMsg(&rxMsg) == true) + { + if((rxMsg.id == UDS_PHYS_RECV_MSG_ID) || (rxMsg.id == UDS_FUNC_RECV_MSG_ID)) + { + IsoTp_HandleIncomingCanMsg(&udsObj.isotp, rxMsg.id, rxMsg.data, rxMsg.len); + } + } + } +} + diff --git a/cva_bootloader_m0118/src/private_driver/CVM011x_features.h b/cva_bootloader_m0118/src/private_driver/CVM011x_features.h new file mode 100644 index 0000000..3585225 --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/CVM011x_features.h @@ -0,0 +1,352 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CVM011X_FEATURES_H_ +#define _CVM011X_FEATURES_H_ + +/*! \brief Contains public interface to various functions related + * to the features definition of CVM011x series chips + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#if defined(MCU_CVM0118FMLF) || defined(MCU_CVM0118LMLF) + +#ifdef FEATURE_PFLASH_SIZE +#undef FEATURE_PFLASH_SIZE +#endif +#define FEATURE_PFLASH_SIZE (0x38000) + +#ifdef FEATURE_RAM_SIZE +#undef FEATURE_RAM_SIZE +#endif +#define FEATURE_RAM_SIZE (0x6400) + +#ifdef FEATURE_DFLASH_SIZE +#undef FEATURE_DFLASH_SIZE +#endif +#define FEATURE_DFLASH_SIZE (0x8000) + +#ifdef FEATURE_EEPROM_SIZE +#undef FEATURE_EEPROM_SIZE +#endif +#define FEATURE_EEPROM_SIZE (0x800) + +#ifdef FEATURE_CAN_FD_INSTANCE_NUM +#undef FEATURE_CAN_FD_INSTANCE_NUM +#endif +#define FEATURE_CAN_FD_INSTANCE_NUM (1) + +#ifdef FEATURE_CAN_2_0_INSTANCE_NUM +#undef FEATURE_CAN_2_0_INSTANCE_NUM +#endif +#define FEATURE_CAN_2_0_INSTANCE_NUM (0) + +#ifdef FEATURE_UART_INSTANCE_NUM +#undef FEATURE_UART_INSTANCE_NUM +#endif +#define FEATURE_UART_INSTANCE_NUM (3) + +#elif defined(MCU_CVM0118BMLF) || defined(MCU_CVM0118AMLF) + +#ifdef FEATURE_PFLASH_SIZE +#undef FEATURE_PFLASH_SIZE +#endif +#define FEATURE_PFLASH_SIZE (0x38000) + +#ifdef FEATURE_RAM_SIZE +#undef FEATURE_RAM_SIZE +#endif +#define FEATURE_RAM_SIZE (0x6400) + +#ifdef FEATURE_DFLASH_SIZE +#undef FEATURE_DFLASH_SIZE +#endif +#define FEATURE_DFLASH_SIZE (0x8000) + +#ifdef FEATURE_EEPROM_SIZE +#undef FEATURE_EEPROM_SIZE +#endif +#define FEATURE_EEPROM_SIZE (0x800) + +#ifdef FEATURE_CAN_FD_INSTANCE_NUM +#undef FEATURE_CAN_FD_INSTANCE_NUM +#endif +#define FEATURE_CAN_FD_INSTANCE_NUM (0) + +#ifdef FEATURE_CAN_2_0_INSTANCE_NUM +#undef FEATURE_CAN_2_0_INSTANCE_NUM +#endif +#define FEATURE_CAN_2_0_INSTANCE_NUM (1) + +#ifdef FEATURE_UART_INSTANCE_NUM +#undef FEATURE_UART_INSTANCE_NUM +#endif +#define FEATURE_UART_INSTANCE_NUM (3) + +#elif defined(MCU_CVM0118FMFM) || defined(MCU_CVM0118LMFM) + +#ifdef FEATURE_PFLASH_SIZE +#undef FEATURE_PFLASH_SIZE +#endif +#define FEATURE_PFLASH_SIZE (0x38000) + +#ifdef FEATURE_RAM_SIZE +#undef FEATURE_RAM_SIZE +#endif +#define FEATURE_RAM_SIZE (0x6400) + +#ifdef FEATURE_DFLASH_SIZE +#undef FEATURE_DFLASH_SIZE +#endif +#define FEATURE_DFLASH_SIZE (0x8000) + +#ifdef FEATURE_EEPROM_SIZE +#undef FEATURE_EEPROM_SIZE +#endif +#define FEATURE_EEPROM_SIZE (0x800) + +#ifdef FEATURE_CAN_FD_INSTANCE_NUM +#undef FEATURE_CAN_FD_INSTANCE_NUM +#endif +#define FEATURE_CAN_FD_INSTANCE_NUM (1) + +#ifdef FEATURE_CAN_2_0_INSTANCE_NUM +#undef FEATURE_CAN_2_0_INSTANCE_NUM +#endif +#define FEATURE_CAN_2_0_INSTANCE_NUM (0) + +#ifdef FEATURE_UART_INSTANCE_NUM +#undef FEATURE_UART_INSTANCE_NUM +#endif +#define FEATURE_UART_INSTANCE_NUM (2) + +#elif defined(MCU_CVM0118BMFM) || defined(MCU_CVM0118AMFM) + +#ifdef FEATURE_PFLASH_SIZE +#undef FEATURE_PFLASH_SIZE +#endif +#define FEATURE_PFLASH_SIZE (0x38000) + +#ifdef FEATURE_RAM_SIZE +#undef FEATURE_RAM_SIZE +#endif +#define FEATURE_RAM_SIZE (0x6400) + +#ifdef FEATURE_DFLASH_SIZE +#undef FEATURE_DFLASH_SIZE +#endif +#define FEATURE_DFLASH_SIZE (0x8000) + +#ifdef FEATURE_EEPROM_SIZE +#undef FEATURE_EEPROM_SIZE +#endif +#define FEATURE_EEPROM_SIZE (0x800) + +#ifdef FEATURE_CAN_FD_INSTANCE_NUM +#undef FEATURE_CAN_FD_INSTANCE_NUM +#endif +#define FEATURE_CAN_FD_INSTANCE_NUM (0) + +#ifdef FEATURE_CAN_2_0_INSTANCE_NUM +#undef FEATURE_CAN_2_0_INSTANCE_NUM +#endif +#define FEATURE_CAN_2_0_INSTANCE_NUM (1) + +#ifdef FEATURE_UART_INSTANCE_NUM +#undef FEATURE_UART_INSTANCE_NUM +#endif +#define FEATURE_UART_INSTANCE_NUM (2) + +#elif defined(MCU_CVM0116FMFM) || defined(MCU_CVM0116LMFM) + +#ifdef FEATURE_PFLASH_SIZE +#undef FEATURE_PFLASH_SIZE +#endif +#define FEATURE_PFLASH_SIZE (0x20000) + +#ifdef FEATURE_RAM_SIZE +#undef FEATURE_RAM_SIZE +#endif +#define FEATURE_RAM_SIZE (0x4400) + +#ifdef FEATURE_DFLASH_SIZE +#undef FEATURE_DFLASH_SIZE +#endif +#define FEATURE_DFLASH_SIZE (0x8000) + +#ifdef FEATURE_EEPROM_SIZE +#undef FEATURE_EEPROM_SIZE +#endif +#define FEATURE_EEPROM_SIZE (0x800) + +#ifdef FEATURE_CAN_FD_INSTANCE_NUM +#undef FEATURE_CAN_FD_INSTANCE_NUM +#endif +#define FEATURE_CAN_FD_INSTANCE_NUM (1) + +#ifdef FEATURE_CAN_2_0_INSTANCE_NUM +#undef FEATURE_CAN_2_0_INSTANCE_NUM +#endif +#define FEATURE_CAN_2_0_INSTANCE_NUM (0) + +#ifdef FEATURE_UART_INSTANCE_NUM +#undef FEATURE_UART_INSTANCE_NUM +#endif +#define FEATURE_UART_INSTANCE_NUM (2) + +#elif defined(MCU_CVM0116BMFM) || defined(MCU_CVM0116AMFM) + +#ifdef FEATURE_PFLASH_SIZE +#undef FEATURE_PFLASH_SIZE +#endif +#define FEATURE_PFLASH_SIZE (0x20000) + +#ifdef FEATURE_RAM_SIZE +#undef FEATURE_RAM_SIZE +#endif +#define FEATURE_RAM_SIZE (0x4400) + +#ifdef FEATURE_DFLASH_SIZE +#undef FEATURE_DFLASH_SIZE +#endif +#define FEATURE_DFLASH_SIZE (0x8000) + +#ifdef FEATURE_EEPROM_SIZE +#undef FEATURE_EEPROM_SIZE +#endif +#define FEATURE_EEPROM_SIZE (0x800) + +#ifdef FEATURE_CAN_FD_INSTANCE_NUM +#undef FEATURE_CAN_FD_INSTANCE_NUM +#endif +#define FEATURE_CAN_FD_INSTANCE_NUM (0) + +#ifdef FEATURE_CAN_2_0_INSTANCE_NUM +#undef FEATURE_CAN_2_0_INSTANCE_NUM +#endif +#define FEATURE_CAN_2_0_INSTANCE_NUM (1) + +#ifdef FEATURE_UART_INSTANCE_NUM +#undef FEATURE_UART_INSTANCE_NUM +#endif +#define FEATURE_UART_INSTANCE_NUM (2) + +#elif defined(MCU_CVM0114BMFM) + +#ifdef FEATURE_PFLASH_SIZE +#undef FEATURE_PFLASH_SIZE +#endif +#define FEATURE_PFLASH_SIZE (0x10000) + +#ifdef FEATURE_RAM_SIZE +#undef FEATURE_RAM_SIZE +#endif +#define FEATURE_RAM_SIZE (0x4400) + +#ifdef FEATURE_DFLASH_SIZE +#undef FEATURE_DFLASH_SIZE +#endif +#define FEATURE_DFLASH_SIZE (0x8000) + +#ifdef FEATURE_EEPROM_SIZE +#undef FEATURE_EEPROM_SIZE +#endif +#define FEATURE_EEPROM_SIZE (0x800) + +#ifdef FEATURE_CAN_FD_INSTANCE_NUM +#undef FEATURE_CAN_FD_INSTANCE_NUM +#endif +#define FEATURE_CAN_FD_INSTANCE_NUM (0) + +#ifdef FEATURE_CAN_2_0_INSTANCE_NUM +#undef FEATURE_CAN_2_0_INSTANCE_NUM +#endif +#define FEATURE_CAN_2_0_INSTANCE_NUM (1) + +#ifdef FEATURE_UART_INSTANCE_NUM +#undef FEATURE_UART_INSTANCE_NUM +#endif +#define FEATURE_UART_INSTANCE_NUM (2) + +#elif defined(MCU_CVM0118TVLF) + +#ifdef FEATURE_PFLASH_SIZE +#undef FEATURE_PFLASH_SIZE +#endif +#define FEATURE_PFLASH_SIZE (0x38000) + +#ifdef FEATURE_RAM_SIZE +#undef FEATURE_RAM_SIZE +#endif +#define FEATURE_RAM_SIZE (0x6400) + +#ifdef FEATURE_DFLASH_SIZE +#undef FEATURE_DFLASH_SIZE +#endif +#define FEATURE_DFLASH_SIZE (0x8000) + +#ifdef FEATURE_EEPROM_SIZE +#undef FEATURE_EEPROM_SIZE +#endif +#define FEATURE_EEPROM_SIZE (0x800) + +#ifdef FEATURE_CAN_FD_INSTANCE_NUM +#undef FEATURE_CAN_FD_INSTANCE_NUM +#endif +#define FEATURE_CAN_FD_INSTANCE_NUM (0) + +#ifdef FEATURE_CAN_2_0_INSTANCE_NUM +#undef FEATURE_CAN_2_0_INSTANCE_NUM +#endif +#define FEATURE_CAN_2_0_INSTANCE_NUM (1) + +#ifdef FEATURE_UART_INSTANCE_NUM +#undef FEATURE_UART_INSTANCE_NUM +#endif +#define FEATURE_UART_INSTANCE_NUM (2) + +#else +#error "No correct chip defined" +#endif + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _CVM011X_FEATURES_H_ */ diff --git a/cva_bootloader_m0118/src/private_driver/drivers/clock/clock_drv.c b/cva_bootloader_m0118/src/private_driver/drivers/clock/clock_drv.c new file mode 100644 index 0000000..2e46e74 --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/drivers/clock/clock_drv.c @@ -0,0 +1,2598 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "clock_drv.h" +#include "rcm_reg.h" +#include "scg0_reg.h" +#include "scg1_reg.h" +#include "scg2_reg.h" +#include "pcc0_reg.h" +#include "pcc1_reg.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* Definitions for LPO frequencies */ +#define LPO_128K_FREQUENCY (128000UL) +#define LPO_32K_FREQUENCY (32000UL) +#define LPO_1K_FREQUENCY (1000UL) + +/* Definitions for all the get and set clock interface */ +#define GET_FREQ_FUNC_DEF(module) static inline bool ClockDrv_Get##module##Freq(const ClockDrvType *obj, uint32_t *frequency) +#define GET_FREQ_FUNC(module) ClockDrv_Get##module##Freq +#define CONFIG_CLOCK_FUNC_DEF(module) static inline bool ClockDrv_Set##module##Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +#define CONFIG_CLOCK_FUNC(module) ClockDrv_Set##module##Clock + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Module clock function table element definition + */ +typedef struct _ClockDrv_ModuleClkFuncType_ +{ + bool (*getFreqFunc)(const ClockDrvType *, uint32_t *); + bool (*setClockFunc)(ClockDrvType *, const ClockDrv_ModuleClkConfigType *); +} ClockDrv_ModuleClkFuncType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/* Forward decleratios for all get and set clock interface */ +GET_FREQ_FUNC_DEF(Sosc); +CONFIG_CLOCK_FUNC_DEF(Sosc); +GET_FREQ_FUNC_DEF(Sirc); +GET_FREQ_FUNC_DEF(Pll); +CONFIG_CLOCK_FUNC_DEF(Pll); +GET_FREQ_FUNC_DEF(SoscDiv); +CONFIG_CLOCK_FUNC_DEF(SoscDiv); +GET_FREQ_FUNC_DEF(SoscDivMft); +CONFIG_CLOCK_FUNC_DEF(SoscDivMft); +GET_FREQ_FUNC_DEF(SircDiv); +CONFIG_CLOCK_FUNC_DEF(SircDiv); +GET_FREQ_FUNC_DEF(SircDivMft); +CONFIG_CLOCK_FUNC_DEF(SircDivMft); +GET_FREQ_FUNC_DEF(PllDiv); +CONFIG_CLOCK_FUNC_DEF(PllDiv); +GET_FREQ_FUNC_DEF(PllDivMft); +CONFIG_CLOCK_FUNC_DEF(PllDivMft); +GET_FREQ_FUNC_DEF(Sys); +CONFIG_CLOCK_FUNC_DEF(Sys); +GET_FREQ_FUNC_DEF(Core); +CONFIG_CLOCK_FUNC_DEF(Core); +GET_FREQ_FUNC_DEF(Apb); +CONFIG_CLOCK_FUNC_DEF(Apb); +GET_FREQ_FUNC_DEF(Fls); +CONFIG_CLOCK_FUNC_DEF(Fls); +GET_FREQ_FUNC_DEF(ClkOut); +CONFIG_CLOCK_FUNC_DEF(ClkOut); +GET_FREQ_FUNC_DEF(RtcPadIn); +GET_FREQ_FUNC_DEF(Lpo1k); +CONFIG_CLOCK_FUNC_DEF(Lpo1k); +GET_FREQ_FUNC_DEF(Lpo32k); +CONFIG_CLOCK_FUNC_DEF(Lpo32k); +GET_FREQ_FUNC_DEF(Lpo128k); +CONFIG_CLOCK_FUNC_DEF(Lpo32k); +GET_FREQ_FUNC_DEF(Cmp); +CONFIG_CLOCK_FUNC_DEF(Cmp); +GET_FREQ_FUNC_DEF(PortA); +CONFIG_CLOCK_FUNC_DEF(PortA); +GET_FREQ_FUNC_DEF(PortB); +CONFIG_CLOCK_FUNC_DEF(PortB); +GET_FREQ_FUNC_DEF(PortC); +CONFIG_CLOCK_FUNC_DEF(PortC); +GET_FREQ_FUNC_DEF(PortD); +CONFIG_CLOCK_FUNC_DEF(PortD); +GET_FREQ_FUNC_DEF(PortE); +CONFIG_CLOCK_FUNC_DEF(PortE); +GET_FREQ_FUNC_DEF(Lptmr); +CONFIG_CLOCK_FUNC_DEF(Lptmr); +GET_FREQ_FUNC_DEF(Lpit); +CONFIG_CLOCK_FUNC_DEF(Lpit); +GET_FREQ_FUNC_DEF(RtcCnt); +CONFIG_CLOCK_FUNC_DEF(RtcCnt); +GET_FREQ_FUNC_DEF(PortAFlt); +CONFIG_CLOCK_FUNC_DEF(PortAFlt); +GET_FREQ_FUNC_DEF(PortBFlt); +CONFIG_CLOCK_FUNC_DEF(PortBFlt); +GET_FREQ_FUNC_DEF(PortCFlt); +CONFIG_CLOCK_FUNC_DEF(PortCFlt); +GET_FREQ_FUNC_DEF(PortDFlt); +CONFIG_CLOCK_FUNC_DEF(PortDFlt); +GET_FREQ_FUNC_DEF(PortEFlt); +CONFIG_CLOCK_FUNC_DEF(PortEFlt); +GET_FREQ_FUNC_DEF(ExtFlt); +CONFIG_CLOCK_FUNC_DEF(ExtFlt); +GET_FREQ_FUNC_DEF(Dma); +CONFIG_CLOCK_FUNC_DEF(Dma); +GET_FREQ_FUNC_DEF(Mscm); +CONFIG_CLOCK_FUNC_DEF(Mscm); +GET_FREQ_FUNC_DEF(Crc); +CONFIG_CLOCK_FUNC_DEF(Crc); +GET_FREQ_FUNC_DEF(Eim); +CONFIG_CLOCK_FUNC_DEF(Eim); +GET_FREQ_FUNC_DEF(Erm); +CONFIG_CLOCK_FUNC_DEF(Erm); +GET_FREQ_FUNC_DEF(Fhu); +CONFIG_CLOCK_FUNC_DEF(Fhu); +GET_FREQ_FUNC_DEF(Adc); +CONFIG_CLOCK_FUNC_DEF(Adc); +GET_FREQ_FUNC_DEF(Pdb); +CONFIG_CLOCK_FUNC_DEF(Pdb); +GET_FREQ_FUNC_DEF(Spi0); +CONFIG_CLOCK_FUNC_DEF(Spi0); +GET_FREQ_FUNC_DEF(Spi1); +CONFIG_CLOCK_FUNC_DEF(Spi1); +GET_FREQ_FUNC_DEF(Uart0); +CONFIG_CLOCK_FUNC_DEF(Uart0); +GET_FREQ_FUNC_DEF(Uart1); +CONFIG_CLOCK_FUNC_DEF(Uart1); +GET_FREQ_FUNC_DEF(Uart2); +CONFIG_CLOCK_FUNC_DEF(Uart2); +GET_FREQ_FUNC_DEF(I2C); +CONFIG_CLOCK_FUNC_DEF(I2C); +GET_FREQ_FUNC_DEF(I2SM); +CONFIG_CLOCK_FUNC_DEF(I2SM); +GET_FREQ_FUNC_DEF(I2SS); +CONFIG_CLOCK_FUNC_DEF(I2SS); +GET_FREQ_FUNC_DEF(PwmLite0); +CONFIG_CLOCK_FUNC_DEF(PwmLite0); +GET_FREQ_FUNC_DEF(PwmLite1); +CONFIG_CLOCK_FUNC_DEF(PwmLite1); +GET_FREQ_FUNC_DEF(Mft0); +CONFIG_CLOCK_FUNC_DEF(Mft0); +GET_FREQ_FUNC_DEF(Mft1); +CONFIG_CLOCK_FUNC_DEF(Mft1); +GET_FREQ_FUNC_DEF(Cmus); +CONFIG_CLOCK_FUNC_DEF(Cmus); +GET_FREQ_FUNC_DEF(Cmup); +CONFIG_CLOCK_FUNC_DEF(Cmup); +GET_FREQ_FUNC_DEF(Tclk0); +GET_FREQ_FUNC_DEF(Tclk1); +GET_FREQ_FUNC_DEF(Tclk2); +GET_FREQ_FUNC_DEF(ExtMft0); +CONFIG_CLOCK_FUNC_DEF(ExtMft0); +GET_FREQ_FUNC_DEF(ExtMft1); +CONFIG_CLOCK_FUNC_DEF(ExtMft1); +GET_FREQ_FUNC_DEF(FixMft0); +CONFIG_CLOCK_FUNC_DEF(FixMft0); +GET_FREQ_FUNC_DEF(FixMft1); +CONFIG_CLOCK_FUNC_DEF(FixMft1); +GET_FREQ_FUNC_DEF(Mpu); +CONFIG_CLOCK_FUNC_DEF(Mpu); + +/* Function table for all get and set clock interface */ +const ClockDrv_ModuleClkFuncType c_clockFuncTable[CLOCKDRV_CLOCK_NUM] = { + {GET_FREQ_FUNC(Sosc), CONFIG_CLOCK_FUNC(Sosc) }, /* CLOCKDRV_SOSC */ + {GET_FREQ_FUNC(Sirc), NULL }, /* CLOCKDRV_SIRC */ + {GET_FREQ_FUNC(Pll), CONFIG_CLOCK_FUNC(Pll) }, /* CLOCKDRV_PLL */ + {GET_FREQ_FUNC(SoscDiv), CONFIG_CLOCK_FUNC(SoscDiv) }, /* CLOCKDRV_SOSC_DIV */ + {GET_FREQ_FUNC(SoscDivMft), CONFIG_CLOCK_FUNC(SoscDivMft)}, /* CLOCKDRV_SOSC_DIV_MFT */ + {GET_FREQ_FUNC(SircDiv), CONFIG_CLOCK_FUNC(SircDiv) }, /* CLOCKDRV_SIRC_DIV */ + {GET_FREQ_FUNC(SircDivMft), CONFIG_CLOCK_FUNC(SircDivMft)}, /* CLOCKDRV_SIRC_DIV_MFT */ + {GET_FREQ_FUNC(PllDiv), CONFIG_CLOCK_FUNC(PllDiv) }, /* CLOCKDRV_PLL_DIV */ + {GET_FREQ_FUNC(PllDivMft), CONFIG_CLOCK_FUNC(PllDivMft) }, /* CLOCKDRV_PLL_DIV_MFT */ + {GET_FREQ_FUNC(Sys), CONFIG_CLOCK_FUNC(Sys) }, /* CLOCKDRV_SYS */ + {GET_FREQ_FUNC(Core), CONFIG_CLOCK_FUNC(Core) }, /* CLOCKDRV_CORE */ + {GET_FREQ_FUNC(Apb), CONFIG_CLOCK_FUNC(Apb) }, /* CLOCKDRV_APB */ + {GET_FREQ_FUNC(Fls), CONFIG_CLOCK_FUNC(Fls) }, /* CLOCKDRV_FLS */ + {GET_FREQ_FUNC(ClkOut), CONFIG_CLOCK_FUNC(ClkOut) }, /* CLOCKDRV_CLKOUT */ + {GET_FREQ_FUNC(RtcPadIn), NULL }, /* CLOCKDRV_RTC_PADIN */ + {GET_FREQ_FUNC(Lpo1k), CONFIG_CLOCK_FUNC(Lpo1k) }, /* CLOCKDRV_LPO_1K */ + {GET_FREQ_FUNC(Lpo32k), CONFIG_CLOCK_FUNC(Lpo32k) }, /* CLOCKDRV_LPO_32K */ + {GET_FREQ_FUNC(Lpo128k), NULL }, /* CLOCKDRV_LPO_128K */ + {GET_FREQ_FUNC(Cmp), CONFIG_CLOCK_FUNC(Cmp) }, /* CLOCKDRV_CMP */ + {GET_FREQ_FUNC(PortA), CONFIG_CLOCK_FUNC(PortA) }, /* CLOCKDRV_PORTA */ + {GET_FREQ_FUNC(PortB), CONFIG_CLOCK_FUNC(PortB) }, /* CLOCKDRV_PORTB */ + {GET_FREQ_FUNC(PortC), CONFIG_CLOCK_FUNC(PortC) }, /* CLOCKDRV_PORTC */ + {GET_FREQ_FUNC(PortD), CONFIG_CLOCK_FUNC(PortD) }, /* CLOCKDRV_PORTD */ + {GET_FREQ_FUNC(PortE), CONFIG_CLOCK_FUNC(PortE) }, /* CLOCKDRV_PORTE */ + {GET_FREQ_FUNC(Lptmr), CONFIG_CLOCK_FUNC(Lptmr) }, /* CLOCKDRV_LPTMR */ + {GET_FREQ_FUNC(Lpit), CONFIG_CLOCK_FUNC(Lpit) }, /* CLOCKDRV_LPIT */ + {GET_FREQ_FUNC(RtcCnt), CONFIG_CLOCK_FUNC(RtcCnt) }, /* CLOCKDRV_RTC_CNT */ + {GET_FREQ_FUNC(PortAFlt), CONFIG_CLOCK_FUNC(PortAFlt) }, /* CLOCKDRV_PORTA_FLT */ + {GET_FREQ_FUNC(PortBFlt), CONFIG_CLOCK_FUNC(PortBFlt) }, /* CLOCKDRV_PORTB_FLT */ + {GET_FREQ_FUNC(PortCFlt), CONFIG_CLOCK_FUNC(PortCFlt) }, /* CLOCKDRV_PORTC_FLT */ + {GET_FREQ_FUNC(PortDFlt), CONFIG_CLOCK_FUNC(PortDFlt) }, /* CLOCKDRV_PORTD_FLT */ + {GET_FREQ_FUNC(PortEFlt), CONFIG_CLOCK_FUNC(PortEFlt) }, /* CLOCKDRV_PORTE_FLT */ + {GET_FREQ_FUNC(ExtFlt), CONFIG_CLOCK_FUNC(ExtFlt) }, /* CLOCKDRV_EXT_FLT */ + {GET_FREQ_FUNC(Dma), CONFIG_CLOCK_FUNC(Dma) }, /* CLOCKDRV_DMA */ + {GET_FREQ_FUNC(Mscm), CONFIG_CLOCK_FUNC(Mscm) }, /* CLOCKDRV_MSCM */ + {GET_FREQ_FUNC(Crc), CONFIG_CLOCK_FUNC(Crc) }, /* CLOCKDRV_CRC */ + {GET_FREQ_FUNC(Eim), CONFIG_CLOCK_FUNC(Eim) }, /* CLOCKDRV_EIM */ + {GET_FREQ_FUNC(Erm), CONFIG_CLOCK_FUNC(Erm) }, /* CLOCKDRV_ERM */ + {GET_FREQ_FUNC(Fhu), CONFIG_CLOCK_FUNC(Fhu) }, /* CLOCKDRV_FHU */ + + {GET_FREQ_FUNC(Adc), CONFIG_CLOCK_FUNC(Adc) }, /* CLOCKDRV_ADC */ + {GET_FREQ_FUNC(Pdb), CONFIG_CLOCK_FUNC(Pdb) }, /* CLOCKDRV_PDB */ + {GET_FREQ_FUNC(Spi0), CONFIG_CLOCK_FUNC(Spi0) }, /* CLOCKDRV_SPI0 */ +#if 0 + {GET_FREQ_FUNC(Spi1), CONFIG_CLOCK_FUNC(Spi1) }, /* CLOCKDRV_SPI1 */ + {GET_FREQ_FUNC(Uart0), CONFIG_CLOCK_FUNC(Uart0) }, /* CLOCKDRV_UART0 */ + {GET_FREQ_FUNC(Uart1), CONFIG_CLOCK_FUNC(Uart1) }, /* CLOCKDRV_UART1 */ + {GET_FREQ_FUNC(Uart2), CONFIG_CLOCK_FUNC(Uart2) }, /* CLOCKDRV_UART2 */ + {GET_FREQ_FUNC(I2C), CONFIG_CLOCK_FUNC(I2C) }, /* CLOCKDRV_I2C */ + {GET_FREQ_FUNC(I2SM), CONFIG_CLOCK_FUNC(I2SM) }, /* CLOCKDRV_I2SM */ + {GET_FREQ_FUNC(I2SS), CONFIG_CLOCK_FUNC(I2SS) }, /* CLOCKDRV_I2SS */ + {GET_FREQ_FUNC(PwmLite0), CONFIG_CLOCK_FUNC(PwmLite0) }, /* CLOCKDRV_PWMLITE0 */ + {GET_FREQ_FUNC(PwmLite1), CONFIG_CLOCK_FUNC(PwmLite1) }, /* CLOCKDRV_PWMLITE1 */ + {GET_FREQ_FUNC(Mft0), CONFIG_CLOCK_FUNC(Mft0) }, /* CLOCKDRV_MFT0 */ + {GET_FREQ_FUNC(Mft1), CONFIG_CLOCK_FUNC(Mft1) }, /* CLOCKDRV_MFT1 */ + {GET_FREQ_FUNC(Cmus), CONFIG_CLOCK_FUNC(Cmus) }, /* CLOCKDRV_CMUS */ + {GET_FREQ_FUNC(Cmup), CONFIG_CLOCK_FUNC(Cmup) }, /* CLOCKDRV_CMUP */ +#endif + {GET_FREQ_FUNC(Tclk0), NULL }, /* CLOCKDRV_TCLK0 */ + {GET_FREQ_FUNC(Tclk1), NULL }, /* CLOCKDRV_TCLK1 */ + {GET_FREQ_FUNC(Tclk2), NULL }, /* CLOCKDRV_TCLK2 */ + {GET_FREQ_FUNC(ExtMft0), CONFIG_CLOCK_FUNC(ExtMft0) }, /* CLOCKDRV_EXT_MFT0 */ + {GET_FREQ_FUNC(ExtMft1), CONFIG_CLOCK_FUNC(ExtMft1) }, /* CLOCKDRV_EXT_MFT1 */ + {GET_FREQ_FUNC(FixMft0), CONFIG_CLOCK_FUNC(FixMft0) }, /* CLOCKDRV_FIX_MFT0 */ + {GET_FREQ_FUNC(FixMft1), CONFIG_CLOCK_FUNC(FixMft1) }, /* CLOCKDRV_FIX_MFT1 */ + {GET_FREQ_FUNC(Mpu), CONFIG_CLOCK_FUNC(Mpu) }, /* CLOCKDRV_MPU */ +}; + +/******************************************************************************* + * the functions + ******************************************************************************/ + +static inline bool ClockDrv_GetSoscFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Scg0Reg_GetOscCtrlEnSosc(obj->scg0Reg) && Scg0Reg_GetStatusSoscRdy(obj->scg0Reg)) + { + *frequency = obj->xtalClkFreq; + return true; + } + return false; +} + +static inline bool ClockDrv_SetSoscClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + /* Disable SOSC first, before configure */ + Scg0Reg_SetOscCtrlEnSosc(obj->scg0Reg, 0); + + /* Enable SOSC if required */ + if(moduleClkConfig->gating) + { + uint8_t soscRange = obj->xtalClkFreq == 4000000 ? 0 : (obj->xtalClkFreq <= 8000000 ? 1 : (obj->xtalClkFreq <= 24000000 ? 2 : (obj->xtalClkFreq <= 40000000 ? 3 : 4))); + if(4 == soscRange) + { + return false; + } + /* Set SOSC frequency range */ + Scg0Reg_SetOscCtrlRange(obj->scg0Reg, soscRange); + /* Disable external EXTAL clock in, cannot enable at the same time */ + Scg0Reg_SetOscCtrlEnExtClk(obj->scg0Reg, 0); + /* Enable SOSC */ + Scg0Reg_SetOscCtrlEnSosc(obj->scg0Reg, 1); + while(Scg0Reg_GetStatusSoscRdy(obj->scg0Reg) == 0) + { + ; /* Wait until SOSC is locked */ + } + } + + return true; +} + +static inline bool ClockDrv_GetSircFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + /* SIRC always enabled */ + if(Scg0Reg_GetStatusSircRdy(obj->scg0Reg)) + { + *frequency = obj->sircFreq; + return true; + } + return false; +} + +static inline bool ClockDrv_GetPllFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Scg0Reg_GetPllCtrl0PllEn(obj->scg0Reg) && Scg0Reg_GetStatusPllLock(obj->scg0Reg)) + { + uint32_t freq; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Scg0Reg_GetPllCtrl1PllClkinSel(obj->scg0Reg)) + { + case 0: /* SOSC clock as source */ + retval = ClockDrv_GetSoscFreq(obj, &freq); + break; + case 1: /* SIRC clock as source */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + /* If the source clock is valid */ + if(false == retval) + { + return false; + } + + /* Get the PLL pre-divider */ + uint32_t preDiv = 1; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Scg0Reg_GetPllCtrl0PllPreDiv(obj->scg0Reg)) + { + case 0: + preDiv = 1; + break; + case 1: + preDiv = 2; + break; + case 2: + preDiv = 4; + break; + case 3: + preDiv = 8; + break; + default: + /* should not get here */ + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + /* Get the PLL feedback divider setting */ + uint32_t mult = Scg0Reg_GetPllCtrl0PllM(obj->scg0Reg); + mult = (mult == 0 ? 128 : mult); + /* Get the PLL feedback divider setting */ + uint32_t postDiv = Scg0Reg_GetPllCtrl0PllPosDiv(obj->scg0Reg); + postDiv = (postDiv == 0 ? 8 : postDiv); + /* Get the PLL Feedback clock divider pre-scaler */ + uint32_t fblSel = Scg0Reg_GetPllCtrl0PllFdkSel(obj->scg0Reg); + fblSel = fblSel + 1; + + /* Calculate the final PLL frequency */ + *frequency = (freq * mult * fblSel) / (2 * preDiv * postDiv); + + retval = true; + } + + return retval; +} + +bool ClockDrv_SetPllClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + /* Disable PLL first, before configure */ + Scg0Reg_SetPllCtrl0PllEn(obj->scg0Reg, 0); + + bool retval = true; + switch(moduleClkConfig->source) + { + case CLOCKDRV_SOSC: /* SOSC clock as source */ + Scg0Reg_SetPllCtrl1PllClkinSel(obj->scg0Reg, 0); + break; + case CLOCKDRV_SIRC: /* SIRC clock as source */ + Scg0Reg_SetPllCtrl1PllClkinSel(obj->scg0Reg, 1); + break; + default: + retval = false; + break; + } + /* If the source clock is valid */ + if(false == retval) + { + return false; + } + + /* Set the PLL pre-divider */ + uint8_t preDiv = moduleClkConfig->pllConfig.preDiv == 1 ? 0 : (moduleClkConfig->pllConfig.preDiv == 2 ? 1 : (moduleClkConfig->pllConfig.preDiv == 4 ? 2 : (moduleClkConfig->pllConfig.preDiv == 8 ? 3 : 0xff))); + /* If PLL pre-divider is valid */ + if(0xff == preDiv) + { + return false; + } + Scg0Reg_SetPllCtrl0PllPreDiv(obj->scg0Reg, preDiv); + + /* Set the PLL feedback divider */ + if(moduleClkConfig->mult >= 1 && moduleClkConfig->mult <= 128) + { + Scg0Reg_SetPllCtrl0PllM(obj->scg0Reg, moduleClkConfig->mult == 128 ? 0 : moduleClkConfig->mult); + } + else + { + return false; + } + + /* Set the post-divider */ + if(moduleClkConfig->pllConfig.postDiv >= 1 && moduleClkConfig->pllConfig.postDiv <= 8) + { + Scg0Reg_SetPllCtrl0PllPosDiv(obj->scg0Reg, moduleClkConfig->pllConfig.postDiv == 8 ? 0 : moduleClkConfig->pllConfig.postDiv); + } + else + { + return false; + } + + /* Set the feedback clock divider pre-scaler */ + if(moduleClkConfig->pllConfig.fblSel == 1 || moduleClkConfig->pllConfig.fblSel == 2) + { + Scg0Reg_SetPllCtrl0PllFdkSel(obj->scg0Reg, moduleClkConfig->pllConfig.fblSel - 1); + } + else + { + return false; + } + + /* Enable PLL if required */ + if(moduleClkConfig->gating) + { + Scg0Reg_SetPllCtrl0PllEn(obj->scg0Reg, 1); + while(Scg0Reg_GetStatusPllLock(obj->scg0Reg) == 0) + { + ; /* Wait until PLL is locked */ + } + } + + return retval; +} + +static inline bool ClockDrv_GetSoscDivFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetSoscCfgEn(obj->scg2Reg)) + { + retval = ClockDrv_GetSoscFreq(obj, &freq); + if(retval) + { + uint32_t div = ((uint32_t)1UL) << Scg2Reg_GetSoscCfgDiv(obj->scg2Reg); + if(div <= 64) + { + *frequency = freq / div; + } + else + { + retval = false; + } + } + } + + return retval; +} + +static inline bool ClockDrv_SetSoscDivClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Scg2Reg_SetSoscCfgEn(obj->scg2Reg, 0); + + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : (moduleClkConfig->div == 16 ? 4 : (moduleClkConfig->div == 32 ? 5 : (moduleClkConfig->div == 64 ? 6 : 7)))))); + if(div != 7) + { + Scg2Reg_SetSoscCfgDiv(obj->scg2Reg, div); + retval = true; + } + /* Enable if required */ + Scg2Reg_SetSoscCfgEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetSoscDivMftFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetSoscMftEn(obj->scg2Reg)) + { + retval = ClockDrv_GetSoscFreq(obj, &freq); + if(retval) + { + uint32_t div = ((uint32_t)1UL) << Scg2Reg_GetSoscMftDiv(obj->scg2Reg); + if(div <= 64) + { + *frequency = freq / div; + } + else + { + retval = false; + } + } + } + + return retval; +} + +static inline bool ClockDrv_SetSoscDivMftClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Scg2Reg_SetSoscMftEn(obj->scg2Reg, 0); + + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : (moduleClkConfig->div == 16 ? 4 : (moduleClkConfig->div == 32 ? 5 : (moduleClkConfig->div == 64 ? 6 : 7)))))); + if(div != 7) + { + Scg2Reg_SetSoscMftDiv(obj->scg2Reg, div); + retval = true; + } + /* Enable if required */ + Scg2Reg_SetSoscMftEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetSircDivFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetSircCfgEn(obj->scg2Reg)) + { + retval = ClockDrv_GetSircFreq(obj, &freq); + if(retval) + { + uint32_t div = ((uint32_t)1UL) << Scg2Reg_GetSircCfgDiv(obj->scg2Reg); + if(div <= 64) + { + *frequency = freq / div; + } + else + { + retval = false; + } + } + } + + return retval; +} + +static inline bool ClockDrv_SetSircDivClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Scg2Reg_SetSircCfgEn(obj->scg2Reg, 0); + + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : (moduleClkConfig->div == 16 ? 4 : (moduleClkConfig->div == 32 ? 5 : (moduleClkConfig->div == 64 ? 6 : 7)))))); + if(div != 7) + { + Scg2Reg_SetSircCfgDiv(obj->scg2Reg, div); + retval = true; + } + /* Enable if required */ + Scg2Reg_SetSircCfgEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetSircDivMftFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetSircMftEn(obj->scg2Reg)) + { + retval = ClockDrv_GetSircFreq(obj, &freq); + if(retval) + { + uint32_t div = ((uint32_t)1UL) << Scg2Reg_GetSircMftDiv(obj->scg2Reg); + if(div <= 64) + { + *frequency = freq / div; + } + else + { + retval = false; + } + } + } + + return retval; +} + +static inline bool ClockDrv_SetSircDivMftClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Scg2Reg_SetSircMftEn(obj->scg2Reg, 0); + + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : (moduleClkConfig->div == 16 ? 4 : (moduleClkConfig->div == 32 ? 5 : (moduleClkConfig->div == 64 ? 6 : 7)))))); + if(div != 7) + { + Scg2Reg_SetSircMftDiv(obj->scg2Reg, div); + retval = true; + } + /* Enable if required */ + Scg2Reg_SetSircMftEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetPllDivFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetPllCfgEn(obj->scg2Reg)) + { + retval = ClockDrv_GetPllFreq(obj, &freq); + if(retval) + { + uint32_t div = ((uint32_t)1UL) << Scg2Reg_GetPllCfgDiv(obj->scg2Reg); + if(div <= 64) + { + *frequency = freq / div; + } + else + { + retval = false; + } + } + } + + return retval; +} + +static inline bool ClockDrv_SetPllDivClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Scg2Reg_SetPllCfgEn(obj->scg2Reg, 0); + + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : (moduleClkConfig->div == 16 ? 4 : (moduleClkConfig->div == 32 ? 5 : (moduleClkConfig->div == 64 ? 6 : 7)))))); + if(div != 7) + { + Scg2Reg_SetPllCfgDiv(obj->scg2Reg, div); + retval = true; + } + /* Enable if required */ + Scg2Reg_SetPllCfgEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetPllDivMftFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetPllMftEn(obj->scg2Reg)) + { + retval = ClockDrv_GetPllFreq(obj, &freq); + if(retval) + { + uint32_t div = ((uint32_t)1UL) << Scg2Reg_GetPllMftDiv(obj->scg2Reg); + if(div <= 64) + { + *frequency = freq / div; + } + else + { + retval = false; + } + } + } + + return retval; +} + +static inline bool ClockDrv_SetPllDivMftClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Scg2Reg_SetPllMftEn(obj->scg2Reg, 0); + + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : (moduleClkConfig->div == 16 ? 4 : (moduleClkConfig->div == 32 ? 5 : (moduleClkConfig->div == 64 ? 6 : 7)))))); + if(div != 7) + { + Scg2Reg_SetPllMftDiv(obj->scg2Reg, div); + retval = true; + } + /* Enable if required */ + Scg2Reg_SetPllMftEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetSysFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + + /* Get system clock freq */ + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Scg2Reg_GetCsrSysSt(obj->scg2Reg)) + { + case 0: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, frequency); + break; + case 1: /* clk_sosc */ + retval = ClockDrv_GetSoscFreq(obj, frequency); + break; + case 2: /* clk_pll */ + retval = ClockDrv_GetPllFreq(obj, frequency); + break; + case 3: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, frequency); + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetSysClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL ? 2 : 0xff)); + if(select == 0xff) + { + return false; + } + + Scg2Reg_SetCsrSrcSys(obj->scg2Reg, select); + while(Scg2Reg_GetCsrSysSt(obj->scg2Reg) != select) + { + ; + } + + return true; +} + +static inline bool ClockDrv_GetCoreFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + /* Get system clock freq */ + uint32_t sysFreq; + retval = ClockDrv_GetSysFreq(obj, &sysFreq); + if(false == retval) + { + return false; + } + /* Get core clock freq */ + *frequency = sysFreq / (Scg1Reg_GetCkSrcSysDiv(obj->scg1Reg) + 1U); + + return retval; +} + +static inline bool ClockDrv_SetCoreClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + /* The clock source is clk_sys */ + if(moduleClkConfig->div >= 1 && moduleClkConfig->div <= 16) + { + Scg1Reg_SetCkSrcSysDiv(obj->scg1Reg, moduleClkConfig->div - 1); + return true; + } + return false; +} + +static inline bool ClockDrv_GetApbFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + /* Get core clock freq */ + uint32_t coreFreq; + retval = ClockDrv_GetCoreFreq(obj, &coreFreq); + if(false == retval) + { + return false; + } + /* Get APB clock freq */ + *frequency = coreFreq / (Scg2Reg_GetCsrDivAips(obj->scg2Reg) + 1U); + + return retval; +} + +static inline bool ClockDrv_SetApbClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + /* The clock source is core clock */ + if(moduleClkConfig->div >= 1 && moduleClkConfig->div <= 16) + { + Scg2Reg_SetCsrDivAips(obj->scg2Reg, moduleClkConfig->div - 1); + return true; + } + return false; +} + +static inline bool ClockDrv_GetFlsFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + /* Get core clock freq */ + uint32_t srcFreq; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetFlsCtlCntSrc(obj->pcc1Reg)) + { + case 0: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &srcFreq); + break; + case 1: /* clk_sosc */ + retval = ClockDrv_GetSoscFreq(obj, &srcFreq); + break; + case 2: /* clk_pll */ + retval = ClockDrv_GetPllFreq(obj, &srcFreq); + break; + case 3: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &srcFreq); + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + if(false == retval) + { + return false; + } + /* Get flash clock freq */ + if(Pcc1Reg_GetFlsCtlCkEn(obj->pcc1Reg)) + { + *frequency = srcFreq / (Pcc1Reg_GetFlsCtlCntDiv(obj->pcc1Reg) + 1U); + } + else + { + retval = false; + } + + return retval; +} + +static inline bool ClockDrv_SetFlsClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + /* The clock source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL ? 2 : 0xff)); + if(select == 0xff) + { + return false; + } + + if(moduleClkConfig->div >= 1 && moduleClkConfig->div <= 16) + { + Pcc1Reg_SetFlsCtlCntSrc(obj->pcc1Reg, select); + Pcc1Reg_SetFlsCtlCntDiv(obj->pcc1Reg, moduleClkConfig->div - 1); + Pcc1Reg_SetFlsCtlCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; + } + return false; +} + +static inline bool ClockDrv_GetClkOutFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Scg2Reg_GetClkOutEn(obj->scg2Reg) == 0) + { + return false; + } + + bool retval = false; + uint32_t freq = 0; + if(Scg2Reg_GetClkOutSrc1(obj->scg2Reg) == 0) + { + /* SCG out selected */ + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Scg2Reg_GetClkOutSrc0(obj->scg2Reg)) + { + case 0: + /* clk_cnt_fls */ + retval = ClockDrv_GetFlsFreq(obj, &freq); + break; + case 1: + /* clk_sosc */ + retval = ClockDrv_GetSoscFreq(obj, &freq); + break; + case 2: + /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + case 3: + /* clk_pll */ + retval = ClockDrv_GetPllFreq(obj, &freq); + break; + case 4: + /* clk_core */ + retval = ClockDrv_GetCoreFreq(obj, &freq); + break; + case 5: + /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, &freq); + break; + case 6: + /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, &freq); + break; + case 7: + /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, &freq); + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + } + else + { + switch(Scg2Reg_GetClkOutSrc1(obj->scg2Reg)) + { + case 1: + /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, &freq); + break; + case 2: + /* clk_lpo128, this is alway available */ + retval = ClockDrv_GetLpo128kFreq(obj, &freq); + break; + case 3: + /* clk_lpo32 */ + retval = ClockDrv_GetLpo32kFreq(obj, &freq); + break; + case 4: + /* clk_lpo1 */ + retval = ClockDrv_GetLpo1kFreq(obj, &freq); + break; + case 5: + /* clk_rtc_cnt */ + retval = ClockDrv_GetRtcCntFreq(obj, &freq); + break; + case 6: + /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + case 7: + /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + default: + break; + } + } + + if(true == retval) + { + *frequency = freq / (Scg2Reg_GetClkOutDiv(obj->scg2Reg) + 1); + } + + return retval; +} + +static inline bool ClockDrv_SetClkOutClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + + /* Disable first before configure */ + Scg2Reg_SetClkOutEn(obj->scg2Reg, 0); + + switch(moduleClkConfig->source) + { + case CLOCKDRV_FLS: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 0); + break; + case CLOCKDRV_SOSC: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 1); + break; + case CLOCKDRV_SIRC: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 2); + break; + case CLOCKDRV_PLL: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 3); + break; + case CLOCKDRV_CORE: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 4); + break; + case CLOCKDRV_APB: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 5); + break; + case CLOCKDRV_SOSC_DIV: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 6); + break; + case CLOCKDRV_SIRC_DIV: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 0); /* scg_out must be selected to enable scg clock out */ + Scg2Reg_SetClkOutSrc0(obj->scg2Reg, 7); + break; + case CLOCKDRV_PLL_DIV: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 1); + break; + case CLOCKDRV_LPO_128K: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 2); + break; + case CLOCKDRV_LPO_32K: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 3); + break; + case CLOCKDRV_LPO_1K: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 4); + break; + case CLOCKDRV_RTC_CNT: + Scg2Reg_SetClkOutSrc1(obj->scg2Reg, 5); + break; + default: + retval = false; + break; + } + + if(retval) + { + if(moduleClkConfig->div >= 1 && moduleClkConfig->div <= 8) + { + Scg2Reg_SetClkOutDiv(obj->scg2Reg, moduleClkConfig->div - 1); + } + else + { + retval = false; + } + } + + /* Enable if required */ + Scg2Reg_SetClkOutEn(obj->scg2Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetRtcPadInFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + (void)obj; /* Unused, avoid warning */ + *frequency = obj->rtcClkInFreq; + return true; +} + +static inline bool ClockDrv_GetLpo1kFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc0Reg_GetLpo1Cken(obj->pcc0Reg)) + { + *frequency = LPO_1K_FREQUENCY; + return true; + } + return false; +} + +static inline bool ClockDrv_SetLpo1kClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetLpo1Cken(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetLpo32kFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc0Reg_GetLpo32Cken(obj->pcc0Reg)) + { + *frequency = LPO_32K_FREQUENCY; + return true; + } + return false; +} + +static inline bool ClockDrv_SetLpo32kClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetLpo32Cken(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetLpo128kFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + (void)obj; /* Unused, avoid warning */ + *frequency = LPO_128K_FREQUENCY; + return true; +} + +static inline bool ClockDrv_GetCmpFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + + /* Check if the cmp clock is enable */ + if(Pcc0Reg_GetCmpCkEn(obj->pcc0Reg) == 0) + { + return false; + } + + if(Pcc0Reg_GetCmpSrc(obj->pcc0Reg) == 0) + { /* clk_core */ + retval = ClockDrv_GetCoreFreq(obj, frequency); + } + else if(Pcc0Reg_GetCmpSrc(obj->pcc0Reg) == 1) + { /* clk_lptmr */ + retval = ClockDrv_GetLptmrFreq(obj, frequency); + } + + return retval; +} + +static inline bool ClockDrv_SetCmpClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + + /* Disable first before configure */ + Pcc0Reg_SetCmpCkEn(obj->pcc0Reg, 0); + + if(moduleClkConfig->source == CLOCKDRV_CORE) + { + Pcc0Reg_SetCmpSrc(obj->pcc0Reg, 0); + retval = true; + } + else if(moduleClkConfig->source == CLOCKDRV_LPTMR) + { + Pcc0Reg_SetCmpSrc(obj->pcc0Reg, 1); + retval = true; + } + + Pcc0Reg_SetCmpCkEn(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetPortAFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortACkEn(obj->pcc0Reg)) + { + retval = ClockDrv_GetApbFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortAClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetPortACkEn(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetPortBFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortBCkEn(obj->pcc0Reg)) + { + retval = ClockDrv_GetApbFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortBClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetPortBCkEn(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetPortCFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortCCkEn(obj->pcc0Reg)) + { + retval = ClockDrv_GetApbFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortCClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetPortCCkEn(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetPortDFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortDCkEn(obj->pcc0Reg)) + { + retval = ClockDrv_GetApbFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortDClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetPortDCkEn(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetPortEFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortECkEn(obj->pcc0Reg)) + { + retval = ClockDrv_GetApbFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortEClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc0Reg_SetPortECkEn(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetLptmrFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + uint32_t freq = 0; + /* Check if the lptmr clock is enable */ + if(Pcc0Reg_GetLptmrCken(obj->pcc0Reg) == 0) + { + return false; + } + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc0Reg_GetLptmrSrc(obj->pcc0Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, &freq); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, &freq); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, &freq); + break; + case 3: /* clk_lpo128 */ + retval = ClockDrv_GetLpo128kFreq(obj, &freq); + break; + case 4: /* clk_lpo1 */ + retval = ClockDrv_GetLpo1kFreq(obj, &freq); + break; + case 5: /* clk_lpo32 */ + retval = ClockDrv_GetLpo32kFreq(obj, &freq); + break; + case 6: /* RTC_CLKIN from PAD_PTA7 */ + retval = ClockDrv_GetRtcPadInFreq(obj, &freq); + break; + case 7: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, &freq); + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + if(retval) + { + uint32_t div = Pcc0Reg_GetLptmrDiv(obj->pcc0Reg) + 1; + *frequency = freq / div; + } + + return retval; +} + +static inline bool ClockDrv_SetLptmrClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + + /* Disable first before configure */ + Pcc0Reg_SetLptmrCken(obj->pcc0Reg, 0); + + switch(moduleClkConfig->source) + { + case CLOCKDRV_SIRC_DIV: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 0); + /* Actually 7 also works */ + break; + case CLOCKDRV_SOSC_DIV: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 1); + break; + case CLOCKDRV_PLL_DIV: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 2); + break; + case CLOCKDRV_LPO_128K: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 3); + break; + case CLOCKDRV_LPO_1K: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 4); + break; + case CLOCKDRV_LPO_32K: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 5); + break; + case CLOCKDRV_RTC_PADIN: + Pcc0Reg_SetLptmrSrc(obj->pcc0Reg, 6); + break; + default: + retval = false; + break; + } + + if(moduleClkConfig->div >= 1 && moduleClkConfig->div <= 8) + { + Pcc0Reg_SetLptmrDiv(obj->pcc0Reg, moduleClkConfig->div - 1); + } + else + { + retval = false; + } + + Pcc0Reg_SetLptmrCken(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetLpitFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + + /* Check if the lpit clock is enable */ + if(Pcc0Reg_GetLpitCken(obj->pcc0Reg) == 0) + { + return false; + } + + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc0Reg_GetLpitSrc(obj->pcc0Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 2: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 3: /* clk_lpo128 */ + *frequency = LPO_128K_FREQUENCY; + retval = true; + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetLpitClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + + /* Disable first before configure */ + Pcc0Reg_SetLpitCken(obj->pcc0Reg, 0); + + switch(moduleClkConfig->source) + { + case CLOCKDRV_SIRC_DIV: + Pcc0Reg_SetLpitSrc(obj->pcc0Reg, 0); + break; + case CLOCKDRV_PLL_DIV: + Pcc0Reg_SetLpitSrc(obj->pcc0Reg, 1); + break; + case CLOCKDRV_SOSC_DIV: + Pcc0Reg_SetLpitSrc(obj->pcc0Reg, 2); + break; + case CLOCKDRV_LPO_128K: + Pcc0Reg_SetLpitSrc(obj->pcc0Reg, 3); + break; + default: + retval = false; + break; + } + + Pcc0Reg_SetLpitCken(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetRtcCntFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + + /* Check if the rtc function clock is enable */ + if(Pcc0Reg_GetRtcCntCken(obj->pcc0Reg) == 0) + { + return false; + } + + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc0Reg_GetRtcCntSrc(obj->pcc0Reg)) + { + case 0: /* clk_lpo32 */ + retval = ClockDrv_GetLpo32kFreq(obj, frequency); + break; + case 1: /* PAD RTC_CLKIN */ + retval = ClockDrv_GetRtcPadInFreq(obj, frequency); + break; + case 2: /* lpo1 */ + retval = ClockDrv_GetLpo1kFreq(obj, frequency); + break; + case 3: /* lpo1 */ + retval = ClockDrv_GetLpo1kFreq(obj, frequency); + break; + default: + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetRtcCntClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + + /* Disable first before configure */ + Pcc0Reg_SetRtcCntCken(obj->pcc0Reg, 0); + + if(moduleClkConfig->source == CLOCKDRV_LPO_32K) + { + Pcc0Reg_SetRtcCntSrc(obj->pcc0Reg, 0); + retval = true; + } + else if(moduleClkConfig->source == CLOCKDRV_RTC_PADIN) + { + Pcc0Reg_SetRtcCntSrc(obj->pcc0Reg, 1); + retval = true; + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_1K) + { + Pcc0Reg_SetRtcCntSrc(obj->pcc0Reg, 2); + /* Actually 3 is also workable */ + retval = true; + } + + Pcc0Reg_SetRtcCntCken(obj->pcc0Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetPortAFltFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortAFltSrc(obj->pcc0Reg) == 0) + { /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, frequency); + } + else if(Pcc0Reg_GetPortAFltSrc(obj->pcc0Reg) == 1) + { /* clk_lpo128 */ + retval = ClockDrv_GetLpo128kFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortAFltClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + if(moduleClkConfig->source == CLOCKDRV_APB) + { /* clk_apb */ + Pcc0Reg_SetPortAFltSrc(obj->pcc0Reg, 0); + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_128K) + { /* clk_lpo128 */ + Pcc0Reg_SetPortAFltSrc(obj->pcc0Reg, 1); + } + return retval; +} + +static inline bool ClockDrv_GetPortBFltFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortBFltSrc(obj->pcc0Reg) == 0) + { /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, frequency); + } + else if(Pcc0Reg_GetPortBFltSrc(obj->pcc0Reg) == 1) + { /* clk_lpo128 */ + retval = ClockDrv_GetLpo128kFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortBFltClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + if(moduleClkConfig->source == CLOCKDRV_APB) + { /* clk_apb */ + Pcc0Reg_SetPortBFltSrc(obj->pcc0Reg, 0); + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_128K) + { /* clk_lpo128 */ + Pcc0Reg_SetPortBFltSrc(obj->pcc0Reg, 1); + } + return retval; +} + +static inline bool ClockDrv_GetPortCFltFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortCFltSrc(obj->pcc0Reg) == 0) + { /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, frequency); + } + else if(Pcc0Reg_GetPortCFltSrc(obj->pcc0Reg) == 1) + { /* clk_lpo128 */ + retval = ClockDrv_GetLpo128kFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortCFltClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + if(moduleClkConfig->source == CLOCKDRV_APB) + { /* clk_apb */ + Pcc0Reg_SetPortCFltSrc(obj->pcc0Reg, 0); + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_128K) + { /* clk_lpo128 */ + Pcc0Reg_SetPortCFltSrc(obj->pcc0Reg, 1); + } + return retval; +} + +static inline bool ClockDrv_GetPortDFltFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortDFltSrc(obj->pcc0Reg) == 0) + { /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, frequency); + } + else if(Pcc0Reg_GetPortDFltSrc(obj->pcc0Reg) == 1) + { /* clk_lpo128 */ + retval = ClockDrv_GetLpo128kFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortDFltClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + if(moduleClkConfig->source == CLOCKDRV_APB) + { /* clk_apb */ + Pcc0Reg_SetPortDFltSrc(obj->pcc0Reg, 0); + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_128K) + { /* clk_lpo128 */ + Pcc0Reg_SetPortDFltSrc(obj->pcc0Reg, 1); + } + return retval; +} + +static inline bool ClockDrv_GetPortEFltFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + if(Pcc0Reg_GetPortEFltSrc(obj->pcc0Reg) == 0) + { /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, frequency); + } + else if(Pcc0Reg_GetPortEFltSrc(obj->pcc0Reg) == 1) + { /* clk_lpo128 */ + retval = ClockDrv_GetLpo128kFreq(obj, frequency); + } + return retval; +} + +static inline bool ClockDrv_SetPortEFltClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + if(moduleClkConfig->source == CLOCKDRV_APB) + { /* clk_apb */ + Pcc0Reg_SetPortEFltSrc(obj->pcc0Reg, 0); + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_128K) + { /* clk_lpo128 */ + Pcc0Reg_SetPortEFltSrc(obj->pcc0Reg, 1); + } + return retval; +} + +static inline bool ClockDrv_GetExtFltFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = false; + + if(RcmReg_GetExtRstFltCk(obj->rcmReg) == 0) + { + /* clk_apb */ + retval = ClockDrv_GetApbFreq(obj, frequency); + } + else if(RcmReg_GetExtRstFltCk(obj->rcmReg) == 1) + { + /* clk_lpo128 */ + *frequency = LPO_128K_FREQUENCY; + retval = true; + } + + return retval; +} + +static inline bool ClockDrv_SetExtFltClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + + if(moduleClkConfig->source == CLOCKDRV_APB) + { + RcmReg_SetExtRstFltCk(obj->rcmReg, 0); + retval = true; + } + else if(moduleClkConfig->source == CLOCKDRV_LPO_128K) + { + RcmReg_SetExtRstFltCk(obj->rcmReg, 1); + retval = true; + } + + return retval; +} + +static inline bool ClockDrv_GetDmaFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetDmaCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetCoreFreq(obj, frequency); +} + +static inline bool ClockDrv_SetDmaClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetDmaCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetMscmFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetMscmCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetMscmClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetMscmCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetCrcFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetCrcCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetCrcClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetCrcCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetEimFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetEimCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetEimClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetEimCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetErmFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetErmCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetCoreFreq(obj, frequency); +} + +static inline bool ClockDrv_SetErmClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetErmCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetFhuFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetFhuCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetFhuClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetFhuCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetAdcFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetAdcCkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + uint32_t freq = 0; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetAdcSrc(obj->pcc1Reg)) + { + case 0: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + case 1: /* clk_sosc */ + retval = ClockDrv_GetSoscFreq(obj, &freq); + break; + case 2: /* clk_pll */ + retval = ClockDrv_GetPllFreq(obj, &freq); + break; + case 3: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + /* Divider */ + uint32_t div = (uint32_t)(1UL << Pcc1Reg_GetAdcDiv(obj->pcc1Reg)); + *frequency = freq / div; + + return retval; +} + +static inline bool ClockDrv_SetAdcClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetAdcCkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetAdcSrc(obj->pcc1Reg, select); + retval = true; + } + + /* Divider */ + if(true == retval) + { + uint8_t div = moduleClkConfig->div == 1 ? 0 : (moduleClkConfig->div == 2 ? 1 : (moduleClkConfig->div == 4 ? 2 : (moduleClkConfig->div == 8 ? 3 : 0xff))); + if(div != 0xff) + { + Pcc1Reg_SetAdcDiv(obj->pcc1Reg, div); + } + else + { + retval = false; + } + } + + /* Enable if required */ + Pcc1Reg_SetAdcCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetPdbFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetPdbCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetPdbClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetPdbCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetSpi0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetSpi0CkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetSpi0Src(obj->pcc1Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 3: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetSpi0Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetSpi0CkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC_DIV ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC_DIV ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL_DIV ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetSpi0Src(obj->pcc1Reg, select); + retval = true; + } + + Pcc1Reg_SetSpi0CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetSpi1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetSpi1CkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetSpi1Src(obj->pcc1Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 3: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetSpi1Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetSpi1CkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC_DIV ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC_DIV ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL_DIV ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetSpi1Src(obj->pcc1Reg, select); + retval = true; + } + + Pcc1Reg_SetSpi1CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetUart0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetUart0CkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetUart0Src(obj->pcc1Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 3: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetUart0Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetUart0CkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC_DIV ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC_DIV ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL_DIV ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetUart0Src(obj->pcc1Reg, select); + retval = true; + } + + Pcc1Reg_SetUart0CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetUart1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ +#if FEATURE_UART_INSTANCE_NUM == 3 + if(Pcc1Reg_GetUart1CkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetUart1Src(obj->pcc1Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 3: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +#else + /* UART1 is not available for M0116 */ + return false; +#endif +} + +static inline bool ClockDrv_SetUart1Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ +#if FEATURE_UART_INSTANCE_NUM == 3 + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetUart1CkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC_DIV ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC_DIV ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL_DIV ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetUart1Src(obj->pcc1Reg, select); + retval = true; + } + + Pcc1Reg_SetUart1CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +#else + /* UART1 is not available for M0116 */ + return false; +#endif +} + +static inline bool ClockDrv_GetUart2Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetUart2CkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetUart2Src(obj->pcc1Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 3: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetUart2Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetUart2CkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC_DIV ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC_DIV ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL_DIV ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetUart2Src(obj->pcc1Reg, select); + retval = true; + } + + Pcc1Reg_SetUart2CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetI2CFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetI2CCkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetI2CSrc(obj->pcc1Reg)) + { + case 0: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + case 1: /* clk_sosc_div */ + retval = ClockDrv_GetSoscDivFreq(obj, frequency); + break; + case 2: /* clk_pll_div */ + retval = ClockDrv_GetPllDivFreq(obj, frequency); + break; + case 3: /* clk_sirc_div */ + retval = ClockDrv_GetSircDivFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetI2CClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetI2CCkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC_DIV ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC_DIV ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL_DIV ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetI2CSrc(obj->pcc1Reg, select); + retval = true; + } + + Pcc1Reg_SetI2CCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetI2SMFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetI2SMCkEn(obj->pcc1Reg) == 0) + { + return false; + } + + bool retval = true; + uint32_t freq = 0; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetI2SMSrc(obj->pcc1Reg)) + { + case 0: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + case 1: /* clk_sosc */ + retval = ClockDrv_GetSoscFreq(obj, &freq); + break; + case 2: /* clk_pll */ + retval = ClockDrv_GetPllFreq(obj, &freq); + break; + case 3: /* clk_sirc */ + retval = ClockDrv_GetSircFreq(obj, &freq); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + /* Divider */ + uint32_t div = Pcc1Reg_GetI2SMDiv(obj->pcc1Reg) + 1; + if(div < 2) + { + div = 2; + } + *frequency = freq / div; + + return retval; +} + +static inline bool ClockDrv_SetI2SMClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = false; + /* Disable first before configure */ + Pcc1Reg_SetI2SMCkEn(obj->pcc1Reg, 0); + /* Select source */ + uint8_t select = moduleClkConfig->source == CLOCKDRV_SIRC ? 0 : (moduleClkConfig->source == CLOCKDRV_SOSC ? 1 : (moduleClkConfig->source == CLOCKDRV_PLL ? 2 : 0xff)); + if(select != 0xff) + { + Pcc1Reg_SetI2SMSrc(obj->pcc1Reg, select); + retval = true; + } + + /* Divider */ + if(true == retval) + { + if(moduleClkConfig->div >= 2 && moduleClkConfig->div <= 64) + { + Pcc1Reg_SetI2SMDiv(obj->pcc1Reg, moduleClkConfig->div - 1); + } + else + { + retval = false; + } + } + + /* Enable if required */ + Pcc1Reg_SetI2SMCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + + return retval; +} + +static inline bool ClockDrv_GetI2SSFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + /* Can not get the frequency of I2S slave */ + return false; +} + +static inline bool ClockDrv_SetI2SSClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetI2SSCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetPwmLite0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetPwm0CkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetPwmLite0Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetPwm0CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetPwmLite1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetPwm1CkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetApbFreq(obj, frequency); +} + +static inline bool ClockDrv_SetPwmLite1Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetPwm1CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetMft0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetMft0CkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetCoreFreq(obj, frequency); +} + +static inline bool ClockDrv_SetMft0Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetMft0CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetMft1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetMft1CkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetCoreFreq(obj, frequency); +} + +static inline bool ClockDrv_SetMft1Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetMft1CkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetCmusFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetCmusCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetSoscFreq(obj, frequency); +} + +static inline bool ClockDrv_SetCmusClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetCmusCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetCmupFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetCmupCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetPllFreq(obj, frequency); +} + +static inline bool ClockDrv_SetCmupClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetCmupCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +static inline bool ClockDrv_GetTclk0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + (void)obj; /* Unused, avoid warning */ + *frequency = obj->tclkFreq[0]; + return true; +} + +static inline bool ClockDrv_GetTclk1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + (void)obj; /* Unused, avoid warning */ + *frequency = obj->tclkFreq[1]; + return true; +} + +static inline bool ClockDrv_GetTclk2Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + (void)obj; /* Unused, avoid warning */ + *frequency = obj->tclkFreq[2]; + return true; +} + +static inline bool ClockDrv_GetExtMft0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetExtMft0Src(obj->pcc1Reg)) + { + case 0: /* TCLK0 */ + retval = ClockDrv_GetTclk0Freq(obj, frequency); + break; + case 1: /* TCLK1 */ + retval = ClockDrv_GetTclk1Freq(obj, frequency); + break; + case 2: /* TCLK2 */ + retval = ClockDrv_GetTclk2Freq(obj, frequency); + break; + case 3: /* clk_sirc_div_mft */ + retval = ClockDrv_GetSircDivMftFreq(obj, frequency); + break; + case 4: /* clk_sosc_div_mft */ + retval = ClockDrv_GetSoscDivMftFreq(obj, frequency); + break; + case 5: /* clk_pll_div_mft */ + retval = ClockDrv_GetPllDivMftFreq(obj, frequency); + break; + case 6: /* clk_sirc_div_mft */ + case 7: /* clk_sirc_div_mft */ + retval = ClockDrv_GetSircDivMftFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetExtMft0Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + + /* Select source */ + switch(moduleClkConfig->source) + { + case CLOCKDRV_TCLK0: /* TCLK0 */ + Pcc1Reg_SetExtMft0Src(obj->pcc1Reg, 0); + break; + case CLOCKDRV_TCLK1: /* TCLK1 */ + Pcc1Reg_SetExtMft0Src(obj->pcc1Reg, 1); + break; + case CLOCKDRV_TCLK2: /* TCLK2 */ + Pcc1Reg_SetExtMft0Src(obj->pcc1Reg, 2); + break; + case CLOCKDRV_SIRC_DIV_MFT: /* clk_sirc_div_mft */ + Pcc1Reg_SetExtMft0Src(obj->pcc1Reg, 3); + /* Actually it can also be 6 or 7 */ + break; + case CLOCKDRV_SOSC_DIV_MFT: /* clk_sosc_div_mft */ + Pcc1Reg_SetExtMft0Src(obj->pcc1Reg, 4); + break; + case CLOCKDRV_PLL_DIV_MFT: /* clk_pll_div_mft */ + Pcc1Reg_SetExtMft0Src(obj->pcc1Reg, 5); + break; + default: + retval = false; + break; + } + + return retval; +} + +static inline bool ClockDrv_GetExtMft1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetExtMft1Src(obj->pcc1Reg)) + { + case 0: /* TCLK0 */ + retval = ClockDrv_GetTclk0Freq(obj, frequency); + break; + case 1: /* TCLK1 */ + retval = ClockDrv_GetTclk1Freq(obj, frequency); + break; + case 2: /* TCLK2 */ + retval = ClockDrv_GetTclk2Freq(obj, frequency); + break; + case 3: /* clk_sirc_div_mft */ + retval = ClockDrv_GetSircDivMftFreq(obj, frequency); + break; + case 4: /* clk_sosc_div_mft */ + retval = ClockDrv_GetSoscDivMftFreq(obj, frequency); + break; + case 5: /* clk_pll_div_mft */ + retval = ClockDrv_GetPllDivMftFreq(obj, frequency); + break; + case 6: /* clk_sirc_div_mft */ + case 7: /* clk_sirc_div_mft */ + retval = ClockDrv_GetSircDivMftFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetExtMft1Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + /* Select source */ + switch(moduleClkConfig->source) + { + case CLOCKDRV_TCLK0: /* TCLK0 */ + Pcc1Reg_SetExtMft1Src(obj->pcc1Reg, 0); + break; + case CLOCKDRV_TCLK1: /* TCLK1 */ + Pcc1Reg_SetExtMft1Src(obj->pcc1Reg, 1); + break; + case CLOCKDRV_TCLK2: /* TCLK2 */ + Pcc1Reg_SetExtMft1Src(obj->pcc1Reg, 2); + break; + case CLOCKDRV_SIRC_DIV_MFT: /* clk_sirc_div_mft */ + Pcc1Reg_SetExtMft1Src(obj->pcc1Reg, 3); + /* Actually it can also be 6 or 7 */ + break; + case CLOCKDRV_SOSC_DIV_MFT: /* clk_sosc_div_mft */ + Pcc1Reg_SetExtMft1Src(obj->pcc1Reg, 4); + break; + case CLOCKDRV_PLL_DIV_MFT: /* clk_pll_div_mft */ + Pcc1Reg_SetExtMft1Src(obj->pcc1Reg, 5); + break; + default: + retval = false; + break; + } + + return retval; +} + +static inline bool ClockDrv_GetFixMft0Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetFixMft0Src(obj->pcc1Reg)) + { + case 0: /* clk_lpo32 */ + retval = ClockDrv_GetLpo32kFreq(obj, frequency); + break; + case 1: /* RTC_CLKIN */ + retval = ClockDrv_GetRtcPadInFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetFixMft0Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + + /* Select source */ + switch(moduleClkConfig->source) + { + case CLOCKDRV_LPO_32K: /* clk_lpo32 */ + Pcc1Reg_SetFixMft0Src(obj->pcc1Reg, 0); + break; + case CLOCKDRV_RTC_PADIN: /* RTC_CLKIN */ + Pcc1Reg_SetFixMft0Src(obj->pcc1Reg, 1); + break; + default: + retval = false; + break; + } + + return retval; +} + +static inline bool ClockDrv_GetFixMft1Freq(const ClockDrvType *obj, uint32_t *frequency) +{ + bool retval = true; + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + switch(Pcc1Reg_GetFixMft1Src(obj->pcc1Reg)) + { + case 0: /* clk_lpo32 */ + retval = ClockDrv_GetLpo32kFreq(obj, frequency); + break; + case 1: /* RTC_CLKIN */ + retval = ClockDrv_GetRtcPadInFreq(obj, frequency); + break; + default: + retval = false; + break; + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still keep default though it's not reachable" */ + + return retval; +} + +static inline bool ClockDrv_SetFixMft1Clock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + bool retval = true; + + /* Select source */ + switch(moduleClkConfig->source) + { + case CLOCKDRV_LPO_32K: /* clk_lpo32 */ + Pcc1Reg_SetFixMft1Src(obj->pcc1Reg, 0); + break; + case CLOCKDRV_RTC_PADIN: /* RTC_CLKIN */ + Pcc1Reg_SetFixMft1Src(obj->pcc1Reg, 1); + break; + default: + retval = false; + break; + } + + return retval; +} + +static inline bool ClockDrv_GetMpuFreq(const ClockDrvType *obj, uint32_t *frequency) +{ + if(Pcc1Reg_GetMpuCkEn(obj->pcc1Reg) == 0) + { + return false; + } + return ClockDrv_GetCoreFreq(obj, frequency); +} + +static inline bool ClockDrv_SetMpuClock(ClockDrvType *obj, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + Pcc1Reg_SetMpuCkEn(obj->pcc1Reg, moduleClkConfig->gating ? 1 : 0); + return true; +} + +void ClockDrv_Init(ClockDrvType *obj, + struct _RcmRegType_ *rcmReg, + struct _Pcc0RegType_ *pcc0Reg, + struct _Scg0RegType_ *scg0Reg, + struct _Scg1RegType_ *scg1Reg, + struct _Pcc1RegType_ *pcc1Reg, + struct _Scg2RegType_ *scg2Reg, + const ClockDrv_InitParamsType *initParams) +{ + obj->rcmReg = rcmReg; + obj->pcc0Reg = pcc0Reg; + obj->scg0Reg = scg0Reg; + obj->scg1Reg = scg1Reg; + obj->pcc1Reg = pcc1Reg; + obj->scg2Reg = scg2Reg; + obj->sircFreq = initParams->sircFreq; + obj->xtalClkFreq = initParams->xtalClkFreq; + obj->rtcClkInFreq = initParams->rtcClkInFreq; + uint8_t i = 0; + for(i = 0; i < TCLK_INPUTS_NUM; ++i) + { + obj->tclkFreq[i] = initParams->tclkFreq[i]; + } +} + +bool ClockDrv_GetFreq(const ClockDrvType *obj, ClockDrv_NamesType clockName, uint32_t *frequency) +{ + if(clockName >= CLOCKDRV_CLOCK_NUM) + { + return false; + } + + bool retval = false; + if(c_clockFuncTable[clockName].getFreqFunc != NULL) + { + retval = c_clockFuncTable[clockName].getFreqFunc(obj, frequency); + } + return retval; +} + +bool ClockDrv_ConfigureClock(ClockDrvType *obj, ClockDrv_NamesType clockName, const ClockDrv_ModuleClkConfigType *moduleClkConfig) +{ + if(clockName >= CLOCKDRV_CLOCK_NUM) + { + return false; + } + + bool retval = false; + if(c_clockFuncTable[clockName].setClockFunc != NULL) + { + Pcc0Reg_SetKey(obj->pcc0Reg, 0x55534552); /* Unlock PCC0, PCC1 */ + Scg0Reg_SetKey(obj->scg0Reg, 0x19962020); /* Unlock SCG0, SCG1, SCG2 */ + RcmReg_SetKey(obj->rcmReg, 0x52434D4B); /* Unlock RCM */ + retval = c_clockFuncTable[clockName].setClockFunc(obj, moduleClkConfig); + Pcc0Reg_SetKey(obj->pcc0Reg, 0); /* Lock PCC0, PCC1 again */ + Scg0Reg_SetKey(obj->scg0Reg, 0); /* Lock SCG0, SCG1, SCG2 again */ + RcmReg_SetKey(obj->rcmReg, 0); /* Lock RCM again */ + } + + return retval; +} diff --git a/cva_bootloader_m0118/src/private_driver/drivers/clock/clock_drv.h b/cva_bootloader_m0118/src/private_driver/drivers/clock/clock_drv.h new file mode 100644 index 0000000..4c1a0c0 --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/drivers/clock/clock_drv.h @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _CLOCK_DRV_H_ +#define _CLOCK_DRV_H_ + +/*! \brief Contains public interface to various functions related + * to the driver of Clock + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +/*! \addtogroup clock_drv + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/* TCLK clock number */ +#define TCLK_INPUTS_NUM (3U) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Definition of Clock names. + */ +typedef enum +{ + /* Source clocks */ + CLOCKDRV_SOSC = 0, /* system crystal oscillator clock*/ + CLOCKDRV_SIRC, /* slow internal reference clock */ + CLOCKDRV_PLL, /* PLL clock */ + CLOCKDRV_SOSC_DIV, /* SOSC_DIV clock */ + CLOCKDRV_SOSC_DIV_MFT, /* SOSC_DIV_MFT clock */ + CLOCKDRV_SIRC_DIV, /* SIRC_DIV clock */ + CLOCKDRV_SIRC_DIV_MFT, /* SIRC_DIV_MFT clock */ + CLOCKDRV_PLL_DIV, /* PLL_DIV clock */ + CLOCKDRV_PLL_DIV_MFT, /* PLL_DIV_MFT clock */ + CLOCKDRV_SYS, /* system clock */ + CLOCKDRV_CORE, /* core clock */ + CLOCKDRV_APB, /* bus clock */ + CLOCKDRV_FLS, /* flash clock */ + CLOCKDRV_CLKOUT, /* CLKOUT clock */ + CLOCKDRV_RTC_PADIN, /* RTC pad input clock */ + CLOCKDRV_LPO_1K, /* LPO 1KHz clock */ + CLOCKDRV_LPO_32K, /* LPO 32KHz clock */ + CLOCKDRV_LPO_128K, /* LPO 128KHz clock */ + /* Always-on clocks */ + CLOCKDRV_CMP, /* CMP clock */ + CLOCKDRV_PORTA, /* PORTA clock */ + CLOCKDRV_PORTB, /* PORTB clock */ + CLOCKDRV_PORTC, /* PORTC clock */ + CLOCKDRV_PORTD, /* PORTD clock */ + CLOCKDRV_PORTE, /* PORTE clock */ + CLOCKDRV_LPTMR, /* LPTMR clock */ + CLOCKDRV_LPIT, /* LPIT clock */ + CLOCKDRV_RTC_CNT, /* RTC module clock for counter */ + CLOCKDRV_PORTA_FLT, /* PORTA digital filter clock */ + CLOCKDRV_PORTB_FLT, /* PORTB digital filter clock */ + CLOCKDRV_PORTC_FLT, /* PORTC digital filter clock */ + CLOCKDRV_PORTD_FLT, /* PORTD digital filter clock */ + CLOCKDRV_PORTE_FLT, /* PORTE digital filter clock */ + CLOCKDRV_EXT_FLT, /* External Reset pin digital Filter clock */ + /* Peripheral clocks */ + CLOCKDRV_DMA, /* DMA clock */ + CLOCKDRV_MSCM, /* MSCM clock */ + CLOCKDRV_CRC, /* CRC clock */ + CLOCKDRV_EIM, /* EIM clock */ + CLOCKDRV_ERM, /* ERM clock */ + CLOCKDRV_FHU, /* FHU clock */ + + CLOCKDRV_ADC, /* ADC clock */ + CLOCKDRV_PDB, /* PDB clock */ + CLOCKDRV_SPI0, /* SPI0 clock */ +#if 0 + CLOCKDRV_SPI1, /* SPI1 clock */ + CLOCKDRV_UART0, /* UART0 clock */ + CLOCKDRV_UART1, /* UART1 clock */ + CLOCKDRV_UART2, /* UART2 clock */ + CLOCKDRV_I2C, /* I2C clock */ + CLOCKDRV_I2SM, /* I2S Mater clock */ + CLOCKDRV_I2SS, /* I2S Slave clock */ + CLOCKDRV_PWMLITE0, /* PWM_LITE0 clock */ + CLOCKDRV_PWMLITE1, /* PWM_LITE1 clock */ + CLOCKDRV_MFT0, /* MFT0 clock */ + CLOCKDRV_MFT1, /* MFT1 clock */ + CLOCKDRV_CMUS, /* CMUS clock */ + CLOCKDRV_CMUP, /* CMUP clock */ +#endif + CLOCKDRV_TCLK0, /* TCLK0 clock */ + CLOCKDRV_TCLK1, /* TCLK1 clock */ + CLOCKDRV_TCLK2, /* TCLK2 clock */ + CLOCKDRV_EXT_MFT0, /* EXT_MFT0 clock */ + CLOCKDRV_EXT_MFT1, /* EXT_MFT1 clock */ + CLOCKDRV_FIX_MFT0, /* FIX_MFT0 clock */ + CLOCKDRV_FIX_MFT1, /* FIX_MFT1 clock */ + CLOCKDRV_MPU, /* MPU clock */ + + CLOCKDRV_CLOCK_NUM +} ClockDrv_NamesType; + +/*! \brief module clock configuration. + */ +typedef struct _ClockDrv_ModuleClkConfigType_ +{ + bool gating; /*!< Clock gating. */ + ClockDrv_NamesType source; /*!< Clock source input (some modules don't have protocol clock) */ + uint16_t mult; /*!< Multiplier (some modules don't have fractional) */ + uint16_t div; /*!< Divider (some modules don't have divider) */ + + /* Only PLL clock has following configures */ + struct + { + uint32_t fblSel; /*!< feedback clock divider pre-scaler */ + uint32_t preDiv; /*!< pre-divider */ + uint32_t postDiv; /*!< post-divider */ + } pllConfig; /*!< PLL related config */ +} ClockDrv_ModuleClkConfigType; + +/*! \brief Initial parameters + */ +typedef struct _ClockDrv_InitParamsType_ +{ + uint32_t sircFreq; /*!< SIRC frequency */ + uint32_t xtalClkFreq; /*!< XTAL clock frequency. */ + uint32_t rtcClkInFreq; /*!< RTC_CLKIN clock frequency. */ + uint32_t tclkFreq[TCLK_INPUTS_NUM]; /*!< TCLKx clocks */ +} ClockDrv_InitParamsType; + +/* Forward declaration of related register */ +struct _RcmRegType_; +struct _Pcc0RegType_; +struct _Scg0RegType_; +struct _Scg1RegType_; +struct _Pcc1RegType_; +struct _Scg2RegType_; + +/*! \brief The definition of LPIT driver class + */ +typedef struct _ClockDrvType_ +{ + struct _RcmRegType_ *rcmReg; /*!< pointer to RCM register */ + struct _Pcc0RegType_ *pcc0Reg; /*!< pointer to PCC0 register */ + struct _Scg0RegType_ *scg0Reg; /*!< pointer to SCG0 register */ + struct _Scg1RegType_ *scg1Reg; /*!< pointer to SCG1 register */ + struct _Pcc1RegType_ *pcc1Reg; /*!< pointer to PCC1 register */ + struct _Scg2RegType_ *scg2Reg; /*!< pointer to SCG2 register */ + uint32_t sircFreq; /*!< SIRC frequency */ + uint32_t xtalClkFreq; /*!< XTAL clock frequency */ + uint32_t rtcClkInFreq; /*!< RTC_CLKIN clock frequency */ + uint32_t tclkFreq[TCLK_INPUTS_NUM]; /*!< TCLKx clocks */ +} ClockDrvType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the Clock driver module + * + * This function initializes Clock driver by setting the register + * instances to it. + * + * \param[in] obj : pointer to Clock driver instance + * \param[in] rcmReg : pointer to RCM register instance + * \param[in] pcc0Reg : pointer to PCC0 register instance + * \param[in] scg0Reg : pointer to SCG0 register instance + * \param[in] scg1Reg : pointer to SCG1 register instance + * \param[in] pcc1Reg : pointer to PCC1 register instance + * \param[in] scg2Reg : pointer to SCG2 register instance + * \param[in] initParams : pointer to clock initialization parameters + */ +extern void ClockDrv_Init(ClockDrvType *obj, + struct _RcmRegType_ *rcmReg, + struct _Pcc0RegType_ *pcc0Reg, + struct _Scg0RegType_ *scg0Reg, + struct _Scg1RegType_ *scg1Reg, + struct _Pcc1RegType_ *pcc1Reg, + struct _Scg2RegType_ *scg2Reg, + const ClockDrv_InitParamsType *initParams); + +/*! \brief Gets the clock frequency for a specific clock name. + * + * This function checks the current clock configurations and then calculates + * the clock frequency for a specific clock name defined in ClockDrv_NamesType. + * Clock modules must be properly configured before using this function. + * If it cannot find the clock name or the clock is not enabled or + * it's not configured properly, it returns false. + * + * \note If return false, don't trust the value of out parameter "frequency" + * even if it's changed. + * + * \param[in] obj : pointer to Clock driver instance + * \param[in] clockName : Clock names defined + * \param[out] frequency : clock frequency value in Hertz + * \return The result of the operation + * - false : Failed to get the frequency + * - true : Success + */ +extern bool ClockDrv_GetFreq(const ClockDrvType *obj, ClockDrv_NamesType clockName, uint32_t *frequency); + +/*! \brief Configures module clock + * + * This function configures a module clock according to the configuration. + * + * \note If the target clock do not have mul or div, the corresponding configuration in + * moduleClkConfig will be ignored. + * + * \param[in] obj : pointer to Clock driver instance + * \param[in] clockName : Clock name of the configured module clock + * \param[in] moduleClkConfig : Pointer to the configuration structure. + * \return The result of the operation + * - false : configure failed + * - true : success + */ +extern bool ClockDrv_ConfigureClock(ClockDrvType *obj, ClockDrv_NamesType clockName, const ClockDrv_ModuleClkConfigType *moduleClkConfig); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +/*! @}*/ + +#endif /* _CLOCK_DRV_H_ */ diff --git a/cva_bootloader_m0118/src/private_driver/isotp/isotp.c b/cva_bootloader_m0118/src/private_driver/isotp/isotp.c new file mode 100644 index 0000000..6d46efc --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/isotp/isotp.c @@ -0,0 +1,849 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "isotp.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/*! \brief Protocol Control Information (PCI) types, for identifying each frame of an ISO-TP message. + */ +#define ISOTP_PCI_TYPE_SINGLE_FRAME (0x0) +#define ISOTP_PCI_TYPE_FIRST_FRAME (0x1) +#define ISOTP_PCI_TYPE_CONSECUTIVE_FRAME (0x2) +#define ISOTP_PCI_TYPE_FLOW_CONTROL_FRAME (0x3) + +/*! \brief Protocol Control Information (PCI) flow control identifiers. + */ +#define ISOTP_PCI_FLOW_STATUS_CONTINUE (0x0) +#define ISOTP_PCI_FLOW_STATUS_WAIT (0x1) +#define ISOTP_PCI_FLOW_STATUS_OVERFLOW (0x2) + +/* invalid bs */ +#define ISOTP_INVALID_BS 0xFFFF + +/*! \brief Network layer result code + */ +#define ISOTP_PROTOCOL_RESULT_OK (0) +#define ISOTP_PROTOCOL_RESULT_TIMEOUT_A (-1) +#define ISOTP_PROTOCOL_RESULT_TIMEOUT_BS (-2) +#define ISOTP_PROTOCOL_RESULT_TIMEOUT_CR (-3) +#define ISOTP_PROTOCOL_RESULT_WRONG_SN (-4) +#define ISOTP_PROTOCOL_RESULT_INVALID_FS (-5) +#define ISOTP_PROTOCOL_RESULT_UNEXP_PDU (-6) +#define ISOTP_PROTOCOL_RESULT_WFT_OVRN (-7) +#define ISOTP_PROTOCOL_RESULT_BUFFER_OVFLW (-8) +#define ISOTP_PROTOCOL_RESULT_ERROR (-9) + +/*! \brief Return logic true if 'a' is after 'b' + */ +#define IsoTp_TimeAfter(a, b) ((int64_t)((int64_t)(b) - (int64_t)(a)) < 0) + +#define IsoTp_SetPciType(byte, type) (byte[0] = (0xFF & ((((uint8_t)type) << 4) | 0x0f))) +#define IsoTp_GetPciType(byte) ((uint8_t)(byte[0] >> 4)) + +/*! \brief single frame + * +-------------------------+-----+ + * | byte #0 | ... | + * +-------------------------+-----+ + * | nibble #0 | nibble #1 | ... | + * +-------------+-----------+ ... + + * | PCIType = 0 | SF_DL | ... | + * +-------------+-----------+-----+ + */ +#define IsoTp_SetSFDataLen(byte, len) (byte[0] &= (((uint8_t)len) | 0xf0)) +#define IsoTp_GetSFDataLen(byte) (byte[0] & 0x0f) + +/*! \brief first frame + * +-------------------------+-----------------------+-----+ + * | byte #0 | byte #1 | ... | + * +-------------------------+-----------+-----------+-----+ + * | nibble #0 | nibble #1 | nibble #2 | nibble #3 | ... | + * +-------------+-----------+-----------+-----------+-----+ + * | PCIType = 1 | FF_DL | ... | + * +-------------+-----------+-----------------------+-----+ + */ +#define IsoTp_SetFFDataLen(byte, len) \ + do \ + { \ + byte[0] &= ((len >> 8) | 0xf0); \ + byte[1] = (len & 0xff); \ + } while(0) +#define IsoTp_GetFFDataLen(byte) (((((uint16_t)byte[0]) & 0x0f) << 8) + byte[1]) + +/*! \brief consecutive frame + * +-------------------------+-----+ + * | byte #0 | ... | + * +-------------------------+-----+ + * | nibble #0 | nibble #1 | ... | + * +-------------+-----------+ ... + + * | PCIType = 2 | SN | ... | + * +-------------+-----------+-----+ + */ +#define IsoTp_SetCFSn(byte, sn) (byte[0] &= (((uint8_t)sn) | 0xf0)) +#define IsoTp_GetCFSn(byte) (byte[0] & 0x0f) + +/*! \brief flow control frame + * +-------------------------+-----------------------+-----------------------+-----+ + * | byte #0 | byte #1 | byte #2 | ... | + * +-------------------------+-----------+-----------+-----------+-----------+-----+ + * | nibble #0 | nibble #1 | nibble #2 | nibble #3 | nibble #4 | nibble #5 | ... | + * +-------------+-----------+-----------+-----------+-----------+-----------+-----+ + * | PCIType = 1 | FS | BS | STmin | ... | + * +-------------+-----------+-----------------------+-----------------------+-----+ + */ +#define IsoTp_SetFCFlowState(byte, fs) (byte[0] &= (((uint8_t)fs) | 0xf0)) +#define IsoTp_GetFCFlowState(byte) (byte[0] & 0x0f) +#define IsoTp_SetFCBlockSize(byte, bs) (byte[1] = bs) +#define IsoTp_GetFCBlockSize(byte) (byte[1]) +#define IsoTp_SetFCStmin(byte, STmin) (byte[2] = STmin) +#define IsoTp_GetFCStmin(byte) (byte[2]) + +#define TP_DUMMY 0xCC + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief ISOTP sender status + */ +typedef enum +{ + ISOTP_SEND_STATUS_IDLE, + ISOTP_SEND_STATUS_INPROGRESS, + ISOTP_SEND_STATUS_ERROR, +} IsoTp_SendStatusType; + +/*! \brief ISOTP receiver status + */ +typedef enum +{ + ISOTP_RECEIVE_STATUS_IDLE, + ISOTP_RECEIVE_STATUS_INPROGRESS, + ISOTP_RECEIVE_STATUS_FULL, +} IsoTp_ReceiveStatusType; + +/*! \brief ISOTP message + */ +typedef struct _IsoTp_MsgType_ +{ + uint8_t byte[8]; +} IsoTp_MsgType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +/* st_min to microsecond */ +static uint8_t IsoTp_MsToStMin(uint8_t ms) +{ + uint8_t stMin; + + stMin = ms; + if(stMin > 0x7F) + { + stMin = 0x7F; + } + + return stMin; +} + +/* st_min to msec */ +static uint8_t IsoTp_StMinToMs(uint8_t stMin) +{ + uint8_t ms; + + if(stMin >= 0xF1 && stMin <= 0xF9) + { + ms = 1; /* Actually it should be 0.1 - 0.9 ms */ + } + else if(stMin <= 0x7F) + { + ms = stMin; + } + else + { + ms = 0; + } + + return ms; +} + +static int8_t IsoTp_SendFlowControl(IsoTpType *obj, uint8_t flow_status, uint8_t block_size, uint8_t st_min_ms) +{ + int8_t ret; + uint8_t index = 0; + IsoTp_MsgType msg; + + /* Setup message */ + IsoTp_SetPciType(msg.byte, ISOTP_PCI_TYPE_FLOW_CONTROL_FRAME); + IsoTp_SetFCFlowState(msg.byte, flow_status); + IsoTp_SetFCBlockSize(msg.byte, block_size); + IsoTp_SetFCStmin(msg.byte, IsoTp_MsToStMin(st_min_ms)); + + /* Send message */ + if(obj->framePadding) + { + /* All pad with 0 */ + for(index = 3; index < 8; ++index) + { + msg.byte[index] = 0; + } + ret = obj->sendCanMsg(obj->sendArbitrationId, msg.byte, 8); + } + else + { + ret = obj->sendCanMsg(obj->sendArbitrationId, msg.byte, 3); + } + + return ret; +} + +static int8_t IsoTp_SendSingleFrame(IsoTpType *obj) +{ + int8_t ret; + uint8_t i = 0; + uint8_t index = 0; + IsoTp_MsgType msg; + + /* Setup message */ + IsoTp_SetPciType(msg.byte, ISOTP_PCI_TYPE_SINGLE_FRAME); + IsoTp_SetSFDataLen(msg.byte, (uint8_t)obj->sendSize); + for(index = 0; index < obj->sendSize; ++index) + { + msg.byte[index + 1] = obj->sendBuffer[index]; + } + + /* Send message */ + if(obj->framePadding) + { + /* All pad with 0 */ + for(i = 0; i < 7 - obj->sendSize; ++i) + { + msg.byte[i + obj->sendSize + 1] = TP_DUMMY; + } + + ret = obj->sendCanMsg(obj->sendArbitrationId, msg.byte, 8); + } + else + { + ret = obj->sendCanMsg(obj->sendArbitrationId, msg.byte, obj->sendSize + 1); + } + + return ret; +} + +static int8_t IsoTp_SendFirstFrame(IsoTpType *obj) +{ + int8_t ret; + IsoTp_MsgType msg; + + /* Setup message */ + IsoTp_SetPciType(msg.byte, ISOTP_PCI_TYPE_FIRST_FRAME); + IsoTp_SetFFDataLen(msg.byte, obj->sendSize); + uint8_t index = 0; + for(index = 0; index < 6; ++index) /* 6 data bytes for the first frame */ + { + msg.byte[index + 2] = obj->sendBuffer[index]; + } + + /* Send message */ + ret = obj->sendCanMsg(obj->sendArbitrationId, msg.byte, 8); + if(ISOTP_RET_OK == ret) + { + obj->sendOffset += 6; /* 6 data bytes for the first frame */ + obj->sendSN = 1; + } + + return ret; +} + +static int8_t IsoTp_SendConsecutiveFrame(IsoTpType *obj) +{ + int8_t ret; + IsoTp_MsgType msg; + uint16_t dataLength; + uint8_t index = 0; + + /* setup message */ + IsoTp_SetPciType(msg.byte, ISOTP_PCI_TYPE_CONSECUTIVE_FRAME); + IsoTp_SetCFSn(msg.byte, obj->sendSN); + dataLength = obj->sendSize - obj->sendOffset; + if(dataLength > 7) /* Max 7 data bytes for the consecutive frame */ + { + dataLength = 7; + } + for(index = 0; index < dataLength; ++index) + { + msg.byte[index + 1] = obj->sendBuffer[obj->sendOffset + index]; + } + + /* Send message */ + if(obj->framePadding) + { + /* All pad with 0 */ + uint8_t i = 0; + for(i = 0; i < 7 - dataLength; ++i) + { + msg.byte[i + 1 + dataLength] = TP_DUMMY; + } + ret = obj->sendCanMsg(obj->sendArbitrationId, msg.byte, 8); + } + else + { + ret = obj->sendCanMsg(obj->sendArbitrationId, msg.byte, dataLength + 1); + } + + if(ISOTP_RET_OK == ret) + { + obj->sendOffset += dataLength; + if(++(obj->sendSN) > 0x0F) + { + obj->sendSN = 0; + } + } + + return ret; +} + +static int8_t IsoTp_ReceiveSingleFrame(IsoTpType *obj, const IsoTp_MsgType *pMsg, uint8_t len) +{ + uint8_t index = 0; + + /* Check data length */ + if((0 == IsoTp_GetSFDataLen(pMsg->byte)) + || (IsoTp_GetSFDataLen(pMsg->byte) > (len - 1))) + { + if(obj->debug != NULL) + { + obj->debug("Single-frame length too small or too large."); + } + return ISOTP_RET_LENGTH; + } + + /* Copying data */ + /* polyspace-begin DEFECT:OUT_BOUND_ARRAY [No action planned:High] "Still keep default because one frame max length is 8" */ + obj->receiveSize = IsoTp_GetSFDataLen(pMsg->byte); + for(index = 0; index < obj->receiveSize; ++index) + { + obj->receiveBuffer[index] = pMsg->byte[index + 1]; + } + /* polyspace-end DEFECT:OUT_BOUND_ARRAY [No action planned:High] "Still keep default because one frame max length is 8" */ + + return ISOTP_RET_OK; +} + +static int8_t IsoTp_ReceiveFirstFrame(IsoTpType *obj, const IsoTp_MsgType *pMsg, uint8_t len) +{ + uint16_t payloadLength; + uint8_t index = 0; + + if(8 != len) + { + if(obj->debug != NULL) + { + obj->debug("First frame should be 8 bytes in length."); + } + return ISOTP_RET_LENGTH; + } + + /* Check data length */ + payloadLength = IsoTp_GetFFDataLen(pMsg->byte); + + /* Should not use multiple frame transmission */ + if(payloadLength <= 7) + { + if(obj->debug != NULL) + { + obj->debug("First frame should not use multiple frame transmission."); + } + return ISOTP_RET_LENGTH; + } + + if(payloadLength > obj->receiveBufferSize) + { + if(obj->debug != NULL) + { + obj->debug("Multi-frame response too large for receiving buffer."); + } + return ISOTP_RET_OVERFLOW; + } + + /* Copying data */ + obj->receiveSize = payloadLength; + for(index = 0; index < 6; ++index) /* 6 data bytes for the first frame */ + { + obj->receiveBuffer[index] = pMsg->byte[index + 2]; + } + obj->receiveOffset = 6; /* 6 data bytes for the first frame */ + obj->receiveSN = 1; + + return ISOTP_RET_OK; +} + +static int8_t IsoTp_ReceiveConsecutiveFrame(IsoTpType *obj, const IsoTp_MsgType *pMsg, uint8_t len) +{ + uint16_t remaining_bytes; + uint8_t index = 0; + + /* Check SN */ + if(obj->receiveSN != IsoTp_GetCFSn(pMsg->byte)) + { + return ISOTP_RET_WRONG_SN; + } + + /* Check data length */ + remaining_bytes = obj->receiveSize - obj->receiveOffset; + if(remaining_bytes > 7) /* Max 7 data bytes for the consecutive frame */ + { + remaining_bytes = 7; + } + if(remaining_bytes > len - 1) + { + if(obj->debug != NULL) + { + obj->debug("Consecutive frame too short."); + } + return ISOTP_RET_LENGTH; + } + + /* Copying data */ + for(index = 0; index < remaining_bytes; ++index) + { + obj->receiveBuffer[index + obj->receiveOffset] = pMsg->byte[index + 1]; + } + + obj->receiveOffset += remaining_bytes; + if(++(obj->receiveSN) > 0x0F) + { + obj->receiveSN = 0; + } + + return ISOTP_RET_OK; +} + +static int8_t IsoTp_ReceiveFlowControlFrame(IsoTpType *obj, const IsoTp_MsgType *pMsg, uint8_t len) +{ + /* Check message length */ + if(len < 3) + { + if(obj->debug != NULL) + { + obj->debug("Flow control frame too short."); + } + return ISOTP_RET_LENGTH; + } + + return ISOTP_RET_OK; +} + +int8_t IsoTp_Send(IsoTpType *obj, const uint8_t payload[], uint16_t size) +{ + return IsoTp_SendWithId(obj, obj->sendArbitrationId, payload, size); +} + +int8_t IsoTp_SendWithId(IsoTpType *obj, uint32_t id, const uint8_t payload[], uint16_t size) +{ + int8_t ret; + uint8_t i = 0; + + if(obj == NULL) + { + return ISOTP_RET_ERROR; + } + + if(size > obj->sendBufferSize) + { + if(obj->debug != NULL) + { + obj->debug("Message size too large. Set a larger send buffer\n"); + } + return ISOTP_RET_OVERFLOW; + } + + if(ISOTP_SEND_STATUS_INPROGRESS == obj->sendStatus) + { + if(obj->debug != NULL) + { + obj->debug("Abort previous message, transmission in progress.\n"); + } + return ISOTP_RET_INPROGRESS; + } + + /* Copy into local buffer */ + obj->sendSize = size; + obj->sendOffset = 0; + for(i = 0; i < size; ++i) + { + obj->sendBuffer[i] = payload[i]; + } + + if(obj->sendSize < 8) + { + /* Send single frame */ + ret = IsoTp_SendSingleFrame(obj); + } + else + { + /* Send multiple frames */ + ret = IsoTp_SendFirstFrame(obj); + + /* Initialize multi-frame control flags */ + if(ISOTP_RET_OK == ret) + { + obj->sendBsRemain = 0; + obj->sendSTMin = 0; + obj->sendWaitFrameCount = 0; + obj->sendTimerSeptime = obj->getTimeMs(); + /* Refresh BS timer */ + obj->sendTimerBlockSize = obj->getTimeMs() + ISOTP_DEFAULT_RESPONSE_TIMEOUT; + obj->sendProtocolResult = ISOTP_PROTOCOL_RESULT_OK; + obj->sendStatus = ISOTP_SEND_STATUS_INPROGRESS; + } + } + /* polyspace-end DEFECT:NULL_PTR [No action planned:High] "Still keep default because the null pointer is handled" */ + + return ret; +} + +void IsoTp_HandleIncomingCanMsg(IsoTpType *obj, uint32_t id, const uint8_t *data, uint8_t len) +{ + int8_t ret; + IsoTp_MsgType msg; + + if(len < 2 || len > 8) + { + return; + } + + uint8_t i = 0; + for(i = 0; i < len; ++i) + { + msg.byte[i] = data[i]; + } + for(i = 0; i < 8 - len; ++i) /* len will NOT > 8 */ + { + msg.byte[i + len] = 0; /* Padding */ + } + + switch(IsoTp_GetPciType(msg.byte)) + { + case ISOTP_PCI_TYPE_SINGLE_FRAME: + { + /* Update protocol result */ + if(ISOTP_RECEIVE_STATUS_INPROGRESS == obj->receiveStatus) + { + obj->receiveProtocolResult = ISOTP_PROTOCOL_RESULT_UNEXP_PDU; + } + else + { + obj->receiveProtocolResult = ISOTP_PROTOCOL_RESULT_OK; + } + + /* Handle message */ + ret = IsoTp_ReceiveSingleFrame(obj, &msg, len); + + if(ISOTP_RET_OK == ret) + { + obj->receiveArbitrationId = id; + /* Change status */ + obj->receiveStatus = ISOTP_RECEIVE_STATUS_FULL; + } + break; + } + case ISOTP_PCI_TYPE_FIRST_FRAME: + { + /* Update protocol result */ + if(ISOTP_RECEIVE_STATUS_INPROGRESS == obj->receiveStatus) + { + obj->receiveProtocolResult = ISOTP_PROTOCOL_RESULT_UNEXP_PDU; + } + else + { + obj->receiveProtocolResult = ISOTP_PROTOCOL_RESULT_OK; + } + + /* Handle message */ + ret = IsoTp_ReceiveFirstFrame(obj, &msg, len); + + /* If overflow happened */ + if(ISOTP_RET_OVERFLOW == ret) + { + /* Update protocol result */ + obj->receiveProtocolResult = ISOTP_PROTOCOL_RESULT_BUFFER_OVFLW; + /* Change status */ + obj->receiveStatus = ISOTP_RECEIVE_STATUS_IDLE; + /* Send error message */ + IsoTp_SendFlowControl(obj, ISOTP_PCI_FLOW_STATUS_OVERFLOW, 0, 0); + break; + } + + /* If receive successful */ + if(ISOTP_RET_OK == ret) + { + obj->receiveArbitrationId = id; + /* Change status */ + obj->receiveStatus = ISOTP_RECEIVE_STATUS_INPROGRESS; + /* Send FC frame */ + obj->receiveBlockSizeCount = obj->blockSize; + IsoTp_SendFlowControl(obj, ISOTP_PCI_FLOW_STATUS_CONTINUE, obj->receiveBlockSizeCount, ISOTP_DEFAULT_ST_MIN); + /* Refresh timer CR */ + obj->receiveTimerCr = obj->getTimeMs() + ISOTP_DEFAULT_RESPONSE_TIMEOUT; + } + + break; + } + case ISOTP_PCI_TYPE_CONSECUTIVE_FRAME: + { + /* Check if in receiving status */ + if(ISOTP_RECEIVE_STATUS_INPROGRESS != obj->receiveStatus) + { + obj->receiveProtocolResult = ISOTP_PROTOCOL_RESULT_UNEXP_PDU; + break; + } + + if(id != obj->receiveArbitrationId) + { + break; + } + + /* Handle message */ + ret = IsoTp_ReceiveConsecutiveFrame(obj, &msg, len); + + /* If wrong SN */ + if(ISOTP_RET_WRONG_SN == ret) + { + TxTestMsg(&msg.byte); + obj->receiveProtocolResult = ISOTP_PROTOCOL_RESULT_WRONG_SN; + obj->receiveStatus = ISOTP_RECEIVE_STATUS_IDLE; + break; + } + + /* If success */ + if(ISOTP_RET_OK == ret) + { + /* Refresh timer CR */ + obj->receiveTimerCr = obj->getTimeMs() + ISOTP_DEFAULT_RESPONSE_TIMEOUT; + + /* Receive finished */ + if(obj->receiveOffset >= obj->receiveSize) + { + obj->receiveStatus = ISOTP_RECEIVE_STATUS_FULL; + } + else + { + /* Send FC when BS reaches limit */ + if(obj->blockSize > 0) + { + if(0 == --obj->receiveBlockSizeCount) + { + obj->receiveBlockSizeCount = obj->blockSize; + IsoTp_SendFlowControl(obj, ISOTP_PCI_FLOW_STATUS_CONTINUE, obj->receiveBlockSizeCount, ISOTP_DEFAULT_ST_MIN); + } + } + } + } + + break; + } + case ISOTP_PCI_TYPE_FLOW_CONTROL_FRAME: + { + /* Handle fc frame only when sending in progress */ + if(ISOTP_SEND_STATUS_INPROGRESS != obj->sendStatus) + { + break; + } + + /* Handle message */ + ret = IsoTp_ReceiveFlowControlFrame(obj, &msg, len); + + if(ISOTP_RET_OK == ret) + { + /* Refresh BS timer */ + obj->sendTimerBlockSize = obj->getTimeMs() + ISOTP_DEFAULT_RESPONSE_TIMEOUT; + + /* Overflow */ + if(ISOTP_PCI_FLOW_STATUS_OVERFLOW == IsoTp_GetFCFlowState(msg.byte)) + { + obj->sendProtocolResult = ISOTP_PROTOCOL_RESULT_BUFFER_OVFLW; + obj->sendStatus = ISOTP_SEND_STATUS_ERROR; + } + + /* Wait */ + else if(ISOTP_PCI_FLOW_STATUS_WAIT == IsoTp_GetFCFlowState(msg.byte)) + { + obj->sendWaitFrameCount += 1; + /* Wait exceed allowed count */ + if(obj->sendWaitFrameCount > ISOTP_MAX_WFT_NUMBER) + { + obj->sendProtocolResult = ISOTP_PROTOCOL_RESULT_WFT_OVRN; + obj->sendStatus = ISOTP_SEND_STATUS_ERROR; + } + } + + /* Permit send */ + else if(ISOTP_PCI_FLOW_STATUS_CONTINUE == IsoTp_GetFCFlowState(msg.byte)) + { + if(0 == IsoTp_GetFCBlockSize(msg.byte)) + { + obj->sendBsRemain = ISOTP_INVALID_BS; + } + else + { + obj->sendBsRemain = IsoTp_GetFCBlockSize(msg.byte); + } + obj->sendSTMin = IsoTp_StMinToMs(IsoTp_GetFCStmin(msg.byte)); + obj->sendWaitFrameCount = 0; + } + } + break; + } + default: + break; + }; + + return; +} + +int8_t IsoTp_Receive(IsoTpType *link, bool *IsFuncAddr, uint8_t *payload, uint16_t payload_size, uint16_t *out_size) +{ + uint16_t copylen; + uint16_t i = 0; + + if(ISOTP_RECEIVE_STATUS_FULL != link->receiveStatus) + { + return ISOTP_RET_NO_DATA; + } + + *IsFuncAddr = (link->receiveArbitrationId == link->funcId) ? true : false; + + copylen = link->receiveSize; + if(copylen > payload_size) + { + copylen = payload_size; + } + + for(i = 0; i < copylen; ++i) + { + payload[i] = link->receiveBuffer[i]; + } + *out_size = copylen; + + link->receiveStatus = ISOTP_RECEIVE_STATUS_IDLE; + + return ISOTP_RET_OK; +} + +void IsoTp_Init(IsoTpType *obj, const IsoTp_Params *pParams) +{ + obj->framePadding = pParams->framePadding; + obj->blockSize = pParams->blockSize; + obj->physId = pParams->recvPhysId; + obj->funcId = pParams->recvFuncId; + obj->sendArbitrationId = pParams->sendid; + obj->sendBuffer = pParams->sendBuf; + obj->sendBufferSize = pParams->sendBufSize; + obj->sendSize = 0; + obj->sendOffset = 0; + obj->sendSN = 0; + obj->sendBsRemain = 0; + obj->sendSTMin = 0; + obj->sendWaitFrameCount = 0; + obj->sendTimerSeptime = 0; + obj->sendTimerBlockSize = 0; + obj->sendProtocolResult = 0; + obj->sendStatus = ISOTP_SEND_STATUS_IDLE; + obj->receiveBuffer = pParams->recvBuf; + obj->receiveBufferSize = pParams->recvBufSize; + obj->receiveSize = 0; + obj->receiveOffset = 0; + obj->receiveSN = 0; + obj->receiveBlockSizeCount = 0; + obj->receiveTimerCr = 0; + obj->receiveProtocolResult = ISOTP_PROTOCOL_RESULT_OK; + obj->receiveStatus = ISOTP_RECEIVE_STATUS_IDLE; + + obj->debug = pParams->debug; + obj->sendCanMsg = pParams->sendCanMsg; + obj->getTimeMs = pParams->getTimeMs; +} + +void IsoTp_Poll(IsoTpType *obj) +{ + int8_t ret; + + /* Only polling when operation in progress */ + if(ISOTP_SEND_STATUS_INPROGRESS == obj->sendStatus) + { + /* Continue send data */ + if((ISOTP_INVALID_BS == obj->sendBsRemain || obj->sendBsRemain > 0) /* send data if bs_remain is invalid or bs_remain large than zero */ + && (0 == obj->sendSTMin || (0 != obj->sendSTMin && IsoTp_TimeAfter(obj->getTimeMs(), obj->sendTimerSeptime)))) + { /* st_min is zero or go beyond interval time */ + ret = IsoTp_SendConsecutiveFrame(obj); + if(ISOTP_RET_OK == ret) + { + if(ISOTP_INVALID_BS != obj->sendBsRemain) + { + obj->sendBsRemain -= 1; + } + /* Refresh BS timer */ + obj->sendTimerBlockSize = obj->getTimeMs() + ISOTP_DEFAULT_RESPONSE_TIMEOUT; + obj->sendTimerSeptime = obj->getTimeMs() + obj->sendSTMin; + + /* Check if send finish */ + if(obj->sendOffset >= obj->sendSize) + { + obj->sendStatus = ISOTP_SEND_STATUS_IDLE; + } + } + else + { + obj->sendStatus = ISOTP_SEND_STATUS_ERROR; + } + } + + /* Check timeout */ + if(IsoTp_TimeAfter(obj->getTimeMs(), obj->sendTimerBlockSize)) + { + obj->sendProtocolResult = ISOTP_PROTOCOL_RESULT_TIMEOUT_BS; + obj->sendStatus = ISOTP_SEND_STATUS_ERROR; + } + } + + /* Only polling when operation in progress */ + if(ISOTP_RECEIVE_STATUS_INPROGRESS == obj->receiveStatus) + { + /* check timeout */ + if(IsoTp_TimeAfter(obj->getTimeMs(), obj->receiveTimerCr)) + { + obj->receiveProtocolResult = ISOTP_PROTOCOL_RESULT_TIMEOUT_CR; + obj->receiveStatus = ISOTP_RECEIVE_STATUS_IDLE; + } + } + + return; +} diff --git a/cva_bootloader_m0118/src/private_driver/isotp/isotp.h b/cva_bootloader_m0118/src/private_driver/isotp/isotp.h new file mode 100644 index 0000000..c485b89 --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/isotp/isotp.h @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _ISOTP_H_ +#define _ISOTP_H_ + +/*! \brief Contains public interface to various functions related + * to the ISO TP (ISO 15765-2) + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/*! \brief Defines all the return values + */ +#define ISOTP_RET_OK (0) +#define ISOTP_RET_ERROR (-1) +#define ISOTP_RET_INPROGRESS (-2) +#define ISOTP_RET_OVERFLOW (-3) +#define ISOTP_RET_WRONG_SN (-4) +#define ISOTP_RET_NO_DATA (-5) +#define ISOTP_RET_TIMEOUT (-6) +#define ISOTP_RET_LENGTH (-7) + +/*! \brief The default timeout to use when waiting for a response during a multi-frame send or receive. + */ +#define ISOTP_DEFAULT_RESPONSE_TIMEOUT (100) + +/*! \brief The STmin parameter value specifies the minimum time gap allowed between + * the transmission of consecutive frame network protocol data units + */ +#define ISOTP_DEFAULT_ST_MIN (1) + +/*! \brief This parameter indicate how many FC N_PDU WTs can be transmitted by the + * receiver in a row. + */ +#define ISOTP_MAX_WFT_NUMBER (1) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The declaration of the buffer used for both send and receive + */ +typedef uint8_t *IsoTp_Buffer; + +/*! \brief User implemented, print debug message + */ +typedef void (*IsoTp_DebugShim)(const char *message, ...); + +/*! \brief User implemented, send can message + */ +typedef int8_t (*IsoTp_SendCanMsgShim)(const uint32_t arbitrationId, const uint8_t *pData, const uint8_t size); + +/*! \brief User implemented, get millisecond + */ +typedef int64_t (*IsoTp_GetTimeShimMs)(void); + +/*! \brief Defines all the parameters used to initialize ISOTP object + */ +typedef struct _IsoTp_Params_ +{ + bool framePadding; + uint8_t blockSize; + uint32_t recvPhysId; + uint32_t recvFuncId; + uint32_t sendid; + uint8_t *sendBuf; + uint16_t sendBufSize; + uint8_t *recvBuf; + uint16_t recvBufSize; + IsoTp_DebugShim debug; + IsoTp_SendCanMsgShim sendCanMsg; + IsoTp_GetTimeShimMs getTimeMs; +} IsoTp_Params; + +/*! \brief Structure containing the data for linking an application to a CAN instance. + * The data stored in this structure is used internally and may be used by software programs + * using this library. + */ +typedef struct _IsoTpType_ +{ + bool framePadding; /*!< whether need frame padding */ + uint8_t blockSize; /*!< Max number of messages the receiver can receive at one time, this value is affected by CAN driver queue length */ + + uint32_t physId; /*!< physical addressing id */ + uint32_t funcId; /*!< functional addressing id */ + + uint32_t sendArbitrationId; /*! used to reply consecutive frame */ + IsoTp_Buffer sendBuffer; /*!< send buffer */ + uint16_t sendBufferSize; /*!< the size of send buffer */ + uint16_t sendSize; /*!< the size of data to send */ + uint16_t sendOffset; /*!< the offset of current send process */ + + uint8_t sendSN; /*!< serial number of send message */ + uint16_t sendBsRemain; /*!< Remaining block size */ + uint8_t sendSTMin; /*!< Separation Time between consecutive frames, unit millisecond */ + uint8_t sendWaitFrameCount; /*!< Maximum number of FC.Wait frame transmissions */ + int64_t sendTimerSeptime; /*!< Last time send consecutive frame */ + int64_t sendTimerBlockSize; /*!< Time until transmission of the next FlowControl N_PDU start at sending FF, CF, receive FC end at receive FC */ + int sendProtocolResult; /*!< the result of send protocol */ + uint8_t sendStatus; /*!< the send status */ + + uint32_t receiveArbitrationId; /*! used to determine whether physical or functional addressing */ + IsoTp_Buffer receiveBuffer; /*!< message receive buffer */ + uint16_t receiveBufferSize; /*!< the size of RX buffer */ + uint16_t receiveSize; /*!< the size to receive */ + uint16_t receiveOffset; /*!< the offset of receive process */ + + uint8_t receiveSN; /*!< serial number of receive message */ + uint8_t receiveBlockSizeCount; /*!< Maximum number of FC.Wait frame transmissions */ + int64_t receiveTimerCr; /*!< Time until reception of the next ConsecutiveFrame N_PDU start at sending FC, receive CF end at receive FC */ + int8_t receiveProtocolResult; /*!< the result of receive protocol */ + uint8_t receiveStatus; /*!< the receive status */ + + IsoTp_DebugShim debug; /*!< the adapter of debug function */ + IsoTp_SendCanMsgShim sendCanMsg; /*!< the adapter of can-send-message function */ + IsoTp_GetTimeShimMs getTimeMs; /*!< the adapter of get-time-stamp function */ + +} IsoTpType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the ISO-TP library. + * + * This function intiliaze the ISO-TP instance + * + * \param[in] obj : pointer to ISOTP instance + * \param[in] pParams : pointer to the initialization parameters + */ +extern void IsoTp_Init(IsoTpType *obj, const IsoTp_Params *pParams); + +/*! \brief Polling function + * + * Call this function periodically to handle timeouts, send consecutive frames, etc. + * + * \param[in] obj : pointer to ISOTP instance + */ +extern void IsoTp_Poll(IsoTpType *obj); + +/*! \brief Handles incoming CAN messages. + * + * Determines whether an incoming message is a valid ISO-TP frame or not and handles it accordingly. + * + * \param[in] obj : pointer to ISOTP instance + * \param[in] id : the incoming CAN frame ID + * \param[in] pData : pointer to data of incoming CAN frame + * \param[in] len : the length of data of incoming CAN frame + */ +extern void IsoTp_HandleIncomingCanMsg(IsoTpType *obj, uint32_t id, const uint8_t *pData, uint8_t len); + +/*! \brief Sends ISO-TP frames via CAN, using the ID set in the initializing function. + * + * Single-frame messages will be sent immediately when calling this function. + * Multi-frame messages will be sent consecutively when calling isotp_poll. + * + * \param[in] obj : pointer to ISOTP instance + * \param[in] pPayload : the incoming CAN frame ID + * \param[in] size : pointer to data of incoming CAN frame + */ +extern int8_t IsoTp_Send(IsoTpType *obj, const uint8_t pPayload[], uint16_t size); + +/*! \brief Send with message ID + * + * With the exception that this function is used only for functional addressing. + * + * \param[in] obj : pointer to ISOTP instance + * \param[in] id : the message ID to send + * \param[in] pPayload : pointer to data to send + * \param[in] size : the size of data to send + */ +extern int8_t IsoTp_SendWithId(IsoTpType *obj, uint32_t id, const uint8_t pPayload[], uint16_t size); + +/*! \brief Receives and parses the received data and copies the parsed data in to the internal buffer. + * + * This function receives and parses the received data and copies the parsed data in to the internal buffer. + * + * \param[in] obj : pointer to ISOTP instance + * \param[out] IsFuncAddr : pointer the result of whether is functional addressing + * \param[out] pPayload : pointer to the payload + * \param[in] payloadSize : the payload size + * \param[out] pOutSize : the size of actual output payload + */ +extern int8_t IsoTp_Receive(IsoTpType *obj, bool *IsFuncAddr, uint8_t *pPayload, uint16_t payloadSize, uint16_t *pOutSize); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _ISOTP_H_ */ diff --git a/cva_bootloader_m0118/src/private_driver/mcu.c b/cva_bootloader_m0118/src/private_driver/mcu.c new file mode 100644 index 0000000..a787cae --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/mcu.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "mcu.h" +#include "drivers/cpu/startup/system_M011x.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void Mcu_Init(McuType *obj) +{ + /* Initialize ADC driver */ + + /* Initialize clock driver */ + ClockDrv_InitParamsType clockInitParams; + clockInitParams.sircFreq = CPU_INT_SLOW_CLK_HZ; + clockInitParams.xtalClkFreq = CPU_XTAL_CLK_HZ; + clockInitParams.rtcClkInFreq = 0; + clockInitParams.tclkFreq[0] = 0; + clockInitParams.tclkFreq[1] = 0; + clockInitParams.tclkFreq[2] = 0; + ClockDrv_Init(&obj->clockDrv, RCM, PCC0, SCG0, SCG1, PCC1, SCG2, &clockInitParams); + + /* Initialize Flash driver */ + FlashDrv_Init(&obj->flashDrv, FTFC, SCG0); + + /* Initialize flexCAN driver */ + FlexCanDrv_InitHwParType initHwPar; + initHwPar.canRamNum = 2; + FlexCanDrv_Init(&obj->flexCanDrv, CAN, PCC1, PCC0, SCG0, SCG2, SIM, &initHwPar); + + /* Initialize PINS driver */ + PinsDrv_Init(&obj->pta, PORTA, GPIOA); + PinsDrv_Init(&obj->ptb, PORTB, GPIOB); + PinsDrv_Init(&obj->ptc, PORTC, GPIOC); + PinsDrv_Init(&obj->ptd, PORTD, GPIOD); + PinsDrv_Init(&obj->pte, PORTE, GPIOE); + + /* Initialize POWER driver */ + PowerDrv_Init(&obj->powerDrv, PMC, SCG2, SCG1, SCG0); + + /* Initialize reset driver */ + ResetDrv_Init(&obj->resetDrv, RCM, PCC1, PCC0); + + SpiDrv_Init(&obj->spiDrv0, SPI0); + + /* Initialize watchdog driver */ + WdgDrv_Init(&obj->wdgDrv, WDG); +} diff --git a/cva_bootloader_m0118/src/private_driver/mcu.h b/cva_bootloader_m0118/src/private_driver/mcu.h new file mode 100644 index 0000000..15bc180 --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/mcu.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _MCU_H_ +#define _MCU_H_ + +/*! \brief Contains public interface to various functions related + * to the MCAL (MCU Abstract Layer) module + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "CVM011x_features.h" +#include "clock_drv.h" +#include "drivers/adc/adc_drv.h" +#include "drivers/cmp/cmp_drv.h" +#include "drivers/cmu/cmu_drv.h" +#include "drivers/cpu/cpu_drv.h" +#include "drivers/crc/crc_drv.h" +#include "drivers/edma/edma_drv.h" +#include "drivers/eim/eim_drv.h" +#include "drivers/erm/erm_drv.h" +#include "drivers/fhu/fhu_drv.h" +#include "drivers/flash/flash_drv.h" +#include "drivers/flexcan/flexcan_drv.h" +#include "drivers/i2c/i2c_drv.h" +#include "drivers/i2sm/i2sm_drv.h" +#include "drivers/i2ss/i2ss_drv.h" +#include "drivers/lpit/lpit_drv.h" +#include "drivers/lptmr/lptmr_drv.h" +#include "drivers/mft/mft_drv.h" +#include "drivers/mpu/mpu_drv.h" +#include "drivers/pdb/pdb_drv.h" +#include "drivers/pins/pins_drv.h" +#include "drivers/power/power_drv.h" +#include "drivers/pwmlite/pwmlite_drv.h" +#include "drivers/reset/reset_drv.h" +#include "drivers/rtc/rtc_drv.h" +#include "drivers/spi/spi_drv.h" +#include "drivers/trgmux/trgmux_drv.h" +#include "drivers/uart/uart_drv.h" +#include "drivers/wdg/wdg_drv.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Definition of MCU prototype + */ +typedef struct _McuType_ +{ + AdcDrvType adcDrv; + ClockDrvType clockDrv; + CmpDrvType cmpDrv; + CmuDrvType cmuPllDrv; + CmuDrvType cmuSoscDrv; + CrcDrvType crcDrv; + EDmaDrvType edmaDrv; + EimDrvType eimDrv; + ErmDrvType ermDrv; + FhuDrvType fhuDrv; + FlashDrvType flashDrv; + FlexCanDrvType flexCanDrv; + I2cDrvType i2cDrv0; + I2smDrvType i2smDrv; + I2ssDrvType i2ssDrv; + LpitDrvType lpitDrv; + LptmrDrvType lptmrDrv; + MftDrvType mftDrv0; + MftDrvType mftDrv1; + MpuDrvType mpuDrv; + PdbDrvType pdbDrv; + PinsDrvType pta; + PinsDrvType ptb; + PinsDrvType ptc; + PinsDrvType ptd; + PinsDrvType pte; + PowerDrvType powerDrv; + PwmLiteDrvType pwmLiteDrv0; + PwmLiteDrvType pwmLiteDrv1; + ResetDrvType resetDrv; + RtcDrvType rtcDrv; + SpiDrvType spiDrv0; + SpiDrvType spiDrv1; + TrgMuxDrvType trgMuxDrv; + UartDrvType uartDrv0; +#if FEATURE_UART_INSTANCE_NUM == 3 + UartDrvType uartDrv1; +#endif + UartDrvType uartDrv2; + WdgDrvType wdgDrv; +} McuType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initializes the MCU + * + * This function initializes MCU by setting up all the peripheral drivers + * + * \param[in] obj : pointer to MCU instance + */ +extern void Mcu_Init(McuType *obj); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _MCU_H_ */ diff --git a/cva_bootloader_m0118/src/private_driver/uds/stack/stimer.h b/cva_bootloader_m0118/src/private_driver/uds/stack/stimer.h new file mode 100644 index 0000000..7542cea --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/uds/stack/stimer.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _STIMER_H_ +#define _STIMER_H_ + +/*! \brief Contains public interface to various functions related + * to the Software Timer (STIMER) object. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Declaration of STIMER object + */ +typedef struct _StimerType_ +{ + uint32_t counter; /*!< The counter register */ + uint32_t period; /*!< The period, time out will occur when count reach period */ + bool enable; /*!< Whether the timer is started */ + bool overflow; /*!< Whether the timer is overflow */ + +} StimerType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief The constructor of the timer object + * + * This function initialize the Stimer object + * + * \param[in] obj : pointer to Stimer instance + */ +static inline void Stimer_Init(StimerType *obj) +{ + obj->counter = 0; + obj->period = 0; + obj->enable = false; + obj->overflow = false; +} + +/*! \brief Start the timer for the period, this is one shot + * + * This function start the timer. This is one-shot. + * + * \note The real time is based on the time base running Ticker() + * \note Call this function if already started will restart the timer + * + * \param[in] obj : pointer to Stimer instance + * \param[in] period : the period value + */ +static inline void Stimer_Start(StimerType *obj, uint32_t period) +{ + obj->counter = 0; + obj->period = period; + obj->enable = true; + obj->overflow = false; +} + +/*! \brief The time base of the timer object + * + * This function provide the real time base of the stimer instance. + * + * \param[in] obj : pointer to Stimer instance + */ +static inline void Stimer_Tick(StimerType *obj) +{ + if(obj->enable && obj->overflow == false) + { + if(obj->counter < obj->period) + { + obj->counter++; + if(obj->counter == obj->period) + { + obj->overflow = true; + } + } + } +} + +/*! \brief Whether timeout + * + * This function returns whether it's timeout + * + * \param[in] obj : pointer to Stimer instance + * \return Whether it's timeout + * - true : the timer is time-out + * - false : the timer is not time-out + */ +static inline bool Stimer_Timeout(const StimerType *obj) +{ + return obj->overflow; +} + +/*! \brief Whether it's started + * + * This function returns whether the Timer instance is started + * + * \param[in] obj : pointer to Stimer instance + * \return Whether it's started + * - true : the timer is started + * - false : the timer is not started + */ +static inline bool Stimer_IsActive(StimerType *obj) +{ + return obj->enable; +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _STIMER_H_ */ diff --git a/cva_bootloader_m0118/src/private_driver/uds/stack/uds.c b/cva_bootloader_m0118/src/private_driver/uds/stack/uds.c new file mode 100644 index 0000000..20f9bc1 --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/uds/stack/uds.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds.h" + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define UDS_GET_SUB_FUNCTION_SUPPRESS_POSRSP(byte) (((byte) >> 7u)&0x01u) + + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + + +/******************************************************************************* + * the globals + ******************************************************************************/ + + +/******************************************************************************* + * the functions + ******************************************************************************/ + +static bool Uds_IsSidValid(UdsType *obj, uint8_t sid) +{ + uint16_t i=0; + for(i=0; iserviceNum; ++i) + { + if(obj->seviceTable[i].sid == sid) + { + return true; + } + } + return false; +} + + +void Uds_Init(UdsType *obj, const Uds_ParamsType *pParams) +{ + IsoTp_Init(&obj->isotp, &pParams->isotpParams); + + obj->session = 0x01; /* Default session */ + obj->securityLevel = 0; /* None security level */ + obj->suppressPosRsp = false; + obj->timeStamp_ms = 0; + obj->p2Server_ms = pParams->p2Server_ms; + obj->p2xServer_10ms = pParams->p2xServer_10ms; + obj->s3Server_ms = pParams->s3Server_ms; + + Stimer_Init(&obj->p2ServerTimer); + Stimer_Init(&obj->p2xServerTimer); + Stimer_Init(&obj->s3ServerTimer); + + uint32_t i=0; + for(i=0; ipayload[i] = 0; + } +} + + +void Uds_Run(UdsType *obj) +{ + uint16_t outSize = 0; + int8_t result = 0; + uint8_t sid = 0; + uint32_t i=0; + + IsoTp_Poll(&obj->isotp); + + result = IsoTp_Receive(&obj->isotp, &obj->isFuncAddr, obj->payload, UDS_MAX_PAYLOAD_SIZE, &outSize); + if (ISOTP_RET_OK == result) + { + /* Handle received message */ + sid = obj->payload[0]; + if(Uds_IsSidValid(obj, sid)) + { + for(i=0; iserviceNum; ++i) + { + if(obj->seviceTable[i].sid == sid) + { + if(obj->seviceTable[i].subFuncOwner) + { + obj->suppressPosRsp = UDS_GET_SUB_FUNCTION_SUPPRESS_POSRSP(obj->payload[1]); + } + else + { + obj->suppressPosRsp = 0; + } + + obj->curServiceIdx = i; + + obj->seviceTable[i].service(obj, obj->payload, outSize); + break; + } + } + } + else + { + Uds_NegativeResponse(obj, sid, NRC_SERVICE_NOT_SUPPORTED); + } + } + + if(true == Stimer_Timeout(&obj->s3ServerTimer)) + { + obj->session = 0x01; /* Default session */ + obj->securityLevel = 0; /* None security level */ + + Stimer_Init(&obj->s3ServerTimer); + } +} diff --git a/cva_bootloader_m0118/src/private_driver/uds/stack/uds.h b/cva_bootloader_m0118/src/private_driver/uds/stack/uds.h new file mode 100644 index 0000000..1c9c286 --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/uds/stack/uds.h @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_H_ +#define _UDS_H_ + +/*! \brief Contains public interface to various functions related + * to the Unified Diagnostic Services (UDS) following ISO 14229 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include +#include +#include "stimer.h" +#include "isotp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define NRC_GENERAL_REJECT (0x10) +#define NRC_SERVICE_NOT_SUPPORTED (0x11) +#define NRC_SUBFUNCTION_NOT_SUPPORTED (0x12) +#define NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT (0x13) +#define NRC_RESPONSE_TOO_LONG (0x14) +#define NRC_CONDITIONS_NOT_CORRECT (0x22) +#define NRC_REQUEST_SEQUENCE_ERROR (0x24) +#define NRC_REQUEST_OUT_OF_RANGE (0x31) +#define NRC_SECURITY_ACCESS_DENIED (0x33) +#define NRC_INVALID_KEY (0x35) +#define NRC_EXCEEDED_NUMBER_OF_ATTEMPTS (0x36) +#define NRC_REQUIRED_TIME_DELAY_NOT_EXPIRED (0x37) +#define NRC_UPLOAD_DOWNNLOAD_NOT_ACCEPTED (0x70) +#define NRC_TRANSFER_DATA_SUSPENDED (0x71) +#define NRC_GENERAL_PROGRAMMING_FAILURE (0x72) +#define NRC_WRONG_BLOCK_SEQUENCE_COUNTER (0x73) +#define NRC_SERVICE_BUSY (0x78) +#define NRC_SUBFUNC_NOT_SUPPORTED_IN_ACTIVE_SESSION (0x7E) +#define NRC_SERVICE_NOT_SUPPORTED_IN_ACTIVE_SESSION (0x7F) + +#define POSITIVE_RSP (0x40) +#define NEGATIVE_RSP (0x7F) +#define UDS_GET_POSITIVE_RSP(sid) (POSITIVE_RSP + sid) + +#define UDS_MAX_PAYLOAD_SIZE (2050) + +#define UDS_SA_NONE (0) +#define UDS_SA_LEVEL_1 (0x01) +#define UDS_SA_LEVEL_3 (0x03) +#define UDS_SA_LEVEL_09 (0x09) +#define UDS_SA_LEVEL_63 (0x63) + +#define UDS_SESSION_DEFAULT (0x01) +#define UDS_SESSION_PROGRAMMING (0x02) +#define UDS_SESSION_EXTENDED (0x03) +#define UDS_SESSION_SAFTY (0x04) +#define UDS_SESSION_SUPPLIER (0x60) + +#define UDS_SERVICE_NUM (15) +#define UDS_SA_LEVEL_NUM (3) + +#define UDS_GET_SUB_FUNCTION(byte) ((byte)&0x7fu) + +#define BYTES_OF(x) (sizeof(x) / sizeof(uint8_t)) + +#define UDS_RSP_LEN_MAX (512) + +/* DID type */ +#define UDS_VAR_TYPE_NONVOL_STORAGE (1 << 0) /* set if non-volatile data */ +#define UDS_VAR_TYPE_MAY_READ (1 << 1) /* set if readable */ +#define UDS_VAR_TYPE_MAY_WRITE (1 << 2) /* set if writable */ +#define UDS_DID_TYPE_RAM_RW (UDS_VAR_TYPE_MAY_READ | UDS_VAR_TYPE_MAY_WRITE) +#define UDS_DID_TYPE_NVM_RW (UDS_VAR_TYPE_NONVOL_STORAGE | UDS_VAR_TYPE_MAY_READ | UDS_VAR_TYPE_MAY_WRITE) +#define UDS_DID_TYPE_NVM_WO (UDS_VAR_TYPE_NONVOL_STORAGE | UDS_VAR_TYPE_MAY_WRITE) +#define UDS_DID_TYPE_NVM_RO (UDS_VAR_TYPE_NONVOL_STORAGE | UDS_VAR_TYPE_MAY_READ) + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief Forward declaration of UDS object + */ +struct _UdsType_; +typedef struct _UdsType_ UdsType; + + +/*! \brief The Data-by-ID definition of UDS + */ +typedef struct _Uds_DidType_ +{ + uint16_t did; + uint8_t type; + uint8_t sessionLevel; + uint8_t securityLevel; + uint8_t *pBytes; + uint16_t length; + void (*function)(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen); +} Uds_DidType; + +/*! \brief The definition of UDS DID table + */ +typedef Uds_DidType *Uds_DidTable; + + +/*! \brief UDS service definition + */ +typedef struct _Uds_ServiceType_ +{ + uint8_t sid; + uint8_t minLen; + bool subFuncOwner; + void (*service)(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); +} Uds_ServiceType; + +/*! \brief The definition of UDS service table + */ +typedef const Uds_ServiceType *Uds_ServiceTable; + +/*! \brief The definition of UDS security table + * \note The table should be like table[SID number][security level number] + */ +typedef const bool *Uds_SecurityTableType; + +/*! \brief The definition of UDS initialization parameters + */ +typedef struct _Uds_ParamsType_ +{ + IsoTp_Params isotpParams; + uint16_t p2Server_ms; + uint16_t p2xServer_10ms; + uint16_t s3Server_ms; +} Uds_ParamsType; + +/*! \brief The UDS prototype definition + */ +struct _UdsType_ +{ + bool active; + uint8_t session; + uint8_t securityLevel; + uint32_t serviceNum; + Uds_ServiceTable seviceTable; + Uds_SecurityTableType securityTable; + Uds_DidTable didTable; + uint16_t didNum; + + IsoTpType isotp; + bool suppressPosRsp; + bool isFuncAddr; + uint8_t curServiceIdx; + uint8_t payload[UDS_MAX_PAYLOAD_SIZE]; + + int64_t timeStamp_ms; + + uint16_t p2Server_ms; + uint16_t p2xServer_10ms; + uint16_t s3Server_ms; + + StimerType p2ServerTimer; + StimerType p2xServerTimer; + StimerType s3ServerTimer; +}; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ +extern void TxTestMsg (uint8_t * data); +/*! \brief Initializes the UDS object. + */ +extern void Uds_Init(UdsType *obj, const Uds_ParamsType *pParams); + +/*! \brief The main service of UDS object. + * \note Suggest run every 1ms + */ +extern void Uds_Run(UdsType *obj); + +/*! \brief This function gives a positive response + */ +static inline void Uds_PositiveResponse(UdsType *obj, const uint8_t data[], uint16_t len) +{ + Stimer_Start(&obj->s3ServerTimer, obj->s3Server_ms); + if(obj->suppressPosRsp == true) + { + return; + } + IsoTp_Send(&obj->isotp, data, len); + return; +} + +/*! \brief This function gives a nagative response + */ +static inline void Uds_NegativeResponse(UdsType *obj, uint8_t sid, uint8_t rsp_nrc) +{ + uint8_t temp_buf[8] = {0}; + + if(rsp_nrc != NRC_SERVICE_BUSY) + { + Stimer_Start(&obj->s3ServerTimer, obj->s3Server_ms); + } + + if(obj->isFuncAddr && (rsp_nrc == NRC_SERVICE_NOT_SUPPORTED || rsp_nrc == NRC_SUBFUNCTION_NOT_SUPPORTED || rsp_nrc == NRC_REQUEST_OUT_OF_RANGE || rsp_nrc == NRC_SUBFUNC_NOT_SUPPORTED_IN_ACTIVE_SESSION || rsp_nrc == NRC_SERVICE_NOT_SUPPORTED_IN_ACTIVE_SESSION)) + { + return; + } + + temp_buf[0] = NEGATIVE_RSP; + temp_buf[1] = sid; + temp_buf[2] = rsp_nrc; + IsoTp_Send(&obj->isotp, temp_buf, 3); +} + +/*! \brief This function provide the time base for the UDS process + */ +static inline void Uds_Tick(UdsType *obj) +{ + obj->timeStamp_ms++; + + Stimer_Tick(&obj->p2ServerTimer); + Stimer_Tick(&obj->p2xServerTimer); + Stimer_Tick(&obj->s3ServerTimer); +} + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_H_ */ diff --git a/cva_bootloader_m0118/src/private_driver/uds/user/uds_service10.c b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service10.c new file mode 100644 index 0000000..d7ee123 --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service10.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_service10.h" +#include "uds_service31.h" +#include "bootloader.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void UdsService10_SessionControl(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint8_t subFunction; + uint8_t rspBuffer[8] = {0}; /* polyspace DEFECT:PARTIALLY_ACCESSED_ARRAY [No action planned:Low] "Still keep default though member6~7 is not written" */ + + if(msgLen != obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x10, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + subFunction = UDS_GET_SUB_FUNCTION (msgBuf[1]); + + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x10); + rspBuffer[1] = subFunction; + rspBuffer[2] = (uint8_t)(obj->p2Server_ms >> 8); + rspBuffer[3] = (uint8_t)(obj->p2Server_ms & 0x00ff); + rspBuffer[4] = (uint8_t)(obj->p2xServer_10ms >> 8); + rspBuffer[5] = (uint8_t)(obj->p2xServer_10ms & 0x00ff); + Routine_StatusInit(); + switch(subFunction) + { + case UDS_SESSION_DEFAULT: + obj->securityLevel = UDS_SA_NONE; + obj->session = subFunction; + Uds_PositiveResponse(obj, rspBuffer, 6); + break; + case UDS_SESSION_EXTENDED: + obj->securityLevel = UDS_SA_NONE; + obj->session = subFunction; + Uds_PositiveResponse(obj, rspBuffer, 6); + Stimer_Start(&obj->s3ServerTimer, obj->s3Server_ms); + break; + case UDS_SESSION_PROGRAMMING: + obj->securityLevel = UDS_SA_NONE; + obj->session = subFunction; + Uds_PositiveResponse(obj, rspBuffer, 6); + Stimer_Start(&obj->s3ServerTimer, obj->s3Server_ms); + + Bootloader_EventEmergeBootRequest(true); + break; + case UDS_SESSION_SAFTY: + obj->securityLevel = UDS_SA_NONE; + obj->session = subFunction; + Uds_PositiveResponse(obj, rspBuffer, 6); + Stimer_Start(&obj->s3ServerTimer, obj->s3Server_ms); + break; + default: + Uds_NegativeResponse(obj, 0x10, NRC_SUBFUNCTION_NOT_SUPPORTED); + break; + } +} + diff --git a/cva_bootloader_m0118/src/private_driver/uds/user/uds_service10.h b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service10.h new file mode 100644 index 0000000..995a8d9 --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service10.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE10_H_ +#define _UDS_SERVICE10_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 10 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 10 processing + */ +extern void UdsService10_SessionControl(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE10_H_ */ diff --git a/cva_bootloader_m0118/src/private_driver/uds/user/uds_service11.c b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service11.c new file mode 100644 index 0000000..5d02af3 --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service11.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_service11.h" +#include "bootloader.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + + + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void UdsService11_ResetEcu(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint8_t subFunction; + uint8_t rspBuffer[8] = {0}; /* polyspace DEFECT:PARTIALLY_ACCESSED_ARRAY [No action planned:Low] "Still keep default though member3~7 is not written" */ + uint8_t powerDownTime = 0xFF; + + if(msgLen != obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x11, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + subFunction = UDS_GET_SUB_FUNCTION(msgBuf[1]); + + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x11); + rspBuffer[1] = subFunction; + rspBuffer[2] = powerDownTime; + switch(subFunction) + { + case UDS_RESET_HARD: + Uds_PositiveResponse(obj, rspBuffer, 2); + /*add hardware reset code*/ + Bootloader_EventResetRequest(true,UDS_RESET_HARD); + break; + case UDS_RESET_KEYOFFON: + Uds_PositiveResponse(obj, rspBuffer, 2); + /*add keyoffon reset code*/ + Bootloader_EventResetRequest(true,UDS_RESET_KEYOFFON); + break; + case UDS_RESET_SOFT: + Uds_PositiveResponse(obj, rspBuffer, 2); + /*add software reset code*/ + Bootloader_EventResetRequest(true,UDS_RESET_SOFT); + break; + default: + Uds_NegativeResponse(obj, 0x11, NRC_SUBFUNCTION_NOT_SUPPORTED); + break; + } +} diff --git a/cva_bootloader_m0118/src/private_driver/uds/user/uds_service11.h b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service11.h new file mode 100644 index 0000000..5927d3a --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service11.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE11_H_ +#define _UDS_SERVICE11_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 11 + */ +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ +/*! \brief The Reset type definition of Uds + */ +typedef enum _UdsResetType_ +{ + UDS_RESET_NONE = 0, + UDS_RESET_HARD, + UDS_RESET_KEYOFFON, + UDS_RESET_SOFT +} UdsResetType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 11 processing + */ +extern void UdsService11_ResetEcu(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE11_H_ */ diff --git a/cva_bootloader_m0118/src/private_driver/uds/user/uds_service27.c b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service27.c new file mode 100644 index 0000000..5b70ed2 --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service27.c @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include "uds_service27.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ + +#define SUPPORT_LEVEL_NUM 2 /* supported security level number */ + +#define MAX_ALLOW_ERROR_NUM 5 /* the max allow number of key error */ + +#define STARTUP_DELAY_MS 2000 /* the service allow access time delay after UDS start */ +#define ERR_EXCEED_DELAY_MS 10000 /* the service allow access time delay after error number exceed */ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +typedef struct _SecurityLevel_Param_ +{ + uint8_t level; + uint8_t keyErrorCnt; + uint8_t maxErrNum; + int64_t MaxErrTimeStamp; +} SecurityLevel_Param; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +SecurityLevel_Param scrtParam[SUPPORT_LEVEL_NUM] = { + {UDS_SA_LEVEL_1, 0, MAX_ALLOW_ERROR_NUM, 0}, + //{UDS_SA_LEVEL_3, 0, MAX_ALLOW_ERROR_NUM, 0}, + {UDS_SA_LEVEL_09, 0, MAX_ALLOW_ERROR_NUM, 0}, + //{UDS_SA_LEVEL_63, 0, MAX_ALLOW_ERROR_NUM, 0}, +}; + +extern uint32_t gSystick1msEvent; +/******************************************************************************* + * the constants + ******************************************************************************/ +static const uint8_t DMxorArray[4] = {0x4D,0x53,0x57,0x51}; + + +/******************************************************************************* + * the functions + ******************************************************************************/ + +static void UdsSecurityAccess_GenerateSeed(UdsType *obj, uint8_t newLevel, uint8_t *outData, uint8_t outBufsize, uint16_t *outLen) +{ + /* seed is defined by user, It's usually a random value */ + uint8_t seed[4] = {1, 2, 3, 4}; + uint32_t timeseed = (uint32_t)(obj->timeStamp_ms); + seed[0] = (uint8_t)(timeseed & 0xFF); + seed[1] = (uint8_t)((timeseed>>8) & 0xFF); + seed[2] = (uint8_t)((timeseed>>16) & 0xFF)+(seed[1]*7); + seed[3] = (uint8_t)((timeseed>>24) & 0xFF)+(seed[0]*3); + + if(outBufsize < sizeof(seed)) + { + return; + } + + *outLen = sizeof(seed); + if(newLevel == obj->securityLevel) + { + memset(outData, 0, sizeof(seed)); + } + else + { + memcpy(outData, seed, sizeof(seed)); + } +} + +static bool UdsSecurityAccess_ValidateKey(uint8_t seedLevel, const uint8_t *seed, uint16_t seedLen, const uint8_t *key, uint16_t keyLen) +{ + /* The encryption algorithm is provided by the vehicle manufacturer */ + uint8_t cal[4],calc_key[8]; + switch (seedLevel) + { + case UDS_SA_LEVEL_1: + cal[0] = seed[0]^DMxorArray[0]; + cal[1] = seed[1]^DMxorArray[1]; + cal[2] = seed[2]^DMxorArray[2]; + cal[3] = seed[3]^DMxorArray[3]; + + calc_key[0] = ((cal[2]&0xF0)<<4)|(cal[3]&0xF0); + calc_key[1] = ((cal[3]&0x2F)<<2)|(cal[1]&0x03); + calc_key[2] = ((cal[1]&0xFC)>>2)|(cal[0]&0xC0); + calc_key[3] = ((cal[0]&0x0F)<<4)|(cal[2]&0x0F); + if (calc_key[0]!=key[0] || calc_key[1]!=key[1] || calc_key[2]!=key[2] || calc_key[3]!=key[3]) + { + //TxTestMsg(calc_key); + return false; + } + return true; + case UDS_SA_LEVEL_09: + cal[0] = seed[0]^DMxorArray[0]; + cal[1] = seed[1]^DMxorArray[1]; + cal[2] = seed[2]^DMxorArray[2]; + cal[3] = seed[3]^DMxorArray[3]; + + calc_key[0] = ((cal[1]&0x7F)<<2)|(cal[2]&0xF0); + calc_key[1] = ((cal[0]&0xEC)>>2)|(cal[1]&0x7E); + calc_key[2] = ((cal[3]&0xF0)>>4)|(cal[0]&0x2C); + calc_key[3] = ((cal[2]&0x0F)<<4)|(cal[3]&0x7D); + if (calc_key[0]!=key[0] || calc_key[1]!=key[1] || calc_key[2]!=key[2] || calc_key[3]!=key[3]) + { + //TxTestMsg(calc_key); + return false; + } + return true; + default: + return false; + } + + return false; +} + +void UdsService27_SecurityAccess(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + static uint8_t seedLevel = 0; + static uint8_t seedValue[8] = {0}; + static uint16_t seedLen = 0; + uint8_t subFunction; + uint8_t udx = 0; + uint8_t rspBuffer[8] = {0}; + uint16_t dataLen = 0, remainSize = 0; + bool ret = false; + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x27, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + if(obj->session == UDS_SESSION_DEFAULT) + { + Uds_NegativeResponse(obj, 0x27, NRC_CONDITIONS_NOT_CORRECT); + return; + } + + subFunction = UDS_GET_SUB_FUNCTION(msgBuf[1]); + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x27); + rspBuffer[1] = subFunction; + if(subFunction % 2) + { + seedLevel = 0; + for(udx = 0; udx < SUPPORT_LEVEL_NUM; udx++) + { + if(subFunction == scrtParam[udx].level) + { + if(scrtParam[udx].keyErrorCnt > scrtParam[udx].maxErrNum) + { + if(obj->timeStamp_ms - scrtParam[udx].MaxErrTimeStamp < ERR_EXCEED_DELAY_MS) + { + Uds_NegativeResponse(obj, 0x27, NRC_EXCEEDED_NUMBER_OF_ATTEMPTS); + return; + } + else + { + scrtParam[udx].keyErrorCnt = 0; + } + } + break; + } + } + + if(udx >= SUPPORT_LEVEL_NUM) + { + Uds_NegativeResponse(obj, 0x27, NRC_REQUEST_OUT_OF_RANGE); + return; + } + + remainSize = sizeof(rspBuffer) - 2; + UdsSecurityAccess_GenerateSeed(obj, subFunction, &rspBuffer[2], remainSize, &dataLen); + if(dataLen > 0) + { + Uds_PositiveResponse(obj, rspBuffer, dataLen + 2); + + seedLevel = subFunction; + seedLen = dataLen; + memcpy(seedValue, &rspBuffer[2], dataLen); + } + else + { + Uds_NegativeResponse(obj, 0x27, NRC_REQUEST_OUT_OF_RANGE); + } + } + else + { + if(subFunction != seedLevel + 1) + { + Uds_NegativeResponse(obj, 0x27, NRC_REQUEST_SEQUENCE_ERROR); + return; + } + + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still reserve though it's maybe unreachable" */ + ret = UdsSecurityAccess_ValidateKey(seedLevel, seedValue, seedLen, &msgBuf[2], msgLen - 2); + if(ret == true) + { + Uds_PositiveResponse(obj, rspBuffer, 2); + + seedLevel = 0; + obj->securityLevel = subFunction - 1; + + for(udx = 0; udx < SUPPORT_LEVEL_NUM; udx++) + { + if(subFunction == scrtParam[udx].level) + { + scrtParam[udx].keyErrorCnt = 0; + } + } + } + else + { + Uds_NegativeResponse(obj, 0x27, NRC_INVALID_KEY); + + for(udx = 0; udx < SUPPORT_LEVEL_NUM; udx++) + { + if(seedLevel == scrtParam[udx].level) + { + scrtParam[udx].keyErrorCnt++; + if(scrtParam[udx].keyErrorCnt > scrtParam[udx].maxErrNum) + { + scrtParam[udx].MaxErrTimeStamp = obj->timeStamp_ms; + } + } + } + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still reserve though it's maybe unreachable" */ + } +} diff --git a/cva_bootloader_m0118/src/private_driver/uds/user/uds_service27.h b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service27.h new file mode 100644 index 0000000..8d04ec9 --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service27.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE27_H_ +#define _UDS_SERVICE27_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 27 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 27 processing + */ +extern void UdsService27_SecurityAccess(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE27_H_ */ diff --git a/cva_bootloader_m0118/src/private_driver/uds/user/uds_service31.c b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service31.c new file mode 100644 index 0000000..b6be23b --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service31.c @@ -0,0 +1,394 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_service31.h" +#include "bootloader.h" + +/******************************************************************************* + * the defines + ******************************************************************************/ +#define RID_ERASE_MEMORY 0xFD01 +#define RID_CHECK_FLSDRV_VALID 0xFD02 +#define RID_CHECK_DATA_VALIDITY 0xFD03 +#define RID_CHECK_DATA_DEPENDENCE 0xFD04 + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The Uds routine control type + */ +typedef enum _UdsRoutineCtrlType_ +{ + UDS_ROUTINE_CTRL_NONE = 0, + UDS_ROUTINE_CTRL_START = 0x01, + UDS_ROUTINE_CTRL_STOP = 0x02, + UDS_ROUTINE_CTRL_REQUEST_RESULT = 0x03 +} UdsRoutineCtrlType; + +/*! \brief The Uds routine control status + */ +typedef enum _UdsRtnCtrlStatus_ +{ + UDS_RTN_ST_IDLE = 0x00, + UDS_RTN_ST_RUNNING = 0x01, +} UdsRtnCtrlStatus; + +/*! \brief The Uds routine control struct + */ +typedef struct _Uds_RtnCtrl_ +{ + uint16_t rtnCtrlId; + uint8_t sessionLevel; + uint8_t securityLevel; + UdsRtnCtrlStatus rtnStatus; + void (*Routine_Start)(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); + void (*Routine_Stop)(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); + void (*Routine_Result)(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); +} Uds_RtnCtrl; + +/******************************************************************************* + * the constants + ******************************************************************************/ + +static void Routine_StartEreaseMemory(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); +static void Routine_StopEreaseMemory(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); +static void Routine_ResultEreaseMemory(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); + +static void Routine_StartValidityData(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); +static void Routine_StopValidityData(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); +static void Routine_ResultValidityData(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); + +static void Routine_StartCheckFlsDriverValid(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); +static void Routine_StopCheckFlsDriverValid(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); +static void Routine_ResultCheckFlsDriverValid(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); + +static void Routine_StartVerifyDataDependency(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); +static void Routine_StopVerifyDataDependency(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); +static void Routine_ResultVerifyDataDependency(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen); + +/******************************************************************************* + * the globals + ******************************************************************************/ + +Uds_RtnCtrl udsRtnCtrlTable[] = { + {RID_ERASE_MEMORY, UDS_SESSION_PROGRAMMING, UDS_SA_LEVEL_09, UDS_RTN_ST_IDLE, &Routine_StartEreaseMemory, &Routine_StopEreaseMemory, &Routine_ResultEreaseMemory }, + {RID_CHECK_FLSDRV_VALID, UDS_SESSION_PROGRAMMING, UDS_SA_LEVEL_09, UDS_RTN_ST_IDLE, &Routine_StartCheckFlsDriverValid, &Routine_StopCheckFlsDriverValid, &Routine_ResultCheckFlsDriverValid }, + {RID_CHECK_DATA_VALIDITY, UDS_SESSION_PROGRAMMING, UDS_SA_LEVEL_09, UDS_RTN_ST_IDLE, &Routine_StartValidityData, &Routine_StopValidityData, &Routine_ResultValidityData }, + {RID_CHECK_DATA_DEPENDENCE, UDS_SESSION_PROGRAMMING, UDS_SA_LEVEL_09, UDS_RTN_ST_IDLE, &Routine_StartVerifyDataDependency, &Routine_StopVerifyDataDependency, &Routine_ResultVerifyDataDependency}, +}; + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void Routine_StatusInit(void) +{ + uint8_t rtnIndex = 0; + uint8_t rntNum = sizeof(udsRtnCtrlTable) / sizeof(Uds_RtnCtrl); + + for(rtnIndex = 0; rtnIndex < rntNum; rtnIndex++) + { + udsRtnCtrlTable[rtnIndex].rtnStatus = UDS_RTN_ST_IDLE; + } +} + +static void Routine_StartEreaseMemory(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + /* user add start erease memory code */ + uint32_t memAddress = 0, memSize = 0; + uint8_t addressLen = 0, memSizeLen = 0, i = 0; + + if(pdata == NULL) + { + *pRspLen = 0; + return; + } + + addressLen = ((pdata[0] >> 4) & 0x0F); + memSizeLen = ((pdata[0] >> 0) & 0x0F); + + for(i = 0; i < addressLen; i++) + { + memAddress |= (((uint32_t)pdata[i + 1]) << ((3 - i) * 8)); + } + + for(i = 0; i < memSizeLen; i++) + { + memSize |= (((uint32_t)pdata[i + 5]) << ((3 - i) * 8)); + } + + Bootloader_EventEraseRequest(memAddress, memSize); +} + +static void Routine_StopEreaseMemory(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + +} + +static void Routine_ResultEreaseMemory(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + uint16_t txLen = *pRspLen; + + if(Bootloader_GetBootState() == BOOTLOADER_STATE_ERASE) + { + Bootloader_SubStateType subState; + + subState = Bootloader_GetBootSubState(); + if(subState == BOOTLOADER_SUB_STATE_END) + { + pRspData[txLen++] = 0x01; + udsRtnCtrlTable[0].rtnStatus = UDS_RTN_ST_IDLE; + } + else + { + pRspData[txLen++] = 0x02; + } + } + else + { + pRspData[txLen++] = 0x03; + udsRtnCtrlTable[0].rtnStatus = UDS_RTN_ST_IDLE; + } + + *pRspLen = txLen; +} + +static void Routine_StartValidityData(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + Bootloader_EventDataCheckRequest(); +} + +static void Routine_StopValidityData(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + +} + +static void Routine_ResultValidityData(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + uint16_t txLen = *pRspLen; + + if(Bootloader_GetBootState() == BOOTLOADER_STATE_CHECK) + { + if(Bootloader_GetBootSubState() == BOOTLOADER_SUB_STATE_DOING) + { + pRspData[txLen++] = 0x02; + } + else if(Bootloader_GetBootSubState() == BOOTLOADER_SUB_STATE_END) + { + if(Bootloader_GetCrcResult() == true) + { + pRspData[txLen++] = 0x01; + + udsRtnCtrlTable[2].rtnStatus = UDS_RTN_ST_IDLE; + } + else + { + pRspData[txLen++] = 0x03; + + udsRtnCtrlTable[2].rtnStatus = UDS_RTN_ST_IDLE; + } + } + } + + *pRspLen = txLen; +} + +static void Routine_StartCheckFlsDriverValid(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + Bootloader_EventDataCheckRequest(); +} + +static void Routine_StopCheckFlsDriverValid(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + +} + +static void Routine_ResultCheckFlsDriverValid(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + uint16_t txLen = *pRspLen; + + if(Bootloader_GetBootState() == BOOTLOADER_STATE_CHECK) + { + if(Bootloader_GetBootSubState() == BOOTLOADER_SUB_STATE_DOING) + { + pRspData[txLen++] = 0x02; + } + else if(Bootloader_GetBootSubState() == BOOTLOADER_SUB_STATE_END) + { + if(Bootloader_GetCrcResult() == true) + { + pRspData[txLen++] = 0x01; + + udsRtnCtrlTable[1].rtnStatus = UDS_RTN_ST_IDLE; + } + else + { + pRspData[txLen++] = 0x03; + + udsRtnCtrlTable[1].rtnStatus = UDS_RTN_ST_IDLE; + } + } + } + + *pRspLen = txLen; +} + +static void Routine_StartVerifyDataDependency(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + +} + +static void Routine_StopVerifyDataDependency(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + +} + +static void Routine_ResultVerifyDataDependency(const uint8_t *pdata, uint16_t len, uint8_t *pRspData, uint16_t rspSize, uint16_t *pRspLen) +{ + +} + +void UdsService31_RoutineControl(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + const uint8_t *pOptionParam = NULL; + uint8_t subFunction = 0; + uint16_t optionParamLen = 0; + uint16_t routineId = 0; + uint8_t rtnIndex = 0; + uint8_t rntNum = sizeof(udsRtnCtrlTable) / sizeof(Uds_RtnCtrl); + uint8_t rspBuffer[UDS_RSP_LEN_MAX] = {0}; + uint16_t rspLen = 0; + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x31, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + subFunction = UDS_GET_SUB_FUNCTION(msgBuf[1]); + routineId = ((uint16_t)msgBuf[2] << 8) + msgBuf[3]; + optionParamLen = msgLen - 4; + if(optionParamLen > 0) + { + pOptionParam = &msgBuf[4]; + } + + for(rtnIndex = 0; rtnIndex < rntNum; rtnIndex++) + { + if(udsRtnCtrlTable[rtnIndex].rtnCtrlId == routineId) + { + if(obj->session == udsRtnCtrlTable[rtnIndex].sessionLevel) + { + if((udsRtnCtrlTable[rtnIndex].securityLevel != UDS_SA_NONE) && (udsRtnCtrlTable[rtnIndex].securityLevel != obj->securityLevel)) + { + Uds_NegativeResponse(obj, 0x31, NRC_SECURITY_ACCESS_DENIED); + return; + } + + break; + } + else + { + Uds_NegativeResponse(obj, 0x31, NRC_CONDITIONS_NOT_CORRECT); + return; + } + } + } + + if(rtnIndex >= rntNum) + { + Uds_NegativeResponse(obj, 0x31, NRC_REQUEST_OUT_OF_RANGE); + return; + } + + memset(rspBuffer, 0, UDS_RSP_LEN_MAX); + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x31); + rspBuffer[1] = msgBuf[1]; + rspBuffer[2] = msgBuf[2]; + rspBuffer[3] = msgBuf[3]; + rspLen = 4; + + switch(subFunction) + { + case UDS_ROUTINE_CTRL_START: + if(udsRtnCtrlTable[rtnIndex].rtnStatus == UDS_RTN_ST_RUNNING) + { + rspBuffer[0] = NEGATIVE_RSP; + rspBuffer[1] = 0x31; + rspBuffer[2] = NRC_REQUEST_SEQUENCE_ERROR; + rspLen = 3; + } + else + { + udsRtnCtrlTable[rtnIndex].Routine_Start(pOptionParam, optionParamLen, rspBuffer, UDS_RSP_LEN_MAX, &rspLen); + udsRtnCtrlTable[rtnIndex].rtnStatus = UDS_RTN_ST_RUNNING; + } + break; + case UDS_ROUTINE_CTRL_STOP: + if(udsRtnCtrlTable[rtnIndex].rtnStatus != UDS_RTN_ST_IDLE) + { + udsRtnCtrlTable[rtnIndex].Routine_Stop(pOptionParam, optionParamLen, rspBuffer, UDS_RSP_LEN_MAX, &rspLen); + udsRtnCtrlTable[rtnIndex].rtnStatus = UDS_RTN_ST_IDLE; + } + else + { + rspBuffer[0] = NEGATIVE_RSP; + rspBuffer[1] = 0x31; + rspBuffer[2] = NRC_REQUEST_SEQUENCE_ERROR; + rspLen = 3; + } + break; + case UDS_ROUTINE_CTRL_REQUEST_RESULT: + if(udsRtnCtrlTable[rtnIndex].rtnStatus != UDS_RTN_ST_IDLE) + { + udsRtnCtrlTable[rtnIndex].Routine_Result(pOptionParam, optionParamLen, rspBuffer, UDS_RSP_LEN_MAX, &rspLen); + } + else + { + rspBuffer[0] = NEGATIVE_RSP; + rspBuffer[1] = 0x31; + rspBuffer[2] = NRC_REQUEST_SEQUENCE_ERROR; + rspLen = 3; + } + break; + default: + rspBuffer[0] = NEGATIVE_RSP; + rspBuffer[1] = 0x31; + rspBuffer[2] = NRC_SUBFUNCTION_NOT_SUPPORTED; + rspLen = 3; + return; + } + + /* polyspace-begin DEFECT:DEAD_CODE [No action planned:Low] "Still reserve though it's maybe unreachable" */ + if((rspLen >= 4) && (rspBuffer[0] == UDS_GET_POSITIVE_RSP(0x31))) + { + Uds_PositiveResponse(obj, rspBuffer, rspLen); + } + else if((rspLen == 3) && (rspBuffer[0] == NEGATIVE_RSP)) + { + Uds_NegativeResponse(obj, 0x31, rspBuffer[2]); + } + else + { + Uds_NegativeResponse(obj, 0x31, NRC_REQUEST_SEQUENCE_ERROR); + } + /* polyspace-end DEFECT:DEAD_CODE [No action planned:Low] "Still reserve though it's maybe unreachable" */ +} diff --git a/cva_bootloader_m0118/src/private_driver/uds/user/uds_service31.h b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service31.h new file mode 100644 index 0000000..8f83696 --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service31.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE31_H_ +#define _UDS_SERVICE31_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 31 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 31 processing + */ +extern void UdsService31_RoutineControl(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +/*! \brief Routine status init + */ +extern void Routine_StatusInit(void); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE31_H_ */ diff --git a/cva_bootloader_m0118/src/private_driver/uds/user/uds_service34.c b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service34.c new file mode 100644 index 0000000..7e9f2f0 --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service34.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_service34.h" +#include "uds_service36.h" +#include "bootloader.h" + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ + +uint32_t Uds_GetMaxfBlockSize(void) +{ + uint32_t blockSize = 0; + /* user add code to get max num of block length */ + blockSize = Bootloader_GetPgmBlockSize() + 2u; + + return blockSize; +} + +uint8_t Uds_GetValidBytesNumOfData(uint32_t data) +{ + uint8_t index = 0; + uint8_t bytesNum = 0; + + for(index = 1; index <= 4; index++) + { + if(data >> ((4 - index) * 8)) + { + bytesNum = 4 - index + 1; + break; + } + } + + return bytesNum; +} + +void UdsService34_RequestDownload(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint32_t memAddress = 0; + uint8_t memAddrLen = 0; + uint32_t memSize = 0; + uint8_t memSizeLen = 0; + uint8_t maxBlockSizeLen = 0; + uint32_t maxBlockSize = 0; + uint8_t index = 0; + uint16_t rspLen = 0; + uint8_t rspBuffer[8]; + + if(obj->session == UDS_SESSION_DEFAULT) + { + Uds_NegativeResponse(obj, 0x34, NRC_CONDITIONS_NOT_CORRECT); + return; + } + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x34, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + memAddrLen = msgBuf[2] & 0x0F; + memSizeLen = msgBuf[2] >> 4; + + if((memAddrLen == 0) || (memAddrLen > sizeof(memAddress)) || (memSizeLen == 0) || (memSizeLen > sizeof(memSize))) + { + Uds_NegativeResponse(obj, 0x34, NRC_REQUEST_OUT_OF_RANGE); + return; + } + + for(index = 0; index < memAddrLen; index++) + { + memAddress <<= 8; + memAddress += msgBuf[3 + index]; + } + + for(index = 0; index < memSizeLen; index++) + { + memSize <<= 8; + memSize += msgBuf[3 + memAddrLen + index]; + } + + if(memSize == 0) + { + Uds_NegativeResponse(obj, 0x34, NRC_CONDITIONS_NOT_CORRECT); + return; + } + + Uds_InitDownload(); + + Uds_SetMemAddr(memAddress); + Uds_SetMemSize(memSize); + + Uds_SetDataTransferDirect(UDS_TRANSFER_DIR_DOWNLOAD); + + maxBlockSize = Uds_GetMaxfBlockSize(); + maxBlockSizeLen = Uds_GetValidBytesNumOfData(maxBlockSize); + + rspBuffer[rspLen++] = UDS_GET_POSITIVE_RSP(0x34); + rspBuffer[rspLen++] = maxBlockSizeLen << 4; + for(index = 1; index <= maxBlockSizeLen; index++) + { + rspBuffer[rspLen++] = maxBlockSize >> (8 * (maxBlockSizeLen - index)); + } + + Bootloader_EventPgmReady(memAddress, memSize); + + Uds_PositiveResponse(obj, rspBuffer, rspLen); +} + + + diff --git a/cva_bootloader_m0118/src/private_driver/uds/user/uds_service34.h b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service34.h new file mode 100644 index 0000000..072140b --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service34.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE34_H_ +#define _UDS_SERVICE34_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 34 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Uds Service 34 processing + */ +extern void UdsService34_RequestDownload(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE34_H_ */ diff --git a/cva_bootloader_m0118/src/private_driver/uds/user/uds_service36.c b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service36.c new file mode 100644 index 0000000..1983803 --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service36.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_service36.h" +#include "bootloader.h" + + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +static uint32_t s_memAddr = 0; +static uint32_t s_memSize = 0; +static UdsTransDirType s_dataTransDir = UDS_TRANSFER_DIR_NONE; + +static uint8_t s_curRcvSequence = 0; +static uint8_t s_lastRcvSqunce = 0; +static uint32_t s_rcvDataTotalLen = 0; + +/******************************************************************************* + * the constants + ******************************************************************************/ + +/******************************************************************************* + * the functions + ******************************************************************************/ +void Uds_InitDownload(void) +{ + s_curRcvSequence = 0; + s_lastRcvSqunce = 0; + s_rcvDataTotalLen = 0; + s_memAddr = 0; + s_memSize = 0; +} + +void Uds_SetMemAddr(uint32_t addr) +{ + s_memAddr = addr; +} + +uint32_t Uds_GetMemAddr(void) +{ + return s_memAddr; +} + +void Uds_SetMemSize(uint32_t size) +{ + s_memSize = size; +} + +uint32_t Uds_GetMemSize(void) +{ + return s_memSize; +} + +void Uds_SetDataTransferDirect(UdsTransDirType dirType) +{ + s_dataTransDir = dirType; +} + +UdsTransDirType Uds_GetDataTransferDirect(void) +{ + return s_dataTransDir; +} + +uint32_t Uds_GetRcvDataTotalLen(void) +{ + return s_rcvDataTotalLen; +} + +void UdsService36_TransferData(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) +{ + uint8_t rspBuffer[10] = {0}; + if(obj->session == UDS_SESSION_DEFAULT) + { + Uds_NegativeResponse(obj, 0x36, NRC_CONDITIONS_NOT_CORRECT); + return; + } + + if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) + { + Uds_NegativeResponse(obj, 0x36, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); + return; + } + + switch(s_dataTransDir) + { + case UDS_TRANSFER_DIR_DOWNLOAD: + s_curRcvSequence = msgBuf[1]; + + if((s_curRcvSequence != s_lastRcvSqunce) && (s_curRcvSequence != ((uint8_t)(s_lastRcvSqunce + 1u)))) + { + Uds_NegativeResponse(obj, 0x36, NRC_WRONG_BLOCK_SEQUENCE_COUNTER); + return; + } + + if((s_rcvDataTotalLen + msgLen - 2u) > s_memSize) + { + Uds_NegativeResponse(obj, 0x36, NRC_TRANSFER_DATA_SUSPENDED); + return; + } + + if(s_curRcvSequence == ((uint8_t)(s_lastRcvSqunce + 1u))) + { + if(Bootloader_EventPgmData(&msgBuf[2], msgLen - 2u, s_curRcvSequence) == true) + { + s_rcvDataTotalLen += (msgLen - 2u); + } + + s_lastRcvSqunce = s_curRcvSequence; + + rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x36); + rspBuffer[1] = s_curRcvSequence; + //Uds_PositiveResponse(obj, rspBuffer, 2); + } + break; + case UDS_TRANSFER_DIR_UPLOAD: + Uds_NegativeResponse(obj, 0x36, NRC_REQUEST_OUT_OF_RANGE); + break; + default: + Uds_NegativeResponse(obj, 0x36, NRC_REQUEST_SEQUENCE_ERROR); + break; + } +} + + + diff --git a/cva_bootloader_m0118/src/private_driver/uds/user/uds_service36.h b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service36.h new file mode 100644 index 0000000..8a020f6 --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/uds/user/uds_service36.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_SERVICE36_H_ +#define _UDS_SERVICE36_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS service 36 + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The Uds IO control type + */ +typedef enum _UdsTransDirType_ +{ + UDS_TRANSFER_DIR_NONE = 0x00, + UDS_TRANSFER_DIR_DOWNLOAD = 0x01, + UDS_TRANSFER_DIR_UPLOAD = 0x02, +} UdsTransDirType; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ +extern void Uds_InitDownload(void); + +/*! \brief set memery start address + */ +extern void Uds_SetMemAddr(uint32_t addr); + +/*! \brief get memery start address + */ +extern uint32_t Uds_GetMemAddr(void); + +/*! \brief set memery size + */ +extern void Uds_SetMemSize(uint32_t size); + +/*! \brief get memery size + */ +extern uint32_t Uds_GetMemSize(void); + +/*! \brief set data transfer direct + */ +extern void Uds_SetDataTransferDirect(UdsTransDirType dirType); + +/*! \brief get data transfer direct + */ +extern UdsTransDirType Uds_GetDataTransferDirect(void); + +/*! \brief get receive data total len + */ +extern uint32_t Uds_GetRcvDataTotalLen(void); + +/*! \brief Uds Service 10 processing + */ +extern void UdsService36_TransferData(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_SERVICE36_H_ */ diff --git a/cva_bootloader_m0118/src/private_driver/uds/user/uds_user.c b/cva_bootloader_m0118/src/private_driver/uds/user/uds_user.c new file mode 100644 index 0000000..e984d14 --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/uds/user/uds_user.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include "uds_user.h" +#include "bootloader_cfg.h" +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/*! \brief The Data-by-ID definition of UDS + */ +typedef struct _Uds_DidBuffer_ +{ + uint8_t buffer_F186[1]; + uint8_t buffer_F187[8];//ecu name + uint8_t buffer_F180[8];//boot version + uint8_t buffer_F191[24];//buildtime + uint8_t buffer_F193[4];//hw version + uint8_t buffer_F195[8];//sw version +} Uds_DidBuffer; + +/******************************************************************************* + * the globals + ******************************************************************************/ + +Uds_DidBuffer udsDidBuf; + +/******************************************************************************* + * the constants + ******************************************************************************/ + +static const Uds_ServiceType udsServiceTable[UDS_SERVICE_NUM] = { + {0x10, 2, true, UdsService10_SessionControl }, + {0x11, 2, true, UdsService11_ResetEcu }, + {0x27, 2, true, UdsService27_SecurityAccess }, + {0x28, 3, true, UdsService28_CommunicationControl }, + {0x3E, 2, true, UdsService3E_TesterPresent }, + {0x85, 2, true, UdsService85_ControlDtcSetting }, + {0x22, 3, false, UdsService22_ReadDataByIdentifier }, + {0x2E, 4, false, UdsService2E_WriteDataByIdentifier}, + {0x14, 4, false, UdsService14_ClearDiagInfo }, + {0x19, 3, true, UdsService19_ReadDtcInformation }, + {0x2F, 3, false, UdsService2F_InputOutputCtrlById }, + {0x31, 4, true, UdsService31_RoutineControl }, + {0x34, 5, false, UdsService34_RequestDownload }, + {0x36, 2, false, UdsService36_TransferData }, + {0x37, 1, false, UdsService37_RequestTransferExit }, +}; + +static const bool udsSecurityTable[UDS_SERVICE_NUM][UDS_SA_LEVEL_NUM] = { + {false, false, false}, /* 0x10 */ + {false, false, false}, /* 0x11 */ + {false, false, false}, /* 0x27 */ + {false, false, false}, /* 0x28 */ + {false, false, false}, /* 0x3E */ + {false, false, false}, /* 0x85 */ + {false, false, false}, /* 0x22 */ + {false, false, false}, /* 0x2E */ + {false, false, false}, /* 0x14 */ + {false, false, false}, /* 0x19 */ + {false, false, false}, /* 0x2F */ + {false, false, false}, /* 0x31 */ + {false, false, false}, /* 0x34 */ + {false, false, false}, /* 0x36 */ + {false, false, false}, /* 0x37 */ +}; + +Uds_DidType udsDidTable[] = { + {0xF186, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F186, BYTES_OF(udsDidBuf.buffer_F186),DID_F186_func}, + {0xF187, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F187, BYTES_OF(udsDidBuf.buffer_F187),DID_F187_func}, + {0xF180, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F180, BYTES_OF(udsDidBuf.buffer_F180),DID_F180_func}, + {0xF191, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F191, BYTES_OF(udsDidBuf.buffer_F191),DID_F191_func}, + {0xF193, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F193, BYTES_OF(udsDidBuf.buffer_F193),DID_F193_func}, + {0xF195, UDS_DID_TYPE_RAM_RW, UDS_SESSION_DEFAULT, UDS_SA_NONE, udsDidBuf.buffer_F195, BYTES_OF(udsDidBuf.buffer_F195),DID_F195_func}, +}; + +/******************************************************************************* + * the functions + ******************************************************************************/ + +void Uds_UserInit(UdsType *obj, const Uds_ParamsType *pParams) +{ + Uds_Init(obj, pParams); + + obj->seviceTable = udsServiceTable; + obj->securityTable = &udsSecurityTable[0][0]; + obj->serviceNum = UDS_SERVICE_NUM; + obj->didTable = udsDidTable; + obj->didNum = sizeof(udsDidTable) / sizeof(Uds_DidType); +} + +/******************************DID FUNC****************************************/ +void DID_F180_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen) +{ + Bootloade_CfgInfoType * PBootInfo; + PBootInfo = (Bootloade_CfgInfoType *)0x00000c0; + memcpy(dataBuf, &(PBootInfo->BLVersion), dataLen); +} +void DID_F186_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen) +{ + dataBuf[0] = obj->session; +} +void DID_F187_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen) +{ + Bootloade_CfgInfoType * PBootInfo; + PBootInfo = (Bootloade_CfgInfoType *)0x00000c0; + memcpy(dataBuf, &(PBootInfo->ECUName), dataLen); +} +void DID_F191_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen) +{ + Bootloade_CfgInfoType * PBootInfo; + PBootInfo = (Bootloade_CfgInfoType *)0x00000c0; + //memcpy(dataBuf, &(PBootInfo->HWVersion), dataLen); + memcpy(dataBuf, &(PBootInfo->bootBuildDate), 12); + memcpy(dataBuf + 12, &(PBootInfo->bootBuildTime), 8); + dataBuf[11] = ' '; +} +void DID_F193_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen) +{ + Bootloade_CfgInfoType * PBootInfo; + PBootInfo = (Bootloade_CfgInfoType *)0x00000c0; + memcpy(dataBuf, &(PBootInfo->HWVersion), dataLen); +} +void DID_F195_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen) +{ + for (uint8_t i = 0; i < dataLen; i++) + { + dataBuf[i] = 0x20;//TODO + } + +} \ No newline at end of file diff --git a/cva_bootloader_m0118/src/private_driver/uds/user/uds_user.h b/cva_bootloader_m0118/src/private_driver/uds/user/uds_user.h new file mode 100644 index 0000000..5f6cb86 --- /dev/null +++ b/cva_bootloader_m0118/src/private_driver/uds/user/uds_user.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD + * All rights reserved. + * + * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use + * exclusively with CVA's microcontroller products. This file can be freely + * distributed within development tools that are supporting such microcontroller + * products. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ + +#ifndef _UDS_USER_H_ +#define _UDS_USER_H_ + +/*! \brief Contains public interface to various functions related + * to the user-defined UDS application + */ + +/******************************************************************************* + * the includes + ******************************************************************************/ + +#include +#include +#include "../stack/uds.h" +#include "uds_service10.h" +#include "uds_service11.h" +#include "uds_service14.h" +#include "uds_service19.h" +#include "uds_service22.h" +#include "uds_service27.h" +#include "uds_service28.h" +#include "uds_service2E.h" +#include "uds_service2F.h" +#include "uds_service31.h" +#include "uds_service34.h" +#include "uds_service36.h" +#include "uds_service37.h" +#include "uds_service3E.h" +#include "uds_service85.h" +#include "uds_dtc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * the defines + ******************************************************************************/ + +/******************************************************************************* + * the typedefs + ******************************************************************************/ + +/******************************************************************************* + * the globals + ******************************************************************************/ + +/******************************************************************************* + * the function prototypes + ******************************************************************************/ + +/*! \brief Initialize the UDS object + */ +extern void Uds_UserInit(UdsType *obj, const Uds_ParamsType *pParams); + +extern void DID_F180_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen); +extern void DID_F186_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen); +extern void DID_F187_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen); +extern void DID_F191_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen); +extern void DID_F193_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen); +extern void DID_F195_func(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen); + +#ifdef __cplusplus +} +#endif /* extern "C" */ + +#endif /* _UDS_USER_H_ */